Jeremy Siek 6 vuotta sitten
vanhempi
commit
e188a12bf9
1 muutettua tiedostoa jossa 56 lisäystä ja 54 poistoa
  1. 56 54
      book.tex

+ 56 - 54
book.tex

@@ -1163,20 +1163,14 @@ the operating system starts executing this program.  The instruction
 \lstinline{movq $10, %rax} puts $10$ into register \key{rax}. The
 following instruction \lstinline{addq $32, %rax} adds $32$ to the
 $10$ in \key{rax} and puts the result, $42$, back into
-\key{rax}. Finally, the instruction \lstinline{movq %rax, %rdi} moves the value
-in \key{rax} into another register, \key{rdi}, and
-\lstinline{callq print_int} calls the external function \code{print\_int}, which
-prints the value in \key{rdi}.
-
-The last two instructions---\lstinline{movq $0, %rax} and \key{retq}---finish
-the \key{main} function by returning the integer in \key{rax} to the
-operating system. The operating system interprets this integer as the program's
-exit code. By convention, an exit code of 0 indicates the program was
-successful, and all other exit codes indicate various errors. To ensure that
-we successfully communicate with the operating system, we explicitly move 0
-into \key{rax}, lest the previous value in \key{rax} be misinterpreted as an
-error code.
+  \key{rax}.
 
+The last instruction, \key{retq}, finishes the \key{main} function by
+returning the integer in \key{rax} to the operating system. The
+operating system interprets this integer as the program's exit
+code. By convention, an exit code of 0 indicates the program was
+successful, and all other exit codes indicate various errors.
+Nevertheless, we return the result of the program as the exit code.
 
 %\begin{wrapfigure}{r}{2.25in}
 \begin{figure}[tbp]
@@ -1185,24 +1179,18 @@ error code.
 main:
 	movq	$10, %rax
 	addq	$32, %rax
-	movq	%rax, %rdi
-	callq	print_int
-	movq    $0, %rax
 	retq
 \end{lstlisting}
 \caption{An x86 program equivalent to $\BINOP{+}{10}{32}$.}
 \label{fig:p0-x86}
 %\end{wrapfigure}
 \end{figure}
-%% \margincomment{Consider using italics for the texts in these figures.
-%%   It can get confusing to differentiate them from the main text.}
-%% It looks pretty ugly in italics.-Jeremy
 
-Unfortunately, x86 varies in a couple ways depending on what operating system it
-is assembled in. The code examples shown here are correct on Linux and most
-Unix-like platforms, but when assembled on Mac OS X, labels like \key{main} must
-be prefixed with an underscore.  So the correct output for the above program on
-Mac would begin with:
+Unfortunately, x86 varies in a couple ways depending on what operating
+system it is assembled in. The code examples shown here are correct on
+Linux and most Unix-like platforms, but when assembled on Mac OS X,
+labels like \key{main} must be prefixed with an underscore.  So the
+correct output for the above program on Mac would begin with:
 \begin{lstlisting}
 	.globl _main
 _main:
@@ -1243,11 +1231,8 @@ main:
 	negq	-8(%rbp)
 	movq	$52, %rax
 	addq	-8(%rbp), %rax
-	movq	%rax, %rdi
-	callq	print_int
 
 	addq	$16, %rsp
-	movq    $0, %rax
 	popq	%rbp
 	retq
 \end{lstlisting}
@@ -1352,23 +1337,26 @@ $R_1$ and x86 assembly? Here we list some of the most important the
 differences.
 
 \begin{enumerate}
-\item[(a)] x86 arithmetic instructions typically take two arguments and
-  update the second argument in place. In contrast, $R_1$ arithmetic
-  operations take two arguments and produce a new value.
-
-\item[(b)] An argument to an $R_1$ operator can be any expression, whereas
-  x86 instructions restrict their arguments to integers, registers,
-  and memory locations.
-
-\item[(c)] The order of execution in x86 is explicit in the syntax: a
+\item[(a)] x86 arithmetic instructions typically take two arguments
+  and update the second argument in place. In contrast, $R_1$
+  arithmetic operations take two arguments and produce a new value.
+  An x86 instruction may have at most one memory-accessing argument
+  and some instructions place further restrictions on the kinds of
+  their arguments.
+
+\item[(b)] An argument to an $R_1$ operator can be any expression,
+  whereas x86 instructions restrict their arguments to simple things
+  like integers, registers, and memory locations.
+
+\item[(d)] The order of execution in x86 is explicit in the syntax: a
   sequence of instructions, whereas in $R_1$ it is a left-to-right
   depth-first traversal of the abstract syntax tree.
 
-\item[(d)] An $R_1$ program can have any number of variables whereas x86
-  has only 16 registers.
+\item[(e)] An $R_1$ program can have any number of variables whereas
+  x86 has only 16 registers.
 
-\item[(e)] Variables in $R_1$ can overshadow other variables with the same
-  name. The registers and memory locations of x86 all have unique
+\item[(f)] Variables in $R_1$ can overshadow other variables with the
+  same name. The registers and memory locations of x86 all have unique
   names.
 \end{enumerate}
 
@@ -1382,31 +1370,45 @@ orders will be better so often some trial-and-error is
 involved. However, we can try to plan ahead and choose the orderings
 based on this planning.
 
+% (b) -> (e)
 For example, to handle difference (b) (nested expressions), we shall
-introduce temporary variables to hold the intermediate results
-of each subexpression.  To deal with difference (d) we
-will be replacing variables with registers and/or stack
-locations. Thus, it makes sense to deal with (b) before (d) so that
-(d) can replace both the original variables and the new ones. Next,
-consider where (a) should fit in. Because it has to do with the format
-of x86 instructions, it makes more sense after we have removed the
-nested expressions (b). What about (c), order of execution?
+introduce temporary variables to hold the intermediate results of each
+subexpression.  To deal with difference (e) we will be replacing
+variables with registers and/or stack locations. Thus, it makes sense
+to deal with (b) before (e) so that (e) can replace both the original
+variables and the new ones.
+%
+% (b) -> (a) ??
+Next, consider where (a) should fit in. Because it has to do with the
+format of x86 instructions, it makes more sense after we have removed
+the nested expressions (b).
+
+What about (c), order of execution?
 
 UNDER CONSTRUCTION
 
+% (e) -> (b)
 Finally, when should we deal with (e) (variable overshadowing)?  We
 shall solve this problem by renaming variables to make sure they have
-unique names. Recall that our plan for (b) involves moving nested
-expressions, which could be problematic if it changes the shadowing of
+unique names. Recall that our plan for (b) involves moving 
+expressions, which could be problematic if a move changes the shadowing of
 variables. However, if we deal with (e) first, then it will not be an
-issue.  Thus, we arrive at the following ordering.
+issue. Of course, this means that during (b), when we insert temporary
+variables, we need to make sure that they are unique.
+%
+
+What about the ordering of (a) (instr. sel) and (e) (register allocation)?
+
+Thus, we arrive at the following ordering.
+
+[ordering of reg. alloc versus instr. sel? -jeremy]
 \[
 \begin{tikzpicture}[baseline=(current  bounding  box.center)]
-\foreach \i/\p in {1/1,2/2,3/3,4/4,5/5}
+\foreach \i/\p in {1/1,2/2,3/3,4/4,5/5,6/6}
 {
   \node (\i) at (\p*1.5,0) {$\bullet$};
 }
-\foreach \x/\y/\lbl in {1/2/a,2/3/b,3/4/c,4/5/d}
+\foreach \x/\y/\lbl in {1/2/e,2/3/b,3/4/c,4/5/a,5/6/d}
 {
   \path[->,bend left=15] (\x) edge [above] node {\small\lbl} (\y);
 }
@@ -1470,7 +1472,7 @@ C_0 & ::= & (\key{program}\;(\Var^{*})\;\Stmt^{+})
 \end{figure}
 
 To get from $C_0$ to x86 assembly, it remains for us to handle
-difference \#1 (the format of instructions) and difference (d)
+difference (a) (the format of instructions) and difference (d)
 (variables versus stack locations and registers). These two
 differences are intertwined, creating a bit of a Gordian Knot. To
 handle difference (d), we need to map some variables to registers