Home > Software design >  How do you differentiate "MOV r/m64, imm32" vs "MOV r/m32, imm32" in MASM64?
How do you differentiate "MOV r/m64, imm32" vs "MOV r/m32, imm32" in MASM64?

Time:06-06

The Intel manual says mov has two variants involving both memory and 32-bit immediate operands:

MOV r/m32, imm32
MOV r/m64, imm32

The first one copies four bytes, the second copies eight, taking the given 32-bit immediate and sign-extending it to 64 bits.

How do you specify which one you want when writing assembly code for MASM64?

CodePudding user response:

@ecm's comment above gives the answer:

mov qword ptr [rsp 08h], 0   ; selects MOV r/m64, imm32
mov dword ptr [rsp 08h], 0   ; selects MOV r/m32, imm32

CodePudding user response:

Override the size of the memory operand, like always.

mov   qword ptr [rdx], 123
add   byte ptr [rcx], 1
movzx eax,  word ptr [r8]
shl   dword ptr [r9], cl

It makes sense in general to think about setting the size of the memory operand, not the immediate, because that always works, even with movzx or shl dword ptr [mem], 4 where the operands don't have to be the same size (the shift count is a byte and could be CL).

You're not overriding anything about the immediate; you still want add qword ptr [mem], 4 to use a sign_extended_imm8 encoding, leaving the encoding up to the assembler. (Only mov and test lack sign-extended byte forms, out of ALU instructions that come from original 8086.)


Even for assemblers like NASM that do accept add [rcx], word 0x0001, I'd never write it that way.

Especially in NASM where you can force it to use a 4-byte immediate with add qword [rdi], strict qword 123 which would use a 4-byte immediate in the machine code that something else could rewrite. Using dword on an immediate without strict seems like the wrong way of thinking about it.

Especially with NASM's default optimization enabled so you don't need stuff like mov rax, dword -1 to avoid the imm64 encoding, or add dword [rdi], byte 1 to avoid the imm32 encoding. (With nasm -O0, those do pick longer encodings if you didn't suggest the smaller encoding with a non-strict hint, so putting sizes on immediates is something you can do separately from setting the operand-size.)

(NASM's a bit messy in requiring strict qword 123 for add qword [rdi], strict qword 123, not strict dword, matching the operand-size instead of the immediate width. IMO it's a bug that it rejects add qword [rdi], strict dword 123. Probably the syntax was designed before x86-64 existed, and/or design mistakes were made in how to extend it to cases where there are non-full-width immediates other than bytes.)

  • Related