LC-3中断实验

一、实验目的

  1. 学会分析和理解给定的编程问题;
  2. 掌握中断驱动的基本原理;
  3. 掌握键盘数据寄存器(KBDR)及键盘状态寄存器(KBSR)工作基本原理;
  4. 掌握输出数据寄存器(DDR)及输出状态寄存器(DSR)工作基本原理;
  5. 利用LC-3设计并编写用户程序及中断程序。

二、实验内容

1.实验背景

在计算机科学中,一个中断就是有硬件和软件发起的一个事件,表明需要立即处理。
高优先级的条件下一个中断通知处理器需要中断正在运行的程序,处理器挂起正在处理的行为,保存执行程序的状态,然后执行一个小的中断处理程序(中断服务程序)来处理事件。
中断是临时的,当处理器执行完中断处理程序后,处理器继续执行之前被中断的程序,中断分硬件中断和软件中断。

2.实验描述

表明中断驱动的输入、输出可以中断一个正在运行的程序,执行中断服务程序,返回被中断的程序,从被中断位置下一个地址继续执行(好像什么也没发生似的)。实验中使用键盘作为输入设备,中断正在运行的程序。

3.实验任务

包括以下三部分:

A.用户程序

用户程序将会包含连续地输出纵横交替的ICS,通过交替输出两个不同行,如下:
在这里插入图片描述
确保输出不至于太快,以至于肉眼不能察觉。用户程序应该包含以小段代码用于每行间的计数,间隔为从25000开始倒计时输出在屏幕上。

B.键盘中断服务程序

键盘中断服务程序将会简单地在屏幕上写上十次,用户随机输入的字符并以Enter(x0A)结束。
中断服务程序中不能使用TRAP指令。如在屏幕上显示一个字符,必须检测先DSR寄存器,然后写进DDR寄存器,并且也不可以调用 TRAP x21(OUT),或者其它TRAP程序。

C.操作系统支持的代码

LC-3上没有安装windows或Linux,所以必须要求在用户程序代码前先做到以下三个步骤。

  1. 正常情况下,操作系统将会先安装一些栈空间,所以当中断发生的时候PCPSR可以被放进栈中(当程序执行RTIPCPSR都会被弹出栈,处理器返回到执行被中断的程序)由于没有操作系统,请先把R6初始化为x3000,表示一个空的栈。
  2. 正常情况下,操作系统会建立中断向量表,它包含对应中断服务程序的起始地址,你必须为键盘中断先建立一个中断向量表。中断向量表的开始地址是x0100,键盘中断的中断向量是x80。你必须在中断向量表提供一个入口供本实验使用。
  3. 操作系统应该设置KBSR的IE(Interrupt Enable)位,这个也由你实现。

三、实验步骤与结果

程序实现思路及流程图

1.用户程序思路和流程图

要实现从键盘输入一个字符后执行中断程序,就需要将中断程序的起始地址写入键盘的中断矢量表中,且要将KBSR的中断使能位设置为1。具体步骤如下(Fig. 1):
首先要进行预处理:

  1. R6初始化为x3000,表示一个空栈,用于存放PCPSR等需要保存和恢复的内容。
  2. 将中断服务程序的入口地址x2000和键盘的中断矢量x0180联系起来。
  3. KBSR的中断使能位设置为1

然后,依次完成以下三个步骤:

  1. 在用户程序中,连续地输出纵横交替的ICS
  2. 在读入来自键盘的字符后,保护现场并进入中断服务子程序
  3. 在子程序中,如果键入回车,则输出十个之前键入的字符,恢复现场,并回到用户程序,重复3。

在这里插入图片描述
Figure 1用户程序的流程图

2.中断服务子程序的思路和流程图

该程序分为以下几个步骤(Fig. 2):

  1. 压栈保存寄存器(保护现场)
  2. 反复检测KBSR[15],如果KBSR[15]=1,则检测键入的字符是否是回车。如果是回车,则执行3;如果不是回车,则更新待输出的字符后回到2。
  3. 连续输出十个之前在用户程序键入的字符并换行。
  4. 退栈以恢复寄存器(恢复现场)并执行RTI
    在这里插入图片描述

实验结果

实验结果如下:

扫描二维码关注公众号,回复: 15300152 查看本文章
  1. 无键盘读入时,交替输出“ICS”;从键盘读入一个字符‘5’后暂停(Fig. 3)。
    在这里插入图片描述
    Figure 3 读入字符‘5’以后,键入回车以前的情景

  2. 键入回车,连续输出10个‘5’以后又回到最初的样子:交替输出“ICS”(Fig. 4)。
    在这里插入图片描述
    Figure 4键入回车以后的情景

四、完整代码

lab5_user_program

; 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

猜你喜欢

转载自blog.csdn.net/weixin_46655675/article/details/130858166