>第 19 章 汇编与C之间的关系>函数调用

lixiang lixiang-best@163.com
2002-11-19 19:19:20

08048394 <bar>:
int bar(int c, int d)
{
 8048394:       55                      push   %ebp
 8048395:       89 e5                   mov    %esp,%ebp
 8048397:       83 ec 10                sub    $0x10,%esp
        int e = c + d;
 804839a:       8b 45 0c                mov    0xc(%ebp),%eax
 804839d:       8b 55 08                mov    0x8(%ebp),%edx
 80483a0:       8d 04 02                lea    (%edx,%eax,1),%eax
 80483a3:       89 45 fc                mov    %eax,-0x4(%ebp)
        return e;
 80483a6:       8b 45 fc                mov    -0x4(%ebp),%eax
}
 80483a9:       c9                      leave
 80483aa:       c3                      ret

你好,return e的汇编与源码为何不一致呢?
我的gcc version 4.4.5 (Debian 4.4.5-8)


linux_ooxxooxx codycody23@gmail.com
2009-05-17 07:34:12

图19.1 ,画的不好理解啊,
左边的地址 和右边的指针 都对不上 相应的
内存单元,建议将,左边的地址 和 右边的指针,与内存单元对其 而不要与 单元间的分割线对齐。画图不就是为了好理解吗? 详见王爽的汇编书里的画法,看上去一目了然。


宋劲杉 songjinshan@akaedu.org
2009-05-21 11:06:43

把地址写在线上是为了强调地址是内存单元的首地址。很多书都遵循这一惯例。This won't change.


姚磊 yaolei135@gmail.com
2009-07-16 23:42:06

原文中:

“foo函数调用完之后要返回到call的下一条指令继续执行,所以把call的下一条指令的地址0x80483e9压栈,同时把esp的值减4,esp的值现在是0xbf822d18。”

从图19.1来看,esp的值应该为0xbff1c418才是,怀疑原文有误,后面凡是涉及到esp的值都有类似的问题。


宋劲杉 songjinshan@akaedu.org
2009-07-17 15:37:45

的确,这里有严重的不一致,多谢指出!


朱夜光 zhuyeguang@163.com
2009-07-30 15:25:18

在执行返回的过程中,mov %esp, %ebp; esp+4.最终esp指向的是CALL的下一条语句的地址,但是在执行函数调用前,函数的参数有压栈。所以我觉得esp的值是不是还应该加一条语句:esp+参数个数*4。
这里不是很懂!


宋劲杉 songjinshan@akaedu.org
2009-07-30 18:35:59

你提的问题很好,不过书上讲的也并没有错。你自己写段程序反汇编研究一下就明白了。


朱立华 zhulihua@redoffice.com
2010-04-14 16:28:00

int bar(int c, int d)
{
 8048394:	55                   	push   %ebp
 8048395:	89 e5                	mov    %esp,%ebp
 8048397:	83 ec 10             	sub    $0x10,%esp
	int e = c + d;
 804839a:	8b 55 0c             	mov    0xc(%ebp),%edx
 804839d:	8b 45 08             	mov    0x8(%ebp),%eax
 80483a0:	01 d0                	add    %edx,%eax
 80483a2:	89 45 fc             	mov    %eax,-0x4(%ebp)

在push %ebb, 和 Mov %esp, %ebp之后,为什么要把esp减16?没有读懂。


宋劲杉 songjinshan@gmail.com
2010-05-11 09:54:31

esp减是为了给局部变量e留出空间,所以才能访问-0x4(%ebp),esp减16是为了对齐到16字节边界。


sd44 sd44sd44@yeah.net
2010-10-24 16:14:47

这节已经看不懂了。。。。


rouduanxiong rouduanxiong@yahoo.cn http://learn.akae.cn/media/ch19s01.html
2011-12-26 17:34:15

"所以下面的指令把参数a和b再次压栈,为调用bar函数做准备,然后把返回地址压栈,调用bar函数:
	return bar(a, b);
 80483b0:	8b 45 0c             	mov    0xc(%ebp),%eax
 80483b3:	89 44 24 04          	mov    %eax,0x4(%esp)
 80483b7:	8b 45 08             	mov    0x8(%ebp),%eax
 80483ba:	89 04 24             	mov    %eax,(%esp)
 80483bd:	e8 d2 ff ff ff       	call   8048394 <bar>"
这里的意思是否是变量b、a赋值成3、2的意思,如果不是那之前0xbff1c41c和0xbff1c420地址对应内存单元应该是3和2而不是b:3和a:2吧,如果是那此时esp值为0xbff1c414,+4和+0分别对应0xbff1c418和0xbff1c41c,将3和2给此2内存单元又不对?对“把参数a和b再次压栈”这个概念不清楚呀


如果您有建设性意见,哪怕只是纠正一个错别字,也请不吝赐教,您留下的姓名和email将会出现在本书前言的致谢中。再次感谢您的宝贵意见!