Instructions
Requirements and Specifications



Screenshots of output




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