题目描述
背景
16名学生成绩排序,及统计分析。
成绩分类规则:
A:全班排名前25%,且成绩在85分及以上。
B:非A成绩,全班排名前50%,且成绩在75分及以上。
C:非A、B成绩。
要求
使用LC-3汇编语言,编写程序实现以上功能。
输入
16名学生成绩,存储于x3200至x320F。
每个成绩为0至100之间,由16比特无符号整数表示。
输出
成绩降序排序,并存储于x4000至x400F内存位置,x4000位置成绩为最高成绩。
得A、B成绩的学生总人数,分别存储于x4100,及x4101位置。
思路分析
1、数据搬移
R0存储原数据首地址x3200,R1存储排序后数据存储的首地址x4000,R2的值为循环次数16,采用基址加偏移的寻址方式读取内存,R3作为中间搬运工,利用LDR和STR指令先将数据搬移。
2、冒泡排序
现在数据已经搬移到x4000~x400F,开始排序。
普通的冒泡排序需要内外两层循环,外循环n-1次,内循环n-1次,因此,我们让R0和R1的值都为15,读取内存时依旧采用基址加偏移的寻址方式,R2存储数据存储地址x4000,R3读取前一个数,R4读取后一个数,之后需要进行比较大小,将R3取反加1存储在R5,然后将R5和R4相加的结果存储在R5,通过判断R5的正负来判断R3和R4的大小,如果R3小于R4,即R5是正数,那么就交换这两个数,利用STR指令将R3的值存储到后一个地址单元,将R4的值存储到前一个地址单元。
3、成绩分类
读取数据采取基址加偏移的寻址方式,R0存储首地址x4000,R1和R2清0用来存储A和B的人数,R3存储循环次数16,R4存储每一个数据,R5作为中间载体,存储数据取反加一的值,R6和R7存储着A和B的临界成绩85和75,同时承担存储和R5相加后的数据,用于比较成绩。最后将R1和R2的值分别存进地址为x4100和x4101的内存单元。
AC代码
.ORIG X3000
LD R0,DATA
LD R1,COPY
LD R2,COUNTER
LOOP1 BRZ NEXT1
LDR R3,R0,#0
ADD R0,R0,#1
STR R3,R1,#0
ADD R1,R1,#1
ADD R2,R2,#-1
BRNZP LOOP1
NEXT1 LD R1,BUBBLE
LOOP2 BRZ NEXT2
LD R0,COPY
LD R2,BUBBLE
LOOP3 BRZ AGAIN
LDR R3,R0,#0
ADD R0,R0,#1
LDR R4,R0,#0
NOT R5,R3
ADD R5,R5,#1
ADD R5,R5,R4
BRNZ RIGHT
STR R3,R0,#0
ADD R0,R0,#-1
STR R4,R0,#0
ADD R0,R0,#1
RIGHT ADD R2,R2,#-1
BRNZP LOOP3
AGAIN ADD R1,R1,#-1
BRNZP LOOP2
NEXT2 LD R0,COPY
AND R1,R1,#0
AND R2,R2,#0
LD R3,COUNTER
LOOP4 BRZ FINISH
LDR R4,R0,#0
LD R6,A
LD R7,B
NOT R4,R4
ADD R4,R4,#1
ADD R6,R6,R4
BRP BB
NOT R5,R0
ADD R5,R5,#1
LD R6,AHOLD
ADD R6,R6,R5
BRN BB
ADD R1,R1,#1
BRNZP TAIL
BB ADD R7,R7,R4
BRP TAIL
LD R7,BHOLD
ADD R7,R7,R5
BRN TAIL
ADD R2,R2,#1
TAIL ADD R0,R0,#1
ADD R3,R3,#-1
BRNZP LOOP4
FINISH STI R1,ANUM
STI R2,BNUM
HALT
DATA .FILL X3200
COPY .FILL X4000
COUNTER .FILL X0010
ANUM .FILL X4100
BNUM .FILL X4101
AHOLD .FILL X4003
BHOLD .FILL X4007
A .FILL #85
B .FILL #75
BUBBLE .FILL #15
.END