How the compiler implements the pass-by-value mechanism
 

  1. When a parameter is specified as passed-by-value, the compiler will pass (= copy) the value of the variable to the parameter store location

  2. Furthermore:

      • when the compiler translates the body (= statements) of the function, the occurence of the parameter will access the value in the parameter store location

 

I will illustrate this with a example next.

How the compiler implements the pass-by-value mechanism - Example

I will code this example in ARM assembler:

    #include <iostream>
     
    using  namespace  std;
     
    /* ====================================================
       Function with a parameter that is passed by value
       ==================================================== */
    void  f(int a)	// Var a is passed by value
    {
       a = a + 1;
    }
     
    int main(int argc, char *argv[])
    {
       int k = 7;
 
       f(k); 
    }
   

How the compiler implements the pass-by-value mechanism - Example

What the compiler will do when a variable is passed-by-value:

    #include <iostream>
     
    using  namespace  std;
     
    /* ====================================================
       Function with a parameter that is passed by value
       ==================================================== */
    void  f(int a)	// Var a is passed by value
    {
       a = a + 1;  // Use the parameter location on stack
    }
     
    int main(int argc, char *argv[])
    {
       int k = 7;
 
       f(k);  // Pass the value of k (=7) on stack
    }
   

How the compiler implements the pass-by-value mechanism - Example

Translating the main( ) function:

main:
    /* =========================================
       Pass k to f( ) by value
       ========================================= */
    movw    r0, #:lower16:k
    movt    r0, #:upper16:k   // r0 = address of k
    ldr     r0, [r0]          // r0 = value of k
    push    {r0}              // Pass k by value (pass k's value)

    bl      f                 // Call function f
    add   sp, sp, #4          // Clean up parameters on the stack

/* ----------------------------------------------------- */
    .data

k:  .4byte  7                 // This is the variable k
   

How the compiler implements the pass-by-value mechanism - Example

Translating the f( ) function:

f:
   /* ****************************************
      Prelude: build stack frame
      **************************************** */
   push    {lr}            // Save return address in LR
   push    {fp}            // Save Frame Pointer in FP
   mov     fp, sp          // Initialize my own FP
   sub     sp, sp, #0      // I create 0 local variable in stack

   /* =======================================
      Translating a = a + 1
      ======================================= */
   ldr     r0, [fp, #8]    // a uses the parameter store location
   add     r0, r0, #1      // r0 = a + 1
   str     r0, [fp, #8]    // Assign result to parameter store location 

   /* ************************************************
      Postlude: break down stack frame
      ************************************************ */
   mov     sp, fp          // De-allocate the local variables
   pop     {fp}            // Restore old FP
   pop     {pc}            // Return
   

DEMO:   /home/cs255001/demo/asm/A-pass-by-ref/pass-by-value.s

How the compiler implements the pass-by-reference mechanism
 

  1. When a parameter is specified as passed-by-reference, the compiler will pass (= copy) the reference (= address) of the variable to the parameter store location

  2. Furthermore:

      • when the compiler translates the body (= statements) of the function, the occurence of the parameter will access the variable through the address in the parameter store location

 

I will illustrate this with a example next.

How the compiler implements the pass-by-reference mechanism - Example

I will code this example in ARM assembler:

    #include <iostream>
     
    using  namespace  std;
     
    /* ====================================================
       Function with a parameter that is passed by value
       ==================================================== */
    void  f(int & a)	// Var a is passed by reference
    {
       a = a + 1;
    }
     
    int main(int argc, char *argv[])
    {
       int k = 7;
 
       f(k); 
    }
   

How the compiler implements the pass-by-reference mechanism - Example

What the compiler will do when a variable is passed-by-reference:

    #include <iostream>
     
    using  namespace  std;
     
    /* ====================================================
       Function with a parameter that is passed by value
       ==================================================== */
    void  f(int & a)	// Var a is passed by reference
    {
       a = a + 1;  // Use variable at address given in a
    }
     
    int main(int argc, char *argv[])
    {
       int k = 7;
 
       f(k);  // Pass the address of k on stack
    }
   

How the compiler implements the pass-by-reference mechanism - Example

Translating the main( ) function:

main:
    /* =========================================
       Pass k to f( ) by reference
       ========================================= */
    movw    r0, #:lower16:k
    movt    r0, #:upper16:k   // r0 = address of k
    push    {r0}              // Pass k by reference (pass k's address)

    bl      f                 // Call function f
    add   sp, sp, #4          // Clean up parameters on the stack

/* ----------------------------------------------------- */
    .data

k:  .4byte  7                 // This is the variable k
   

How the compiler implements the pass-by-reference mechanism - Example

Translating the f( ) function:

f:
   /* ****************************************
      Prelude: build stack frame
      **************************************** */
   push    {lr}         // Save return address in LR
   push    {fp}         // Save Frame Pointer in FP
   mov     fp, sp       // Initialize my own FP
   sub     sp, sp, #0   // I create 0 local variable in stack

   /* =======================================
      Translating a = a + 1
      ======================================= */
   ldr     r0, [fp, #8] // r0 = address of parameter
   ldr     r1, [r0]     // Get the value through the address
   add     r1, r1, #1   // r0 = a + 1
   ldr     r0, [fp, #8] // r0 = address of parameter
   str     r1, [r0]     // Assign result to the variable through its address 

   /* ************************************************
      Postlude: break down stack frame
      ************************************************ */
   mov     sp, fp       // De-allocate the local variables
   pop     {fp}         // Restore old FP
   pop     {pc}         // Return 

DEMO:   /home/cs255001/demo/asm/A-pass-by-ref/pass-by-ref.s