當我們在函數原型中放入_stdcall
(調用者不需要清除堆棧)時,是由編譯器還是鏈接器來處理?調用由編譯器或鏈接器處理的約定嗎?
回答
調用約定會影響代碼生成,因此編譯器會處理它。鏈接器不需要知道這一點。
調用約定是如何調用函數(參數編制具體的機器代碼,並清理CTACK)和鏈接涉及這功能(功能在其地址)來調用。
因此,通常編譯器會生成正確的代碼,併爲確切的函數地址留下「佔位符」,然後鏈接器會將實際地址放在那裏。也就是說,所謂的link-time code generation這兩個都是由鏈接器完成的。
函數地址與調用約定無關,那就是說,調用約定是由編譯器完成的,對嗎? – kern 2011-05-05 14:29:07
@kern:是的,除非涉及LTCG。 – sharptooth 2011-05-05 14:43:00
在某些系統上,目標文件只是一堆數據,符號和補丁點。目標文件將告訴鏈接器鏈接代碼的第574字節應該被修補以包含符號Foo和Bar之間差別的MSB,並且鏈接器將這樣做,但鏈接器沒有超出要執行的計算。
在其他一些系統上,鏈接器可能更多地涉及代碼生成。例如,一些ARM處理器可以運行使用16位或32位指令集編碼的代碼。某些類型的代碼只能使用32位指令集有效運行;一些將充分運行,但使用16位集更加緊湊。 ARM鏈接器知道使用每個指令集編寫哪些例程,如果使用一個指令集編寫的代碼嘗試調用使用另一個指令集編寫的函數,鏈接器將生成一個名爲「veneer」的包裝器方法,並具有第一個函數調用。單板將執行調用其他方法所需的操作。即使單板是「代碼」,它完全由鏈接器生成。
編譯器和鏈接器之間確實沒有固定的分工。我見過一些系統,「編譯器」將程序轉換爲「中間」形式,並且鏈接器執行所有真正的代碼生成,並根據事物在內存中的位置進行優化。如前所述,還有一些鏈接器只是一個「修補處理器」。可能在這兩個極端之間的每一個可想象的分工可能都存在於某個系統的某個地方。
- 1. AVX寄存器如何由通用調用約定來處理?
- 2. 瞭解C#編譯器如何處理鏈接linq方法
- 3. OpenCL編譯器預處理定義?
- 4. C預處理器與C編譯器
- 5. 鏈接器或加載器如何處理共享庫的斷開軟鏈接?
- 6. 鏈接器錯誤,使用g ++鏈接到由gcc編譯的庫,未定義的引用該函數
- 7. Borland C++編譯器中的鏈接DLL
- 8. 棧是由編譯器或OS /建築
- 9. 用C++編譯器的歐拉 - 編譯器不會在100 x 101後處理
- 10. 從Windows批處理文件調用Intel編譯器
- 11. C++編譯器(或鏈接器?)如何知道如何處理cpp和頭文件類?
- 12. C++遺傳編程:調用鏈接器/編譯器,執行編譯後的程序和管道輸入/輸出
- 13. 混合調用約定編譯錯誤
- 14. redhat:netbeans:g ++:適用於鏈接器的編譯器選項
- 15. Scrapy CrawlSpider - 不能按照特定的鏈接或自定義的處理器
- 16. 編譯器如何處理`(c = getchar())!= EOF`?
- 17. C#編譯器:預處理只有
- 18. 編譯器處理一個委託
- 19. JIT編譯器和異常處理
- 20. 編譯器不處理freertos #define代碼
- 21. C++「編譯器」與預處理
- 22. 編譯器如何處理const函數?
- 23. 編譯器如何處理註釋?
- 24. 轉到代碼編譯鏈接器錯誤。我可以手動鏈接嗎?
- 25. 與UI路由器鏈接的鏈接
- 26. clang編譯器中的標誌是什麼以定義要由預處理器使用的宏?
- 27. 單處理器或多處理器
- 28. 修身路由器鏈接調用控制器沒有硬編碼在地圖
- 29. 如何將編譯器鏈接到編輯器
- 30. 編譯器/彙編程序如何理解處理器內核寄存器?
希望這些名稱的格式不同,以致調用約定中的不一致將導致鏈接時發生錯誤。 – 2011-05-05 14:57:19
@James在導入DLL時,您經常需要指定調用約定,並且它們通常以無損的方式命名。 – 2011-05-05 15:01:03
Heffeman如果該函數是'extern「C」',顯然,調用約定不能被修改爲名稱。如果函數是「extern」C++「',那麼沒有理由不這樣做。 – 2011-05-05 15:30:16