局部變量存儲在棧里?


比如:
int main()
{
    int i =0;
    i++;
}
只知道局部變量,存放在棧里,過了作用域就自動銷毀,但是棧是push pop存放的吧,肯定不能把ipush了吧,我感覺應該是把cpu的寄存器push進去,用完后在pop,保護cpu的寄存器,可是如果局部變量太多,得push多少寄存器啊,有點糊塗

而且這個棧是存放cpu的寄存器的那個棧嗎?

16 个解决方案

#1


這個棧是內存的,寄存器有寄存器變量用register聲明,而且寄存器變量不能用&取址符。

#2


不是說把i  push了,而是說調整下棧幀指針給i一個空間。

#3


棧、堆

#4


C++五大存儲區,int i =0;這種局部變量存儲在棧中。在內存中給i分配了空間以后,調整下棧頂指針寄存器EBP(ps:好像是這個,記不清了),而不是將i push到系統棧中。

#5


c可以嵌套調用函數,每當調用一個新函數時,在棧上為其分配一段空間,村儲其所用的變量,次空間由一個新的幀指針開始,向下伸展,退出時銷毀幀指針,幀指針之上是返回地址,段應該類似 

#6


VC調試時按Alt+8,TC或BC用TD調試,打開匯編窗口看每句C對應的匯編不就啥都明白了嗎。
(Linux或Unix下應該也可以在用GDB調試時,看每句C對應的匯編。)

計算機組成原理→DOS命令→匯編語言→C語言(不包括C++)、代碼書寫規范→數據結構、編譯原理、操作系統→計算機網絡、數據庫原理、正則表達式→其它語言(包括C++)、架構……

#7


是在棧里,但有可能被優化為寄存器存放

#8


還有可能直接把
  int i =0;
  i++;
這兩句沒意義的代碼去掉了

#9


意思是這個函數的棧跟保護現場的棧不是一個棧?保護現場的比如push 當前寄存器的狀態,和這個不是一回事吧
引用 2 樓 pengzhixi 的回復:
不是說把i push了,而是說調整下棧幀指針給i一個空間。

#10


意思是這個函數的棧跟保護現場的棧不是一個棧?保護現場的比如push 當前寄存器的狀態,和這個不是一回事吧

引用 4 樓 wuyan6293 的回復:
C++五大存儲區,int i =0;這種局部變量存儲在棧中。在內存中給i分配了空間以后,調整下棧頂指針寄存器EBP(ps:好像是這個,記不清了),而不是將i push到系統棧中。

#11



返回的地址貌似不是存在這個棧里吧,要不不就亂了,我感覺應該是在那個保護現場的棧里,不知道理解的對不對
引用 5 樓 anyidan 的回復:
c可以嵌套調用函數,每當調用一個新函數時,在棧上為其分配一段空間,村儲其所用的變量,次空間由一個新的幀指針開始,向下伸展,退出時銷毀幀指針,幀指針之上是返回地址,段應該類似

#12


進程空間大約是這樣分布的:
|----------------------------|高地址
| 命令行參數和環境變量       |
|----------------------------|
|  棧。。。                  |
|                            |
|                            |
|  堆。。。                  |
|----------------------------|
| 未初始化的數據             |
|----------------------------|
| 初始化的數據(樓主的I)    |
|----------------------------|
| 代碼                       |
|----------------------------|地地址
首先 樓主舉的例子是在main函數中聲明的以初始化的變量 不是局部變量 而會存儲在一個交.data的區域 在進程空間的位置如圖
然后說局部變量 因為棧是從高低值向低地址生長的 就是說如果a()函數調用了b()函數 那么a()的相關信息會在b()的上面 這樣呢 如果你在a()里面聲明了好多好多的局部變量 他們也會依次向下生長保存在棧里面 等到b()執行結束時 會直接返回到a()的地址 由於a()的地址很高很高 就把b()里面的變量覆蓋掉了
如圖
|--------------------|
|a()相關信息等等。。  |b()函數返回地址
 |---------------------|
 | b()相關信息等到。。 |
 | b()定義的變量們     |b()函數中變量的地址
 | ...                 |
 |---------------------|          
然后你說寄存器會不會夠用。。是這樣的 寄存器讀寫當然快 但是寄存器是很少的 如果函數只有一個變量 那么編譯器會自動把這個變量放在寄存器里面 但是如果變量多的話 當然就只有用的時候再放在編譯器里面拉 但是棧空間是很大第 所以不用擔心局部變量太多棧裝不下

#13


返回地址也是在這個棧里面 比如a()調用b() 那么不僅需要保存傳遞的實參 還需要記錄返回地址
這些信息是記錄在一個結構體的 操作系統認識這個結構體 因此不會混亂

#14


貌似這個棧跟push pop不掛鈎啊,你說a b那個例子,b執行完后返回后,棧頂指針自動移動到a的棧頂,是這樣的吧,可是他如何知道移動到哪了呢


引用 12 樓 padmepingouin 的回復:
進程空間大約是這樣分布的:
|----------------------------|高地址
| 命令行參數和環境變量       |
|----------------------------|
|  棧。。。                  |
|                            |
|                            |
|  ……

#15


實際上操作系統定義了一個結構體用來存儲函數的活動記錄 這個結構體的內容就包括了返回地址參數等等
所謂pop或者彈出 就是想我所指的那樣 回到原來的地址 如果機器指令執行到b()返回的指令 那么就將跳轉到函數返回的地方 就像彈出了b()函數相關的信息一樣 其實只是跳轉到一個位置 然后程序如果繼續執行的話就把原來b()的內容覆蓋掉了

#16


局部變量不是需要時才申請。用完后就收回寄存器嗎。會浪費嗎。全局變量才浪費寄存器吧。

注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com