I'm writing a pretty basic program in PIC18 assembly. It requires that I write a subroutine to multiply two 16-bit numbers... This is what I have right now:
;***********************************************************************
; mul_16bit: subroutine that multiplies two 16 bit numbers stored in
; addresses mul_16ptr1, mul_16ptr1+1 and mul_16ptr2,mul_16ptr2+1 and
; returns the 32-bit result in addresses mul_16res1 to mul_16res1+3
;***********************************************************************
mul_16bit:
movf mul_16ptr2, W ;multiply the lower bytes
mulwf mul_16ptr1, W
movff PRODH, mul_16res+1
movff PRODL, mul_16res
movf mul_16ptr2+1, W ;multiply upper bytes
mulwf mul_16ptr1+1, W
movff PRODH, mul_16res+3
movff PRODL, mul_16res+2
movf mul_16ptr2, W ;multiply lower byte of num2
mulwf mul_16ptr1+1, W ; and upper byte of num1
movf PRODL, W
addwf mul_16res+1, F
movf PRODH, W
addwfc mul_16res+2, F
movlw 0 ; add carry
addwfc mul_16res+3, F
movf mul_16ptr2+1, W ;multiply upper byte
;of num1 and lower
mulwf mul_16ptr1, W ; byte of num2
movf PRODL, W ;add the result to mul_16res
addwf mul_16res+1, F ;...
movf PRODH, W ;...
addwfc mul_16res+2, F ;...
movlw 0 ; add carry
addwfc mul_16res+3, F
return
So the way I have it written right now is that it multiplies numbers stored in the registered mentioned in the first comment and stores them in the 4 registers in the comment. This works well if I only need to do this multiplication once or twice, i.e. i can just say something like
mul_16ptr1 set 0x45
mul_16ptr2 set 0x47
mul_16res set 0x50
call mul_16bit
to multiply 0x45 and 0x47 and store it in 0x50. The problem is when I need to call this more than once on different data, because the assembler won't let me "set" any of the pointers twice. I've tried using indirect access (i.e. using LFSR1, LFSR2, and LFSR0 to store the multiplicands and result) but then I just get in a huge mess of POSTINC0's etc. Is there anyway to make this function calling thing nicer?
Thanks