日常运行程序时,我们经常要用到输入输出函数。输入经常来自于键盘,输出经常用于屏幕。而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也是如此。