BCD 码的应用

来源:互联网 发布:java 163邮箱发送邮件 编辑:程序博客网 时间:2024/05/16 17:49

大家都知道在计算机里面都是使用二进制,其实,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码

变换部分仅有四条指令,是不是很简单?

;============================================

0 0