簡體   English   中英

有關通話慣例的問題

[英]Questions about call convention

我記得很久以前,當我使用Turbo C時,我不需要關心函數的調用約定,我使用或定義的每個函數都采用C調用約定的形式。

但是,在轉到Windows平台之后,我發現有很多調用約定專用字符,例如:

WINAPI,STDCALL,__ cdecl ...

這是編譯器發展的結果嗎?

不,它是Windows API的簡單或大部分歷史遺留物。 Windows之外的大多數系統通常不會使用不同的調用約定(例外:syscalls和內核模式)。

不同的調用約定具有不同的特征,有時所使用的語言或API可能需要不同的功能。 檢查文章為不同的調用約定的概述,以及哪些API通常使用它們。

WINAPI,STDCALL等不是調用約定,它們是定義調用約定的宏。 實際上,只有大約兩種或三種實際類型。 宏的原因是為了向后兼容。

不,這是Microsoft愚蠢的結果。 沒有理由在C環境中曾經使用過/混合使用不同的調用約定。

調用約定非常重要,但是您幾乎不必考慮。

當以其他語言(例如,pascal等)編寫的其他操作系統或對象\\庫為目標時,它就變得有意義。

它確定哪些參數以及如何將參數(由調用方)壓入堆棧,以及由誰負責在被調用函數返回時從堆棧中彈出這些參數。

由於C \\ C ++支持可變參數列表,因此調用程序的任務是彈出堆棧(因為被調用方不知道給它提供了多少個參數)。

因此,這將導致生成大量代碼(每個函數調用都使用堆棧彈出代碼擴展)。

但是,本機不允許可變參數列表的語言可以承擔通過調用函數(他們始終知道如何調用)來彈出堆棧的負擔。 這樣僅導致一個堆棧彈出代碼(在被調用方的末尾),因此生成的代碼更少。

此外,語言還可以選擇如何將HOW參數壓入堆棧。 它可以選擇以與調用中寫入順序相同的順序來推送參數(首先是第一個參數,最后是最后一個參數),也可以選擇先推送最后一個參數,最后推送第一個參數(就像C \\ C ++一樣)。 后者允許“輕松”實現可變參數列表。

如果不使用可變參數列表,則可以選擇其他默認調用約定(例如PASCAL)。 但是,這意味着將使用您選擇的約定來處理未指定調用約定的每個函數。 如果聲明與其實現不同,則可能會得到未解決的外部錯誤(最好),嚴重的運行時錯誤或(最壞的)錯誤計算。

舉一個實際的例子:我是一家移動計算機制造商的程序員。 由於MSVC會生成大型對象,因此他們使用了特殊的(有限的)編譯器來生成緊湊的代碼(移動計算機的內存非常有限)。

我建議將c調用約定更改為pascal調用約定,並進行其他一些小的更改。 從那時起,他們可以使用更復雜的編譯器(MSVC)並做更多的事情。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM