Lecture 02 - Memory, Stack and Function Calls
Course: Computer Architectures
Topics
Address vs value
A label names a memory location.
Example:
Val_A: .word 10Keep these separate:
Val_A = address
memory[Val_A] = stored valueLoad address
la x1, Val_Aputs the address of Val_A into x1.
Load word
lw x1, 0(x1)loads the word stored at address:
x1 + 0Store word
sw x3, 0(x4)stores the value from x3 at:
x4 + 0Why offset(base)?
RISC-V loads and stores use:
offset(base_register)This is useful for arrays.
Example:
lw x5, 0(x1)
lw x6, 4(x1)
lw x7, 8(x1)With 4-byte words, these can access consecutive elements.
Walking through arrays
If x1 points at the current word:
addi x1, x1, 4moves the pointer to the next word.
That is why vector code often advances several pointers by 4 each iteration.
Function calls
ra is the ABI name for:
x1A function call commonly saves the address to return to in ra.
Example:
jal ra, functioncall function is a convenient pseudo-instruction for calling a subroutine.
Returning
retreturns using the address stored in ra.
Why save ra?
If function A calls function B, B’s call will use ra too.
So A must preserve its own return address if it needs it afterward.
Simplified example:
funcA:
addi sp, sp, -4
sw ra, 0(sp)
call funcB
lw ra, 0(sp)
addi sp, sp, 4
retStack idea
The stack grows by moving sp to a new memory location before saving data.
Example:
initial sp = 1000
A saves at 996
B saves at 992
C saves at 988This prevents nested calls from overwriting each other’s saved return addresses.
The stack is LIFO:
main -> A -> B -> C
C -> B -> A -> mainQuestions to review
- What is the difference between
laandlw? - Why is
0(x1)not redundant? - Why does an array pointer increase by 4 for
.worddata? - Why must a non-leaf function preserve
ra?