代码(src/05/gdb.c)
int g(int x)
{
return x + 4;
}
int f(int x)
{
return g(x);
}
int main(void)
{
return f(8) + 4;
}
gcc编译
使用gcc -g src/05/gdb.c -o gdb -m32命令在64位的机器上产生32位汇编代码
gdb调试可执行文件
-
使用gdb gdbdemo指令打开gdb调试器
-
使用break main指令在main函数处设置断点,使用r指令运行代码,可以看到运行时在main函数位置停了下来
-
使用disassemble指令获取汇编代码
-
用i r指令查看各寄存器的值
-
此时主函数的栈基址为0xffffcf68,用x 0xffffcf68指令查看内存地址中的值,目前%esp所指堆栈内容为0,%ebp所指内容也为0
-
使用display /i $pc指令进行设置,在每次执行下一条汇编语句时,都会显示出当前执行的语句。
-
依次如下指令调试汇编代码,并查看%esp、%ebp和堆栈内容:
1、使用si指令单步跟踪一条机器指令
2、使用i r指令查看各寄存器的值
3、使用x/na %esp对应的值指令查看堆栈变化 -
%esp、%ebp和堆栈内容变化
-
call指令将下一条指令的地址入栈,此时%esp,%ebp和堆栈的值为:
-
将上一个函数的基址入栈,从当前%esp开始作为新基址:
-
为传参做准备:
-
实参入栈:
-
call指令将下一条指令的地址入栈:
-
分配栈空间
-
pushl 0x8(%ebp)将%esp中的8存入栈中
-
将 %eax 与立即数4相加
-
pop %ebp在g结束前弹栈
-
ret返回g中call的调用位置,结束g函数
-
将 %esp 与立即数相加
-
leave返回准备栈
-
ret返回f中call的调用位置,结束f函数
-
进入main函数,将 %esp 与立即数相加
-
将 %eax 与立即数4相加
-
leave返回准备栈
-
ret结束main函数
-
分析