Pointers
Pointer operations in Slang
Reference
t1 = &xStore the address of x (not the value) in
t1.
Dereference
t2 = *t1t1 is an address. Take the value of memory at the
address and store it in t2.
Dereference assignment
*t1 = 11t1 is an address. Store the value 11 at
that address.
Complete example
begin main(a, b)
locals x, y, t1, t2, t3
x = 8
y = 9
t1 = &x
t2 = *t1
*t1 = 11
t3 = x
return x
endWhat is the value of x that gets returned?
xgets 8t1gets the address ofx- 11 gets stored at the address given by
t1, which is the address ofx x’s value is then 11
Local variables
Recall that local variables and parameters are stored at offsets from
%rbp
Symbol table
begin main(a, b)
locals x, y, t1, t2, t3| Variable | Offset |
|---|---|
| x | -16 |
| y | -24 |
| t1 | -32 |
| t2 | -40 |
| t3 | -48 |
| a | -56 |
| b | -64 |
mov -16(%rbp), %rax # Load x into %raxMemory 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 := &xStack 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 | -16 |
| t1 | -32 |
Assembly code
mov %rbp, %rax # Start with stack frame addressadd $-16, %rax # Add the offset of the referenced var (x)mov %rax, -32(%rbp) # Store the result in the assigned var (t1)(Diagram)
Dereferencing a pointer
t2 = *t1What’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 | -16 |
| t1 | -32 |
| t2 | -40 |
Assembly code
mov -32(%rbp), %rax # Value of the deref'ed variable (t1)mov (%rax), %rbx # The value in memory at address %rax (*t1)mov %rbx, -40(%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 Slang
Dereference assignment
*t1 = 11t1 is an address. Store the value 11 at
that address.
Stack frame layout
begin main(a, b)
locals x, y, t1, t2, t3
x = 8
y = 9
t1 = &x
t2 = *t1
*t1 = 11
t3 = x
return x
endStack frame diagram, same as prior lecture
Assigning to a dereferenced pointer
*t1 = 11Stack 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 = 11mov -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
Slang
begin main(a, b)
locals x, y, t1, t2, t3
x = 8
y = 9
t1 = &x
t2 = *t1
*t1 = 11
t3 = x
return x
endAssembly
.file "stdin"
.section .note.GNU-stack,"",@progbits
.text
.globl main
.type main, @function
main:
# Prologue, ypdate stack pointer
pushq %rbp # Save old base ponter
movq %rsp, %rbp # Set new base pointer
push %rbx # Save old %rbx
sub $56, %rsp # Allocate stack space for locals
mov %rdi, -16(%rbp) # Move parameter a to local variable
mov %rsi, -24(%rbp) # Move parameter b to local variable
# x := 8
mov $8, %rax
mov %rax, -32(%rbp)
# y := 9
mov $9, %rax
mov %rax, -40(%rbp)
# t1 := &x
mov %rbp, %rax
add $-32, %rax
mov %rax, -48(%rbp)
# t2 := *1
mov -48(%rbp), %rax
mov (%rax), %rbx
mov %rbx, -56(%rbp)
# t1 := 11
mov -48(%rbp), %rax
mov $11, %rbx
mov %rbx, (%rax)
# t3 := x
mov -32(%rbp), %rax
mov %rax, -64(%rbp)
# Set return value
mov -32(%rbp), %rax
# Epilogue
add $56, %rsp # Deallocate stack space for locals
pop %rbx # Restore %rbx
pop %rbp # Restore old base pointer
ret # ReturnDiagram
(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)