-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}):
+@example
+void
+_start (int argc, char *argv[])
+@{
+ exit (main (argc, argv));
+@}
+@end example
+
+The kernel must put the arguments for the initial function on the stack
+before it allows the user program to begin executing. The arguments are
+passed in the same way as the normal calling convention (@pxref{80x86
+Calling Convention}).
+
+Consider how to handle arguments for the following example command:
+@samp{/bin/ls -l foo bar}.
+First, break the command into words: @samp{/bin/ls},
+@samp{-l}, @samp{foo}, @samp{bar}. Place the words 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 null pointer sentinel ensures that @code{argv[argc]}
+is a null pointer, as required by the C standard. The order ensures
+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 shows the state of the stack and the relevant registers
+right before the beginning of the user program, assuming
+@code{PHYS_BASE} is @t{0xc0000000}: