2013-02-05 115 views
8

根據Wikipedia,英特爾ABI允許使用EAX,ECXEDX而不將它們保留在函數中。
我不確定「Intel ABI」是什麼意思。這是否意味着所有針對英特爾CPU的編譯器都強制執行/遵循這個規定?我在寫一個將從C代碼調用的彙編函數。我可以爲所有編譯器假設這一點嗎? (目前我只針對x86哪些寄存器在函數中可以安全使用(x86)

回答

6

英特爾ABI只是由英特爾設立的通話協議。

一般而言,參數的傳遞和寄存器函數調用期間保存或丟棄由函數的調用約定定義:

http://en.wikipedia.org/wiki/Calling_convention

尤其對於__cdecl,__stdcall和__fastcall你應該期望EAX,ECX和EDX被丟棄,並且你的函數應該保留其他的寄存器並且在EAX(或者EDX:EAX中返回64位)返回。

如果您不知道應該使用的調用約定是什麼,那麼您不應該在彙編中編寫代碼,因爲搞亂調用約定會導致應用程序中的可利用的錯誤。

在C中,默認調用約定通常是__cdecl,對於Windows導出的API,通常是__stdcall。

+0

我知道我需要使用的調用約定,並且只要參數和堆棧清理的順序知道它的含義。我不知道寄存器。你知道哪些編譯器遵循這個ABI嗎? MSVC/GCC? – baruch

+0

@baruch至少對於MSVC來說,調用約定是在函數原型中指定的。編譯器查看這個並做正確的事情。例如,WSARecv的def像這樣開始:int WSAAPI WSARecv。 WSAAPI解決了(通過幾個#defines)到__stdcall。 –

+0

@MarcSherman我知道調用約定,但是調用約定的寄存器保留部分? – baruch

1

它是英特爾應用程序二進制接口,一組規則指示什麼寄存器可用而不保存,如何將參數壓入堆棧,主叫方或被叫方是否清除堆棧幀等。

如果你知道規則正在遵循,那很好。我傾向於保存一切以防萬一(除了那些我用來返回信息的東西)。

但並非所有編譯器都強制執行,除非編譯器明確說明,否則您不應該這樣想。

相關問題