检查输入的数字是否在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, 1
mov rdi, 1
mov rsi, 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, 1
mov rdi, 1
mov rsi, output1
mov rdx, op1Len
syscall
ret
isOdd:
cmp dword [input], 5
jle lessThan
call moreThan
ret
lessThan:
mov rax, 1
mov rdi, 1
mov rsi, output2
mov rdx, op2Len
syscall
ret
moreThan:
mov rax, 1
mov rdi, 1
mov rsi, output3
mov rdx, op3Len
syscall
ret
goAgain:
mov rax, 1
mov rdi, 1
mov rsi, confirm
mov rdx, cLen
syscall

mov rax, 0
mov rdi, 0
mov rsi, 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, 1
mov rdi, 1
mov rsi, 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, 1
mov rdi, 1
mov rsi, output1
mov rdx, op1Len
syscall
call goAgain
isOdd:
cmp byte [input], '5'
jbe lessThan
call moreThan
call goAgain
lessThan:
mov rax, 1
mov rdi, 1
mov rsi, output2
mov rdx, op2Len
syscall
call goAgain
moreThan:
mov rax, 1
mov rdi, 1
mov rsi, output3
mov rdx, op3Len
syscall
ret
goAgain:
mov rax, 1
mov rdi, 1
mov rsi, confirm
mov rdx, cLen
syscall

mov rax, 0
mov rdi, 0
mov rsi, 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

相关内容

  • 没有找到相关文章

最新更新