一直存在比较模糊的概念,因此用一个例子强化记忆。
linux x86 gcc3.2.3 AT&T格式的汇编 代码如下: void fun() { int a = 'A'; } void main() { int b; fun(); return; } 开始调试 [sanool@sanool ex2]$ gdb a.out GNU gdb Red Hat Linux (6.0post-0.20031117.6rh) Copyright 2003 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i386-redhat-linux-gnu"...(no debugging symbols found)...Using host libthread_db library "/lib/tls/libthread_db.so.1". (gdb) disas main Dump of assembler code for function main: 0x08048323 <main+0>: push %ebp 0x08048324 <main+1>: mov %esp,%ebp 0x08048326 <main+3>: sub $0x8,%esp 0x08048329 <main+6>: and $0xfffffff0,%esp 0x0804832c <main+9>: mov $0x0,%eax 0x08048331 <main+14>: sub %eax,%esp 0x08048333 <main+16>: call 0x8048314 <fun> 0x08048338 <main+21>: leave 0x08048339 <main+22>: ret 0x0804833a <main+23>: nop 0x0804833b <main+24>: nop End of assembler dump. (gdb) disas fun Dump of assembler code for function fun: 0x08048314 <fun+0>: push %ebp 0x08048315 <fun+1>: mov %esp,%ebp 0x08048317 <fun+3>: sub $0x4,%esp 0x0804831a <fun+6>: movl $0x41,0xfffffffc(%ebp) 0x08048321 <fun+13>: leave 0x08048322 <fun+14>: ret End of assembler dump. 解释如下: **当程序下一步执行 0x08048333 <main+16>: call 0x8048314 <fun> 时 esp = 0xbfffe660 (运行时) ebp = 0xbfffe668 (运行时) eip = 0x08048333 **然后执行 call 0x8048314<fun> 也就是 push %eip ( 相当于 sub $4 %esp 再 mov %eip %esp ) movl $0x8048314, %eip 则0xbfffe65c 处为 eip = 0x08048338 且esp = 0xbfffe65c eip = 0x8048314 ebp = 0xbfffe668 **执行0x08048314 <fun+0>: push %ebp后 esp = 0xbfffe658 ebp = 0xbfffe668 0xbfffe658处的值为 ebp = 0xbfffe668 **继续0x08048315 <fun+1>: mov %esp,%ebp 将esp的值赋值给ebp 即 ebp = esp = 0xbfffe658 **开始执行 0x08048321 <fun+13>: leave 前 eip = 0x08048321 ebp = 0xbfffe658 esp = 0xbfffe654 **开始执行 0x08048321 <fun+13>: leave 时 即进行 movl %ebp, %esp ( 即 esp = ebp = 0xbfffe658) pop %ebp ( 也就是 mov %esp,%ebp 再 add $4,%esp ) 此时 ebp = 0xbfffe668 回到了原函数的ebp值, **再执行 0x08048322 <fun+14>: ret 即 pop %eip ( 也就是 mov %esp,%eip 再 add $4,%esp ) 此时 eip = 0x08048338 程序继续执行 main 中的 leave 调用fun函数结束