【lc3】汇编实现I/O中断

1.Purpose——To showhow interrupt-driven Input/Output can interrupt a program that is running,execute the interrupt service routine, and return to the interrupted program,picking up exactly where it left off (just as if nothing had happened).

The assignment consists of three parts:

1)The user program

2)The keyboard interrupt service routine

3)The operating system enabling code

 

2.Principle: (1)本实验中对键盘输入采用interrupt I/O方式,对显示屏幕输出则采用polling的方式

 (2)在user program 中,讲“cs@ustc”与“      ”作为两个字符串,控制二者轮流输出和换行时机,以达到实验要求输出方式

                     (3)为了至于显示频刷新过快,采用了延时的方法,即每一行输出后,count2500方进行下一行的输出

(4)在interrupt routine中不能采用trap指令,则逐一将需要输出的字符存储到DDR中以达到输出目的

 

 

3. procedure

  代码注释:

.ORIG x3000

                     LDR6,STACK ; initialize the stack pointer

LD R2,ADDR  ; set up the keyboard interrupt vector tableentry             LD R3,VECTOR

                     STRR2,R3,#0

 

                     LD R2,ENABLE      ;enable keyboard interrupts

                     LDR3,KBSR

                     STRR2,R3,#0

 

                     LDR1,FEEDNUM1 ; start of actual user programto print checkerboard

OUTPUT1      LEAR0,OUT1        ;输出第一行,从字符串OUT1开始轮流输出OUT1和

                     TRAPx22             ;OUT2两个字符串,共输出9个则换行

                     ADDR1,R1,#-1

                     LEAR0,OUT2

                     TRAPx22

                     ADDR1,R1,#-1

                     BRzOUTFED1      ;输出换行

                     BRpOUTPUT1

 

OUTFED1      JSRDELAY

                     LDR0,FEED

                     TRAPx21

                     LDR1,FEEDNUM2

                     BRnzpOUTPUT2  ;转至输出第二行部分

 

OUTPUT2      LEAR0,OUT2        ;输出第一行,从字符串OUT2开始轮流输出OUT2和

                     TRAPx22             ;OUT1两个字符串,共输出8个则换行

                     ADDR1,R1,#-1

                     LEAR0,OUT1

                     TRAPx22

                     ADDR1,R1,#-1

                     BRzOUTFED2

                     BRpOUTPUT2

 

OUTFED2      JSRDELAY            ;换行并且转至输出line1的部分

                     LDR0,FEED

                     TRAPx21

                     LDR1,FEEDNUM1

                     BRnzpOUTPUT1

      

DELAY          STR1, SaveR1       ;延时

                    LD R1, COUNT

REP               ADDR1,R1,#-1

                    BRp REP

                    LD R1, SaveR1

                    RET

 

ENABLE        .FILLx4000

KBSR             .FILLxFE00

VECTOR        .FILLx180

ADDR            .FILLx1500

STACK           .FILLx3000

COUNT         .FILL#2500

SaveR1         .BLKW#1

FEED             .FILL#13

FEEDNUM1   .FILL#9

FEEDNUM2   .FILL#8

OUT1            .STRINGZ"CS@USTC"

OUT2            .STRINGZ"       "

                     .END

----------------------------------------------------------------------------

 

                     .ORIGx1500

      

                     STR0,SAVER0              ;store the registers

                     STR2,SAVER2

                     STR3,SAVER3

                     STR4,SAVER4

                     STR5,SAVER5

                     STR7,SAVER7

             

LDI R1,KBDR         ;初始化值

                     LDR2,NUM0

                     LDR3,NUM9

                     NOTR2,R2           ;讲kbdr中只与0,9比较以判断是否是数字

                     ADDR2,R2,#1

                     ADDR2,R2,R1

                     BRnNOTNUM

                     NOTR3,R3

                     ADDR3,R3,#1

                     ADDR3,R3,R1

                     BRpNOTNUM

                     BRnzpISNUM

 

ISNUM          LEAR2,OUT1        ;是数字输出相应的字符串

ISNUM2        LDRR0,R2,#0

                     JSROUTPUT

                     ADDR2,R2,#1

                     LEAR3,OUT2

                     NOTR3,R3

                     ADDR3,R3,#1

                     ADDR3,R3,R2

                     BRzDONE

                     BRnpISNUM2

 

 

NOTNUM      LEAR3,OUT2        ;不是数字,输出相应的字符串

NOTNUM2    LDRR0,R3,#0

                     JSROUTPUT

                     ADDR3,R3,#1

                     LEAR2,KBDR

                     NOTR2,R2

                     ADDR2,R2,#1

                     ADDR2,R2,R3

                     BRzDONE

                     BRnpNOTNUM2

 

OUTPUT        STR1,SAVER1              ;因为不能使用trap,采用的输出方法

LOOP            LDIR1,DSR

                     BRzpLOOP

                     STIR0,DDR

                     LDR1,SAVER1

                     RET

 

DONE           LDR1,ENABLE      ;结束

                     LDR2,KBSR

                     STRR1,R2,#0

                     LDR0,SAVER0

                     LDR2,SAVER2

                     LDR3,SAVER3

                     LDR4,SAVER4

                     LDR5,SAVER5

                     LDR7,SAVER7

                     RTI

 

OUT1            .STRINGZ"\nICS2017:It is a number.\n"

OUT2            .STRINGZ"\nICS2017: ?????? What is this ??????\n"

KBDR             .FILLxFE02

KBSR             .FILLxFE02

ENABLE         .FILLx4000

DSR               .FILLxFE04

DDR              .FILLxFE06

NUM0           .FILL#48

NUM9           .FILL#57

SAVER0         .BLKW#1

SAVER1         .BLKW#1

SAVER2         .BLKW#1

SAVER3         .BLKW#1

SAVER4         .BLKW#1

SAVER5         .BLKW#1

SAVER7         .BLKW#1

                     .END

 

 

 

 

4.results

(1)测试

输入1,结果如下

输入k,结果如下

 

*以其他字符进行测试,输出均与要求一致

 

(2)反思

1.每行延迟为计数2500,在实际操作中仍然过快,在本人实验中,每输出一个7个字符的字符串delay等同时间,显示效果较佳

2.上述轮流输出的方式较为繁琐,把每行设置成一个字符串能使代码简化

3.在实验中PC,PSR的栈的入栈操作由模拟器本身进行,出栈由RTI执行,未能清楚得到乃至修改PSR的值的方法

 

生命游戏(Game of Life)是一种经典的细胞动机,可以用LC3汇编语言来实现。下面是一个简单的生命游戏的LC3汇编代码示例: ``` .ORIG x3000 ; 定义常量 WIDTH .FILL 10 HEIGHT .FILL 10 ; 定义存储空间 .BLKW WIDTH*HEIGHT .BLKW WIDTH*HEIGHT ; 初始化细胞状态 INIT LEA R0, GRID LEA R1, GRID_COPY LD R2, WIDTH LD R3, HEIGHT INIT_LOOP LDR R4, R0, #0 STR R4, R1, #0 ADD R0, R0, #1 ADD R1, R1, #1 ADD R3, R3, #-1 BRp INIT_LOOP ; 游戏循环 GAME_LOOP LEA R0, GRID LEA R1, GRID_COPY LD R2, WIDTH LD R3, HEIGHT JSR UPDATE_GRID ; 显示当前细胞状态 JSR DISPLAY_GRID ; 复制GRID_COPY到GRID LEA R0, GRID_COPY LEA R1, GRID LD R2, WIDTH LD R3, HEIGHT JSR COPY_GRID BR GAME_LOOP ; 更新细胞状态 UPDATE_GRID LD R4, #0 ST R4, COUNT_ALIVE LEA R0, GRID LEA R1, GRID_COPY LD R2, WIDTH LD R3, HEIGHT UPDATE_LOOP LDR R4, R0, #0 JSR COUNT_NEIGHBORS JSR UPDATE_CELL ADD R0, R0, #1 ADD R1, R1, #1 ADD R3, R3, #-1 BRp UPDATE_LOOP RET ; 统计邻居细胞的数量 COUNT_NEIGHBORS ST R7, SAVE_R7 ADD R7, R7, #-1 ST R0, SAVE_R0 ST R1, SAVE_R1 ST R2, SAVE_R2 ST R3, SAVE_R3 AND R4, R4, #0 ADD R5, R0, #-1 ADD R6, R1, #-1 LD R0, WIDTH LD R1, HEIGHT ADD R2, R5, #2 ADD R3, R6, #2 JSR IS_VALID_CELL ADD R2, R5, #2 ADD R3, R6, #1 JSR IS_VALID_CELL ADD R2, R5, #2 ADD R3, R6, #0 JSR IS_VALID_CELL ADD R2, R5, #1 ADD R3, R6, #2 JSR IS_VALID_CELL ADD R2, R5, #1 ADD R3, R6, #0 JSR IS_VALID_CELL ADD R2, R5, #0 ADD R3, R6, #2 JSR IS_VALID_CELL ADD R2, R5, #0 ADD R3, R6, #1 JSR IS_VALID_CELL ADD R2, R5, #0 ADD R3, R6, #0 JSR IS_VALID_CELL LD R0, SAVE_R0 LD R1, SAVE_R1 LD R2, SAVE_R2 LD R3, SAVE_R3 LD R7, SAVE_R7 RET ; 判断细胞是否有效 IS_VALID_CELL ADD R4, R4, #1 BRn INVALID_CELL BRp VALID_CELL ; 细胞无效 INVALID_CELL RET ; 细胞有效 VALID_CELL LDR R5, R1, #0 ADD R5, R5, R4 STR R5, R1, #0 RET ; 更新细胞状态 UPDATE_CELL LDR R5, R1, #0 LDR R6, COUNT_ALIVE ADD R6, R6, #-1 ADD R7, R4, #-1 BRn CELL_DEAD ADD R7, R4, #-2 BRn CELL_DEAD ADD R7, R4, #-3 BRn CELL_DEAD ADD R7, R4, #-4 BRn CELL_DEAD ADD R7, R4, #-5 BRn CELL_DEAD ADD R7, R4, #-6 BRn CELL_DEAD ADD R7, R4, #-7 BRn CELL_DEAD ADD R7, R4, #-8 BRn CELL_DEAD CELL_ALIVE ADD R5, R5, #1 STR R5, R1, #0 ADD R6, R6, #1 STR R6, COUNT_ALIVE RET CELL_DEAD STR R5, R1, #0 RET ; 显示细胞状态 DISPLAY_GRID LEA R0, GRID LD R2, WIDTH LD R3, HEIGHT DISPLAY_LOOP LDR R4, R0, #0 OUT ADD R0, R0, #1 ADD R3, R3, #-1 BRp DISPLAY_LOOP RET ; 复制GRID_COPY到GRID COPY_GRID LEA R0, GRID_COPY LEA R1, GRID LD R2, WIDTH LD R3, HEIGHT COPY_LOOP LDR R4, R0, #0 STR R4, R1, #0 ADD R0, R0, #1 ADD R1, R1, #1 ADD R3, R3, #-1 BRp COPY_LOOP RET ; 存储空间 GRID .BLKW WIDTH*HEIGHT GRID_COPY .BLKW WIDTH*HEIGHT ; 寄存器保存 SAVE_R0 .BLKW 1 SAVE_R1 .BLKW 1 SAVE_R2 .BLKW 1 SAVE_R3 .BLKW 1 SAVE_R7 .BLKW 1 ; 统计存活细胞数量 COUNT_ALIVE .FILL 0 .END ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值