将分数转换为小数NASM

时间:2014-04-22 22:12:22

标签: assembly nasm

所以自从我上一篇文章以来,我已经修复了很多,但我仍然没有得到结果。我们正在研究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 

1 个答案:

答案 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