bottom text
Quiz 0x7
Same rules apply
Reminders
● Exam 0x2 Next Friday (Nov 1st)!
○ Same procedure as Exam 0x1
○ Bring an ID (UT ID is fine)
○ Cheat sheets – you will be provided with a list of ARM
instructions
● AC Lab Week 2 Due Next Sunday (Nov 3rd)!
○ For week 2, only 1 slip day can be used.
○ Please be sure to download the QoL updates in post #1052!
● SE Lab Week 1 Released Next Friday (Nov 1st)!
● Disable VSCode Extensions on AWS Machines :)
Quiz Review
Quiz 0x6
D:
A. Valid
B. Invalid; immediate cannot go there
C. Invalid; can’t use W and X in same instruction
D. Invalid; can’t use an immediate and shift for ADD
STUR X10, [SP, #32] will change no registers
STUR X10, [SP, #32]! will change SP (not a GPR)
C, V – no chance of overflow when adding 0
N – will be set if the msb of X0 is 1
Z – will be set if X0 is 0
assembly
.c
Code gen part 2
If there are questions about codegen for basic types
then speak now or forever hold your peas
General strategy for codegen
● You have the C code
● Convert into code that is more similar to assembly (how?)
○ Use labels and gotos
○ Use the “templates” we are about to show you for control structures
● Convert into actual assembly code.
Code gen for Conditionals (if statements)
● if-then-else
○ Break it down to “if not condition, skip to else. Otherwise do the then”.
○ This can be implemented in C with gotos
int y = 0;
// prior code l_ifstatement:
int y = 0; if (x != 5)
if (x == 5) { goto l_else
y = 10; y = 10;
} else {
goto l_done
y = 1;
} l_else:
// other code y = 1;
l_done:
// other code
Code gen for Conditionals: Assembly
int y = 0;
-
f movz w1, #0 Y 0
=
l_ifstatement: cmp w0, #5 ↓ !S
if (x != 5)
-
-
[
if Tive
b.ne
-
z
.l_else
-
goto l_else // then part
G
-
y = 10; movz w1, #10
-y
10=
-
goto l_done b .l_done
l_else: .l_else: // else part
y = 1; movz w1, #1 y =
- -
l_done: .l_done:
// other code // other code
Let’s compare these two things
Codegen: Looping: Do-while subs Sets flags
& that are checked
[
First we do 1 iteration, then we do the check. ● Why isn’t there a CMP here?
● Does “foo” take any
// some prior code
mov w19, #5 parameter(s)?
.loop: ● Can we reconstruct the C
mov w1, w19 code?
(
mov x0, x20
bl foo function call into for
0) [
>
- -
subs w19, w19, #1 While (X ! =
-
b.ne .loop ↑ x
--j
-
ret x
too () ;
3
c
[ Whileloo,
,
asm( while while
Codegen: Looping: Jump-to-middle
-
Notice how we first jump to the test label
mov w1, #5 then
b .test
jump and
- -
condition to
-
.loop_body: check
bl printf
sub w1, w1, #1 keep going
.test:
C cmp
b.ne
-
w1, #0scond
.loop_body // jump to the loop body
.done: -
ret
-
Small note: we left out an instruction called ADRP, you’ll learn about it next week
so we left them out for clarity
Codegen: Looping: Guarded-Do
Here the initial unconditional jump is replaced with a copy of the condition test
mov w1, #5
cmp w1, #0 // here we’re doing the test
b.eq .done
Check first and
.loop_body:
then
bl printf Loop
sub w1, w1, #1
.test:
cmp w1, #0
b.ne .loop_body // jump to the loop body
.done:
ret
Small note: we left out an instruction called ADRP, you’ll learn about it next week
so we left them out for clarity
garded do it
loop runs 0 times
~ While loop save on a
jump to
label
to middle
jump , it loop runs more than 0 times
do while
o
N loop save on a
cmp instr
Codegen: Advanced
256
4
x
-
long array_sum(unsigned a[256]){
-1024 -
array_sum: sum = O
long sum = 0;E 7 mov x8, xzr
for(int i = 0; A
T
i < 256; i++){ add x1, x0, #1024
-
sum += a[i]; idx a .loop:
accessing
-
-
-
w10, [x0], #4J
-
} add ldr
return sum; Set sum some ali] + cmp
= x0, x1
-
} inst add x8, x8, x10 Sum
sumi)
-- -
b.ne .loop
● Notice that “256” doesn’t show up. mov
-
x0, x8
2
● Is it ok that the “add” is between the
“cmp” and the “b.ne”? Yes since
ret
-
-
add doesn't change
flags
L
- xi
lar wo , (10) #1 ali]
,
cmp =Os
+ 56
i
-
r10
W
X10
////
mouz
H) 16
always means
X
Idor >
-
unscaled ,
not taking into account
scaled
size of operand
Idr >
-
taking
- >
-
it into account
Y
# I be
might not justI byte
offset always must be offset
multiple of 8
Codegen: Advanced, Equivalent C Code
long array_sum(unsigned a[256]){ array_sum:
long sum = 0; mov x8, xzr
unsigned *end = a + 256; add x1, x0, #1024
- -
unsigned num; .loop:
loop: ldr w10, [x0], #4
num = *a; cmp x0, x1
a++; add x8, x8, x10
sum += num; b.ne .loop
J
if (a != end) mov x0, x8
goto loop; ret
return sum;
}
RET == BR X50
use
Procedure Calls onteluna ,
↑
The ‘BL’ instruction allows us to branch to another location, but keep a address
E
-
“bookmark” (called a Return Address) so we can come back later. => Instruction
- after
LR - On its own, though, this isn’t enough to form a robust system for procedure func
calls. How do we handle parameters? Return values? Recursion? Register call
-
allocation?
X30
- To solve all these issues, we define a Procedure Call Standard that contains
all the common protocols for how to call subroutines.
- IMPORTANT: If you do any Googling/GPT’ing about this, be sure to look only
at AARCH64 information!
- Other architectures (like x86) have their own procedure call standards which are very different
from A64’s.
Recall
P calling Q
-stores the addr of instr to return to
>
- pointer to your stack frame
#
Before we call funchons , we
put our
parameters in these
registers
Before we return , we have c
a tura
value , required to
put in Xo
Procedure Call Standard: Register Management
Q
Register management: Some registers are “callee-saved”, meaning the Callee
must save them before using them. Others are “caller-saved”, meaning the Caller
must save them before calling a subroutine. P save these was is les before
Example: P calls Q, P is using X19, X20, X0, X1, X2. Q will use X19, X1. A9single
parameter is passed in X0, and Q will return a value through X0. going ,ho Q
- P has to save X0, X1, and X2 before the function call. Q has to save X19.
- Why did P save X2 even though Q doesn’t mess with it? Because P doesn’t
know what Q does, it only knows that P needs X2.
- Most compilers prefer to use callee-saved registers. Why? Because this leads
to less unnecessary overhead (like with X2 in this example. Notice how Q
didn’t need to save X20.) -
Doesn't need X20 in Q
main [
X
find as in+ b)
·i to
int a ;
intbi
Procedure Call Standard: Stack Frames
- Stack Frames hold local data, saved registers, and the Frame Record
- Pointed to by SP
- Can also store parameters, but that is beyond our scope
- SP always has to be a multiple of 16, enforced by the CPU
ro-r7 >
-
parameter registers ,
extra parameters will be
pur on stack
P calls &
.
p
I
# stack downward
growns
FP inside frame record
Frame Record >
-
+
Procedure Call Standard: Stack Frames: Frame Record
Return Address to exit from P
From AAPCS section 6.4.6: “Code shall
NULL (indicates end of linked list)
construct a linked list of stack-frames. Each
-
frame shall link to the frame of its caller with a <local stuff for P’s stack frame>
Frame Record.” Return Address to exit from Q
“The lowest addressed double-word shall point Pointer to P’s Frame Record
to the previous frame record and the highest
↑
<local stuff for Q’s stack frame>
addressed double-word shall contain the
Return Address to exit from R
Return Address of the current function call.“
Pointer to Q’s Frame Record
Usually at the top of a stack frame.
<local stuff for R’s stack frame>
Example: P calls Q calls R. P is the root call.
FP register (x29)
p :
00 : 31 Q (R = 0x100th =
OXIOY
I
Q:
%0:b
a R = R = 0x200 + y
=
0x204
⑪
rit ? >
-
read OxIOU - still inside
Q function NOT
In p!
LR = 0x204
ret
0x300 :
Tread 0x204
#us
-
Codegen: Prologues and Epilogues
x29
Idr
Esp]
.
=
Function Prologues have a few required tasks:
↓ Ida
- Csp #8]
Open up space on the stack (remember, the stack grows downward!)
,
= x30
- Write the Frame Record onto the stack
- Save any callee-saved registers
Function Epilogues do the inverse of Prologues, undoing the Prologue.
X
Very commonly we see the ‘stp’/’ldp’ instructions used for Prologue/Epilogue
stack
respectively.
Impityfour X create frame record
stp x29, x30, [sp, -48]! // open stack space, write frame record
-
mov x29, sp // sp now points to frame record -
str x19, [sp, 16] // save x19
& save X19 on stack
Annotate this code on whiteboard/ipad.
Mystery Function
or a chalkboard :)
For extra Fall23
practice , go ra
mystery:
+
Sp'24 Exan 2
Y Prologue
stp x29, x30, [sp, -48]!
mov x29, sp T
values into stack have
str x19, [sp, 16] ->
put
parameter
a str x0, [sp, 40]
ldr x0, [sp, 40]
cmp x0, 1 - - cases to to if branch
go XOX1 we
E b.hi
ldr
b
.L2 -
3
x0, [sp, 40]
.L3
parameter
1
.L2: > register
&
-
ldr
sub
x0, [sp, 40]
x0, x0, #1 Exo - = 1
i bl mystery >
-
calling mystery
(xO -
1)
5
mov x19, x0
XO value X19
ldr x0, [sp, 40] -
presenting in
sub x0, x0, #2
bl mystery 3 XO -
2
epilogues
(XO-2) + stored X
calling mystery
in
add x0, x19, x0
.L3: -
3 stack frame
ldr x19, [sp, 16]
ldp x29, x30, [sp], 48 done wh huchon ,
remove
ret ref
↑ return 1;
add XO
,
X19 ,
XO
x19 mystery (x0 - 1)
=
x0
mystery (X0- 2)
=
XO =
mystery (x0-1) +
mystery (X0-2)
(XO-17 (X0-2)
return
mystery mystery
+
-
cmp XO ,
if (xoc = 1) b hi
.
L2
Leturn 1;
&
else 3
return
mystery (xO-1) mystery (xO-2) ;
+
S
Mystery Function: Stack Trace
Trace the state of the CPU, stack, SP/FP/LR through the execution of the call:
mystery(3).
Assume SP starts with value 0x1000, LR starts with 0x2000, and FP starts with
value 0x1020.
AC Week 2 Intro