调用函数时 寄存器到底发生了那些变化
2013-05-22 09:07
316 查看
一直存在比较模糊的概念,因此用一个例子强化记忆。
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 : push %ebp
0x08048324 : mov %esp,%ebp
0x08048326 : sub $0x8,%esp
0x08048329 : and $0xfffffff0,%esp
0x0804832c : mov $0x0,%eax
0x08048331 : sub %eax,%esp
0x08048333 : call 0x8048314
0x08048338 : leave
0x08048339 : ret
0x0804833a : nop
0x0804833b : nop
End of assembler dump.
(gdb) disas fun
Dump of assembler code for function fun:
0x08048314 : push %ebp
0x08048315 : mov %esp,%ebp
0x08048317 : sub $0x4,%esp
0x0804831a : movl $0x41,0xfffffffc(%ebp)
0x08048321 : leave
0x08048322 : ret
End of assembler dump.
解释如下:
**当程序下一步执行 0x08048333 : call 0x8048314 时
esp = 0xbfffe660 (运行时)
ebp = 0xbfffe668 (运行时)
eip = 0x08048333
**然后执行 call 0x8048314 也就是
push %eip ( 相当于 sub $4 %esp 再 mov %eip %esp )
movl $0x8048314, %eip
则0xbfffe65c 处为 eip = 0x08048338
且esp = 0xbfffe65c
eip = 0x8048314
ebp = 0xbfffe668
**执行0x08048314 : push %ebp后
esp = 0xbfffe658
ebp = 0xbfffe668
0xbfffe658处的值为 ebp = 0xbfffe668
**继续0x08048315 : mov %esp,%ebp
将esp的值赋值给ebp
即 ebp = esp = 0xbfffe658
**开始执行 0x08048321 : leave 前
eip = 0x08048321
ebp = 0xbfffe658
esp = 0xbfffe654
**开始执行 0x08048321 : leave 时
即进行
movl %ebp, %esp ( 即 esp = ebp = 0xbfffe658)
pop %ebp ( 也就是 mov %esp,%ebp 再 add $4,%esp )
此时 ebp = 0xbfffe668 回到了原函数的ebp值,
**再执行 0x08048322 : ret
即 pop %eip
( 也就是 mov %esp,%eip 再 add $4,%esp )
此时 eip = 0x08048338
程序继续执行 main 中的 leave
调用fun函数结束。
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 : push %ebp
0x08048324 : mov %esp,%ebp
0x08048326 : sub $0x8,%esp
0x08048329 : and $0xfffffff0,%esp
0x0804832c : mov $0x0,%eax
0x08048331 : sub %eax,%esp
0x08048333 : call 0x8048314
0x08048338 : leave
0x08048339 : ret
0x0804833a : nop
0x0804833b : nop
End of assembler dump.
(gdb) disas fun
Dump of assembler code for function fun:
0x08048314 : push %ebp
0x08048315 : mov %esp,%ebp
0x08048317 : sub $0x4,%esp
0x0804831a : movl $0x41,0xfffffffc(%ebp)
0x08048321 : leave
0x08048322 : ret
End of assembler dump.
解释如下:
**当程序下一步执行 0x08048333 : call 0x8048314 时
esp = 0xbfffe660 (运行时)
ebp = 0xbfffe668 (运行时)
eip = 0x08048333
**然后执行 call 0x8048314 也就是
push %eip ( 相当于 sub $4 %esp 再 mov %eip %esp )
movl $0x8048314, %eip
则0xbfffe65c 处为 eip = 0x08048338
且esp = 0xbfffe65c
eip = 0x8048314
ebp = 0xbfffe668
**执行0x08048314 : push %ebp后
esp = 0xbfffe658
ebp = 0xbfffe668
0xbfffe658处的值为 ebp = 0xbfffe668
**继续0x08048315 : mov %esp,%ebp
将esp的值赋值给ebp
即 ebp = esp = 0xbfffe658
**开始执行 0x08048321 : leave 前
eip = 0x08048321
ebp = 0xbfffe658
esp = 0xbfffe654
**开始执行 0x08048321 : leave 时
即进行
movl %ebp, %esp ( 即 esp = ebp = 0xbfffe658)
pop %ebp ( 也就是 mov %esp,%ebp 再 add $4,%esp )
此时 ebp = 0xbfffe668 回到了原函数的ebp值,
**再执行 0x08048322 : ret
即 pop %eip
( 也就是 mov %esp,%eip 再 add $4,%esp )
此时 eip = 0x08048338
程序继续执行 main 中的 leave
调用fun函数结束。
相关文章推荐
- 调用函数时 寄存器到底发生了那些变化
- 调用函数时,寄存器到底发生了那些变化?
- 每隔一小时生成一个新的日志文件,当寄存器状态发生变化记录一次
- 社群,从1.0发展到3.0到底发生了哪些变化?
- VM Aware和Machine Learning相遇Tintri,存储未来将发生那些变化?
- 在浏览器输入栏敲入一个网址,之后发生了那些变化?
- 你站着编程两年身体会发生那些变化
- [How to]使用自定义cell进行tableview的创建,适用于cell样式不发生变化的情况。
- 老生常谈-从输入url到页面展示到底发生了什么
- Android中如何编写图片选择器,实现按点击按钮时按钮的图片或者颜色发生变化
- 页面发生跳转但是url 不发生变化
- 【OGG-01161】源端表结构发生变化导致replicat进程abend
- Swift 3.0 重大版本发生了哪些变化,各位看官请
- 互联网究竟带来中心化还是去中心化 那些赚钱的模式 探讨下互联网会把社会改造成什么样子,到底是中心化还是去中心化
- 天海投资股东名单发生变化 或因看好公司转型
- 老生常谈-从输入url到页面展示到底发生了什么
- 当数据库某张表数据发生变化时,更新c#程序中缓存的用法
- 数据中心管理人员预计2018年发生的变化
- oracle 临时表 解决 "表 *** 发生了变化,触发器/函数不能读"的问题
- GridView:当鼠标滑过,行的背景颜色发生变化