1. 実験の目的
- 特定のプログラミングの問題を分析して理解することを学びます。
- 割り込み駆動の基本原理をマスターします。
- キーボード データ レジスタ (KBDR) とキーボード ステータス レジスタ (KBSR) の動作原理をマスターします。
- 出力データ レジスタ (DDR) と出力ステータス レジスタ (DSR) の基本的な動作原理をマスターします。
- LC-3 を使用して、ユーザー プログラムと割り込みプログラムを設計および作成します。
2. 実験内容
1. 実験の背景
コンピューター サイエンスでは、割り込みはハードウェアとソフトウェアによって開始されるイベントであり、即時の処理が必要であることを示します。
優先度の高い条件での割り込みは、実行中のプログラムを中断する必要があることをプロセッサに通知し、プロセッサは実行中の処理を一時停止し、実行中のプログラムの状態を保存し、その後、処理するための小さな割り込みハンドラ (割り込みサービス ルーチン) を実行します。行事。
割り込みは一時的なものです。プロセッサが割り込みハンドラを実行した後、プロセッサは以前に割り込まれたプログラムを実行し続けます。割り込みはハードウェア割り込みとソフトウェア割り込みに分けられます。
2. 実験の説明
割り込み駆動の入出力が実行中のプログラムに割り込み、割り込みサービス プログラムを実行し、割り込まれたプログラムに戻り、割り込まれた位置の次のアドレスから (何も起こらなかったかのように) 実行を継続できることを示します。実験では、実行中のプログラムを中断するための入力デバイスとしてキーボードが使用されます。
3. 実験タスク
次の 3 つの部分が含まれます。
A. ユーザープログラム
ICS
ユーザー プログラムは、次のように 2 つの異なるラインを交互に出力することによって、連続的にクロスバーを出力することで構成されます。
出力が速すぎて肉眼で検出できないことを確認してください。ユーザー プログラムには、各行の間でカウントするための小さなコードが含まれている必要があり、25000
カウントダウンの開始から間隔が画面に出力されます。
B. キーボード割り込みサービスルーチン
キーボード割り込みサービス ルーチンは、単純に 10 個のランダムな文字を画面に書き込み、Enter(x0A)
で終了します。
TRAP命令は割り込みサービスルーチンでは使用できません。画面に文字が表示される場合は、DSR
最初にレジスタを検出してからDDR
レジスタに書き込む必要があり、そのレジスタ TRAP x21(OUT)
や他のTRAP
プログラムを呼び出すことはできません。
C. オペレーティング システムでサポートされているコード
LC-3 には Windows または Linux がインストールされていないため、ユーザー プログラム コードの前に次の 3 つの手順を実行する必要があります。
- 通常の状況では、オペレーティング システムは最初にスタック領域をインストールするため、割り込みが発生して
PC
スタックPSR
に置くことができます (プログラムが実行されRTI
、スタックからポップされると、プロセッサは割り込まれたプログラムに戻ります)PC
。PSR
オペレーティング システムの場合は、空のスタックを示すR6
として初期化してください。x3000
- 通常の状況では、オペレーティング システムは、対応する割り込みサービス ルーチンの開始アドレスを含む割り込みベクタ テーブルを作成します。最初に、キーボード割り込み用の割り込みベクタ テーブルを作成する必要があります。割り込みベクタテーブルの開始アドレスは
x0100
、キーボード割り込みの割り込みベクタは ですx80
。このラボで使用するには、割り込みベクタ テーブルにエントリを指定する必要があります。 - オペレーティング システムは
KBSR
IE (割り込みイネーブル) ビットを設定する必要があります。これもユーザーが実装します。
3. 実験手順と結果
プログラム実施のアイデアとフローチャート
1. ユーザープログラムの考え方とフローチャート
キーボードから文字を入力した後に割り込みプログラムを実行するには、キーボードの割り込みベクタテーブルに割り込みプログラムの開始アドレスを書き込み、KBSRの割り込み許可ビットを1に設定する必要があります。具体的な手順は次のとおりです (図 1):
まず、前処理が必要です。
R6
これを として初期化し、保存および復元が必要なコンテンツを保存および待機するx3000
ための空のスタックを示します。PC
PSR
- 割り込みサービス ルーチンのエントリ アドレスを
x2000
キーボードの割り込みベクトルにx0180
リンクします。 KBSR
の割り込みイネーブルビットを設定します。1
次に、次の 3 つの手順を順番に実行します。
- ユーザプログラムでは縦横交互に連続出力します
ICS
。 - キーボードから文字を読み込んだ後、シーンを確保し、割り込みサービスサブルーチンに入ります。
- サブルーチン内で Enter を押すと、以前に入力した 10 文字が出力され、シーンが復元され、ユーザー プログラムに戻り、3 を繰り返します。
図1 ユーザプログラムのフローチャート
2. 割り込みサービスサブルーチンの考え方とフローチャート
手順は次のステップに分かれています (図 2)。
- スタックをプッシュしてレジスタを保存(シーンを保護)
- 繰り返しチェックし
KBSR[15]
、 であればKBSR[15]=1
、入力された文字がキャリッジリターンであるかどうかをチェックします。復帰の場合は3を実行し、復帰でない場合は出力する文字を更新して2に戻ります。 - ユーザープログラム内で以前に入力した 10 文字を改行で連続して出力します。
- アンスタックしてレジスタを復元(コンテキストを復元)し、 を実行します
RTI
。
実験結果
実験結果は次のとおりです。
-
読み込むキーボードがない場合は、「 」を交互に出力し、キーボードから
ICS
文字「 」を読み取って一時停止します(図3)。図 3 文字「」を読んだ後、Enter を入力する前の状況5
5
-
Enter を押すと、「
5
」を 10 個連続して出力し、元の表示に戻ります。「ICS
」を交互に出力します (図 4)。
図 4 Enter を入力した後のシーン
4. 完全なコード
lab5_ユーザー_プログラム
; author: CAO-Wuhui
; date: 2021.6.19
; This is the program of user
.ORIG x3000
LD R6,STACK ; initialize the stack pointer saved in R6
; set up the keyboard interrupt vector table entry
LD R1,ENTRANCE ; Interrupt Vector
LD R2,INTV ; The entrance of the interrupt service routine
STR R1,R2,#0 ; If there is something input from keyboard, PC will go to x2000
; enable keyboard interrupts
LD R3,IE
STI R3,KBSR ; KBSR[14] = 1
; Start of actual user program to print ICS checkerboard
PRINT LEA R0,STR1
TRAP x22 ; Print the first string
LEA R0,STR2
JSR DELAY
TRAP x22 ; Print the second string
JSR DELAY
BRnzp PRINT ; Continue printing
HALT
DELAY ST R1, SaveR1
LD R1, COUNT
REP ADD R1,R1,#-1
BRp REP
LD R1, SaveR1
RET
STR1 .STRINGZ "ICS ICS ICS ICS ICS ICS\n"
STR2 .STRINGZ " ICS ICS ICS ICS ICS\n"
IE .FILL x4000 ;0100 0000 0000 0000
KBSR .FILL xFE00
KBDR .FILL xFE02
COUNT .FILL #25000
INTV .FILL x0180
ENTRANCE .FILL x2000
SaveR1 .FILL #0
STACK .FILL x3000
.END
lab5_interrupt_service_routine.asm
.ORIG x2000 ; the code
ADD R6,R6,#-1
STR R0,R6,#0
ADD R6,R6,#-1
STR R1,R6,#0
ADD R6,R6,#-1
STR R2,R6,#0
ADD R6,R6,#-1
STR R3,R6,#0
LOOP ST R0,SaveR0
CHECK LDI R1,KBSR ; Check the value of KBSR[15]
ADD R1,R1,#0 ; If KBSR[15] = 1, break
BRzp CHECK ;
LDI R0,KBDR
LD R2,_ENDLINE ;
ADD R2,R2,R0
BRnp LOOP
AND R3,R3,#0
ADD R3,R3,#10
P_LOOP LD R0,SaveR0
START LDI R1,DSR ; Check the value of DSR[15]
BRzp START ; If DSR[15] = 1, break
STI R0,DDR
ADD R3,R3,#-1
BRp P_LOOP
P_ENDL LD R0,ENDLINE
LDI R1,DSR
BRzp P_ENDL
STI R0,DDR
LDR R3,R6,#0
ADD R6,R6,#1
LDR R2,R6,#0
ADD R6,R6,#1
LDR R1,R6,#0
ADD R6,R6,#1
LDR R0,R6,#0
ADD R6,R6,#1
RTI
; buffer space as required
_ENDLINE .FILL xFFF6 ; _'\n'
ENDLINE .FILL x000A ; '\n'
SaveR0 .FILL #0
KBSR .FILL xFE00
KBDR .FILL xFE02
DSR .FILL xFE04
DDR .FILL xFE06
.END