**
執行環境:ubuntu 14.04(32bit)
編譯環境:gcc
source code:
#include
#include
intmain
(int argc, char *argv)
- 第一組對比:在棧溢位保護機制下的編譯和沒有溢位保護機制下的編譯的入棧順序的對比:
區域性變數在源**中是:
char buffer_one[8], buffer_two[8];
int value = 5;
棧溢位保護機制下的編譯:
$ gcc -g -o so stack_test.c
$ ./so
[before] buffer_two is at 0xbfa12fb4
and contains 'two'
[before] buffer_one is at 0xbfa12fac
and contains 'one'
[before] value is at 0xbfa12fa8
andis
5 (0x00000005)
可以看出來為變數建立建立的棧順序依次是:buffer_two,buffer_one,value;
沒有溢位保護機制下的編譯:
$ gcc -fno-stack-protector -g -o so stack_test.c
$ ./so
[before] buffer_two is at 0xbf9a1530
and contains 'two'
[before] buffer_one is at 0xbf9a1538
and contains 'one'
[before] value is at 0xbf9a152c
andis
5 (0x00000005)
可以看出來為變數建立建立的棧順序依次是:buffer_one,buffer_two,value;
- 第二組對比:調整區域性變數的順序,再次在棧溢位保護機制下的編譯和沒有溢位保護機制下的編譯的入棧順序的對比:
即原始碼中區域性變數宣告改為:
int value = 5;
char buffer_one[8], buffer_two[8];
棧溢位保護機制下的編譯:
$ gcc -g -o so stack_test.c
$ ./so
[before] buffer_two is at 0xbfe0ac54
and contains 'two'
[before] buffer_one is at 0xbfe0ac4c
and contains 'one'
[before] value is at 0xbfe0ac48
andis
5 (0x00000005)
可以看出來為變數建立建立的棧順序依次是:buffer_two,buffer_one,value;
沒有溢位保護機制下的編譯:
$ gcc -fno-stack-protector -g -o so stack_test.c
$ ./so
[before] buffer_two is at 0xbf9998bc
and contains 'two'
[before] buffer_one is at 0xbf9998c4
and contains 'one'
[before] value is at 0xbf9998cc
andis
5 (0x00000005)
可以看出來為變數建立建立的棧順序依次是:value,buffer_one,buffer_two;
- 第三組對比:調整區域性變數中buffer_one,buffer_two的順序,再次在棧溢位保護機制下的編譯和沒有溢位保護機制下的編譯的入棧順序的對比:
即原始碼中區域性變數宣告改為:
int value = 5;
char buffer_two[8], buffer_one[8];
棧溢位保護機制下的編譯:
$ gcc -g -o so stack_test.c
$ ./so
[before] buffer_two is at 0xbff96dfc
and contains 'two'
[before] buffer_one is at 0xbff96e04
and contains 'one'
[before] value is at 0xbff96df8
andis
5 (0x00000005)
可以看出來為變數建立建立的棧順序依次是:buffer_one,buffer_two,value;
沒有溢位保護機制下的編譯:
$ gcc -fno-stack-protector -g -o so stack_test.c
$ ./so
[before] buffer_two is at 0xbfa55234
and contains 'two'
[before] buffer_one is at 0xbfa5522c
and contains 'one'
[before] value is at 0xbfa5523c
andis
5 (0x00000005)
可以看出來為變數建立建立的棧順序依次是:value,buffer_two,buffer_one;
得出的結論:在沒有溢位保護機制下的編譯時,我們可以發現,所有的區域性變數入棧的順序(準確來說是系統為區域性變數申請記憶體中棧空間的順序)是正向的,即哪個變數先申明哪個變數就先得到空間,
也就是說,編譯器給變數空間的申請是直接按照變數申請順序執行的。
在有溢位保護機制下的編譯時,情況有了順序上的變化,對於每一種型別的變數來說,棧空間申請的順序都與源**中相反,即哪個變數在源**中先出現則後申請空間;而對不同的變數來說,申請的順序也不同,有例子可以看出,int型總是在char的buf型之後申請,不管源**中的順序如何(這應該**於編譯器在進行溢位保護時設下的規定)。
全域性變數 區域性變數 棧 堆
一般全域性變數存放在資料區,區域性變數存放在棧區,動態變數存放在堆區,函式 放在 區。棧區是普通的棧資料結構,遵循lifo後進先出的規則,區域性變數安排在那裡是asm時就規定的,這樣可以在乙個函式結束後平衡堆疊,操作簡單,效率高 堆 動態區 在這裡應當叫堆疊 不要和資料結構中的堆搞混 是程式在編譯時...
區域性變數太大導致棧溢位
問題 昨天,有同學遇到棧溢位的問題。在做大三小學期專案時,需要乙個750x750的矩陣。於是在棧中定義了乙個二維陣列。為了說明問題,做如下簡化 測試環境 window平台 vs2013 int main 這看似沒有問題,定義了乙個變數,不大,才4.5m左右。可是,當執行時出現了棧溢位。什麼情況?編譯...
迴圈內部區域性變數與呼叫棧
正如其他部落格所提到的,區域性變數的生命週期是在乙個大括號內,即乙個所處塊結束。區域性變數和全域性變數的區別,區域性變數的生命週期是從建立開始到所處的塊結束就被 而全域性變數的生命週期是從建立開始到程式結束。正如上面所說,區域性變數是直到所處的塊結束才從呼叫棧中把它 先看下面的 for int i ...