我正在尝试打印出素数列表,但没有打印出任何内容,出了什么问题/我可以在代码中更改什么?

问题描述 投票:0回答:1

我编写了一个汇编程序,我的目标是打印出用户输入的素数。用户只需输入一个数字,例如 15,就会打印前 15 个素数。用户可以输入的范围是 1 到 200 之间。

我的错误捕获功能有效,因此输入低于 1 或高于 200 的任何数字都会重新提示输入另一个数字,但是当我输入一个应该有效的正确范围内的数字时,不会打印任何内容,并且程序几乎停止在它的轨迹,但并没有结束。任何帮助将不胜感激,这是我现在拥有的代码。

INCLUDE Irvine32.inc

; Constant definitions
LOWER_BOUND = 1
UPPER_BOUND = 200

.data
    ; All text prompts and statements
    nameAndProgram      BYTE "Prime Numbers Programmed by Norman O'Brien", 13, 10, 0
    promptPt1           BYTE "Enter the number of prime numbers you would like to see.", 13, 10, 0
    promptPt2           BYTE "I'll accept orders for up to 200 primes.", 13, 10, 0 
    enterNumberOf       BYTE "Enter the number of primes to display [1 ... 200]: ", 0
    outOfRange          BYTE "No primes for you! Number out of range. Try again.", 13, 10, 0
    certified           BYTE "Results certified by Norman O'Brien. Goodbye.", 13, 10, 0
    spacer              BYTE "   ", 0       ; This is for separating the prime numbers when it is printed

    ; Variables
    validNum        DWORD 0
    userInput       SDWORD ?

.code
main PROC

    call    introduction
    call    getUserData
    call    showPrimes
    call    farewell

    Invoke ExitProcess,0    ; exit to operating system
main ENDP


introduction PROC
    ; Print the my name and program name
    MOV     EDX, OFFSET nameAndProgram
    call    WriteString
    call    CrLf

    ; Print first part of prompt info
    MOV     EDX, OFFSET promptPt1
    call    WriteString

    ; Print second part of prompt info
    MOV     EDX, OFFSET promptPt2
    call    WriteString
    call    CrLf

    ret
introduction ENDP


getUserData PROC
top:
    MOV     EDX, OFFSET enterNumberOf
    call    WriteString

    call    ReadInt
    MOV     userInput, EAX

    call validate

    MOV     EAX, validNum
    CMP     EAX, 0
    JE      top

    ret
getUserData ENDP


validate PROC
    MOV     EBX, userInput
    CMP     EBX, LOWER_BOUND
    JL      rangeError
    
    CMP     EBX, UPPER_BOUND
    JG      rangeError
    JL      valid

rangeError:
    MOV     EDX, OFFSET outOfRange
    call    WriteString
    JMP     ending

valid:
    MOV     EAX, 1
    MOV     validNum, EAX

ending:
    ret
validate ENDP


showPrimes PROC
    MOV     EBX, userInput  ; set EBX to number of primes
    MOV     ECX, 0          ; counter, start at 0
    MOV     EAX, 2          ; EAX starts at 2 because it is the first prime

printPrime:
    ; checks if the current number is a prime number
    PUSH    EAX             ; push current number to stack
    CALL    isPrime         
    POP     EAX             ; restores number from stack after it is checked by isPrime
    
    CMP     EAX, 1          ; check if the number is prime
    JNE     notPrime        ; if it's not prime, skip displaying
    
    ; display the prime number
    CALL    WriteDec
    MOV     EDX, OFFSET spacer
    call    WriteString
    INC     ECX             ; increment prime count

    ; after 10 primes have been printed, make new line and reset the count
    CMP     ECX, 10         
    JNE     nextPrime       ; go to next prime if 10 have not been displayed
    CALL    CrLf
    MOV     ECX, 0          ; reset count

    CMP     ECX, EBX        ; see if enough primes have been displayed based on the user input (EBX)
    JL      printPrime      ; display the next prime if not
    ret

nextPrime:
    INC     EAX             ; move on to the next number by incrementing EAX
    JMP     printPrime

; if not prime just move on to the next number
notPrime:
    INC     EAX 
    JMP     printPrime

    ret
showPrimes ENDP


isPrime PROC
    MOV     ECX, 2          ; checking for the primes will start at 2

    ; 1 does not count as prime, so jump to notPrime if that is the case
    CMP     EAX, 1      
    JLE     notPrime

checkDivisor:
    ; divide the number in EAX by the current divisor (ECX) and if there is 
    ; no remainder, then the number is not prime, so jump to notPrime
    MOV     EDX, 0
    DIV     ECX
    CMP     EDX, 0
    JE      notPrime

    ; increment the divisor and see if we have checked all possible divisors
    ; when we compare, if total number of divisors is great than the input (ECX > EAX), it's prime
    INC     ECX             
    CMP     ECX, EAX
    JG      prime
    JMP     checkDivisor

notPrime:
    MOV     EAX, 0
    ret

prime:
    MOV     EAX, 1
    ret
isPrime ENDP


farewell PROC
    MOV     EDX, OFFSET certified
    call    WriteString

    ret
farewell ENDP

END main

assembly x86
1个回答
0
投票
    MOV     EBX, userInput  ; set EBX to number of primes
    ; ....
    MOV     ECX, 0          ; reset count
    CMP     ECX, EBX        ; <- ???
© www.soinside.com 2019 - 2024. All rights reserved.