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

Assembly - Issue getting user input

在此先感谢您的帮助。这个问题一直让我发疯。所以我有一个小的计算器应用程序,它询问用户姓名,询问 2 个数字,询问他们是否想要 Add/Sub/Mul/Div,打印出答案,然后询问他们是否想要再次这样做。好吧,一切都很完美,直到我进入询问他们是否想再做一次的部分。当我们到达这一点时,系统会打印问题,但不会等待响应。所有用户输入的代码都非常相同,所以我对问题出在哪里感到非常困惑。我包含了下面的代码并突出显示了问题所在的功能。您会看到其他一些完全相同,并且没有问题。不管怎样,就在这里。

; "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$

所以在它打印出总和之后,它就完全变得愚蠢了。在同一行打印下一个字符串,不获取用户输入就结束。

谢谢 Michael Petch 让我走上正轨。你最后的评论,建议机会 mov rdx, 1mov rdx, 2 让我走上了正确的道路。不得不再做一些小调整,但它现在可以正常运行了,正如我所期望的那样。由于我读取了 2 个字节,其中一个是换行符(再次感谢迈克尔),然后我只是对 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