这个程序以一个非负整数作为输入,并确定它是否是素数。问题是4000000007需要作为输入,但是失败了。我知道问题是这个数字太大了,并且位于MyReadInt proc中的某个地方,但是我不知道如何修复它。我只包括了影响错误的代码。当输入40000000007时,控制台返回TryAgain消息。
INCLUDE Irvine32.inc
.DATA
startTime DWORD ?
enter1 BYTE "Enter a non-negative integer (0 to exit): ",0
tryAgain BYTE "That input is not allowed. Try again.",0
prime BYTE " is a prime number.",0
notPrime BYTE " is not a prime number; it is divisible by: ",0
exitMessage BYTE "Goodbye",0
time BYTE "Procedure runtime in milliseconds: ",0
LMAX_DIGITS = 80
Linputarea BYTE LMAX_DIGITS dup(0),0
overflow_msgL BYTE " <32-bit integer overflow>",0
invalid_msgL BYTE " ",0
neg_msg BYTE " ",0
.code
main PROC
beginning: mov edx, OFFSET enter1
call WriteString ; writes null-terminated string to standard output
call myReadInt. ; input stored in eax
cmp eax, 0 ; compares eax to 0
jge noError ; continue if input >= 0
mov edx, OFFSET tryAgain ; if number is negative, write error message
call writeString ; writes null-terminated string to standard output
jmp beginning ; loop beginning
main ENDP
; end of procedure
;______________________________________________________________________________
; MyReadInt PROC
; Modified from Irvine32.asm by _________
; Reads a 32-bit unsigned decimal integer from standard
; input, stopping when the Enter key is pressed.
; All valid digits occurring before a non-numeric character
; are converted to the integer value. Leading spaces are
; ignored, and an optional leading + sign is permitted.
; Receives: nothing
; Returns: If CF=0, the integer is valid, and EAX = binary value.
; If CF=1, the integer is invalid and EAX = 0.
;______________________________________________________________________________
MyReadInt PROC uses ebx ecx edx esi
; Input a string of digits using ReadString.
mov edx,offset Linputarea
mov esi,edx ; save offset in ESI
mov ecx,LMAX_DIGITS
call ReadString
mov ecx,eax ; save length in ECX
cmp ecx,0 ; greater than zero?
jne L1 ; yes: continue
mov eax,0 ; no: set return value
jmp L9 ; and exit
; Skip over any leading spaces.
L1: mov al,[esi] ; get a character from buffer
cmp al,' ' ; space character found?
jne L2 ; no: check for a sign
inc esi ; yes: point to next char
loop L1
jcxz L8 ; quit if all spaces
; Check for a leading sign.
L2: cmp al,'-' ; minus sign found?
jne L3 ; no: look for plus sign
mov edx, offset neg_msg ; tell user negative numbers not allowed
jmp L8
L3: cmp al,'+' ; plus sign found?
jne L4 ; no: must be a digit
inc esi ; yes: skip over the sign
dec ecx ; subtract from counter
; Test the first digit, and exit if it is nonnumeric.
L3A:mov al,[esi] ; get first character
call IsDigit ; is it a digit?
jnz L7A ; no: show error message
; Start to convert the number.
L4: mov eax,0 ; clear accumulator
mov ebx,10 ; EBX is the divisor
; Repeat loop for each digit.
L5: mov dl,[esi] ; get character from buffer
cmp dl,'0' ; character < '0'?
jb L10
cmp dl,'9' ; character > '9'?
ja L10
and edx,0Fh ; no: convert to binary
push edx
mul ebx ; EDX:EAX = EAX * EBX
pop edx
jo L6 ; quit if result too big for 32 bits
add eax,edx ; add new digit to AX
jo L6 ; quit if result too big for 32 bits
inc esi ; point to next digit
jmp L5 ; get next digit
; Carry out of 32 bits has occured, choose "integer overflow" messsage.
L6: mov edx,OFFSET overflow_msgL
jmp L8
; Choose "invalid integer" message.
L7A:mov edx,OFFSET invalid_msgL
; Display the error message pointed to by EDX.
L8: call WriteString
call Crlf
mov eax,0 ; set return value to zero and exit
L9: stc ; set Carry flag to indicate error
ret
L10: clc ; clear Carry flag to indicate success
ret
MyReadInt ENDP
END main
1条答案
按热度按时间wbgh16ku1#
问题是需要将4000000007作为输入
您可能希望将 MyReadInt 重命名为 MyReadUInt,因为Unsigned**Int* 埃格是您想要的。
并且允许使用可选的前导+号
允许一个前导'+'号,有点违背了输入无符号数字的目的。
目标 * L 8 * 期望EDX指向 invalid_msgL 的偏移量。事实并非如此!您应该将其写成:
jecxz L7A
(这是jecxz
,而不是jcxz
)以下代码将允许转换高达4GB-1:
当然,为了实际执行程序的其余部分,你不应该只检查EAX寄存器。而是测试进位标志: