c语言入栈函数 c语言函数入栈顺序

c语言函数参数入栈顺序

从右向左;

为西和等地区用户提供了全套网页设计制作服务,及西和网站建设行业解决方案。主营业务为成都网站设计、做网站、西和网站设计,以传统方式定制建设网站,并提供域名空间备案等一条龙服务,秉承以专业、用心的态度为用户提供真诚的服务。我们深信只要达到每一位用户的要求,就会得到认可,从而选择与我们长期合作。这样,我们也可以走得更远!

例如:f(int a, int b, int c)

c先入栈,然后b,其次a;

C语言函数调用栈

程序的执行过程可看作连续的函数调用。当一个函数执行完毕时,程序要回到调用指令的下一条指令(紧接call指令)处继续执行。函数调用过程通常使用堆栈实现,每个用户态进程对应一个调用栈结构(call stack)。编译器使用堆栈传递函数参数、保存返回地址、临时保存寄存器原有值(即函数调用的上下文)以备恢复以及存储本地局部变量。

不同处理器和编译器的堆栈布局、函数调用方法都可能不同,但堆栈的基本概念是一样的。

寄存器是处理器加工数据或运行程序的重要载体,用于存放程序执行中用到的数据和指令。因此函数调用栈的实现与处理器寄存器组密切相关。

AX(AH、AL):累加器。有些指令约定以AX(或AL)为源或目的寄存器。输入/输出指令必须通过AX或AL实现,例如:端口地址为43H的内容读入CPU的指令为INAL,43H或INAX,43H。目的操作数只能是AL/AX,而不能是其他的寄存器。 [5]

BX(BH、BL): 基址寄存器 。BX可用作间接寻址的地址寄存器和 基地址寄存器 ,BH、BL可用作8位通用数据寄存器。 [5]

CX(CH、CL):计数寄存器。CX在循环和串操作中充当计数器,指令执行后CX内容自动修改,因此称为计数寄存器。 [5]

DX(DH、DL):数据寄存器。除用作通用寄存器外,在 I/O指令 中可用作端口 地址寄存器 ,乘除指令中用作辅助累加器。 [5]

2.指针和 变址寄存器

BP( Base Pointer Register):基址指针寄存器。 [5]

SP( Stack Pointer Register): 堆栈指针寄存器 。 [5]

SI( Source Index Register):源变址寄存器。 [5]

DI( Destination Index Register):目的变址寄存器。 [5]

函数调用栈的典型内存布局如下图所示:

图中给出主调函数(caller)和被调函数(callee)的栈帧布局,"m(%ebp)"表示以EBP为基地址、偏移量为m字节的内存空间(中的内容)。该图基于两个假设:第一,函数返回值不是结构体或联合体,否则第一个参数将位于"12(%ebp)" 处;第二,每个参数都是4字节大小(栈的粒度为4字节)。在本文后续章节将就参数的传递和大小问题做进一步的探讨。 此外,函数可以没有参数和局部变量,故图中“Argument(参数)”和“Local Variable(局部变量)”不是函数栈帧结构的必需部分。

其中,主调函数将参数按照调用约定依次入栈(图中为从右到左),然后将指令指针EIP入栈以保存主调函数的返回地址(下一条待执行指令的地址)。进入被调函数时,被调函数将主调函数的帧基指针EBP入栈,并将主调函数的栈顶指针ESP值赋给被调函数的EBP(作为被调函数的栈底),接着改变ESP值来为函数局部变量预留空间。此时被调函数帧基指针指向被调函数的栈底。以该地址为基准,向上(栈底方向)可获取主调函数的返回地址、参数值,向下(栈顶方向)能获取被调函数的局部变量值,而该地址处又存放着上一层主调函数的帧基指针值。本级调用结束后,将EBP指针值赋给ESP,使ESP再次指向被调函数栈底以释放局部变量;再将已压栈的主调函数帧基指针弹出到EBP,并弹出返回地址到EIP。ESP继续上移越过参数,最终回到函数调用前的状态,即恢复原来主调函数的栈帧。如此递归便形成函数调用栈。

EBP指针在当前函数运行过程中(未调用其他函数时)保持不变。在函数调用前,ESP指针指向栈顶地址,也是栈底地址。在函数完成现场保护之类的初始化工作后,ESP会始终指向当前函数栈帧的栈顶,此时,若

c语言怎么调用栈函数

给你个例子:

#include

//写好加法,以便调用

int sum(int x1,int x2)

{

int x3=x1+x2;

return x3;

}

void main()

{

int a=0;

int b=0;

int c=0;

printf("请输入两个整数\n");

scanf("%d%d",a,b);

c=sum(a,b);//传递参数给sum()函数,返回他们的和

printf("%d+%d的和是:%d\n",a,b,c);

}

总之:就是你把一种方法写到单独的块,这里就是sum()函数,执行一个单一的功能,在main函数调用就是了!

C语言入栈出栈操作的程序,希望有人为我解答

您好:

你是在学习数据结构方面的知识吧。

首先呢,你学习栈,要了解栈的定义,明白它是怎么一回事,就是去理解他的思想。

最后才去用代码来体现出来。

栈是先进后出,其实是用代码控制的,

其实你要他先进先出也可以。

你只要明白他的原理就行。

代码,你可以理解为跟计算的一种对话的语言。

不用想的那么复杂。

就好比说话,你只要知道你要说什么就行(算法),而不用刻意明白要怎么说(语法)。

下面给我出我以前写的代码,关于栈的,顺序栈,其实还有链栈。

/*   数据结构-栈   */

/*   异常的细节处理还没弄好*/

#include iostream

#include stdlib.h

#include malloc.h

#define len_chu_shi 50   //初始空间大小

#define len_zeng_jia 10  //额外增加空间大小

#define OK 0       //正确

#define OVER -2     //

#define ERROR -1   //

using namespace std;

typedef int elem_type;          //元素类型

typedef int function_type;      //函数类型

typedef struct zhan

{

elem_type *top;    //栈顶

elem_type *base;   //栈底

int len;           //当前空间大小

}zhan;                //栈结构

function_type Init_zhan(zhan *exam);//初始化栈

function_type Get_top(zhan *exam,elem_type *e);//获取栈顶元素

function_type Add_top(zhan *exam,elem_type *e);//增加栈顶元素

function_type Delete_top(zhan *exam, elem_type *e);//删除栈顶元素

int main(int argc,char *argv[])

{

zhan *example = (zhan *)malloc(sizeof(zhan));

Init_zhan(example);

return OK;

}

function_type Init_zhan(zhan *exam)

{

exam-base = (elem_type *)malloc(len_chu_shi*sizeof(elem_type));

if(!exam-base)  //分配失败

exit(OVER);

exam-top = exam-base;

exam-len = len_chu_shi;

return OK;

}//--end

function_type Get_top(zhan *exam,elem_type *e)

{

if(!exam-base)

exit(OVER);

*e = *(exam-top - 1);  //不能用自减运算符,那样会改变栈顶指针的值

return OK;

}//--end

function_type Add_top(zhan *exam,elem_type *e)

{

if(exam-len = exam-top - exam-base)  //我个人觉得,如果 已经"",就已经数据溢出了,就应该报错

exam-base = (elem_type *)realloc(exam-base,(exam-len + len_zeng_jia)*sizeof(elem_type));

if(!exam-base)  //分配失败

exit(OVER);

*(exam-top++) = *e;   //应该是先改变栈顶指针的内容,然后栈顶指针再自增

exam-len += len_zeng_jia;

return OK;

}//--end

function_type Delete_top(zhan *exam, elem_type *e)

{

if(!exam-base)  //空栈

exit(OVER);

*e = *(--exam-top);  //应该是栈顶指针先自减,然后获取栈顶指针的内容

return OK;

}//--end


文章标题:c语言入栈函数 c语言函数入栈顺序
分享URL:http://hbruida.cn/article/ddejegh.html