x86上為什麼C語言呼叫乙個函式要先把引數壓棧,之後才是返回位址?

時間 2021-05-07 04:58:44

1樓:Thomson

把壓棧和跳轉分開,讓編譯器甚至程式設計師計算返回位址,即使可以,效能安全性也是很大的問題。除了把返回位址放在函式棧幀的頂部,也可以給函式的引數區域大小預留本函式或者裡面可能的tail call中最大值,就不用擔心引數放不下了。

tail call對x86和命令式語言幫助不大吧,反正有迴圈,所以也沒見到與發雜的tail call優化。

2樓:airtrack

C語言支援可變引數函式,因此被呼叫函式不知道傳遞的引數個數有多少,引數傳遞的時候是從右向左依次壓棧,最後call指令會把返回位址壓棧並跳轉到被呼叫的函式。

如果先壓返回位址入棧,那被呼叫函式就需要知道引數個數有多少,這樣才能找到返回位址。可變引數函式的特性決定了C語言的被呼叫的函式不知道引數有多少,也決定了引數需要從右向左依次入棧,返回位址最後入棧,並且函式呼叫方需要負責清理傳遞引數的棧。

只回答了問題頭,關於尾遞迴請參考其它答案,題主補充的方法也是乙個不錯的方案。

有沒有可能設計乙個及有x86架構指令的又有ARM架構用的指令的處理器呢?

比較 常規 的想法是用轉譯器,比如Rosseta2或者Exagear。Rosseta2可以跑出單核80 全核60 的效率。對比4核X86 4核ARM和8核ARM,很容易想到,如果不要求X86和ARM都追求極限效能或者X86和ARM負載的比例非常穩定,否則轉譯比較合算。聽人介紹過另一種有趣的想法 處理...

乙個C語言問題,迴圈之後引數值為什麼發生變化了?

李展發 藏雲 讓老夫試試終結這個問題吧。首先你要了解對於函式內宣告的變數 非靜態變數 它是儲存在棧中的。進入函式後首先壓入棧的變數就是你的引數。也就是N。然後再壓入你宣告的第乙個變數,也即是陣列bucketArray.關鍵就在這裡,N跟BUCKETARRAY這兩個變數是放在一起的。而你在FOR迴圈中...

c語言中為什麼一維陣列名可以賦值給乙個普通的指標,二維陣列名卻不可以賦值給乙個指向指標的指標?

yihonge 可以,不過有編譯 警告罷了。警告是在提示你可能存在潛在問題,而不是不能這樣做,你完全可以強制轉換。編譯器行為罷了,就像char s hello 其實字串常量應該是const char 但是C編譯器偏偏沒有警告,C 編譯器就會有警告,因為C 的型別檢查比C嚴格。至於為什麼有警告 拋個問...