在x86-32彙編中,參數存儲在堆棧中,但存儲在寄存器中的參數是x86-64。這是什麼原因?爲什麼參數存儲在寄存器中而不是x86-64彙編中的堆棧上?
回答
訪問CPU寄存器比訪問RAM更快(很多)。
由於64位CPU有更多的通用寄存器(與64位無關,只是因爲它們更新/更大),因此使用它們是有意義的。
另請參閱:https://en.wikipedia.org/wiki/Calling_convention –
有人應該將x64添加到該Wikipedia文章... – Thilo
它在那裏,在一篇鏈接的文章中:https://en.wikipedia.org/wiki/X86_calling_conventions –
存儲/重新加載往返需要花費大約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向量的規則,而不是在堆棧中)。
有關調用約定文檔的鏈接,請參閱x86標記wiki,以及有關存儲轉發延遲的更多詳細信息的性能鏈接。
- 1. ARM彙編,POP堆棧和存儲在寄存器
- 2. 從寄存器讀取參數而不是從堆棧中讀取參數
- 3. 爲什麼值被存儲在寄存器0x605040c,而不是12?
- 4. 爲什麼在FreeBSD中重置堆棧指針寄存器?
- 5. 爲什麼編譯器將變量存儲在寄存器中?
- 6. 爲什麼內存和寄存器不允許遞歸,而堆棧呢?
- 7. 爲什麼我們將s寄存器中的值存入堆棧而不是在函數中移動到新的寄存器?
- 8. ARM彙編中的Raspberry Pi寄存器r0-r4中是否存在嚴格的函數參數存儲序列?
- 9. XOR寄存器,寄存器(彙編)
- 10. 如何將堆棧指針寄存器中的值存儲到存儲器(8085)?
- 11. 將函數的參數傳遞給堆棧還是寄存器?
- 12. 爲什麼我的const數組存儲在堆棧而不是文本部分?
- 13. 堆棧上EBP寄存器的大小?
- 14. 爲什麼%ebx%esi%edi%ebp這些寄存器在x86彙編中的線程切換時被壓入堆棧
- 15. 導出寄存器對堆棧的性能影響是什麼?
- 16. 線程堆棧上存儲了什麼?
- 17. 我應該將sockaddr與push一起存儲在堆棧中還是存儲在syscall connect的寄存器中?
- 18. 這些寄存器爲什麼被推入堆棧?
- 19. 彙編寄存器在C代碼中引用了什麼?
- 20. 爲什麼12在這個80x86彙編代碼中存儲在寄存器EAX中?
- 21. 彙編和寄存器
- 22. 堆棧上的C++存儲保存在堆棧上
- 23. 爲什麼存儲在寄存器中的數據有內存地址?
- 24. 68k彙編:CPU是否在中斷時存儲狀態寄存器?
- 25. Python是否將函數參數加載到寄存器中,還是將它們保存在堆棧中?
- 26. 裝配 - 寄存器被推入堆棧後的參數更改
- 27. PIC彙編 - 通過寄存器作爲參數
- 28. 什麼數據將被存儲在堆棧中在C#
- 29. 爲什麼value-types存儲在堆棧上?
- 30. 爲什麼堆棧彈出(而不是+
由於歷史原因,IA64不是x64。 – harold
這是不好的概括,在x86下參數總是在堆棧上,永遠不會在寄存器中。這一切都取決於調用約定,傳遞的數據類型和參數的數量。 –
1)因爲它可以2)更多註冊3)速度 –