x64 和 SSE 中 mov 宽度的语义

Semantics of mov widths in x64 and SSE

考虑 here 中的以下内容:

mov BYTE PTR [ebx], 2 ; Move 2 into the single byte at the address stored in EBX.

mov WORD PTR [ebx], 2 ; Move the 16-bit integer representation of 2 into the 2 bytes starting at the address in EBX.

mov DWORD PTR [ebx], 2 ; Move the 32-bit integer representation of 2 into the 4 bytes starting at the address in EBX.

显然,我们正在定义要移动的数据宽度。

现在考虑一下:

movdqu        qword ptr [rcx], xmm0

这里是移动128位,但是我们不写movdqu dqword。事实上,movdqu dword ptr 产生相同的结果。

为什么语义会随着 SSE 操作而改变?

虽然在这种情况下汇编器确实可以计算出操作大小,但如果您使用与指令冲突的大小规范,它至少应该提供警告。您忘记提及您使用的是哪个汇编程序,但是 nasm 和 gas 都提供了这样的诊断:

nasm: error: impossible combination of address sizes
gas: Error: operand size mismatch for `movdqu'

使用 MASM(32 位,但是)这两行被视为错误而被拒绝。

movdqu        qword ptr [ecx], xmm0
movdqu        [ecx], xmm0             ; standard prefix DWORD
...
test.asm(121) : error A2022:instruction operands must be the same size

这两个被接受:

movdqu oword ptr [ecx], xmm0    ; explicit 128bit
movdqu xmmword ptr [ecx], xmm0  ; explicit 128bit

因此前缀是必需的,大小前缀匹配 xmm 寄存器的 16 字节=128 位大小。和MOVZX类似的还有另外两条指令,32位和64位:

movd [ecx], xmm0            ; standard prefix DWORD
movd dword ptr [ecx], xmm0  ; explicit DWORD
movq qword ptr [ecx], xmm0  ; explicit QWORD needed

所以我无法确认语义上的不一致 - 至少在 MASM 中是这样。