关闭

2006-05-26 (1)C语言函数的堆栈细述

1570人阅读 评论(0) 收藏 举报

#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)"
.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
        movl    %esp, %ebp
        subl    $8, %esp
        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
        ret
.Lfe2:
        .size    main,.Lfe2-main
        .ident  "GCC: (GNU) 2.96 20000731 (Red Hat Linux 7.1 2.96-98)"

 

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:308389次
    • 积分:4964
    • 等级:
    • 排名:第5901名
    • 原创:181篇
    • 转载:0篇
    • 译文:0篇
    • 评论:21条
    文章分类