.ORIG x3000 ; forms the inner product of two vectors stored as an array ; each array contains 10 elements. ; array1 is stored starting at address x3100 ; array2 is stored starting at address x3200 ; the inner product (or dot product) is the sum of the products of corresponding array elements ; product = A(1)*B(1) + A(2)*B(2) + ....+ A(10)*B(10) ; program returns the result in register R4 product AND R0, R0, #0 ;clear R0. This will be used to count number of elements processed AND R4, R4, #0 ;clear R4. This will be used to keep track of the running sum (the inner product) ADD R0, R0, #10 ; initialize R0 to 10 -- the number of elements in array ;fill in code below for computing dot product ; the result will be stored in R4 ; load address of first element of array 1 into registr R5 LD R5, array1 ; load address of first element of array 2 into register R6 LD R6, array2 ; fetch first element of each array into a register loop1 LDR R1, R5, #0 ;load first element into R0 -address is in R5 and offset is zero LDR R2, R6,#0 ;load second element into R1 - address is in R6 and offset is zero ST R5, saveR5 ; caller-save registers- save contents of registers R5 and R6 since these ST R6, saveR6 ; contain address of the two arrays, and these registers will be used ; by the main program and we do not want to overwrite these values ; the program must call the subroutine MULT defined below to perform the multiplications ; while counter in R0 greater than zero, call MULT and add result to running sum in R4 ; make sure you save any registers that will be altered by MULT ; SOLUTION: two ways to do this - (1) rewrite MULT so that it uses a different set of registers than those used ; by the main program. if there are enough registers then this is easy to do. ; (2) if there are not enough registers, then save the registers in memory location. the registers used ; by MULT are R0,R1,and R4. So need to store these before calling MULT and restore them after ; returning from MULT ; figure out how you will store and load address of MULT ; SOLUTION: (1) If the program is small enough and the address of MULT is within the PC offset maximum then we ; can use JSR mult to call the MULT subroutine ; (2) If the program is large then the address of MULT may be more than 256 locations away from the ; current PC location. In this case, we have to load the address of MULT into a register and then ; do a JSRR Register. To load the address of MULT, use a memory location "goMult" and initialize it to ; address of MULT. Then load contents of location "gomult" into a register. LD R5, gomult ;load contents of location gomult, i.e., the address of mult, into register R5 JSRR R5 ;call mult subroutine (its address is in register R5) ;this will transfer control to mult and store return address in R7 ;the result (the product of the two numbers in R1 and R2) is returned in R3 LD R5, saveR5 ; restore old/saved value of R5 into register R5- this is address of array1 LD R6, saveR6 ; restore old/saved value of R6 ADD R4, R4, R3 ; add result of MULT, in register R3, to running sum in R4 ADD R5, R5,#1 ; increment index of array1 to point to next element in array1 ADD R6, R6, #1 ; increment index of array2 to point to next element in array2 ADD R0, R0, #-1 ; decrement R0 by 1 BRp loop1 ; if R0 is greater than zero then repeat the loop by processing the next two ;numbers in the arrays HALT ; if R0 is zero then done. HALT array1 .FILL x3100 ;array1 starts at address x3100 array2 .FILL x3200 ; array2 starts at address x3200 gomult .FILL mult ;store address of mult in location gomult saveR5 .BLKW 1 ;reserve one location with label saveR5 to store current value of R5 saveR6 .BLKW 1 ;reserve one location with label saveR6 to store current value of R6 ; Create Multiplication subroutine ;.ORIG x4000 -- the origin command has to be removed from the original code ; the original code for MULT multiplies two non-negative numbers, stored in registers R0, and R1 and the product/result is stored in R7 ; Modify this code so that it is now a subroutine and can be called by any function, and will return to the caller. ; SOLUTION: ; first, note that R7 is being used - this will cause problems when MULT is used as a subroutine since ; R7 is the link register which stores the return address. So instead of R7 use another register R4 ; second, If either number is zero then the product is zero - so check if either number is zero. ; if either is zero then branch to DONE ; third, register R0 is being used by the main program to keep count of the number of elements so ; use a different register R2. ; finally, to return from the subroutine you have to change HALT to a RET - this returns to the ; calling program (the main program) using the return address stored in register R7 ; Below is the final MULT subroutine code: register R3 stores result, input arguments to this subroutine ; are passed using registers R1 and R2 mult AND R3, R3, #0 ;initialize product stored in R3 to 0 ; can you insert code here to check if either of the numbers is zero (in which case product is zero) ADD R1, R1, #0 ; add 0 to R1 - the condition codes will be set based on value of R0 BRz done ; if R1=0 then condition register z=1 and branch to done ADD R2, R2, #0 ; add 0 to R3 - similar to what we did for R1 BRz done ; if R2=0 then done, and product=0 loopmult ADD R3, R3, R2 ; add R2 to itself R1 times and store result in R3- add y to itself x times ADD R1, R1, #-1 ;decrement R1 BRp loopmult done RET ; to return from MULT you have to use RET instruction to return to calling routine ; remove .END at end of MULT ;End of your entire program goes below .END