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 assembler 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.)