推动64位英特尔osx

RLT*_*RLT 7 macos assembly x86-64

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

__asm("pushq $0x1122334455667788");
Run Code Online (Sandbox Code Playgroud)

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

__asm("pushq $0x11223344");
Run Code Online (Sandbox Code Playgroud)

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

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

Mat*_*ery 16

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

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

    这意味着您可以使用pushq范围内的immedate值0x0- 0x7fffffff(即带有0位符号扩展的带正号的32位值)或0xffffffff80000000- 0xffffffffffffffff)(即带有1位符号扩展的带负号的32位值) .但是您不能使用此范围之外的值(因为它们不能在指令编码中表示).

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

  3. 如果您真的不想破坏寄存器,可以使用较小值的多次推送.但是,推送两个32位值的显而易见的事情是行不通的.在64位世界中,push将使用64位操作数(如上面的第1点,如果它是立即数),或16位操作数,但不是32位操作数(甚至pushl %eax无效).所以你能做的最好是4个16位推送:

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

  • 对第3点的评论:`subq $ 8,%rsp; movl $ 0x55667788,(%rsp); movl $ 11223344,4(%rsp)`也可以. (7认同)
  • @Jester:pushl $ 0x55667788; movl $ 11223344,4(%rsp)? (3认同)

Dan*_*zar 9

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

movq $0x1122334455667788, %rax
pushq %rax
Run Code Online (Sandbox Code Playgroud)

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


Dav*_*rtz 5

没有单个指令能够获取64位立即值并将其推入堆栈.


Aki*_*nen 5

如何使用 rip 相对寻址

pushq my_const(%rip)
...
my_const: .quad 1122334455667788
Run Code Online (Sandbox Code Playgroud)