2011-01-31 179 views
0

我正在通過Jonathan Barlett編寫的一本名爲「Programming from Ground Up」的書來研究x86彙編語言。最近我將系統更新到64位平臺,出現了彙編代碼語法問題,pushl指令更具體。我花了一些時間在x86_64 isa上尋找信息,但我認爲完成學習x86的基礎知識會更好。爲了做到這一點,我想知道是否有方法將較舊的語法組合成一個64位對象,或類似的東西。還是有重大的變化,這使得不可能? 我使用Ubuntu 10.10和GNU便攜式彙編程序。在64位平臺上運行的32位彙編代碼

無論如何。如果您在x86_64上指出一本好書或任何信息來源,或者它與他的前任之間存在差異,那麼這樣做會很好。

編輯:謝謝!我得到了我需要的東西。兩個答案都非常有用。別擔心,我期待着放開X86。

回答

3

Linux使用指定的x86_64 ABI here。您可以做的最好的事情是讀取與您所在地區最相關的ABI位。下面是幾個想到的:

  • 與x86不同,在x86_64上只有一個調用約定;如果您再次指出微軟Windows完全不同的事實,那麼兩者是相同的。
  • 在x86中,函數的參數通常在堆棧上傳遞。在x86_64中,前幾部分是整數類型的寄存器rdi,rsi,rdx,rcx,r8r9
  • 內存地址類型都是QWORD所以如果你使用全寄存器(r10等)與AT & T語法,你需要movqaddq

現在,x86_64設計的一部分是它與x86向後兼容,即如果操作系統設置正確,則可以執行x86代碼。所以,舉例來說,沒有什麼不對的,例如:

nasm -felf32 myprog.asm 
gcc -o myprog -m32 myprog.o 

但是,要知道;越是開始依賴其他可用代碼,就越需要所有內容的32位副本。請注意,這基本上是在32位模式下完全使用代碼,完成調用約定和一切。總之,它也應該在32位機器上執行。正如Jerry所說(+1),無法在64位模式下使用32位約定編譯32位程序集。你必須遵守64位ABI。

當然,除此之外,你可以在你的例程中免費使用像eax這樣的寄存器,只要注意它會影響整個rax,或者說是影響eax的一半。

2

在彙編語言級別的32位和64位操作之間有足夠的差異,您幾乎可以肯定不會試圖將32位代碼視爲64位代碼,並希望最好的,或類似的東西。

當你在編寫彙編語言時「接近金屬」時,它通常是有原因的 - 你一般不會/不會/不會欣賞彙編器試圖猜測你的東西真正的意圖,並修改你的代碼以適應。在某些情況下,你會失去優點(例如速度),而在另外一些情況下,它可能會破壞你完全正在做的事情(例如,如果/如果它的符號擴展到應該實際上已經被零擴展的64位)。