title Matrix (matrix.asm)
; Dani Horowitz
; CSC111 x86 Assembly Programming
; This program randomly generates two 3x3 integer matrices, A and B
; It then prints out the product of the matrices
INCLUDE Irvine32.inc
;--------------------------------------------------
.stack ; begin stack segment
;--------------------------------------------------
TimerStart PROTO,
pSavedTime: PTR DWORD
TimerStop PROTO,
pSavedTime: PTR DWORD
.data ; begin data segment
A dword 10000 dup(0) ; matrix A
B dword 10000 dup(0) ; matrix B
num_rows dword 0;
num_cols dword 0;
col_counter dword 0 ; inner loop counter
row_counter dword 0 ; outer loop counter
counter byte 0 ; this will always come in handy
sum dword 0
; used for CPU timer
newmatrix dword 1
time dword 0
; used to generate product matrix
working_row dword 0; (0=1st row, 12=2nd row, 24=3rd row)
working_col dword 0; (0=1st col, 4=2nd col, 8=3rd col)
; ######################
; ### MAY BE EDITED: ###
; ######################
matrix_size = 5 ; 2= [3x3] 9= [10x10]
upbound dword 50 ; upper bound value for matrix values
num_matrices = 5 ; how many matrices to generate - 1
; ######################
nextrow = (matrix_size + 1) * 4
; ###########################
; ##### STOPWATCH TIMER #####
; ###########################
msg BYTE " milliseconds have elapsed", 0dh, 0ah, 0
timer1 dword ?
; ###########################
;--------------------------------------------------
.code ; begin code segment
;--------------------------------------------------
;--------------------------------------------------
TimerStart PROC uses eax esi,
pSavedTime: PTR DWORD
INVOKE GetTickCount
mov esi, pSavedTime
mov [esi], eax
ret
TimerStart ENDP
TimerStop PROC uses esi,
pSavedTime: PTR DWORD
INVOKE GetTickCount
mov esi, pSavedTime
sub eax, [esi]
ret
TimerStop ENDP
;--------------------------------------------------
;--------------------------------------------------
determinesize PROC
;
; Calculate num_rows and num_cols based on matrix_size
;--------------------------------------------------
mov eax, matrix_size
mov ebx, nextrow
mul ebx
mov num_rows, eax
mov eax, matrix_size
mov ebx, 4
mul ebx
mov num_cols, eax
ret
;--------------------------------------------------
determinesize ENDP
;--------------------------------------------------
;--------------------------------------------------
setvalue PROC
;
; Set a value in the matrix to a random #
;--------------------------------------------------
mov eax, upbound ; set range between 1 and upbound
call RandomRange ; put a random int in eax
inc eax
mov [esi], eax ; put the value in the array
ret
;--------------------------------------------------
setvalue ENDP
;--------------------------------------------------
;--------------------------------------------------
createA PROC
;
; Initialize generation of matrix A
;--------------------------------------------------
mov esi, OFFSET A ; finds the start of the matrix
call traversematrix ; fills in the matrix
ret
;--------------------------------------------------
createA ENDP
;--------------------------------------------------
;--------------------------------------------------
createB PROC
;
; Initialize generation of matrix B
;--------------------------------------------------
mov esi, OFFSET B ; finds the start of the matrix
call traversematrix ; fills in the matrix
ret
;--------------------------------------------------
createB ENDP
;--------------------------------------------------
;--------------------------------------------------
printvalue PROC
;
; Print a value neatly
;--------------------------------------------------
push eax
call WriteDec ; print value
mov al, ' '
call WriteChar ; print a space
pop eax
ret
;--------------------------------------------------
printvalue ENDP
;--------------------------------------------------
;--------------------------------------------------
traversematrix PROC
;
; Traverse each row of the matrix
;--------------------------------------------------
call Crlf ; line feed
mov row_counter, 0 ; set to first row
NewRow:
mov col_counter, 0 ; set to first column
NewCol:
; -- begin inner loop --
call setvalue ; put value in location
call printvalue ; print value while we're here
add esi, 4 ; next data member of array
inc col_counter ; did we reach the last column
cmp col_counter, matrix_size ; of the row?
jle NewCol ; if not, add another element
; -- end inner loop --
call Crlf
inc row_counter ; new row
cmp row_counter, matrix_size ; stop at 3rd row
jle NewRow
ret
;--------------------------------------------------
traversematrix ENDP
;--------------------------------------------------
;--------------------------------------------------
addelements PROC
;
; Add A1B1 + A2B2 + A3B3
;--------------------------------------------------
mov eax, working_row ; row_counter = working_row
mov ebx, working_col ; col_counter = working_col
mov row_counter, eax
mov col_counter, ebx
mov counter, 0
mov sum, 0
Next:
; -- begin loop --
call multiplyelements ; multiply AxBx
add sum, eax ; accumulate the sum
add row_counter, 4 ; next elements
add col_counter, nextrow
inc counter ; increment loop counter
cmp counter, matrix_size ; stop at 3rd row
jle Next
; -- end loop --
mov eax, sum
ret
;--------------------------------------------------
addelements ENDP
;--------------------------------------------------
;--------------------------------------------------
multiplyelements PROC
;
; Multiply Ax and Bx
;--------------------------------------------------
mov esi, OFFSET A ; find matrix A
add esi, row_counter ; find location we want
mov eax, [esi] ; put into eax
mov esi, OFFSET B ; find matrix B
add esi, col_counter ; find location we want
mov ebx, [esi] ; put into ebx
mul ebx ; do multiplication
ret
;--------------------------------------------------
multiplyelements ENDP
;--------------------------------------------------
;--------------------------------------------------
multiplymatrix PROC
;
; Do matrix multiplication
;--------------------------------------------------
call Crlf
mov working_row, 0 ; start on the first row
NewRow:
mov working_col, 0 ; go to first column
NewCol:
; -- begin inner loop --
call addelements ; do all the addition and multiplication
call printvalue ; print value
add working_col, 4 ; get ready to do the next column
mov eax, working_col ; did we reach the end of a row?
cmp eax, num_cols
jle NewCol
; -- end inner loop --
call Crlf ; new row
add working_row, nextrow
mov eax, working_row ; did we reach the last row?
cmp eax, num_rows
jle NewRow
call Crlf
ret
;--------------------------------------------------
multiplymatrix ENDP
;--------------------------------------------------
;--------------------------------------------------
main proc
;--------------------------------------------------
call Clrscr ; clear screen
call Randomize ; randomize seed
mov ebx, num_matrices ; how many matrices to generate
; ########## TIMER ##########
INVOKE TimerStart, ; start the timer
ADDR timer1
; ########## TIMER ##########
NextMatrix:
; -- begin loop --
call createA ; generate matrix A
call createB ; generate matrix B
call determinesize ; determine size of matrices
call multiplymatrix ; multiply matrices
inc newmatrix
mov eax, newmatrix
cmp eax, num_matrices
jle NextMatrix
; ########## TIMER ##########
INVOKE TimerStop,
ADDR timer1
call WriteDec
mov edx, OFFSET msg
call WriteString
; ########## TIMER ##########
exit
main endp
end main
;--------------------------------------------------