通常使用内存是从低向高地址用,但栈是预留的空间,栈底在高地址,push时,数据是向低地址存放。局部变量寻址,要用到栈的访问。调用函数时,计算机常用栈来存储传递给函数的参数。
栈是一种先进后出的数据结构,栈有一个存储区、一个栈顶指针。栈顶指针指向堆栈中第一个可用的数据项(被称为栈顶)。用户可以在栈顶上方向栈中加入数据,这个操作被称为压栈(Push),压栈以后,栈顶自动变成新加入数据项的位置,栈顶指针也随之修改(指针数值减小)。用户也可以从堆栈中取走栈顶,称为弹出栈(pop),弹出栈后,栈顶下的一个元素变成栈顶,栈顶指针随之修改(指针数值增大)。函数调用时,调用者依次把参数压栈,然后调用函数,函数被调用以后,在堆栈中取得数据,并进行计算。函数计算结束以后,或者调用者、或者函数本身修改堆栈,使堆栈恢复原装。
在参数传递中,有两个重要的问题必须要明确说明:
1.当参数个数多于一个时,按照什么顺序把参数压入堆栈;
2.函数调用后,由谁来把堆栈恢复原状。
在高级语言中,就是通过函数的调用方式来说明这两个问题的。常见的调用方式有:
stdcall(Pascal调用方式)
cdecl(C调用方式)
fastcall(快速调用方式)
thiscall(C++类成员函数缺省的调用方式)
naked call(是一种比较少见的调用方式,一般高级程序设计语言中不常见)
cdecl
cdecl调用方式又称为C调用方式,是C语言缺省的调用方式,它的语法为:
int function(int a, int b)
int _cdecl function(int a, int b)
cdecl的调用方式决定了:
(1)参数从右向左依次压入堆栈
(2) 由调用者恢复堆栈
(3)函数名自动加前导下划线
由于是由调用者来恢复堆栈,因此C调用方式允许函数的参数个数是不固定的,这是C语言的一大特色。
此方式的函数被翻译为:
push b
push a
call funtion
add
在编译时,此方式的函数被翻译成:_function
关于函数的调用有以下几点:
2. C语言中参数是从右向左进栈的。
3. 被调函数使用的堆栈区域结构为:
局部变量(如temp)
返回地址
函数参数
4.由主调函数在调用后清理堆栈(汇编代码:add
5. 函数的返回值一般是放在寄存器中的。