一、 实验要求
- 编程实现两个数:#998877H 和 #778899H 的加法运算。
- 编程实现两个数:#998877H 和 #778899H 的减法运算。
二、 实验设计
1.整体思路
无符号角度:
(1)加法
1.初始化:设置两个数 998877H 和 778899H。
2.低位相加:
从 NUM1 获取第2位(即77)并存入 R0。
从 NUM2 获取第2位(即77)并存入 A。
执行 ADD A, R0 将 A 与 R0 相加,结果存回 A。
将结果存入 R3。
3.中位相加:
从 NUM1 获取第1位(即88)并存入 R1。
从 NUM2 获取第1位(即88)并存入 A。
执行 ADDC A, R1 将 A 与 R1 及进位相加,结果存回 A。
将结果存入 R4。
4.高位相加:
从 NUM1 获取第0位(即99)并存入 R2。
从 NUM2 获取第0位(即99)并存入 A。
执行 ADDC A, R2 将 A 与 R2 及进位相加,结果存回 A。
将结果存入 R5。
5.检查进位:
如果最高位运算后没有进位,则将 R6 设置为 01H。
否则,清除进位标志。
(2)减法
1.初始化:设置两个数 998877H 和 778899H。
2.低位相减:
从 NUM1_SUB 获取低位并存入 R0。
从 NUM2_SUB 获取低位并存入 A。
执行 SUBB A, R0 将 A 减去 R0,结果存回 A。
将结果存入 R3。
3.中位相减:
从 NUM1_SUB 获取中位并存入 R1。
从 NUM2_SUB 获取中位并存入 A。
执行 SUBB A, R1 将 A 减去 R1,结果存回 A。
将结果存入 R4。
4.高位相减:
从 NUM1_SUB 获取高位并存入 R2。
从 NUM2_SUB 获取高位并存入 A。
执行 SUBB A, R2 将 A 减去 R2,结果存回 A。
将结果存入 R5。
有符号数角度:
对于有符号数的加法和减法,过程与无符号数相同,因为在这个代码中没有涉及到负数的情况。如果有负数参与,需要考虑补码表示和溢出检测。
2.流程图
1.加法
2.减法
1.主要模块设计思路及分析
(1)加法模块
数据准备:将两个数分别存储在内存中,按照字节顺序排列。
逐位相加:从最低位开始,逐位进行加法运算,同时处理进位。
结果存储:将每一步的结果存储在寄存器中。
进位处理:使用 JNC 指令来检测是否有进位产生。
(2)减法模块
数据准备:将两个数分别存储在内存中,按照字节顺序排列。
逐位相减:从最低位开始,逐位进行减法运算。
结果存储:将每一步的结果存储在寄存器中。
借位处理:使用 SUBB 指令来自动处理借位。
三、 实现效果
1.加法部分
/*#998877H 和 #778899H 的加法运算。 0111 1110 */
2.减法部分
/*#998877H 和 #778899H 的减法运算。 21 FFDE */
四、总结
(1)遇到的问题及解决办法(当我想将加法和减法写在一起时)
1. 将加法和减法程序分开,分别使用不同的起始地址(例如,ORG 0000H 和 ORG 0100H),以防止重定义,同时确保在汇编时不会冲突。
2.当完成加法模块后不能直接写END,可以加上指令JMP START_SUB跳转到减法部分,继续执行下面的减法部分
3. 将减法部分的数据标签定义为 NUM1_SUB 和 NUM2_SUB,以确保数据标签之间没有冲突。
4. 我发现图中的位置读错了,我是想先读取两个num的低位然后相加。第12行,我将num1地址赋给DRTR,它的0H地址存放的是99H,1H是88H,2H是77H,所以我的A偏移量2H是对的,可以正确读到num1的77H。第18行,我将num2地址赋给DRTR,它的0H地址存放的是77H,1H是88H,2H是99H,所以取它的低位时,还是用2H偏移量
修改之后:
5. 代码取数值的时候错了,我将低位相减取的0H,算的时候就是高位相减了。错误结果会与正确结果相差一个-1
6. 我知道了JNC指令的运用:
如果最近一次算术运算(如加法)没有产生进位(C=0),则执行跳转,跳转到标签LOOP指定的位置继续执行。
如果产生了进位(C=1),则不跳转,程序顺序执行下一条指令。
(2)收获与体会
通过这次编程实验,我更加深入地理解了十六进制数与二进制数之间的转换以及它们在进行算术运算时的具体实现方式。特别是如何逐位进行加法和减法运算,并处理进位和借位。实验中,我使用了多个寄存器(如A、R0-R5)来暂存数据和运算结果。这使我更加熟悉了寄存器间的数据传输指令(如MOV)以及如何使用这些寄存器进行算术运算(如ADD、ADDC、SUBB)。在加法运算中,我使用了JNC(无进位跳转)指令来根据进位标志(C)的状态决定是否执行某个代码段。这加深了我对条件跳转指令的理解,并学会了如何根据程序的需要灵活使用它们。在减法运算中,我使用了SUBB指令来进行带借位的减法运算。这使我理解了无符号数减法运算的特殊性,即在发生借位时如何正确处理。