It seems like to be able to add the max 64
bit value immediate you have to use the movabsq
instruction, and cannot just do movq
or mov
. For example, here is what I did to test:
movq $0xFFFFFFFFFFFFFFFF, %rbx
mov $0xFFFFFFFFFFFFFFFF, %rbx
movq $0xEFFFFFFFFFFFFFFF, %rbx # starts with 'E' // probably added as 8-
mov $0xEFFFFFFFFFFFFFFF, %rbx # starts with 'E' // bytes because cannot be
movabsq $0xFFFFFFFFFFFFFFFF, %rbx # // reduced by sign-extension
And it assembled as:
0x0000000000401000 48 c7 c3 ff ff ff ff ? mov $0xffffffffffffffff,%rbx
0x0000000000401007 48 c7 c3 ff ff ff ff ? mov $0xffffffffffffffff,%rbx
0x000000000040100e 48 bb ff ff ff ff ff ff ff ef ? movabs $0xefffffffffffffff,%rbx
0x0000000000401018 48 bb ff ff ff ff ff ff ff ef ? movabs $0xefffffffffffffff,%rbx
0x0000000000401022 48 bb ff ff ff ff ff ff ff ff ? movabs $0xffffffffffffffff,%rbx
Why does this occur? For example, why does the mov/movq
add it as a four-byte value, 0x FF FF FF FF
? Whereas it tries to add it as an 8-byte immediate when the value is less than the 8-byte max. And the only way I'm only to get the full value is specifying movabsq
(without doing a trick like -1
or something). Or, is the assembly trying to be 'smart' and just seeing 'oh, this value is the same as 32-bit sign extended and we can save 4 bytes by doing Move imm32 sign extended to 64-bits to r/m64.
?
And if the answer is yes to that question, is part of the responsibility of the assembler to 'improve/reduce possible assembly inefficiencies'? Or does that fall to the compiler, and the assembler is merely supposed to take the assembly presented to it and put it into ELF (or whatever format the target is)?