Figure 1.2 read()函数执行过程
以read为例,其功能是从一个资源中复制数据到进程所申请的空间。如图1.2所示,如果不考虑系统调用的触发机制而只考虑系统调用本身,read()系统调用的流程是:参数压栈->EAX置_NR_READ(系统调用号,在<asm/unistdh>中定义)->其他寄存器或连续储存区域存储参数(取决于参数长度)->INT 0x80指令-> 转入内核运行->检查错误,返回->出栈,用户进程恢复运行。对于具体读文件的过程中是在内核中运行的,用户程序并不清楚所有在Kernel Space运行的过程,它只是提供了参数,然后发出了read命令。因此,对于x86平台,系统调用的主要过程是:用户进程进行必要的寄存器参数设置后,执行INT 0x80指令,系统硬件切换用户堆栈到核心堆栈,并将SS、ESP、EFLAGS、CS、EIP压入到核心堆栈中,然后执行system_call调用,该调用保存寄存器参数值,并根据EAX寄存器的值确定sys_call_table表中对应的系统调用函数,然后执行该函数,函数执行完毕后返回到system_call,system_call恢复寄存器(部分寄存器可能已修改),然后执行IRET指令,该指令根据保存到核心栈的SS和ESP切换到用户栈,并恢复原有的代码段选择子和程序执行指针,从而回到用户进程继续运行。
系统调用一般有两种激活方法:system_call函数和lcall7调用门(call gate)(syscall函数是通过lcall7实现的,不能算独立的一种方法)。其中一般使用的是system_call函数,由于本文并不涉及激活方法研究,故使用system_call函数说明。
文章来源于领测软件测试网 https://www.ltesting.net/