LKD(Linux内核设计与实现) Chapter 5 System Calls

当一个进程要进行系统调用的时候,它要先停止,然后把执行交给内核,这个过程英文叫做trapping。trap在英文中是陷阱的意思,用在系统调用上算是非常贴切。

目前在x86系统上,进入系统调用的方式有两种,一是通过软中断,二是通过特殊指令。不管何种方式,每个系统调用都由一个向量标识,可带若干参数。

软中断方式进入

这种方式下,程序在用户空间由0x80中断进入系统调用,0x80的中断处理函数根据向量标识来识别系统调用。在使用i386ABI的系统,向量标志在arch/x86/entry/syscalls/syscall_32.tbl定义:

write()的向量标识是4exit()的是1,下面的hi.s举例看如何在汇编代码中调用这两个系统调用:

使用gcc命令gcc hi.s -o hi编译后执行./hi,可见输出:

sysenter/syscall指令进入

采用软中断的方式存在一个问题,就是操作比较繁琐,要先找到系统调用表,然后查表再跳转到执行代码段。如果能把系统调用表地址和执行代码段地址硬编码到指令中,就可以省略一些内存访问操作,加快速度。这些操作由相应的的sysenter/syscall指令实现,sysenter一般应用在32位系统,syscall一般应用在64位系统。