陣列函式呼叫過程中的步驟:
我們已經知道,因為每個函式被呼叫過程,那個函式的引數、區域性變數、返回位址, 都會放在一斷特定的棧區域中,並且每個被呼叫的函式,都對應了一段特定的棧區 域,那一段特定的棧區域,稱為那乙個被呼叫函式的棧幀。
void fun2(int arg)
void fun1(int arg)
int main(int argc, char* ar**)
通過以上的圖和**實驗,也可以很容易的理解,為什麼區域性變數,即使同名,也不 能跨函式使用。
##函式呼叫的返回過程
當函式執行結束,或者遇到return時,會進行函式返回。
函式返回的過程,其實是函式呼叫的逆過程。
##【小練習】
如下是乙個密碼驗證的程式:
使用者有3次機會輸入密碼,如果密碼正確,則提示正確。如果密碼錯誤三次,則列印錯 誤資訊,結束程式。
以下程式,可以暴露出與棧有關的安全問題:
void repassword() //密碼驗證函式
; for (int time = 1; time < 4; time++)
else
if (time >= 3)
}}int main(int argc, char* ar**)
以上,如果我們輸入內容過多(超出16個位元組),可以覆蓋到返回位址處的記憶體,這樣,就可以控制程式流程到自己構造的**處。
如果精心構造輸入內容,不僅可以改變流程,還可以決定改變流程後的功能。 這就是棧溢位漏洞(現在幾乎不可能有了)。
欲知詳細內容,可以搜尋shellcode。
陣列的基本用法:
int main(int argc, char* ar**)
;//陣列的定義
printf("%d\r\n", nary[1]);//陣列的引用
nary[2] = 100;//陣列成員的賦值
return 0;
}
關於陣列的定義的特點(c89標準):
int main(int argc, char* ar**)
; printf("%p\r\n", &nary[0]);
printf("%p\r\n", &nary[16]);
printf("%p\r\n", &nary[-3]);
printf("%p\r\n", &4[nary]);
return 0;
}
&ary[i]
//以下兩行等價
printf("%p\r\n", &nary[0]);
printf("%p\r\n", nary);
陣列引用的細節過程,如果:
printf("%p",nary[5]);
nary[5]的值其實經歷以下兩步被取出:
int main(int argc, char* ar**)
; printf("%p\r\n", &nary[-3]);
return 0;
}
所以,定址nary[i]就變得非常重要,在編譯器內部,其實是通過非常簡單的公式
達成目的:
nary[i]的位址 = nary(首位址) + i * sizeof(陣列成員的型別)
sizeof是c語言中的乙個運算子(地位是關鍵字級別),它的作用是計算型別或者變數的位元組數。
int main(int argc, char* ar**)
; printf("%d,%d,%d,%d,%d\r\n",
sizeof(int),
sizeof(short),
sizeof(char),
sizeof(double),
sizeof(float)
);printf("%p\r\n", sizeof(nary));
return 0;
}
C 函式呼叫過程
int fun1 int a,int b int main 將彙編 執行到函式呼叫的地方,檢視函式呼叫引數帶入的指令。int a fun1 10,20 0131141e push 14h 01311420 push 0ah 01311422 call fun1 0131118bh 引數順序是10,2...
C函式的呼叫過程
c函式的引數傳遞過程 基礎知識 函式呼叫的本質將在這裡得到闡明。首先請讀者理解堆疊的操作。函式和堆疊的關係密切,這是因為 c語言程式通過堆疊把引數從函式外部傳入到函式內部。此外,在堆疊中劃分區域來容納函式的內部變數。呼叫push和pop指令的時候,暫存器 esp用於指向棧頂的位置 棧頂總是棧中位址最...
C語言 函式呼叫過程(棧幀)
首先舉個栗子 include int add int x,int y int main 在這個程式裡,函式被呼叫才會發揮函式的功能,而函式的呼叫其實是乙個過程,在這個過程計算機要為函式開闢棧空間,用於本次函式臨時變數的儲存和現場保護,這塊空間稱為函式的棧幀。現場保護的作用是為了在呼叫完另乙個函式,返...