计算机系统(1)实验三 汇编语言试验

简介: 计算机系统(1)实验三 汇编语言试验

实验目的


熟悉和理解LC-3的汇编指令格式。

进一步掌握在LC-3仿真平台下汇编指令的设计输入和调试过程。

掌握利用汇编指令解决问题的思路,加深对汇编指令的理解。


实验内容


分析和理解试验指定的需解决问题。

利用LC-3的汇编语言代码设计实现相关程序。

通过LC-3仿真器调试和运行相关程序并得到正确的结果


实验要求


熟悉和理解LC-3的汇编语言指令格式。

掌握在LC-3仿真平台下汇编语言代码的设计输入和调试过程。

掌握利用汇编语言解决问题的思路,加深对底层硬件的理解。


实验问题


程序起始地址x3000

在x3200处开始存放16个学生成绩,成绩为0-100的正整数

编写程序对16个学生的成绩进行排序,从高至低存放在起始地址x4000处。

计算学生获得成绩等级为A的数量存放在x4100,获得B等级的数量存放在x4101处。(成绩等级计算方法:如果一个学生的成绩在85分以上同时排名前25%则获得A,如果一个学生不能获得A,他的成绩在75分以上同时排名前50%,则可获得B。其它成绩则获得C)

实验报告要写清楚排序算法的实现过程以及等级的计算方法


实验步骤


题目分析


 本题中主要需要实现转移数据位置、并统计在给定分数区间和给定分数名次以内的学生个数这三个功能,下面逐一进行分析:


①转移数据位置:


 可以通过类似于C++语言中指针的方式,分别将R1和R2(此处仅作为说明用,并不是真正意义上的R1和R2,实际操作可以换成如R3、R5或R7等其他寄存器)指向数据源单元首地址(x3200)和目标存储单元首地址(x4000),每次复制一个学生的成绩数据,每次复制完成后,将R1和R2所指地址加一(指针加一)使其指向下一个单元并用另一寄存器进行计数,待计数器数满十六次后,数据转移功能完成,并进入下一功能的代码块中。


②对数据进行降序排列:


 常用排序方法有冒泡法选择法等,本实验中选择了选择排序法对学生成绩进行排序,此处需要注意的是因为汇编语言中没有比较数值大小的指令,因此在进行大小比较时,应比较两数做差之后的值是否大于一,需要将一个数值转换为对应的负值(取反加一),而在进行判断之后不能忘记将对应的负值转换为相应的原数值(非负数),否则会造成出现错误的数据。

 排序过程中有两层循环,大循环(外层循环)用于遍历所有的学生成绩数据,小循环(内层循环)用于找到单次循环的最大值,并进行位置的调换。直至大循环循环完毕,所有排序操作结束,并进入下一功能的代码块中。


③统计学生个数:


 依照本题的要求需要统计A、B两个等级的学生,由于对各个等级的学生要求存在对排名的要求故从头部往后逐一遍历,遇到符合要求的成绩相应的计数器就加一,等遍历到中间位置(50%)就可结束,并将计数器的个数存在相应的内存中。


代码实现


设置程序起始位置:


3876216dbf93468ca3a58161d53d40ec.png


初始化寄存器


30aaef2d4567400c904fb6cad196da45.png


进行数据复制


d27de0d4af564ce796af9715107ec50e.png


将成绩进行排序


8d4767b066bb45c1a246a1b5a1565ac6.png


统计A、B等级学生人数:

前面已经介绍,需要分两步进行统计:

①统计获得A和前25%中获得B的学生人数:

090240cf35974f04a5da5947589da526.png

②统计25%-50%中B的学生人数:

98b4894a10a8420fb38eb29e961a471b.png


符号表


bb07075b4a4e43cda89f559435649d07.png


进行测试


测试数据为:97,83,72,69,50,93,80,71,68,51,87,74,70,67,62,86

预期排序结果为:97,93,86,87,83,80,74,72,71,70,69,68,67,62,51,50共有4个A等级成绩,2个B等级成绩。

在simulator中运行并设置测试数据如下:


99932588de6b491bb0fd90e506e33bc6.png


排序结果如下图

1dc8ca5e306241c1bfadf8ae34b66ba2.png

对A、B等级学生的成绩计数结果如下:

0f3e6b1e83a64e54addb4174567a6b3b.png

可以看到A等级学生有4人,B等级学生有2人。

完美符合预期,故实验编程正确。


实验结论


 通过这次的实验,我对汇编语言有了更深的认识。在实验过程中遇到不少困难,最终都成功解决。如判断时条件错误,忘记将因用于比较而变成负数的值转回原值等。最后在一次次debug和测试中都得到解决。在对汇编语言进行编程时,如果代码较长,理解起各个指令的含义变得困难,此时就需要借助注释来进行提示,注释的作用在本实验中得到了很大体现。

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


完整源码(仅供参考)

.ORIG x3000 ;程序起始位于x3000
;初始化寄存器
  LD R0,SCORE ;将R0初始化为x3200,使R0指向第一个成绩
  AND R1,R1,#0  ;R1清零
  ADD R1,R1,#15 ;
  ADD R1,R1,#1  ;通过两次赋值将R1初始化为16
  LD R3,AStart  ;将R3初始化为x4000指向目标地址
  AND R5,R5,#0  ;R5清零
  ADD R5,R5,#15 ;
  ADD R5,R5,#1  ;通过两次赋值将R5初始化为16
;将输入到以x3200起始的成绩复制到x4000起始的内存单元
copy  BRz sort  ;当计数器为0的时候就进行排序
  LDR R4,R0,#0  ;将x3200存储的数据复制给R4
  STR R4,R3,#0  ;将R4存储在x4000中
  ADD R0,R0,#1  ;数据源指针地址加1
  ADD R3,R3,#1  ;目标指针地址加1
  ADD R5,R5,#-1 ;计数器减1
  BRnzp copy  ;跳转到copy,继续复制数据
;成绩排序
sort  LD R3,AStart  ;初始化R3指针为x4000
  ADD R1,R1,#0  ;设条件码
F BRz C   ;外层循环计数器跳转指令
  ADD R2,R1,#-1 ;R2为内层循环的计数器,R1为外层循环的计数器
  LDR R4,R3,#0  ;用R4来存储最大的数
  ADD R6,R3,#0  ;对最大数的地址进行修改
  ADD R7,R3,#0  ;存储最大的数的地址
  NOT R4,R4 ;
  ADD R4,R4,#1  ;准备比较大小
E ADD R6,R6,#1  ;R6是内层循环的指针
  LDR R5,R6,#0  ;
  ADD R5,R4,R5  ;
  BRnz D    ;若R5>R4,那么交换最大的与被比较的位置
  LDR R4,R6,#0  ;若R5<R4,把R6所存的地址的内容给R4
  NOT R4,R4 ;
  ADD R4,R4,#1  ;将R4变回原数据
  ADD R7,R6,#0  ;将当前所存最大数的地址给R7
D ADD R2,R2,#-1 ;内层循环计数器的值减1
  BRp E   ;跳回选择排序的小循环,继续进行排序
  LDR R0,R3,#0  ;把R3所存地址(x4000)的数据赋给R0
  STR R0,R7,#0  ;把R0数据赋给R7所存的地址的内存单元
  NOT R4,R4 ;
  ADD R4,R4,#1  ;把R4原数据
  STR R4,R3,#0  ;将最大的数存储到被比较的数所在的地址
  ADD R3,R3,#1  ;外层循环指针加1
  ADD R1,R1,#-1 ;外层循环计数器减1
  BRnzp F   ;跳回到外循环,继续进行排序
;统计获得A和前25%中获得B的学生人数
C LD R0,AStart  ;将R0指向AStart的x4000  
  AND R1,R1,#0  ;R1作为计数器
  AND R2,R2,#0  ;
  AND R3,R3,#0  ;
  AND R4,R4,#0  ;
  AND R5,R5,#0  ;
  AND R6,R6,#0  ;寄存器R1到R6清零
  ADD R1,R1,#4  ;将4赋给R1即排名前4(25%)
G BRz StoreA  ;
  ADD R1,R1,#-1 ;计数器R1减1
  LDR R2,R0,#0  ;将成绩传给R2
  LD R7,Ne85  ;将-85赋给R7
  ADD R3,R2,R7  ;比较R2与85
  BRn G1    ;R2<85,跳过R4的计数到G1
  ADD R4,R4,#1  ;R4存A的人数
  BRnzp Dyh ;
G1  ADD R7,R7,#10 ;将-75赋给R7
  ADD R5,R2,R7  ;比较R2与75
  ADD R5,R5,#0  ;设置条件码
  BRn Dyh ;R2<75,跳过R6的计数到Dyh
  ADD R6,R6,#1  ;R6存B的人数
Dyh ADD R0,R0,#1  ;指针加1
  ADD R1,R1,#0  ;设置条件码
  BRp G   ;跳回判断G
StoreA  STI R4,SaveA  ;将R4中的内容(等级为A的学生人数)存储在地址x4100中
;统计25%-50%中B的学生人数
  LD R0,BStart  ;将R0x4004 
  AND R1,R1,#0  ;R1作为计数器
  AND R2,R2,#0  ;
  AND R3,R3,#0  ;寄存器R1到R3清零
  ADD R1,R1,#4  ;将4赋给R1即4到8(25%到50%)
I ADD R1,R1,#0  ;设置条件码
  BRz StoreB  ;
  ADD R1,R1,#-1 ;计数器减1
  LDR R2,R0,#0  ;通过循环,将排名为5到8名的学生成绩赋给R2
  LD R5,Ne75  ;将-75赋给R5
  ADD R3,R2,R5  ;将成绩R2与75进行比较
  ADD R3,R3,#0  ;设置条件码
  BRn H   ;n表示R2不足75,跳过R6的计数到H
  ADD R6,R6,#1  ;R6存B的人数
H ADD R0,R0,#1  ;指针加1
  BRnzp I   ;跳回判断I
StoreB  STI R6,SaveB  ;将R6存在地址x4101
;程序结束
  HALT
;
Ne85  .FILL #-85
Ne75  .FILL #-75
SCORE .FILL x3200
AStart  .FILL x4000
BStart  .FILL x4004
SaveA .FILL x4100
SaveB .FILL x4101
  .END
相关文章
|
3月前
|
程序员 编译器
计算机语言分为三种:机器语言、汇编语言和高级语言
计算机语言分为三种:机器语言、汇编语言和高级语言
|
3月前
|
存储 固态存储
【汇编】计算机的组成
【汇编】计算机的组成
【汇编】计算机的组成
|
存储 缓存
当执行汇编指令MOV [0001H] 01H时,计算机都做了什么?
今天和几位单位大佬聊天时,讨论到一个非常有趣的问题-当程序执行MOV [0001H], 01H计算机实际上都做了哪些工作?乍一看这个问题平平无奇,CPU只是把立即数01H放在了地址为0001的内存里,但仔细想想这个问题远没有那么简单,由于现代计算机体系中CPU速度比内存要快2到3个个数量级,因此从CPU执行MOV指令,到实际把01H写入内存之间,还有非常漫长而复杂的过程。
|
存储 编译器 C语言
计算机底层知识之汇编语言
汇编语言和本地代码是一一对应的 推荐阅读指数⭐️⭐️⭐️⭐️⭐️ 不会转换成本地代码的伪指令 推荐阅读指数 ⭐️⭐️⭐️ 汇编语言的语法是操作码 + 操作数 推荐阅读指数⭐️⭐️⭐️⭐️⭐️ mov指令 推荐阅读指数 ⭐️⭐️⭐️ 对栈进行push 和 pop 推荐阅读指数 ⭐️⭐️⭐️ 函数调用机制 推荐阅读指数 ⭐️⭐️⭐️⭐️⭐️ 函数内部的处理 推荐阅读指数 ⭐️⭐️⭐️⭐️⭐️ 全局变量用的内存空间 推荐阅读指数 ⭐️⭐️⭐️ 循环处理的实现方法 推荐阅读指数 ⭐️⭐️⭐️⭐️⭐️
计算机底层知识之汇编语言
|
程序员 芯片 流计算
MOTOROLA MVME 162-01 直接用汇编语言编程的计算机程序
MOTOROLA MVME 162-01 直接用汇编语言编程的计算机程序
102 0
MOTOROLA MVME 162-01 直接用汇编语言编程的计算机程序
|
Linux C语言 芯片
Linux系统中使用汇编初始化外设方法
大家好,我是ST。 今天主要和大家聊一聊,如何使用汇编语言来实现芯片外设的初始化功能。
164 0
Linux系统中使用汇编初始化外设方法
|
存储 Linux C语言
嵌入式Linux系统中ARM汇编语言的使用方法
大家好,今天主要大家聊一聊,如何在ARM中使用汇编语言的方法。
205 0
嵌入式Linux系统中ARM汇编语言的使用方法
|
存储
微机原理之指令系统和汇编程序设计
### **8086 CPU的七种寻址方式** 8086 CPU寻址方式 •8086中,CS、DS、ES和SS段寄存器在程序运行过程中分别指向当前的代码段、数据段、附加段和堆栈段。而操作数可能存放在代码段中,也可能存放在数据段、附加段、堆栈段中,还可能存放在8086CPU内部的寄存器中。**存放操作数的内存单元相对于其所在段的段起始地址偏移量称为偏移地址或有效地址EA(Effective Address)。获得操作数所在地址的方法称为寻址方式。**在8086系统中,一般将寻址方式分为两类:一类是寻找操作数的地址;另一类是寻找要执行的下一条指令的地址,即程序寻址。 •MOV DST, SRC
259 0
微机原理之指令系统和汇编程序设计