检查输入的数字是否介于 0 和 9 之间

问题描述

我在用汇编编程,我对这门语言很陌生。我在 Ubuntu 中使用 yasm 进行编程。我应该从用户那里获取输入并判断他们的输入是偶数还是奇数。如果输入是奇数,我需要查看它是大于 5 还是小于 5。然后,在一切之后,我需要确保用户想要再次访问。我很确定我已经解决了,我只是在验证用户输入时遇到了麻烦。我试图确保他们输入一个从 0 到 9 的数字。

以下是我为我的程序编写的所有内容,我找不到哪里出错了。当我尝试运行它时,出现此错误:浮点异常(核心转储)

; Data section,declaring variables
section .data
    output  dd  'Enter a single digit between 0 and 9'  ;1st output
    nl  db  0x0a                    
    opLen   equ $-output                                ;length of 1st output
    
    Go  equ 0x59                                        ;to check confirmation
    go  equ 0x79                                        ;to check confirmation
    
    rem dd  0xffff                                      ;empty remainder for modulo
    output1 dd  'You entered an even number'            ;output for even
    op1Len  equ $-output1                               ;even output length
    output2 dd  'You entered an odd number <= 5'        ;output for odd less or equal to 5
    op2Len  equ $-output2                               ;output length for first odd
    output3 dd  'you entered an odd number > 5'         ;output for odd more than 5
    op3Len  equ $-output3                               ;output length for second odd
    output4 dd  '...what?...'                           ;output for if the thing entered is not a number
    op4Len  equ $-output4                               ;else output length
    
    confirm dd  'go again? (y/n): '         ;confirmation message
    cLen    equ $-confirm                   ;confirmation message length
    
    divs    dd  2

section .bss
    input   dd  0xffff                      ;for user input
    again   dd  0xffff                      ;for second user input

section .text
global _start
_start: 
    call printOutput    ;prints first output
    call getInput       ;receives user input
    call checkNumZero   ;checks if number is greater than zero
    call checkEvenOdd   ;does the modulo operation on the number
    cmp dword [rem],0  ;compares the remainder and 0
    je handleTrueEven   ;if remainder is zero,then the first message is outputted
    call isOdd          ;if the remainder isn't zero,it checks if it is greater or less than 5
    call goAgain        ;asks the user if they want to go again
    

printOutput:
    mov rax,1
    mov rdi,1
    mov rsi,output
    mov rdx,opLen
    syscall
    ret

getInput:
    mov rax,0
    mov rdi,0
    mov rsi,input
    mov rdx,0xffff
    syscall
    ret

checkNumZero:
    cmp dword [input],'0'
    jbe checkNumNine
    call else

checkNumNine:
    cmp dword [input],'9'
    ja else
    ret

else:
    mov rax,output4
    mov rdx,op4Len
    syscall
    ret

checkEvenOdd:
    mov rax,0
    mov eax,dword [input]
    div dword [divs]
    mov dword [rem],edx
    ret

handleTrueEven:
    mov rax,output1
    mov rdx,op1Len
    syscall
    ret

isOdd:
    cmp dword [input],5
    jle lessthan
    call moreThan
    ret

lessthan:
    mov rax,output2
    mov rdx,op2Len
    syscall
    ret

moreThan:
    mov rax,output3
    mov rdx,op3Len
    syscall
    ret

goAgain:
    mov rax,confirm
    mov rdx,cLen
    syscall
    
    mov rax,again
    mov rdx,0xffff
    syscall
    
    cmp dword [again],0x79
    jne doneIf
    cmp dword [again],0x59
    jne doneIf
    ret

doneIf:
    mov rax,60
    mov rdi,0
    syscall

解决方法

为了解决这个问题,我们做了几处更改,如下所示。

section .data
    output  dd  'Enter a single digit between 0 and 9'  ;1st output
    nl  db  0x0a                    
    opLen   equ $-output                ;length of 1st output
    
    rem dd  0xffff                  ;empty remainder for modulo
    output1 dd  'You entered an even number'        ;output for even
    nl1     db  0x0a
    op1Len  equ $-output1               ;even output length
    output2 dd  'You entered an odd number <= 5'    ;output for odd less or equal to 5
    nl2 db  0x0a
    op2Len  equ $-output2               ;output length for first odd
    output3 dd  'you entered an odd number > 5'     ;output for odd more than 5
    nl3     db  0x0a
    op3Len  equ $-output3               ;output length for second odd
    output4 dd  '...what?...'               ;output for if the thing entered is not a number
    nl4     db  0x0a
    op4Len  equ $-output4               ;else output length
    
    confirm dd  'go again? (y/n):'          ;confirmation message
    nl5     db  0x0a
    cLen    equ $-confirm               ;confirmation message length
    
    divs    db  2

section .bss
    input   resb    0xff                    ;for user input
    again   resb    0xff                    ;for second user input

section .text
global _start
_start: 
    call printOutput    ;prints first output
    call getInput       ;receives user input
    call checkNumZero   ;checks if number is greater than zero
    call checkEvenOdd   ;does the modulo operation on the number
    cmp byte [rem],0       ;compares the remainder and 0
    je handleTrueEven   ;if remainder is zero,then the first message is outputted
    call isOdd      ;if the remainder isn't zero,it checks if it is greater or less than 5
    ;call goAgain       asks the user if they want to go again
    

printOutput:
    mov rax,1
    mov rdi,1
    mov rsi,output
    mov rdx,opLen
    syscall
    ret

getInput:
    mov rax,0
    mov rdi,0
    mov rsi,input
    mov rdx,0xff
    syscall
    ret

checkNumZero:
    cmp byte [input],0x30
        jae checkNumNine
        call else

checkNumNine:
        cmp byte [input],0x39
        ja else
    ret

else:
    mov rax,output4
    mov rdx,op4Len
    syscall
    call goAgain

checkEvenOdd:
    mov al,byte [input]
    mov ah,0
    div byte [divs]
    mov byte [rem],ah
    ret

handleTrueEven:
    mov rax,output1
    mov rdx,op1Len
    syscall
    call goAgain

isOdd:
    cmp byte [input],'5'
    jbe lessThan
    call moreThan
    call goAgain

lessThan:
    mov rax,output2
    mov rdx,op2Len
    syscall
    call goAgain

moreThan:
    mov rax,output3
    mov rdx,op3Len
    syscall
    ret

goAgain:
    mov rax,confirm
    mov rdx,cLen
    syscall
    
    mov rax,again
    mov rdx,0xff
    syscall
    
    cmp byte [again],0x79
    je _start
    cmp byte [again],0x59
    je _start
    jmp doneIf

doneIf:
    mov rax,60
    mov rdi,0
    syscall

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...