Postscript: Using the non-leaf function technique to implement leaf functions
 

  • The technique that we used to implement non-leaf methods:

    nonLeafFunc:
                 push {lr}
    	     ....
    	     ....
    	     pop  {pc}
    

    can also be used to implement leaf methods:

          Orignal solution:                      Alternative solution:
      -------------------------               ------------------------
    leafFunc:                           leafFunc:
                                                 push {lr}
    	 ....                                ....
    	 ....                                ....
    	 mov pc, lr                          pop  {pc}
    

 

I.e.:   we can use the non-leaf function technique to implement a leaf function

Example: Using the non-leaf function technique to implement leaf functions
 

Example: (expressed in Java)

   public static void main(String[] args)
   {
      A( );
   }

   public static void A( )
   {
      ...
      B( );   // Calls B( )
      ...
   }

   public static void B( )
   {
      ...     // Does not call any method/function     
      ...
   }
   

Example: Using the non-leaf function technique to implement leaf functions

Example: using the non-leaf technique in the leaf function B( )

        mov     r0, #4
        mov     r1, #4
        bl      A
        mov     r2, #4
        mov     r3, #4

Stop:

A:
        push    {lr}     // Save return address

        mov     r0, #44
        mov     r1, #44
        bl      B        // Overwrites lr, it's OK, we saved it !!!
        mov     r2, #44
        mov     r3, #44

        pop     {pc}    // A returns to main !!!


B:
        push    {lr}    // Save return address

        mov     r0, #4444
        mov     r1, #4444

        pop     {pc}    // B returns to A !!!
   

DEMO:   /home/cs255001/demo/asm/8-sub/bl+popX.s

Comment
 

  • The subroutine call instruction (bl instruction) of older CPU types:

    • Saves the return address on the program (runtime) stack !!

    Example: Intel !

  • Modern CPUs (like the ARM) saves the return address in a register for speed:

    • Leaf functions are very common (used often)

    • Saving the return address in a register is faster

      • Because accessing the stack stored in RAM memory is slower than accessing a register)