URN Logo
UNIX Resources » Linux » China Linux Forum » C/C++编程版 » 35 » [精华] [FAQ] 调用函数时,寄存器到底发生了那些变化?
announcement 声明: 本页内容为中国Linux论坛的内容镜像,文章的版权以及其他所有的相关权利属于中国Linux论坛和相应文章的作者,如果转载,请注明文章来源及相关版权信息。
Resources
China Linux Forum(finished)
Linux Forum(finished)
FreeBSD China(finished)
linuxforum.net
  业界新闻与评论
  自由软件杂谈
  IT 人生
  Linux软件快递
  翻译作坊
  Linux图书与评论
  GNU Emacs/XEmacs
  Linux 中文环境和中文化
  Linux桌面与办公软件
  Linux 多媒体与娱乐版
  自由之窗Mozilla
  笔记本电脑上的Linux
  Gentoo
  Debian 一族
  网络管理技术
  Linux 安装与入门
  WEB服务器和FTP服务器
  域名服务器和邮件服务器
  Linux防火墙和代理服务器应用
  文件及打印服务器
  技术培训与认证
  Linux内核技术
  Linux 嵌入技术
  Linux设备驱动程序
  Linux 集群技术
  LINUX平台数据库
  系统和网络安全
  CPU 与 编译器
  系统计算研究所专栏
  Linux下的GUI软件开发
  C/C++编程版
  PHP 技 术
  Java&jsp技术
  Shell编程技术
  Perl 编 程
  Python 编 程
  XML/Web Service 技术
  永远的Unix
  FreeBSD世界
   
[精华] [FAQ] 调用函数时,寄存器到底发生了那些变化?
Author: sanool    Posted: 2005-04-15 15:19    Length: 3,866 byte(s)
[Original] [Print] [Top]
一直存在比较模糊的概念,因此用一个例子强化记忆。

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函数结束
[Original] [Print] [Top]
« Previous thread
程序运行总是提示 segmentation fault (core dumped)是什么错啊?
C/C++编程版
35
Next thread »
有没有人使用 bjam/jam?
     

Copyright © 2007 UNIX Resources Network, All Rights Reserved.      About URN | Privacy & Legal | Help | Contact us
备案序号: 京ICP备05006143    webmaster: webmaster@unixresources.net
This page created on 2008-07-17 03:53:00, cost 0.038348913192749 ms.