|
@@ -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}
|
|
|
|
|
|
|
|
|
|