在nasm中从2个输入数字中查找并显示最大公约数

时间:2014-09-22 13:11:53

标签: x86 nasm dos

美好的一天,

我一直在尝试编写一个执行以下操作的程序:

  1. 接受来自用户的两个ASCII号码(我还没有费心去尝试检查值)
  2. 将这些ASCII数转换为十进制值。
  3. 从这两个数字中找出最大公约数
  4. 显示结果
  5. 我觉得我已经成功完成了第1-3步,尽管我并不完全确定。这是代码:

    bits 16
    org 0x100;
    jmp main ;
    
    number1_str: db 3,0,0,0,0,'$'
    number2_str: db 3,0,0,0,0,'$'
    num1_hex: dw 2
    num2_hex: dw 2
    
    prompt1: db 'Please enter first number (from 1 to 50): ','$'
    prompt2: db 'Please enter second number (from 1 to 50): ','$'
    
    cr_lf:
         db 13,10,'$'   ; carriage return and line feed
    
    ;
    ;Displays a string in dx
    ;
    disp_str: 
        mov ah,09              ;
        int 0x21               ;
        ret                ;
    
    ;
    ; Converts an ASCII string of digits to a decimal number, and puts the result
    ; in ax, and passes the address to dx. If an error occurs, AL is set to 'E'.
    ;
    str_to_num:
        xor ax,ax              ; initial value of AX = 0
        xor bh,bh              ;                  BH = 0
        mov cx,10              ; To build integer in AX (multiply by 10)
        mov si,dx              ; DX points to start of input buffer
        call next_char         ;  
        ret                ;
    next_char:
        mov bl,[si]            ; move contents of memory pointed to by SI to BL
        cmp bl,0x0D    ; Is it a carriage return?
        je finis               ; Yes, we are done
        cmp bl,0x39            ; ASCII for the character '9' is 39h
        jg  error              ; > '9', invalid character
        sub bl,0x30            ; Convert to numeric value (ASCII '0' - 30h)
        jl error               ; < 0, invalid character
        imul cx        ; DX:AX = AX * 10 (32-bit result)
        add ax,bx              ; add next digit
        inc si                 ; pointer to next char
        jmp next_char      ; repeat for next character
        ret                ;
    error: 
        mov al,'E'             ; Flag an error
    finis:
        ret                ; return to calling program
    
    ;
    ;Calculates the greatest common divisor from the values in
    ;ax and bx. The GCD will be stored in ax.
    ;
    GCD:
        idiv bx         ; remainder (7) in DX, quotient (1) in ax
        mov ax,bx               ; move bx into ax
        mov bx,dx               ; move dx into bx
        cmp bx, 0x0     ; Is y = 0?
        jg yIsZero              ; Y is zero, return to call from main
        call GCD                ; loop again if y isn't zero
    ;
    ; Displays result in ax and terminates program
    ;
    yIsZero:
        xor dx,dx              ; set dx to 0
        add ax,0x30    ; convert remainder to ascii, store in ax
        mov dx,ax              ;
        int 0x21               ;
        int 0x20               ; terminate program
    
    
    main:
        mov dx,prompt1     ; move prompt1 to dx
        call disp_str              ; display prompt1
    
        ;get number1_str
        xor dx,dx              ; set dx to 0
        mov ah,0x0a    ; accept string from user
        mov dx,number1_str; address for string
        int 0x21               ;    
    
        call str_to_num    ;
        mov [num1_hex],ax ; put value of ax into contents of memory address at
                            ; num1_hex
    
        mov ah,09              ; display string
        mov dx,cr_lf       ; display carriage return and line feed
        int 0x21               ;
    
        mov dx,prompt2     ; move prompt2 to dx
        call disp_str      ; display prompt2
    
        ;get number2
        xor dx,dx              ; set dx to 0
        mov ah,0x0a    ; accept string from user
        mov dx,number2_str; address for string
        int 0x21               ;
    
        call str_to_num    ;
        mov [num2_hex],ax ; put value of ax into contents of memory address at
                            ; num2_hex
    
        mov ah,09              ; display string
        mov dx,cr_lf       ; display carriage return and line feed
        int 0x21               ;
    
        ; Find the greatest common divisor
        xor dx,dx              ; set dx to 0
        mov ax,num1_hex   ; move value in num1_hex to ax
        mov bx,num2_hex   ; move value in num2_hex to bx
        call GCD               ; find greatest common divisor from values in ax and bx
    

    我期待y_is_zero显示结果,但它只是在我运行上面的代码时等待输入。如果我按任意键,程序就会结束。我

    非常感谢任何帮助。 - JS

1 个答案:

答案 0 :(得分:0)

GDC似乎没有尝试显示任何内容;它从不调用disp_str,它所做的系统调用(在退出程序之前)与该子例程中的那个不匹配。