; ; Assignment 2. Sample solution, bsy. ; ; This program calculates the expression a b + c d, where a, b, c, and d are ; integers stored in memory locations 0, 1, 2, and 3 respectively. ; The result is stored in memory location 4. It is assumed that the values ; will not cause an overflow, and that the inputs are greater than or equal ; to zero. ; ; The program uses a subroutine to multiply two numbers together. The ; returned value is actually the negative of the product, so the routine ; is named negMult. This is a natural side effect of using a loop with ; a subge to accumulated the product, subtracting from zero the second ; parameter a number of times equal to the first. Instead of negating ; this negative product in the subroutine, we leave it as negative, since ; the main routine needs to compute the sum by subtraction and will ; again naturally flip the sign. ; a equ 0 b equ 1 c equ 2 d equ 3 output equ 4 move: macro src,dst subge tmp,tmp,next subge tmp,src,next subge dst,dst,next subge dst,tmp,next endmacro call: macro subr,retInstAddr clear retInstrAddr subge retInstrAddr,L0,next goto subr LretLabel: .data ; indicate place elsewhere, not ; part of the instruction stream L0: .word neg(triple(tmp,tmp,LretLabel)) ; L label means local label .text endmacro .org 0x100 main: move a,x ; params move b,y call negMult, negMultRet ; negProd = -ab subge output,output,next subge output,negProd,next ; output = ab move c,x move d,y call negMult, negMultRet ; negProd = -cd subge output,negProd,next ; output = ab + cd done: subge tmp,tmp,done ; all done! .data tmpSum: .word 0 tmp: .word 0 .text negMult: subge xx,xx,next subge xx,x,next ; xx = -x subge negProd,negProd,next ; negProd = 0 ; ; loop invariant: -x y = negProd + xx * y ; multLoop: subge xx,zero,negMultRet ; xx = xx + 0 ; = -x + 0 >= 0 ; or 0 >= x. subge negProd,y,next ; negProd = negProd - y subge xx,neg1,next ; xx = xx + 1 goto multLoop ; ; exit when xx = 0, so invariant tells us that ; -x y = negProd + 0 * y = negProd ; which is the desired return value ; negMultRet: .word 0,0,0 ; negProd = -(x * y) .data zero: .word 0 neg1: .word neg(1) negProd: .word 0 x: .word 0 y: .word 0 xx: .word 0