所谓”当前栈“,指的是ESP的值所指的栈空间。如果ESP的值位于用户栈的范围内,那么程序的当前栈就是用户栈,反之亦然。此外,存储器SS的值还应指向当前栈所在的页。过程如下:
1)保存当前的ESP、SS的值
2)将ESP、SS的值设置为内核栈的相应值
反过来,内核栈切换到用户栈:
1)恢复原来的ESP、SS的值
2)用户态的ESP和SS的值是保存在内核栈上的,内核态的ESP和SS的值不需要保存。
当0x80中断发生的时候,CPU除了切入内核态之外,还会自动完成下列几件事:
1)找到当前进程的内核栈(每一个进程都有自己的内核栈)
2)在内核栈中依次压入用户态的寄存器SS、ESP、EFLAGS、CS、EIP
而当内核从系统调用返回时,需要调用iret指令来回到用户态,iret指令则会从内核栈里弹出寄存器SS、ESP、EFLAGS、CS、EIP的值,使得栈恢复到用户态的状态。这个过程如下:

3)中断处理程序
在中断向量表中找到int 0x80的中断处理程序。Linux的中的处理程序例程:

通过中断号0x80,最后调用函数system_call。通过eax中存放的系统调用号,查找系统调用表,然后调用相应的系统调用函数,即,sys_fork

Q&A
Q:内核里以sys开头的系统调用函数是如何从用户那里获得参数的?
A:我们知道用户系统调用时,根据系统调用参数数量的不同,依次将参数放入EBX、ECX、EDX、ESI、EDI和EBP这6个寄存器中传递。
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-76057-9.html
阿斗还是阿斗
应该是个不错的选择
为什么我看不到