2016-08-15 66 views
1

在x86-32彙編中,參數存儲在堆棧中,但存儲在寄存器中的參數是x86-64。這是什麼原因?爲什麼參數存儲在寄存器中而不是x86-64彙編中的堆棧上?

+2

由於歷史原因,IA64不是x64。 – harold

+1

這是不好的概括,在x86下參數總是在堆棧上,永遠不會在寄存器中。這一切都取決於調用約定,傳遞的數據類型和參數的數量。 –

+0

1)因爲它可以2)更多註冊3)速度 –

回答

8

訪問CPU寄存器比訪問RAM更快(很多)。

由於64位CPU有更多的通用寄存器(與64位無關,只是因爲它們更新/更大),因此使用它們是有意義的。

+0

另請參閱:https://en.wikipedia.org/wiki/Calling_convention –

+0

有人應該將x64添加到該Wikipedia文章... – Thilo

+0

它在那裏,在一篇鏈接的文章中:https://en.wikipedia.org/wiki/X86_calling_conventions –

5

存儲/重新加載往返需要花費大約6個週期的存儲轉發延遲,因此現代調用約定使用更高效的設計。這在某些情況下也可以保存指令,因爲調用者可以在寄存器中生成arg而不是推送它。 (並且不必在返回後彈出堆棧)。

因爲x86-64是一種新模式,所以它沒有任何向後兼容的要求,所以可以設計一個沒有傳統行李的全新ABI。請參閱this answer瞭解x86-64 SysV調用約定是如何設計的,以及爲什麼它比Windows x86-64調用約定更有效。 (紅色區域,更多arg通過寄存器。)它比windows約定更復雜,尤其是可變參數函數。


傳遞在寄存器中的第一對ARGS是在32位代碼更高效的,太多,但引入新的調用約定斷開與庫向後compat的。

即使如此,MS也是這樣做的,即使在32位模式下,MS也使用兩個調用破壞寄存器(ecx和edx)來傳遞參數。這些調用約定的64位版本使用更多的arg傳遞寄存器,因爲x86-64具有更多的GP寄存器。

Unix/Linux沒有試圖引入32位新的調用約定,基本上放棄了32位作爲過時的遺留代碼,而這些代碼被阻滯得很慢。 (儘管32位SysV ABI擴展了向量寄存器中傳遞/返回16B SSE和32B AVX向量的規則,而不是在堆棧中)。

有關調用約定文檔的鏈接,請參閱標記wiki,以及有關存儲轉發延遲的更多詳細信息的性能鏈接。

相關問題