在NASM中将分数转换为十进制

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

标签: assembly nasm

我们正在研究8086微处理器和NASM汇编程序。我的代码汇编很好,但是当我执行时,我只得到一堆随机符号。我们的任务说明是:

  1. 显示适当的提示。
  2. 调用名为DEC_IN的过程,该过程将为a。从键盘b输入有效的无符号base-10整数(0-65,535)。将输入的字符转换为等效的二进制数,存储在寄存器BX
  3. 将输入值保存到内存位置M
  4. 显示另一个适当的提示。
  5. 再次调用DEC_IN,将值读入BX并将其保存到另一个存储位置N。
  6. 使用以下算法打印扩展:a。打印“。”b。执行以下步骤10次:i。将10 x M除以N,得到商Q和余数R. ii.Print Q. iii。用R代替M并转到步骤i。
  7. 您的程序应保存并恢复他们更改的任何寄存器
  8. 这是我的代码,它被严重破坏了:

    org     1000h
    ; program converts fraction to decimal, where M < N, M & N are both positive, and upto 6 decimal places are printed
    
    section .data
    MSG1    dw  "Enter the numerator: ", '$'
    MSG2    dw  "Enter the denominator: ", '$'
    EMSG    dw  "Please enter a number between 0 and 9 ", '$'
    section .bss
    M       RESW    1   
    N       RESW    1
    
    section .text
    main:
    ; print user prompt 
    mov     dx, MSG1    ; get message
    mov     ah, 09h     ; display string function
    int     21h         ; display 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
    xor     cx, cx      ; clear cx
    jmp     DEC_IN  
    prompt:
    ; print second prompt
    mov     dx, MSG2    ; get message
    mov     ah, 09h     ; display string function
    int     21h         ; display 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
    inc     cx          ; will make next iteration store denominator in N
    jmp     DEC_IN
    DEC_IN:
    ; input character from keyboard, converts ASCII to appropriate binary, stores into respective memory location
    mov     ah, 01h     ; keyboard input function
    int     21h         ; character input, copies character into al
    mov     bx, ax      ; moves ax into bx to avoid ax being messed with
    cmp     bx, 30h     ; compares input to ASCII code for 0
    jl      error       ; if input is less than 0 jump to error
    cmp     bx, 39h     ; compares input to ASCII code for 9
    jg      error       ; if input is greater than 9 jump to error
    sub     bx, 30h     ; subtracts 30h to make the ASCII code into the base 10 number
    cmp     cx, 1       ; check if input is denominator
    je      prepare     
    mov     word [M], bx ; stores user input into memory location M
    jmp     prompt
    
    prepare:
    ; store denominator in N
    mov     word [N], bx    ; stores input into memory location N
    mov     dl, 2Eh     ; moves '.' to display character register
    mov     ah, 02h     ; display character function
    int     21h         ; displays it
    mov     cx, 10      ; set loop to run 10 times
    mov     bx, word [M]
    jmp     print
    
    print:
    ; loop to print 
    mov     ax, 10      ; setup for multiplication
    mul     bx          ; multiply numerator by 10
    mov     bx, word [N]
    div     bx
    push    dx
    mov     dx, ax      
    mov     ah, 09h     ; display string function
    int     21h         ; display it
    pop     dx  
    mov     bx, dx
    loop    print
    jmp     exit
    
    error:
    ; displays error message then jumps back to DEC_IN
    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     DEC_IN      
    
    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 :(得分:4)

如果您的代码被严重破坏,则可能表明您需要备份并采取较小的步骤。

org 1000h几乎肯定是错的。正如rjbh所说,你不想要一个org的.exe文件(Nasm不会接受它!)。我假设你正在做.com文件,但是想要org 100h。这不会导致&#34;我们要在100h加载,只是告诉Nasm dos会在100h加载我们。如果这不仅仅是&#34; posto&#34;,修复它应该至少会在屏幕上显示提示。

您的提示应为db而不是dw。 (我认为我们没有做UNICODE)。您可能希望在提示中包含回车符/换行符对,而不是在代码中打印它们。它会使您的代码更小更简单......从而更容易找到错误。 :)无论哪种方式都有效。

您的变量MN是正确的。可怕的名字 - 不是很有意义&#34;有意义的&#34; - 但在作业中指定。我可能已经将它们命名为&#34;分子&#34;和&#34;分母&#34; - 更多打字,但值得跟踪你正在做什么(IMO)。那里有一点点&#34;陷阱&#34;与分母 - 我们可能不想让用户输入0!

您的代码启动正常,最高为jmp DEC_IN。我认为这应该是一个用call指令调用并从ret指令返回的子程序。通常&#34;通常&#34;从ax中的子例程返回值,但是赋值为bx。没问题...

; your prompt
call DEC_IN
mov [M], bx
; your other prompt
call DEC_IN
mov [N], bx
; call a display routine?
; or put it in-line?
exit:
; always!
; your subroutines go here
; after the "main" part of your code

; your prompt call DEC_IN mov [M], bx ; your other prompt call DEC_IN mov [N], bx ; call a display routine? ; or put it in-line? exit: ; always! ; your subroutines go here ; after the "main" part of your code 这样可以避免您使用来了解您正在执行的号码。当然,cx需要以DEC_IN结尾,并且赋值表示保存和恢复寄存器。我们无法保存和恢复ret当然,我们会在其中返回我们的号码!你开始...... bx

DEC_IN:
; input character from keyboard, converts ASCII to appropriate binary, stores into respective memory location
mov     ah, 01h     ; keyboard input function
int     21h         ; character input, copies character into al
mov     bx, ax      ; moves ax into bx to avoid ax being messed with
不要急于将号码输入DEC_IN: ; input character from keyboard, converts ASCII to appropriate binary, stores into respective memory location mov ah, 01h ; keyboard input function int 21h ; character input, copies character into al mov bx, ax ; moves ax into bx to avoid ax being messed with 。首先,中仍有垃圾。首先,您要确保它是有效数字。在此之前,你可能想检查它是否是指示用户完成的回车 - 我们不想尝试制作我们号码的那一部分! bx

ah

我会让你弄清楚其余部分 - 这个答案太长了。再问一下你是否卡住了。