-@item
-@b{I can't seem to figure out how to read from and write to user
-memory. What should I do?}
-
-The kernel must treat user memory delicately. As part of a system
-call, the user can pass to the kernel a null pointer, a pointer to
-unmapped virtual memory, or a pointer to kernel virtual address space
-(above @code{PHYS_BASE}). All of these types of invalid pointers must
-be rejected without harm to the kernel or other running processes. At
-your option, the kernel may handle invalid pointers by terminating the
-process or returning from the system call with an error.
-
-There are at least two reasonable ways to do this correctly. The
-first method is to ``verify then access'':@footnote{These terms are
-made up for this document. They are not standard terminology.} verify
-the validity of a user-provided pointer, then dereference it. If you
-choose this route, you'll want to look at the functions in
-@file{userprog/pagedir.c} and in @file{threads/mmu.h}. This is the
-simplest way to handle user memory access.
-
-The second method is to ``assume and react'': directly dereference
-user pointers, after checking that they point below @code{PHYS_BASE}.
-Invalid user pointers will then cause a ``page fault'' that you can
-handle by modifying the code for @func{page_fault} in
-@file{userprog/exception.cc}. This technique is normally faster
-because it takes advantage of the processor's MMU, so it tends to be
-used in real kernels (including Linux).
-
-In either case, you need to make sure not to ``leak'' resources. For
-example, suppose that your system call has acquired a lock or
-allocated a page of memory. If you encounter an invalid user pointer
-afterward, you must still be sure to release the lock or free the page
-of memory. If you choose to ``verify then access,'' then this should
-be straightforward, but for ``assume and react'' it's more difficult,
-because there's no way to return an error code from a memory access.
-Therefore, for those who want to try the latter technique, we'll
-provide a little bit of helpful code:
-
-@verbatim
-/* Tries to copy a byte from user address USRC to kernel address DST.
- Returns true if successful, false if USRC is invalid. */
-static inline bool get_user (uint8_t *dst, const uint8_t *usrc) {
- int eax;
- asm ("mov %%eax, offset 1f; mov %%al, %2; mov %0, %%al; 1:"
- : "=m" (*dst), "=&a" (eax) : "m" (*usrc));
- return eax != 0;
-}
-
-/* Tries write BYTE to user address UDST.
- Returns true if successful, false if UDST is invalid. */
-static inline bool put_user (uint8_t *udst, uint8_t byte) {
- int eax;
- asm ("mov %%eax, offset 1f; mov %0, %b2; 1:"
- : "=m" (*udst), "=&a" (eax) : "r" (byte));
- return eax != 0;
-}
-@end verbatim
-
-Each of these functions assumes that the user address has already been
-verified to be below @code{PHYS_BASE}. They also assume that you've
-modified @func{page_fault} so that a page fault in the kernel causes
-@code{eax} to be set to 0 and its former value copied into @code{eip}.
-
-@item
-@b{I'm also confused about reading from and writing to the stack. Can
-you help?}
-
-@itemize @bullet
-@item
-Only non-@samp{char} values will have issues when writing them to
-memory. If a digit is in a string, it is considered a character.
-However, the value of @code{argc} would be a non-char.
-
-@item
-You will need to write characters and non-characters into main memory.
-
-@item
-When you add items to the stack, you will be decrementing the stack
-pointer. You'll need to decrement the stack pointer before writing to
-the location.
-
-@item
-Each character is 1 byte.
-@end itemize
-
-@item
-@b{Why doesn't keyboard input work with @samp{pintos -v}?}