目录
目的与要求
- 分析和理解实验指定的问题。
- 利用LC-3的机器代码设计实现相关程序。
- 通过LC-3仿真器调试和运行相关程序并得到正确的结果。
内容与方法
- 利用LC-3的机器代码计算一个16位的字中有多少位是’1’
- 程序从x3000开始
- 需计算的字存储在x3100
- 计算的结果存储在x3101
程序总体设计
根据题目,用与操作不断取出操作数各位,我计划先用部分寄存器存放数据:
- R1:存放内存x3100的数据
- R2 = 16,代表循环次数,每次经过1次循环处理完1位数后,自减1,为0时结束循环。采用do-while。
- R3:存放结果,即1的个数,初始化为0。
- R4:用于取位和操作数相与的操作数,初始为1(即从最低位开始取位),通过不断左移(即乘2,这里用加法实现)实现依次取各位。
核心数据结构及算法流程
具体算法实现流程图如下:
注意代码得先声明程序起始于x3000,以及程序结束HALT。
代码如下:
0011000000000000 ;程序从x3000开始
0010001011111111 ;R1 <- M[PC+xFF]=M[x3001+xFF]=M[x3100],把x3100内存存的16位数加载到R1
0101011011100000 ;R3 <- 0, R3清零用于存放结果
0101100100100000 ;R4 <- 0, R4清零
0001100100100001 ;R4 <- R4+1=1, R4初始化为1,用于辅助取位(从最低位开始)
0101010010100000 ;R2 <- 0, R2清零
0001010010101111 ;R2 <- R2+15=0+15=15
0001010010100001 ;R2 <- R2+1=15+1=16, R2初始化为16,用于记录位数(循环次数,为0时结束)
0101101001000100 ;循环开始,R5 <- R1&R4, R1与R4相与并将结果存于R5,表示R2不为0时取第R2位数字
0000010000000001 ;R5为0时跳转至PC+1=x3009+1=x300A, R5=0说明取出的位为0,直接跳至x300A开始处理下一位
0001011011100001 ;R3 <- R3+1, R3自加,R5不为0时执行,此时说明取出的位为1,计数R3加1
0001100100000100 ;R4 <- R4+R4, R4加倍,等同R4左移,方便取下一位
0001010010111111 ;R2 <- R2-1, R2减1
0000101111111010 ;R2非0时继续循环,跳转至LOOP
0011011011110011 ;M[PC+xF3]=M[x300E+xF3]=M[x3101] <- R3, 将R3里的结果存于内存x3101处
1111000000100101 ;程序结束
调试过程
- 打开LC3Edit将上述汇编代码输入,保存为二进制文件格式(.bin),并编译生成可执行文件(.obj)(图1)
图表 1 保存编译
- 打开LC3Simulator导入编译生成的可执行文件(.obj),并设置断点。(图2)
图表 2 导入程序,设置断点
- 设值并运行(图3)
图表 3 设值运行
- 运行至断点结束,跳转至x3101,答案正确。(图4 5)
图表 4 运行及结果
图表 5 答案均正确
结论或体会
通过本次实验,我初次尝试用 LC3编写机器代码,实现简单的程序。初步学会LC3代码的编写,进一步加深了关于LC3汇编代码指令的相关学习应用。学会了关于LC3里面跳转指令,循环结构,基本加减实现。学会寄存器的灵活运用。学会如何将一个问题利用流程图的方式进行程序框架的设计。