X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=doc%2Fuserprog.texi;h=655c5be8691dcb0bf6e167283c7b9c427de02c76;hb=157b63dc9764dbecd8dfba88c4c127d1629f6828;hp=a9a84b2dcd854609cbd40bd82648cf96b1a9773c;hpb=ba35f69bce055ba00eb79a6f7141e2b6bb38c4b2;p=pintos-anon diff --git a/doc/userprog.texi b/doc/userprog.texi index a9a84b2..655c5be 100644 --- a/doc/userprog.texi +++ b/doc/userprog.texi @@ -430,29 +430,37 @@ 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 KDST. - Returns true if successful, false if USRC is invalid. */ -static inline bool get_user (uint8_t *kdst, const uint8_t *usrc) { - int eax; - asm ("movl $1f, %%eax; movb %2, %%al; movb %%al, %0; 1:" - : "=m" (*kdst), "=&a" (eax) : "m" (*usrc)); - return eax != 0; +/* Reads a byte at user virtual address UADDR. + UADDR must be below PHYS_BASE. + Returns the byte value if successful, -1 if a segfault + occurred. */ +static int +get_user (const uint8_t *uaddr) +{ + int result; + asm ("movl $1f, %0; movzbl %1, %0; 1:" + : "=&a" (result) : "m" (*uaddr)); + return result; } - -/* Tries to 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 ("movl $1f, %%eax; movb %b2, %0; 1:" - : "=m" (*udst), "=&a" (eax) : "r" (byte)); - return eax != 0; + +/* Writes BYTE to user address UDST. + UDST must be below PHYS_BASE. + Returns true if successful, false if a segfault occurred. */ +static bool +put_user (uint8_t *udst, uint8_t byte) +{ + int error_code; + asm ("movl $1f, %0; movb %b2, %1; 1:" + : "=&a" (error_code), "=m" (*udst) : "r" (byte)); + return error_code != -1; } @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 merely sets -@code{eax} to 0 and copies its former value into @code{eip}. +modified @func{page_fault} so that a page fault in the kernel merely +sets @code{eax} to @t{0xffffffff} and copies its former value +into @code{eip}. @node Project 2 Suggested Order of Implementation @section Suggested Order of Implementation