|
发表于 2023-7-26 00:23:59
|
显示全部楼层
- $ cat main.c
- #include <stdio.h>
- void func(int i) {
- if(!i) return;
- printf("%p\n", &i);
- func(i - 1);
- }
- int main(void) {
- func(3);
- return 0;
- }
- $ gcc -m32 -g -Wall -o main main.c
- $ ./main
- 0xff84bcc0
- 0xff84bca0
- 0xff84bc80
- $
复制代码
- 0000118d <func>:
- #include <stdio.h>
- void func(int i) {
- 118d: 55 pushl %ebp
- 118e: 89 e5 movl %esp,%ebp
- 1190: 53 pushl %ebx
- 1191: 83 ec 04 subl $0x4,%esp
- 1194: e8 73 00 00 00 calll 120c <__x86.get_pc_thunk.ax>
- 1199: 05 5b 2e 00 00 addl $0x2e5b,%eax
- if(!i) return;
- 119e: 8b 55 08 movl 0x8(%ebp),%edx
- 11a1: 85 d2 testl %edx,%edx
- 11a3: 74 2c je 11d1 <func+0x44>
- printf("%p\n", &i);
- 11a5: 83 ec 08 subl $0x8,%esp
- 11a8: 8d 55 08 leal 0x8(%ebp),%edx
- 11ab: 52 pushl %edx
- 11ac: 8d 90 14 e0 ff ff leal -0x1fec(%eax),%edx
- 11b2: 52 pushl %edx
- 11b3: 89 c3 movl %eax,%ebx
- 11b5: e8 96 fe ff ff calll 1050 <printf@plt>
- 11ba: 83 c4 10 addl $0x10,%esp
- func(i - 1);
- 11bd: 8b 45 08 movl 0x8(%ebp),%eax
- 11c0: 83 e8 01 subl $0x1,%eax
- 11c3: 83 ec 0c subl $0xc,%esp
- 11c6: 50 pushl %eax
- 11c7: e8 c1 ff ff ff calll 118d <func>
- 11cc: 83 c4 10 addl $0x10,%esp
- 11cf: eb 01 jmp 11d2 <func+0x45>
- if(!i) return;
- 11d1: 90 nop
- }
- 11d2: 8b 5d fc movl -0x4(%ebp),%ebx
- 11d5: c9 leavel
- 11d6: c3 retl
- 000011d7 <main>:
- int main(void) {
- 11d7: 8d 4c 24 04 leal 0x4(%esp),%ecx
- 11db: 83 e4 f0 andl $0xfffffff0,%esp
- 11de: ff 71 fc pushl -0x4(%ecx)
- 11e1: 55 pushl %ebp
- 11e2: 89 e5 movl %esp,%ebp
- 11e4: 51 pushl %ecx
- 11e5: 83 ec 04 subl $0x4,%esp
- 11e8: e8 1f 00 00 00 calll 120c <__x86.get_pc_thunk.ax>
- 11ed: 05 07 2e 00 00 addl $0x2e07,%eax
- func(3);
- 11f2: 83 ec 0c subl $0xc,%esp
- 11f5: 6a 03 pushl $0x3
- 11f7: e8 91 ff ff ff calll 118d <func>
- 11fc: 83 c4 10 addl $0x10,%esp
- return 0;
- 11ff: b8 00 00 00 00 movl $0x0,%eax
- }
- 1204: 8b 4d fc movl -0x4(%ebp),%ecx
- 1207: c9 leavel
- 1208: 8d 61 fc leal -0x4(%ecx),%esp
- 120b: c3 retl
复制代码
在func函数中,ebp + 0x8就是局部变量 i 的地址
这个程序输出了3个局部变量 i 的地址,都不一样
118d: 55 pushl %ebp
118e: 89 e5 movl %esp,%ebp
// ...
11d5: c9 leavel
11d6: c3 retl
这4行指令保证了正常的函数调用和返回
如果不这么做,要如何才能实现这个程序的输出效果呢?
自己调试一下这个程序,看一看为什么输出的这3个局部变量 i 的地址不一样
看一看是如何通过ebp访问局部变量的
|
|