ITSC 2181 - Module 6 Unit 4/5 Functions in RISC-V
Functions in RISC-V Introduction
RISC-V Architecture: Involves using functions to improve code readability and efficiency.
Creates functions to handle repetitive tasks, making code modular.
Programming Constructs:
Example C Code - Simple Conditional:
if (a != b)
i = a - b;
else
i = 0;
RISC-V Assembly Equivalent:
lw x1, 0(x11) # load a
lw x2, 0(x12) # load b
beq x1, x2, else # branch if a == b
sub x5, x1, x2 # x5 = a - b
sw x5, 0(x15) # store result in i
beq x0, x0, exit # unconditionally jump to exit
else:
sw x0, 0(x15) # store 0 in i
exit:
Function Definition in Assembly
Calling Functions:
Arguments must be passed through registers.
Control transfer instructions (e.g.,
jal) to jump to function code block (branching).Allocate storage for function execution and manage return values.
Perform function operations.
Store function result in a register.
Return to instruction after control transfer (exit function code block).
3 Main Things Needed:
Assembly instructions
Control transfer needed to go back and forth between calling function and function that is being called
Data storage
Arguments and return values from functions must be stored somehow in registers and/or memory
Stack memory to manage data allocation
Callee vs. Caller Functions:
Caller: Starts execution of a function (e.g.,
main()in C).Callee: Performs operations for the caller (print a statement, compute a value, etc), using temporary registers (
tregisters).
Stack Management in RISC-V
4 Parts of Memory Layout Components:
Text: Code Section, where instructions are stored.
Static Data: Global variables.
Dynamic Data: Heap for dynamic memory (e.g.,
malloc()in C).Stack: Automatic storage for a function; used for function local variables and return addresses, follows Last-In-First-Out (LIFO) principle.
Register Usage in Functions
Important Registers:
x0/zero: Always 0.ra: Return address register for storing address to return to after function call.sp: Stack pointer, points to the current stack location.s0-s11: Saved registers for persistent values across function calls.t0-t6: Temporary registers for intermediate values.a0-a7: Argument registers for passing function arguments and return values.
Jump Instructions for Function Calls
j: Unconditional jump to a specific address.jal: Jump and link; saves return address inra.Tells computer to go to label code block and store first instruction after the jumping to the label in the given register
Used for making function calls
jr: Jump register; jumps to address specified by a register.jalr: Jump and link register; a combination ofjalandjrto return control to caller.Saves address of next instruction in the register, adds immediate value offset to the given source register
E.g.,
jal x1, labelstores the return address inx1and jumps tolabel.
Examples:
jal x1, label # jump to label without saving return address
jalr x1, 0(source register) # jump to the address in source register without saving return
Example of Function Call in C to Assembly
C Function Example:
int loop() {
int sum = 0;
for(int n = 10; n > 0; n--){
sum += n;
}
return sum;
}
Assembly Conversion:
addi s1, x0, 0 # Initialize sum
loop:
beq s0, x0, exit # exit loop if n = 0
add s1, s1, s0 # sum += n
addi s0, s0, -1 # decrement n
jal x0, loop # repeat loop
exit:
Register Name(s) | Usage |
x0/zero | Always holds 0 |
ra | Holds the return address |
sp | Holds the address of the boundary of the stack |
t0-t6 | Holds temporary values that do not persist after functional calls |
s0-s11 | Holds values that persist after function calls |
a0-a1 | Holds the first two arguments to the function or the return values |
a2-a7 | Holds any remaining arguments |
Lab Implementation Notes
Learning objectives include implementing loops and function calls in RISC-V assembly language.
Example projects could include integer accumulation and averaging of arrays.
Use environment calls (
ecall) for outputting values and program termination.
Key Takeaways:
Proper use of the stack and appropriate register management is crucial in assembly programming.
Understanding function calls, local scope, and stack operations are foundational for advanced programming in assembly languages.