推动 64 位 intel osx

问题描述 投票:0回答:4

我想将 64 位地址压入堆栈,如下所示,

__asm("pushq $0x1122334455667788");

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

__asm("pushq $0x11223344");

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

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

macos assembly x86-64
4个回答
18
投票

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

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

    这意味着您可以将

    pushq
    用于
    0x0
    -
    0x7fffffff
    范围内的立即值(即用 0 位进行符号扩展的正符号 32 位值)或
    0xffffffff80000000
    -
    0xffffffffffffffff
    )(即带负号的 32 位值,其符号扩展为 1 位)。但您不能使用此范围之外的值(因为它们无法在指令编码中表示)。

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

  3. 如果您真的不想损坏寄存器,您可以使用多次推送较小的值。然而,推入两个 32 位值的明显做法是行不通的。在 64 位世界中,

    push
    将适用于 64 位操作数(如果是立即数,则受上述第 1 点限制)或 16 位操作数,但不适用于 32 位操作数(甚至
    pushl %eax
    也不是有效的)。所以你能做的最好的事情就是 4 次 16 位推送:

    pushw $0x1122; pushw $0x3344; pushw $0x5566; pushw $0x7788


9
投票

你最好的选择就是做这样的事情。

movq $0x1122334455667788, %rax
pushq %rax

%rax
替换为您认为合适的任何其他 64 位寄存器。


5
投票

没有任何一条指令能够获取 64 位立即值并将其推入堆栈。


5
投票

来自如何使用rip相对寻址

pushq my_const(%rip)
...
my_const: .quad 1122334455667788
© www.soinside.com 2019 - 2024. All rights reserved.