三、图C.7具体内容
文章目录
一、部分知识
1.为什么将中断启动工作安排在取指令阶段?
答:因为相比于在指令译码后测试中断,在取指令阶段进行测试,处理起来会更方便,并且也更利于指令周期的完整进行。否则,太多个指令周期嵌套起来,可能会出现栈溢出的问题。
------②浅浅的说一句,上面提到栈溢出问题,还有一个栈泄露问题。
2.堆栈指针的切换以及堆栈内容的加减
------①P655的Supervisor stack,P657的SP、SSP、USP,还有Saved_SSP、Saved_USP,读书。
------②前面我们曾说过,通用寄存器不一定通用,现如:R6就被作为存放当前栈指针(SP)的专用寄存器。SSP、USP分别是特权模式和用户模式下的栈指针,如果当前处于特权模式下,则SP是SSP;如果当前处于用户模式下,则SP是USP。注意FigA.1中SSP与USP的位置。Saved_SSP、Saved_USP则分别是被储存的特权模式和用户模式下的栈指针。
(1).关于45号状态堆栈指针的切换
答:当发生中断时,我们不确定程序处于用户模式下,还是处于正在中断的情况下又发生了嵌套中断等诸如此类的情况,因此我们必须测试当前权限模式。如图C.7中,在49号状态最后对当前权限模式进行了测试,如果当前处于用户模式则转入45号状态,并将当前栈指针指向的内容存放到Saved_USP,再将Saved_SSP指向的内容加载到当前栈指针里。
(2). 栈及一个案例(P273&P347)
------①栈
-------------( a )栈是一种数据结构,你可以理解为这事一种储存数据的结构。这种结构的构造就像一包纸抽一样:有具体容量、放入的时候只能从下往上一张一张的放、取出的时候只能从上往下的一张一张取,有着先进后出的特点。
-------------( b )当在内存开辟出一段内存空间来作为栈的容量时,它先存放的元素被放置在高地址,它后存放的元素被放置在低地址处。如P275 Fig8.9所示,当栈内元素逐渐增多时,新增的元素被存放在了更低的地址处。
------②如从P347页开始演示的嵌套中断案例,
-------------( a )在A程序执行时,相继接收到了B、C所发出的请求中断,且三者的优先级为C>B>A。因此如Fig 9.20所示,——在程序A执行完x3006处的ADD指令后,开始处理设备B的中断请求;而当设备B执行完x6202处的ADD指令后,又开始处理设备C的中断请求。——之后,直到C设备执行完才返回到设备B被中断处继续执行,又等到B设备执行完才返回到设备A被中断处继续执行,最终完成进程。——这里需要留意的是:之前曾强调过的,子程序最后会执行RTI指令。
-------------( b )现在开始配合Fig C.7的中断启动工作来创造出Fig 9.21,——当程序A执行完ADD指令后接收到B设备请求的中断,这时进入取指令阶段,PC增量,测试INT信号为1;——转入49号状态,再会到37号状态,最终再到18号状态。这个过程将主程序的PSR和主程序下一条该执行指令的地址存入了栈空间。因此在Fig9.21中,先后存入了A、B程序的PSR和下一条指令地址;——再到各子程序执行完,通过当前栈指针将各信息逐项返回,继续执行往外一层剩余的程序;——最终,程序结束。
-------------( c )第二版译版的图10-7错得太明显了。
3.Table、Vector、Table’Vector
(1).Table、Vector
------Table和Vector是两个八位的内部寄存器,
-------------( a )在违反特权模式的情况下,Vector是x00;在非法操作码的情况下的情况下,Vector是x01;在ACV异常的情况下,Vector是x02;其余Vector内容自行在FigC.7中查看。
-------------( b )Tablex00、Tablex01则分别是:系统访问程序入口地址的高八位(x0000 to x00FF)和 中断异常服务程序入口地址的高八位(x0100 to x01FF)。
(2). Table’Vector
------Table’Vector则构成了16位地址。
INTV
4.49状态内容写与存的问题
现在看49号状态的具体内容,可以看到:——在将优先级存入PSR后(PSR[10:8 ]<–Priority),又想保存上一个状态的PSR(MDR<-PSR);——在将0赋给PSR[15]后(PSR[15]<-0),又去测试PSR[15]([PSR[15]])。这内容就很矛盾的。
(1).主从锁存器(P91 Fig3.33)
------①具体结构:——首先在图中找到Master和Slave,分别代表主、从;——他们外侧各有一个方框,每个方框内部就是一个锁存器,它们就分别是主、从锁存器;——因为还没讲到,我们先将锁存器的构造封装起来,只需要知道它能记忆住存储进来的1或0;——图左下角传入了时钟信号,一个时钟周期有高电频和低电频两种时钟信号。——因为时钟信号传入主从锁存器时,一个经过了非门再传入、另一个直接传入,所以当一种时钟信号传入时,主从锁存器是两种情况。
------②在高电频变低电频的一瞬间,Clock被置为0,向主锁存器传入1,主锁存器存数据,向从锁存器传入0,从锁存器什么都不能做;——在低电频变高电频的一瞬间,Clock被置为1,向主锁存器传入0,主锁存器什么都不能做,向从锁存器传入1,从锁存器从主锁存器得数据。
------③所以可以看出,当主锁存器存入数据时,从锁存器的数据并不会直接改变,仍是上一个时钟周期所存的数据。
(2). 49号状态内容
------①一个状态里面的处理步骤是同时进行的,所以对于上面提到的四个步骤,部分是向主锁存器里存值,部分是从从锁存器里取值,它们并不互相影响。
二、Fig C.7 在18号状态里,PC所存地址的指向为即将被执行指令的储存地址
1.权限模式异常
每次测试[PSR[15]]都是对权限模式进行测试,若发生异常则转入45号状态并往下进行。
2.中断启动工作
——(49)当发生中断时,分别设置Table和Vector、将中断程序的优先级写入PSR、将当前PSR保存到MDR中、将PSR[15]赋为0,并对被中断程序的权限模式进行判断;——(45)若被中断程序的权限模式处于用户模式,则切换当前栈指针并转入37号状态,若被中断程序的权限模式处于特权模式,则直接进入37号状态;——(37)将当前栈指针向上移动一项,并将指向的地址存入MAR中;——(41)在多个时钟周期中,将在49号状态里储存的PSR,通过MDR写入内存中MAR的位置上;——(43)PC减一恢复到当前指令所存地址,并存入MDR中;——(46)同37号状态;——(52)在多个时钟周期中,将在46号状态里储存的PC,通过MDR写入内存中MAR的位置上;——(54)将Table’Vector构成的16位地址存入MAR中;——(53)再将内存中MAR位置的内容写入MDR中;——(55)将MDR赋给PC,之后将开始处理异常。
3.RTI
------①当异常处理完成时,需要返回到原来被中断的程序中,这时就需要运行RTI指令。RTI指令的启动工作与 中断启动工作存储PSR和下一条指令地址的过程恰恰相反,先后从栈中取出被中断程序下一条指令的地址和PSR;——(34)在恢复了被中断程序的PC和PSR后,将当前栈指针所指内容往高地址增一位,再测试PSR[15];——(51)如果被中断程序仍处于特权模式下,则什么也不做,进入到下一个指令周期;——(59)如果被中断程序处入用户模式,则将当前栈指针所指内容存入特权栈指针,再将用户栈指针所指内容恢复到当前栈指针中,随后进入下一个指令周期。
------②(44)若在执行RTI指令时,发生权限模式异常,则将处理程序地址装入Table、Vector,将当前执行RTI指令程序的PSR装入MDR中并修改权限模式后,进入45号状态。
4.TRAP&1101&ACV
只要悟了,它们几个都大同小异。需要额外说明的是TRAP指令15号状态中对PC进行了PC+1,来抵消42号状态中的PC-1。因为TRAP是条指令,PC+1才是下一条指令的地址,而不是PC。在ACV异常中,48、56、57、60、61号状态的内容相同。