在阅读了这个堆栈溢出答案和这个文档之后,我仍然不明白和之间的movq
区别movabsq
。
我目前的理解是,在 中movabsq
,第一个操作数是 64 位立即操作数,而movq
符号扩展了 32 位立即操作数。从上面引用的第二个文件:
将立即数数据移动到 64 位寄存器可以使用
movq
指令来完成,该指令将对 32 位立即数进行符号扩展,或者movabsq
在需要完整的 64 位立即数时使用指令。
在第一个参考文献中,彼得说:
有趣的实验:
movq $0xFFFFFFFF, %rax
可能是不可编码的,因为它不能用符号扩展的 32 位立即数表示,并且需要 imm64 编码或%eax
目标编码。(编者注:这个错误的假设已在该答案的当前版本中得到修复)。
但是,当我组装/运行它时,它似乎工作正常:
.section .rodata
str:
.string "0x%lx\n"
.text
.globl main
main:
pushq %rbp
movq %rsp, %rbp
movl $str, %edi
movq $0xFFFFFFFF, %rsi
xorl %eax, %eax
call printf
xorl %eax, %eax
popq %rbp
ret
$ clang file.s -o file && ./file
打印0xffffffff
。(这同样适用于较大的值,例如,如果您添加几个额外的“F”)。movabsq
生成相同的输出。
Clang 是在推断我想要什么吗?movabsq
如果是的话,还有好处movq
吗?
我错过了什么?