Example: passing parameters and return values using registers

  • Consider the following function call:

      int sumSquares(int a, int b)
      {
          return a*a + b*b;
      }
    
      int main( )
      {
          int x, y, z;
    
          z = sumSquares(x, y);
      }


  • We will translate the main( ) function and the sumSquares( ) function in ARM assembler so:

    • You can see how:

      • The parameters are passed from the main() to the sumSquares()
      • The return value is passed from the sumSquares() to the main()

How a computer program passes parameters and return values in registers

  • Consider the following function call:

  • The function call to sumSquares( ) is translated as:

       bl  sumSquares
    

How a computer program passes parameters and return values in registers

  • The function call to sumSquares( ) is implemented with:   bl sumSquares

  • Before the function call:

    • We must pass the parameter using the designated registers

How a computer program passes parameters and return values in registers

  • Assume we use the designation:   param x <--> reg r0 and param y <--> reg r1

  • The function body of sumSquares( ) will be translated with:

       parameter a --->  use register r0 as operand
       parameter b --->  use register r1 as operand
    

How a computer program passes parameters and return values in registers

  • Example translation:

  • The expression a*a and b*b will use registers r0 and r1:

       a*a      ------>     mul   r2, r0, r0  // r2 = a*a
       b*b      ------>     mul   r3, r1, r1  // r3 = b*b
    

How a computer program passes parameters and return values in registers

  • We must also designate a register to store the return value:

  • Typically, the register r0 is used to store return value (and we will adopt this):

    • Before the function returns, it must put the result a*a + b*b in register r0

How do we write the main( ) function

We can now code the main( ) function:

 main:                         sumSquares:

     // Pass x in r0                // Compute x*x+y*y 
                                    // where x = r0 and y = r1     


     // Pass y in r1

                                    // Return result in r0

     bl sumSquares                  mov pc, lr

     // Store return value
     // in z                         



Stop:                     
   

How do we write the main( ) function

Pass the 1st parameter in register r0:

 main:                         sumSquares:

     movw r0, #:lower16:x           // Compute x*x+y*y 
     movt r0, #:upper16:x           // where x = r0 and y = r1     
     ldr  r0, [r0]

     // Pass y in r1                     
                              
                                    // Return result in r0

     bl sumSquares                  mov pc, lr

     // Store return value
     // in z                         



Stop:                     
   

How do we write the main( ) function

Pass the 2nd parameter in register r1:

 main:                         sumSquares:

     movw r0, #:lower16:x           // Compute x*x+y*y 
     movt r0, #:upper16:x           // where x = r0 and y = r1     
     ldr  r0, [r0]

     movw r1, #:lower16:y
     movt r1, #:lower16:y
     ldr  r1, [r1]                  // Return result in r0

     bl sumSquares                  mov pc, lr

     // Store return value
     // in z                         



Stop:                     
   

How do we write the main( ) function

When sumSquares( ) returns, assign the return value (in the designated register r0) to variable z:

 main:                         sumSquares:

     movw r0, #:lower16:x           // Compute x*x+y*y 
     movt r0, #:upper16:x           // where x = r0 and y = r1     
     ldr  r0, [r0]

     movw r1, #:lower16:y
     movt r1, #:lower16:y
     ldr  r1, [r1]                  // Return result in r0

     bl sumSquares                  mov pc, lr

     movw r1, #:lower16:z
     movt r1, #:upper16:z                          
     str  r0, [r1]


Stop:                     
   

How do we write the sumSquares( ) function

We can code the sumSquares( ) function using the designated registers for parameters and return values:

 main:                         sumSquares:

     movw r0, #:lower16:x           // Compute x*x+y*y 
     movt r0, #:upper16:x           // where x = r0 and y = r1     
     ldr  r0, [r0]

     movw r1, #:lower16:y
     movt r1, #:lower16:y
     ldr  r1, [r1]                  // Return result in r0

     bl sumSquares                  mov pc, lr

     movw r1, #:lower16:z
     movt r1, #:upper16:z                          
     str  r0, [r1]


Stop:                     
   

How do we write the sumSquares( ) function

Compute x*x:

 main:                         sumSquares:

     movw r0, #:lower16:x           // Compute x*x+y*y 
     movt r0, #:upper16:x           // where x = r0 and y = r1 
     ldr  r0, [r0]                  mul r2, r0, r0 // r2 = x*x
                                    
     movw r1, #:lower16:y           
     movt r1, #:lower16:y
     ldr  r1, [r1]                  // Return result in r0

     bl sumSquares                  mov pc, lr 

     movw r1, #:lower16:z
     movt r1, #:upper16:z                          
     str  r0, [r1]


Stop:                     
   

How do we write the sumSquares( ) function

Compute y*y:

 main:                         sumSquares:

     movw r0, #:lower16:x           // Compute x*x+y*y 
     movt r0, #:upper16:x           // where x = r0 and y = r1 
     ldr  r0, [r0]                  mul r2, r0, r0 // r2 = x*x
                                    mul r3, r1, r1 // r3 = y*y
     movw r1, #:lower16:y           
     movt r1, #:lower16:y
     ldr  r1, [r1]                  // Return result in r0

     bl sumSquares                  mov pc, lr 

     movw r1, #:lower16:z
     movt r1, #:upper16:z                          
     str  r0, [r1]


Stop:                     
   

How do we write the sumSquares( ) function

Compute x*x + y*y:

 main:                         sumSquares:

     movw r0, #:lower16:x           // Compute x*x+y*y 
     movt r0, #:upper16:x           // where x = r0 and y = r1 
     ldr  r0, [r0]                  mul r2, r0, r0 // r2 = x*x
                                    mul r3, r1, r1 // r3 = y*y
     movw r1, #:lower16:y           add r2, r2, r3 // r2 = x*x+y*y 
     movt r1, #:lower16:y
     ldr  r1, [r1]                  // Return result in r0

     bl sumSquares                  mov pc, lr 

     movw r1, #:lower16:z
     movt r1, #:upper16:z                          
     str  r0, [r1]


Stop:                     
   

How do we write the sumSquares( ) function

Return the result in the designated register r0:

 main:                         sumSquares:

     movw r0, #:lower16:x           // Compute x*x+y*y 
     movt r0, #:upper16:x           // where x = r0 and y = r1 
     ldr  r0, [r0]                  mul r2, r0, r0 // r2 = x*x
                                    mul r3, r1, r1 // r3 = y*y
     movw r1, #:lower16:y           add r2, r2, r3 // r2 = x*x+y*y 
     movt r1, #:lower16:y
     ldr  r1, [r1]                  mov r0, r2

     bl sumSquares                  mov pc, lr

     movw r1, #:lower16:z
     movt r1, #:upper16:z                          
     str  r0, [r1]


Stop:                     
   

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