首页 专栏 c 文章详情
关注作者
关注作者
0
读懂汇编代码
doujiang24 发布于 3 月 2 日
对于这样一份 C 代码:
int add (int a, int b) {
return a + b;
}
int main (void) {
int a = 10;
int b = 20;
int c = add(a, b);
return c;
}
先使用 gcc
编译
$ gcc -g -O0 hello.c -o hello
然后使用 objdump
来查看反汇编
只摘取其中结果中最重要的汇编代码,#
之后的内容为手动加的注释
$ objdump -j .text -d hello
00000000004004ed <add>:
4004ed: 55 push %rbp # 将 rbp 寄存器的值压入栈
4004ee: 48 89 e5 mov %rsp,%rbp # 将 rsp 寄存器的值 移动到 rbp 寄存器,栈底(rbp)移动到原来的栈顶的位置(rsp)
4004f1: 89 7d fc mov %edi,-0x4(%rbp) # 将 edi 寄存器的值,移动到 -0x4(相对于 rbp 的地址)
4004f4: 89 75 f8 mov %esi,-0x8(%rbp) # 将 esi 寄存器的值,移动到 -0x8(相对于 rbp 的地址)
4004f7: 8b 45 f8 mov -0x8(%rbp),%eax # 将 -0x8 的值移动到 eax
4004fa: 8b 55 fc mov -0x4(%rbp),%edx # 将 -0x4 的值移动到 edx
4004fd: 01 d0 add %edx,%eax # eax += edx
}
4004ff: 5d pop %rbp # 从栈顶弹出一个值,放到 rbp 里
400500: c3 retq # 从栈顶弹出一个值,放到 rip 里,也就是相当于 pop %rip
0000000000400501 <main>:
400501: 55 push %rbp # 将 rbp 压入栈
400502: 48 89 e5 mov %rsp,%rbp # 将 rsp 寄存器的值 移动到 rbp 寄存器,栈底(rbp)移动到原来的栈顶的位置(rsp)
400505: 48 83 ec 10 sub $0x10,%rsp # rsp -= 0x10,栈顶向下生长高度 0x10
400509: c7 45 fc 0a 00 00 00 movl $0xa,-0x4(%rbp) # 将整数 0xa 移动到 -0x4(相对于 rbp)
400510: c7 45 f8 14 00 00 00 movl $0x14,-0x8(%rbp) # 将整数 0x14 移动到 -0x8(相对于 rbp)
400517: 8b 55 f8 mov -0x8(%rbp),%edx # 将 -0x8 移动到 edx
40051a: 8b 45 fc mov -0x4(%rbp),%eax # 将 -0x4 移动到 eax
40051d: 89 d6 mov %edx,%esi # esi = edx
40051f: 89 c7 mov %eax,%edi # edi = eax
400521: e8 c7 ff ff ff callq 4004ed <add> # 调用函数 add
400526: 89 45 f4 mov %eax,-0xc(%rbp) # 将 eax 移动到 -0xc
400529: 8b 45 f4 mov -0xc(%rbp),%eax # 将 -0xc 移动到 eax
40052c: c9 leaveq # 相当于movq %rbp, %rsp + popq %rbp,将 rbp 和 rsp 回退到上一帧
40052d: c3 retq # 从栈顶弹出一个值,放到 rip 里,也就是相当于 pop %rip
40052e: 66 90 xchg %ax,%ax # nop
c
阅读 45 更新于 3 月 2 日
赞
收藏
分享
本作品系原创, 采用《署名-非商业性使用-禁止演绎 4.0 国际》许可协议
doujiang24
中年程序员
0 声望
0 粉丝
0 条评论
得票 时间
提交评论
doujiang24
中年程序员
0 声望
0 粉丝
宣传栏
目录
▲
对于这样一份 C 代码:
int add (int a, int b) {
return a + b;
}
int main (void) {
int a = 10;
int b = 20;
int c = add(a, b);
return c;
}
先使用 gcc
编译
$ gcc -g -O0 hello.c -o hello
然后使用 objdump
来查看反汇编
只摘取其中结果中最重要的汇编代码,#
之后的内容为手动加的注释
$ objdump -j .text -d hello
00000000004004ed <add>:
4004ed: 55 push %rbp # 将 rbp 寄存器的值压入栈
4004ee: 48 89 e5 mov %rsp,%rbp # 将 rsp 寄存器的值 移动到 rbp 寄存器,栈底(rbp)移动到原来的栈顶的位置(rsp)
4004f1: 89 7d fc mov %edi,-0x4(%rbp) # 将 edi 寄存器的值,移动到 -0x4(相对于 rbp 的地址)
4004f4: 89 75 f8 mov %esi,-0x8(%rbp) # 将 esi 寄存器的值,移动到 -0x8(相对于 rbp 的地址)
4004f7: 8b 45 f8 mov -0x8(%rbp),%eax # 将 -0x8 的值移动到 eax
4004fa: 8b 55 fc mov -0x4(%rbp),%edx # 将 -0x4 的值移动到 edx
4004fd: 01 d0 add %edx,%eax # eax += edx
}
4004ff: 5d pop %rbp # 从栈顶弹出一个值,放到 rbp 里
400500: c3 retq # 从栈顶弹出一个值,放到 rip 里,也就是相当于 pop %rip
0000000000400501 <main>:
400501: 55 push %rbp # 将 rbp 压入栈
400502: 48 89 e5 mov %rsp,%rbp # 将 rsp 寄存器的值 移动到 rbp 寄存器,栈底(rbp)移动到原来的栈顶的位置(rsp)
400505: 48 83 ec 10 sub $0x10,%rsp # rsp -= 0x10,栈顶向下生长高度 0x10
400509: c7 45 fc 0a 00 00 00 movl $0xa,-0x4(%rbp) # 将整数 0xa 移动到 -0x4(相对于 rbp)
400510: c7 45 f8 14 00 00 00 movl $0x14,-0x8(%rbp) # 将整数 0x14 移动到 -0x8(相对于 rbp)
400517: 8b 55 f8 mov -0x8(%rbp),%edx # 将 -0x8 移动到 edx
40051a: 8b 45 fc mov -0x4(%rbp),%eax # 将 -0x4 移动到 eax
40051d: 89 d6 mov %edx,%esi # esi = edx
40051f: 89 c7 mov %eax,%edi # edi = eax
400521: e8 c7 ff ff ff callq 4004ed <add> # 调用函数 add
400526: 89 45 f4 mov %eax,-0xc(%rbp) # 将 eax 移动到 -0xc
400529: 8b 45 f4 mov -0xc(%rbp),%eax # 将 -0xc 移动到 eax
40052c: c9 leaveq # 相当于movq %rbp, %rsp + popq %rbp,将 rbp 和 rsp 回退到上一帧
40052d: c3 retq # 从栈顶弹出一个值,放到 rip 里,也就是相当于 pop %rip
40052e: 66 90 xchg %ax,%ax # nop