I am attempting to print out a list of prime numbers, but nothing is printing out, what is wrong / what could I change in my code?

I have written an assembly program where my goal is to print out prime numbers the amount of times that the user enters. The user only has to enter one number, say, 15, and the first 15 prime numbers will be printed. The range the user can enter in is between 1 and 200.

My error-catching works, so entering anything below 1 or above 200 re-prompts for another number, but when I enter a number in the correct range that is supposed to be valid, nothing is printed out and the program pretty much stops in its tracks, but does not end. Any help would be greatly appreciated, here is the code I have as of right now.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>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
</code>
<code>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 </code>
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

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật