UP | HOME

Local Variables
Compiler Implementation
COP-3402 COP-3402

What is a function?

How do we implement functions?

With local state that works with recursion?

Code generation for simple functions

  • No parameters
  • No locals
  • Constant return values

main.ir:

function main
phonyvar := call func
return 10

func.ir:

function func
return 5

Generation approach

  • function NAME
    • Declare and label NAME
    • Generate prologue
    • Generate epilogue (after function body)
  • call NAME
    • Generate call NAME
  • return NUM
    • Generate mov $NUM, %rax

(Diagram: code generation)

        .file "stdin"
        .section .note.GNU-stack,"",@progbits
        .text
        .globl main
        .type main, @function
main:
        pushq	%rbp
        movq	%rsp, %rbp
        push	%rbx
        call	func
        mov	$10, %rax
  pop %rbx
        mov	%rbp, %rsp
        pop	%rbp
        ret
        .file "func.ir"
        .section .note.GNU-stack,"",@progbits
        .text
        .globl func
        .type func, @function
func:
        pushq	%rbp
        movq	%rsp, %rbp
        push	%rbx
        mov	$5, %rax
  pop %rbx
        mov	%rbp, %rsp
        pop	%rbp
        ret

(Diagram: runtime behavior)

  • call main (no args), pushes return address
  • main sets up stack frame
  • call func (no args), pushes return address
  • func sets up stack frame
  • return movs to %rax
  • func tears down stack frame
  • ret pops address and branches
  • return movs to %rax
  • ret pops address and branches

Local variables

Where are locals stored?

Application binary interface (ABI)

Stored in the stack frame, after the old base pointer

Example

function myfunc
localvars var1 x retval
x := 1
retval := x
return x
  • Three locals
  • Two assignments

How to translate locals to assembly?

Allocate locals on the stack

  • Assembly has no named function-local variables (stack-allocated)
  • Store in stack frame
  • Access via offsets from base pointer
  • Fixed set of variables (and types) means same offsets every call

How do we track a variable's memory location?

  • Generate code to allocate space on stack
  • Use offsets from base pointer for runtime accesses

Symbol table

Compiler maps variable names to base pointer offsets

Use that table to find the offset whenever we encounter a local variable

Example

(Diagram: Stack frame for myfunc)

function myfunc
localvars var1 x retval
x := 1
retval := x
return x

Assignment

Constants

x := 1

Move immediate

Store integer 1 in a register

mov $1, %rax

Move to a register

Overwrites %rbp. Not what we want to do

mov %rax, %rbp

Move to an address given by a register

Overwrites value at address held in %rbp.

mov %rax, (%rbp)

What part of the stack frame is at address %rbp?

Move to an offset from an address given by a register

Overwrites value at address held in %rbp + -16.

mov	%rax, -16(%rbp)

What part of the stack is at %rbp + -16 for myfunc?

Complete assignment

SimpleIR

x := 1

becomes assembly

mov	$1, %rax
mov	%rax, -16(%rbp)

Using a variable

What are the offsets from %rbp of retval and x?

retval := x

-16 and -24

How do we copy the value of x's memory location?

Overwrites value at address held in %rbp + -16.

mov	-16(%rbp), %rax

Load the value of x's memory location to a temporary register

How do we store something to retval's memory location?

mov	%rax, -24(%rbp)

Complete assignment from a variable

SimpleIR

retval := x

becomes assembly

mov	-16(%rbp), %rax
mov	%rax, -24(%rbp)

Complete myfunc example

Assume myfunc is called. It has no parameters.

function myfunc
localvars var1 x retval
x := 1
retval := x
return x

Run-time behavior

Author: Paul Gazzillo

Created: 2024-11-12 Tue 08:08

Validate