Browse Source

more on functions

Jeremy Siek 9 years ago
parent
commit
f90564a7c6
1 changed files with 59 additions and 11 deletions
  1. 59 11
      book.tex

+ 59 - 11
book.tex

@@ -14,6 +14,7 @@
 \usepackage{xypic}
 \usepackage{semantic}
 \usepackage{wrapfig}
+\usepackage{multirow}
 
 %% For pictures
 \usepackage{tikz}
@@ -3035,8 +3036,13 @@ the element at index $0$ of the 1-tuple.
 This chapter studies the compilation of functions (aka. procedures) as
 they appear in the C language. The syntax for function definitions and
 function application (aka. function call) is shown in
-Figure~\ref{fig:r4-syntax}, where we define the $R_4$ language.  These
-functions are first-class in the sense that a function pointer is data
+Figure~\ref{fig:r4-syntax}, where we define the $R_4$ language.
+Programs now start with zero or more function definitions.  The
+function names from these definitions are in-scope for the entire
+program, including all other function definitions (so the ordering of
+function definitions does not matter). 
+
+Functions are first-class in the sense that a function pointer is data
 and can be stored in memory or passed as a parameter to another
 function.  Thus, we introduce a function type, written
 \begin{lstlisting}
@@ -3095,6 +3101,9 @@ we return the \code{42}.
 \label{fig:r4-function-example}
 \end{figure}
 
+
+
+
 \section{Functions in x86}
 
 The x86 architecture provides a few features to support the
@@ -3126,7 +3135,25 @@ locations for passing arguments, following the conventions used by
 be passed in registers, using the registers \code{rdi}, \code{rsi},
 \code{rdx}, \code{rcx}, \code{r8}, and \code{r9}. If there are more
 than six arguments, then the rest must be placed on the stack, which
-we call \emph{stack arguments}.
+we call \emph{stack arguments}, which we discuss in the following
+paragraphs. Continuing on the topic of registers, each function may
+need to use all the registers for storing local variables, frame base
+pointers, etc. so when we make a function call, we need to figure out
+how the two functions can share the same register set without getting
+in each others way. The convention for x86-64 is that the caller is
+responsible freeing up some registers, the \emph{caller save
+  registers}, prior to the function call, and the callee is
+responsible for saving and restoring some other registers, the
+\emph{callee save registers}, before and after using them. The
+caller save registers are 
+\begin{lstlisting}
+rdx rcx rsi rdi r8 r9 r10 r11
+\end{lstlisting}
+while the callee save registers are 
+\begin{lstlisting}
+rbx r12 r13 r14 r15
+\end{lstlisting}
+UNDER CONSTRUCTION
 
 Recall from Section~\ref{sec:x86-64} that the stack is also used for
 local variables, and that at the beginning of a function we move the
@@ -3141,16 +3168,37 @@ the function. In preparation for a function call, we offset from
 argument in \code{0(\%rsp)}, the second in \code{8(\%rsp)}, and so on.
 
 Upon calling the function, the stack arguments are retrieved by the
-callee using the base pointer \code{rbp} (recall
-Figure~\ref{fig:frame}).  The address \code{16(\%rbp)} is the location
-of the first stack argument, \code{24(\%rbp)} is the address of the
-second, and so on.
-
-
-\marginpar{\scriptsize
-to do: talk about caller and callee-save registers. --Jeremy}
+callee using the base pointer \code{rbp}. The address \code{16(\%rbp)}
+is the location of the first stack argument, \code{24(\%rbp)} is the
+address of the second, and so on. Figure~\ref{fig:call-frames} shows
+the layout of the caller and callee frames. Notice how important it is
+that we correctly compute the maximum number of arguments needed for
+function calls; if that number is too small then the arguments and
+local variables will overlap in memory!
 
+\begin{figure}[tbp]
+\centering
+\begin{tabular}{r|r|l|l} \hline
+Caller View & Callee View & Contents       & Frame \\ \hline
+8(\key{\%rbp})  & & return address & \multirow{5}{*}{Caller}\\
+0(\key{\%rbp})  &  & old \key{rbp} \\
+-8(\key{\%rbp}) &  & variable $1$ \\
+\ldots & & \ldots \\
+$-8k$(\key{\%rbp}) &  & variable $k$ \\
+ & &  \\
+$8n-8$\key{(\%rsp)} & $8n+8$(\key{\%rbp})& argument $n$ \\
+& \ldots           & \ldots \\
+0\key{(\%rsp)} & 16(\key{\%rbp})  & argument $1$   & \\ \hline
+& 8(\key{\%rbp})   & return address & \multirow{5}{*}{Callee}\\
+& 0(\key{\%rbp})   & old \key{rbp} \\
+& -8(\key{\%rbp})  & variable $1$ \\
+&  \ldots          & \ldots \\
+& $-8m$(\key{\%rsp})   & variable $m$\\ \hline
+\end{tabular}
 
+\caption{Memory layout of caller and callee frames.}
+\label{fig:call-frames}
+\end{figure}