当前位置: 代码迷 >> 汇编语言 >> 对于汇编代码pushl %ebp movl %esp,%ebp 了解无能
  详细解决方案

对于汇编代码pushl %ebp movl %esp,%ebp 了解无能

热度:187   发布时间:2016-05-02 04:32:31.0
对于汇编代码pushl %ebp movl %esp,%ebp 理解无能啊
最近在看《深入理解计算机系统这本书》,对于它汇编出来的代码不能理解呢。
源文件中含以下代码
1 int simple(int *xp, int y)
2 {
3 int t = *xp + y;
4 *xp = t;
5 return t;
6 }

使用-S -01运行GCC 产生的汇编代码有以下一段:
1 simple:
2 pushl %ebp   
3 movl %esp,%ebp   //这个时候栈顶存的是什么要给栈基址的?
4 movl 8(%ebp),%eax  //这个里面的8和12是怎么得出来的呀,bdp+4 又是什么东西呢?
5 movl (%eax),%edx 
6 addl 12(%ebp),%edx 
7 movl %edx,(%eax) 
8 movl %edx,%eax  //书上说这里完成了把t作为返回值,这一点是怎么做到的?
9 movl %ebp,%esp 
10 popl %ebp 
11 ret 

我自己理解不通呢,知道自己有很多理解错误以及不够的地方,希望大神们来教下小虾米哈,注释后面是我不能理解的地方。
------解决方案--------------------
通常情况下在 x32程序 函数用 Eax 作为返回值
去了解下 stdcall 调用约定

;这里将esp 赋给ebp 是为了方便计算偏移
pushl %ebp   
movl %esp,%ebp 
;此时堆栈情况
int   y                ;ebp + 12
int *xp              ;ebp + 8
函数返回地址 ;ebp + 4
ebp                  ;ebp + 0
参数 int *xp 与参数 int y 占用空间均为4字节

------解决方案--------------------
栈,也是在普通的存储空间里,当以栈的方式来访问时,才遵循先进后出,以其它方式来访问,就随意了;这样以不同的方式来操作同一数据存储结构,类似于高级语言里对变量访问的类型转换(好像是越来越不被支持了?)。
------解决方案--------------------
1 simple:                                                                        ;[0-retaddr,4-par2,8-par1]
2 pushl %ebp                                                                     ;[0-(old_ebp),4-retaddr,8-par2,12-par1]
3 movl %esp,%ebp   //这个时候栈顶存的是什么要给栈基址的?                        ;  ^new_ebp==esp
4 movl 8(%ebp),%eax  //这个里面的8和12是怎么得出来的呀,ebp+4 又是什么东西呢?retaddr
5 movl (%eax),%edx
6 addl 12(%ebp),%edx                                                             ; edx=par2+par1
7 movl %edx,(%eax)                                                               ; eax=edx
8 movl %edx,%eax  //书上说这里完成了把t作为返回值,这一点是怎么做到的?          ; 规定/约定eax中保存返回值
9 movl %ebp,%esp
10 popl %ebp                                                                     ;[0-retaddr,4-par2,8-par1]
11 ret                                                                           ; ^esp
                                                                                  

...                       ;[]
         push par1        ;[0-par1]
         push par2        ;[0-par2,4-par1