2012-11-12 81 views
7

我想推如下堆疊64位地址,推的64位英特爾OSX

__asm("pushq $0x1122334455667788"); 

,但我得到的編譯錯誤,我只能在下列方式推動,

__asm("pushq $0x11223344"); 

人幫我理解我的錯誤?

我是新裝配,所以請原諒我的問題聽起來很愚蠢。

回答

16

X86-64有一些有趣的怪癖,這是不是就算你熟悉32位x86明顯...

  1. 大多數指令只能取32位立即值,如果在64位上下文中使用,則將其擴展爲64位。 (指令編碼只存儲32位)

    這意味着可以在0x0範圍使用pushq爲immedate值 - 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

+7

評論指向#3:'SUBQ $ 8%RSP; movl $ 0x55667788,(%rsp); movl $ 11223344,4(%rsp)'也可以。 – Jester

+3

@Jester:pushl $ 0x55667788; movl $ 11223344,4(%rsp)? –

5

沒有一個指令能夠取得64位立即數值並將其推入堆棧。

9

你最好打賭就是做這樣的事情。

movq $0x1122334455667788, %rax 
pushq %rax 

%rax替換爲您認爲合適的任何其他64位寄存器。