.text
.set SEG_KDATA_SEL ,0x10 #selector for SEG_KDATA
#vector.S send all trap here
.globl alltraps
alltraps: // <!-- @page { margin: 0.79in } P { margin-bottom: 0.08in } -->
alltraps 的主要任务是设置 和恢复 调用堆栈, <!-- @page { margin: 0.79in } P { margin-bottom: 0.08in } -->
而 trap 的输入为 trapframe* , trapframe 中 eip 、 cs 等由硬件设置 , trapno 和 err 由 vectors.S 中的代码设置 , alltraps 要做的就是依照下图顺序把 ds 、 es 、其他所有寄存器压入堆栈。一方面为了保存中断现场 ,另一方面也为中断处理程序获得与中断有关的信息提供方便 。
<!-- @page { margin: 0.79in } P { margin-bottom: 0.08in } -->
#build trap frame
pushl %ds //ds,es 进栈 保存当前数据段的内容
pushl %es
pushal // 参照x86.h 对于trapframe结构的定义将trapframe的内容压入栈中
#set up data segment
movl $SEG_KDATA_SEL ,%eax //将当前数据段设置为内核数据段
movw %ax ,%ds
movw %ax ,%es
#call trap(tf),where tf= %esp
pushl %esp //以直向trapframe 内容的指针(esp)作为参数,调用trap函数
call trap//
addl $4 ,%esp
#return falls through to trapret
.globl trapret
trapret:
popal //出栈
popl %es //es出栈
popl %ds //ds出栈
addl $0x8, %esp #trapno and errcode
iret //中断返回
#A forked process switch to user mode by calling
#forkret1(tf),where tf is the trap frame to use
.global forkret1
forkret1:
movl 4(%esp),%esp
jmp trapret
-
trapframe*
pusha 压的寄存器
es
ds
trapno
Err
eip
cs
....