我想把一个64位地址压入堆栈,如下所示:
__asm("pushq $0x1122334455667788");
字符串但我得到编译错误,我只能在下面的方式推,
__asm("pushq $0x11223344");
型有人能帮我理解我的错误吗?我是新来的,所以如果我的问题听起来很愚蠢,请原谅。
jaql4c8m1#
x86-64有一些有趣的怪癖,即使你熟悉32位x86,这些怪癖也不明显。1.大多数指令只能采用32位立即值,如果在64位上下文中使用,则将其符号扩展为64位。(指令编码仅存储32位。)这意味着您可以将pushq用于0x0-0x7fffffff范围内的immedate值(即正负号的32位值,其用0位进行符号扩展)或0xffffffff80000000-0xffffffffffffffff)(即负符号的32位值,其用1位进行符号扩展)。但是您不能使用此范围之外的值(因为它们不能在指令编码中表示)。
pushq
0x0
0x7fffffff
0xffffffff80000000
0xffffffffffffffff
mov
push
pushl %eax
pushw $0x1122; pushw $0x3344; pushw $0x5566; pushw $0x7788
ffscu2ro2#
你最好的选择就是这样做。
movq $0x1122334455667788, %rax pushq %rax
字符串将%rax替换为您认为合适的任何其他64位寄存器。
%rax
t3irkdon3#
没有一条指令能够接受一个64位的立即值并将其压入堆栈。
ds97pgxw4#
从how to use rip relative addressing
pushq my_const(%rip) ... my_const: .quad 1122334455667788
字符串
4条答案
按热度按时间jaql4c8m1#
x86-64有一些有趣的怪癖,即使你熟悉32位x86,这些怪癖也不明显。
1.大多数指令只能采用32位立即值,如果在64位上下文中使用,则将其符号扩展为64位。(指令编码仅存储32位。)
这意味着您可以将
pushq
用于0x0
-0x7fffffff
范围内的immedate值(即正负号的32位值,其用0位进行符号扩展)或0xffffffff80000000
-0xffffffffffffffff
)(即负符号的32位值,其用1位进行符号扩展)。但是您不能使用此范围之外的值(因为它们不能在指令编码中表示)。mov
是一个特例:存在采用全64位立即操作数的编码。因此,丹尼尔的答案(这可能是你最好的选择)。1.如果你真的不想破坏一个寄存器,你可以使用多次推送较小的值。但是,推送两个32位值的明显做法是行不通的。在64位世界中,
push
将使用64位操作数(如果是立即常量,则受上面第1点的限制)或16位操作数,但不能使用32位操作数(即使pushl %eax
也无效)。因此,您最多可以执行4次16位推送:pushw $0x1122; pushw $0x3344; pushw $0x5566; pushw $0x7788
ffscu2ro2#
你最好的选择就是这样做。
字符串
将
%rax
替换为您认为合适的任何其他64位寄存器。t3irkdon3#
没有一条指令能够接受一个64位的立即值并将其压入堆栈。
ds97pgxw4#
从how to use rip relative addressing
字符串