热门关键字:  ubuntu  分区  Fedora  linux系统进程  函数

当前位置 :| 主页>Linux教程>编程开发>

调用函数时 寄存器到底发生了那些变化

来源: 作者: 时间:2007-03-12 Tag: 点击:

一直存在比较模糊的概念,因此用一个例子强化记忆。

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函数结束。




相关文章:
ioctl函数
struts与spring三种整合方法
进程的创建fork
jsp速成
Hibernate单向一对多应注意的问题
Java RMI之HelloWorld篇
常用的Eclipse快捷键
sparc linux 系统调用
一个关于jboss "Halting VM"的情况处理
编写更好的Linux程序3(这次只讲void *)
Tikiwiki 2.2+ Ucenter 1.5(Discuz)整合
玩转ptrace(一)
玩转ptrace(二)
dup2
pipe
Jboss的学习
gcc用法
将UI从代码中解放出来
数据结构与算法(2)
有关于JAVA中的CLASSPATH的作用
const成员函数
虚函数
《c和指针》读书笔记2
初次接触Zend Framework需要掌握的内容
php中require和include的简单区别
正则表达式在PHP中的应用
在PHP中使用与Perl兼容的正则表达式
Zend Studio 生成 wsdl
freebsd7 + php5.2.6 + xdebug2.0.2安装
PHP抓取远程网站数据的代码