LC-3 汇编语言实验1求成绩等级

实验内容

(一) 实验描述

对学生的成绩使用数组进行排序

背景:一位老师需要你帮忙决定学生的成绩,她想要根据学生分数在班上的排名和考试分数一起决定学生最后的成绩等级。

具体要求:

a. 如果学生的分数排名在全班的25%之前,且考试分数达到85分及以上,则学生可以获得A

b. 如果学生不能拿A,但是分数排名在全班的50%之前,且考试分数达到75及以上,则学生可以获得B

c. 剩下的学生都是C

具体的情况:一共有16名学生,每名学生只有一个成绩

(二) 实验要求

(1)用汇编语言给这个班写一个成绩排序的程序

(2)你的程序必须给学生的分数排序,然后计算出获得A和B的学生人数。程序从x3000开始

(3)程序的输入

a. 班上16个学生的没有排序的成绩;

b. 每个分数是用16位无符号数表示的0~100的整数;

c. 分数存储在16个连续的内存位置-每一个位置一个分数;从x3200开始;

d. 最后一个分数的存储位置为x320F;

e. 你可以假设所有的分数相互之间不相同(每个分数是唯一的);

(4)程序的输出(你的程序必须有两个输出)

a. 16位学生的分数排序。分数必须按降序排序在连续的内存位置-每个内存地址一个分数,从x4000开始存储;即x4000存储的分数是最高的

b. 获得A和B的学生的人数。获得A的学生人数必须存储在x4100,获得B的人数必须存储在x4101

实验步骤

(1) 程序实现思路:

① 首先读取x3200到x320F的16个成绩,然后使用冒泡排序对成绩进行排序,并将排序后的成绩存储到x4000~x400F中;

② 通过计算获得A和B的学生人数并分别存储到x4100和x4101中。

(2)编写汇编语言

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
.ORIG x3000   ;程序起始位于x3000

;初始化寄存的值
LD R0 SCORE ;R0为地址x3200指向第一个成绩
LD R1 VALUE_16 ;R1 = 16,用于copy和sort
LD R2 S_START ;R2指向copy后存放成绩的地址x4000

;将位于x3200的成绩拷贝到x4000
copy BRz sort ;计数器为0时进入排序操作
LDR R4 R0 #0 ;将x3200的数据拷贝到x4000
STR R4 R2 #0
ADD R0 R0 #1 ;源指针和目标指针都+1
ADD R2 R2 #1
ADD R1 R1 #-1 ;计数器R1-1
BRnzp copy ;无条件跳转到copy开始

;冒泡排序
sort LD R1 VALUE_16 ;还原R1

LOOP1 LD R2 S_START ;还原R2
ADD R1 R1 #-1
BRz count_A ;外循环结束时进入count_A
AND R3 R3 #0 ;初始化R3为0
ADD R3 R3 R1 ;R3设置为内循环计数器

LOOP2 LDR R0 R2 #0
LDR R4 R2 #1
NOT R4 R4
ADD R4 R4 #1 ;R4取相反数
ADD R0 R4 R0 ;R0 = R0 - R4
BRn swap ;前一个小于后一个时swap
s_out ADD R2 R2 #1 ;R2指针后移1
ADD R3 R3 #-1 ;内循环计数器-1
BRp LOOP2 ;为正数就继续循环

BRz LOOP1 ;为0则跳出内循环

swap LDR R4 R2 #1 ;前后两个数交换位置
LDR R0 R2 #0
STR R0 R2 #1
STR R4 R2 #0
BRnzp s_out ;函数返回

;统计A人数
count_A LD R0 S_START ;将R0指向S_START的x4000
AND R1 R1 #0 ;R1作为A上限
ADD R1 R1 #4 ;将4赋给R1
AND R2 R2 #0 ;R2作为B上限
ADD R2 R2 #8 ;将8赋给R2
AND R3 R3 #0 ;寄存器初始化为0
AND R4 R4 #0 ;R4记录A人数


LOOP3 LDR R3 R0 #0 ;将成绩传给R3
LD R7 Ne85 ;将-85赋给R7
ADD R3 R3 R7 ;比较R3与85
BRn store_A ;得分小于85,记录A人数
ADD R2 R2 #-1 ;得分大于等于85,B上限-1
ADD R4 R4 #1 ;A人数+1
ADD R1 R1 #-1 ;A上限-1
BRz store_A ;A上限为0,记录A人数
ADD R0 R0 #1 ;指针后移
BRp LOOP3 ;

store_A STI R4,SaveA ;将R4中的内容(等级为A的学生人数)存储在地址x4100中

;统计B人数
count_B AND R4 R4 #0 ;R4记录B人数
AND R3 R3 #0 ;寄存器初始化为0

LOOP4 LDR R3 R0 #0 ;将成绩传给R3
LD R7 Ne75 ;将-75赋给R7
ADD R3 R3 R7 ;比较R3与85
BRn store_B ;得分小于75,记录B人数
ADD R2 R2 #-1 ;得分大于等于75,B上限-1
ADD R4 R4 #1 ;B人数+1
ADD R2 R2 #-1 ;B上限-1
BRz store_B ;B上限为0,记录B人数
ADD R0,R0,#1 ;指针后移
BRp LOOP4 ;

store_B STI R4,SaveB ;将R6存在地址x4101


;程序结束
HALT


Ne85 .FILL #-85
Ne75 .FILL #-75
VALUE_16 .FILL #16
SCORE .FILL x3200
S_START .FILL x4000
SaveA .FILL x4100
SaveB .FILL x4101
.END

(3)编译程序,开启模拟器,加载并运行该程序

(4)使用手工给内存赋值的方式,给x3200~x320F输入实验数据

(5) 运行程序,检查内存x4000~x400F,可以看到学生成绩已经降序排列

(6)检查内存x4100、x4101,结果正确,实验完毕。

(上述过程自己补充实验截图)

实验结论

这次实验让我对汇编语言有了更深入的理解。

虽然在实验过程中遇到了一些困难,如条件判断错误和忘记给计数器操作等,但最终都在debug和测试中得到了解决。

我发现,在编写较长的汇编代码时,理解各个指令的含义会变得困难,因此注释的作用就显得尤为重要。

此外,我还学会了如何将高级语言中的排序算法应用到汇编语言中,这大大降低了实现相应操作的难度。