從C語言到彙編(九)函式引數
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位元組。這也是為了資料對齊操作。