C语言的堆栈

来源:互联网 发布:面板数据与截面数据 编辑:程序博客网 时间:2024/03/29 04:19

#include <stdio.h>
void swap(int *a,int *b)
{
        *a=*a^*b;
        *b=*a^*b;
        *a=*a^*b;
}
int main(int argc,char **argv)
{
        int a=100;
        int b=1000;
        swap(&a,&b);
        printf("the num of sub is %d/n",a-b);
        return(a-b);
}

C语言函数的堆栈细述
1堆栈的增加方向是向着低地址方向的

2函数的返回地址是在调用函数里开辟的

3可以这样来表示调用函数时栈桢的变化的esp(栈的顶部的指针)-->ebp(栈的底部)(本操作发生在被调用函数中)

4地址变量也会给开辟空间
5返回值放入寄存器中

5

        .file   "asm.c"
        .version        "01.01"
gcc2_compiled.:
.text
        .align 4
.globl swap
        .type    swap,@function
swap:
        pushl   %ebp                                                     //保存栈桢的底部
        movl    %esp, %ebp                                         //更新栈桢的底部,移动到新的栈桢
       movl    8(%ebp), %ecx                                    //取出&a---->ecx,edx//这两个寄存器在调用函数中就被保存起来                                                                                                                                      //了,不需要被调用函数的维护
        movl    8(%ebp), %edx                           
        movl    12(%ebp), %eax                                   //取出&b---->eax,,并取出b
        movl    (%eax), %eax             
        xorl    (%edx), %eax                                           //异或a,b,结果放到eax
        movl    %eax, (%ecx)                                         //保存到a   //下面有编译器生成的多余的指令
        movl    12(%ebp), %ecx                                    //取出&b---->ecx
        movl    8(%ebp), %edx                                      //取出&a---->edx
        movl    12(%ebp), %eax                                    //取出&b---->eax 并取出b
        movl    (%eax), %eax
        xorl    (%edx), %eax                                            //异或a,b,结果放到eax
        movl    %eax, (%ecx)
        movl    8(%ebp), %ecx
        movl    8(%ebp), %edx
        movl    12(%ebp), %eax
        movl    (%eax), %eax
        xorl    (%edx), %eax
        movl    %eax, (%ecx)
        popl    %ebp
        ret
.Lfe1:
        .size    swap,.Lfe1-swap
                .section        .rodata
.LC0:
        .string "the num of sub is %d/n"
.text
        .align 4
.globl main
        .type    main,@function
main:
        pushl   %ebp                                      //因为main本身就是一个函数、所以,跟swap时一样处理的
        movl    %esp, %ebp
        subl    $8, %esp                                //为整形a,b分配空间
        movl    $100, -4(%ebp)
        movl    $1000, -8(%ebp)
        subl    $8, %esp                                //为地址分配空间
        leal    -8(%ebp), %eax
        pushl   %eax                                      //作为参数调用压栈
        leal    -4(%ebp), %eax
        pushl   %eax
        call    swap
        addl    $16, %esp
        subl    $8, %esp
        movl    -8(%ebp), %edx
        movl    -4(%ebp), %eax
        subl    %edx, %eax
        pushl   %eax
        pushl   $.LC0
        call    printf
        addl    $16, %esp
        movl    -8(%ebp), %edx
        movl    -4(%ebp), %eax
        subl    %edx, %eax
        movl    %eax, %eax
        leave                                                     //movl %ebp,%esp             popl %ebp
        ret
.Lfe2:
        .size    main,.Lfe2-main
        .ident  "GCC: (GNU) 2.96 20000731 (Red Hat Linux 7.1 2.96-98)"

原创粉丝点击