在NASM/Intel语法中,mov r64, 0x...
根据常量选择a MOV encoding。有四种可选择的立即操作数:
- 5字节
mov r32, imm32
。 (zero-extended to fill the 64-bit register like always)。 AT & T:mov
/movl
- 6字节
mov r/m32, imm32
。仅对内存目标有用。 AT & T: mov
/movl
- 7字节
mov r/m64, sign-extended-imm32
。 可以将8个字节存储到内存,或将64位寄存器设置为负值。 AT & T:mov
/movq
- 10字节
mov r64, imm64
。 (这是REX.W = 1版本相同的操作码作为mov r32, imm32
的)AT & T:movabs
(字节计数仅用于寄存器的目的地,或寻址不需要一个SIB字节或DISP8模式/ disp32对比:只是操作码+ MODR/M + IMM32)
在气体与AT & T语法
movabsq
意味着机器代码编码将包含一个64位值:或者是一个立即数,或者是一个绝对内存地址。没有movabsq
,它不能。
使用AT & T语法在此what's new in x86-64 guide中提到了其中的一些。除非你想要一个更长的指令用于对齐的目的(而不是稍后用NOP填充),否则不要使用mov $1, %rax
。使用mov $1, %eax
获取5字节的格式。
有趣的实验:movq $0xFFFFFFFF, %rax
可能不是encodeable,因为它不是一个符号扩展 32位立即所能表述的,并且需要无论是imm64编码或%eax
目的地编码。
movabs
与直接来源永远是imm64形式。 (movabs
也可以是以64位绝对地址和RAX作为源或目标的MOV编码:如REX.W + A3
MOV moffs64, RAX
)。
一些Intel的语法汇编器(但不是GAS)将优化的32位常数到5字节mov r32, imm32
(NASM做到这一点),而其他(如YASM)将使用7字节mov r/m64, sign-extended-imm32
。他们都选择imm64编码只用于大常量,而不必使用特殊的助记符。
我不知道怎样才能在64位立即值转移到内存中。
这是一个单独的问题,答案是:你不能。 insn ref manual entry for MOV说明了这一点:具有imm64立即数操作数的唯一形式只有一个寄存器目的地,而不是r/m64。
如果您的值适合符号扩展的32位立即数,则movq $0x123456, 32(%rdi)
将执行一个8字节的存储至存储器。限制是它只是一个imm32。
你必须将它移动到一个寄存器然后移动到内存。这里的所有都是它的。 –