title: PIC Assembly function calling
body: <p>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:</p>
  
  <pre><code>;***********************************************************************
  ; 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
  </code></pre>
  
  <p>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: </p>
  
  <pre><code>mul_16ptr1   set    0x45
  mul_16ptr2   set    0x47
  mul_16res    set    0x50
  call         mul_16bit
  </code></pre>
  
  <p>To multiply <code>0x45</code> and <code>0x47</code> and store it in <code>0x50</code>. 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?</p>