導航:首頁 > 源碼編譯 > 編譯局部變數

編譯局部變數

發布時間:2022-11-19 23:29:29

⑴ GCC編譯器局部變數地址分配為什麼總是從低

原因:GCC的堆棧保護技術—— canary的使用。
使用的原因是為了防止某些溢出的攻擊。但是只是溢出時方向發生了改變,並沒有起到太大的作用,可能對於傳統的一些攻擊方法有用。
GCC 中的堆棧保護實現
Stack Guard 是第一個使用 Canaries 探測的堆棧保護實現,它於 1997 年作為 GCC 的一個擴展發布。最初版本的 Stack Guard 使用 0x00000000 作為 canary word。盡管很多人建議把 Stack Guard 納入 GCC,作為 GCC 的一部分來提供堆棧保護。但實際上,GCC 3.x 沒有實現任何的堆棧保護。直到 GCC 4.1 堆棧保護才被加入,並且 GCC4.1 所採用的堆棧保護實現並非 Stack Guard,而是 Stack-smashing Protection(SSP,又稱 ProPolice)。
SSP 在 Stack Guard 的基礎上進行了改進和提高。它是由 IBM 的工程師 Hiroaki Rtoh 開發並維護的。與 Stack Guard 相比,SSP 保護函數返回地址的同時還保護了棧中的 EBP 等信息。此外,SSP 還有意將局部變數中的數組放在函數棧的高地址,而將其他變數放在低地址。這樣就使得通過溢出一個數組來修改其他變數(比如一個函數指針)變得更為困難。

⑵ (C語言)編譯時給全局變數和靜態變數分配存儲空間,運行時給局部變數分配存儲空間,這樣說對嗎

全局變數,靜態局部變數,靜態全局變數都在靜態存儲區分配空間,而局部變數在棧里分配空間

全局變數本身就是靜態存儲方式, 靜態全局變數當然也是靜態存儲方式。這兩者在存儲方式上並無不同。這兩者的區別雖在於非靜態全局變數的作用域是整個源程序,當一個源程序由多個源文件組成時,非靜態的全局變數在各個源文件中都是有效的。而靜態全局變數則限制了其作用域,即只在定義該變數的源文件內有效,在同一源程序的其它源文件中不能使用它。由於靜態全局變數的作用域局限於一個源文件內,只能為該源文件內的函數公用,因此可以避免在其它源文件中引起錯誤。

⑶ c編譯原理,如何處理同名局部變數和全局變數

定義就不說了,位置不同就有區別了,只說訪問——若全局變數和局部變數都名為a,則在既可訪問全局變數又可訪問局部變數的地方,訪問全局變數用::a,訪問局部變數直接用a。

⑷ C語言中的 局部變數,存儲在什麼地方

C語言中的局部變數存儲在棧里。

普通的局部變數在棧空間上分配,這個局部變數所在的函數被多次調用時,每次調用這個局部變數在棧上的位置都不一定相同。局部變數也可以在堆上動態分配(malloc),但是記得使用完這個堆空間後要釋放之。

在棧空間上分配時是要注意內存的,不能分配內存過大。如果棧內空間小於所申請的空間大小,那麼這時系統將揭示棧溢出,並給出相應的異常信息。但是堆不一樣,堆可分配空間是很大的。

(4)編譯局部變數擴展閱讀

局部變數分類

1、位置:靜態局部變數被編譯器放在全局存儲區.data,所以它雖然是局部的,但是在程序的整個生命周期中存在(定義時出生,隨著程序結束而結束)。

2、訪問許可權:靜態局部變數只能被其作用域內的變數或函數訪問。也就是說雖然它會在程序的整個生命周期中存在,由於它是static的,它不能被其他的函數和源文件訪問。

3、值:靜態局部變數如果沒有被用戶初始化,則會被編譯器自動賦值為0,以後每次調用靜態局部變數的時候都用上次調用後的值。

⑸ 編譯器對作為局部變數的數組是怎麼管理的放在堆棧中

C語言的堆跟棧是有區別的,請大家不要混淆。
局部變數和函數調用時的實參是放在棧里。所以有大家常說函數調用時的入棧,出桟這個說話。
動態申請的內存放在堆里的。
全局變數和靜態變數是放在另外的全局內存區。

⑹ 局部變數為什麼在編譯時無法確定

編譯時能確定的只是常量(PE放到data區),其他所有的都要等到堆棧分配(運行時),局部變數更是要等到所在函數或類分配後才能進行分配的

⑺ 操作系統和編譯器是怎麼識別全局變數和局部

⑻ C語言中的「局部變數」是什麼意思

C語言全局變數和局部變數
引子---
? ?? ???變數可以在程序中三個地方說明: 函數內部、函數的參數定義中或所有的函數外部。根據所定義位置的不同, 變數可分為局部變數、形式參數和全程變數。從空間角度來看,變數可以分為全局變數和局部變數,而從時間角度來分的 可以有靜態存儲變數和動態存儲變數之分。

一。全局變數和局部變數

1。局部變數

他是 指在函數內部定義的變數 作用域為定義局部變數的函數 也就是說他只能在定義他的函數中使用

最值得注意的是 只有在程序執行到定義他的模塊時才能生成,一旦執行退出該模塊則起變數消失

eg.

func ()

{
? ?int x;? ?局部變數x的作用域 很明確
? ?......
}

2。全局變數

在程序執行的過程中一直有效

eg.

int x=1;

func ()

{
? ?x=x+1;

}

func1 ()

{
??x=x-1;

}

main ()

{

}
由此不難看出整型x的作用范圍

對於全局變數 如果在定義的時候不做初始化 則系統將自動為起賦值 數值型為0

字元型為空'\0'

全局變數的弊端 增加內存開銷 降低函數的通用性

定義全局變數時 理想的位置是在文件的開頭 當這些函數以及同一個程序中的其他源程序文件中的某些函數需要使用該全局變數時 在函數內部對該變數使用extern 加以說明 說明他是外部的

(這里還要做詳細的講解)

eg.

main ()

{
extern int a,b;
printf ("mIn is %d\n",min(a,b));
}

int a=1,b=2;
int min (x,y)
int x,y;
{
int z;
z=x<y?x:y;
return(z);
}
我還要說明的是 對外部變數的說明和對全局變數的定義不是一回事

對外部變數的說明 只是聲明該變數是在外部定義過的一個全局變數 在這里引用 而對全局變數的定義則是要對起分配存儲單元的

一個全局變數只能定義一次 可是卻可以多次引用

*** 在同一源文件中,全局變數和局部變數同名時,在局部變數的作用域內,全局變數不起作用的。

二。靜態存儲變數和動態存儲變數

對於程序運行期間根據需要進行臨時動態分配存儲空間的變數 為動態存儲變數

對於那些程序運行期間永久佔用固定內存的變數 稱為靜態存儲變數

還要說明的是 程序的指令代碼是存放在程序代碼區的 靜態存儲變數是存放在靜態數據區的 包括全局變數等 而程序中的動態存儲變數存放在動態數據區 如函數的形參以及函數調用時的返回地址等

三。C語言中的變數存儲分類指定
? ?
? ? auto
? ? auto稱為自動變數 如果函數不做其他說明的話 均為自動變數

? ? static
? ? static稱為靜態變數。根據變數的類型可以分為靜態局部變數和靜態全程變數。
? ? 1. 靜態局部變數
? ?

? ???它與局部變數的區別在於: 在函數退出時, 這個變數始終存在, 但不能被其它函數使用, 當再次進入該函數時, 將保存上次的結果。其它與局部變數一樣。
? ?

? ? 2. 靜態全程變數
? ?

? ???Turbo C2.0允許將大型程序分成若干獨立模塊文件分別編譯, 然後將所有模塊的目標文件連接在一起, 從而提高編譯速度, 同時也便於軟體的管理和維護。靜態全程變數就是指只在定義它的源文件中可見而在其它源文件中不可見的變數。它與全程變數的區別是: 全程變數可以再說明為外部變數(extern), 被其它源文件使用, 而靜態全程變數卻不能再被說明為外部的, 即只能被所在的源文件使用。
? ?
? ?
? ? extern
? ? extern稱為外部變數。為了使變數除了在定義它的源文件中可以使用外, 還要被其它文件使用。因此,? ?必須將全程變數通知每一個程序模塊文件,? ?此時可用extern來說明。

eg.
? ?? ???文件1為file1.c? ?? ?? ?? ?? ?? ?文件2為file2.c
? ? int i, j;/*定義全程變數*/? ?? ???extern int i, j;/*說明將i, j從
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ???文件1中復制過來*/
? ? char c;? ?? ?? ?? ?? ?? ?? ?? ???extern char c; /*將c復制過來*/
? ? void func1(int k);? ?? ?? ?? ?? ?func2()? ?? ???/*用戶定義函數*/
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? {
? ? main()? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?static float k;/*定義靜態變數*/
? ? {? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ???i=j*5/100;
? ?? ?? ? func1(20);/*調用函數*/? ?? ???k=i/1.5;
? ?? ?? ? func2();? ?? ?? ?? ?? ?? ?? ?? ?? ?.
? ?? ?? ? .? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? .
? ?? ?? ? .? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? .
? ?? ?? ? .? ?? ?? ?? ?? ?? ?? ?? ?? ? }
? ???}
? ???func1(int k) /*用戶定義函數*/
? ???{
? ?? ?? ? j=k*100;
? ???}

? ? 對於以上兩個文件file1.c和file2.c, 用Turbo C2.0的集成開發環境進行編譯
連接時, 首先應建立一個.prj的文件。例如file.prj, 該文件內容如下:
? ???file1.c
? ???file2.c
? ? 然後將file.prj的文件名寫入主菜單Project中的Project Name項中。 再用F9
編譯連接, 就可產生一個文件名為fioe.exe的可執行文件。
? ???
??

? ? register
? ? register稱為寄存器變數。它只能用於整型和字元型變數。定義符register說明的變數被Turbo C2.0存儲在CPU的寄存器中,??而不是象普通的變數那樣存儲在內存中, 這樣可以提高運算速度。但是Turbo C2.0隻允許同時定義兩個寄存器變數,一旦超過兩個, 編譯程序會自動地將超過限制數目的寄存器變數當作非寄存器變數來處理。因此, 寄存器變數常用在同一變數名頻繁出現的地方。
? ? 另外, 寄存器變數只適用於局部變數和函數的形式參數, 它屬於auto型變數,
因此, 不能用作全程變數。定義一個整型寄存器變數可寫成:
? ?? ?register int a;
? ? 對於以上所介紹的變數類型和變數存儲類型將會在以後的學習中, 通過例行程序中的定義、使用來逐漸加深理解。

⑼ 全局變數和局部變數有什麼區別是怎麼實現的

1、 全局變數的作用用這個程序塊,而局部變數作用於當前函數;

2、前者在內存中分配在全局數據區,後者分配在棧區;

3、 生命周期不同:全局變數隨主程序創建和創建,隨主程序銷毀而銷毀,局部變數在局部函數內部,甚至局部循環體等內部存在,退出就不存在;

4、 使用方式不同:通過聲明後全局變數程序的各個部分都可以用到,局部變數只能在局部使用
操作系統和編譯器通過內存分配的位置來知道的全局變數分配在全局數據段,並且在程序被運行的時候就被載入。;

編譯器通過語法詞法的分析,判斷出是全局變數還是局部變數。如果是全局變數的話,編譯器在將源代碼翻譯成二進制代碼時就為全局變數分配好一個虛擬地址 (windows下0x00400000以上的地址,也就是所說的全局區),所以程序在對全局變數的操作時是對一個硬編碼的地址操做。

局部變數的話,編譯時不分配空間,而是以相對於ebp或esp的偏移來表示局部變數的地址,所以局部變數內存是在局部變數所在的函數被調用時才真正分配。 以匯編的角度來看:函數執行時,局部變數在棧中分配,函數調用完畢釋放局部變數對應的內存,另外局部變數可以直接分配在寄存器中。

操作系統通過變數的分配地址就可以判斷出是局部變數和全局變數。

⑽ 編譯器怎麼知道是全局變數還是局部變數

這個要細說,能說的很詳細,我說一下,比較好理解的你就懂了!
我說之前先打個比方:小區人家,幾十戶,每家每戶都有燈光自己用就是局部的
月亮..全局的.都能用懂了?
按照目前的面向對象來說如Java,C++,C#,Ruby中,由於變數都是封裝在類裡面的,對別的類不可見,所以已經幾乎完全拋棄了全局變數的概念。然而,可以通過把一個類定義為public static,把類成員變數也定義為public static,使該變數在內存中佔用固定、唯一的一塊空間,來實現全局變數的功能。
說通俗點,你如果想理解,就假如在一個類中,看你定義的變數,位置!類中,方法外面,就屬於全局,每個方法都能拿去用..方法裡面定義的,就屬於局部的,只能他自己用.懂了?
和你一樣初學者,不足之處還請指點!

閱讀全文

與編譯局部變數相關的資料

熱點內容
什麼是車鑒定app 瀏覽:64
戰地一私人伺服器怎麼買 瀏覽:497
陳天程序員 瀏覽:831
編譯原理如何運用到編程中 瀏覽:17
linux選擇資料庫 瀏覽:376
php兩個數組差集 瀏覽:978
迷你pdf閱讀器下載 瀏覽:433
做一個python小程序 瀏覽:655
pythonossystem和 瀏覽:645
win2008如何搭建ftp伺服器 瀏覽:53
安卓手機為什麼不翻牌 瀏覽:546
刪除pkpm及相關文件夾 瀏覽:481
房貸解壓銀行內部流程 瀏覽:734
安卓手機如何更改語音 瀏覽:601
android紅包實現 瀏覽:734
蘋果的nvme為什麼安卓不用 瀏覽:32
python輸入單詞統計個數 瀏覽:998
腳本軟體提取源碼 瀏覽:281
程序員能給自己的微信錢包刷錢么 瀏覽:73
怎麼讓小天才app查看寶貝的通訊錄 瀏覽:624