这里的运行情况和我们常规调试看到的并不一样,我们回到之前的汇编代码,分析一下每一步在干什么。 为了方便查看源C代码和汇编代码的对应关系,我们利用反汇编工具objdump得到的反汇编代码,来分析程序执行过程。 从目标文件反汇编得到的汇编代码:
gcc -g -Wall add.c -o add
objdump -S add
得到:
00000000004004ed <add>:
int add(int a, int b) {
4004ed: 55 push %rbp
4004ee: 48 89 e5 mov %rsp,%rbp
4004f1: 89 7d ec mov %edi,-0x14(%rbp)
4004f4: 89 75 e8 mov %esi,-0x18(%rbp)
int result;
result = a + b;
4004f7: 8b 45 e8 mov -0x18(%rbp),%eax
4004fa: 8b 55 ec mov -0x14(%rbp),%edx
4004fd: 01 d0 add %edx,%eax
4004ff: 89 45 fc mov %eax,-0x4(%rbp)
return result;
400502: 8b 45 fc mov -0x4(%rbp),%eax
}
400505: 5d pop %rbp
400506: c3 retq
0000000000400507 <main>:
int main(int argc, char *argv[]) {
400507: 55 push %rbp
400508: 48 89 e5 mov %rsp,%rbp
40050b: 48 83 ec 20 sub $0x20,%rsp //为main函数分配栈帧空间,此处为32个字节
40050f: 89 7d ec mov %edi,-0x14(%rbp) //将系统传给main函数的第一个参数复制到自己的栈帧(可以查看值吗?)
400512: 48 89 75 e0 mov %rsi,-0x20(%rbp) //将系统传给main函数的第二个参数复制到自己的栈帧,,并存放在栈帧的最顶部(可以查看值吗?)
int a,b,result;
a = 1;
400516: c7 45 f4 01 00 00 00 movl $0x1,-0xc(%rbp) //此处为给main函数的局部变量a赋值过程,将该值复制到main函数的栈帧中;使用movl表明这个变量是4个字节的,打在C代码第12行的断点,在汇编代码里实际断点在这里
b = 2;
40051d: c7 45 f8 02 00 00 00 movl $0x2,-0x8(%rbp) //此处为给main函数的局部变量b赋值过程,将该值复制到main函数的栈帧中;可以看出局部变量的地址是从低向高分配的
result = add(a,b);
400524: 8b 55 f8 mov -0x8(%rbp),%edx
400527: 8b 45 f4 mov -0xc(%rbp),%eax
40052a: 89 d6 mov %edx,%esi
40052c: 89 c7 mov %eax,%edi
40052e: e8 ba ff ff ff callq 4004ed <add>
400533: 89 45 fc mov %eax,-0x4(%rbp)
return 0;
400536: b8 00 00 00 00 mov $0x0,%eax
}
40053b: c9 leaveq
40053c: c3 retq
40053d: 0f 1f 00 nopl (%rax)