Skip to content

Commit cc056f6

Browse files
committed
Update notes for Shakedown and make public (still some work)
1 parent 1375344 commit cc056f6

File tree

2 files changed

+73
-5
lines changed

2 files changed

+73
-5
lines changed

www/notes.scrbl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,4 @@
2020
@include-section{notes/knock.scrbl}
2121
@include-section{notes/graphviz.scrbl}
2222
@include-section{notes/loot.scrbl}
23-
@include-section{notes/mug.scrbl}
23+
@include-section{notes/shakedown.scrbl}

www/notes/shakedown.scrbl

Lines changed: 72 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -216,14 +216,82 @@ In short, a calling convention specifies @emph{at least} the following:
216216
@item{What things is the @emph{callee} responsible for keeping track of?}
217217
]
218218

219+
Note that there are many ways to solve this coordination problem! The pro and
220+
con of using a convention is that it's not really up to us, instead we just
221+
look up what the convention specifies. For Shakedown we're only going to
222+
implement calling C functions with (up to 6) integer arguments. As mentioned
223+
above, this is not a restriction from the System V ABI, which desscribes how to
224+
pass more than 6 arguments as well as arguments of various types.
225+
226+
The calling convention specifies that the first 6 integer arguments are passed
227+
@emph{in left to right order} in the following registers:
228+
229+
@verbatim|{
230+
rdi, rsi, rdx, rcx, r8, and r9
231+
}|
232+
233+
What this means is that in order to call a C function @tt{f(int x, int y)}, we
234+
should put the value of @tt{x} in @tt{rdi} and @tt{y} in @tt{rsi}, and so on.
235+
This means that if you were using any of these registers, you need to save
236+
those values elsewhere. Which brings us to the next two concerns: who is in
237+
charge of keeping track of what?
238+
239+
240+
@subsection[#:tag-prefix "shakedown"]{Who saves what?}
241+
242+
In calling conventions there are @emph{caller}-save and @emph{callee}-save
243+
registers. This determines which `side' of the function call is responsible for
244+
keeping track of what the value stored in a register should be once the
245+
call/return cycle of a function call is complete.
246+
247+
@emph{Caller}-save registers are the ones that a called function can assume
248+
they are safe to use, with no consequences. Because of this, if you are calling
249+
a function (i.e. you are the @emph{caller}) and you care about what is stored
250+
in one of these registers, it is your responsibility to save it elsewhere
251+
(could be on the stack, as long as it's not in another caller-save register).
252+
@emph{Callee}-save registers are registers that can be used to store
253+
information before @emph{calling} a function. If the function being called (the
254+
@emph{callee}) wants to use any of these registers, it is that function's
255+
responsibility to remember the value in that register in some way (perhaps
256+
putting it on the stack) and restoring that register to its original value
257+
before returning.
258+
259+
The @emph{callee}-save registers are the following:
260+
261+
@verbatim|{
262+
rbp, rbx, and r12-r15 (inclusive)
263+
}|
264+
265+
All other registers are @emph{caller}-save. The one exception is the register
266+
@{rsp}, which is expected to be used by both the caller and the callee to
267+
manage the stack in concert, so it's not `saved' by either the caller or the
268+
callee.
269+
270+
The `ownership' of the various registers is described in Section 3.2.1 of the
271+
System V ABI document.
219272

273+
@subsection[#:tag-prefix "shakedown"]{Securing the result}
220274

275+
The System V ABI specifies that at the end of the function's execution it is
276+
expected to put the first @emph{integer} machine word of its result (remember
277+
that in in C you can return a struct that contains more than one machine word)
278+
in @tt{rax}. We've already been following this part of the convention! In fact,
279+
this is how our generated code has communicated its result with the runtime
280+
system, we just chose to use @tt{rax} for the result of @emph{all} intermediate
281+
computations as well.
221282

222-
@subsection[#:tag-prefix "shakedown"]{Determining the point of the argument}
283+
This is described near the end of Section 3.2.3 (page 22) of the System V ABI
284+
document.
223285

224-
We can now discuss
225286

226-
@subsection[#:tag-prefix "shakedown"]{Securing the result}
287+
@subsection[#:tag-prefix "shakedown"]{But wait, there's more!}
227288

228-
@codeblock-include["shakedown/compile.rkt"]
289+
Earlier we mentioned that a calling convention would specify @emph{at least}
290+
the three things above. The System V ABI for x86_64 also specifies that our
291+
stack pointer (@tt{rsp}) should be aligned to 16 bytes! (this is described in
292+
Section 3.2.2 of the System V ABI document). We've never worried about the
293+
alignment of our stack before, so this will also need consideration.
229294

295+
@codeblock-include["shakedown/compile.rkt"]
296+
@filebox-include[fancy-make "shakedown/Makefile"]
297+
@filebox-include["shakedown/clib.c"]

0 commit comments

Comments
 (0)