首页 > 解决方案 > 无法使用 nasm 编译具有 xmmword 操作数大小的汇编代码

问题描述

我试图使用nasm( nasm -o file input.asm) 编译汇编代码,并在以下代码片段的第 2 行抛出错误:

mov rsi, 0x400200
movdqu xmm0,xmmword [rsi]
nop

我不确定是否可以使用 128 位寄存器编译指令,nasm但在涉及 128 位寄存器的情况下,是否有任何其他方法可以使用 nasm 进行编译?

标签: assemblynasmsse128-bit

解决方案


您不需要为内存操作数指定操作数大小,
只需使用movdqu xmm0, [rsi]并让 xmm0 表示 128 位操作数大小。
NASM 支持 SSE/AVX/AVX-512 指令。

如果您确实想指定操作数大小,则 128 位的名称是oword,根据ndisasm您是否汇编该指令然后反汇编生成的机器代码。oword = oct-word = 8x 2 字节字 = 16 字节。


请注意,与 NASM 不同,GNU .intel_syntax noprefix(由 使用objdump -drwC -Mintel使用。xmmword ptr

如果您真的想使用 xmmword,%define xmmword oword请在文件顶部。

对于所有 SSE/AVX/AVX-512 指令,助记符和/或其他寄存器操作数始终隐含操作数大小;我想不出任何需要指定qwordvs. owordvs.yword或任何东西的指令,就像你用movsx eax, byte [rdi]vs.做的那样word [rdi]。通常它与寄存器的大小相同,但也有一些 shuffle / insert / extract 指令的例外情况。例如:

  • SSE2pinsrw xmm0, [rdi], 3加载 aword并将其合并到 xmm0 的字节 6 和 7 中。
  • SSE2movq [rdi], xmm0存储 qword 低半部分
  • SSE1movhps [rdi], xmm0存储高qword
  • AVX1vextractf128 [rdi], ymm0, 1对高半部分进行 128 位存储
  • AVX2vpmovzxbw ymm0, [rdi]对 128 位内存源操作数进行压缩字节->字零扩展
  • AVX-512Fvpmovdb [rdi]{k1}, zmm2将 dword 缩小到字节元素(截断;其他版本进行饱和)并进行 128 位存储,以字节粒度进行屏蔽。(在没有 AVX-512BW 的情况下进行字节粒度屏蔽的唯一方法之一,除了maskmovdqu具有缓存驱逐 NT 语义的 legacy-SSE 之外。所以我想这对于 Xeon Phi KNL 来说特别有趣。)

可以指定oword其中任何一个以确保内存访问的大小是您认为的大小。(即让 NASM 为您检查。)


推荐阅读