BCD 码的应用
2016-01-25 11:55
302 查看
大家都知道在计算机里面都是使用二进制,其实,8086/8088 CPU 也可以使用十进制进行计算的。
在计算机中的十进制数称为 BCD 码,它是使用四位二进制数,表示一位十进制数字。
常见的 BCD 码是 8421 码。即:0000 ~ 1001 分别代表 0 ~ 9。
一个字节有 8 位数,可以代表两位十进制数,即:0000 0000 ~ 1001 1001,分别代表 0 ~ 99。
二进制的写法,太长了,写成 16 进制好看些,即:00H ~ 99H,代表十进制的 0 ~ 99。
用一个字节代表两位十进制数,这称为压缩的 BCD 码。
如果只是使用低四位,一个字节代表就只能代表一位十进制数,这称为非压缩的 BCD 码。
用 BCD 码代表十进制进行数值计算,我们的希望是“逢十进一”。
但是,CPU 是按照二进制计算的,它只会“逢二进一”。
那么,低四位向高低位进位的时候,仅仅是超过 15 的时候才进位,即“逢 16 进一”。
如果用 BCD 码相加,希望低四位(或高四位)能够“逢十进一”,那就在它们超过了 9 、应该进位而没有进位的时候,给它再加上 6,它就可以进位了。
另外,如果已经发生了进位,这个进位 1,就代表进走了 16,比十进制多进走了 6,此时,也应该再加上 6。
这两个步骤,称为“十进制调整”。经过十进制调整,运算结果就符合十进制的运算规则了。
在 8086/8088 CPU 指令系统中,具有这种调整指令:DAA。
在压缩的 BCD 码相加后,使用 DAA 指令,它就会把结果调整为符合十进制运算的 BCD 码。
如果是非压缩的 BCD 码相加,则应该使用 AAA 指令。
其它几种 BCD 码的运算,应该使用的调整指令如下:
压缩的 BCD 码相减后,应使用 DAS 指令;
非压缩的 BCD 码相减后,应该使用 AAS 指令;
非压缩的 BCD 码相乘后,应该使用 AAM 指令;
非压缩的 BCD 码相除后,应该使用 AAD 指令。
注意,没有压缩的 BCD 码相乘、除后的调整指令。
这些 BCD 码的十进制调整指令,都是对 AL 中的运算进行调整。因此,各种 BCD 码的运算,都应放在 AL 中进行。
下面是几个十进制调整指令的应用例题。
;============================================
一、非压缩的 BCD 码的加法
;12345+67890=80235 计算并全部显示出来
;----------------------------------------------
DATAS SEGMENT
X DB 1, 2, 3, 4, 5 ;存放5位十进制数
Y DB 6, 7, 8, 9, 0 ;都是非压缩的BCD码
Z DB 6 DUP(?) ;6位数的和
DATAS ENDS
;----------------------------------------------
CODES SEGMENT
ASSUME CS:CODES, DS:DATAS
START:
MOV AX, DATAS
MOV DS, AX
MOV SI, 0
MOV CX, 5 ;计划循环5次
K1: MOV DL, X[SI] ;取出一位X
ADD DL, 30H ;变成ASCII码
MOV AH, 2 ;显示在屏幕
INT 21H
INC SI ;指向下一位
LOOP K1
MOV DL, '+' ;显示加号
MOV AH, 2
INT 21H
MOV SI, 0
MOV CX, 5
K2: MOV DL, Y[SI]
ADD DL, 30H
MOV AH, 2 ;显示5位数Y
INT 21H
INC SI
LOOP K2
MOV DL, '=' ;显示等号
MOV AH, 2
INT 21H
;---------------下面是5位非压缩的BCD码相加.
CLC
MOV SI, 4
MOV CX, 5 ;循环加5次
K3: MOV AL, X[SI] ;X、Y都是非压缩的BCD码
ADC AL, Y[SI] ;在AL中相加
AAA ;非压缩的BCD码调整
MOV Z[SI + 1], AL ;保存和数
DEC SI
LOOP K3
;---------------下面第6位BCD码.
MOV AL, 0
ADC AL, 0
MOV Z, AL
;---------------下面是6位和的BCD码显示.
MOV SI, 0
MOV CX, 6 ;显示6位
K4: MOV DL, Z[SI]
ADD DL, 30H
MOV AH, 2
INT 21H
INC SI
LOOP K4
;---------------下面就结束程序.
MOV AH, 4CH
INT 21H
CODES ENDS
END START
从这个程序来看,进行多位数的加减法计算,用 BCD 码是十分方便的,位数的多少,几乎就没有障碍。
特别是显示,要比使用二进制来计算后,再用十进制数字的显示,要方便的多
参考网址:http://zhidao.baidu.com/question/392882475.html
;============================================
二、压缩的 BCD 码相乘
压缩的 BCD 码相乘,8086/8088 指令系统中并没有相应的十进制调整指令,因此,就不能使用乘法指令了。
那么,这个乘法,就只能用“累加”的方法来做。
即:用乘数当做循环次数,循环的把被乘数加起来。每一次循环,加一次被乘数,乘数减一次一,直到减到0。
这里的加、减,都是 BCD 码运算,加减之后,都要用十进制调整。
;压缩BCD码相乘程序
DATA SEGMENT
N1 DB 28H ;28 ,写两个压缩的BCD码
N2 DB 04H ; 4 ,当做乘数
Product DW ? ;乘积,结果应为0112H,即28*4=112
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE, DS:DATA
START:
MOV AX, DATA
MOV DS, AX
;-----------------------------------------
MOV AX, 0 ;积为0
MOV CL, N2 ;相加的次数
AGAIN:
ADD AL, N1 ;N1加入到积中
DAA ;压缩BCD码的加法十进制调整
XCHG AH, AL ;交换高8位
ADC AL, 0 ;高8位加上进位
DAA ;调整
XCHG AH, AL ;交换回来
XCHG AL, CL ;相加的次数
SUB AL, 01 ;减一
DAS ;压缩BCD码的减法十进制调整
XCHG AL, CL ;送回
JNZ AGAIN ;非0转移,继续累加
MOV Product, AX ;保存乘积
;-----------------------------------------
MOV AH, 4CH
INT 21H
CODE ENDS
END START
DAA、DAS,这两条指令,只能用在AL的加减运算的后面。
因此,其它寄存器的运算,都要弄到AL中来进行,算完了,再弄回去。所以,要来回的换。
原题网址:http://zhidao.baidu.com/question/392894929.html
;============================================
三、16 进制数变换成 ASCII 码
16 进制数 0 ~ 9、A ~ F 变换成 ASCII 码 30H ~ 39H、41H ~ 46H,需要分别对数字加上 30H 或 37H。
这种变换一般都是使用分支程序、查表程序的方法。
还有一种使用十进制调整的方法,程序非常简单,但是技巧性很强,一般人是难以理解的。
程序片断如下:
MOV AL, X ;取来数字0~9、A~F
ADD AL, 90H
DAA
ADC AL, 40H
DAA
MOV Y, AL ;保存ASCII码
变换部分仅有四条指令,是不是很简单?
;============================================
在计算机中的十进制数称为 BCD 码,它是使用四位二进制数,表示一位十进制数字。
常见的 BCD 码是 8421 码。即:0000 ~ 1001 分别代表 0 ~ 9。
一个字节有 8 位数,可以代表两位十进制数,即:0000 0000 ~ 1001 1001,分别代表 0 ~ 99。
二进制的写法,太长了,写成 16 进制好看些,即:00H ~ 99H,代表十进制的 0 ~ 99。
用一个字节代表两位十进制数,这称为压缩的 BCD 码。
如果只是使用低四位,一个字节代表就只能代表一位十进制数,这称为非压缩的 BCD 码。
用 BCD 码代表十进制进行数值计算,我们的希望是“逢十进一”。
但是,CPU 是按照二进制计算的,它只会“逢二进一”。
那么,低四位向高低位进位的时候,仅仅是超过 15 的时候才进位,即“逢 16 进一”。
如果用 BCD 码相加,希望低四位(或高四位)能够“逢十进一”,那就在它们超过了 9 、应该进位而没有进位的时候,给它再加上 6,它就可以进位了。
另外,如果已经发生了进位,这个进位 1,就代表进走了 16,比十进制多进走了 6,此时,也应该再加上 6。
这两个步骤,称为“十进制调整”。经过十进制调整,运算结果就符合十进制的运算规则了。
在 8086/8088 CPU 指令系统中,具有这种调整指令:DAA。
在压缩的 BCD 码相加后,使用 DAA 指令,它就会把结果调整为符合十进制运算的 BCD 码。
如果是非压缩的 BCD 码相加,则应该使用 AAA 指令。
其它几种 BCD 码的运算,应该使用的调整指令如下:
压缩的 BCD 码相减后,应使用 DAS 指令;
非压缩的 BCD 码相减后,应该使用 AAS 指令;
非压缩的 BCD 码相乘后,应该使用 AAM 指令;
非压缩的 BCD 码相除后,应该使用 AAD 指令。
注意,没有压缩的 BCD 码相乘、除后的调整指令。
这些 BCD 码的十进制调整指令,都是对 AL 中的运算进行调整。因此,各种 BCD 码的运算,都应放在 AL 中进行。
下面是几个十进制调整指令的应用例题。
;============================================
一、非压缩的 BCD 码的加法
;12345+67890=80235 计算并全部显示出来
;----------------------------------------------
DATAS SEGMENT
X DB 1, 2, 3, 4, 5 ;存放5位十进制数
Y DB 6, 7, 8, 9, 0 ;都是非压缩的BCD码
Z DB 6 DUP(?) ;6位数的和
DATAS ENDS
;----------------------------------------------
CODES SEGMENT
ASSUME CS:CODES, DS:DATAS
START:
MOV AX, DATAS
MOV DS, AX
MOV SI, 0
MOV CX, 5 ;计划循环5次
K1: MOV DL, X[SI] ;取出一位X
ADD DL, 30H ;变成ASCII码
MOV AH, 2 ;显示在屏幕
INT 21H
INC SI ;指向下一位
LOOP K1
MOV DL, '+' ;显示加号
MOV AH, 2
INT 21H
MOV SI, 0
MOV CX, 5
K2: MOV DL, Y[SI]
ADD DL, 30H
MOV AH, 2 ;显示5位数Y
INT 21H
INC SI
LOOP K2
MOV DL, '=' ;显示等号
MOV AH, 2
INT 21H
;---------------下面是5位非压缩的BCD码相加.
CLC
MOV SI, 4
MOV CX, 5 ;循环加5次
K3: MOV AL, X[SI] ;X、Y都是非压缩的BCD码
ADC AL, Y[SI] ;在AL中相加
AAA ;非压缩的BCD码调整
MOV Z[SI + 1], AL ;保存和数
DEC SI
LOOP K3
;---------------下面第6位BCD码.
MOV AL, 0
ADC AL, 0
MOV Z, AL
;---------------下面是6位和的BCD码显示.
MOV SI, 0
MOV CX, 6 ;显示6位
K4: MOV DL, Z[SI]
ADD DL, 30H
MOV AH, 2
INT 21H
INC SI
LOOP K4
;---------------下面就结束程序.
MOV AH, 4CH
INT 21H
CODES ENDS
END START
从这个程序来看,进行多位数的加减法计算,用 BCD 码是十分方便的,位数的多少,几乎就没有障碍。
特别是显示,要比使用二进制来计算后,再用十进制数字的显示,要方便的多
参考网址:http://zhidao.baidu.com/question/392882475.html
;============================================
二、压缩的 BCD 码相乘
压缩的 BCD 码相乘,8086/8088 指令系统中并没有相应的十进制调整指令,因此,就不能使用乘法指令了。
那么,这个乘法,就只能用“累加”的方法来做。
即:用乘数当做循环次数,循环的把被乘数加起来。每一次循环,加一次被乘数,乘数减一次一,直到减到0。
这里的加、减,都是 BCD 码运算,加减之后,都要用十进制调整。
;压缩BCD码相乘程序
DATA SEGMENT
N1 DB 28H ;28 ,写两个压缩的BCD码
N2 DB 04H ; 4 ,当做乘数
Product DW ? ;乘积,结果应为0112H,即28*4=112
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE, DS:DATA
START:
MOV AX, DATA
MOV DS, AX
;-----------------------------------------
MOV AX, 0 ;积为0
MOV CL, N2 ;相加的次数
AGAIN:
ADD AL, N1 ;N1加入到积中
DAA ;压缩BCD码的加法十进制调整
XCHG AH, AL ;交换高8位
ADC AL, 0 ;高8位加上进位
DAA ;调整
XCHG AH, AL ;交换回来
XCHG AL, CL ;相加的次数
SUB AL, 01 ;减一
DAS ;压缩BCD码的减法十进制调整
XCHG AL, CL ;送回
JNZ AGAIN ;非0转移,继续累加
MOV Product, AX ;保存乘积
;-----------------------------------------
MOV AH, 4CH
INT 21H
CODE ENDS
END START
DAA、DAS,这两条指令,只能用在AL的加减运算的后面。
因此,其它寄存器的运算,都要弄到AL中来进行,算完了,再弄回去。所以,要来回的换。
原题网址:http://zhidao.baidu.com/question/392894929.html
;============================================
三、16 进制数变换成 ASCII 码
16 进制数 0 ~ 9、A ~ F 变换成 ASCII 码 30H ~ 39H、41H ~ 46H,需要分别对数字加上 30H 或 37H。
这种变换一般都是使用分支程序、查表程序的方法。
还有一种使用十进制调整的方法,程序非常简单,但是技巧性很强,一般人是难以理解的。
程序片断如下:
MOV AL, X ;取来数字0~9、A~F
ADD AL, 90H
DAA
ADC AL, 40H
DAA
MOV Y, AL ;保存ASCII码
变换部分仅有四条指令,是不是很简单?
;============================================
相关文章推荐
- 80x86汇编编程两题
- 在WPF中使用PlaneProjection模拟动态3D效果
- 双向流水灯的最简单程序
- CRC 的应用
- 彩虹文字--RainbowText
- 十进制586用格雷码表示是多少?
- CRC 的简介
- 直接写屏
- 找出所有n的平方具有对称性质(也称回文数)的数
- 80x86汇编语言编程--
- 51单片机汇编语言--延时程序的延时时间
- 用80x86汇编语言编程:输入字符串,并把大写字符转为小写再输出
- 用80x86汇编语言编程--用递归方法求阶乘
- WC联合训练总结
- tomcat 加 gzip 压缩
- [问题记录] openssl error:0906D064:PEM routines:PEM_read_bio:bad base64 decode
- 淘宝双飞翼布局,两边固定中间自适应布局。中间内容先显示。
- SSH端口转发
- SpringMVC实战
- 用80x86汇编语言编程--统计1和0的个数,并显示