所以自从我上一篇文章以来,我已经修复了很多,但我仍然没有得到结果。我们正在研究8086微处理器和NASM汇编器。我的代码工作得很好,直到它即将给出结果。它将显示第3条消息"数字为:"并打印小数点,"。"但在此之后它不会打印任何数字,我无法输入或退出程序或其他任何内容。我必须关闭DOSBox并再次运行它。请帮忙。
org 100h
; program converts fraction, M/N, to decimal, where M < N, M & N are both positive, and upto 6 decimal places are printed
section .data
MSG1 db "Enter the numerator: ", '$'
MSG2 db "Enter the denominator: ", '$'
MSG3 db "The number is: ", '$'
EMSG db "Please enter a number between 0 and 9 ", '$'
section .bss
M RESb 1
N RESb 1
section .text
main:
; print user prompt
mov dx, MSG1 ; get message
mov ah, 09h ; display string function
int 21h ; display it
call DEC_IN
mov [M], bx ; move numerator to memory location M
; print second prompt
mov dl, 0Ah ; line feed moved into character display register
mov ah, 02h ; charcter display function
int 21h ; display line feed
mov dl, 0Dh ; carriage return moved into character display register
int 21h ; display carriage return
mov dx, MSG2 ; get message
mov ah, 09h ; display string function
int 21h ; display it
call DEC_IN
mov [N], bx ; store denominator in memory location N
mov dl, 0Ah ; line feed moved into character display register
mov ah, 02h ; charcter display function
int 21h ; display line feed
mov dl, 0Dh ; carriage return moved into character display register
int 21h ; display carriage return
mov dx, MSG3 ; get message
mov ah, 09h ; display string function
int 21h ; display it
mov dl, 2Eh ; moves '.' to display character register
mov ah, 02h ; display character function
int 21h ; displays it
mov cx, 6 ; set loop to run 6 times
mov bx, [M] ; prepare numerator in M to be multiplied
jmp print
DEC_IN:
; input character from keyboard, converts ASCII to appropriate binary
push ax
xor bx,bx
.top:
mov ah, 01h ; keyboard input function
int 21h ; character input, copies character into al
cmp al, 0Dh ; is the input a carriage return?
je .done ; user is done
cmp al, 30h ; compares input to ASCII code for 0
jb error ; if input is less than 0 jump to error
cmp al, 39h ; compares input to ASCII code for 9
ja error ; if input is greater than 9 jump to error
sub al, 30h ; subtracts 30h to make the ASCII code into the base 10 number
imul bx, 10 ; in case the number is more than one digit
mov ah, 0 ; clear ah before copy
add bx, ax ; store ax in bx so it can run again.
jmp .top
.done:
pop ax
ret
print:
; loop to print
mov al, 10 ; prepare al for multiplication
mul bx ; multiply numerator by 10, result in AX
mov bx, [N] ; move denominator to bx to be divisor
div bx ; divide AX by denominator quotient in AL remainder in AH
add al, 30h ; convert quotient to respective ASCII symbol
mov dl, al ; move quotient into display char register
push ax ; save the remainder in AH by pushing AX on stack
mov ah, 02h ; display character function
int 21h ; display it
pop ax ; retrieve remainder in AH by popping AX from stack
mov al, 0 ; clear the quotient, AL so only the remainder, AH, is in AX
mov bx, ax ; move remainder to bx so it can run again
loop print
jmp exit
error:
; displays error message then jumps back to DEC_IN
mov dl, 0Ah ; line feed moved into character display register
mov ah, 02h ; charcter display function
int 21h ; display line feed
mov dl, 0Dh ; carriage return moved into character display register
int 21h ; display carriage return
mov dx, EMSG ; moves error message into display string register
mov ah, 09h ; display string function
int 21h ; displays it
mov dl, 0Ah ; line feed moved into character display register
mov ah, 02h ; charcter display function
int 21h ; display line feed
mov dl, 0Dh ; carriage return moved into character display register
int 21h ; display carriage return
jmp main
exit:
;exit to DOS
mov ah, 04Ch ; DOS function: Exit program
mov al, 0 ; Return exit code value
int 21h ; Call DOS. Terminate program
答案 0 :(得分:1)
好的我修好了。那些16位寄存器很棘手,因此我使用8位寄存器进行乘法和除法。我必须解决的唯一问题是例程print:
其余代码是相同的,除了在main:
中跳转到print:
之前的最后一条指令更改为mov bl,[m]
}。这是更正的例程print:
:
print:
; loop to print
xor ax, ax ; clear ax
mov al, 10 ; prepare for multiplication
mul bl ; multiply numerator in BL by 10 in AL
xor bl, bl ; clear bl to be used again
mov bl, [N] ; move denominator in to BL
div bl ; divide numerator*10 in AX by denominator in BL
mov dl, al ; move quotient in AL to display char register
push ax ; save the remainder in AH
add dl, 30h ; convert quotient to respective ASCII symbol
xor ax, ax ; clear ax for function
mov ah, 02h ; display char function
int 21h ; display it
pop ax ; retrieve remainder in AH
mov bl, ah ; move remainder to BL to start loop over
loop print
jmp exit