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

原创 2006年05月26日 12:25:00

#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)"

 

相关文章推荐

Poedu_C语言_lesson26_20161008_文件处理函数

一些常用的文件处理函数

Linux gcc 利用反汇编来研究C语言函数堆栈的分配方式

越来越感觉学习C和汇编才是最能接近计算机本质的途径。所以,今天开始研究汇编了,先从gcc反汇编开始。     首先是下面的C代码: #include int sum(int a,int b) { ...

嵌入式C语言笔记03——函数指针,内存陷阱,堆栈

嵌入式C语言笔记03——函数指针,内存陷阱,堆栈 http://insswer.iteye.com/blog/1040408 嵌入式C语言笔记03——函数指针,内存陷阱,堆栈 函数指...
  • wenhui_
  • wenhui_
  • 2011年09月19日 22:06
  • 2149

iOS开发学习之C语言---C05 函数-2

// //  operation.h //  C05 函数-2 // //  Created by xalo on 15/10/20. //  Copyright (c)...

【C语言】05-printf和scanf函数

本文目录 一、printf函数二、scanf函数 说明:这个C语言专题,是学习iOS开发的前奏。也为了让有面向对象语言开发经验的程序员,能够快速上手C语言。如果你还没有编程经验,或者对...

为何C语言(的函数调用)需要堆栈,而汇编语言却不需要堆

之前看了很多关于uboot的分析,其中就有说要为C语言的运行,准备好堆栈。 而自己在Uboot的start.S汇编代码中,关于系统初始化,也看到有堆栈指针初始化这个动作。但是,从来只是看到有人说...

C语言函数调用中堆栈知识

C语言的程序运行可以说就是不断的调用函数,从主入口的main函数到各种各样的库函数,再到用户自定义的完成特定功能的函数。 程序中关于一个函数的操作主要包括三个方面。①函数声明,②函数定义,③函数调用...

C语言:一个涉及指针函数返回值与printf乱码、内存堆栈的经典案例

一个奇怪的C语言问题,涉及到指针、数组、堆栈、以及printf。下面实现: 整数向字符串的转换,返回字符串指针,并在main函数中调用printf显示。 #include#include#inc...

C语言函数堆栈的思考

源于一段课程案例的代码,拿编译器编译一下,结果不对,反复查了一下,无意中把结果改出来了,于是修改代码探索原因。虽然还有一些地方不太明确的,先总结一笔。   源码是这样的:  ...

C语言高级实例解析[1].part05

  • 2008年10月08日 20:44
  • 2.86MB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:2006-05-26 (1)C语言函数的堆栈细述
举报原因:
原因补充:

(最多只允许输入30个字)