我正在用汇编语言编程,而且我对这种语言非常陌生。我在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