例10.7是用“用16位除10”的方法从低向高依次得到每位的数值,但若待输出的数据是32位,用10除之后,其商很可能会超过16位,所以,不能简单地引用例10.7的方法来输出32位二进制。

假设:32位二进制数Z为A×216+B,其中:A和B都是16位二进制数。 用10去除A,得:A=A1×10+A2,于是, 

         (1) 

假设A2×216+B被10除后所得的商和余数分别为B1和C1(B1≥0,C1≥0)。 

利用式(1)和“A2<10”,我们不难看出:Z的个位就是C1和B1<216。 

令Z1=A1×216+B1,显然,Z1就是Z/10所得到的商。 

对于Z1,再利用式(1)得到商Z2和C2。……,重复上面的步骤,直到所得商为0为止。

下面的例10.9就是利用上面方法来输出32位二进制数值。

例10.9 编写一个子程序,该子程序能把32位二进制变量的数值以十进制形式输出出来。若该数值为负数,则需要输出负号"-",否则,不输出符号。

解:
.MODEL SMALL, C
.DATA

CR = 13

LF = 10

Data1

DD    908976789
.CODE
;子程序Display是按十进制输出32位二进制数值SOURCE
Display PROC USES AX BX CX DX SI DI SOURCE:DWORD
LOCAL FLAG:BYTE ;定义一个字节类型的局部变量FLAG
MOV BX, WORD PTR [SOURCE]
MOV CX, WORD PTR [SOURCE+2]
MOV FLAG, 0 ;FLAG=0——正数
CMP CX, 0
JGE next
INC FLAG ;FLAG=1——负数
NOT BX
NOT CX
ADD BX, 1 ;能否用指令INC BX?
ADC CX, 0 ;上四条指令把32位数CX-BX变为正数
next:
XOR DI, DI ;压入堆栈字符的个数
MOV SI,10 ;用10来除
.REPEAT ;本循环把32位二进制数转换成十进制

XOR

DX, DX ;数的字符串存入堆栈之中

MOV

AX, CX

DIV

SI

MOV

CX, AX

MOV

AX, BX

DIV

SI

ADD

DL, '0'

PUSH

DX

INC

DI

MOV

BX, AX
.UNTIL BX==0 && CX==0
.IF FLAG==1 ;判断前面转换的数是否为负数

MOV

AL, '-' ;若是,把符号'-'压入堆栈

PUSH

AX

INC

DI
.ENDIF
MOV CX, DI
.REPEAT ;本循环把堆栈中的字符串显示出来

POP

DX

MOV

AH, 2

INT

21H
.UNTILCXZ
MOV DL, CR ;下面六条指令显示回车、换行
MOV AH, 2
INT 21H
MOV DL, LF
MOV AH, 2
INT 21H
RET
Display ENDP
.STARTUP
INVOKE Display, Data1
INVOKE Display, -123456789
.EXIT 0
END