首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C語言指針深度解析(二):棧幀、匯編視角與函數參數傳遞陷阱

     編輯:關於C語言

棧:從數據結構到運行時內存區

棧是一塊連續內存,以 4 字節為單位劃分。ESP 永遠指向棧頂,棧從高地址向低地址增長。

  • 入棧:ESP -= 4,數據寫入新棧頂
  • 出棧:讀取棧頂數據,ESP += 4

關鍵匯編指令速查

指令作用示例
MOV A,BA = BMOV EAX, 10
SUB A,BA = A - BSUB EAX, 10
LEA A,BA = &BLEA EDI, val
REP STOS DWORD PTR [EDI]將 EAX 循環寫入 EDI 指向內存,ECX 次,EDI+4初始化數組
PUSH A入棧PUSH EAX
POP A出棧POP EAX
CALL FUN調用函數,壓入返回地址 (EIP)CALL swap
RET返回,彈出 EIPRET

核心寄存器速覽

  • EAX:累加器,通用運算
  • ECX:計數器,循環控制
  • ESP:棧指針,永遠指向棧頂
  • EBP:基址指針,棧幀定位
  • EIP:指令指針,指向下一條指令
  • ESI/EDI/EBX:保存函數上下文、字符串操作
寄存器窗口

函數調用棧幀演示:值傳遞失敗案例

void swap(int a, int b) { // 形參為副本
    int tem = a; a = b; b = tem;
}
int main() {
    int a=1, b=2;
    swap(a,b); // 實參值拷貝給形參,函數內交換無法影響外部
    return 0;
}

視頻演示棧幀變化:調用 swap 時,實參 1,2 壓棧,形參在棧幀中佔據獨立位置,函數返回前棧幀銷毀,交換僅發生在臨時副本上。

指針傳遞修正版:真正實現交換

void swap(int *pa, int *pb) { // 傳遞地址
    int tem = *pa; *pa = *pb; *pb = tem;
}
int main() {
    int a=1, b=2;
    swap(&a, &b); // 傳入變量地址,函數通過解引用修改原變量
    return 0;
}

核心差異:值傳遞複製數據,指針傳遞複製地址。通過地址可跨棧幀訪問並修改原變量,這是指針在函數參數中最經典的用武之地。

實踐建議

  1. 親自在 VC6 中單步執行兩版代碼,觀察棧內存、寄存器、反匯編變化。
  2. 多讀幾遍前六篇文章,「書讀百遍,其義自見」。
  3. 理解棧幀生命周期,是掌握指針、遞歸、局部變量返回陷阱的前提。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved