C语言参数依照从右到左的顺序依次传入栈中。有几个参数就传入几个参数。
int fun(int a,int b)
{
return a-b;
}
int main(void)
{
fun(5,-1);
return 0;
}
汇编代码
fun:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax
subl 12(%ebp), %eax
popl %ebp
ret
main:
pushl %ebp
movl %esp, %ebp
pushl $-1
pushl $5
call fun
addl $8, %esp
movl $0, %eax
leave
ret
当参数为char ,unsigned char,short,unsigned short时会自动扩展为int。
int fun(char a,unsigned char b,short c,unsigned short d)
{
return 0;
}
int main(void)
{
char a=-1;
unsigned char b=1;
short c=-2;
unsigned short d=2;
fun(a,b,c,d);
return 0;
}
汇编代码
fun:
pushl %ebp
movl %esp, %ebp
pushl %ebx
subl $16, %esp
movl 8(%ebp), %ebx
movl 12(%ebp), %ecx
movl 16(%ebp), %edx
movl 20(%ebp), %eax
movb %bl, -8(%ebp)
movb %cl, -12(%ebp)
movw %dx, -16(%ebp)
movw %ax, -20(%ebp)
movl $0, %eax
addl $16, %esp
popl %ebx
popl %ebp
ret
main:
pushl %ebp
movl %esp, %ebp
pushl %ebx
subl $16, %esp
movb $-1, -10(%ebp)
movb $1, -9(%ebp)
movw $-2, -8(%ebp)
movw $2, -6(%ebp)
movzwl -6(%ebp), %ebx
movswl -8(%ebp), %ecx
movzbl -9(%ebp), %edx
movsbl -10(%ebp), %eax
pushl %ebx
pushl %ecx
pushl %edx
pushl %eax
call fun
addl $16, %esp
movl $0, %eax
movl -4(%ebp), %ebx
leave
ret
以上fun函数都是在一个文件内写的,如果fun函数在另一个文件中,函数参数调用会有什么区别呢?
extern int fun(int a);
int fun2(void)
{
fun(123);
}
int main(void)
{
fun2();
}
汇编代码
fun2:
pushl %ebp
movl %esp, %ebp
subl $8, %esp
subl $12, %esp
pushl $123
call fun
addl $16, %esp
nop
leave
ret
看到subl $12, %esp了吗,12字节+传入的参数123(4字节)=16字节。如果是调用外部函数参数占用的空间大小都会变为16的倍数。
还有subl $8, %esp,8字节+%ebp(4字节)+返回地址(4字节)=16字节。这也是为了数据对齐操作。