函数调用中参数传递的内在机制#

**

函数调用中参数传递的内在机制

**

****函数调用,其执行过程如下:①在内存的栈空间中为其分配一个栈帧,用来存放该函数的形参和局部变量;②将实参的值复制给相应的形参变量;③控制流转移到该函数的起始位置;④该函数开始执行;⑤控制流和返回值返回到函数调用点,栈帧释放。在此过程中堆栈完成了两个非常重要的工作:①实现了函数调用过程中现场的保护和恢复;②完成了参数的传递。另外,堆栈是动态的,在调用函数时动态申请内存, 函数执行完毕后又及时地释放内存,这对于充分利用计算机内存资源,提高程序的执行效率有着十分重要的意义。

C/C++参数传递分为值传递、指针传递、引用传递,java主要是值传递和引用传递。计算机以地址作为参数(引用传递、指针传递)进行函数调用与以值作为参数进行函数调用几乎没有什么差别,惟一不同的是前者是将实参的地址压入堆栈,而后者是将实参的数值压入堆栈,在整个函数执行完毕后,前者实参的数值发生了变化,而后者实参的数值没有发生任何变化。
下图为参数传递时栈的示意图,程序调用函数时首先将实参的值压入堆栈(C语言中压栈的顺序是从右到左),然后才进行函数的调用。在调用函数时,先将调用函数的下一条指令的偏移量(段内调用)压入堆栈(保护现场),作为函数返回的地址,再将ebp(形式参数)的值压入堆栈,并通过EBP指针来向被调用的函数传递参数。整个函数调用完毕后,恢复调用前相关寄存器的值,堆栈恢复为函数调用前的状态。需要注意的时C语言在调用函数时是在堆栈上临时存放被调函数参数的值,即C语言是传值类语言,没有直接的方法可用来在被调用函数中修改调用者变量的值。因此为了达到修改的目的就需要向函数传递变量的指针(即变量的地址)。****

函数调用中参数传递的内在机制#
(图片来源于中国知网)

lua函数调用原理主要分为:
(1)受保护调用,用C层面的堆栈来保护和恢复状态
(2)不受保护的调用,使用自定义的栈存储结构CallInfo数组作为调用栈,修正数据栈,然后把字节码的执行位置跳转到被调用的函数开头,lua 函数的return操作则做了相反的操作,恢复数据栈,弹出 CallInfo ,修改字节码的执行位置,恢复到原有的执行序列上。