1 assembly
with great amounts of help from Andrew Lin’s 20fall 6.004 class notes, I’ve recently reviewed the course.
0 introduction¶
Goal: how to physically implement computation?
1 binary representation¶
- binary representations
- modular arithmetic idea: wheel modulo 2**N
- binary encoding
- two’s complement
2 assembly¶
- microprocessor: comprised of: register file, ALU(computation), main memory
- Assembly: comprised of: computation(arithmetic, comparison, logical, shift), load/store, control transfer
- Three-address instructions: reg-imm instructions, reg-reg instructions,…
- see the pattern behind these instructions
3 procedures¶
Problem: hotw to translate high-level program to RISC-V?
-
Pseudoinstructions: mv, lui, li…
-
Schema
-
compiling simple expressions into RISC-V code
- Assign variables to regs
- tranlate operators into computational instructions
- use reg-imm instructions
-
conditional statements
-
if
1
2
3
4
5# if (expression), then execute (if-body)
compile (expression) into a register xN
beqz xN, endif
compile (if-body) here
endif: -
if-else
1
2
3
4
5
6
7
8# if (expression), then execute (if-body), otherwise execute (else-body)
compile (expression) into a register xN
beqz xN, else
compile (if-body) here
j endif (that is, jump straight to endif)
else:
compile (else-body) here
endif -
while
1
2
3
4
5
6
7
8
9
10
11
12
13
14# do (while-body) while (expression)
compile (expression) into a register xN
beqz xN, endwhile
compile (while-body) here
j while
endwhile
# reduce branched by putting the comparison at the end instead
j compare (ensuring that we still check the (expression) condition first)
loop:
compile (while-body) here
compare:
compile (expression) into a register xN
bnez xN, loop.
-
-
-
calling convention
Problem 1: how to call procedures multiple times without corrupting code?
Example: set function argument registers: x10-x17
Problem 2: how to go back to place wherever we were at in our main code even calling same function multiple times?
Example: remember the return address-> RA register
1
jal ra, label # ra = 4 + procedure call address
Problem 3: save registers for nested procedures
Sol: callee, caller, local storage component(activation record, stack)
Fact: This distinction between caller-saved and callee-saved registers is important to keep in mind – the former is not preserved across function calls, but the latter is, so certain arguments must be saved on the stack to preserve values
-
program counter(reg)
-
Problem: how the instructions look like?
activation records, stack structure(last-in-first-out)
the memory is always available to us, but we need to return it the way that we found it.
-> Caller-saved register, not preserved across calls
-> callee-saved register, preserved
1
2
3
4
5
6
7# push
addi sp, sp, -4
sw a1, 0(sp)
# pop
lw a1, 0(sp)
addi sp, sp, 4 -
nested procedures: use calling conventions
Related reg: call func, ret
-
Fact: data structures are implemented with blocks of memory with words that refer to various addresses.
fact 1: most languages use several distinct memory regions for data: stack, static, heap, text(there is no need to memory it.)
fact 2: In RISC-V, we put the text, static, and heap regions in memory consecutively, starting from the smallest address 0x0; in contrast, the stack starts from the highest address 0xFF…F and grows towards lower addresses
Specific pointers: stack pointer, global pointer(static), program counter(current line of code executing)
Problem: how this related to inputs and outputs?
-
memory mapped IO(MMIO): special dedicated address
some issues remained? waiting for labs