我的问题与我编写的程序有关,该程序获取DX中的值,使用增量循环将其转换为十进制ASCII,并将其存储在字符串变量中。
首先,这是存储在其中的字符串变量:
;This string holds a 16 bit value represented in ascii decimal.
;the first byte is the starting char offset byte. It's used by the
;procedure that prints it to determine which character to print first.
;For instance the number "27" would have a starting char offset value of 4.
;This is done to avoid printing unnecessary leading zeros.
;eos is the end of string marker. It has a value of 0.
dec_str db ?,"00000",eos
以下是程序:
DX_2_DEC PROC
;CONVERTS A 16 BIT VALUE INTO DECIMAL ASCII CHARACTERS STORING IT
;AS A PRINTABLE STRING IN dec_str.
;EXPECTS THE 16 BIT HEX NUMBER IN DX.
;EXPECTS DS TO BE LOADED WITH DATA SEGMENT textSeg
push ax
push cx
push di
lea di, dec_str ;ds:di -> textSeg:dec_str
inc di ;skip past the starting char offset byte
mov al, '0' ;initializing the string with 0's
mov cx, 5 ;writing 5 0's
INIT_STR_WITH_ZEROS:
mov BYTE PTR [di], al
inc di
loop INIT_STR_WITH_ZEROS ;dec_str is now initialized.
dec di ;dec back to the 5th ascii character
test dx, 0ffffh ;if dx = 0, then skip the inc loop
jz SET_1S_ ;and hop down to set the starting char
;offset byte to 5
mov cx, dx ;the given 16 bit value is the loop cntr
DECIMAL_ASCII_INC:
inc BYTE PTR [di-0] ;inc the 5th ascii char
cmp BYTE PTR [di-0], '9' ;is the 5th character greater than a 9
jbe INC_DEC_ASCII ;if not, loop back & inc the 5th ascii char
mov BYTE PTR [di-0], '0' ;if so, reset 5th char to 0
inc BYTE PTR [di-1] ;and inc the 4th char
cmp BYTE PTR [di-1], '9' ;is the 4th character greater than a 9
jbe INC_DEC_ASCII ;if not, loop back & inc the 5th ascii char
mov BYTE PTR [di-0], '0'
mov BYTE PTR [di-1], '0' ;if so reset 5th & 4th char to 0
inc BYTE PTR [di-2] ;and inc the 3rd char
cmp BYTE PTR [di-2], '9' ;is the 3rd character greater than a 9
jbe INC_DEC_ASCII ;if not, loop back & inc the 5th ascii char
mov BYTE PTR [di-0], '0'
mov BYTE PTR [di-1], '0'
mov BYTE PTR [di-2], '0' ;if so reset 5th - 3rd char to 0
inc BYTE PTR [di-3] ;and inc the 2nd char
cmp BYTE PTR [di-3], '9' ;is the 2nd character greater than a 9
jbe INC_DEC_ASCII ;if not, loop back & inc the 5th ascii char
mov BYTE PTR [di-0], '0'
mov BYTE PTR [di-1], '0'
mov BYTE PTR [di-2], '0'
mov BYTE PTR [di-3], '0' ;if so reset 5th - 2nd char to 0
inc BYTE PTR [di-4] ;and inc the 1st char
cmp BYTE PTR [di-4], '7' ;1st can't be 7 or more (65,535 is the max)
jb INC_DEC_ASCII
pop di
pop cx
pop ax
ret
INC_DEC_ASCII:
loop DECIMAL_ASCII_INC ;loop until the ascii decimal characters
;represent the value of the hexadecimal
;number in dx.
jmp SET_DEC_LEN ;skip the hop
SET_1S_: ;need a hop since jump is out of range
jmp SET_1S
SET_DEC_LEN:
cmp dx, 10000d
jb CHK_1000S ;if dx < 10,000 check the 1000s place value.
mov BYTE PTR [di-5], 1 ;otherwise, starting char offset byte takes 1
jmp DONE_WITH_DEC
CHK_1000S:
cmp dx, 1000d
jb CHK_100S ;if dx < 1,000 check the 100s place value.
mov BYTE PTR [di-5], 2 ;otherwise, starting char offset byte takes 2
jmp DONE_WITH_DEC
CHK_100S:
cmp dx, 100d
jb CHK_10S ;if dx < 100 check 10s place value.
mov BYTE PTR [di-5], 3 ;otherwise, starting char offset byte takes 3
jmp DONE_WITH_DEC
CHK_10S:
cmp dx, 10d
jb SET_1S ;if dx < 10 check 1s place value.
mov BYTE PTR [di-5], 4 ;otherwise, starting char offset byte takes 4
jmp DONE_WITH_DEC
SET_1S: ;set to 1s place value.
mov BYTE PTR [di-5], 5 ;starting char offset byte takes 5
DONE_WITH_DEC:
pop di
pop cx
pop ax
ret
DX_2_DEC ENDP
此过程有效,它确实将DX转换为十进制ascii字符串,但它并不总是在相同的时间内完成。 DX中的值越大,增量循环执行的时间越长。将十六进制和二进制转换为ascii要容易得多,但每种方法都完全不同。这个程序的姐妹程序DX_2_HEX&amp; DX_2_BIN根本不相似。但是,无论给定16位值的实际大小如何,DX_2_HEX和DX_2_BIN始终执行相同的时间。这就是我想要用这个程序做的。
我有一种感觉我应该使用二进制编码的十进制指令,但在阅读了intel 8086程序员的参考资料之后,我只是看不出它们如何用于将数字从0转换为65,535到十进制ascii。我找不到任何可能导致十进制值大于9,999的转换过程示例。
答案 0 :(得分:1)
mov ax, dx
lea di, dec_str
mov cl, 5
mov bx, 100000
CONVERT: xor dx, dx
div bx
add al, 30h
mov si, dx
mov [di], al
inc di
mov ax, bx
mov bx, 0Ah
xor dx, dx
div bx
mov bx, ax
mov ax, si
dec cl
jnz CONVERT