Assembly 将分数转换为小数NASM
因此,自从我上一篇文章以来,我已经修正了很多,但我仍然没有得到结果。我们正在研究8086微处理器和NASM汇编程序。我的代码在给出结果之前一直运行良好。它将显示第三条消息“数字是:”并打印小数点“.”,但之后它不会打印任何数字,我也无法键入或退出程序或任何内容。我必须关闭DOSBox并再次运行它。请帮忙Assembly 将分数转换为小数NASM,assembly,nasm,Assembly,Nasm,因此,自从我上一篇文章以来,我已经修正了很多,但我仍然没有得到结果。我们正在研究8086微处理器和NASM汇编程序。我的代码在给出结果之前一直运行良好。它将显示第三条消息“数字是:”并打印小数点“.”,但之后它不会打印任何数字,我也无法键入或退出程序或任何内容。我必须关闭DOSBox并再次运行它。请帮忙 org 100h ; program converts fraction, M/N, to decimal, where M < N, M & N are both
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
org 100h
; 程序将分数M/N转换为十进制,其中M
好的,我修好了。那些16位寄存器很复杂,所以我使用8位寄存器进行乘法和除法运算。我唯一需要修复的是例程print:
其余的代码是相同的,除了在main:
中,跳转到print:
之前的最后一条指令被更改为mov bl,[m]
。下面是更正后的例行程序打印:
:
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
@KenWhite我认为cx是循环计数寄存器,循环指令会自动递减cx。而且,即使它是一个无限循环,它也应该在小数点后打印数字,只是永远不会打印,而不是在循环开始之前我将cx设置为小数点后6位(打印:)是的,我想你是对的-我错过了。我说我的asm生锈了。:-)我能让它把数字打印在第一个小数位上!在跳转到例程“打印”之前,我添加了
xor ax,ax