我想在堆栈上按64位地址,如下所示,
__asm("pushq $0x1122334455667788");
但是我收到了编译错误,我只能按照以下方式推送,
__asm("pushq $0x11223344");
有人可以帮助我理解我的错误吗?
我是集会的新手,所以如果我的问题听起来很愚蠢,请原谅。
答案 0 :(得分:16)
x86-64有一些有趣的怪癖,即使你熟悉32位x86也不明显......
大多数指令只能采用32位立即数,如果在64位上下文中使用,则会将其符号扩展为64位。 (指令编码只存储32位。)
这意味着您可以将pushq
用于0x0
- 0x7fffffff
范围内的即时值(即带有0位符号扩展的带正号的32位值)或{ {1}} - 0xffffffff80000000
)(即负带符号的32位值,用1位进行符号扩展)。但是你不能使用这个范围之外的值(因为它们不能在指令编码中表示)。
0xffffffffffffffff
是一种特殊情况:有一种编码需要一个完整的64位立即数操作数。因此丹尼尔的回答(这可能是你最好的选择)。
如果确实不想破坏寄存器,则可以使用较小值的多次推送。但是,推送两个32位值的显而易见的事情是行不通的。在64位世界中,mov
将使用64位操作数(如上面的第1点,如果它是立即数),或16位操作数,但不是32位操作数(偶数{{1无效)。所以你能做的最好就是4次16位推送:
push
答案 1 :(得分:9)
你最好的选择是做这样的事情。
movq $0x1122334455667788, %rax
pushq %rax
将%rax
替换为您认为合适的任何其他64位寄存器。
答案 2 :(得分:5)
没有单个指令能够获取64位立即值并将其推送到堆栈中。
答案 3 :(得分:4)
来自how to use rip relative addressing
pushq my_const(%rip)
...
my_const: .quad 1122334455667788