0 前言
所谓系统调用,就是用户态程序“伪装”产生一个中断,陷入到内核态执行的过程。
这个特殊的中断,是0x80中断。
1 源码
本周作业要求任意选择一个系统调用,分别使用系统调用API的形式与嵌入式汇编的形式进行分别实现。
为了简单明了,选择了mkdir系统调用,对应了系统调用号0x27。
实现源码如下,
API调用:
嵌入式汇编:
2 实验
分别对程序进行编译,执行,发现可以正常建立文件夹,满足预期结果。
在编译过程中,出现了挺多编译错误。。。
分别是
Error: operand size mismatch for `int' int 后面的操作数忘记加$了
Error: the number of operands mismatch for `mov' mov后面的2个操作数之间忘记了逗号
Error: operand type mismatch for `mov' 操作数类型不匹配,与32-64位有关系
3 分析
从上面源码可以看出,系统调用经历了如下几个过程
1) 系统调用进行之前的准备工作,例如参数设定与传入。
对于API调用,执行传参调用函数即可;
对于嵌入式汇编,在32位X86结构下,将参数依次写入%ebx %ecx %edx %esi %edi %ebp;如果参数超过6个,则使用间接传递的方式,即将参数写入内存,由一个寄存器指向该内存。而系统调用号,写入了%eax;
2) 执行系统调用
对于API调用,直接调用参数。
对于嵌入式汇编,执行int $0x80 指令。
3) 系统调用执行
通过系统调用号,在中断服务例程中执行对应函数。
4) 系统调用返回
对于API调用,直接取函数返回值。
对于嵌入式汇编,32位X86结构下从%eax中取得返回值。
4 总结
最后用一张图来总结一下系统调用的过程。
作者:胡川
原创作品转载请注明出处
《Linux内核分析》MOOC课程
阅读(2707) | 评论(0) | 转发(0) |