- 论坛徽章:
- 0
|
读了Lions'的UNIX源代码分析,对c语言函数调用有点心得,
这里写出来,抛砖引玉,和大家探讨学习。
//C语言的调用
// 1)参数是从右向左入栈的,也就是说
// 左边参数在栈中的位置更接近栈顶。
// 2)栈是由呼叫函数清理的
// 3)对于优化编译,并不是所有的参数都是经过栈传递
// 可能有的参数是通过寄存器传过来的。
// 比如一个两个参数的函数f(int ,int ),被调用的情形,
f(a,b):
//压入参数:
push b
push a
//调用函数:
call f
//此时栈中包含有返回地址,也就是下条语句的地址。
//所以栈的布局应该是这样的:
入栈参数
返回地址
保存在栈中的寄存器
函数中的临时变量。
//(地址从高---〉低)
//这里有一点应注意,对于临时变量是数组的情况,
//如果没有检查边界长度的话,那末过长的输入
//就可能导致返回地址被覆盖,产生缓冲区溢出的问题。
//清理栈 :
add 8,esp
//备注:如果呼叫函数不是直接清理栈(add 8,esp),而是需要
//获得参数传回的一些信息,比如
pop c
pop d
//那 c 就包含函数f结束时函数中参数a的值,d就包含b的值
//对于硬件中断和陷入很有用,因为好些寄存器被入栈传给调用函数,该函数可能要根据不同的情况调整各个寄存器的值,返回的时候这些寄存器被恢复,改过的内容就在里面了。
// 4)C语言中参数入栈的顺序好处是函数可以是变参数的,
// 因为只要知道第一个参数的地址,那相应的参数(基本类型)地址
// 就可知道,如prinf(char fmt[],...).坏处就是每次调用,
// 呼叫函数都要清理栈,因为只有呼叫函数才知道究竟
// 有多少个参数被入栈,所以这样会轻微增加代码的长度。 |
|