對于中斷處理程序中使用到的寄存器,如果主程序中也要使用該寄存器就會發(fā)生沖突。常見的需要保護的寄存器有A、B、DPTR、PSW和工作寄存器組。由于本技能訓(xùn)練的中斷處理程序十分簡單,對主程序沒有影響,所以未進行保護現(xiàn)場,而一般的中斷處理程序均需要保護現(xiàn)場。常見的幾種保護現(xiàn)場的方法如下:
(1)累加器A的保護
累加器A是程序中使用最為頻繁的寄存器,中段處理程序中如果需要使用累加器A,就會改變A的數(shù)值。這樣中斷調(diào)用返回后,主程序中的輸出控制字就被破壞了,造成輸出錯誤。為了防止這種現(xiàn)象的出現(xiàn),在中斷處理程序中首先將需要使用的寄存器壓入堆棧保存,中段處理程序完成后再使其彈出堆棧。以流水燈的中斷程序為例,這一程序如下:
K1:PUSHACC;將累加器A壓入堆棧
MOVR6,#0FFH;中斷處理程序
...............
K2:POPACC;從堆棧中彈出數(shù)據(jù)到累加器A中
RETI;中斷返回
注意:將累加器A壓入堆棧的指令不是PUSHA,而是PUSHACC。這里ACC是匯編語言默認的符號,它代表累加器A的地址0E0H。
(2)程序狀態(tài)字的保護
由于程序狀態(tài)字寄存器PSW有幾個標(biāo)志位是執(zhí)行指令時自動設(shè)置的,如果子程序中有改變程序狀態(tài)字寄存器PSW的指令,則一定要將PSW壓入堆棧保護。
例如:主程序指令如下:
ADDA,#0FH
JCL1
其中第一條指令會根據(jù)運算結(jié)果改變進位標(biāo)志位C的狀態(tài),而第二條指令需要根據(jù)C的狀態(tài)決定是否轉(zhuǎn)移。如果執(zhí)行完第一條指令后發(fā)生中斷,中斷處理程序中有改變了C的狀態(tài),這樣終端返回後在執(zhí)行JCL1 時就會發(fā)生錯誤。盡管在主程序和子程序中并未直接出現(xiàn)PSW ,但是卻出現(xiàn)了PSW 寄存器沖突。為了避免這種情況的出現(xiàn),子程序中只要使用了能影響PSW中某一位的指令,則一定要將PSW壓入堆棧保護。
影響PSW中標(biāo)志位的指令參考指令表。
(3)工作寄存器組的保護
由于并沒有PUSHRn指令,所以需要將工作寄存器壓入堆棧是只能使用地址。例如:要將R6對應(yīng)的地址壓入堆棧。但是根據(jù)PSW中RS0和RS1的數(shù)值,R6可能對應(yīng)4格地址,即06H、0EH、16H、1EH,究竟應(yīng)當(dāng)壓哪一個地址判斷起來比較麻煩。工作寄存器族的設(shè)置則提供了一個保護工作寄存器的簡單方法。
程序設(shè)計前可以將4格工作寄存器組安排在不同的程序段中,如第0組安排在主程序中使用、第1組安排在外部中斷0中使用等。在外部中斷0的處理程序中首先將PSW壓入堆棧,然后設(shè)置RS1=0、RS0=1,這樣再使用工作寄存器時就會直接使用第1組工作寄存器組,而不影響第0組工作寄存器組。中斷處理程序執(zhí)行完后彈出PSW,就直接恢復(fù)了程序中的工作寄存器組。工作寄存器組及其對應(yīng)地址見表:
工作寄存器組及其對應(yīng)的地址
PSW.4 RS1 | PSW.3RS0 | PSW | 組 | R0-R7 |
0 | 0 | #00H | 第0組 | 00H-07H |
0 | 1 | #08H | 第1組 | 08H-0FH |
1 | 0 | #10H | 第2組 | 10H-17H |
1 | 1 | #18H | 第3組 | 18H-1FH |
保護方法舉例如下:
PUSHPSW;將PSW壓入堆棧
MOVPSW,#08H;使用第1組工作寄存器組
.......................;中斷處理程序
POPPSW;恢復(fù) PSW
RET;中斷返回
(4)DPTR的保護
DPTR是一個常用的地址指針,它是一個16位的寄存器,壓入堆棧保護時必須分別將高8位和低8位壓入。操作如下:
.........................
PUSHDPH;將DPTR高8位壓入堆棧
PUSHDPL;將DPTR低8位壓入堆棧
.........................
POPDPL;將DPTR低8位彈出堆棧
POPDPH;將DPTR高8位彈出堆棧
.........................
注意:根據(jù)堆棧先進后出的操作原理,先壓入的必須后彈出,不得顛倒順序。
評論