北航微机原理上机实验之二(4位BCD码相加)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
2011- 2012 学年第一学期
微机原理实验二:4位BCD码相加班级392311(转系)学院高等工程
姓名李柏学号3903·2415
2011年12月4日
本人声明
我声明,本论文为本人独立完成的,在完成论文时所利用的一切资料均已在参考文献中列出。
学习字符型数据与数值型数据的相互转换方法,了解BCD码输入及相加的方法。
在数据段中定义3个变量x1,x2,x3,用于存储从键盘上输入的两个BCD码,要求低位数据占高位置存放,x3存放这两个BCD码的和;从键盘输入两个4位的BCD码,检查是否为数字键,非数字键不接收;将输入的2个4位字符型数据转换为4位非压缩BCD码存于数据段的变量中;将2个4位非压缩BCD码相加,将结果利用INT21H的2号功能
DATA SEGMENT ;用X1与X2定义数据段存储输入的十进制数,用X3存储运算结果.
X1 DB 4 DUP(0)
X2 DB 4 DUP(0)
X3 DB 5 DUP(0) ;两个4位数相加可以生成5位数,因此定义5个字节.
DATA ENDS
STACK SEGMENT STACK ;定义堆栈段,该定义也可不写,由系统自动分配空间.
DW 100 DUP(?)
STACK ENDS
CODE SEGMENT ;码段定义
ASSUME CS:CODE,DS:DATA,SS:STACK ;段分配伪指令
TYPEIN PROC ;定义子程序TYPEIN,处理每一个输入的字符
AGAIN:MOV AH, 8 ;使用DOS的8号功能,即【将键盘的输入存入AL且无回显】
INT 21H
CMP AL, 30H ;30H即‘0’,将键盘输入与’0’和’9’比较,一旦不在此范围内则认定输入无效
JB AGAIN
CMP AL, 39H
JA AGAIN
PUSH AX ;此处将输入值入栈保存,即保护现场,因为下文运用2号功能显示时中断指令INT 21H会破坏AL寄存器MOV DL, AL
MOV AH, 2
INT 21H ;执行2号指令,将DL中存储的AL【显示】
POP AX ;恢复现场
RET ;TYPEIN过程的返回指令
TYPEIN ENDP ;结束子程序TYPEIN的书写
MAIN PROC FAR ;远调用
PUSH DS ;以下三句为结尾返回DOS做准备
MOV AX, 0
PUSH AX
MOV AX, DATA
MOV DS, AX ;以下两句将指针对准数据段内的X1处
MOV SI, OFFSET X1
MOV CX, 4 ;设置了4次循环,为了在存储器的变量X1内存放被加数
NEXT1: CALL TYPEIN ;调用子程序TYPEIN
AND AL, 0FH;将AL高4位清零,因为输入的数字仅仅占用AL低4位就足够用,清零则是为了防止高4位对存储结果的干扰MOV [SI], AL ;将AL存入SI指向的位置,而SI在最初指向X1的EA
INC SI ;指针加1 (因为PTR BYTE)
LOOP NEXT1 ;循环执行4次,将被加数存入X1变量内,但是注意先输入的是十进制的高位,所以高位在低地址。
MOV DL, '+' ;上屏显示一个+号
MOV AH, 2
INT 21H
MOV SI, OFFSET X2 ;以下部分完全同理,输入加数,依然占用4字节,存入X2变量内
MOV CX, 4
NEXT2: CALL TYPEIN
AND AL, 0FH
MOV [SI], AL
INC SI
LOOP NEXT2 ;至此将加数存入了X2之中,以下进行加法运算
MOV SI, (OFFSET X2)-1 ;以下三句将SI,DI,BX分别对准了被加数,加数以及结果的最高位
MOV DI, (OFFSET X3)-1
MOV BX, (OFFSET X3)+4
MOV CX, 4 ;对CX赋值往往暗示将有4次循环
OR CX,CX ;清空FR标志位,只是为将CF置零
ADD1:
MOV AL, [SI] ;把被加数最高位送进AL
ADC AL, [DI] ;被加数与加数的最高为相加,并加上CF运算前那个状态的值
AAA;由于[SI]与[DI]存储的数位都代表非压缩的一个十进制数字,即各自的高4位一律0,且结果在AL内,满足AAA指令的条件MOV [BX], AL ;将AAA处理后的AL送入X3变量的相应位置保存起来
DEC SI ;以下三个指针自动减1,分别对齐下一位
DEC DI
DEC BX
LOOP ADD1 ;执行循环,将加数与被加数的4个数位的加和,也就是结果的低4位正确地存入X3相应位置之中,但是暂且未顾及最高位是否进位得1
;
MOV AL, 0 ;以下两句旨在获取次高位运算后产生的那个CF值,将这个标志位存入AL.
ADC AL, 0
MOV [BX],AL ;将其注入X3中充当加和结果的最高位(恰好存放在OFFSET X3代表的低地址之中)
MOV DL, '=' ;显示一个=号
MOV AH, 2
INT 21H
MOV BX, OFFSET X3
MOV CX, 5 ;此处5次循环是为了分别存入DL,将最终加和结果按各数位依次地上屏显示
NEXT3:MOV DL,[BX]
ADD DL,30H ;此处将0-9二进制数码转换成对应的ASCII码,只有加了这句才能正确显示各位数字
MOV AH,2
INT 21H
INC BX ;使用递增是因为这样正好符合十进制数高位在左先显示的客观事实
LOOP NEXT3
RET ;在MAIN过程中的退出
MAIN ENDP ;结束MAIN过程
CODE ENDS ;码段编写完毕
END ;全文结束标记
在代码编写中,收获较大,自认为需要格外注意以下几点:
1.在保护现场的动作中,对某寄存器压栈保护时,必须谨记堆栈是对字操作,千万不能犯PUSH AL之类的低级错误。
2.相应的过程开始结束有固定的语句,开始前先要想好如何退出,要一一对应。
3.显示数码时,务必将二进制码转成对应的ASCII,否则一定显示错误,具体做法是,ADD一个30H。
4.对一些固定技巧需要更敏感地读懂其意图,例如OR CX,CX (自己异或自己)等等等等。