我想推如下堆疊64位地址,推的64位英特爾OSX
__asm("pushq $0x1122334455667788");
,但我得到的編譯錯誤,我只能在下列方式推動,
__asm("pushq $0x11223344");
能
人幫我理解我的錯誤?
我是新裝配,所以請原諒我的問題聽起來很愚蠢。
我想推如下堆疊64位地址,推的64位英特爾OSX
__asm("pushq $0x1122334455667788");
,但我得到的編譯錯誤,我只能在下列方式推動,
__asm("pushq $0x11223344");
能
人幫我理解我的錯誤?
我是新裝配,所以請原諒我的問題聽起來很愚蠢。
X86-64有一些有趣的怪癖,這是不是就算你熟悉32位x86明顯...
大多數指令只能取32位立即值,如果在64位上下文中使用,則將其擴展爲64位。 (指令編碼只存儲32位)
這意味着可以在0x0
範圍使用pushq
爲immedate值 - 0x7fffffff
(即正簽署其是符號擴展與0位的32位的值)或0xffffffff80000000
- 0xffffffffffffffff
)(即帶符號擴展1位的負符號32位值)。但是你不能使用這個範圍以外的值(因爲它們不能用指令編碼表示)。
mov
是一個特殊情況:有一個編碼需要一個完整的64位立即數操作數。因此丹尼爾的回答(這可能是你最好的選擇)。
如果你真的不想破壞寄存器,你可以使用多次推小的值。但是,推送兩個32位值的明顯事情將不起作用。在64位的世界中,push
將使用64位操作數(受上述第1點的限制,如果它是立即數)或16位操作數,但不是32位操作數(即使pushl %eax
無效)。所以,你能做的最好的是4個16位推:
pushw $0x1122; pushw $0x3344; pushw $0x5566; pushw $0x7788
沒有一個指令能夠取得64位立即數值並將其推入堆棧。
你最好打賭就是做這樣的事情。
movq $0x1122334455667788, %rax
pushq %rax
將%rax
替換爲您認爲合適的任何其他64位寄存器。
從how to use rip relative addressing
pushq my_const(%rip)
...
my_const: .quad 1122334455667788
評論指向#3:'SUBQ $ 8%RSP; movl $ 0x55667788,(%rsp); movl $ 11223344,4(%rsp)'也可以。 – Jester
@Jester:pushl $ 0x55667788; movl $ 11223344,4(%rsp)? –