Problems with using registers as local variables for a function
 

  • The number of CPU registers is limited

      • You cannot have many local variables

  • CPU registers are shared:

      • For this reason, non-leaf functions cannot use registers are their local variables !!!

I will illustrate what can go wrong if you use registers to store value while you call another function next

Example to show what can go wrong when you call a function

We call a square( ) function that computes the square of its input parameter in register r0 and returns the square value in register r0:

   //  result = square(3);

   /* -------------------------------------------------
      Call square(3)
      ------------------------------------------------- */
   mov     r0, #3      // Pass parameter 3 in r0 
   bl      square      // Call square(3)

   /* -------------------------------------------------
      Save return value (in r0) in variable result
      ------------------------------------------------- */      
   movw    r1, #:lower16:result
   movt    r1, #:upper16:result

   str     r0, [r1]
   

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

Example to show what can go wrong when you call a function

Now let's executes:   result = square(3) + square(4)

  //  result = square(3) + square(4);

  /* -------------------------------------------------
     Call square(3)
     ------------------------------------------------- */
   mov     r0, #3      // Pass parameter 3 in r0 
   bl      square      // Call square(3)

   mov	   r1, r0      // Save return value in r1

   /* -------------------------------------------------
      Call square(4)
      ------------------------------------------------- */
   mov     r0, #4      // Pass parameter 4 in r0 
   bl      square      // Call square(4)

   add	   r0, r0, r1  // Computes square(3) + square(4) ??

   /* -------------------------------------------------
      Store in result
      ------------------------------------------------- */      
   movw    r1, #:lower16:result
   movt    r1, #:upper16:result

   str     r0, [r1] 

Fails because the "saved" value was lost !!!

Example to show what can go wrong when you call a function

Rule of a function call:

  //  result = square(3) + square(4);

  /* -------------------------------------------------
     Call square(3)
     ------------------------------------------------- */
   mov     r0, #3      // Pass parameter 3 in r0 
   bl      square      // Call square(3)

   mov	   r1, r0      // Save value in r1

   /* -------------------------------------------------
      Call square(4)
      ------------------------------------------------- */
   mov     r0, #4      // Pass parameter 4 in r0 
   bl      square      // Call square(4)
   Values in all registers (except the return value) are invalid !!!
   add	   r0, r0, r1  // Computes square(3) + square(4) ??

   /* -------------------------------------------------
      Store in result
      ------------------------------------------------- */      
   movw    r1, #:lower16:result
   movt    r1, #:upper16:result

   str     r0, [r1]  

The safe way (place) to store parameters (and store local variables
 

  • The safest way to store parameters (and to store local variables) is:

      • reserve memory cells that are only used to store the parameter (or the local variable)

        I.e.: that cannot be used to store something else

    (Registers can store different variables at different times !)

  • Because the parameters (and local variables) are created and destroyed in the LIFO order (= function call/return order) :

      • We will store parameters (and local variables) in the runtime stack