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

程式在電腦中如何執行(一):從原始碼到機器指令

     編輯:關於C語言

習慣高階語言開發時,幾行代碼便能完成複雜運算。但這些代碼究竟如何在電腦中存儲與運行?本文以 C 語言遞歸範例為切入點,帶你深入理解程式執行的底層機制——代碼段、數據段、堆疊幀、基址指標(EBP)與堆疊指標(ESP)的協作。

範例程式

#include <stdio.h>
int recursiveFun(int i) {
    if (i < 1) return recursiveFun(i + 1);
    else return i;
}
int fun() {
    int i = 0;
    i = recursiveFun(i);
    return i;
}
int main() {
    int i;
    i = fun();
    printf("%d", i);
}

代碼段:指令存放區

程式編譯後,機器指令存放在代碼段。以 VC++ 反組譯觀察,`main` 函數入口地址為 0x002a1490,該記憶體單元儲存的機器指令為 55(對應 `push ebp`)。

數據段與堆疊:活動記錄的建立與銷毀

未顯式申請堆記憶體時,區域變數、返回地址等存放在堆疊中,形成活動記錄。函數巢狀調用對應堆疊的壓入與彈出。兩個關鍵暫存器:

  • EBP(基址指標):指向當前函數堆疊幀的基址
  • ESP(堆疊指標):指向堆疊頂端

EBP 鏈:串聯調用鏈

每個函數入口處,EBP 所指記憶體單元存放的是呼叫該函數的上一層函數的 EBP 值。透過這條鏈,函數返回時能找回呼叫者上下文,繼續執行。

實測觀察:

  • 執行至 `i = fun()` 時,EBP = 0x0022fec8,該位置存值 0x0022ff18(main 的 EBP)
  • 進入 `fun()` 後,EBP = 0x0022fde8,存值 0x0022fec8(上一層 EBP)

這樣的鏈結構確保了函數返回後能正確恢復現場。

下一步預告

本文建立了靜態視角的認知,下一篇將動態演示堆疊在遞歸調用過程中的壓入、彈出細節,並解析參數傳遞、返回值處理等機制。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved