Chinaunix首页 | 论坛 | 博客
  • 博客访问: 465380
  • 博文数量: 104
  • 博客积分: 3455
  • 博客等级: 中校
  • 技术积分: 1216
  • 用 户 组: 普通用户
  • 注册时间: 2009-01-18 18:33
文章分类

全部博文(104)

文章存档

2015年(3)

2014年(1)

2013年(7)

2012年(8)

2011年(11)

2010年(18)

2009年(56)

我的朋友

分类:

2011-05-16 10:44:57

堆栈帧(the stack frame)是在堆栈中为当前运行的函数分配的区域


#include<stdio.h>
int fun(int x, int y, int z)
{
    int sum;
    sum = x + y + z;
    return sum;
}
int main()
{
    int i;
    i = fun(1,2,3);
    return 0;
}


gcc -S -m32 test.c

.file "test.c"
        .text
.globl fun
        .type fun, @function
fun:
        pushl %ebp               // 此时ebp为main函数的堆栈帧,压栈保存
        movl %esp, %ebp          // ebp指向fun函数的堆栈帧
        subl $16, %esp           // esp下移16个字节,用于保存局部变量
sum
        movl 12(%ebp), %eax      // ebp加12,指向实参y,放入eax
        movl 8(%ebp), %edx       // ebp加8, 指向实参x,放入ebx
        leal (%edx,%eax), %eax   // x+y ,放入eax
        addl 16(%ebp), %eax      // ebp加16,指向实参z,然后加上x+y,放入eax
        movl %eax, -4(%ebp)      // 把x+y+z 放入申请的sum空间
        movl -4(%ebp), %eax      // 然后把求和值放入eax
        leave
        ret
        .size fun, .-fun
.globl main
        .type main, @function
main:
        pushl %ebp              
        movl %esp, %ebp         
        subl $28, %esp           // esp下移28个字节,用于保存局部变量i
        movl $3, 8(%esp)         // 保存实参3
        movl $2, 4(%esp)         // 保存实参2
        movl $1, (%esp)          // 保存实参1
        call fun                 // 调用函数fun,同时把下一个指针的地址压栈
        movl %eax, -4(%ebp)      // ebp减4,为i地址空间.eax保存了fun函数返回值
        movl $0, %eax            // return 0
        leave
        ret
        .size main, .-main
        .ident "GCC: (GNU) 4.4.0 20090514 (Red Hat 4.4.0-6)"
        .section .note.GNU-stack,"",@progbits


             

上图为执行fun函数时的堆栈帧
 

leave指令
等价于
movl %ebp, %esp
popl %ebp
call指令
在取出call之后,执行call之前,首先使EIP指向紧接call的下一条指令,然后将EIP入栈,最后执行跳转.
ret指令
从栈中弹出地址,并跳转到这个位置. (即call指令压入的EIP)

寄存器使用惯例
%eax %ecx %edx 调用过程可以覆盖.
%ebx %edi %esi %esp %ebp 调用过程不能负载,使用前入栈,返回前恢复.

esp 栈顶指针
ebp 堆栈帧指针 ( ebp所指内存保存的值为 previous frame pointer,就是主调函数的ebp堆栈帧指针 ) 

阅读(1005) | 评论(1) | 转发(0) |
0

上一篇:林间小路

下一篇:nonblock and block

给主人留下些什么吧!~~

chinaunix网友2011-06-09 00:04:36

可以啊,我的汇编又忘了。