代码如下:
gdb生成调试信息,进去看看。
在hello处设置断点1,在main处设置断点2
运行到断点2处,查看寄存器情况:
Breakpoint 2, 0x080483f4 in main ()
Missing separate debuginfos, use: debuginfo-install glibc.i686
(gdb) info registers
eax 0x1 1
ecx 0xbfae89d0 -1079080496
edx 0xbfae89f0 -1079080464
ebx 0x2513ff4 38879220
esp 0xbfae89b4 0xbfae89b4
ebp 0xbfae89b8 0xbfae89b8
esi 0x0 0
edi 0x8048310 134513424
eip 0x80483f4 0x80483f4 <main+14>
eflags 0x286 [ PF SF IF ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51
继续运行到断点1处,查看寄存器情况:
(gdb) n
Single stepping until exit from function main,
which has no line number information.
Breakpoint 1, 0x080483ca in hello ()
(gdb) info registers
eax 0x1 1
ecx 0xbfae89d0 -1079080496
edx 0xbfae89f0 -1079080464
ebx 0x2513ff4 38879220
esp 0xbfae8990 0xbfae8990
ebp 0xbfae89a8 0xbfae89a8
esi 0x0 0
edi 0x8048310 134513424
eip 0x80483ca 0x80483ca <hello+6>
eflags 0x286 [ PF SF IF ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51
根据两个栈桢中寄存器的变化,看看变化前的esp - 变化后的ebp,得到以下结果:
(gdb) p 0xbfae89b4-0xbfae89a8
$1 = 12
再看看,在hello之中*(ebp)和*(ebp+4)的数据:
(gdb) x 0xbfae89a8
0xbfae89a8: 0xbfae89b8
(gdb) x 0xbfae89a8+4
0xbfae89ac: 0x080483fc
其中,第一次打印的结果0xbfae89b8是main栈桢中ebp寄存器的数据。
反汇编main函数的结果如下:
(gdb) disassemble main
Dump of assembler code for function main:
0x080483e6 <main+0>: lea 0x4(%esp),%ecx
0x080483ea <main+4>: and $0xfffffff0,%esp
0x080483ed <main+7>: pushl -0x4(%ecx)
0x080483f0 <main+10>: push %ebp
0x080483f1 <main+11>: mov %esp,%ebp
0x080483f3 <main+13>: push %ecx
0x080483f4 <main+14>: sub $0x4,%esp
0x080483f7 <main+17>: call 0x80483c4 <hello>
0x080483fc <main+22>: mov $0x0,%eax
0x08048401 <main+27>: add $0x4,%esp
0x08048404 <main+30>: pop %ecx
0x08048405 <main+31>: pop %ebp
0x08048406 <main+32>: lea -0x4(%ecx),%esp
0x08048409 <main+35>: ret
End of assembler dump.
可以看到,在调用call hello的下一句指令的地址是0x080483fc,就是上面
(gdb) x 0xbfae89a8+4
0xbfae89ac: 0x080483fc
的结果。
程序调用函数时,会执行call指令,此时会将下一条要执行的指令地址压栈。