First I am a little bit confused with the differences between movq
and movabsq
, my text book says:
The regular movq
For the first question:
From the official documentation of gnu assembler:
In 64-bit code,
movabs
can be used to encode themov
instruction with the 64-bit displacement or immediate operand.
mov reg64, imm
(in intel syntax, destination first) is the only instruction that accepts a 64-bit immediate value as a parameter. That's why you can't write a 64-bit immediate value directly to memory.
For the second question:
For other destinations, for example a memory location, a 32-bit immediate can be sign-extended to a 64-bit immediate (which means the top 33 bits are the same there). In this case, you use the movq
instruction.
This is also possible if the target is a register, saving 3 bytes:
C8 B0 FF FF FF 7F 00 00 00 00 movabs $0x7FFFFFFF, %rax
C8 C7 C0 FF FF FF 7F movq $0x7FFFFFFF, %rax
At the 64-bit immediate 0xFFFFFFFF
, the top 33 bits are not the same, so movl
cannot be used here. That's why I chose 0x7FFFFFFF
in this example. But there is another option:
When writing to a 32-bit register (the lower part of a 64-bit register), the upper 32-bit of the register are zeroed. For a 64-bit immediate whose upper 32-bits are zero, movl
can therefore also be used, which saves another byte:
C7 C0 FF FF FF 7F movl $0xFFFFFFFF, %eax
GAS does not do this automatically, but it can choose between movabs
and movq
if you use mov
, depending on the size of the immediate.
Credit: Thanks to Peter Cordes for noting that I initially messed up something in my answer and adding further information.