代码之家  ›  专栏  ›  技术社区  ›  Brad Bass

程序集-获取用户输入的问题

  •  0
  • Brad Bass  · 技术社区  · 9 年前

    提前感谢您的帮助。这个问题让我发疯了。所以我有了一个小小的计算器应用程序,它要求输入用户名,要求输入2个数字,询问他们是否想加/减/多/分,打印出答案,然后问他们是否想再做一次。好吧,一切都很完美,直到我到了问他们是否想再做一次的部分。当我们到达这一点时,系统会打印问题,但不会等待响应。所有用户输入的代码都是一样的,所以我对问题是什么感到难以置信的困惑。我包括了下面的代码,并强调了问题所在的函数。你会看到,还有其他的完全相同,而且没有问题。无论如何,它在这里。

    ; "Hello World!" in 64 bit Linux NASM
    
    global _start            ; global entry point export for ld
    
    section .text
    _start: 
        ; sys_write(stdout, message, length) 
        nop
        mov     rax, 4          ; sys_write syscall
        mov     rbx, 1          ; std_out
        mov     rcx, inputMsg  ; message address
        mov     rdx, input_L    ; message string length
        int     80h
    
        ; grab user input   
        mov     rax, 3          ; sys_read syscall
        mov     rbx, 0          ; std_in
        mov     rcx, userIn     ; output to username
        mov     rdx, 16         ; accept 16 bytes
        int     80h
    
        ; say hello 
        mov     rax, 4          ; sys_write
        mov     rbx, 1          ; std_out
        mov     rcx, helloMsg
        mov     rdx, helloMsg_L
        int     80h
    
        ; print users name
        mov     rax, 4
        mov     rbx, 1
        mov     rcx, userIn
        mov     rdx, 16
        int     80h
    
    _calc:
        ; ask for first number
        mov     rax, 4
        mov     rbx, 1
        mov     rcx, numMsg1
        mov     rdx, numMsg1_L
        int     80h
    
        ; grab first number
        mov     rax, 3
        mov     rbx, 2
        mov     rcx, num1
        mov     rdx, 8
        int     80h
    
        ; ask user for second number
        mov     rax, 4
        mov     rbx, 1
        mov     rcx, numMsg2
        mov     rdx, numMsg2_L
        int     80h
    
        ; grab second number
        mov     rax, 3
        mov     rbx, 2
        mov     rcx, num2
        mov     rdx, 8
        int     80h
    
        ; ask user what function they want to do 1=add, 2=sub, 3=mul, 4=div
        mov rax, 4
        mov rbx, 1
        mov rcx, function
        mov rdx, function_L
        int 80h
    
        ; get what function user wants to do
        mov     rax, 3
        mov rbx, 2
        mov rcx, func
        mov rdx, 1
        int 80h
    
        ; go to appropriate label
        mov rax, [func]
        sub rax, '0'
        cmp rax, 1
        je  _add
        cmp rax, 2
        je  _sub
        cmp rax, 3
        je  _mul
        cmp rax, 4
        je  _div
    
    _sum:
        ; display sum
        mov     rax, 4          ; sys_write
        mov     rbx, 1          ; std_out
        mov     rcx, sum
        mov     rdx, 16
        int     80h
    
        ; ask user if they want to enter more numbers
        mov rax, 4
        mov rbx, 1
        mov rcx, inMsg2
        mov rdx, inMsg2_L
        int     80h
    
        ;get answer
        mov rax, 3
        mov rbx, 2
        mov rcx, response
        mov rdx, 1
        int     80h
    
        mov rax, [response]
        sub rax, '0'
        cmp rax, 1
        je  _calc
        jmp _end
    
    _add:
        ; add numbers
        mov     rax, [num1]     ; move first number into rax
        sub     rax, '0'        ; sub '0' to convert ascii to decimal
        mov     rbx, [num2]     ; move second number into rbx
        sub     rbx, '0'        ; sub ascii '0' to convert to decimal
        add     rax, rbx        ; add rbx to rax
        add     rax, '0'        ; add ascii '0' to convert to ascii
        mov     [sum], rax      ; move the sum to a temp variable
        jmp _sum
    
    _sub:
        ; subtract numbers
        mov     rax, [num1]     ; move first number into rax
        sub     rax, '0'        ; sub '0' to convert ascii to decimal
        mov     rbx, [num2]     ; move second number into rbx
        sub     rbx, '0'        ; sub ascii '0' to convert to decimal
        sub     rax, rbx        ; add rbx to rax
        add     rax, '0'        ; add ascii '0' to convert to ascii
        mov     [sum], rax      ; move the sum to a temp variable
        jmp _sum
    
    _mul:
        ; multiply numbers
        mov     rax, [num1]     ; move first number into rax
        sub     rax, '0'        ; sub '0' to convert ascii to decimal
        mov     rbx, [num2]     ; move second number into rbx
        sub     rbx, '0'        ; sub ascii '0' to convert to decimal
        imul    rax, rbx        ; multiply rbx to rax
        add     rax, '0'        ; add ascii '0' to convert to ascii
        mov     [sum], rax      ; move the sum to a temp variable
        jmp _sum
    
    _div:
        ; devide numbers
        mov     rax, [num1]     ; move first number into rax
        sub     rax, '0'        ; sub '0' to convert ascii to decimal
        mov     rbx, [num2]     ; move second number into rbx
        sub     rbx, '0'        ; sub ascii '0' to convert to decimal
        idiv    rbx     ; divide rbx to rax
        add     rax, '0'        ; add ascii '0' to convert to ascii
        mov     [sum], rax      ; move the sum to a temp variable
        jmp     _sum
    
    _end:
        ; sys_exit(return_code) 
        mov     rax, 1        ; sys_exit syscall
        mov     rbx, 0        ; return 0 (success)
        int     80h
    
    section .data
        helloMsg:   db  'Hello, '       ; message and newline
        helloMsg_L:     equ     $-helloMsg           ; 
        inputMsg:   db  'Enter your name: '  ; message telling user to input name
        input_L:    equ     $-inputMsg
        numMsg1:    db  'Enter number 1: '  ; message telling user to inpt first number
        numMsg1_L:  equ     $-numMsg1
        numMsg2:    db  'Enter number 2: '  ; message telling user to input second number
        numMsg2_L:  equ     $-numMsg2
        function:   db  'Select function: ADD(1), SUB(2), MUL(3), DIV(4) '
        function_L:     equ     $-function
        inMsg2:     db  'Run again? YES(1), NO(0) '
        inMsg2_L:   equ $-inMsg2
        sumMsg:     db  'The sum is: '
        sumMsg_L:   equ $-sumMsg
    
    section .bss
        userIn:     resb    16
        num1:       resb    8
        num2:       resb    8
        sum:        resb    16
        func:       resb    2
        response:   resb    2
    

    所以粗体部分是问题所在,至少我认为是这样。基本上,它只是跳过了这个,或者看起来好像跳过了它。前一个函数显示问题,但不等待响应,因为我们不能输入任何内容,所以它就结束了。

    再次感谢您的帮助,

    布拉德。

    哦,我希望这是我刚刚忽略的一件非常愚蠢的事情。我可以处理愚蠢的事情,我只想让这件事奏效。

    编辑:当我用GDB调试时,没有问题,所以不幸的是调试没有帮助。。

    EDIT2:我刚刚意识到这一部分实际上并没有加粗,而是在前面和后面加了**。我想简化一下,对于那些不想阅读所有代码的人来说,这是函数或系统调用,似乎没有正常工作。

    ; ask user if they want to enter more numbers
        mov rax, 4
        mov rbx, 1
        mov rcx, inMsg2
        mov rdx, inMsg2_L
        int     80h
    
        ;get answer
        mov rax, 3
        mov rbx, 2
        mov rcx, response
        mov rdx, 1
        int     80h
    
        mov rax, [response]
        sub rax, '0'
        cmp rax, 1
        je  _calc
        jmp _end
    

    然后就是这个,它确实起作用。

    ; ask user what function they want to do 1=add, 2=sub, 3=mul, 4=div
        mov rax, 4
        mov rbx, 1
        mov rcx, function
        mov rdx, function_L
        int 80h
    
        ; get what function user wants to do
        mov     rax, 3
        mov rbx, 2
        mov rcx, func
        mov rdx, 1
        int 80h
    
        ; go to appropriate label
        mov rax, [func]
        sub rax, '0'
        cmp rax, 1
        je  _add
        cmp rax, 2
        je  _sub
        cmp rax, 3
        je  _mul
        cmp rax, 4
        je  _div
    

    同样,为什么一个工作,另一个没有在这一点上逃脱我,我已经调试了代码,不幸的是,这并没有真正让我了解问题所在。

    编辑3:

    这就是我运行它时得到的结果。

    h**p@h**p-VirtualBox:~/Programming$ ./helloInput64
    Enter your name: brad
    Hello, brad
    Enter number 1: 2
    Enter number 2: 3
    Select function: ADD(1), SUB(2), MUL(3), DIV(4) 1
    The sum is: 5Run again? YES(1), NO(0) h**p@h**p-VirtualBox:~/Programming$
    

    所以在它打印出总数之后,它就完全变傻了。在同一行上打印下一个字符串,并在不获取用户输入的情况下结束。。

    1 回复  |  直到 9 年前
        1
  •  1
  •   Brad Bass    9 年前

    谢谢迈克尔·佩奇让我走上了正确的轨道。你的最后一条评论,建议碰碰运气 mov rdx, 1 mov rdx, 2 让我走对了路。不得不再做一些小的调整,但它现在的功能正如我所期望的那样。因为我读了两个字节,其中一个是换行(再次感谢Michael),所以我只对AL进行了cmp,这似乎起到了作用。

    再次感谢。

    ;get answer
    mov eax, 3
    mov ebx, 0
    mov ecx, response
    mov edx, 2
    int     80h
    
    mov eax, [response]
    sub al, '0'
    cmp al, 1
    je  _calc
    jmp _end