GDB調試匯編分析
代碼

-
本次實踐我參照了許多先做了的同學的博客,有盧肖明,高其,張梓靖同學。代碼借用的是盧肖明同學的代碼進行調試運行。
GCC編譯
- 使用
gcc -g gdbtest.c -o gdbtest -m32
命令在64位的機器上產生32位匯編代碼 -
在使用gdb進行調試運行時,有cgdb和gdb兩種工具,我建議大家使用張梓靖同學使用的cgdb工具,因為使用時可以隨時看到自己的源代碼,看到我們的斷點在哪里,每一步返回值到了哪行,更加直觀。
分析過程
-
使用b main指令在main函數處設置斷點,然后,使用r指令運行代碼,使用disassemble指令獲取匯編代碼
-
使用display /i $pc(結合display命令和寄存器/pc內部變量)指令進行設置
- 可見此時主函數的棧基址為0xffffd068,用x(examine)指令查看內存地址中的值,但目前%esp所指堆棧內容為0,%ebp所指內容也為0
- 用i r指令查看各寄存器的值
- 依次如下指令調試匯編代碼,並查看%esp、%ebp和堆棧內容:
- 1、使用si指令單步跟蹤一條機器指令
- 2、使用i r指令查看各寄存器的值(在這里要看%eip、%eax、%esp和%ebp)
- 3、使用x/na %esp對應的值指令查看堆棧變化
-
將上一個函數的基址入棧,從當前%esp開始作為新基址:
-
call指令將下一條指令的地址入棧,此時%esp,%ebp和堆棧的值為:
- 實參准備入棧:
- 實參的計算在%eax中進行:
- 將棧中的數據push
- push后寄存器中的值發生轉變。
-
函數f修改了%esp,用leave指令恢復。
-
ret結束main函數
總結反思
- 這次學習讓我對於gdb有了更加深刻地認識,設置斷點是我們在進行編寫代碼時在整體編譯沒有問題,但是卻無法得到我們想要的結果時所進行分段糾錯步驟,這次的實踐讓我對於堆棧變化了有了更加深刻的理解,在使用終端三件工具編程時,沒有編程軟件上自帶寫好我們拿來就用的斷點設置按鈕,之后若是遇到這樣的問題我們只能自己動手去做,所以說這次的實踐又是我們掌握的一件有力的linux中C語言編程工具。