+1 (315) 557-6473 

Roll Pair Of Dice And Calculate The Percentage For Each Value After N Trials Using MARS Mips Assembly Assignment Solution.


Instructions

Objective
Write an assembly language homework to find primes using sieve, greatest common divisor.

Requirements and Specifications

c simply coding
c simply coding 1
c simply coding 2

Screenshots of output

find-primes-and-gcd-using-sieve-in-assembly-language find-primes-and-gcd-using-sieve-in-assembly-language 1 find-primes-and-gcd-using-sieve-in-assembly-language 2 find-primes-and-gcd-using-sieve-in-assembly-language 3

Source Code

Problem 1

INCLUDE Irvine32.inc

.data

menuStr DB "Main menu", 13, 10

            DB "----------------------------------------------", 13, 10

            DB "1. Display all primes between 2 and 5000", 13, 10

            DB "2. Display all primes between 2 and n", 13, 10

            DB "3. Euclid's Algorithm", 13, 10

            DB "4. Exit", 13, 10

            DB "Option?: ", 0

errorOptStr DB "Invalid option.", 13, 10, 13, 10, 0

promptStr DB "Value for n?: ", 0

errorNStr DB "Invalid n value.", 13, 10, 13, 10, 0

promptN1Str DB "Value for first number?: ", 0

promptN2Str DB "Value for second number?: ", 0

header1Str DB 13, 10, "There are ", 0

header2Str DB " primes between 2 and n (n = ", 0

header3Str DB ")", 13, 10

            DB "----------------------------------------------", 13, 10, 0

gcdHeadStr DB 13, 10, "Number #1 Number #2 GCD GCD Prime?", 13, 10

            DB "-------------------------------------------", 13, 10, 0

gcdYes DB "Yes", 0

gcdNo DB "No", 0

is_prime DB 10001 DUP(0)

.code

;-------------------------------------------------------

main PROC

;

; Main procedure

;-------------------------------------------------------

            ; initialize is_prime array

            push OFFSET is_prime ; pass is_prime address

            call FindPrimes ; find all primes <= 10000

            add esp, 4 ; pop argument from stack

menuloop:

            ; display and get option

            push OFFSET errorOptStr ; pass error string

            push OFFSET menuStr ; pass menu string

            call MainMenu ; print menu and get option

            add esp, 8 ; pop arguments from stack

            cmp eax, 1 ; if first option

            je print5000 ; print first 5000 primes

            cmp eax, 2 ; if second option

            je printN ; print first n primes

            cmp eax, 3 ; if third option

            je euclid ; do Euclid's algorithm

            jmp done ; if fourth option, exit

print5000:

            ; display primes <= 5000

            push OFFSET header3Str ; pass header string

            push OFFSET header2Str ; pass header string

            push OFFSET header1Str ; pass header string

            mov eax, 5000 ; print primes up to n=5000

            push eax ; pass n

            push OFFSET is_prime ; pass is_prime address

            call DisplayResults ; display result

            add esp, 20 ; pop arguments from stack

            jmp pauseDisp ; wait for a key press

printN:

            push OFFSET errorNStr ; pass address of error string

            push OFFSET promptStr ; pass address of prompt string

            call InputN ; read N

            add esp, 8 ; restore stack

            push OFFSET header3Str ; pass header string

            push OFFSET header2Str ; pass header string

            push OFFSET header1Str ; pass header string

            push eax ; pass n

            push OFFSET is_prime ; pass is_prime address

            call DisplayResults ; display result

            add esp, 20 ; pop arguments from stack

            jmp pauseDisp ; wait for a key press

euclid:

            ; read first number

            push OFFSET errorNStr ; pass address of error string

            push OFFSET promptN1Str ; pass address of prompt string

            call InputN ; read N1

            add esp, 8 ; restore stack

            mov ebx, eax

            ; read second number

            push OFFSET errorNStr ; pass address of error string

            push OFFSET promptN2Str ; pass address of prompt string

            call InputN ; read N2

            add esp, 8 ; restore stack

            push OFFSET gcdNo ; pass no string

            push OFFSET gcdYes ; pass yes string

            push OFFSET gcdHeadStr ; pass header string

            push eax ; pass n2

            push ebx ; pass n1

            push OFFSET is_prime ; pass is_prime address

            call DisplayGCDResults ; display result

            add esp, 24 ; pop arguments from stack

pauseDisp:

            call WaitMsg ; wait for a key press

            call CrLF

            call CrLF ; leave empty line

            jmp menuloop

done:

            call WaitMsg ; wait for a key press

            exit ; terminate the program

main ENDP

;-------------------------------------------------------

InputN PROC

;

; Accepts an unsigned number from the user and verifies

; that the number is a valid input.

; Receives: address of prompt string and address of error string

; Returns: EAX has the validated number

;-------------------------------------------------------

            push ebp ; save base pointer

            mov ebp, esp ; base of stack frame

readInLoop:

            mov edx, [ebp + 8] ; load address of prompt string

            call WriteString ; display the string

            call ReadDec ; read an unsigned number from the user

            cmp eax, 2 ; if n < 2

            jl invalidInput ; it's invalid

            cmp eax, 5000 ; if n <= 5000

            jle validInput ; it's valid

invalidInput:

            mov edx, [ebp + 12] ; load address of error string

            call WriteString ; display the string

            jmp readInLoop ; read again

validInput:

            pop ebp ; restore base pointer

            ret

InputN ENDP

;-------------------------------------------------------

InitSieve PROC

;

;

; Initializes Sieve array filling it with ones

; Receives: Address of sieve array in first stack argument

; Returns: nothing

;-------------------------------------------------------

            push ebp ; save base pointer

            mov ebp, esp ; base of stack frame

            push esi ; save used registers

            push ecx

            mov esi, [ebp + 8] ; load address of array

            mov ecx, 10001 ; initialize all 10000 entries

iniSieveLoop:

            mov BYTE PTR[esi], 1 ; save 1 in array

            inc esi ; advance to next number

            loop iniSieveLoop ; decrement ecx, repeat loop until ecx is zero

            pop ecx ; restore used registers

            pop esi

            pop ebp ; restore base pointer

            ret

InitSieve ENDP

;-------------------------------------------------------

FindPrimes PROC

;

; Calculates the prime numbers between 2 and 10000 using

; the Sieve of Eratosthenes

; Receives: Address of is_prime array

; Returns: nothing

;-------------------------------------------------------

            push ebp ; save base pointer

            mov ebp, esp ; base of stack frame

            push esi ; save used registers

            push ebx

            push ecx

            mov esi, [ebp + 8] ; load address of array

            push esi ; pass is_prime array

            call InitSieve ; initialize is_prime array

            add esp, 4 ; restore stack pointer

            mov ebx, 2 ; start i in 2

SieveLoop:

            cmp BYTE PTR[esi], 1 ; if is_prime[i] is true

            jne SieveNext ; if not, go to next

            mov ecx, ebx ; load current i as m

            add ecx, ebx ; multiply m by 2 = 2*i

SieveMarkLoop:

            cmp ecx, 10000 ; if m > 10000

            jg SieveNext ; go to next number

            mov BYTE PTR[esi + ecx], 0 ; else, set is_prime[m] to false

            add ecx, ebx ; advance by i

            jmp SieveMarkLoop ; repeat loop

SieveNext:

            inc ebx ; increment i

            cmp ebx, 10000 ; if i <= 10000

            jle SieveLoop ; repeat loop

            pop ecx ; restore used registers

            pop ebx

            pop esi

            pop ebp ; restore base pointer

            ret

FindPrimes ENDP

;-------------------------------------------------------

CountPrimes PROC

;

; Count the number of primes between 2 and n

; Receives: Address of is_prime array and n

; Returns: number of primes between 2 and n

;-------------------------------------------------------

            push ebp ; save base pointer

            mov ebp, esp ; base of stack frame

            push esi ; save registers

            push ebx

            mov esi, [ebp + 8] ; point to array

            mov ebx, 2 ; start i in 2

            mov eax, 0 ; count = 0

countLoop:

            cmp BYTE PTR[esi + ebx], 1 ; if not prime

            jne countNext ; go to next

            inc eax ; else, increment count

countNext:

            inc ebx ; advance i to next

            cmp ebx, [ebp + 12] ; compare i with n

            jle countLoop ; if i <= n , repeat

            pop ebx ; restore registers

            pop esi

            pop ebp ; restore base pointer

            ret

CountPrimes ENDP

;-------------------------------------------------------

CountDigits PROC

;

; Counts the number of digits in the unsigned number

; Receives: number

; Returns: number of digits

;-------------------------------------------------------

            push ebp ; save base pointer

            mov ebp, esp ; base of stack frame

            push ebx ; save registers

            push ecx

            mov ecx, 0 ; start count in zero

            mov ebx, 10 ; for divisions

            mov eax, [ebp + 8] ; load number

digLoop: mov edx, 0

            div ebx ; divide by 10

            inc ecx ; increment digits

            cmp eax, 0 ; if number is not zero

            jne digLoop ; repeat loop

            mov eax, ecx ; return count

            pop ecx ; restore registers

            pop ebx

            pop ebp ; restore base pointer

            ret

CountDigits ENDP

;-------------------------------------------------------

DisplayArray PROC

;

; Displays primes between 2 and n

; Receives: Address of is_prime array and n

; Returns: nothing

;-------------------------------------------------------

            push ebp ; save base pointer

            mov ebp, esp ; base of stack frame

            push esi ; save registers

            push edi

            push ebx

            push ecx

            mov esi, [ebp + 8] ; point to array

            mov ebx, 2 ; start i in 2

            mov edi, 5 ; count 5 per line

dispLoop:

            cmp BYTE PTR[esi + ebx], 1 ; if not prime

            jne dispNext ; go to next

            mov eax, ebx ; copy current prime

            mov eax, 6 ; fill 6 spaces

            push eax

            push ebx ; pass number

            call DisplayDecN ; print number

            add esp, 8 ; restore stack

            dec edi

            jne dispNext ; if not 5, go to next

            mov edi, 5 ; else, reload count

            call CrLF ; jump to next line

dispNext:

            inc ebx ; advance i to next

            cmp ebx, [ebp + 12] ; compare i with n

            jle dispLoop ; if i <= n , repeat

            cmp edi, 5 ; if we printed a whole line

            je dispEnd ; skip

            call CrLF ; else, print new line

dispEnd:

            pop ecx ; restore registers

            pop ebx

            pop edi

            pop esi

            pop ebp ; restore base pointer

            ret

DisplayArray ENDP

;-------------------------------------------------------

DisplayResults PROC

;

; Displays the primes from 2 to n using the given is_prime array

; Receives: Address of is_prime array, n, header1, header2 and header3 strings

; Returns: nothing

;-------------------------------------------------------

            push ebp ; save base pointer

            mov ebp, esp ; base of stack frame

            push esi ; save registers

            push ebx

            mov esi, [ebp + 8] ; point to array

            mov ebx, [ebp + 12] ; load n

            push ebx ; pass n

            push esi ; pass array pointer

            call CountPrimes ; count the number of primes

            add esp, 8 ; restore stack

            mov ebx, eax ; save number of primes

            mov edx, [ebp + 16] ; load header string

            call WriteString

            mov eax, ebx ; print n

            call WriteDec

            mov edx, [ebp + 20] ; load header2 string

            call WriteString

            mov eax, [ebp + 12] ; print n

            call WriteDec

            mov edx, [ebp + 24] ; load header3 string

            call WriteString

            mov esi, [ebp + 8] ; point to array

            mov ebx, [ebp + 12] ; load n

            push ebx ; pass n

            push esi ; pass array pointer

            call DisplayArray ; display the array

            add esp, 8 ; restore stack

            pop ebx ; restore registers

            pop esi

            pop ebp ; restore base pointer

            ret

DisplayResults ENDP

;-------------------------------------------------------

GCD PROC

;

; Calculates the GCD of 2 numbers using euclid's algorithm

; it validates the user input.

; Taken from:

; https://en.wikipedia.org/wiki/Euclidean_algorithm

; Receives: 2 numbers

; Returns: GCD result

;-------------------------------------------------------

            push ebp ; save base pointer

            mov ebp, esp ; base of stack frame

            push ebx ; save registers

            mov eax, [ebp + 8] ; load a

            mov ebx, [ebp + 12] ; load b

            cmp DWORD PTR[ebp + 12], 0 ; if b = 0

            je gcdReturn ; return a

gcdElse:

            mov edx, 0 ; clear edx for division

            div ebx ; a/b

            push edx ; pass a mod b

            push ebx ; pass b

            call GCD ; recurse gcd(b, a mod b)

            add esp, 8 ; restore stack

gcdReturn:

            pop ebx ; restore registers

            pop ebp ; restore base pointer

            ret

GCD ENDP

;-------------------------------------------------------

DisplayDecN PROC

;

; Displays number filling to n spaces

; Receives: number, n spaces

; Returns: nothing

;-------------------------------------------------------

            push ebp ; save base pointer

            mov ebp, esp ; base of stack frame

            mov eax, [ebp + 8] ; load number

            call WriteDec ; print it

            mov eax, [ebp + 8] ; load n

            push eax ; get digits in number

            call CountDigits

            add esp, 4 ; restore stack

            mov ecx,[ebp + 12] ; load separation

            sub ecx, eax ; calculate remainder

            mov eax, 32

dispSpcLoop:

            call WriteChar ; fill remaining space with chars

            loop dispSpcLoop

            pop ebp ; restore base pointer

            ret

DisplayDecN ENDP

;-------------------------------------------------------

DisplayGCDResults PROC

;

; Displays the gcd of 2 numbers

; Receives: Address of is_prime array, n1, n2, header string, yes str, no str

; Returns: nothing

;-------------------------------------------------------

            push ebp ; save base pointer

            mov ebp, esp ; base of stack frame

            push esi ; save registers

            push ebx

            mov edx, [ebp + 20] ; load header string

            call WriteString ; display header

            mov eax, 12 ; fill 12 spaces

            push eax

            mov eax, [ebp + 12] ; pass n1

            push eax

            call DisplayDecN ; print number

            add esp, 8 ; restore stack

            mov eax, 13 ; fill 13 spaces

            push eax

            mov eax, [ebp + 16] ; pass n2

            push eax

            call DisplayDecN ; print number

            add esp, 8 ; restore stack

            mov eax, [ebp + 12] ; load n1

            mov ebx, [ebp + 16] ; load n2

            push ebx ; pass n2

            push eax ; pass n1

            call GCD ; calculate gcd

            add esp, 8 ; restore stack

            mov ebx, eax

            mov eax, 9 ; fill 9 spaces

            push eax

            push ebx ; pass gcd

            call DisplayDecN ; print number

            add esp, 8 ; restore stack

            mov esi, [ebp + 8] ; point to array

            cmp BYTE PTR[esi + ebx], 1 ; if prime

            je gcdPrime

            mov edx, [ebp + 28] ; load no

            jmp displayGCDPrime

gcdPrime:

            mov edx, [ebp + 24] ; load yes

displayGCDPrime:

            call WriteString

            call CrLF

            pop ebx ; restore registers

            pop esi

            pop ebp ; restore base pointer

            ret

DisplayGCDResults ENDP

;-------------------------------------------------------

MainMenu PROC

;

; Displays the menu and returns the selected option

; it validates the user input

; Receives: menu string address and error string address

; Returns: validated menu option

;-------------------------------------------------------

            push ebp ; save base pointer

            mov ebp, esp ; base of stack frame

mLoop:

            mov edx, [ebp + 8] ; load address of menu string

            call WriteString ; display the string

            call ReadDec ; read the input

            cmp eax, 1 ; if < 1

            jl invalidOpt ; is invalid

            cmp eax, 4 ; if <= 4

            jle validOpt ; is valid

invalidOpt:

            mov edx, [ebp + 12] ; load address of error string

            call WriteString ; display the string

            jmp mLoop ; read again

validOpt:

            pop ebp ; restore base pointer

            ret

MainMenu ENDP

END main

Problem 2

INCLUDE Irvine32.inc

MainMenu PROTO

Generate7x7Matrix PROTO,

                    ptrMatrix: PTR DWORD

Display7x7Matrix PROTO,

                    ptrMatrix: PTR DWORD

isVowel PROTO,

                    char: BYTE

DisplayWord PROTO,

                    ptrWord: PTR BYTE,

                    incVal: DWORD

FindWords PROTO,

                    ptrMatrix: PTR DWORD

FindRowWords PROTO,

                    ptrMatrix: PTR DWORD

FindColWords PROTO,

                    ptrMatrix: PTR DWORD

FindDiagWords PROTO,

                    ptrMatrix: PTR DWORD

.data

matGenStr DB "Matrix has been generated...", 13, 10, 0

matrix7x7 DWORD 49 DUP(0)

.code

;-------------------------------------------------------

main PROC

;

; Main procedure

;-------------------------------------------------------

            call Randomize ; initialize the random generator

            ; initialize matrix

            INVOKE Generate7x7Matrix, ADDR matrix7x7

menuloop:

            ; print menu and get option

            INVOKE MainMenu

            cmp eax, 1 ; if first option

            je genMat ; generate matrix

            cmp eax, 2 ; if second option

            je printMat ; print random matrix

            cmp eax, 3 ; if third option

            je findSets ; find sets of 7 letters

            jmp done ; if fourth option, exit

genMat:

            INVOKE Generate7x7Matrix, ADDR matrix7x7 ; generate new matrix

            mov edx, OFFSET matGenStr ; load address of message

            call WriteString ; display string

            jmp pauseDisp ; wait for a key press

printMat:

            INVOKE Display7x7Matrix, ADDR matrix7x7 ; print the matrix

            jmp pauseDisp ; wait for a key press

findSets:

            INVOKE FindWords, ADDR matrix7x7 ; find 7 letter words and print them

pauseDisp:

            call WaitMsg ; wait for a key press

            call CrLF

            call CrLF ; leave empty line

            jmp menuloop

done:

            call WaitMsg ; wait for a key press

            exit ; terminate the program

main ENDP

.data

menuStr DB "Main menu", 13, 10

            DB "----------------------------------------------", 13, 10

            DB "1. Generate a 7x7 matrix with random letters", 13, 10

            DB "2. Print random matrix", 13, 10

            DB "3. Find sets of 7 letter words", 13, 10

            DB "4. Exit", 13, 10

            DB "Option?: ", 0

errorStr DB "Invalid option.", 13, 10, 13, 10, 0

.code

;-------------------------------------------------------

MainMenu PROC

;

; Displays the menu and returns the selected option

; it validates the user input

; Receives: menu string address and error string address

; Returns: validated menu option

;-------------------------------------------------------

mLoop:

            mov edx, OFFSET menuStr ; load address of menu string

            call WriteString ; display the string

            call ReadDec ; read the input

            cmp eax, 1 ; if < 1

            jl invalidOpt ; is invalid

            cmp eax, 4 ; if <= 4

            jle validOpt ; is valid

invalidOpt:

            mov edx, OFFSET errorStr ; load address of error string

            call WriteString ; display the string

            jmp mLoop ; read again

validOpt:

            ret

MainMenu ENDP

.data

vowels DB "AEIOU"

consonants DB "BCDFGHJKLMNPQRSTVWXYZ"

.code

;-------------------------------------------------------

Generate7x7Matrix PROC,

                    ptrMatrix: PTR DWORD

; Generates a 7 x 7 random matrix of letters

; Receives: address of matrix to save letters

; Returns: nothing

;-------------------------------------------------------

            push edi ; save registers

            push ecx

            mov edi, ptrMatrix ; load address of matrix

            mov ecx, 49 ; generate 7x7 elements

genLoop:

            call Random32 ; generate a random number

            and eax, 1 ; if odd,

            je genVowel ; generate vowel

genConsonant:

            mov eax, 21 ; generate one consonant

            call RandomRange ; generate it

            mov al, consonants[eax] ; load consonant

            mov [edi], al ; save in matrix

            jmp genNext

genVowel:

            mov eax, 5 ; generate one vowel

            call RandomRange ; generate it

            mov al, vowels[eax] ; load vowel

            mov [edi], al ; save in matrix

genNext:

            inc edi ; advance to next position in matrix

            loop genLoop

            pop ecx ; restore registers

            pop edi

            ret

Generate7x7Matrix ENDP

.data

titleStr DB "The matrix is:", 13, 10, 13, 10, 0

.code

;-------------------------------------------------------

Display7x7Matrix PROC,

                    ptrMatrix: PTR DWORD

;

; Displays a matrix of 7x7

; Receives: Address of matrix to print

; Returns: nothing

;-------------------------------------------------------

            push esi ; save registers

            push ebx

            push ecx

            mov edx, OFFSET titleStr ; load address of title string

            call WriteString ; print title

            mov esi, ptrMatrix ; point to matrix

            mov ebx, 7 ; print 7 from a row

dispRow:

            mov ecx, 7 ; print 7 from a column

dispCol:

            mov al, [esi] ; load letter

            call WriteChar ; display letter

            mov al, 32 ; load ascii space

            call WriteChar ; display space

            inc esi ; advance to next position

            loop dispCol ; decrement cols, repeat if not zero

            call CrLF ; jump to next line

            dec ebx ; decrement rows

            jne dispRow ; repeat if not zero

            call CrLF ; print new line

            pop ecx ; restore registers

            pop ebx

            pop esi

            ret

Display7x7Matrix ENDP

;-------------------------------------------------------

DisplayWord PROC,

            ptrWord: PTR BYTE,

            incVal: DWORD

;

; Display 7 letter word at a given address incrementing each time by incVal

; Receives: address of start of word, increment

; Returns: nothing

;-------------------------------------------------------

            push esi ; save registers

            push ebx

            push ecx

            mov esi, ptrWord ; load address of word

            mov ecx, 7 ; print 7 letters

            mov ebx, incVal ; load increment

dispWordLoop:

            mov al, [esi] ; load letter

            call WriteChar ; display letter

            add esi, ebx ; advance to next char

            loop dispWordLoop ; decrement letter count, repeat if not zero

            pop ecx ; restore registers

            pop ebx

            pop esi

            ret

DisplayWord ENDP

;-------------------------------------------------------

isVowel PROC,

                char: BYTE

;

; Returns 1 if the character is a vowel, 0 if not

; Receives: character

; Returns: 1 if the character is a vowel, 0 if not

;-------------------------------------------------------

            mov al, char ; load character

            cmp al, 'A' ; if vowel

            je vowelOk ; return 1

            cmp al, 'E' ; if vowel

            je vowelOk ; return 1

            cmp al, 'I' ; if vowel

            je vowelOk ; return 1

            cmp al, 'O' ; if vowel

            je vowelOk ; return 1

            cmp al, 'U' ; if not vowel

            jne vowelNot ; go to not

vowelOk:

            mov eax, 1 ; return 1

            jmp isVowelEnd

vowelNot:

            mov eax, 0 ; return 0

isVowelEnd:

            ret

isVowel ENDP

.data

foundStr DB "The words from this matrix is/are:", 13, 10, 0

notFoundStr DB "No words were found", 13, 10, 0

.code

;-------------------------------------------------------

FindWords PROC,

            ptrMatrix: PTR DWORD

            LOCAL nFound:DWORD

;

; Find the 7 letter words with 2 vowels and prints them

; Receives: Address of random matrix of 7x7

; Returns: Nothing

;-------------------------------------------------------

            push esi ; save registers

            push ebx

            push edx

            mov edx, OFFSET foundStr ; load address of found string

            call WriteString ; print title

            mov esi, ptrMatrix ; point to start of matrix

            INVOKE FindRowWords, esi ; find in rows

            mov ebx, eax ; save number of found words

            INVOKE FindColWords, esi ; find in columns

            add ebx, eax ; add to number of found words

            INVOKE FindDiagWords, esi ; find in diagonals

            add ebx, eax ; add to number of found words

            cmp ebx, 0 ; if number of found words != 0

            jne findEnd ; end

            mov edx, OFFSET notFoundStr ; load address of not found string

            call WriteString ; print the string

findEnd:

            pop edx ; restore registers

            pop ebx

            pop esi

            ret

FindWords ENDP

.code

;-------------------------------------------------------

FindRowWords PROC,

            ptrMatrix: PTR DWORD

;

; Find the 7 letter words with 2 vowels in the rows and prints them

; Receives: Address of random matrix of 7x7

; Returns: Number of found words

;-------------------------------------------------------

            push edi ; save registers

            push esi

            push ebx

            push ecx

            push edx

            mov edi, 0 ; number of found words = 0

            mov esi, ptrMatrix ; point to start of matrix

            mov edx, 7 ; repeat for 7 rows

findRLoop:

            mov ecx, 0 ; vowels = 0

            mov ebx, 0 ; try 7 letters

findRVowels:

            INVOKE isVowel, BYTE PTR[esi + ebx] ; check if it's a vowel

            add ecx, eax ; increment number of vowels

            inc ebx ; increment position in matrix

            cmp ebx, 7 ; if below 7

            jl findRVowels ; repeat

            cmp ecx, 2 ; if 2 vowels were found

            jne nextRow ; if not, go to next row

            INVOKE DisplayWord, esi, 1 ; display the 7 letter word

            call CrLF ; print newline

            inc edi ; increment number of found words

nextRow:

            add esi, 7 ; advance to next row

            dec edx ; decrement rows

            jne findRLoop ; repeat if not zero

            mov eax, edi ; return found words

            pop edx ; restore registers

            pop ecx

            pop ebx

            pop esi

            pop edi

            ret

FindRowWords ENDP

;-------------------------------------------------------

FindColWords PROC,

                ptrMatrix: PTR DWORD

;

; Find the 7 letter words with 2 vowels in the columns and prints them

; Receives: Address of random matrix of 7x7

; Returns: Number of found words

;-------------------------------------------------------

            push edi ; save registers

            push esi

            push ebx

            push ecx

            push edx

            mov edi, 0 ; number of found words = 0

            mov esi, ptrMatrix ; point to start of matrix

            mov edx, 7 ; repeat for 7 columns

findCLoop:

            mov ecx, 0 ; vowels = 0

            mov ebx, 0 ; try 7 letters

            push edx

            mov edx, 7

findCVowels:

            INVOKE isVowel, BYTE PTR[esi + ebx] ; check if it's a vowel

            add ecx, eax ; increment number of vowels

            add ebx, 7 ; increment position in matrix

            dec edx ; decrement count to check

            jne findCVowels ; repeat if not zero

            pop edx

            cmp ecx, 2 ; if 2 vowels were found

            jne nextCol ; if not, go to next column

            INVOKE DisplayWord, esi, 7 ; display the 7 letter word

            call CrLF ; print newline

            inc edi ; increment number of found words

nextCol:

            inc esi ; advance to next column

            dec edx ; decrement columns

            jne findCLoop ; repeat if not zero

            mov eax, edi ; return found words

            pop edx ; restore registers

            pop ecx

            pop ebx

            pop esi

            pop edi

            ret

FindColWords ENDP

;-------------------------------------------------------

FindDiagWords PROC,

                ptrMatrix: PTR DWORD

;

; Find the 7 letter words with 2 vowels in the diagonals and prints them if found

; Receives: Address of random matrix of 7x7

; Returns: Number of found words

;-------------------------------------------------------

            push edi ; save registers

            push esi

            push ebx

            push ecx

            push edx

            mov edi, 0 ; number of found words = 0

            mov esi, ptrMatrix ; point to start of matrix

            mov ebx, 0 ; current pos

            mov ecx, 7 ; repeat for 7 letters in diag

            mov edx, 0 ; number of vowels

findD1Vowels:

            INVOKE isVowel, BYTE PTR[esi + ebx] ; check if it's a vowel

            add edx, eax ; increment number of vowels

            add ebx, 8 ; increment position in matrix diagonal

            loop findD1Vowels ; decrement leters and repeat if not zero

            cmp edx, 2 ; if 2 vowels were found

            jne nextDiag ; if not, go to next diagonal

            INVOKE DisplayWord, esi, 8 ; display the 7 letter diagonal word

            call CrLF ; print newline

            inc edi ; increment number of found words

nextDiag:

            mov ebx, 6 ; current pos

            mov ecx, 7 ; repeat for 7 letters in diag

            mov edx, 0 ; number of vowels

findD2Vowels:

            INVOKE isVowel, BYTE PTR[esi + ebx] ; check if it's a vowel

            add edx, eax ; increment number of vowels

            add ebx, 6 ; increment position in matrix diagonal

            loop findD2Vowels ; decrement leters and repeat if not zero

            cmp edx, 2 ; if 2 vowels were found

            jne findDiagEnd ; if not, end

            mov ebx, esi ; point to start of second diagonal

            add ebx, 6

            INVOKE DisplayWord, ebx, 6 ; display the 7 letter diagonal word

            call CrLF ; print newline

            inc edi ; increment number of found words

findDiagEnd:

            mov eax, edi ; return found words

            pop edx ; restore registers

            pop ecx

            pop ebx

            pop esi

            pop edi

            ret

FindDiagWords ENDP

END main