Q:怎么从用户态切换到内核态
A:用户程序调用系统调用的时候,用户程序先将系统调用号放入eax,执行int0x80指令触发中断,中断发生时,cpu切入内核态,从 用户栈 切换到 内核栈 ,在 内核栈 中依次压入用户态的寄存器,也就是保护现场,根据中断号在中断向量表中查找对应的中断处理程序,并调用它。
中断
中断:操作系统是通过中断来从用户态切换到内核态
中断分两种:
硬件中断:电源掉电,键盘被按下
软件中断:i386下是 int 指令
linux上系统调用的中断号是0x80,而windows上是0x2E
中断号有限,所以不可能用一个中断号去对应一个系统调用,于是引进了系统调用号,用一个中断号来表示触发系统调用,然后根据eax里的系统调用号,来确定调用哪一个系统调用。
保护现场:由int依次压入寄存器SS,ESP,EFLAGS,CS,EIP
恢复现场:由iret依次弹出寄存器
system
调用int0x80后,根据中断向量表找到0x80是system_call
-
system_call首先将各种寄存器压入栈中(依次是EBX,ECX,EDX,ESI,EDI,EBP,作为系统调用的参数)
-
调用sys_call_table(0, %eax, 4)查找中断服务程序并执行
-
执行结束后恢复被保存的寄存器
-
最后通过指令iret从中断处理程序中返回。
用户态 内核态
为什么要有用户态和内核态
操作系统为了让不同的代码运行在不同的模式上,限制他们的权利,提高稳定性和安全性,CPU划分出两个权限等级 -- 用户态 和 内核态
用户态:cpu只能受限的访问内存
内核态:cpu可以访问内存所有数据
Q:谈谈用户态和内核态
A:操作系统为了让不同的代码运行在不同的模式上,限制他们的权利,提高稳定性和安全性,CPU划分出两个权限等级 -- 用户态 和 内核态,处于用户态时cpu只能受限的访问内存,处于内核态时cpu可以访问内存所有数据,应用程序基本上都是运行在用户态的,而系统调用时运行在内核态的。