8
根據維基:混淆函數調用棧
呼叫者將返回地址壓入堆棧,和被叫 子程序中,當它完成,彈出返回地址斷呼叫 堆棧和轉移控制到那個地址。
產品圖來自維基:
我不太明白這一點。 說我有一個C程序如下:
#include <stdio.h>
int foo(int x)
{
return x+1;
}
void spam()
{
int a = 1; //local variable
int b = foo(a); //subroutine called
int c = b; //local variable
}
int main()
{
spam();
return 0;
}
而且我覺得調用堆棧應該是這樣的一個圖如下:
<None> means none local variables or params
_| parameters for foo() <int x> |_
top | local of spam() <int c> |
^ | return address of foo() |<---foo() called, when finishes, return here?
| | local of spam() <int b> |
bot | local of spam() <int a> |
_| parameters for spam() <None> |_
| locals of main() <None> |
| return address of spam() |<---spam() called, when finishes, return here?
| parameters for main() <None> |
問:
根據所引用的話來自Wiki,
被調用的子程序,當它完成時,彈出返回地址off 調用堆棧並將控制權轉交給該地址。
1.我的繪圖是否正確?
2.如果是正確的,那麼當FOO()完成後,它會
中彈出調用棧和傳輸控制的返回地址 ,解決
,但如何它可以彈出返回地址嗎? 因爲當foo完成時,當前堆棧指針指向垃圾郵件的本地, 對不對?
UPDATE:
什麼,如果在main()看起來是這樣的:
int main()
{
spam();
foo();
}
然後調用堆棧應該是什麼樣子?
是的,先生,我同意你的意見。但在「垃圾郵件()」中,「foo()」在「」之前被調用,對吧?那麼我應該把「int c」放在調用堆棧中?還低於返回地址? –
Alcott
本地變量的堆棧保留通常在函數執行開始時一勞永逸地完成。所以a,b和c都是在foo被調用之前保留的棧空間。 –
明白了,先生。如果我在main中調用spam()和foo()會怎麼樣(請參閱UPDATE)?調用堆棧的外觀如何?你的意思是一個函數的堆棧幀的大小是它的本地大小的總和? – Alcott