CS 452/652 Spring 2022 - Lecture 4
May 12, 2022
prev
next
CPU State
see
ARM Architecure Reference Manual
, Sections A1, A2 (showed PDF Pages 29, 41, 43).
R0-R15 registers
operands for processor operation
special purpose: r13/sp (stack pointer), r14/lr (link register), r15/pc (program counter)
PSR: Processor Status Register
condition codes (N,Z,C,V)
interrupt flags
processor mode
etc.
per-mode instances of ('banked') registers, CPSR vs. SPSR
other instances not directly usable/accessible
but needed for mode switch (more later)
ARM Instructions
mov
- copy register values
str
/
ldr
- store/load registers ↔ memory
stm
/
ldm
- store/load multiple registers
special case: access user registers from exception modes
special case: cpsr := spsr (
ldm
only)
RISC architecture: instructions + operands encoded in 32 bits
Context Switch
"execution state" = context = stack + registers
save / restore execution state
similar to and presents as subroutine call
Subroutine Call
starting point for context switch considerations
call to subroutine: branch-and-link (lr := pc + 4)
bl <immediate>
, OR
blx <register>
(only ARMv5)
return from subroutine (pc := lr)
bx lr
other branching and returning instructions
mov pc, lr
ldr pc, [mem]
ldm [mem], {...,pc,...}
Application Binary Interface (ABI) defines rules for subroutine call:
ARM Call Standard
stack pointer alignment: 8 bytes
argument passing: r0-r3, rest on stack
caller-saved registers (subroutine can overwrite): r0-r3, r12, psr
callee-saved registers (subroutine must preserve): r4-r11, sp
lr is special (modified during branch): both caller- and callee-saved
Stack Switch
simplest form of context switch
used for coroutines, user-level threading, or inside multi-threaded kernel
could be declared as
void StackSwitch(char* newSP, char** oldSP);
implemented in assembler
push callee-saved registers on stack (r4-r11, lr)
save stack pointer into memory location r1
load stack pointer from register r0
pop callee-saved registers from stack
return
seems easy, why?
no mode switch, no register banking
synchronous routine call → ABI rules apply
symmetric invocation
Mode Switch
SP is banked: automatic stack switch
CPSR saved to SPSR
rest of context still needs saving!
asymmetric:
enter_kernel()
vs.
leave_kernel()
potentially multiple variants of
enter_kernel()
for system call, interrupt...
system call: synchronous (ABI rules apply)
interrupt: asynchronous (no ABI guarantees)
SWI Instruction
user call into kernel ("software interrupt"); implements system calls
swi N
hard-coded branch to
0x08
after-reset contents of
0x08
:
ldr pc, [pc, #0x18]
branches to value from
pc
-relative memory location
evaluating
pc
in ARM's pipeline results in
pc+8
i.e., branch to destination stored in
0x28
set up SWI: change instruction at
0x08
or branch destination at
0x28
branch to your hard-coded
enter_kernel()
handler