推动64位英特尔osx

时间:2012-11-12 20:51:00

标签: macos assembly x86-64

我想在堆栈上按64位地址,如下所示,

__asm("pushq $0x1122334455667788");

但是我收到了编译错误,我只能按照以下方式推送,

__asm("pushq $0x11223344");

有人可以帮助我理解我的错误吗?

我是集会的新手,所以如果我的问题听起来很愚蠢,请原谅。

4 个答案:

答案 0 :(得分:16)

x86-64有一些有趣的怪癖,即使你熟悉32位x86也不明显......

  1. 大多数指令只能采用32位立即数,如果在64位上下文中使用,则会将其符号扩展为64位。 (指令编码只存储32位。)

    这意味着您可以将pushq用于0x0 - 0x7fffffff范围内的即时值(即带有0位符号扩展的带正号的32位值)或{ {1}} - 0xffffffff80000000)(即负带符号的32位值,用1位进行符号扩展)。但是你不能使用这个范围之外的值(因为它们不能在指令编码中表示)。

  2. 0xffffffffffffffff是一种特殊情况:有一种编码需要一个完整的64位立即数操作数。因此丹尼尔的回答(这可能是你最好的选择)。

  3. 如果确实不想破坏寄存器,则可以使用较小值的多次推送。但是,推送两个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