從C語言到彙編(二)輸入輸出函數

日常運行程序時,我們經常要用到輸入輸出函數。輸入經常來自於鍵盤,輸出經常用於屏幕。而C語言標準庫提供了相應的函數scanf和printf。
scanf函數和printf函數的函數原型是:

int scanf(const char *format, ...);
int printf(const char *format, ...);

可以看出它們都是參數可變的函數。
舉個例子。

#include <stdio.h>
int main(void)
{
	int a;
	int b;
	int c;
	
	scanf("%d %d",&a,&b);
	c=a+b;
	printf("sum=%d\n",c);
	
	return 0;
}	

鍵盤輸入

12 32

輸出

sum=44

scanf函數接受的是"%d %d",一個整數加空格加一個整數。輸入符合要求,所以得到了需要的輸入。
將以上C代碼轉爲彙編代碼。

.section .rodata
	.LC0:.string "%d %d"
	.LC1:.string "sum=%d\n"
.text
.global main
main:
	pushl %ebp
	movl %esp,%ebp
	
	subl $12,%esp
	leal -4(%ebp),%eax
	pushl %eax
	leal -8(%ebp),%eax
	pushl %eax
	pushl $.LC0
	call scanf
	addl $12,%esp
	
	movl -4(%ebp),%eax
	addl -8(%ebp),%eax
	movl %eax,-12(%ebp)
	
	pushl -12(%ebp)
	pushl $.LC1
	call printf
	addl $8,%esp
	
	movl $0,%eax	
	leave
	ret

當我們要調用一個函數時,需要傳入參數,而這裏scanf接受3個參數,leal -4(%ebp),%eax pushl %eax取a的地址,並傳入棧中。leal -8(%ebp),%eax pushl %eax取b的地址,並傳入棧中。將.LC0的地址傳入棧中。調用scanf完成函數的調用,之後函數進入scanf函數內部執行,直至scanf函數的ret指令執行,函數返回到call scanf下一條執令。addl $12,%esp,清理參數佔用的棧空間。這樣完成了scanf函數的調用。同理,printf也是如此。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章