2016-02-12 4 views
0

Заранее благодарим за любую помощь. Эта проблема сводила меня с ума. Итак, у Ive есть небольшое приложение калькулятора, которое запрашивает имя пользователя, запрашивает 2 номера, спрашивает, хотят ли они добавить/Sub/Mul/Div, распечатывает ответ, а затем спрашивает, хотят ли они сделать это снова. Ну, все работает отлично, пока я не доберусь до той части, которая спрашивает, хотят ли они сделать это снова. Когда мы доберемся до этого момента, система печатает вопрос, но не ждет ответа. Код очень хорошо для всех пользователей, поэтому я невероятно смущен в отношении того, что проблема. Ive включил код ниже и выделил функцию, которая является проблемой. Вы увидите, что есть другие, которые очень хорошо совпадают, и у них нет проблем. Во всяком случае, вот оно.Сборка - проблема с вводом пользователя

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

Таким образом, выделенная область, где проблема, по крайней мере, где я думаю. В основном это просто проскакивает над этим, или кажется, что он пропускает его. Предыдущая функция отображает вопрос, но затем не ждет ответа и, потому что мы ничего не можем ввести, он просто заканчивается.

Еще раз спасибо за помощь,

Brad.

О, и я надеюсь, что это будет что-то действительно глупое, что я просто упустил из виду. Я могу иметь дело с глупым Лолом, я просто хочу, чтобы это сработало.

EDIT: Когда я отладки это с помощью 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 

Итак, еще раз, почему один работает, а другой оленья кожа избегает меня на данный момент, и я отлаживается код, который, к сожалению, на самом деле не дал мне никаких INSITE в чем дело.

EDIT3:

Это то, что я получаю, когда я запускаю его.

h**[email protected]**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**[email protected]**p-VirtualBox:~/Programming$ 

Таким образом, после этого печатается сумма, которую она просто совершенно глупо. Распечатывает следующую строку на одной строке и просто заканчивается, не захватывая ввод пользователя.

+2

Кстати, я думаю, что ваш код будет намного красивее, если вы фактически сделаете свои функции действительными функциями, используя call и ret вместо jmp. –

+0

@ Lurker, Lol да, это была опечатка. Сейчас он работает только с одноразрядными числами. на самом деле не беспокоился о том, чтобы сразу подумать об этом.Проблема, с которой я сталкиваюсь, которая, как я полагаю, вы просто повторяете, заключается в том, что она не ждет ответа и просто выходит ... поэтому я думаю, что вы просто повторяете проблему, или вы не читали, что моя проблема. Во всяком случае, все работает отлично, за исключением этой последней функции, и Ive многократно проходил через нее, поэтому нет, у нее нет больше проблем, чем просто не повторять должным образом. –

+0

@ S.Klumpers, это определенно было бы красивее, но это был супер простой, супер быстрый маленький проект. Однако я ценю ввод. –

ответ

1

Спасибо, Майкл Пётч, за то, что вы на правильном пути. Ваш последний комментарий, посоветовавшись с шансом mov rdx, 1 до mov rdx, 2, заставил меня идти правильным путем. Пришлось сделать еще пару небольших хитростей, но теперь он функционирует так, как я ожидал. Поскольку я читаю в 2 байтах, один из которых является линией перевода (опять же спасибо Майкл), я тогда просто cmp против AL, который, похоже, сделал трюк.

Еще раз спасибо.

;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 
Смежные вопросы