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 中是这样。
考虑 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 中是这样。