首先,我们的中断处理程序是通过中断门来实现的,因此,需要在中断描述符表中提前注册好中断描述符。
image.png
中断描述符中有段选择子(一般为代码段选择子),自己的属性(DPL),以及中断处理程序的偏移量。当用户进程调用执行软中断的时候还需要进行相应的特权级检查(用户进程的特权级和门特权级以及代码段描述符的特权级需要进行比较),当特权级检查通过之后才能够执行内核的中断处理程序。
如果是用户进程执行系统调用,则是通过软中断来实现的,Linux中通过Int 0x80+eax中存储子功能号的形式执行系统调用,通过如下宏定义的方式,调用int0x80,通过寄存器传参
image.png
image.png
而关于中断号0x80我们是提前注册在中断描述符表中的(其实就是个索引号),然后会调用相应的中断处理程序
image.png
中断处理程序中要进行现场保护(保存用户进程执行系统调用前的一些寄存器映像等),然后在通过子功能数组(其中存放对应子功能的处理函数)来根据具体的子功能执行相应的处理
image.png
这里需要注意,call函数的返回值是存放在eax寄存器中,因此如果想让内核态时eax返回给用户进程,需要在内核态的时候将eax的值写入到用户进程的eax中,即写入到刚才在栈中保存的eax的栈空间中,那么当用户进程从中断中返回的时候,会将栈中的内容进行还原,也就得到了通过内核态计算得到的结果。