code:0751 ~ 0805 - ikarishinjieva/unixV6-code-analyze-chs GitHub Wiki
- trap:
- 汇编版陷入处理函数,用以进行一些初步处理,然后调用C语言版陷入处理函数
0750
0751 /* ------------------------- */
0752 .globl trap, call
- 初始时候的堆栈状态
0753 /* ------------------------- */
0754 .globl _trap
0755 trap:
0756 mov PS,-4(sp)
0757 tst nofault
- 将新PS字入栈
- 注:入栈位置比较诡异,不是直接放在栈顶,而是空开了一个位置,这个位置是留给R0的,后面可以看到
0758 bne 1f
0759 mov SSR0,ssr
- 此处检测是否有错误
- 若出错,跳转至0764行,进行出错处理
0762 jsr r0,call1; _trap
0763 / no return
0764 1:
0765 mov $1,SSR0
0767 rtt
0768
- call1:
- 针对陷入的部分处理
0769 /* -------------------------*/
0770 .globl _runrun, _swtch
0771 call1:
0772 tst -(sp)
0773 bic $340,PS
0774 br 1f
0775
- 栈顶指向PS
- 开中断
- 跳转至778行
- 陷入不执行777行的原因:
- PS已经在上面入过栈了,无需重复入栈
- call:
- 此处是硬中断的处理函数入口
0776 call:
0777 mov PS,-(sp)
- 对于硬中断,由于没有像陷入那样经过756行的处理,所以需要在此处将新PS入栈
0778 1:
- 778 - 805:
- 以下为所有中断(包括硬中断和陷入)的公共处理部分
0779 mov r1,-(sp)
0780 mfpi sp
0781 mov 4(sp),-(sp)
0782 bic $!37,(sp)
0783 bit $30000,PS
0784 beq 1f
- R1,(先前态地址空间的)SP,当前PS字的低五位(俗称dev,在中断处理中用以表明中断类型)入核心栈
- 判断先前态为用户态,若为用户态,跳转至797行
- 当前堆栈状态
0785 jsr pc,*(r0)+
- 785 - 796 :对于先前态为用户态的处理
0786 2:
- 执行中断处理子程序,程序入口地址存放于R0寄存器中
0787 bis $340,PS
0788 tstb _runrun
0789 beq 2f
0790 bic $340,PS
0792 br 2b
0793 2:
0794 tst (sp)+
0795 mtpi sp
0796 br 2f
- dev退栈(被扔了)
- 恢复用户态的sp指针
- 跳转至801行
0797 1:
- 797 - 800:对于先前态为核心态的处理
0798 bis $30000,PS
0799 jsr pc,*(r0)+
0800 cmp (sp)+,(sp)+
0801 2:
- 将先前态 强制 设置为用户态(中断处理程序 需要 访问用户态数据,将先前态强制置为用户态...)
- 执行中断处理子程序,程序入口地址存放于R0寄存器中
- 中断处理完成后,将当前栈顶的两个元素dev和sp相继弹出(他们被扔了)
0802 mov (sp)+,r1
0803 tst (sp)+
0804 mov (sp)+,r0
0805 rtt
- 恢复R1
- 抛弃nps
- 恢复R0
- 中断返回