有时候调用者需要向被调用者
传递参数
,同时被调用者也可能需要向调用者返回数据
。
默认情况下X64
(英特尔64位)中前6个参数存放在一组约定的寄存器中,其余参数以从右到左
的顺序压入堆栈
,因此调用者可以访问这组寄存器或堆栈
来获取参数。而在X86
(英特尔32位)中会直接将所有的参数以从右到左
的顺序压入堆栈,所以调用者只需要访问堆栈
就可以获取参数。
另外当被调用函数引用了参数的内存地址,那么这个参数也必须放在栈中,因为寄存器是没有内存地址的。
C语言中参数传递的例子(以X64
为例):
void Q(long arg1, long arg2, long arg3, long arg4, long arg5, long arg6, long arg7, long arg8) {
printf("this is Q.\n");
return;
}
void main() {
printf("readying to call Q.\n");
Q(1, 2, 3, 4 ,5 ,6 ,7 ,8);
return;
}
上面代码中函数Q
有8个参数,前6个参数通过寄存器传递,多出来的2个参数arg7
和arg8
以从右到左
的顺序压入堆栈,所以这里的压栈顺序是先arg7
后arg8
。为了方便绘图所以这里使用了long
类型,它占8个字节刚好对应图中一个单元格。
压栈过程:
函数最多只会有一个返回值,所以通常就直接放在寄存器中,然后调用者再从这个寄存器中获取返回值。