Pointers
Compiler Implementation
COP-3402
Table of Contents
Pointer operations in SimpleIR
Reference
t1 := &x
Store the address of x (not the value) in t1.
Dereference
t2 := *t1
t1 is an address. Take the value of memory at the address and store it in t2.
Dereference assignment
*t1 := 11
t1 is an address. Store the value 11 at that address.
Complete example
function main localVariables a b x y t1 t2 t3 parameters a b x := 8 y := 9 t1 := &x t2 := *t1 *t1 := 11 t3 := x return x end function
What is the value of x that gets returned?
- x gets 8
- t1 gets the address of x
- 11 gets stored at the address given by t1, which is the address of x
- x's value is then 11
Local variables
Recall local variables stored at %rbp
Symbol table
localVariables a b x y t1 t2 t3
| Variable | Offset |
|---|---|
| a | -16 |
| b | -24 |
| x | -32 |
| y | -40 |
| t1 | -48 |
| t2 | -56 |
| t3 | -64 |
mov -16(%rbp), %rax # load a into %rax
Memory layout
(Diagram)
- Layout of local variables in memory
- Give numeric addresses to each frame entry.
- Show %rbp
Assignment
How does assignment work in assembly?
Use an offset from %rbp
mov $8, -32(%rbp)
Getting (referencing) a pointer
t1 := &x
Stack frame, with addresses
How do we get the address?
- What will hold the stack frame address?
- What's the offset?
- Assembly operations to compute the address?
Computing the address
- Start with %rbp
- Add the offset (it's negative so it's equivalent to subtraction)
- Store the result
Does this involve the value of the address in anyway?
A little easier to see in when looking at the stack frame
Computing the address
(Diagram)
Assembly code
Assume the following offsets (see the symbol table)
| Variable | Offset |
|---|---|
| x | -32 |
| t1 | -48 |
Assembly code
mov %rbp, %rax # start with stack frame address
add $-32, %rax # add the offset of the referenced var (x)
mov %rax, -48(%rbp) # store the result in the assigned var (t1)
(Diagram)
Dereferencing a pointer
t2 := *t1
What's the value of t2?
- If t1 = 260
- If t1 = 260 and address 260 holds the value 10?
Following an address
What assembly instructions loads a value from an address?
Register indirect mov
mov (%rax), %rbx
(%rax) here means load the value at the address given in %rax.
Computing the address
- Get the value of the de-ref'ed variable (the address)
- Get the value of memory at that address
- Store that the value of memory at that address
Computing the address
(Diagram)
Assembly code
Assume the following offsets
| Variable | Offset |
|---|---|
| x | -32 |
| t1 | -48 |
| t2 | -56 |
Assembly code
mov -48(%rbp), %rax # value of the deref'ed variable (t1)
mov (%rax), %rbx # the value in memory at address %rax (*t1)
mov %rbx, -56(%rbp) # store the result in the assigned var (t2)
Notice how the value of x is the same as the value of *t1. Why is that?
Show on stack frame why this is the case.
Pointer assignment in SimpleIR
Dereference assignment
*t1 := 11
t1 is an address. Store the value 11 at that address.
Stack frame layout
function main localVariables a b x y t1 t2 t3 parameters a b x := 8 y := 9 t1 := &x t2 := *t1 *t1 := 11 t3 := x return x end function
Stack frame diagram, same as prior lecture
Assigning to a dereferenced pointer
*t1 := 11
Stack frame, with addresses
- What's the value of t1?
- What's the value of *t1?
Following an address
What assembly instruction stores a value from to address?
Register indirect mov
mov %rbx, (%rax)
(%rax) here means store the value at the address given in %rax.
Computing the address
- Get the value of the variable (the address)
- Get the value of memory at that address
- Store that the value of memory at that address
- Add the offset (it's negative so it's equivalent to subtraction)
- Store the result
Computing the address
(Diagram)
Assembly code
Assume the following offsets
| Variable | Offset |
|---|---|
| t1 | -48 |
Assembly code
# *t1 := 11
mov -48(%rbp), %rax # value of the deref'ed variable (t1)
mov $11, %rbx # value of the right-hand side (11)
mov %rbx, (%rax) # store the result in the address (*t1)
Complete example
SimpleIR
function main localVariables a b x y t1 t2 t3 parameters a b x := 8 y := 9 t1 := &x t2 := *t1 *t1 := 11 t3 := x return x end function
Assembly
.file "stdin"
.section .note.GNU-stack,"",@progbits
.text
.globl main
.type main, @function
main:
# prologue, update stack pointer
pushq %rbp # save old base ponter
movq %rsp, %rbp # set new base pointer
push %rbx # %rbx is callee-saved
# allocate stack space for locals
sub $56, %rsp
# move register parameter a to local variable
mov %rdi, -16(%rbp)
# move register parameter b to local variable
mov %rsi, -24(%rbp)
# assign 8 to x
mov $8, %rax
mov %rax, -32(%rbp)
# assign 9 to y
mov $9, %rax
mov %rax, -40(%rbp)
# ref x to t1
mov %rbp, %rax
add $-32, %rax
mov %rax, -48(%rbp)
# deref t1 to t2
mov -48(%rbp), %rax
mov (%rax), %rbx
mov %rbx, -56(%rbp)
# assignderef 11 to t1
mov -48(%rbp), %rax
mov $11, %rbx
mov %rbx, (%rax)
# assign x to t3
mov -32(%rbp), %rax
mov %rax, -64(%rbp)
# set return value
mov -32(%rbp), %rax
# epilogue
add $56, %rsp
pop %rbx # restore %rbx
pop %rbp # restore old base pointer
ret
Diagram
(Diagram)
Coding Templates
# reference
mov %rbp, %rax
add $OPERAND_OFFSET, %rax
mov $rax, DESTINATION_OFFSET(%rbp)
# dereference
mov OPERAND_OFFSET(%rbp), %rax
mov (%rax), %rbx
mov %rbx DESTINATION_OFFSET(%rbp)
# derefence assignment
mov DESTINATION_OFFSET(%rbp), %rax
mov OPERAND, %rbx
mov $rbx, ($rax)