// multiply.dsa // usage: // // include multiply "" // // usage for multiply: // push (arg1) // push (arg0) // call multiply::multiply // pop (arg0) // pop (arg1) multiply: push bpr mov spr, bpr ldw bpr, rg0, 8 // load op 2 ldw bpr, rg1, 12 // load op 1 lwi 0, rg2 // initialise rg2 to zero _multiply_loop: add rg2, rg0, rg2 dec rg1 cmp rg1, zero jgt _multiply_loop _multiply_end: stw rg2, bpr, 8 mov bpr, spr pop bpr return divmod: push bpr mov spr, bpr ldw bpr, rg1, 8 // load op 2 ldw bpr, rg0, 12 // load op 1 lli 0, rg3 _divmod_loop: cmp rg0, rg1 jlt _divmod_end sub rg0, rg1, rg0 inc rg3 jmp _divmod_loop _divmod_end: // store div in first arg // store mod in second arg stw rg3, bpr, 8 stw rg0, bpr, 12 mov bpr, spr pop bpr return // multiply.dsa - improved version // Multiplies two 32-bit numbers using shift-and-add // // Usage: // push operand2 (multiplier) // push operand1 (multiplicand) // call multiply::multiply // pop result // pop zero (discard second argument) new_multiply: push bpr mov spr, bpr ldw bpr, rg0, 8 // rg0 = multiplicand ldw bpr, rg1, 12 // rg1 = multiplier lli 0, rg2 // rg2 = result (accumulator) lli 32, rg3 // rg3 = bit counter mult_loop: // Check if lowest bit of multiplier is 1 lli 1, acc and rg1, acc, acc // acc = rg1 & 1 cmp acc, zero jeq skip_add // if (rg1 & 1) == 0, skip addition // Add multiplicand to result add rg2, rg0, rg2 skip_add: shl rg0, 1 // shift multiplicand left shr rg1, 1 // shift multiplier right dec rg3 cmp rg3, zero jgt mult_loop stw rg2, bpr, 8 // store result mov bpr, spr pop bpr return