我的博客:www.while0.com
我的博客:www.shishangguan.net
区别:
- 系统调用的参数存储在寄存器中,函数调用的则存储在堆栈中。
- 系统调用使用中断方式,函数调用使用call指令
相同之处:
- 都有返回值和输入值
- 返回值都存储在%eax寄存器中
下边详细介绍他们的不同之处:
系统调用:
- 使用:在%eax中存储系统调用号(可以在linux系统的/user/include/asm/unistd.h文件中查找可用的linux系统调用),然后使用0x80中断。
- 传参数:
- %EBX 第一个参数
- %ECX 第二个参数
- %EDX 第三个参数
- %ESI 第四个参数
- %EDI 第五个参数
- 返回值:
%EAX
- 例子:
1 movl $1, %eax #exit调用的调用号是1,要把调用号存储在%eax中 2 movl $0, %ebx #exit调用接收一个参数,即程序退出值,第一个参数放在%ebx中 3 int %0x80 #使用0x80中断,引发linux系统调用
函数调用(主要讲解标准类C函数):
- 使用
- 第一步,给堆栈中放参数
- 第二步,调用函数
- 第三步,清空堆栈
- 定义
1 .type funcname, @function 2 functionname: 3 pushl %ebp 4 movl %esp, %ebp #开头部分可以用enter指令代替 5 6 ............ 7 8 movl %ebp, %esp #结尾部分可以用leave指令代替 9 popl %ebp 10 ret
- 传参数
调用函数时堆栈情况如下图:
因为%ESP是不停变化的,所以通常把%ESP复制到%EBP寄存器中,并且把旧的%EBP寄存器也放到堆栈中,如下图所示:
这样我们就可以拿到参数值了。 - 给整个程序传命令行参数
程序运行时堆栈如图所示: - 返回值
在类C标准中,返回值存放在%EAX寄存器。