Search code examples
assemblyx86-64ssefreepascal

Semantics of mov widths in x64 and SSE


Consider the following from 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.

Clearly, we are defining the width of data to move.

Now consider this:

movdqu        qword ptr [rcx], xmm0

This is moving 128 bits, but we don't write movdqu dqword. In fact, movdqu dword ptr produces the same results.

Why do the semantics change with the SSE op?


Solution

  • With MASM(32 bit, but however) these two lines are rejected as an error.

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

    These two are accepted:

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

    So the prefix is neccessary and the size prefix matches the 16 bytes=128 bit size of the xmm register. There are two other instructions similar to MOVZX, 32 bit and 64 bit:

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

    So I couldn't confirm an inconsequency in semantics - at least with MASM.