-argument vector (that is, the addresses of the strings @samp{/bin/ls},
-@samp{-l}, @samp{*.h}, and @samp{*.c}) 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). 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.
-
-Finally, 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 main and therefore is on first (smaller address) on the
-stack. We leave the stack pointer to point to the location where
-@code{argc} is, because it is at the top of the stack, the location
-directly below @code{argc}.
-
-All of which may sound very confusing, so here's a picture which will
+argument vector, that is, a null pointer, then the addresses of the
+strings @samp{/bin/ls}, @samp{-l}, @samp{*.h}, and @samp{*.c}) 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
+@code{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