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

GDB 實戰:觀測函數調用時的棧幀變化

     編輯:關於C語言

實驗代碼

#include <stdio.h>

void hello() {
    int i = 0;
    printf("i = %d, hello world\n", i);
}

int main() {
    hello();
    return 0;
}

調用 hello() 前(在 main 內)的寄存器狀態

(gdb) info registers
eax 0xbff644a4  ecx 0xbff64420  edx 0x1
ebx 0xb7f2fff4  esp 0xbff64400  ebp 0xbff64408
eip 0x80483f7 <main+17>  // call hello 前

進入 hello() 後的寄存器狀態

(gdb) info registers
esp 0xbff643e0  ebp 0xbff643f8
eip 0x80483ca <hello+6>

棧幀變化量化分析

main 的 esp (0xbff64400) 減去 hello 的 ebp (0xbff643f8) = 8 位元組。

檢查 hello 棧幀內容:

(gdb) x 0xbff643f8     // *(ebp) = 0xbff64408 → main 的 ebp
(gdb) x 0xbff643fc     // *(ebp+4) = 0x080483fc → 返回地址 (main+22)

main 反組譯對照

0x080483e6 <main+0>:  lea 0x4(%esp),%ecx
0x080483ea <main+4>:  and $0xfffffff0,%esp   // 16-byte 對齊
0x080483ed <main+7>:  pushl -0x4(%ecx)
0x080483f0 <main+10>: push %ebp              // 保存 main ebp
0x080483f1 <main+11>: mov %esp,%ebp          // 建立 main ebp
0x080483f3 <main+13>: push %ecx
0x080483f4 <main+14>: sub $0x4,%esp
0x080483f7 <main+17>: call 0x80483c4 <hello> // 壓入返回地址
...

結論

  • call 指令壓入返回地址(4 bytes)
  • hello 序言 push %ebp; mov %esp,%ebp 再壓入 main 的 ebp(4 bytes)
  • 兩者共 8 bytes,與觀測到的 esp_main - ebp_hello = 8 完全吻合
  • 棧幀鏈結構:hello.ebp → main.ebp → main.ret_addr
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved