-@node Argument Passing to main
-@subsection Argument Passing to @code{main()}
-
-In @func{main}'s case, there is no caller to prepare the stack
-before it runs. Therefore, the kernel needs to do it. Fortunately,
-since there's no caller, there are no registers to save, no return
-address to deal with, etc. The only difficult detail to take care of,
-after loading the code, is putting the arguments to @func{main} on
-the stack.
-
-(The above is a small lie: most compilers will emit code where main
-isn't strictly speaking the first function. This isn't an important
-detail. If you want to look into it more, try disassembling a program
-and looking around a bit. However, you can just act as if
-@func{main} is the very first function called.)
-
-Pintos is written for the 80@var{x}86 architecture. Therefore, we
-need to adhere to the 80@var{x}86 calling convention. Basically, you
-put all the arguments on the stack and move the stack pointer
-appropriately. You also need to insert space for the function's
-``return address'': even though the initial function doesn't really
-have a caller, its stack frame must have the same layout as any other
-function's. The program will assume that the stack has been laid out
-this way when it begins running.
-
-So, what are the arguments to @func{main}? Just two: an @samp{int}
-(@code{argc}) and a @samp{char **} (@code{argv}). @code{argv} is an
-array of strings, and @code{argc} is the number of strings in that
-array. However, the hard part isn't these two things. The hard part
-is getting all the individual strings in the right place. As we go
-through the procedure, let us consider the following example command:
-@samp{/bin/ls -l foo bar}.
-
-The first thing to do is to break the command line into individual
-strings: @samp{/bin/ls}, @samp{-l}, @samp{foo}, and @samp{bar}. These
-constitute the arguments of the command, including the program name
-itself (which belongs in @code{argv[0]}).
-
-These individual, null-terminated strings should be placed on the user
-stack. They may be placed in any order, as you'll see shortly,
-without affecting how main works, but for simplicity let's assume they
-are in reverse order (keeping in mind that the stack grows downward on
-an 80@var{x}86 machine). As we copy the strings onto the stack, we
-record their (virtual) stack addresses. These addresses will become
-important when we write the argument vector (two paragraphs down).
-
-After we push all of the strings onto the stack, we adjust the stack
-pointer so that it is word-aligned: that is, we move it down to the
-next 4-byte boundary. This is required because we will next be
-placing several words of data on the stack, and they must be aligned
-to be read correctly. In our example, as you'll see below,
-the strings start at address @t{0xffed}. One word below that would be
-at @t{0xffe9}, so we could in theory put the next word on the stack
-there. However, since the stack pointer should always be
-word-aligned, we instead leave the stack pointer at @t{0xffe8}.
-
-Once we align the stack pointer, we then push the elements of the
-argument vector, that is, a null pointer, then the addresses of the
-strings @samp{/bin/ls}, @samp{-l}, @samp{foo}, and @samp{bar}) onto
-the stack. This must be done in reverse order, such that
-@code{argv[0]} is at the lowest virtual address, again because the
-stack is growing downward. (The null pointer pushed first is because
-@code{argv[argc]} must be a null pointer.) This is because we are now
-writing the actual array of strings; if we write them in the wrong
-order, then the strings will be in the wrong order in the array. This
-is also why, strictly speaking, it doesn't matter what order the
-strings themselves are placed on the stack: as long as the pointers
-are in the right order, the strings themselves can really be anywhere.
-After we finish, we note the stack address of the first element of the
-argument vector, which is @code{argv} itself.
-
-Then we push @code{argv} (that is, the address of the first element of
-the @code{argv} array) onto the stack, along with the length of the
-argument vector (@code{argc}, 4 in this example). This must also be
-done in this order, since @code{argc} is the first argument to
-@func{main} and therefore is on first (smaller address) on the
-stack. Finally, we push a fake ``return address'' and leave the stack
-pointer to point to its location.
-
-All this may sound very confusing, so here's a picture which will
-hopefully clarify what's going on. This represents the state of the
-stack and the relevant registers right before the beginning of the
-user program (assuming for this example that the stack bottom is
-@t{0xc0000000}):
+@node Program Startup Details
+@subsection Program Startup Details
+
+The Pintos C library for user programs designates @func{_start}, in
+@file{lib/user/entry.c}, as the entry point for user programs. This
+function is a wrapper around @func{main} that calls @func{exit} if
+@func{main} returns:
+
+@example
+void
+_start (int argc, char *argv[])
+@{
+ exit (main (argc, argv));
+@}
+@end example
+
+The kernel is responsible for setting up the arguments for the initial
+function on the stack, in accordance with the calling convention
+explained in the preceding section, before it allows the user program to
+begin executing.
+
+Consider the following example command: @samp{/bin/ls -l foo bar}.
+First, the kernel must break the command into words, as @samp{/bin/ls},
+@samp{-l}, @samp{foo}, and @samp{bar}, and place them at the top of the
+stack. Order doesn't matter, because they will be referenced through
+pointers.
+
+Then, push the address of each string plus a null pointer sentinel, on
+the stack, in right-to-left order. These are the elements of
+@code{argv}. The order ensure that @code{argv[0]} is at the lowest
+virtual address. Word-aligned accesses are faster than unaligned
+accesses, so for best performance round the stack pointer down to a
+multiple of 4 before the first push.
+
+Then, push @code{argv} (the address of @code{argv[0]}) and @code{argc},
+in that order. Finally, push a fake ``return address'': although the
+entry function will never return, its stack frame must have the same
+structure as any other.
+
+The table below show the state of the stack and the relevant registers
+right before the beginning of the user program, assuming
+@code{PHYS_BASE} is @t{0xc0000000}: