我正在处理我的程序,该程序应该将十进制数字从0到65535转换为十六进制。问题是我的程序不会打印4位十六进制数字。例如,它将打印5FF而不是FFFF或711而不是1111,我找不到错误。请帮忙。
下面是代码:
;***************************************************************
; decimal to hexadecimal
;***************************************************************
.model small
bufSize EQU 121
.stack 100h
.data
bufSize DB bufSize
read DB ? ;how many symbols
buf DB bufSize dup (?)
msg DB 'Please, enter decimal digit: $'
enterr DB 13, 10, '$'
errormsg DB 'wrong input $'
form DB 'answer is: $'
.code
begin:
MOV ax, @data
MOV ds, ax
;****reads line****
MOV ah, 9
MOV dx, offset msg
INT 21h
MOV ah, 0Ah
MOV dx, offset bufSize
INT 21h
MOV ah, 9
MOV dx, offset enterr
INT 21h
;****algorythm****
XOR ax, ax
MOV cl, read ;how many symbols
MOV bx, offset buf ;first symbol to bx
check:
CMP cl, 0
MOV ah, 9
JNE loop0
MOV dx, offset errormsg
INT 21h ;spausdiname rezultato žinutę
JE ending
errorr:
MOV ah, 9
MOV dx, offset errormsg
INT 21h ;spausdiname rezultato žinutę
JMP ending
loop0:
PUSH ax
PUSH dx
XOR ax,ax
XOR dx,dx
JMP loop1
loop1:
MOV dh,0Ah
MUL dh
MOV dl,[bx]
cmp dl, '0'
JB errorr
cmp dl, '9'
JA errorr
SUB dl,30h
ADD al,dl
loop2:
INC bx
DEC cl
CMP cl, 0
JNE loop1
MOV cx, 16
PUSH '$$'
Division:
MOV dx, 0
DIV cx ;[DX,AX]:10 = AX(remainder DX)
PUSH dx
CMP ax, 0
JA Division
;printing
MOV ah, 9
MOV dx, offset form
INT 21h
MOV ah, 2
Print:
POP dx
CMP dx, "$$"
JE ending
CMP dx, 9
JNBE above
less:
ADD dl, '0'
INT 21h
JMP Print
above:
ADD dl, '7'
INT 21h
JMP Print
pop dx
pop ax
ending:
MOV ah, 4Ch
MOV al, 0
INT 21h
END begin
感谢您的回答。 :)
答案 0 :(得分:0)
问题在于第一个循环中的乘法步骤:
MUL dh
这种形式的MUL
指令采用8位寄存器或内存操作数(此处为DH
),将其与8位AL
寄存器相乘,并存储16-位结果为AX
。因为这只允许8位操作数,所以它只能在高达255的输入值下正常工作。如果希望它适用于高达65535的值,则需要使用将两个16位值相乘的形式来生成DX:AX
中的32位结果(并忽略该结果的高16位,放在DX
中),例如:
MUL dx
但这需要改变您的寄存器,因为您当前已经使用DL
来保存当前数字,正如我所说,DX
将设置为高16位。 32位结果。在这种情况下,最好使用IMUL
带符号的乘法指令,这很方便,因为它最多可能需要3个参数(x86不常见):
MOV dx,0Ah;
IMUL ax,ax,0Ah
这会将AX
设置为结果的最后16位,并丢弃前16位。乘法有符号这一事实在这里没有任何区别,因为在这两种情况下,底部的16位都是相同的。