assembly 在64位intel osx上推送

e5njpo68  于 2023-08-06  发布在  其他
关注(0)|答案(4)|浏览(89)

我想把一个64位地址压入堆栈,如下所示:

__asm("pushq $0x1122334455667788");

字符串
但我得到编译错误,我只能在下面的方式推,

__asm("pushq $0x11223344");


有人能帮我理解我的错误吗?
我是新来的,所以如果我的问题听起来很愚蠢,请原谅。

jaql4c8m

jaql4c8m1#

x86-64有一些有趣的怪癖,即使你熟悉32位x86,这些怪癖也不明显。
1.大多数指令只能采用32位立即值,如果在64位上下文中使用,则将其符号扩展为64位。(指令编码仅存储32位。)
这意味着您可以将pushq用于0x0-0x7fffffff范围内的immedate值(即正负号的32位值,其用0位进行符号扩展)或0xffffffff80000000-0xffffffffffffffff)(即负符号的32位值,其用1位进行符号扩展)。但是您不能使用此范围之外的值(因为它们不能在指令编码中表示)。

  1. mov是一个特例:存在采用全64位立即操作数的编码。因此,丹尼尔的答案(这可能是你最好的选择)。
    1.如果你真的不想破坏一个寄存器,你可以使用多次推送较小的值。但是,推送两个32位值的明显做法是行不通的。在64位世界中,push将使用64位操作数(如果是立即常量,则受上面第1点的限制)或16位操作数,但不能使用32位操作数(即使pushl %eax也无效)。因此,您最多可以执行4次16位推送:
    pushw $0x1122; pushw $0x3344; pushw $0x5566; pushw $0x7788
ffscu2ro

ffscu2ro2#

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

movq $0x1122334455667788, %rax
pushq %rax

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

t3irkdon

t3irkdon3#

没有一条指令能够接受一个64位的立即值并将其压入堆栈。

ds97pgxw

ds97pgxw4#

how to use rip relative addressing

pushq my_const(%rip)
...
my_const: .quad 1122334455667788

字符串

相关问题