Using registers as local variables in a leaf function

  • Local variable:

      • is a variable that is "created" (= reserved) when the function starts running

      • The local variable is "destroyed" (= unreserved) when the function exits (= returns)

  • Safety pre-condition:

      • Only leaf functions can designate (= reserve) available (= unused) registers as its local variables

    (Non-leaf function cannot use registers as its local variables because when it calls another function, that function can overwrite values in registers used as local variables

    I.e.: reserving registers in a non-leaf function is not possible)

How use reserve a register as a local variable in a leaf function

It's very easy (it is a matter of sticking to an arrangement):

  • The method reserves (= designates) some unused register exclusively to store the value of a local variable

  • Any updates made to that local variable will update the designated register

  • Caveat:

      • Do not update the designated register (used as a local variable) when the local variable appears on the RHS of an assignment !!!

        (Because variables in the RHS are read (and not written)

    (This is a common error made by students)

Example: using registers as local variable (in a leaf function)
 

   /* -------------------------------------------------------
      sumRange(A,a,b):  returns  (A[a] + A[a+1] + ... + A[b-1]) 
      ------------------------------------------------------- */  
   int sumRange(int[] A, int a, int b )           
   {
       int i, s;

       s = 0;
       for (i = a, i < b; i++)
          s = s + A[i];
       return(s);
   }
   

DEMO:   /home/cs255001/demo/asm/8-sub/reg-local1.s

How we will designated the register usage in the sumRange( ) function
 

Register assignments:

Parameters:        A in r0, a in r1, b in r2
Local variables:   i in r3, s in r4

The sumRange( ) function in ARM assembler code

sumRange:

        // When  sumRange  begins, we will have: r0 = A, r1 = a, r2 = b
        // We will use  r3  as local variable i  and  r4 as local variable s

        

        // s = 0;
        mov     r4, #0          // r4(=s) = 0

        // i = a;
        mov     r3, r1          // r3(=i) = r1(=a)

while:  // while (i < b)

        cmp     r3, r2          // r3 = i, r2 = b
        bge     whileEnd

        // s = s + A[i];

        ///// get A[i] in r10
        mov     r5, r3          // r5 = i (because r3 = i)
        add     r5, r5, r5      // r5 = 2*i
        add     r5, r5, r5      // r5 = 4*i   = offset used to access A[i]

        ldr     r10, [r0, r5]   // r10 = A[i] (r0=A(base), r5=offset)

        add     r4, r4, r10     // r4(=s) = r4(=s) + r10(=A[i])


        // i++
        add     r3, r3, #1      // r3(=i) = r3(=i) + 1

        b       while           // End of while body - loop back !!

whileEnd:

        // return(s)

        
        mov     r0, r4          // r0(return location) = r4(=s)
                                // The return value is now in r0

        mov     pc, lr          // Return to the caller
   

DEMO:   /home/cs255001/demo/asm/8-sub/reg-local1.s