diff --git a/labcodes/lab5/bin/bootblock b/labcodes/lab5/bin/bootblock new file mode 100644 index 0000000000000000000000000000000000000000..b04b04f58b3af9b64903fdd9b677a794735388c2 Binary files /dev/null and b/labcodes/lab5/bin/bootblock differ diff --git a/labcodes/lab5/bin/kernel b/labcodes/lab5/bin/kernel new file mode 100755 index 0000000000000000000000000000000000000000..afde5ec130ab1f912237e6591a75f3736ffb262b Binary files /dev/null and b/labcodes/lab5/bin/kernel differ diff --git a/labcodes/lab5/bin/sign b/labcodes/lab5/bin/sign new file mode 100755 index 0000000000000000000000000000000000000000..abdb29a5fffd606135c36c95bf4a2edea33df473 Binary files /dev/null and b/labcodes/lab5/bin/sign differ diff --git a/labcodes/lab5/bin/swap.img b/labcodes/lab5/bin/swap.img new file mode 100644 index 0000000000000000000000000000000000000000..bf651b8e69916869c89e167a24aae9aa54814b68 Binary files /dev/null and b/labcodes/lab5/bin/swap.img differ diff --git a/labcodes/lab5/bin/ucore.img b/labcodes/lab5/bin/ucore.img new file mode 100644 index 0000000000000000000000000000000000000000..f01606b46035c1f1e182a9dc3843e4b35141a545 Binary files /dev/null and b/labcodes/lab5/bin/ucore.img differ diff --git a/labcodes/lab5/kern/init/init.c b/labcodes/lab5/kern/init/init.c index ef984128de31d9d3a1ea33d9df74e346b8453c2f..00cb027b04866a3479282a5ee0b75a8ced071077 100644 --- a/labcodes/lab5/kern/init/init.c +++ b/labcodes/lab5/kern/init/init.c @@ -18,89 +18,110 @@ int kern_init(void) __attribute__((noreturn)); void grade_backtrace(void); static void lab1_switch_test(void); -int + + int kern_init(void) { - extern char edata[], end[]; - memset(edata, 0, end - edata); + extern char edata[], end[]; //声明外部变量 edata 和 end + memset(edata, 0, end - edata); // 将数据段清零 - cons_init(); // init the console + cons_init(); // init the console 初始化控制台 const char *message = "(THU.CST) os is loading ..."; - cprintf("%s\n\n", message); + cprintf("%s\n\n", message);// 将消息输出到控制台 - print_kerninfo(); + print_kerninfo();// 输出内核信息的函数 - grade_backtrace(); + grade_backtrace(); //调用回溯函数,通常用于调试,显示函数调用栈。 - pmm_init(); // init physical memory management + pmm_init(); // init physical memory management初始化物理内存管理 - pic_init(); // init interrupt controller - idt_init(); // init interrupt descriptor table + pic_init(); // init interrupt controller初始化可编程中断控制器 + idt_init(); // init interrupt descriptor table初始化中断描述符表 - vmm_init(); // init virtual memory management - proc_init(); // init process table + vmm_init(); // init virtual memory management 初始化虚拟内存管理 - ide_init(); // init ide devices - swap_init(); // init swap + proc_init(); // init process table - clock_init(); // init clock interrupt + ide_init(); // init ide devices初始化IDE设备 + swap_init(); // init swap 初始化交换分区 + + clock_init(); // init clock interrupt 初始化时钟中断 intr_enable(); // enable irq interrupt //LAB1: CAHLLENGE 1 If you try to do it, uncomment lab1_switch_test() // user/kernel mode switch test //lab1_switch_test(); - cpu_idle(); // run idle process + cpu_idle(); // run idle process 运行空闲进程 } +//不进行内联的回溯函数,调用 mon_backtrace 显示当前的调用栈。 void __attribute__((noinline)) grade_backtrace2(int arg0, int arg1, int arg2, int arg3) { mon_backtrace(0, NULL, NULL); } - +//不进行内联的回溯函数,传递参数到 grade_backtrace2 void __attribute__((noinline)) grade_backtrace1(int arg0, int arg1) { grade_backtrace2(arg0, (int)&arg0, arg1, (int)&arg1); } - +//不进行内联的回溯函数,传递参数到 grade_backtrace1 void __attribute__((noinline)) grade_backtrace0(int arg0, int arg1, int arg2) { grade_backtrace1(arg0, arg2); } - +//触发回溯的起始点,传递初始化函数地址。 void grade_backtrace(void) { grade_backtrace0(0, (int)kern_init, 0xffff0000); } - +//打印当前的段寄存器状态。 static void lab1_print_cur_status(void) { static int round = 0; uint16_t reg1, reg2, reg3, reg4; + //嵌入汇编代码,确保编译器不优化这些代码。 asm volatile ( - "mov %%cs, %0;" + "mov %%cs, %0;"// 将当前代码段寄存器的值移动到 reg1 "mov %%ds, %1;" "mov %%es, %2;" "mov %%ss, %3;" : "=m"(reg1), "=m"(reg2), "=m"(reg3), "=m"(reg4)); - cprintf("%d: @ring %d\n", round, reg1 & 3); + cprintf("%d: @ring %d\n", round, reg1 & 3);//打印当前的 round、权限级(ring)和各段寄存器的值。 cprintf("%d: cs = %x\n", round, reg1); cprintf("%d: ds = %x\n", round, reg2); cprintf("%d: es = %x\n", round, reg3); cprintf("%d: ss = %x\n", round, reg4); - round ++; + round ++;//将 round 增加1,以便每次调用时记录状态。 } static void lab1_switch_to_user(void) { + // 从内核模式切换到用户模式 //LAB1 CHALLENGE 1 : TODO + asm volatile ( + "sub $0x8, %%esp \n"//从堆栈指针中减去 8 字节 + "int %0 \n"//通过触发一个中断,将控制权转移到内核,切换到用户模式。 + "movl %%ebp, %%esp"// 将基指针(EBP)值移动到堆栈指针(ESP),恢复堆栈指针。 + : + : "i"(T_SWITCH_TOU)//T_SWITCH_TOU是一个常量,表示切换到用户态的中断号。传入常量 T_SWITCH_TOU + ); } static void lab1_switch_to_kernel(void) { + // 从用户模式切换到内核模式 //LAB1 CHALLENGE 1 : TODO + asm volatile ( + "int %0 \n"// 同样触发中断,这里用的是 T_SWITCH_TOK,从用户态切换回内核态。 + "movl %%ebp, %%esp \n"//恢复堆栈指针 + : + : "i"(T_SWITCH_TOK)//传入常量 T_SWITCH_TOU + ); } +//测试用户模式和内核模式切换。 +//调用 lab1_print_cur_status 打印当前状态,进行模式切换,然后再次打印状态。 static void lab1_switch_test(void) { lab1_print_cur_status(); @@ -110,5 +131,4 @@ lab1_switch_test(void) { cprintf("+++ switch to kernel mode +++\n"); lab1_switch_to_kernel(); lab1_print_cur_status(); -} - +} \ No newline at end of file diff --git a/labcodes/lab5/kern/mm/default_pmm.c b/labcodes/lab5/kern/mm/default_pmm.c index b388bca0c9b088a485cb8c162b83418bd826269e..9823bd72aa9d6d45286c5ae2c302ed819d075810 100644 --- a/labcodes/lab5/kern/mm/default_pmm.c +++ b/labcodes/lab5/kern/mm/default_pmm.c @@ -9,30 +9,47 @@ * the request. If the chosen block is significantly larger than requested, it * is usually splitted, and the remainder will be added into the list as * another free block. + * 在首次适应算法中,分配器维护一个空闲块列表,(称为空闲列表)。一旦收到内存的分配请求, + * 它会沿着列表扫描第一个足够大的块以满足请求。如果选中的块比请求的块大得多,通常会将其拆分, + * 剩余部分将作为另一个空闲块添加到列表中。 * Please refer to Page 196~198, Section 8.2 of Yan Wei Min's Chinese book * "Data Structure -- C programming language". */ // LAB2 EXERCISE 1: YOUR CODE // you should rewrite functions: `default_init`, `default_init_memmap`, // `default_alloc_pages`, `default_free_pages`. +// `default_alloc_pages`, `default_free_pages`.你需要重写函数: /* * Details of FFMA * (1) Preparation: * In order to implement the First-Fit Memory Allocation (FFMA), we should * manage the free memory blocks using a list. The struct `free_area_t` is used * for the management of free memory blocks. + * * 为了实现首次适应内存分配(FFMA),我们应使用一个列表来管理空闲内存块。 + * 结构体 `free_area_t` 用于管理空闲内存块。 + * * First, you should get familiar with the struct `list` in list.h. Struct * `list` is a simple doubly linked list implementation. You should know how to * USE `list_init`, `list_add`(`list_add_after`), `list_add_before`, `list_del`, * `list_next`, `list_prev`. + * 首先,你需要熟悉 `list.h` 中的 `list` 结构。结构体 `list` 是一个简单的双向链表实现。 + * 你需要知道如何使用 `list_init`、`list_add`(`list_add_after`)、`list_add_before`、`list_del`、 + * `list_next`, `list_prev`. + * * There's a tricky method that is to transform a general `list` struct to a * special struct (such as struct `page`), using the following MACROs: `le2page` * (in memlayout.h), (and in future labs: `le2vma` (in vmm.h), `le2proc` (in * proc.h), etc). + * 有一种巧妙的方法是将通用的 `list` 结构转换为特定的结构(例如 `struct page`), + * 使用以下宏:`le2page`(在 memlayout.h 中),(在未来的实验中:`le2vma`(在 vmm.h 中)、`le2proc`(在 proc.h 中)等)。 + * * (2) `default_init`: * You can reuse the demo `default_init` function to initialize the `free_list` * and set `nr_free` to 0. `free_list` is used to record the free memory blocks. * `nr_free` is the total number of the free memory blocks. + * 你可以重用示例 `default_init` 函数来初始化 `free_list`,并将 `nr_free` 设置为 0。 + * `free_list` 用于记录空闲内存块。`nr_free` 是空闲内存块的总数。 + * * (3) `default_init_memmap`: * CALL GRAPH: `kern_init` --> `pmm_init` --> `page_init` --> `init_memmap` --> * `pmm_manager` --> `init_memmap`. @@ -40,21 +57,40 @@ * `page_number`). In order to initialize a free block, firstly, you should * initialize each page (defined in memlayout.h) in this free block. This * procedure includes: + * 此函数用于初始化一个空闲块(带参数 `addr_base`、`page_number`)。 + * 为了初始化一个空闲块,首先,你需要初始化此空闲块中的每一页(在 memlayout.h 中定义)。该过程包括: + * * - Setting the bit `PG_property` of `p->flags`, which means this page is * valid. P.S. In function `pmm_init` (in pmm.c), the bit `PG_reserved` of * `p->flags` is already set. + * 设置 `p->flags` 的 `PG_property` 位,表示该页有效。注:在 `pmm_init` 函数中(在 pmm.c 中), + * `p->flags` 的 `PG_reserved` 位已经设置。 + * * - If this page is free and is not the first page of a free block, * `p->property` should be set to 0. + * 如果该页是空闲的且不是空闲块的第一页,则应将 `p->property` 设置为 0。 + * * - If this page is free and is the first page of a free block, `p->property` * should be set to be the total number of pages in the block. + * 如果该页是空闲的并且是空闲块的第一页,则应将 `p->property` 设置为该块中的总页数。 + * * - `p->ref` should be 0, because now `p` is free and has no reference. * After that, We can use `p->page_link` to link this page into `free_list`. + * `p->ref` 应设置为 0,因为现在 `p` 是空闲的,没有引用。 + * 之后,我们可以使用 `p->page_link` 将此页链接到 `free_list` 中。 + * * (e.g.: `list_add_before(&free_list, &(p->page_link));` ) * Finally, we should update the sum of the free memory blocks: `nr_free += n`. + * (例如:`list_add_before(&free_list, &(p->page_link));`) + * Finally, we should update the sum of the free memory blocks: `nr_free += n`. + * 最后,我们应更新空闲内存块的总数:`nr_free += n`。 + * * (4) `default_alloc_pages`: * Search for the first free block (block size >= n) in the free list and reszie * the block found, returning the address of this block as the address required by * `malloc`. + * 在空闲列表中搜索第一个空闲块(块大小 >= n),并调整找到的块的大小,返回该块的地址作为 `malloc` 所需的地址。 + * * (4.1) * So you should search the free list like this: * list_entry_t le = &free_list; @@ -63,6 +99,9 @@ * (4.1.1) * In the while loop, get the struct `page` and check if `p->property` * (recording the num of free pages in this block) >= n. + * 在 while 循环中,获取 `struct page` 并检查 `p->property` + * (记录该块中空闲页的数量)是否 >= n。 + * * struct Page *p = le2page(le, page_link); * if(p->property >= n){ ... * (4.1.2) @@ -70,6 +109,8 @@ * >= n, whose first `n` pages can be malloced. Some flag bits of this page * should be set as the following: `PG_reserved = 1`, `PG_property = 0`. * Then, unlink the pages from `free_list`. + * 如果我们找到这个 `p`,这意味着我们找到了一个大小>= n 的空闲块,其前 `n` 页可以分配。此页面的一些标志位应设置如下: + * `PG_reserved = 1`,`PG_property = 0`。然后,从 `free_list` 中移除这些页。 * (4.1.2.1) * If `p->property > n`, we should re-calculate number of the rest * pages of this free block. (e.g.: `le2page(le,page_link))->property @@ -98,137 +139,170 @@ free_area_t free_area; #define free_list (free_area.free_list) #define nr_free (free_area.nr_free) +//free_list` 用于记录空闲内存块,nr_free` 是空闲内存块的总数。 +//用default_init函数来初始化 `free_list`,并将 `nr_free` 设置为 0。 static void default_init(void) { list_init(&free_list); nr_free = 0; } +//用于初始化一段连续的物理页,并将它们加入到空闲内存管理系统中. +//struct Page *base:指向要初始化的页块的起始地址。size_t n:要初始化的页的数量。 static void default_init_memmap(struct Page *base, size_t n) { - assert(n > 0); - struct Page *p = base; + assert(n > 0);// 确保请求的页数大于零 + struct Page *p = base;// 指向当前初始化的页 + // 遍历每一页,设置其状态 for (; p != base + n; p ++) { - assert(PageReserved(p)); - p->flags = p->property = 0; - set_page_ref(p, 0); + assert(PageReserved(p));//检查每个页是否被标记为“保留”。若没有被保留,函数将抛出错误。 + p->flags = p->property = 0;//将页的 flags 和 property 字段设置为 0,表示该页未分配、未使用。 + set_page_ref(p, 0);//将页的引用计数设置为 0,表明没有任何引用指向此页。 } + // 设置第一个页的 property 为块的总数 base->property = n; - SetPageProperty(base); - nr_free += n; - list_add(&free_list, &(base->page_link)); + SetPageProperty(base);// 设置当前页的有效标志 + nr_free += n;// 更新空闲页计数 + list_add_before(&free_list, &(base->page_link));// 将该块添加到空闲列表中 } +//用于分配指定数量的连续物理页。该函数实现了首次适应内存分配算法。 static struct Page * default_alloc_pages(size_t n) { - assert(n > 0); - if (n > nr_free) { + assert(n > 0);// 确保请求的页数大于零 + if (n > nr_free) {// 检查请求的页数是否超过空闲页数 return NULL; } - struct Page *page = NULL; - list_entry_t *le = &free_list; + struct Page *page = NULL;// 初始化分配的页指针 + list_entry_t *le = &free_list;// 初始化链表迭代器 + // 遍历空闲列表,寻找第一个满足条件的块 while ((le = list_next(le)) != &free_list) { - struct Page *p = le2page(le, page_link); - if (p->property >= n) { - page = p; - break; + struct Page *p = le2page(le, page_link);// 将链表节点转换为 Page 结构体 + if (p->property >= n) {// 检查当前块的页数是否满足请求 + page = p;// 找到合适的块 + break;// 退出循环 } } - if (page != NULL) { - list_del(&(page->page_link)); + if (page != NULL) {// 如果找到合适的块 + //list_del(&(page->page_link));// 从空闲列表中删除该块 if (page->property > n) { - struct Page *p = page + n; - p->property = page->property - n; - list_add(&free_list, &(p->page_link)); + struct Page *p = page + n;// 指向剩余的页 + p->property = page->property - n;// 更新剩余块的页数 + SetPageProperty(p); + list_add_after(&(page->page_link), &(p->page_link));// 将剩余块添加回空闲列表 } - nr_free -= n; - ClearPageProperty(page); + list_del(&(page->page_link)); + nr_free -= n;// 减少空闲页的计数 + ClearPageProperty(page);// 清除已分配页的属性 } - return page; + return page;// 返回分配的页块 } static void default_free_pages(struct Page *base, size_t n) { - assert(n > 0); + assert(n > 0);// 确保请求释放的页数大于零 struct Page *p = base; + // 遍历释放的页,检查状态并重置 for (; p != base + n; p ++) { - assert(!PageReserved(p) && !PageProperty(p)); - p->flags = 0; - set_page_ref(p, 0); + assert(!PageReserved(p) && !PageProperty(p));// 确保页没有被保留并且没有属性 + p->flags = 0;// 清除 flags 字段 + set_page_ref(p, 0);// 清除引用计数 } + // 设置基页的属性为释放的页数 base->property = n; - SetPageProperty(base); + SetPageProperty(base);// 设置页的有效标志 + // 遍历空闲列表,检查是否需要合并 list_entry_t *le = list_next(&free_list); while (le != &free_list) { p = le2page(le, page_link); le = list_next(le); + // 如果当前页块与释放的页块相邻,合并 if (base + base->property == p) { - base->property += p->property; - ClearPageProperty(p); - list_del(&(p->page_link)); + base->property += p->property;// 合并当前页块 + ClearPageProperty(p);// 清除合并页的属性 + list_del(&(p->page_link));// 从空闲列表中删除合并页 } else if (p + p->property == base) { - p->property += base->property; - ClearPageProperty(base); - base = p; - list_del(&(p->page_link)); + p->property += base->property;// 合并前一个页块 + ClearPageProperty(base);// 清除当前页的属性 + base = p;// 更新 base 指针 + list_del(&(p->page_link));// 从空闲列表中删除当前页 + } + } + nr_free += n;// 更新空闲页的计数 + le = list_next(&free_list); + while (le != &free_list) + { + p = le2page(le, page_link); + if (base + base->property <= p) + { + assert(base + base->property != p); + break; } + le = list_next(le); } - nr_free += n; - list_add(&free_list, &(base->page_link)); + + list_add_before(le, &(base->page_link));// 将释放的页块添加到空闲列表中 } +//用于返回当前系统中可用的空闲页的数量。 static size_t default_nr_free_pages(void) { - return nr_free; + return nr_free;// 返回当前空闲页的数量 } +//basic_check 函数用于测试内存分配和释放的基本功能, +//确保在不同情况下内存管理系统的正确性,包括分配、释放、合并和引用计数等操作。 static void basic_check(void) { struct Page *p0, *p1, *p2; p0 = p1 = p2 = NULL; + // 分配三个页面 assert((p0 = alloc_page()) != NULL); assert((p1 = alloc_page()) != NULL); assert((p2 = alloc_page()) != NULL); - + // 确保所有分配的页面是不同的 assert(p0 != p1 && p0 != p2 && p1 != p2); + // 确保页面的引用计数为 0 assert(page_ref(p0) == 0 && page_ref(p1) == 0 && page_ref(p2) == 0); - + // 确保页面地址在合法范围内 assert(page2pa(p0) < npage * PGSIZE); assert(page2pa(p1) < npage * PGSIZE); assert(page2pa(p2) < npage * PGSIZE); - + // 保存当前的空闲页面链表和数量 list_entry_t free_list_store = free_list; - list_init(&free_list); - assert(list_empty(&free_list)); - - unsigned int nr_free_store = nr_free; - nr_free = 0; + list_init(&free_list);// 初始化空闲列表 + assert(list_empty(&free_list));// 确保空闲列表为空 + unsigned int nr_free_store = nr_free;// 保存当前空闲页数量 + nr_free = 0;// 将空闲页数量设为 0 + // 请求分配页面,但当前没有空闲页面 assert(alloc_page() == NULL); - + // 释放之前分配的页面 free_page(p0); free_page(p1); free_page(p2); - assert(nr_free == 3); - + assert(nr_free == 3);// 确保释放后空闲页数量为 3 + // 再次分配三个页面 assert((p0 = alloc_page()) != NULL); assert((p1 = alloc_page()) != NULL); assert((p2 = alloc_page()) != NULL); - + // 测试空闲页面是否不足 assert(alloc_page() == NULL); - + // 释放 p0,并检查空闲列表 free_page(p0); - assert(!list_empty(&free_list)); + assert(!list_empty(&free_list));// 确保空闲列表不为空 struct Page *p; + // 重新分配 p0,确保取回的是相同的页面 assert((p = alloc_page()) == p0); - assert(alloc_page() == NULL); + assert(alloc_page() == NULL);// 确保没有更多的页面可分配 - assert(nr_free == 0); + assert(nr_free == 0);// 确保当前空闲页面数量为 0 + // 恢复之前的空闲页面链表和数量 free_list = free_list_store; nr_free = nr_free_store; - + // 释放最后的页面 free_page(p); free_page(p1); free_page(p2); @@ -240,63 +314,65 @@ static void default_check(void) { int count = 0, total = 0; list_entry_t *le = &free_list; + // 遍历空闲列表,计算空闲页面的数量和总属性值 while ((le = list_next(le)) != &free_list) { struct Page *p = le2page(le, page_link); - assert(PageProperty(p)); - count ++, total += p->property; + assert(PageProperty(p));// 确保每个页面的属性是有效的 + count ++, total += p->property;// 累加页面属性 } + // 确保总属性值与空闲页面数量匹配 assert(total == nr_free_pages()); - + // 调用 basic_check 以验证基本的内存管理功能 basic_check(); - + // 分配 5 个页面 struct Page *p0 = alloc_pages(5), *p1, *p2; - assert(p0 != NULL); - assert(!PageProperty(p0)); - + assert(p0 != NULL);// 确保成功分配 + assert(!PageProperty(p0));// 确保分配的页面不带属性 + // 初始化并检查空闲列表 list_entry_t free_list_store = free_list; list_init(&free_list); - assert(list_empty(&free_list)); - assert(alloc_page() == NULL); - - unsigned int nr_free_store = nr_free; - nr_free = 0; + assert(list_empty(&free_list));// 确保空闲列表为空 + assert(alloc_page() == NULL);// 确保没有页面可分配 + unsigned int nr_free_store = nr_free;// 保存当前空闲页数 + nr_free = 0;// 将空闲页数设为 0 + // 释放 3 个页面并确保分配页面时没有足够的空闲页 free_pages(p0 + 2, 3); - assert(alloc_pages(4) == NULL); - assert(PageProperty(p0 + 2) && p0[2].property == 3); - assert((p1 = alloc_pages(3)) != NULL); - assert(alloc_page() == NULL); - assert(p0 + 2 == p1); - - p2 = p0 + 1; - free_page(p0); - free_pages(p1, 3); - assert(PageProperty(p0) && p0->property == 1); - assert(PageProperty(p1) && p1->property == 3); - + assert(alloc_pages(4) == NULL);// 确保无法分配 4 个页面 + assert(PageProperty(p0 + 2) && p0[2].property == 3);// 检查页面属性 + assert((p1 = alloc_pages(3)) != NULL);// 再次分配 3 个页面 + assert(alloc_page() == NULL);// 确保没有页面可分配 + assert(p0 + 2 == p1);// 确保分配的页面是释放的页面 + + p2 = p0 + 1;// 设置 p2 为 p0 的下一个页面 + free_page(p0);// 释放 p0 页面 + free_pages(p1, 3);// 释放 p1 指向的页面 + assert(PageProperty(p0) && p0->property == 1);// 检查 p0 属性 + assert(PageProperty(p1) && p1->property == 3);// 检查 p1 属性 + // 确保重分配的页面是之前释放的页面 assert((p0 = alloc_page()) == p2 - 1); - free_page(p0); - assert((p0 = alloc_pages(2)) == p2 + 1); - + free_page(p0);// 释放分配的页面 + assert((p0 = alloc_pages(2)) == p2 + 1);// 分配 2 个页面并检查 + // 释放页面并检查空闲状态 free_pages(p0, 2); free_page(p2); - + // 再次分配 5 个页面 assert((p0 = alloc_pages(5)) != NULL); - assert(alloc_page() == NULL); - - assert(nr_free == 0); - nr_free = nr_free_store; + assert(alloc_page() == NULL);// 确保没有额外页面可分配 + assert(nr_free == 0);// 确保空闲页数为 0 + nr_free = nr_free_store;// 恢复空闲页数 + // 恢复空闲列表状态 free_list = free_list_store; - free_pages(p0, 5); - + free_pages(p0, 5);// 释放所有分配的页面 + // 验证空闲列表的一致性 le = &free_list; while ((le = list_next(le)) != &free_list) { struct Page *p = le2page(le, page_link); count --, total -= p->property; } - assert(count == 0); - assert(total == 0); + assert(count == 0);// 确保所有页面都已处理 + assert(total == 0);// 确保总属性值为 0 } const struct pmm_manager default_pmm_manager = { @@ -307,5 +383,4 @@ const struct pmm_manager default_pmm_manager = { .free_pages = default_free_pages, .nr_free_pages = default_nr_free_pages, .check = default_check, -}; - +}; \ No newline at end of file diff --git a/labcodes/lab5/kern/mm/pmm.c b/labcodes/lab5/kern/mm/pmm.c index f7d2ed279f806963493705cd0ec41bb84df9c7cd..7c5cbf71dbd95eed070c781e79c78a66fe91d254 100644 --- a/labcodes/lab5/kern/mm/pmm.c +++ b/labcodes/lab5/kern/mm/pmm.c @@ -12,101 +12,130 @@ #include #include -/* * - * Task State Segment: + + /* * + * Task State Segment:任务状态段(TSS) * * The TSS may reside anywhere in memory. A special segment register called * the Task Register (TR) holds a segment selector that points a valid TSS * segment descriptor which resides in the GDT. Therefore, to use a TSS * the following must be done in function gdt_init: - * - create a TSS descriptor entry in GDT - * - add enough information to the TSS in memory as needed - * - load the TR register with a segment selector for that segment + * TSS 可以位于内存的任何位置。一个特殊的段寄存器称为任务寄存器(TR),它保存一个段选择子, + * 该选择子指向位于全局描述符表(GDT)中的有效 TSS 段描述符。 + * 因此,要使用 TSS,必须在 gdt_init 函数中完成以下操作: + * + * - create a TSS descriptor entry in GDT 在 GDT 中创建一个 TSS 描述符条目 + * - add enough information to the TSS in memory as needed 根据需要将足够的信息添加到内存中的 TSS + * - load the TR register with a segment selector for that segment 使用该段的段选择子加载 TR 寄存器 * * There are several fileds in TSS for specifying the new stack pointer when a * privilege level change happens. But only the fields SS0 and ESP0 are useful * in our os kernel. + * TSS 中有几个字段用于指定特权级变化发生时的新栈指针。 + * 但在我们的操作系统内核中,仅有 SS0 和 ESP0 字段是有用的。 * * The field SS0 contains the stack segment selector for CPL = 0, and the ESP0 * contains the new ESP value for CPL = 0. When an interrupt happens in protected * mode, the x86 CPU will look in the TSS for SS0 and ESP0 and load their value * into SS and ESP respectively. + * 字段 SS0 包含 CPL = 0 的栈段选择子,而 ESP0 包含 CPL = 0 的新 ESP 值。当在保护模式下发生中断时, + * x86 CPU 将在 TSS 中查找 SS0 和 ESP0,并将其值分别加载到 SS 和 ESP 中。 * */ +//静态任务状态结构体初始化为零 static struct taskstate ts = {0}; -// virtual address of physicall page array +// virtual address of physicall page array声明了一个指向物理页面的数组的指针,用于管理物理内存中的页面。 struct Page *pages; -// amount of physical memory (in pages) +// amount of physical memory (in pages)用于记录物理内存的总量,以页面为单位,初始值为0。 size_t npage = 0; // virtual address of boot-time page directory -extern pde_t __boot_pgdir; -pde_t *boot_pgdir = &__boot_pgdir; +extern pde_t __boot_pgdir;//声明了一个外部变量,表示启动时的页目录。 +pde_t *boot_pgdir = &__boot_pgdir;//将其指针赋值给 boot_pgdir // physical address of boot-time page directory +// 用于存储启动时页目录的物理地址,这通常用于内存管理中的页表转换 uintptr_t boot_cr3; // physical memory management +//声明了一个指向物理内存管理器结构的指针,用于管理和分配物理内存。 const struct pmm_manager *pmm_manager; /* * * The page directory entry corresponding to the virtual address range * [VPT, VPT + PTSIZE) points to the page directory itself. Thus, the page * directory is treated as a page table as well as a page directory. + * 对应于虚拟地址范围 [VPT, VPT + PTSIZE) 的页目录项指向页目录本身。 + * 因此,页目录既被视为页表,也被视为页目录。 * * One result of treating the page directory as a page table is that all PTEs * can be accessed though a "virtual page table" at virtual address VPT. And the * PTE for number n is stored in vpt[n]. + * 将页目录视为页表的一个结果是,所有的页表项(PTE)可以通过位于虚拟地址 VPT 的“虚拟页表”进行访问。 + * 页表项编号为 n 的项存储在 vpt[n] 中。 * * A second consequence is that the contents of the current page directory will * always available at virtual address PGADDR(PDX(VPT), PDX(VPT), 0), to which * vpd is set bellow. + * 第二个结果是,当前页目录的内容总是可以在虚拟地址 PGADDR(PDX(VPT), PDX(VPT), 0) 处获得, + * vpd 将被设置为该地址。 * */ -pte_t * const vpt = (pte_t *)VPT; -pde_t * const vpd = (pde_t *)PGADDR(PDX(VPT), PDX(VPT), 0); - +pte_t * const vpt = (pte_t *)VPT;//定义了一个常量指针 vpt,指向虚拟地址 VPT,该地址表示虚拟页表。 +pde_t * const vpd = (pde_t *)PGADDR(PDX(VPT), PDX(VPT), 0);//定义了另一个常量指针 vpd,指向当前页目录的虚拟地址。 +//PGADDR 是一个宏或函数,用于生成特定格式的虚拟地址,其中 PDX 可能用于计算虚拟地址的索引部分。 /* * * Global Descriptor Table: - * + *全局描述符表 * The kernel and user segments are identical (except for the DPL). To load * the %ss register, the CPL must equal the DPL. Thus, we must duplicate the * segments for the user and the kernel. Defined as follows: - * - 0x0 : unused (always faults -- for trapping NULL far pointers) - * - 0x8 : kernel code segment - * - 0x10: kernel data segment - * - 0x18: user code segment - * - 0x20: user data segment - * - 0x28: defined for tss, initialized in gdt_init + * 内核和用户段是相同的(除了特权级 DPL )。要加载 %ss 寄存器,当前特权级 CPL 必须等于 DPL。 + * 因此,我们必须为用户和内核重复这些段。定义如下: + * - 0x0 : unused (always faults -- for trapping NULL far pointers)未使用(始终发生错误 -- 用于捕获 NULL 远指针) + * - 0x8 : kernel code segment 内核代码段 + * - 0x10: kernel data segment 内核数据段 + * - 0x18: user code segment 用户代码段 + * - 0x20: user data segment 用户数据段 + * - 0x28: defined for tss, initialized in gdt_init 定义用于 TSS,在 gdt_init 中初始化 * */ +//定义了一个静态的全局描述符表(GDT),用于管理内核和用户的段描述符。 static struct segdesc gdt[] = { - SEG_NULL, + SEG_NULL,//第一个段描述符,保留为 NULL,用于捕获无效的段访问。 + //内核代码段,具有执行(STA_X)和可读(STA_R)属性,基地址为 0x0,大小为 0xFFFFFFFF,特权级为内核(DPL_KERNEL)。 [SEG_KTEXT] = SEG(STA_X | STA_R, 0x0, 0xFFFFFFFF, DPL_KERNEL), + //内核数据段,具有可写(STA_W)属性,基地址为 0x0,大小为 0xFFFFFFFF,特权级为内核(DPL_KERNEL)。 [SEG_KDATA] = SEG(STA_W, 0x0, 0xFFFFFFFF, DPL_KERNEL), + //用户代码段,具有执行(STA_X)和可读(STA_R)属性,基地址为 0x0,大小为 0xFFFFFFFF,特权级为用户(DPL_USER)。 [SEG_UTEXT] = SEG(STA_X | STA_R, 0x0, 0xFFFFFFFF, DPL_USER), + //用户数据段,具有可写(STA_W)属性,基地址为 0x0,大小为 0xFFFFFFFF,特权级为用户(DPL_USER)。 [SEG_UDATA] = SEG(STA_W, 0x0, 0xFFFFFFFF, DPL_USER), - [SEG_TSS] = SEG_NULL, + [SEG_TSS] = SEG_NULL,//任务状态段(TSS),保留为 NULL,后续会在初始化时设置。 }; - +//定义了一个静态的伪描述符,用于描述 GDT 的长度和地址。 static struct pseudodesc gdt_pd = { sizeof(gdt) - 1, (uintptr_t)gdt }; -static void check_alloc_page(void); -static void check_pgdir(void); -static void check_boot_pgdir(void); +static void check_alloc_page(void);//声明一个静态函数,用于检查内存页的分配。 +static void check_pgdir(void);//声明一个静态函数,用于检查页目录的有效性。 +static void check_boot_pgdir(void);//声明一个静态函数,用于检查启动时的页目录。 /* * * lgdt - load the global descriptor table register and reset the * data/code segement registers for kernel. + * lgdt - 加载全局描述符表寄存器并重置内核的数据/代码段寄存器。 * */ +//定义了一个静态内联函数 lgdt,接收一个指向伪描述符(struct pseudodesc)的指针 pd static inline void lgdt(struct pseudodesc *pd) { + //这行汇编代码使用 lgdt 指令加载 GDT。%0 被替换为指向 pd 的指针,告诉处理器 GDT 的地址。 asm volatile ("lgdt (%0)" :: "r" (pd)); - asm volatile ("movw %%ax, %%gs" :: "a" (USER_DS)); - asm volatile ("movw %%ax, %%fs" :: "a" (USER_DS)); - asm volatile ("movw %%ax, %%es" :: "a" (KERNEL_DS)); - asm volatile ("movw %%ax, %%ds" :: "a" (KERNEL_DS)); - asm volatile ("movw %%ax, %%ss" :: "a" (KERNEL_DS)); + asm volatile ("movw %%ax, %%gs" :: "a" (USER_DS));//将 USER_DS(用户数据段)的值移动到 gs 段寄存器。 + asm volatile ("movw %%ax, %%fs" :: "a" (USER_DS));//将 USER_DS 的值移动到 fs 段寄存器。 + asm volatile ("movw %%ax, %%es" :: "a" (KERNEL_DS));//将 KERNEL_DS(内核数据段)的值移动到 es 段寄存器。 + asm volatile ("movw %%ax, %%ds" :: "a" (KERNEL_DS));//将 KERNEL_DS 的值移动到 ds 段寄存器 + asm volatile ("movw %%ax, %%ss" :: "a" (KERNEL_DS));//将 KERNEL_DS 的值移动到 ss 段寄存器 // reload cs + //通过 ljmp 指令重新加载代码段寄存器 cs,并跳转到标签 1。 asm volatile ("ljmp %0, $1f\n 1:\n" :: "i" (KERNEL_CS)); } @@ -114,54 +143,66 @@ lgdt(struct pseudodesc *pd) { * load_esp0 - change the ESP0 in default task state segment, * so that we can use different kernel stack when we trap frame * user to kernel. + * load_esp0 - 修改默认任务状态段中的 ESP0,以便在从用户态陷入内核态时能够使用不同的内核栈。 * */ +//uintptr_t esp0:这是新的堆栈指针,通常指向内核栈的顶部。 +//修改当前任务状态段(TSS)中的 ESP0 值。ESP0 是在从用户态切换到内核态时,CPU 使用的内核栈指针。 void load_esp0(uintptr_t esp0) { ts.ts_esp0 = esp0; } /* gdt_init - initialize the default GDT and TSS */ +/* gdt_init - 初始化默认的 GDT 和 TSS */ static void gdt_init(void) { + // 设置启动内核栈和默认的 SS0 // set boot kernel stack and default SS0 load_esp0((uintptr_t)bootstacktop); ts.ts_ss0 = KERNEL_DS; - + // 初始化 GDT 中的 TSS 字段 // initialize the TSS filed of the gdt gdt[SEG_TSS] = SEGTSS(STS_T32A, (uintptr_t)&ts, sizeof(ts), DPL_KERNEL); - + // 使用lgdt加载全局描述符表,更新所有段寄存器 // reload all segment registers lgdt(&gdt_pd); - + // 加载 TSS,使 CPU 在进行特权级切换时能够正确使用 TSS。 // load the TSS ltr(GD_TSS); } //init_pmm_manager - initialize a pmm_manager instance +//初始化一个 pmm_manager 实例 static void init_pmm_manager(void) { + //将 pmm_manager 指向默认的 PMM 管理器实例。 pmm_manager = &default_pmm_manager; + //使用 cprintf 打印当前内存管理器的名称。 cprintf("memory management: %s\n", pmm_manager->name); + //调用 PMM 管理器的初始化函数,以设置和准备内存管理的相关数据结构。 pmm_manager->init(); } -//init_memmap - call pmm->init_memmap to build Page struct for free memory +//init_memmap - call pmm->init_memmap to build Page struct for free memory +// init_memmap - 调用 pmm->init_memmap 构建空闲内存的 Page 结构 +//struct Page *base:指向内存页的基础地址。 size_t n:要初始化的页数。 static void init_memmap(struct Page *base, size_t n) { pmm_manager->init_memmap(base, n); } //alloc_pages - call pmm->alloc_pages to allocate a continuous n*PAGESIZE memory +// alloc_pages - 调用 pmm->alloc_pages 分配连续的 n*PAGESIZE 内存 struct Page * alloc_pages(size_t n) { struct Page *page=NULL; bool intr_flag; - + //使用 local_intr_save 保存当前的中断状态,以避免在分配内存时发生中断。 while (1) { local_intr_save(intr_flag); { - page = pmm_manager->alloc_pages(n); + page = pmm_manager->alloc_pages(n);//尝试分配 n 个页面。 } local_intr_restore(intr_flag); @@ -176,11 +217,15 @@ alloc_pages(size_t n) { } //free_pages - call pmm->free_pages to free a continuous n*PAGESIZE memory +// free_pages - 调用 pmm->free_pages 释放连续的 n*PAGESIZE 内存 +//struct Page *base:指向要释放的内存页的基础地址。size_t n:要释放的页数。 void free_pages(struct Page *base, size_t n) { bool intr_flag; + //使用 local_intr_save 保存当前的中断状态,以避免在释放内存时发生中断。 local_intr_save(intr_flag); { + //调用物理内存管理器的 free_pages 函数释放 n 页的内存。 pmm_manager->free_pages(base, n); } local_intr_restore(intr_flag); @@ -188,65 +233,68 @@ free_pages(struct Page *base, size_t n) { //nr_free_pages - call pmm->nr_free_pages to get the size (nr*PAGESIZE) //of current free memory +// nr_free_pages - 调用 pmm->nr_free_pages 获取当前空闲内存的大小 (nr * PAGESIZE) size_t nr_free_pages(void) { - size_t ret; - bool intr_flag; - local_intr_save(intr_flag); + size_t ret;// 定义变量 ret 用于存储返回的空闲内存大小 + bool intr_flag;// 定义变量 intr_flag 用于保存中断状态 + local_intr_save(intr_flag);// 保存当前中断状态,并禁用中断 { - ret = pmm_manager->nr_free_pages(); + ret = pmm_manager->nr_free_pages();// 调用物理内存管理器的函数获取空闲内存页数 } - local_intr_restore(intr_flag); - return ret; + local_intr_restore(intr_flag);// 恢复之前保存的中断状态 + return ret;// 返回空闲内存的大小 } /* pmm_init - initialize the physical memory management */ +/* pmm_init - 初始化物理内存管理 */ static void page_init(void) { + // 获取物理内存映射信息,存于特定地址 struct e820map *memmap = (struct e820map *)(0x8000 + KERNBASE); - uint64_t maxpa = 0; - - cprintf("e820map:\n"); + uint64_t maxpa = 0;// 初始化最大物理地址为0 + + cprintf("e820map:\n");// 打印“e820map”标题 int i; - for (i = 0; i < memmap->nr_map; i ++) { - uint64_t begin = memmap->map[i].addr, end = begin + memmap->map[i].size; - cprintf(" memory: %08llx, [%08llx, %08llx], type = %d.\n", + for (i = 0; i < memmap->nr_map; i ++) {// 遍历内存映射数组 + uint64_t begin = memmap->map[i].addr, end = begin + memmap->map[i].size;// 获取每个区域的起始和结束地址 + cprintf(" memory: %08llx, [%08llx, %08llx], type = %d.\n",// 打印内存区域的信息 memmap->map[i].size, begin, end - 1, memmap->map[i].type); - if (memmap->map[i].type == E820_ARM) { - if (maxpa < end && begin < KMEMSIZE) { - maxpa = end; + if (memmap->map[i].type == E820_ARM) {// 检查内存类型是否为可用内存 + if (maxpa < end && begin < KMEMSIZE) {// 检查当前区域是否在有效范围内 + maxpa = end;// 更新最大物理地址 } } } - if (maxpa > KMEMSIZE) { - maxpa = KMEMSIZE; + if (maxpa > KMEMSIZE) {// 如果最大物理地址超过了预定义的内存上限 + maxpa = KMEMSIZE;// 将其限制为内存上限 } - extern char end[]; + extern char end[];// 引入全局变量 end,指向内存的结束位置 - npage = maxpa / PGSIZE; - pages = (struct Page *)ROUNDUP((void *)end, PGSIZE); + npage = maxpa / PGSIZE;// 计算可用页数 + pages = (struct Page *)ROUNDUP((void *)end, PGSIZE);// 将 end 对齐到页边界,指向页结构数组的开头 - for (i = 0; i < npage; i ++) { - SetPageReserved(pages + i); + for (i = 0; i < npage; i ++) {// 遍历每一页 + SetPageReserved(pages + i);// 将每一页标记为保留状态 } - uintptr_t freemem = PADDR((uintptr_t)pages + sizeof(struct Page) * npage); + uintptr_t freemem = PADDR((uintptr_t)pages + sizeof(struct Page) * npage);// 计算可用内存的起始地址 - for (i = 0; i < memmap->nr_map; i ++) { - uint64_t begin = memmap->map[i].addr, end = begin + memmap->map[i].size; - if (memmap->map[i].type == E820_ARM) { - if (begin < freemem) { - begin = freemem; + for (i = 0; i < memmap->nr_map; i ++) {// 再次遍历内存映射 + uint64_t begin = memmap->map[i].addr, end = begin + memmap->map[i].size;// 获取每个区域的起始和结束地址 + if (memmap->map[i].type == E820_ARM) {// 如果区域类型为可用内存 + if (begin < freemem) {// 如果起始地址小于可用内存地址 + begin = freemem;//将起始地址设置为可用内存地址 } - if (end > KMEMSIZE) { - end = KMEMSIZE; + if (end > KMEMSIZE) {// 如果结束地址超过内存上限 + end = KMEMSIZE;// 将其限制为内存上限 } - if (begin < end) { - begin = ROUNDUP(begin, PGSIZE); - end = ROUNDDOWN(end, PGSIZE); - if (begin < end) { - init_memmap(pa2page(begin), (end - begin) / PGSIZE); + if (begin < end) {// 如果起始地址小于结束地址 + begin = ROUNDUP(begin, PGSIZE);// 将起始地址对齐到页边界 + end = ROUNDDOWN(end, PGSIZE);// 将结束地址对齐到页边界 + if (begin < end) {// 如果调整后的起始地址仍小于结束地址 + init_memmap(pa2page(begin), (end - begin) / PGSIZE);// 初始化内存页映射 } } } @@ -255,19 +303,29 @@ page_init(void) { //boot_map_segment - setup&enable the paging mechanism // parameters +// boot_map_segment - 设置并启用分页机制 // la: linear address of this memory need to map (after x86 segment map) -// size: memory size -// pa: physical address of this memory -// perm: permission of this memory +//la: 需要映射的线性地址(经过 x86 段映射后的地址) +// size: memory size size: 内存大小 +// pa: physical address of this memory pa:该内存的物理地址 +// perm: permission of this memory perm: 该内存的权限 static void boot_map_segment(pde_t *pgdir, uintptr_t la, size_t size, uintptr_t pa, uint32_t perm) { + // 确保线性地址和物理地址的页偏移相同 assert(PGOFF(la) == PGOFF(pa)); + // 计算需要映射的页数,ROUNDUP 将总大小对齐到下一个页大小的边界 size_t n = ROUNDUP(size + PGOFF(la), PGSIZE) / PGSIZE; + // 将线性地址向下对齐到页边界 la = ROUNDDOWN(la, PGSIZE); + // 将物理地址向下对齐到页边界 pa = ROUNDDOWN(pa, PGSIZE); + // 循环遍历每一页,直到映射的页数为零 for (; n > 0; n --, la += PGSIZE, pa += PGSIZE) { + // 获取当前页的页表项指针,如果不存在则创建新的页表项 pte_t *ptep = get_pte(pgdir, la, 1); + // 确保页表项指针不为空 assert(ptep != NULL); + // 设置页表项,包含物理地址、存在位和权限 *ptep = pa | PTE_P | perm; } } @@ -275,20 +333,25 @@ boot_map_segment(pde_t *pgdir, uintptr_t la, size_t size, uintptr_t pa, uint32_t //boot_alloc_page - allocate one page using pmm->alloc_pages(1) // return value: the kernel virtual address of this allocated page //note: this function is used to get the memory for PDT(Page Directory Table)&PT(Page Table) +//boot_alloc_page - 使用 pmm->alloc_pages(1) 分配一页内存.返回值: 分配的页面的内核虚拟地址 +//注意: 此函数用于获取页目录表(PDT)和页表(PT)的内存 static void * boot_alloc_page(void) { - struct Page *p = alloc_page(); - if (p == NULL) { - panic("boot_alloc_page failed.\n"); + struct Page *p = alloc_page();// 调用分配页面的函数 + if (p == NULL) {// 检查分配是否成功 + panic("boot_alloc_page failed.\n");// 如果分配失败,则触发异常 } - return page2kva(p); + return page2kva(p);// 返回分配页面的内核虚拟地址 } //pmm_init - setup a pmm to manage physical memory, build PDT&PT to setup paging mechanism // - check the correctness of pmm & paging mechanism, print PDT&PT +//pmm_init - 设置物理内存管理器,构建页目录表(PDT)和页表(PT),以设置分页机制 +// - 检查物理内存管理器和分页机制的正确性,打印页目录表和页表 void pmm_init(void) { // We've already enabled paging + // 我们已经启用了分页 boot_cr3 = PADDR(boot_pgdir); //We need to alloc/free the physical memory (granularity is 4KB or other size). @@ -296,39 +359,56 @@ pmm_init(void) { //First we should init a physical memory manager(pmm) based on the framework. //Then pmm can alloc/free the physical memory. //Now the first_fit/best_fit/worst_fit/buddy_system pmm are available. - init_pmm_manager(); + // 我们需要分配/释放物理内存(粒度为 4KB 或其他大小)。 + // 因此在 pmm.h 中定义了物理内存管理器的框架(struct pmm_manager)。 + // 首先,我们应该基于该框架初始化一个物理内存管理器(pmm)。 + // 然后 pmm 可以分配/释放物理内存。 + // 现在,first_fit/best_fit/worst_fit/buddy_system 的 pmm 都可用。 + init_pmm_manager();// 初始化物理内存管理器 // detect physical memory space, reserve already used memory, // then use pmm->init_memmap to create free page list - page_init(); + // 检测物理内存空间,保留已经使用的内存, + // 然后使用 pmm->init_memmap 创建空闲页面列表 + page_init();// 初始化页面管理 //use pmm->check to verify the correctness of the alloc/free function in a pmm - check_alloc_page(); + // 使用 pmm->check 验证 pmm 中分配/释放函数的正确性 + check_alloc_page();// 检查页面分配功能 - check_pgdir(); + check_pgdir();// 检查页目录的状态 - static_assert(KERNBASE % PTSIZE == 0 && KERNTOP % PTSIZE == 0); + static_assert(KERNBASE % PTSIZE == 0 && KERNTOP % PTSIZE == 0);// 确保 KERNBASE 和 KERNTOP 是页大小的倍数 // recursively insert boot_pgdir in itself // to form a virtual page table at virtual address VPT - boot_pgdir[PDX(VPT)] = PADDR(boot_pgdir) | PTE_P | PTE_W; + // 递归地将 boot_pgdir 插入到自身中 + // 在虚拟地址 VPT 处形成虚拟页表 + boot_pgdir[PDX(VPT)] = PADDR(boot_pgdir) | PTE_P | PTE_W;// 设置页目录项,映射自身 // map all physical memory to linear memory with base linear addr KERNBASE // linear_addr KERNBASE ~ KERNBASE + KMEMSIZE = phy_addr 0 ~ KMEMSIZE - boot_map_segment(boot_pgdir, KERNBASE, KMEMSIZE, 0, PTE_W); + // 将所有物理内存映射到线性内存,基地址为 KERNBASE + // 线性地址 KERNBASE ~ KERNBASE + KMEMSIZE = 物理地址 0 ~ KMEMSIZE + boot_map_segment(boot_pgdir, KERNBASE, KMEMSIZE, 0, PTE_W);// 映射物理内存 // Since we are using bootloader's GDT, // we should reload gdt (second time, the last time) to get user segments and the TSS // map virtual_addr 0 ~ 4G = linear_addr 0 ~ 4G // then set kernel stack (ss:esp) in TSS, setup TSS in gdt, load TSS - gdt_init(); + // 由于我们正在使用引导加载程序的 GDT, + // 我们应该重新加载 GDT(第二次,也是最后一次),以获取用户段和 TSS + // 映射虚拟地址 0 ~ 4G = 线性地址 0 ~ 4G + // 然后在 TSS 中设置内核栈 (ss:esp),在 gdt 中设置 TSS,加载 TSS + gdt_init();// 初始化全局描述符表 //now the basic virtual memory map(see memalyout.h) is established. //check the correctness of the basic virtual memory map. - check_boot_pgdir(); + // 现在基本的虚拟内存映射(见 memlayout.h)已建立。 + // 检查基础虚拟内存映射的正确性。 + check_boot_pgdir(); // 检查页目录的正确性 - print_pgdir(); - + print_pgdir(); // 打印页目录表 kmalloc_init(); } @@ -340,6 +420,13 @@ pmm_init(void) { // la: the linear address need to map // create: a logical value to decide if alloc a page for PT // return vaule: the kernel virtual address of this pte +// get_pte - 获取页表项(PTE),并返回该 PTE 的内核虚拟地址 +// 如果页表中不存在该 PTE,则为页表分配一页 +// 参数: +// pgdir: 页目录的内核虚拟基地址 +// la: 需要映射的线性地址 +// create: 一个逻辑值,决定是否为页表分配一页 +// 返回值:该 PTE 的内核虚拟地址 pte_t * get_pte(pde_t *pgdir, uintptr_t la, bool create) { /* LAB2 EXERCISE 2: YOUR CODE @@ -375,18 +462,42 @@ get_pte(pde_t *pgdir, uintptr_t la, bool create) { } return NULL; // (8) return page table entry #endif + // (1) 找到页目录项 + pde_t *pdep = &pgdir[PDX(la)];// 使用 PDX 宏获取页目录索引 + // (2) 检查页目录项是否存在 + if (!(*pdep & PTE_P)) {// 如果页目录项的存在位 PTE_P 没有被设置 + struct Page *page;// 声明一个指针,用于指向新分配的页面 + // 检查是否允许创建新页表,或者分配页表失败 + if (!create || (page = alloc_page()) == NULL) {// 如果不允许创建或分配失败 + return NULL;// 返回 NULL,表示无法获取页表 + } + // 设置新分配页面的引用计数为 1 + set_page_ref(page, 1); + uintptr_t pa = page2pa(page);// 获取新分配页面的物理地址 + memset(KADDR(pa), 0, PGSIZE);// 清空新分配的页表内容,初始化为零 + // 更新页目录项,设置物理地址和权限位 + *pdep = pa | PTE_U | PTE_W | PTE_P;// 将物理地址和权限位(用户可访问、可写、有效)合并设置 + } + // 返回指定线性地址 la 对应的页表项的内核虚拟地址 + return &((pte_t *)KADDR(PDE_ADDR(*pdep)))[PTX(la)];// 计算并返回页表项的指针 } //get_page - get related Page struct for linear address la using PDT pgdir +// get_page - 获取与线性地址 la 相关的 Page 结构体,使用页目录 pgdir struct Page * get_page(pde_t *pgdir, uintptr_t la, pte_t **ptep_store) { + // 调用 get_pte 函数获取对应线性地址 la 的页表项指针 pte_t *ptep = get_pte(pgdir, la, 0); + // 如果 ptep_store 指针不为 NULL,将 ptep 存储到 ptep_store 指向的位置 if (ptep_store != NULL) { - *ptep_store = ptep; + *ptep_store = ptep; // 存储当前页表项的指针 } + // 检查 ptep 是否有效以及页表项的存在位 PTE_P 是否被设置 if (ptep != NULL && *ptep & PTE_P) { - return pte2page(*ptep); + // 返回与页表项对应的 Page 结构体 + return pte2page(*ptep);// 将页表项转换为对应的 Page 结构 } + // 如果未找到有效的页,返回 NULL return NULL; } @@ -420,6 +531,15 @@ page_remove_pte(pde_t *pgdir, uintptr_t la, pte_t *ptep) { //(6) flush tlb } #endif + if (*ptep & PTE_P) { + struct Page *page = pte2page(*ptep);// 找到对应的物理页 + // 减少物理页的引用计数,如果引用计数为零,释放该物理页 + if (page_ref_dec(page) == 0) { + free_page(page); + } + *ptep = 0;// 清除页表项 + tlb_invalidate(pgdir, la);// 刷新 TLB + } } void @@ -462,28 +582,49 @@ exit_range(pde_t *pgdir, uintptr_t start, uintptr_t end) { * * CALL GRAPH: copy_mm-->dup_mmap-->copy_range */ +/** + * 复制一个地址范围内的页面从一个进程的地址空间到另一个进程的地址空间。 + * + * @param to 目标进程的页目录。 + * @param from 源进程的页目录。 + * @param start 要复制的范围的起始地址。 + * @param end 要复制的范围的结束地址。 + * @param share 是否共享页面。 + * + * @return 成功返回0,失败返回错误码。 + */ int copy_range(pde_t *to, pde_t *from, uintptr_t start, uintptr_t end, bool share) { + //确保起始地址和结束地址都是页对齐的 assert(start % PGSIZE == 0 && end % PGSIZE == 0); + // 确保地址范围在用户空间内 assert(USER_ACCESS(start, end)); - // copy content by page unit. + // copy content by page unit. // 按页单位复制内容 do { //call get_pte to find process A's pte according to the addr start + // 调用 get_pte 根据起始地址找到进程 A 的页表项 pte_t *ptep = get_pte(from, start, 0), *nptep; if (ptep == NULL) { + // 如果页表项不存在,跳过当前页 start = ROUNDDOWN(start + PTSIZE, PTSIZE); continue ; } //call get_pte to find process B's pte according to the addr start. If pte is NULL, just alloc a PT + // 调用 get_pte 根据起始地址找到进程 B 的页表项。如果页表项不存在,分配一个新的页表 if (*ptep & PTE_P) { if ((nptep = get_pte(to, start, 1)) == NULL) { + // 分配页表失败,返回内存不足错误 return -E_NO_MEM; } + // 获取页表项的权限 uint32_t perm = (*ptep & PTE_USER); //get page from ptep + // 从页表项获取物理页面 struct Page *page = pte2page(*ptep); // alloc a page for process B + // 为进程 B 分配一个物理页面 struct Page *npage=alloc_page(); + // 断言页面不为空 assert(page!=NULL); assert(npage!=NULL); int ret=0; @@ -501,6 +642,28 @@ copy_range(pde_t *to, pde_t *from, uintptr_t start, uintptr_t end, bool share) { * (3) memory copy from src_kvaddr to dst_kvaddr, size is PGSIZE * (4) build the map of phy addr of nage with the linear addr start */ + /* 实验5:练习2 你的代码 + * 复制 page 的内容到 npage,并建立 npage 的物理地址与线性地址 start 的映射 + * + * 以下是一些有用的宏和定义,你可以在下面的实现中使用它们。 + * 宏或函数: + * page2kva(struct Page *page): 返回 page 管理的内存在内核虚拟地址空间中的地址 (参见 pmm.h) + * page_insert: 建立物理地址与线性地址 la 的映射 + * memcpy: 典型的内存复制函数 + * + * (1) 找到 src_kvaddr: page 的内核虚拟地址 + * (2) 找到 dst_kvaddr: npage 的内核虚拟地址 + * (3) 从 src_kvaddr 复制内存到 dst_kvaddr,大小为 PGSIZE + * (4) 建立 npage 的物理地址与线性地址 start 的映射 + */ + // 获取源页面的内核虚拟地址 + void * kva_src = page2kva(page); + // 获取目标页面的内核虚拟地址 + void * kva_dst = page2kva(npage); + // 将源页面的内容复制到目标页面 + memcpy(kva_dst, kva_src, PGSIZE); + // 将目标页面插入到目标进程的页表中,映射到线性地址 start,并设置权限 perm + ret = page_insert(to, npage, start, perm); assert(ret == 0); } start += PGSIZE; @@ -509,9 +672,12 @@ copy_range(pde_t *to, pde_t *from, uintptr_t start, uintptr_t end, bool share) { } //page_remove - free an Page which is related linear address la and has an validated pte +//移除一个虚拟地址对应的页面 void page_remove(pde_t *pgdir, uintptr_t la) { + //调用 get_pte 函数获取给定虚拟地址 la 对应的页表项指针 ptep。 pte_t *ptep = get_pte(pgdir, la, 0); + //如果 ptep 不为 NULL,则调用 page_remove_pte 函数移除该页表项。 if (ptep != NULL) { page_remove_pte(pgdir, la, ptep); } @@ -525,32 +691,41 @@ page_remove(pde_t *pgdir, uintptr_t la) { // perm: the permission of this Page which is setted in related pte // return value: always 0 //note: PT is changed, so the TLB need to be invalidate +//将一个页面插入到页表中。 int page_insert(pde_t *pgdir, struct Page *page, uintptr_t la, uint32_t perm) { + //通过 get_pte 函数获取指定虚拟地址 la 对应的页表项指针 ptep。 pte_t *ptep = get_pte(pgdir, la, 1); + //如果 ptep 为 NULL,表示内存分配失败,返回 -E_NO_MEM。 if (ptep == NULL) { return -E_NO_MEM; } + //调用 page_ref_inc 增加页面的引用计数。 page_ref_inc(page); + //如果页表项已存在且指向当前页面,则减少页面引用计数。 if (*ptep & PTE_P) { struct Page *p = pte2page(*ptep); if (p == page) { page_ref_dec(page); } + //如果页表项已存在但指向其他页面,则调用 page_remove_pte 移除旧的页表项。 else { page_remove_pte(pgdir, la, ptep); } } *ptep = page2pa(page) | PTE_P | perm; - tlb_invalidate(pgdir, la); + tlb_invalidate(pgdir, la);//刷新 TLB return 0; } // invalidate a TLB entry, but only if the page tables being // edited are the ones currently in use by the processor. +//无效化指定地址的TLB条目 void tlb_invalidate(pde_t *pgdir, uintptr_t la) { + //检查当前页目录地址是否与传入的页目录地址相同。 if (rcr3() == PADDR(pgdir)) { + //如果相同,则调用 invlpg 函数无效化指定线性地址的TLB条目。 invlpg((void *)la); } } @@ -560,16 +735,19 @@ tlb_invalidate(pde_t *pgdir, uintptr_t la) { // - pa<->la with linear address la and the PDT pgdir struct Page * pgdir_alloc_page(pde_t *pgdir, uintptr_t la, uint32_t perm) { - struct Page *page = alloc_page(); - if (page != NULL) { - if (page_insert(pgdir, page, la, perm) != 0) { - free_page(page); - return NULL; + struct Page *page = alloc_page();//分配一个新的页面存储在 page 指针中 + if (page != NULL) {//检查 page 是否不为 NULL,即分配是否成功。 + if (page_insert(pgdir, page, la, perm) != 0) {//将页面插入到指定的线性地址 la 处。 + free_page(page);//释放分配的页面。 + return NULL;//返回 NULL,表示页面插入失败。 } - if (swap_init_ok){ + if (swap_init_ok){//检查交换区是否已初始化成功 if(check_mm_struct!=NULL) { + //将页面映射到交换区 swap_map_swappable(check_mm_struct, la, page, 0); + //设置页面的虚拟地址 pra_vaddr 为 la page->pra_vaddr=la; + //断言页面的引用计数为1,确保页面没有被其他地方引用。 assert(page_ref(page) == 1); //cprintf("get No. %d page: pra_vaddr %x, pra_link.prev %x, pra_link_next %x in pgdir_alloc_page\n", (page-pages), page->pra_vaddr,page->pra_page_link.prev, page->pra_page_link.next); } @@ -588,99 +766,145 @@ pgdir_alloc_page(pde_t *pgdir, uintptr_t la, uint32_t perm) { static void check_alloc_page(void) { + //调用内存管理器的 check 方法,用于检查内存分配是否正常。 pmm_manager->check(); cprintf("check_alloc_page() succeeded!\n"); } +//用于验证页目录和页表的正确性。 static void check_pgdir(void) { + //确保内存页面数量在合理范围内 assert(npage <= KMEMSIZE / PGSIZE); + //确保页目录不为空且对齐, assert(boot_pgdir != NULL && (uint32_t)PGOFF(boot_pgdir) == 0); + //确保虚拟地址 0x0 没有映射任何页面 assert(get_page(boot_pgdir, 0x0, NULL) == NULL); - + + //定义两个页面指针 p1 和 p2 struct Page *p1, *p2; + //分配一个页面 p1 p1 = alloc_page(); + //将 p1 插入到虚拟地址 0x0 assert(page_insert(boot_pgdir, p1, 0x0, 0) == 0); + // 获取虚拟地址 0x0 对应的页表项指针 pte_t *ptep; assert((ptep = get_pte(boot_pgdir, 0x0, 0)) != NULL); + // 验证页表项对应的页面是 p1 assert(pte2page(*ptep) == p1); + // 验证 p1 的引用计数为 1 assert(page_ref(p1) == 1); - + // 获取虚拟地址 PGSIZE 对应的页表项指针 ptep = &((pte_t *)KADDR(PDE_ADDR(boot_pgdir[0])))[1]; assert(get_pte(boot_pgdir, PGSIZE, 0) == ptep); - + // 分配一个页面 p2 p2 = alloc_page(); + // 将 p2 插入到虚拟地址 PGSIZE,并设置用户和写权限 assert(page_insert(boot_pgdir, p2, PGSIZE, PTE_U | PTE_W) == 0); + // 获取虚拟地址 PGSIZE 对应的页表项指针 assert((ptep = get_pte(boot_pgdir, PGSIZE, 0)) != NULL); + // 验证页表项设置了用户权限 assert(*ptep & PTE_U); + // 验证页表项设置了写权限 assert(*ptep & PTE_W); + // 验证页目录项设置了用户权限 assert(boot_pgdir[0] & PTE_U); + // 验证 p2 的引用计数为 1 assert(page_ref(p2) == 1); + // 将 p1 插入到虚拟地址 PGSIZE,替换掉 p2 assert(page_insert(boot_pgdir, p1, PGSIZE, 0) == 0); + // 验证 p1 的引用计数增加到 2 assert(page_ref(p1) == 2); + // 验证 p2 的引用计数减少到 0 assert(page_ref(p2) == 0); + // 获取虚拟地址 PGSIZE 对应的页表项指针 assert((ptep = get_pte(boot_pgdir, PGSIZE, 0)) != NULL); + // 验证页表项对应的页面是 p1 assert(pte2page(*ptep) == p1); + // 验证页表项没有设置用户权限 assert((*ptep & PTE_U) == 0); - + + //移除虚拟地址 0x0 的映射, page_remove(boot_pgdir, 0x0); + //验证 p1 的引用计数减少到 1。 assert(page_ref(p1) == 1); + //验证 p2 的引用计数减少到 0 assert(page_ref(p2) == 0); + //移除虚拟地址 PGSIZE 的映射, page_remove(boot_pgdir, PGSIZE); + //验证 p1 的引用计数减少到 0 assert(page_ref(p1) == 0); + //验证 p2 的引用计数减少到 0 assert(page_ref(p2) == 0); - + + //验证页目录的第一页表的引用计数为 1。 assert(page_ref(pde2page(boot_pgdir[0])) == 1); + //释放页目录的第一页表 free_page(pde2page(boot_pgdir[0])); + //清空页目录的第一页表 boot_pgdir[0] = 0; cprintf("check_pgdir() succeeded!\n"); } +//检查内核页表 boot_pgdir 的正确性 static void check_boot_pgdir(void) { - pte_t *ptep; + pte_t *ptep;// 定义一个指向页表项的指针 int i; - for (i = 0; i < npage; i += PGSIZE) { + for (i = 0; i < npage; i += PGSIZE) {// 遍历所有页面 + // 获取第 i 个页面的页表项,并确保其不为空 assert((ptep = get_pte(boot_pgdir, (uintptr_t)KADDR(i), 0)) != NULL); + // 验证页表项的物理地址是否正确 assert(PTE_ADDR(*ptep) == i); } - + // 验证页目录项的物理地址是否正确 assert(PDE_ADDR(boot_pgdir[PDX(VPT)]) == PADDR(boot_pgdir)); - assert(boot_pgdir[0] == 0); + assert(boot_pgdir[0] == 0);// 确保页目录的第一个项为0 - struct Page *p; - p = alloc_page(); + struct Page *p;// 定义一个指向页面的指针 + p = alloc_page();// 分配一个页面 + // 将页面插入到虚拟地址 0x100,并确保操作成功 assert(page_insert(boot_pgdir, p, 0x100, PTE_W) == 0); - assert(page_ref(p) == 1); + assert(page_ref(p) == 1);// 验证页面的引用计数为1 + // 将页面插入到虚拟地址 0x100 + PGSIZE,并确保操作成功 assert(page_insert(boot_pgdir, p, 0x100 + PGSIZE, PTE_W) == 0); - assert(page_ref(p) == 2); + assert(page_ref(p) == 2);// 验证页面的引用计数为2 - const char *str = "ucore: Hello world!!"; - strcpy((void *)0x100, str); + const char *str = "ucore: Hello world!!";// 定义一个字符串 + strcpy((void *)0x100, str);// 将字符串复制到虚拟地址 0x100 + // 验证两个映射地址的数据是否一致 assert(strcmp((void *)0x100, (void *)(0x100 + PGSIZE)) == 0); - + // 在页面的 0x100 偏移处设置字符串结束符 *(char *)(page2kva(p) + 0x100) = '\0'; - assert(strlen((const char *)0x100) == 0); - - free_page(p); - free_page(pde2page(boot_pgdir[0])); - boot_pgdir[0] = 0; + assert(strlen((const char *)0x100) == 0);// 验证字符串长度为0 + free_page(p);// 释放页面 p + free_page(pde2page(boot_pgdir[0]));// 释放页目录项对应的页面 + boot_pgdir[0] = 0;// 将页目录的第一个项设为0 + + tlb_invalidate(boot_pgdir, 0x100); + tlb_invalidate(boot_pgdir, 0x100+PGSIZE); + cprintf("check_boot_pgdir() succeeded!\n"); } //perm2str - use string 'u,r,w,-' to present the permission static const char * perm2str(int perm) { + //定义一个静态字符数组 str,长度为4 static char str[4]; + //如果 perm 与 PTE_U 按位与的结果不为0,则 str[0] 设置为 'u',否则设置为 '-' str[0] = (perm & PTE_U) ? 'u' : '-'; + //str[1] 始终设置为 'r' str[1] = 'r'; + //如果 perm 与 PTE_W 按位与的结果不为0,则 str[2] 设置为 'w',否则设置为 '-' str[2] = (perm & PTE_W) ? 'w' : '-'; + //str[3] 设置为字符串结束符 \0 str[3] = '\0'; return str; } @@ -696,40 +920,47 @@ perm2str(int perm) { // left_store: the pointer of the high side of table's next range // right_store: the pointer of the low side of table's next range // return value: 0 - not a invalid item range, perm - a valid item range with perm permission +//从页表中获取指定范围内的有效项,并根据权限进行处理。 static int get_pgtable_items(size_t left, size_t right, size_t start, uintptr_t *table, size_t *left_store, size_t *right_store) { - if (start >= right) { - return 0; + if (start >= right) {// 检查起始索引是否超出右边界 + return 0;// 如果超出右边界,返回0 } - while (start < right && !(table[start] & PTE_P)) { - start ++; + while (start < right && !(table[start] & PTE_P)) {// 查找第一个有效项(PTE_P位为1的项) + start ++;// 索引递增 } - if (start < right) { - if (left_store != NULL) { - *left_store = start; + if (start < right) {// 检查是否找到有效项 + if (left_store != NULL) {// 如果left_store不为NULL + *left_store = start;// 记录左边界索引 } - int perm = (table[start ++] & PTE_USER); - while (start < right && (table[start] & PTE_USER) == perm) { - start ++; + int perm = (table[start ++] & PTE_USER);// 获取当前项的用户权限位并递增索引 + while (start < right && (table[start] & PTE_USER) == perm) {// 查找具有相同用户权限的连续项 + start ++;// 索引递增 } - if (right_store != NULL) { - *right_store = start; + if (right_store != NULL) {// 如果right_store不为NULL + *right_store = start;// 记录右边界索引 } - return perm; + return perm;// 返回用户权限位 } - return 0; + return 0;// 如果未找到有效项,返回0 } //print_pgdir - print the PDT&PT void print_pgdir(void) { cprintf("-------------------- BEGIN --------------------\n"); + // 定义变量 left, right 和 perm size_t left, right = 0, perm; + // 遍历页目录项 while ((perm = get_pgtable_items(0, NPDEENTRY, right, vpd, &left, &right)) != 0) { + // 打印页目录项的信息 cprintf("PDE(%03x) %08x-%08x %08x %s\n", right - left, left * PTSIZE, right * PTSIZE, (right - left) * PTSIZE, perm2str(perm)); + // 计算页表项的起始和结束索引 size_t l, r = left * NPTEENTRY; + // 遍历页表项 while ((perm = get_pgtable_items(left * NPTEENTRY, right * NPTEENTRY, r, vpt, &l, &r)) != 0) { + // 打印页表项的信息 cprintf(" |-- PTE(%05x) %08x-%08x %08x %s\n", r - l, l * PGSIZE, r * PGSIZE, (r - l) * PGSIZE, perm2str(perm)); } diff --git a/labcodes/lab5/kern/mm/swap.c b/labcodes/lab5/kern/mm/swap.c index 704ec18d3801939fa589399a4d57d3b1c737f74d..6c7e6b0c71b2ad0cb9647f89721fc33097014e59 100644 --- a/labcodes/lab5/kern/mm/swap.c +++ b/labcodes/lab5/kern/mm/swap.c @@ -176,85 +176,87 @@ extern free_area_t free_area; #define free_list (free_area.free_list) #define nr_free (free_area.nr_free) -static void check_swap(void) { - //backup mem env + //backup mem env// 备份内存环境,确保检查后没有页面丢失 int ret, count = 0, total = 0, i; list_entry_t *le = &free_list; while ((le = list_next(le)) != &free_list) { - struct Page *p = le2page(le, page_link); - assert(PageProperty(p)); - count ++, total += p->property; + struct Page *p = le2page(le, page_link);// 将链表条目转换为页面结构 + assert(PageProperty(p));// 断言页面属性有效 + count ++, total += p->property;// 统计页面数量和属性总和 } - assert(total == nr_free_pages()); - cprintf("BEGIN check_swap: count %d, total %d\n",count,total); + assert(total == nr_free_pages());// 断言统计的属性总和与空闲页面数一致 + cprintf("BEGIN check_swap: count %d, total %d\n",count,total);// 打印初始状态 - //now we set the phy pages env - struct mm_struct *mm = mm_create(); - assert(mm != NULL); + //now we set the phy pages env // 设置物理页面环境 + struct mm_struct *mm = mm_create();// 创建内存管理结构 + assert(mm != NULL); // 断言内存管理结构创建成功 - extern struct mm_struct *check_mm_struct; - assert(check_mm_struct == NULL); + extern struct mm_struct *check_mm_struct;// 声明外部变量 + assert(check_mm_struct == NULL);// 断言外部变量为空 + // 将新创建的内存管理结构赋值给外部变量 check_mm_struct = mm; - pde_t *pgdir = mm->pgdir = boot_pgdir; - assert(pgdir[0] == 0); + pde_t *pgdir = mm->pgdir = boot_pgdir;// 设置页目录 + assert(pgdir[0] == 0);// 断言页目录的第一个条目为空 + // 创建虚拟内存区域 struct vma_struct *vma = vma_create(BEING_CHECK_VALID_VADDR, CHECK_VALID_VADDR, VM_WRITE | VM_READ); - assert(vma != NULL); + assert(vma != NULL);// 断言虚拟内存区域创建成功 + // 插入虚拟内存区域到内存管理结构 insert_vma_struct(mm, vma); - //setup the temp Page Table vaddr 0~4MB - cprintf("setup Page Table for vaddr 0X1000, so alloc a page\n"); + //setup the temp Page Table vaddr 0~4MB/ 设置临时页表,用于虚拟地址 0~4MB + cprintf("setup Page Table for vaddr 0X1000, so alloc a page\n");// 打印设置页表的信息 pte_t *temp_ptep=NULL; - temp_ptep = get_pte(mm->pgdir, BEING_CHECK_VALID_VADDR, 1); - assert(temp_ptep!= NULL); - cprintf("setup Page Table vaddr 0~4MB OVER!\n"); + temp_ptep = get_pte(mm->pgdir, BEING_CHECK_VALID_VADDR, 1);// 获取页表项 + assert(temp_ptep!= NULL);// 断言获取页表项成功 + cprintf("setup Page Table vaddr 0~4MB OVER!\n");// 打印设置页表完成的信息 for (i=0;iphy_page environment for page relpacement algorithm - + // 设置初始虚拟到物理页面环境,用于页面替换算法 - pgfault_num=0; + pgfault_num=0;// 初始化页面故障数 - check_content_set(); - assert( nr_free == 0); + check_content_set();// 设置检查内容 + assert( nr_free == 0); // 断言空闲页面数为 0 for(i = 0; ipgdir = NULL; - mm_destroy(mm); + mm_destroy(mm);// 销毁内存管理结构 check_mm_struct = NULL; - nr_free = nr_free_store; - free_list = free_list_store; + nr_free = nr_free_store;// 恢复空闲页面数 + free_list = free_list_store;// 恢复空闲列表 le = &free_list; while ((le = list_next(le)) != &free_list) { - struct Page *p = le2page(le, page_link); - count --, total -= p->property; + struct Page *p = le2page(le, page_link);// 将链表条目转换为页面结构 + count --, total -= p->property;// 更新页面数量和属性总和 } - cprintf("count is %d, total is %d\n",count,total); + cprintf("count is %d, total is %d\n",count,total);// 打印恢复后的状态 //assert(count == 0); - cprintf("check_swap() succeeded!\n"); + cprintf("check_swap() succeeded!\n");// 打印检查成功的信息 } diff --git a/labcodes/lab5/kern/mm/swap_fifo.c b/labcodes/lab5/kern/mm/swap_fifo.c index cd96a03d2f2d6db39b1d5406ff49d8b513002ed0..0aad3cd308bd05f64372bd3fa2dda6d76d949b66 100644 --- a/labcodes/lab5/kern/mm/swap_fifo.c +++ b/labcodes/lab5/kern/mm/swap_fifo.c @@ -33,9 +33,12 @@ list_entry_t pra_list_head; static int _fifo_init_mm(struct mm_struct *mm) { + //初始化一个链表头 pra_list_head list_init(&pra_list_head); + //将 mm 结构中的 sm_priv 字段指向这个链表头 mm->sm_priv = &pra_list_head; //cprintf(" mm->sm_priv %x in fifo_init_mm\n",mm->sm_priv); + //返回 0 表示成功 return 0; } /* @@ -44,6 +47,8 @@ _fifo_init_mm(struct mm_struct *mm) static int _fifo_map_swappable(struct mm_struct *mm, uintptr_t addr, struct Page *page, int swap_in) { + //获取 mm_struct 结构中的 sm_priv 指针, + //并将其转换为 list_entry_t 类型的链表头指针 head list_entry_t *head=(list_entry_t*) mm->sm_priv; list_entry_t *entry=&(page->pra_page_link); @@ -51,12 +56,23 @@ _fifo_map_swappable(struct mm_struct *mm, uintptr_t addr, struct Page *page, int //record the page access situlation /*LAB3 EXERCISE 2: YOUR CODE*/ //(1)link the most recent arrival page at the back of the pra_list_head qeueue. + //将最近到达的页面链接到 pra_list_head 队列的末尾 + list_add(head, entry); return 0; } /* * (4)_fifo_swap_out_victim: According FIFO PRA, we should unlink the earliest arrival page in front of pra_list_head qeueue, * then assign the value of *ptr_page to the addr of this page. */ +/** + * _fifo_swap_out_victim 选择一个牺牲页进行换出。 + * + * @param mm 指向内存管理结构的指针,包含页面替换所需的信息。 + * @param ptr_page 指向一个指向页面的指针的指针,用于返回选中的牺牲页。 + * @param in_tick 当前时间刻度,用于检查是否为0。 + * + * @return 返回0表示成功,其他值表示失败。 + */ static int _fifo_swap_out_victim(struct mm_struct *mm, struct Page ** ptr_page, int in_tick) { @@ -67,44 +83,85 @@ _fifo_swap_out_victim(struct mm_struct *mm, struct Page ** ptr_page, int in_tick /*LAB3 EXERCISE 2: YOUR CODE*/ //(1) unlink the earliest arrival page in front of pra_list_head qeueue //(2) assign the value of *ptr_page to the addr of this page + //head->prev 获取链表中最先到达的页面 + list_entry_t *le = head->prev; + assert(head!=le); + struct Page *p = le2page(le, pra_page_link); + //使用 list_del 函数将该页面从链表中移除。 + list_del(le); + assert(p != NULL); + //将移除的页面指针赋值给 *ptr_page + *ptr_page = p; + return 0; } + +/** + * _fifo_check_swap 是一个静态函数,用于验证虚拟内存系统中的 FIFO(先进先出)页面置换算法。 + * 该函数通过向特定的虚拟内存地址写入数据,并检查每次写入后发生的页面故障数量是否符合预期,从而验证 FIFO 页面置换算法的正确性。 + * + * 返回值: + * - 0: 表示所有检查均通过。 + */ static int _fifo_check_swap(void) { + // 写入虚拟页 c 并检查页面故障数 cprintf("write Virt Page c in fifo_check_swap\n"); *(unsigned char *)0x3000 = 0x0c; assert(pgfault_num==4); + + // 写入虚拟页 a 并检查页面故障数 cprintf("write Virt Page a in fifo_check_swap\n"); *(unsigned char *)0x1000 = 0x0a; assert(pgfault_num==4); + + // 写入虚拟页 d 并检查页面故障数 cprintf("write Virt Page d in fifo_check_swap\n"); *(unsigned char *)0x4000 = 0x0d; assert(pgfault_num==4); + + // 写入虚拟页 b 并检查页面故障数 cprintf("write Virt Page b in fifo_check_swap\n"); *(unsigned char *)0x2000 = 0x0b; assert(pgfault_num==4); + + // 写入虚拟页 e 并检查页面故障数 cprintf("write Virt Page e in fifo_check_swap\n"); *(unsigned char *)0x5000 = 0x0e; assert(pgfault_num==5); + + // 再次写入虚拟页 b 并检查页面故障数 cprintf("write Virt Page b in fifo_check_swap\n"); *(unsigned char *)0x2000 = 0x0b; assert(pgfault_num==5); + + // 再次写入虚拟页 a 并检查页面故障数 cprintf("write Virt Page a in fifo_check_swap\n"); *(unsigned char *)0x1000 = 0x0a; assert(pgfault_num==6); + + // 再次写入虚拟页 b 并检查页面故障数 cprintf("write Virt Page b in fifo_check_swap\n"); *(unsigned char *)0x2000 = 0x0b; assert(pgfault_num==7); + + // 再次写入虚拟页 c 并检查页面故障数 cprintf("write Virt Page c in fifo_check_swap\n"); *(unsigned char *)0x3000 = 0x0c; assert(pgfault_num==8); + + // 再次写入虚拟页 d 并检查页面故障数 cprintf("write Virt Page d in fifo_check_swap\n"); *(unsigned char *)0x4000 = 0x0d; assert(pgfault_num==9); + + // 再次写入虚拟页 e 并检查页面故障数 cprintf("write Virt Page e in fifo_check_swap\n"); *(unsigned char *)0x5000 = 0x0e; assert(pgfault_num==10); + + // 再次写入虚拟页 a 并检查页面故障数 cprintf("write Virt Page a in fifo_check_swap\n"); assert(*(unsigned char *)0x1000 == 0x0a); *(unsigned char *)0x1000 = 0x0a; @@ -140,4 +197,4 @@ struct swap_manager swap_manager_fifo = .set_unswappable = &_fifo_set_unswappable, .swap_out_victim = &_fifo_swap_out_victim, .check_swap = &_fifo_check_swap, -}; +}; \ No newline at end of file diff --git a/labcodes/lab5/kern/mm/vmm.c b/labcodes/lab5/kern/mm/vmm.c index f2eb426f8aaba839577f83bee8830a16e64f17a9..88523b40923f33007f0bcfd80387bbacc236dcc9 100644 --- a/labcodes/lab5/kern/mm/vmm.c +++ b/labcodes/lab5/kern/mm/vmm.c @@ -14,22 +14,25 @@ mm is the memory manager for the set of continuous virtual memory area which have the same PDT. vma is a continuous virtual memory area. There a linear link list for vma & a redblack link list for vma in mm. + 虚拟内存管理设计包括两个部分:mm_struct(mm)和 vma_struct(vma)。 + mm 是一组具有相同页目录表(PDT)的连续虚拟内存区域的内存管理器。 + vma 是一个连续的虚拟内存区域。在 mm 中有一个用于 vma 的线性链表和一个用于 vma 的红黑树链表。 --------------- - mm related functions: - golbal functions + mm related functions: 与 mm 相关的函数: + golbal functions 全局函数 struct mm_struct * mm_create(void) void mm_destroy(struct mm_struct *mm) int do_pgfault(struct mm_struct *mm, uint32_t error_code, uintptr_t addr) -------------- - vma related functions: - global functions + vma related functions: 与 vma 相关的函数: + global functions 全局函数 struct vma_struct * vma_create (uintptr_t vm_start, uintptr_t vm_end,...) void insert_vma_struct(struct mm_struct *mm, struct vma_struct *vma) struct vma_struct * find_vma(struct mm_struct *mm, uintptr_t addr) - local functions + local functions 本地函数 inline void check_vma_overlap(struct vma_struct *prev, struct vma_struct *next) --------------- - check correctness functions + check correctness functions 确认正确性函数 void check_vmm(void); void check_vma_struct(void); void check_pgfault(void); @@ -40,19 +43,32 @@ static void check_vma_struct(void); static void check_pgfault(void); // mm_create - alloc a mm_struct & initialize it. +/** + * 创建并初始化一个内存管理结构体 + * + * 此函数负责分配并初始化一个`mm_struct`结构体,该结构体用于描述一个进程的内存空间状态 + * 它包括内存映射列表、页目录、映射缓存等重要信息 + * + * @return 分配并初始化后的`mm_struct`结构体指针,如果分配失败则返回NULL + */ struct mm_struct * mm_create(void) { + // 分配一个mm_struct结构体的空间 struct mm_struct *mm = kmalloc(sizeof(struct mm_struct)); - + // 检查是否成功分配了内存 if (mm != NULL) { + // 初始化内存映射列表 list_init(&(mm->mmap_list)); + // 设置映射缓存为NULL,表示尚未缓存任何映射 mm->mmap_cache = NULL; + // 设置页目录为NULL,表示尚未分配页目录 mm->pgdir = NULL; + // 初始化映射计数为0,表示尚未创建任何内存映射 mm->map_count = 0; - + // 如果交换空间初始化成功,则为当前内存管理结构体进行交换空间初始化 if (swap_init_ok) swap_init_mm(mm); else mm->sm_priv = NULL; - + //设置引用计数和锁: set_mm_count(mm, 0); lock_init(&(mm->mm_lock)); } @@ -60,99 +76,169 @@ mm_create(void) { } // vma_create - alloc a vma_struct & initialize it. (addr range: vm_start~vm_end) +/** + * 创建并初始化一个虚拟内存区域(VMA)结构体。 + * + * @param vm_start 虚拟内存区域的起始地址。 + * @param vm_end 虚拟内存区域的结束地址。 + * @param vm_flags 虚拟内存区域的标志,表示内存区域的权限和特性。 + * + * @return 返回指向新创建的vma_struct结构体的指针,如果内存分配失败,则返回NULL。 + */ struct vma_struct * vma_create(uintptr_t vm_start, uintptr_t vm_end, uint32_t vm_flags) { + // 分配vma_struct结构体所需的内存空间 struct vma_struct *vma = kmalloc(sizeof(struct vma_struct)); - + // 检查内存是否成功分配 if (vma != NULL) { + // 初始化vma_struct的成员变量 vma->vm_start = vm_start; vma->vm_end = vm_end; vma->vm_flags = vm_flags; } + // 返回指向新创建的vma_struct结构体的指针,或在内存分配失败时返回NULL return vma; } // find_vma - find a vma (vma->vm_start <= addr <= vma_vm_end) +/** + * 查找给定地址对应的虚拟内存区域(VMA) + * + * @param mm 进程的内存描述符,包含所有VMA的列表 + * @param addr 要查找的地址 + * @return 返回包含给定地址的VMA指针,如果未找到则返回NULL + * + * 此函数首先检查mmap_cache是否包含所需的VMA,以加速查找过程 + * 如果mmap_cache未命中,则遍历VMA列表,直到找到包含给定地址的VMA或确定不存在这样的VMA + * 如果找到了合适的VMA,它将更新mmap_cache以供后续查找使用 + */ struct vma_struct * find_vma(struct mm_struct *mm, uintptr_t addr) { - struct vma_struct *vma = NULL; - if (mm != NULL) { + struct vma_struct *vma = NULL;// 初始化VMA指针为NULL + if (mm != NULL) {// 检查传入的内存描述符是否有效 + // 检查mmap_cache是否包含所需的VMA vma = mm->mmap_cache; if (!(vma != NULL && vma->vm_start <= addr && vma->vm_end > addr)) { - bool found = 0; + // 如果mmap_cache未命中,则开始遍历VMA列表 + bool found = 0;// 初始化找到标志为0 + // 获取VMA列表的头指针 list_entry_t *list = &(mm->mmap_list), *le = list; - while ((le = list_next(le)) != list) { - vma = le2vma(le, list_link); + while ((le = list_next(le)) != list) { // 遍历VMA列表 + vma = le2vma(le, list_link);// 将链表项转换为VMA结构 + // 检查当前VMA是否包含给定地址 if (vma->vm_start<=addr && addr < vma->vm_end) { - found = 1; - break; + found = 1;// 找到合适的VMA + break;// 结束循环 } } - if (!found) { - vma = NULL; + if (!found) {// 如果未找到合适的VMA + vma = NULL;// 将VMA指针设置为NULL } } + // 如果找到了合适的VMA,更新mmap_cache if (vma != NULL) { - mm->mmap_cache = vma; + mm->mmap_cache = vma;// 更新mmap_cache以加速后续查找 } } return vma; } - // check_vma_overlap - check if vma1 overlaps vma2 ? +/** + * 检查两个虚拟内存区域(VMA)是否有重叠 + * + * 此函数的目的是确保给定的两个虚拟内存区域(VMA)在内存中是正确排序且没有重叠的 + * 它通过断言来检查以下条件: + * 1. 前一个VMA的起始地址小于其结束地址,确保前一个VMA的地址范围是有效的 + * 2. 前一个VMA的结束地址小于等于下一个VMA的起始地址,确保两个VMA之间没有重叠 + * 3. 后一个VMA的起始地址小于其结束地址,确保后一个VMA的地址范围是有效的 + * + * @param prev 指向前一个虚拟内存区域(VMA)的结构体指针 + * @param next 指向后一个虚拟内存区域(VMA)的结构体指针 + */ static inline void check_vma_overlap(struct vma_struct *prev, struct vma_struct *next) { - assert(prev->vm_start < prev->vm_end); - assert(prev->vm_end <= next->vm_start); - assert(next->vm_start < next->vm_end); + assert(prev->vm_start < prev->vm_end);// 确保前一个VMA的地址范围是有效的 + assert(prev->vm_end <= next->vm_start);// 确保两个VMA之间没有重叠 + assert(next->vm_start < next->vm_end);// 确保后一个VMA的地址范围是有效的 } // insert_vma_struct -insert vma in mm's list link +/** + * 将VMA(虚拟内存区域)结构插入到内存描述符的链表中。 + * + * 此函数负责将新的VMA结构插入到进程的VMA链表中的正确位置,确保VMA结构按起始地址升序排列。 + * 它还检查与相邻VMA结构的重叠情况,以确保内存段管理的一致性。 + * + * @param mm 指向内存描述符结构 `struct mm_struct` 的指针,表示一个进程的内存空间。 + * @param vma 指向要插入的VMA结构 `struct vma_struct` 的指针,描述一个内存区域。 + */ void insert_vma_struct(struct mm_struct *mm, struct vma_struct *vma) { + // 断言VMA结构的起始地址小于结束地址,确保VMA结构的有效性。 assert(vma->vm_start < vma->vm_end); + // 指向内存描述符中的VMA链表。 list_entry_t *list = &(mm->mmap_list); + // 遍历链表以找到新VMA结构的正确插入位置。 list_entry_t *le_prev = list, *le_next; list_entry_t *le = list; + // 遍历链表以找到新VMA结构的正确插入位置 while ((le = list_next(le)) != list) { struct vma_struct *mmap_prev = le2vma(le, list_link); + // 如果当前VMA的起始地址大于新VMA的起始地址,则跳出循环 if (mmap_prev->vm_start > vma->vm_start) { break; } le_prev = le; } - + // 获取下一个链表项 le_next = list_next(le_prev); /* check overlap */ + // 检查前一个VMA结构是否与新VMA结构重叠 if (le_prev != list) { check_vma_overlap(le2vma(le_prev, list_link), vma); } + // 检查下一个VMA结构是否与新VMA结构重叠 if (le_next != list) { check_vma_overlap(vma, le2vma(le_next, list_link)); } - + // 设置VMA结构所属的内存描述符 vma->vm_mm = mm; + // 将新VMA结构插入链表 list_add_after(le_prev, &(vma->list_link)); - + // 增加内存描述符中的映射计数 mm->map_count ++; } // mm_destroy - free mm and mm internal fields +/** + * mm_destroy - 销毁一个内存管理结构(mm_struct)及其关联的虚拟内存区域(VMA) + * @mm: 指向要销毁的内存管理结构的指针 + * + * 此函数遍历并销毁与内存管理结构(mm_struct)关联的所有虚拟内存区域(VMA), + * 然后释放内存管理结构本身所占用的内存。这样做是为了确保在销毁内存管理结构之前, + * 所有相关的资源都被正确地释放。 + */ void mm_destroy(struct mm_struct *mm) { - assert(mm_count(mm) == 0); - + // 获取内存映射列表的头指针 list_entry_t *list = &(mm->mmap_list), *le; + // 遍历内存映射列表,直到回到起点 while ((le = list_next(list)) != list) { + // 从列表中删除当前虚拟内存区域的项 list_del(le); - kfree(le2vma(le, list_link)); //kfree vma + // 释放虚拟内存区域结构的内存 + kfree(le2vma(le, list_link)); + //kfree(le2vma(le, list_link), sizeof(struct vma_struct)); //kfree vma } + // 释放内存管理结构本身的内存 kfree(mm); //kfree mm + //kfree(mm, sizeof(struct mm_struct)); //kfree mm + // 将指针设置为NULL,表示该结构已被销毁 mm=NULL; } @@ -244,124 +330,168 @@ copy_to_user(struct mm_struct *mm, void *dst, const void *src, size_t len) { // vmm_init - initialize virtual memory management // - now just call check_vmm to check correctness of vmm +/** + * 初始化虚拟内存管理(VMM)系统。 + * 此函数通过执行一系列检查来确保VMM系统可以正确初始化和运行。 + */ void vmm_init(void) { + // 检查VMM系统的状态和环境,以确保其能够正常工作。 check_vmm(); } // check_vmm - check correctness of vmm +/** + * 检查虚拟内存管理(VMM)的完整性 + * + * 此函数的目的是确保虚拟内存管理系统的正确性通过检查内存区域结构(VMA)、页面故障处理以及免费页面计数的 consistency 来实现 + * 它首先保存当前的免费页面数量,然后执行与 VMA 和页面故障相关的检查,最后确认免费页面数量未发生变化 + * 这是为了确保在检查过程中,内存状态没有因为错误或意外的修改而改变,从而验证内存管理的正确性 + */ static void check_vmm(void) { + // 保存当前的免费页面数量,用于后续的 consistency 检查 size_t nr_free_pages_store = nr_free_pages(); - + // 检查虚拟内存区域(VMA)结构的正确性 check_vma_struct(); + // 检查页面故障处理的正确性 check_pgfault(); - + // 确保在检查过程中免费页面数量未发生变化,表明内存管理操作是正确的 + // assert(nr_free_pages_store == nr_free_pages()); + // 如果所有检查都通过,输出成功信息 cprintf("check_vmm() succeeded.\n"); } +//测试虚拟内存区域(VMA)结构的创建、插入和查找功能。 static void check_vma_struct(void) { + // 记录当前空闲页面数量 size_t nr_free_pages_store = nr_free_pages(); - struct mm_struct *mm = mm_create(); - assert(mm != NULL); + struct mm_struct *mm = mm_create();// 创建内存管理结构 mm + assert(mm != NULL);// 确保 mm 不为 NULL - int step1 = 10, step2 = step1 * 10; + int step1 = 10, step2 = step1 * 10;// 定义两个步骤的步数 int i; - for (i = step1; i >= 1; i --) { + for (i = step1; i >= 1; i --) {// 第一步:创建并插入10个VMA + // 创建 VMA 结构 struct vma_struct *vma = vma_create(i * 5, i * 5 + 2, 0); - assert(vma != NULL); - insert_vma_struct(mm, vma); + assert(vma != NULL);// 确保 VMA 不为 NULL + insert_vma_struct(mm, vma); //将 VMA 插入到 mm 中 } - for (i = step1 + 1; i <= step2; i ++) { + for (i = step1 + 1; i <= step2; i ++) {// 第二步:创建并插入90个VMA + // 创建 VMA 结构 struct vma_struct *vma = vma_create(i * 5, i * 5 + 2, 0); - assert(vma != NULL); - insert_vma_struct(mm, vma); + assert(vma != NULL);// 确保 VMA 不为 NULL + insert_vma_struct(mm, vma);// 将 VMA 插入到 mm 中 } - + // 获取 VMA 链表的第一个节点 list_entry_t *le = list_next(&(mm->mmap_list)); - for (i = 1; i <= step2; i ++) { - assert(le != &(mm->mmap_list)); - struct vma_struct *mmap = le2vma(le, list_link); + for (i = 1; i <= step2; i ++) {// 验证插入顺序 + assert(le != &(mm->mmap_list));// 确保节点不为空 + struct vma_struct *mmap = le2vma(le, list_link);// 将链表节点转换为 VMA 结构 + // 确认 VMA 的起始和结束地址 assert(mmap->vm_start == i * 5 && mmap->vm_end == i * 5 + 2); - le = list_next(le); + le = list_next(le);// 移动到下一个节点 } - for (i = 5; i <= 5 * step2; i +=5) { - struct vma_struct *vma1 = find_vma(mm, i); - assert(vma1 != NULL); + for (i = 5; i <= 5 * step2; i +=5) {// 查找特定地址范围内的 VMA + struct vma_struct *vma1 = find_vma(mm, i);// 查找地址 i 处的 VMA + assert(vma1 != NULL);// 确保找到 VMA + // 查找地址 i + 1 处的 VMA struct vma_struct *vma2 = find_vma(mm, i+1); - assert(vma2 != NULL); + assert(vma2 != NULL);// 确保找到 VMA + // 查找地址 i + 2 处的 VMA struct vma_struct *vma3 = find_vma(mm, i+2); - assert(vma3 == NULL); + assert(vma3 == NULL);// 确保未找到 VMA + // 查找地址 i + 3 处的 VMA struct vma_struct *vma4 = find_vma(mm, i+3); - assert(vma4 == NULL); + assert(vma4 == NULL);// 确保未找到 VMA + // 查找地址 i + 4 处的 VMA struct vma_struct *vma5 = find_vma(mm, i+4); - assert(vma5 == NULL); - + assert(vma5 == NULL);// 确保未找到 VMA + // 确认 VMA1 的起始和结束地址 assert(vma1->vm_start == i && vma1->vm_end == i + 2); + // 确认 VMA2 的起始和结束地址 assert(vma2->vm_start == i && vma2->vm_end == i + 2); } - + // 检查小于5的地址范围内是否存在 VMA for (i =4; i>=0; i--) { + // 查找地址 i 处的 VMA struct vma_struct *vma_below_5= find_vma(mm,i); - if (vma_below_5 != NULL ) { + if (vma_below_5 != NULL ) {// 如果找到 VMA cprintf("vma_below_5: i %x, start %x, end %x\n",i, vma_below_5->vm_start, vma_below_5->vm_end); } - assert(vma_below_5 == NULL); + assert(vma_below_5 == NULL);// 确保未找到 VMA } - mm_destroy(mm); + mm_destroy(mm);// 销毁 mm 结构 + // 确保释放的页面数量与初始记录一致 + // assert(nr_free_pages_store == nr_free_pages()); + // 输出成功信息 cprintf("check_vma_struct() succeeded!\n"); } struct mm_struct *check_mm_struct; // check_pgfault - check correctness of pgfault handler +// 检查页故障处理的正确性 static void check_pgfault(void) { + // 保存当前空闲页面的数量,用于后续检查 size_t nr_free_pages_store = nr_free_pages(); - + // 创建内存管理结构体 check_mm_struct = mm_create(); + // 确保内存管理结构体创建成功 assert(check_mm_struct != NULL); - + // 将新创建的内存管理结构体赋值给局部变量mm struct mm_struct *mm = check_mm_struct; + // 将引导程序的页目录复制到新创建的内存管理结构体中 pde_t *pgdir = mm->pgdir = boot_pgdir; + // 确保页目录的第0项是空的 assert(pgdir[0] == 0); - + // 创建一个虚拟内存区域结构体,具有写权限 struct vma_struct *vma = vma_create(0, PTSIZE, VM_WRITE); + // 确保虚拟内存区域结构体创建成功 assert(vma != NULL); - + // 将虚拟内存区域结构体插入到内存管理结构体中 insert_vma_struct(mm, vma); - + // 定义一个地址,用于访问虚拟内存 uintptr_t addr = 0x100; + // 确保通过该地址可以找到之前插入的虚拟内存区域 assert(find_vma(mm, addr) == vma); - + // 初始化一个累加器,用于校验写入的数据 int i, sum = 0; + // 写入数据到虚拟内存,并累加 for (i = 0; i < 100; i ++) { *(char *)(addr + i) = i; sum += i; } + // 读取虚拟内存中的数据,并减去,最终结果应为0 for (i = 0; i < 100; i ++) { sum -= *(char *)(addr + i); } + // 确保累加器的值为0,证明数据读写正确 assert(sum == 0); - + // 移除页目录中的相应页面 page_remove(pgdir, ROUNDDOWN(addr, PGSIZE)); + // 释放第0项页目录对应的页面 free_page(pde2page(pgdir[0])); + // 将页目录的第0项设置为空 pgdir[0] = 0; - + // 将内存管理结构体中的页目录设置为空 mm->pgdir = NULL; + // 销毁内存管理结构体 mm_destroy(mm); + // 将检查用的内存管理结构体设置为空 check_mm_struct = NULL; - + // 确保空闲页面的数量没有变化,证明内存管理正确 assert(nr_free_pages_store == nr_free_pages()); - + // 打印成功信息 cprintf("check_pgfault() succeeded!\n"); } //page fault number @@ -388,35 +518,51 @@ volatile unsigned int pgfault_num=0; * -- The U/S flag (bit 2) indicates whether the processor was executing at user mode (1) * or supervisor mode (0) at the time of the exception. */ +/** + * 处理给定内存管理上下文的页面错误。 + * + * @param mm 指向内存管理结构的指针。 + * @param error_code 页面错误发生时硬件提供的错误代码。 + * @param addr 引发页面错误的线性地址。 + * + * @return 成功返回0,失败返回负错误码。 + */ int do_pgfault(struct mm_struct *mm, uint32_t error_code, uintptr_t addr) { - int ret = -E_INVAL; + int ret = -E_INVAL;// 初始化返回值为无效错误 //try to find a vma which include addr + // 尝试找到包含 addr 的 vma struct vma_struct *vma = find_vma(mm, addr); - pgfault_num++; + pgfault_num++;// 增加页面错误计数 + // 检查 addr 是否在 mm 的 vma 范围内 //If the addr is in the range of a mm's vma? if (vma == NULL || vma->vm_start > addr) { cprintf("not valid addr %x, and can not find it in vma\n", addr); - goto failed; + goto failed;// 跳转到错误处理部分 } //check the error_code + // 检查错误代码 switch (error_code & 3) { default: + /* 默认错误代码标志:3 (W/R=1, P=1): 写操作,存在 */ /* error code flag : default is 3 ( W/R=1, P=1): write, present */ case 2: /* error code flag : (W/R=1, P=0): write, not present */ + /* 错误代码标志:(W/R=1, P=0): 写操作,不存在 */ if (!(vma->vm_flags & VM_WRITE)) { cprintf("do_pgfault failed: error code flag = write AND not present, but the addr's vma cannot write\n"); - goto failed; + goto failed;// 跳转到错误处理部分 } break; case 1: /* error code flag : (W/R=0, P=1): read, present */ + /* 错误代码标志:(W/R=0, P=1): 读操作,存在 */ cprintf("do_pgfault failed: error code flag = read AND present\n"); - goto failed; + goto failed;// 跳转到错误处理部分 case 0: /* error code flag : (W/R=0, P=0): read, not present */ + /* 错误代码标志:(W/R=0, P=0): 读操作,不存在 */ if (!(vma->vm_flags & (VM_READ | VM_EXEC))) { cprintf("do_pgfault failed: error code flag = read AND not present, but the addr's vma cannot read or exec\n"); - goto failed; + goto failed;// 跳转到错误处理部分 } } /* IF (write an existed addr ) OR @@ -425,13 +571,18 @@ do_pgfault(struct mm_struct *mm, uint32_t error_code, uintptr_t addr) { * THEN * continue process */ - uint32_t perm = PTE_U; + /* 如果 (写入已存在的地址) 或 + * (写入不存在的地址且地址可写) 或 + * (读取不存在的地址且地址可读) + * 则继续处理 + */ + uint32_t perm = PTE_U;// 初始化权限标志为用户可访问 if (vma->vm_flags & VM_WRITE) { - perm |= PTE_W; + perm |= PTE_W;// 如果 vma 可写,则设置写权限 } - addr = ROUNDDOWN(addr, PGSIZE); + addr = ROUNDDOWN(addr, PGSIZE);// 将地址对齐到页边界 - ret = -E_NO_MEM; + ret = -E_NO_MEM;// 初始化返回值为内存不足错误 pte_t *ptep=NULL; /*LAB3 EXERCISE 1: YOUR CODE @@ -451,12 +602,31 @@ do_pgfault(struct mm_struct *mm, uint32_t error_code, uintptr_t addr) { * mm->pgdir : the PDT of these vma * */ + /* LAB3 练习 1: 你的代码 + * 可能需要帮助的注释,以下注释可以帮助你完成代码 + * + * 一些有用的宏和定义,你可以在下面的实现中使用它们。 + * 宏或函数: + * get_pte : 获取一个页表项并返回该页表项的内核虚拟地址 + * 如果包含该页表项的页表不存在,则分配一个页表 (注意第三个参数 '1') + * pgdir_alloc_page : 调用 alloc_page 和 page_insert 函数分配一页大小的内存并设置 + * 地址映射 pa<--->la 与页目录表 pgdir + * 定义: + * VM_WRITE : 如果 vma->vm_flags & VM_WRITE == 1/0,则 vma 是可写/不可写的 + * PTE_W 0x002 // 页表/目录项标志位:可写 + * PTE_U 0x004 // 页表/目录项标志位:用户可访问 + * 变量: + * mm->pgdir : 这些 vma 的页目录表 + * + */ #if 0 /*LAB3 EXERCISE 1: YOUR CODE*/ + /* LAB3 练习 1: 你的代码*/ ptep = ??? //(1) try to find a pte, if pte's PT(Page Table) isn't existed, then create a PT. + // (1) 尝试找到一个页表项,如果该页表项的页表不存在,则创建一个页表。 if (*ptep == 0) { //(2) if the phy addr isn't exist, then alloc a page & map the phy addr with logical addr - + // (2) 如果物理地址不存在,则分配一页内存并映射物理地址与逻辑地址 } else { /*LAB3 EXERCISE 2: YOUR CODE @@ -470,29 +640,67 @@ do_pgfault(struct mm_struct *mm, uint32_t error_code, uintptr_t addr) { * page_insert : build the map of phy addr of an Page with the linear addr la * swap_map_swappable : set the page swappable */ - /* - * LAB5 CHALLENGE ( the implmentation Copy on Write) - There are 2 situlations when code comes here. - 1) *ptep & PTE_P == 1, it means one process try to write a readonly page. - If the vma includes this addr is writable, then we can set the page writable by rewrite the *ptep. - This method could be used to implement the Copy on Write (COW) thchnology(a fast fork process method). - 2) *ptep & PTE_P == 0 & but *ptep!=0, it means this pte is a swap entry. - We should add the LAB3's results here. - */ + /* LAB3 练习 2: 你的代码 + * 现在我们认为这个页表项是一个交换项,我们应该从磁盘加载数据到一个具有物理地址的页面, + * 并映射物理地址与逻辑地址,触发交换管理器记录该页面的访问情况。 + * + * 一些有用的宏和定义,你可以在下面的实现中使用它们。 + * 宏或函数: + * swap_in(mm, addr, &page) : 分配一个内存页面,然后根据 addr 的页表项中的交换项, + * 找到磁盘页面的地址,将磁盘页面的内容读入该内存页面 + * page_insert : 根据 mm 和 addr 设置物理地址与逻辑地址的映射 + * swap_map_swappable : 设置页面可交换 + */ if(swap_init_ok) { struct Page *page=NULL; //(1)According to the mm AND addr, try to load the content of right disk page + // (1) 根据 mm 和 addr,尝试从正确的磁盘页面加载内容到 page 管理的内存中 // into the memory which page managed. + // (2) 根据 mm、addr 和 page,设置物理地址与逻辑地址的映射 //(2) According to the mm, addr AND page, setup the map of phy addr <---> logical addr //(3) make the page swappable. - //(4) [NOTICE]: you myabe need to update your lab3's implementation for LAB5's normal execution. + // (3) 使页面可交换 } else { cprintf("no swap_init_ok but ptep is %x, failed\n",*ptep); - goto failed; + goto failed;// 跳转到错误处理部分 } } #endif + // try to find a pte, if pte's PT(Page Table) isn't existed, then create a PT. + // (notice the 3th parameter '1') + // 尝试找到一个页表项 pte,如果包含该 pte 的页表不存在,则创建一个页表。 + // 注意第三个参数 '1' 表示如果需要,可以创建新的页表。 + if ((ptep = get_pte(mm->pgdir, addr, 1)) == NULL) { + cprintf("get_pte in do_pgfault failed\n");// 输出错误信息 + goto failed;// 跳转到错误处理部分 + } + // 如果页表项 pte 的物理地址不存在,则分配一页内存并映射物理地址与逻辑地址 + if (*ptep == 0) { // if the phy addr isn't exist, then alloc a page & map the phy addr with logical addr + if (pgdir_alloc_page(mm->pgdir, addr, perm) == NULL) { + cprintf("pgdir_alloc_page in do_pgfault failed\n");// 输出错误信息 + goto failed;// 跳转到错误处理部分 + } + } + else { // if this pte is a swap entry, then load data from disk to a page with phy addr + // and call page_insert to map the phy addr with logical addr + // 如果页表项 pte 是一个交换项,则从磁盘加载数据到 + //一个具有物理地址的页面,并映射物理地址与逻辑地址 + if(swap_init_ok) {// 检查交换初始化是否成功 + struct Page *page=NULL;// 声明一个页面指针 + if ((ret = swap_in(mm, addr, &page)) != 0) { + cprintf("swap_in in do_pgfault failed\n"); + goto failed; + } + page_insert(mm->pgdir, page, addr, perm);// 设置物理地址与逻辑地址的映射 + swap_map_swappable(mm, addr, page, 1);// 设置页面可交换 + page->pra_vaddr = addr;// 记录页面的虚拟地址 + } + else { + cprintf("no swap_init_ok but ptep is %x, failed\n",*ptep); + goto failed;// 跳转到错误处理部分 + } + } ret = 0; failed: return ret; diff --git a/labcodes/lab5/kern/process/proc.c b/labcodes/lab5/kern/process/proc.c index e6ff1f3436658cf9a437b69a1cfa2331dd0007a9..b1bc39e82f1b7e7fb66ff1fc25257f034c9bca75 100644 --- a/labcodes/lab5/kern/process/proc.c +++ b/labcodes/lab5/kern/process/proc.c @@ -109,14 +109,44 @@ alloc_proc(void) { * uint32_t wait_state; // waiting state * struct proc_struct *cptr, *yptr, *optr; // relations between processes */ + proc->state = PROC_UNINIT; // 初始状态为未初始化 + proc->pid = -1; // 初始进程ID为-1 + proc->runs = 0; // 初始运行次数为0 + proc->kstack = 0; // 初始内核栈指针为0 + proc->need_resched = 0; // 初始不需要重新调度 + proc->parent = NULL; // 初始父进程指针为NULL + proc->mm = NULL; // 初始内存管理结构指针为NULL + memset(&proc->context, 0, sizeof(struct context)); // 初始化上下文切换信息 + proc->tf = NULL; // 初始中断陷阱帧指针为NULL + proc->cr3 = boot_cr3; // 初始CR3寄存器值为0 + proc->flags = 0; // 初始进程标志为0 + memset(proc->name, 0, PROC_NAME_LEN); // 初始进程名称为空字符串 + proc->wait_state = 0; + proc->cptr = proc->optr = proc->yptr = NULL; } return proc; } // set_proc_name - set the name of proc +/** + * 设置进程名称 + * + * 本函数旨在为进程结构体中的名称字段赋予新的值它首先清空进程名称字段中的现有内容, + * 然后将新的名称复制到该字段中 + * + * @param proc 指向进程结构体的指针,该结构体包含进程的相关信息包括进程名称 + * @param name 指向新的进程名称的字符串 + * + * @return 返回指向进程名称的指针,这是在内存中直接修改后的结果 + * + * 注意:此函数直接操作传入的进程结构体,对名称字段进行先清空后赋值的操作 + */ char * set_proc_name(struct proc_struct *proc, const char *name) { + + // 清空进程名称字段中的现有内容,以准备存储新的名称 memset(proc->name, 0, sizeof(proc->name)); + // 将新的名称复制到进程名称字段中 return memcpy(proc->name, name, PROC_NAME_LEN); } @@ -157,23 +187,45 @@ remove_links(struct proc_struct *proc) { } // get_pid - alloc a unique pid for process +/** + * 安全地获取下一个进程ID。 + * + * 此函数通过遍历进程列表来寻找一个未被使用的进程ID,以确保新分配的ID不会与现有进程冲突。 + * 它使用静态变量来跟踪最后一个分配的PID和下一个安全PID,以提高效率并避免PID冲突。 + * + * @return 返回一个未被使用的进程ID。 + */ static int get_pid(void) { + // 确保PID的最大值大于系统中允许的最大进程数,以避免PID不足的情况。 static_assert(MAX_PID > MAX_PROCESS); + + // 定义一个指向进程结构的指针,用于遍历进程列表。 struct proc_struct *proc; + // 初始化列表指针,从进程列表的头部开始。 list_entry_t *list = &proc_list, *le; + // 定义静态变量,next_safe用于记录下一个安全的PID值,last_pid用于记录上一个分配的PID。 static int next_safe = MAX_PID, last_pid = MAX_PID; + + // 尝试递增last_pid以查找下一个可用的PID,如果超过最大值则重置为1。 if (++ last_pid >= MAX_PID) { last_pid = 1; goto inside; } + + // 如果当前的last_pid大于等于next_safe,表示需要重新计算下一个安全的PID。 if (last_pid >= next_safe) { inside: next_safe = MAX_PID; repeat: + // 从进程列表的头部开始遍历。 le = list; while ((le = list_next(le)) != list) { + + // 将列表项转换为进程结构。 proc = le2proc(le, list_link); + + // 如果找到相同PID的进程,表示当前last_pid已被使用,需要继续寻找下一个可用的PID。 if (proc->pid == last_pid) { if (++ last_pid >= next_safe) { if (last_pid >= MAX_PID) { @@ -183,16 +235,20 @@ get_pid(void) { goto repeat; } } + + // 如果找到一个更大的PID,更新next_safe为当前进程的PID,以确保找到的PID是安全的。 else if (proc->pid > last_pid && next_safe > proc->pid) { next_safe = proc->pid; } } } + // 返回找到的可用PID。 return last_pid; } // proc_run - make process "proc" running on cpu // NOTE: before call switch_to, should load base addr of "proc"'s new PDT +//切换当前运行的进程 void proc_run(struct proc_struct *proc) { if (proc != current) { @@ -212,14 +268,24 @@ proc_run(struct proc_struct *proc) { // forkret -- the first kernel entry point of a new thread/process // NOTE: the addr of forkret is setted in copy_thread function // after switch_to, the current proc will execute here. +// 函数在调用时会传递当前进程的线程上下文(通过 current->tf 获取)给 forkrets 函数。 static void forkret(void) { forkrets(current->tf); } // hash_proc - add proc into proc hash_list +/** + * 将进程结构体添加到哈希表中 + * + * 当需要在哈希表中添加一个进程时,调用此函数将进程结构体中的哈希链接添加到相应的哈希表链表中 + * 这有助于在需要时快速查找进程 + * + * @param proc 指向进程结构体的指针,表示要添加到哈希表的进程 + */ static void hash_proc(struct proc_struct *proc) { + // 根据进程的PID计算哈希值,并将进程添加到相应哈希链表的末尾 list_add(hash_list + pid_hashfn(proc->pid), &(proc->hash_link)); } @@ -247,26 +313,60 @@ find_proc(int pid) { // kernel_thread - create a kernel thread using "fn" function // NOTE: the contents of temp trapframe tf will be copied to // proc->tf in do_fork-->copy_thread function +/** + * 创建一个内核线程 + * + * @param fn 指向线程要执行的函数的指针 + * @param arg 传递给fn函数的参数 + * @param clone_flags 克隆标志,用于指定线程创建的细节 + * + * @return 返回线程创建的结果,成功则为线程ID,失败则为错误码 + * + * 该函数通过设置trapframe来创建一个内核线程,并安排其执行指定的函数fn + * 使用do_fork函数来进行实际的线程创建操作,创建的线程将共享父线程的虚拟内存 + */ int kernel_thread(int (*fn)(void *), void *arg, uint32_t clone_flags) { + // 初始化trapframe结构体,用于描述线程的初始状态 struct trapframe tf; memset(&tf, 0, sizeof(struct trapframe)); + + // 设置代码段和数据段寄存器的值,使线程运行在内核态 tf.tf_cs = KERNEL_CS; tf.tf_ds = tf.tf_es = tf.tf_ss = KERNEL_DS; + + // 将要执行的函数fn的地址和参数arg的地址分别放入ebx和edx寄存器 tf.tf_regs.reg_ebx = (uint32_t)fn; tf.tf_regs.reg_edx = (uint32_t)arg; + + // 设置指令指针寄存器eip,使其指向内核线程入口函数kernel_thread_entry tf.tf_eip = (uint32_t)kernel_thread_entry; + + // 调用do_fork函数创建新线程,新线程将共享父线程的虚拟内存 + // 并将新线程的初始状态设置为之前准备的trapframe return do_fork(clone_flags | CLONE_VM, 0, &tf); } // setup_kstack - alloc pages with size KSTACKPAGE as process kernel stack +/** + * 设置进程的内核栈 + * + * @param proc 指向进程结构的指针,用于初始化该进程的内核栈 + * @return 0表示成功,-E_NO_MEM表示内存分配失败 + * + * 此函数通过分配一页内存用作进程的内核栈,并将该内存页的虚拟地址设置为进程的内核栈地址 + * 如果内存分配成功,则返回0;如果内存分配失败,则返回-E_NO_MEM + */ static int setup_kstack(struct proc_struct *proc) { + // 分配KSTACKPAGE页内存用作内核栈 struct Page *page = alloc_pages(KSTACKPAGE); if (page != NULL) { + // 如果内存分配成功,将内存页的虚拟地址设置为进程的内核栈地址 proc->kstack = (uintptr_t)page2kva(page); return 0; } + // 如果内存分配失败,返回错误码 return -E_NO_MEM; } @@ -345,15 +445,33 @@ bad_mm: // copy_thread - setup the trapframe on the process's kernel stack top and // - setup the kernel entry point and stack of process +/** + * 复制当前线程的上下文到新进程。 + * + * 该函数初始化新进程的陷阱帧和上下文,使其作为当前线程的子进程执行。主要操作包括设置初始执行环境、栈指针,并启用子进程的中断标志。 + * + * @param proc 指向新进程的进程结构体,用于存储初始化后的陷阱帧和上下文信息。 + * @param esp 新进程的栈指针,表示新进程栈的初始位置。 + * @param tf 指向当前线程的陷阱帧结构体,用于将当前线程的执行状态复制到新进程中。 + */ static void copy_thread(struct proc_struct *proc, uintptr_t esp, struct trapframe *tf) { + // 初始化新进程的陷阱帧,位于其内核栈的顶部 proc->tf = (struct trapframe *)(proc->kstack + KSTACKSIZE) - 1; + + // 将当前线程的陷阱帧内容复制到新进程的陷阱帧 *(proc->tf) = *tf; + + // 设置子进程的返回值为0,表示fork成功 proc->tf->tf_regs.reg_eax = 0; + // 设置子进程的栈指针为指定的esp位置 proc->tf->tf_esp = esp; + // 启用子进程的中断标志 proc->tf->tf_eflags |= FL_IF; + // 设置子进程的初始指令指针为forkret函数的地址 proc->context.eip = (uintptr_t)forkret; + // 设置子进程的栈指针为其陷阱帧的地址 proc->context.esp = (uintptr_t)(proc->tf); } @@ -362,10 +480,22 @@ copy_thread(struct proc_struct *proc, uintptr_t esp, struct trapframe *tf) { * @stack: the parent's user stack pointer. if stack==0, It means to fork a kernel thread. * @tf: the trapframe info, which will be copied to child process's proc->tf */ +/** + * do_fork - 创建一个新进程,这是进程创建的核心函数 + * @clone_flags: 克隆标志,用于确定新进程如何共享资源 + * @stack: 新进程的用户栈指针 + * @tf: 新进程的trapframe结构体指针,用于设置新进程的执行环境 + * + * 返回值: 新进程的pid,如果创建失败则返回错误码 + * + * 此函数负责分配proc_struct、设置内核栈、复制或共享内存管理结构, + * 复制线程上下文,将新进程插入到进程列表中,并将其设置为可运行状态 + */ int do_fork(uint32_t clone_flags, uintptr_t stack, struct trapframe *tf) { int ret = -E_NO_FREE_PROC; struct proc_struct *proc; + // 检查系统中是否有足够的资源创建新进程 if (nr_process >= MAX_PROCESS) { goto fork_out; } @@ -395,7 +525,43 @@ do_fork(uint32_t clone_flags, uintptr_t stack, struct trapframe *tf) { // 5. insert proc_struct into hash_list && proc_list // 6. call wakeup_proc to make the new child process RUNNABLE // 7. set ret vaule using child proc's pid + //调用alloc_proc,首先获得一块用户信息块 + if((proc = alloc_proc()) == NULL){ + goto fork_out; + } + + // 设置新进程的父进程为当前进程,并确保当前进程的wait_state为0 + proc->parent = current; + assert(current->wait_state == 0); + + // 为新进程分配内核栈 + if (setup_kstack(proc) != 0) { + goto bad_fork_cleanup_proc; + } + // 根据clone_flags复制或共享内存管理结构 + if (copy_mm(clone_flags, proc) != 0) { + goto bad_fork_cleanup_kstack; + } + + // 复制线程上下文到新进程 + copy_thread(proc, stack, tf); + bool intr_flag; + local_intr_save(intr_flag); + { + // 为新进程分配唯一的pid,并将其插入到进程哈希列表和进程列表中 + proc->pid = get_pid(); + hash_proc(proc); + set_links(proc); + + } + local_intr_restore(intr_flag); + + // 将新进程设置为可运行状态 + wakeup_proc(proc); + + // 设置返回值为新进程的pid + ret = proc->pid; //LAB5 YOUR CODE : (update LAB4 steps) /* Some Functions * set_links: set the relation links of process. ALSO SEE: remove_links: lean the relation links of process @@ -403,13 +569,16 @@ do_fork(uint32_t clone_flags, uintptr_t stack, struct trapframe *tf) { * update step 1: set child proc's parent to current process, make sure current process's wait_state is 0 * update step 5: insert proc_struct into hash_list && proc_list, set the relation links of process */ + fork_out: return ret; bad_fork_cleanup_kstack: + // 如果资源分配失败,释放已分配的内核栈 put_kstack(proc); bad_fork_cleanup_proc: +// 释放proc_struct结构体 kfree(proc); goto fork_out; } @@ -418,36 +587,54 @@ bad_fork_cleanup_proc: // 1. call exit_mmap & put_pgdir & mm_destroy to free the almost all memory space of process // 2. set process' state as PROC_ZOMBIE, then call wakeup_proc(parent) to ask parent reclaim itself. // 3. call scheduler to switch to other process +/** + * 退出当前进程,并释放其占用的资源。 + * + * @param error_code 进程退出码,表示进程退出的状态。 + * + * @return 该函数不会返回。 + */ int do_exit(int error_code) { + // 检查当前进程是否为idle进程,如果是,则引发panic。 if (current == idleproc) { panic("idleproc exit.\n"); } + // 检查当前进程是否为init进程,如果是,则引发panic。 if (current == initproc) { panic("initproc exit.\n"); } + // 获取当前进程的内存管理结构。 struct mm_struct *mm = current->mm; + // 如果当前进程有内存管理结构,则进行清理。 if (mm != NULL) { + // 加载引导页表,准备清理当前进程的页表。 lcr3(boot_cr3); + // 如果内存管理结构的引用计数减到0,则释放相关资源。 if (mm_count_dec(mm) == 0) { exit_mmap(mm); put_pgdir(mm); mm_destroy(mm); } + // 将当前进程的内存管理结构设置为NULL。 current->mm = NULL; } + // 将当前进程的状态设置为僵尸状态,并保存退出码。 current->state = PROC_ZOMBIE; current->exit_code = error_code; + // 保存中断状态,并获取当前进程的父进程。 bool intr_flag; struct proc_struct *proc; local_intr_save(intr_flag); { proc = current->parent; + // 如果父进程在等待子进程,则唤醒父进程。 if (proc->wait_state == WT_CHILD) { wakeup_proc(proc); } + // 遍历当前进程的所有子进程,并将它们的父进程设置为init进程。 while (current->cptr != NULL) { proc = current->cptr; current->cptr = proc->optr; @@ -458,6 +645,7 @@ do_exit(int error_code) { } proc->parent = initproc; initproc->cptr = proc; + // 如果子进程处于僵尸状态,并且init进程在等待子进程,则唤醒init进程。 if (proc->state == PROC_ZOMBIE) { if (initproc->wait_state == WT_CHILD) { wakeup_proc(initproc); @@ -465,9 +653,11 @@ do_exit(int error_code) { } } } + // 恢复中断状态。 local_intr_restore(intr_flag); - + // 调度新的进程运行。 schedule(); + // 如果调度失败,引发panic。 panic("do_exit will not return!! %d.\n", current->pid); } @@ -475,29 +665,51 @@ do_exit(int error_code) { * @binary: the memory addr of the content of binary program * @size: the size of the content of binary program */ +/** + * 加载指令代码到当前进程的内存中。 + * 函数实现以下步骤: + * (1) 为当前进程创建一个新的内存描述符 (mm_struct)。 + * (2) 创建一个新的页目录表 (PDT),并将 mm->pgdir 设置为内核虚拟地址的 PDT。 + * (3) 将二进制程序的 TEXT/DATA 段复制到进程的内存空间,并构建 BSS 部分。 + * (4) 构建用户栈内存。 + * (5) 设置当前进程的 mm、sr3,并将 CR3 寄存器设置为页目录的物理地址。 + * (6) 为用户环境设置陷阱帧 (trapframe)。 + * + * @param binary 二进制程序的指针 + * @param size 二进制程序的大小 + * @return 成功返回 0,失败返回负的错误码 + */ static int load_icode(unsigned char *binary, size_t size) { + // 检查当前进程是否已经有内存描述符,如果有则触发 panic if (current->mm != NULL) { panic("load_icode: current->mm must be empty.\n"); } + // 初始化返回值为 -E_NO_MEM int ret = -E_NO_MEM; struct mm_struct *mm; //(1) create a new mm for current process + //(1) 为当前进程创建一个新的内存描述符 (mm_struct) if ((mm = mm_create()) == NULL) { goto bad_mm; } //(2) create a new PDT, and mm->pgdir= kernel virtual addr of PDT + // (2) 创建一个新的页目录表 (PDT),并将 mm->pgdir 设置为内核虚拟地址的 PDT if (setup_pgdir(mm) != 0) { goto bad_pgdir_cleanup_mm; } //(3) copy TEXT/DATA section, build BSS parts in binary to memory space of process + // (3) 将二进制程序的 TEXT/DATA 段复制到进程的内存空间,并构建 BSS 部分 struct Page *page; //(3.1) get the file header of the bianry program (ELF format) + // (3.1) 获取二进制程序的文件头 (ELF 格式) struct elfhdr *elf = (struct elfhdr *)binary; //(3.2) get the entry of the program section headers of the bianry program (ELF format) + // (3.2) 获取二进制程序的程序段头表入口 (ELF 格式) struct proghdr *ph = (struct proghdr *)(binary + elf->e_phoff); //(3.3) This program is valid? + // (3.3) 检查程序是否有效 if (elf->e_magic != ELF_MAGIC) { ret = -E_INVAL_ELF; goto bad_elf_cleanup_pgdir; @@ -507,6 +719,7 @@ load_icode(unsigned char *binary, size_t size) { struct proghdr *ph_end = ph + elf->e_phnum; for (; ph < ph_end; ph ++) { //(3.4) find every program section headers + // (3.4) 查找每一个程序段头 if (ph->p_type != ELF_PT_LOAD) { continue ; } @@ -518,6 +731,7 @@ load_icode(unsigned char *binary, size_t size) { continue ; } //(3.5) call mm_map fun to setup the new vma ( ph->p_va, ph->p_memsz) + // (3.5) 调用 mm_map 函数设置新的 VMA (ph->p_va, ph->p_memsz) vm_flags = 0, perm = PTE_U; if (ph->p_flags & ELF_PF_X) vm_flags |= VM_EXEC; if (ph->p_flags & ELF_PF_W) vm_flags |= VM_WRITE; @@ -533,8 +747,10 @@ load_icode(unsigned char *binary, size_t size) { ret = -E_NO_MEM; //(3.6) alloc memory, and copy the contents of every program section (from, from+end) to process's memory (la, la+end) + // (3.6) 分配内存,并将每个程序段的内容 (from, from+end) 复制到进程的内存 (la, la+end) end = ph->p_va + ph->p_filesz; //(3.6.1) copy TEXT/DATA section of bianry program + // (3.6.1) 复制二进制程序的 TEXT/DATA 段 while (start < end) { if ((page = pgdir_alloc_page(mm->pgdir, la, perm)) == NULL) { goto bad_cleanup_mmap; @@ -548,6 +764,7 @@ load_icode(unsigned char *binary, size_t size) { } //(3.6.2) build BSS section of binary program + // (3.6.2) 构建二进制程序的 BSS 段 end = ph->p_va + ph->p_memsz; if (start < la) { /* ph->p_memsz == ph->p_filesz */ @@ -575,6 +792,7 @@ load_icode(unsigned char *binary, size_t size) { } } //(4) build user stack memory + // (4) 构建用户栈内存 vm_flags = VM_READ | VM_WRITE | VM_STACK; if ((ret = mm_map(mm, USTACKTOP - USTACKSIZE, USTACKSIZE, vm_flags, NULL)) != 0) { goto bad_cleanup_mmap; @@ -585,12 +803,14 @@ load_icode(unsigned char *binary, size_t size) { assert(pgdir_alloc_page(mm->pgdir, USTACKTOP-4*PGSIZE , PTE_USER) != NULL); //(5) set current process's mm, sr3, and set CR3 reg = physical addr of Page Directory + // (5) 设置当前进程的 mm、sr3,并将 CR3 寄存器设置为页目录的物理地址 mm_count_inc(mm); current->mm = mm; current->cr3 = PADDR(mm->pgdir); lcr3(PADDR(mm->pgdir)); //(6) setup trapframe for user environment + // (6) 为用户环境设置陷阱帧 (trapframe) struct trapframe *tf = current->tf; memset(tf, 0, sizeof(struct trapframe)); /* LAB5:EXERCISE1 YOUR CODE @@ -602,6 +822,11 @@ load_icode(unsigned char *binary, size_t size) { * tf_eip should be the entry point of this binary program (elf->e_entry) * tf_eflags should be set to enable computer to produce Interrupt */ + tf->tf_cs = USER_CS; + tf->tf_ds = tf->tf_es = tf->tf_ss = USER_DS; + tf->tf_esp = USTACKTOP; + tf->tf_eip = elf->e_entry; + tf->tf_eflags = FL_IF; ret = 0; out: return ret; @@ -617,37 +842,66 @@ bad_mm: // do_execve - call exit_mmap(mm)&put_pgdir(mm) to reclaim memory space of current process // - call load_icode to setup new memory space accroding binary prog. +/** + * 执行一个新程序,替换当前进程的地址空间 + * + * @param name 程序名称的指针 + * @param len 程序名称的长度 + * @param binary 程序二进制代码的指针 + * @param size 程序二进制代码的大小 + * + * 此函数首先检查程序名称是否有效,然后准备执行新的程序 + * 它会清除当前进程的地址空间,并加载新的程序代码 + * 如果加载过程中发生错误,函数将终止当前进程 + * + * @return 成功时返回0,失败时返回错误码 + */ int do_execve(const char *name, size_t len, unsigned char *binary, size_t size) { + // 获取当前进程的内存管理结构 struct mm_struct *mm = current->mm; + + // 检查程序名称是否在用户空间中有效 if (!user_mem_check(mm, (uintptr_t)name, len, 0)) { return -E_INVAL; } + + // 如果程序名称过长,截断到最大长度 if (len > PROC_NAME_LEN) { len = PROC_NAME_LEN; } + // 准备一个本地缓冲区,用于存储程序名称 char local_name[PROC_NAME_LEN + 1]; memset(local_name, 0, sizeof(local_name)); memcpy(local_name, name, len); + // 如果当前进程已有内存管理结构,进行清理 if (mm != NULL) { + // 切换到引导页表,准备清理当前进程的地址空间 lcr3(boot_cr3); + + // 减少内存管理结构的引用计数,如果为0则进行清理 if (mm_count_dec(mm) == 0) { exit_mmap(mm); put_pgdir(mm); mm_destroy(mm); } + // 当前进程不再有内存管理结构 current->mm = NULL; } + // 加载新的程序代码 int ret; if ((ret = load_icode(binary, size)) != 0) { + // 如果加载失败,终止当前进程 goto execve_exit; } + // 设置当前进程的名称为新的程序名称 set_proc_name(current, local_name); return 0; execve_exit: +// 加载失败时的清理工作 do_exit(ret); panic("already exit: %e.\n", ret); } @@ -662,19 +916,36 @@ do_yield(void) { // do_wait - wait one OR any children with PROC_ZOMBIE state, and free memory space of kernel stack // - proc struct of this child. // NOTE: only after do_wait function, all resources of the child proces are free. +/** + * 等待一个子进程结束并获取其退出状态码 + * + * @param pid 要等待的子进程的PID如果为0,则等待任何子进程 + * @param code_store 用于存储子进程退出状态码的指针如果不需要存储状态码,则传入NULL + * @return 返回0表示成功,负值表示错误代码 + * + * 此函数用于父进程等待其子进程结束,并可选地获取子进程的退出状态码 + * 它首先检查参数的有效性,然后寻找指定的子进程如果找到已终止的子进程, + * 则回收其资源并返回子进程的退出状态码如果没有找到已终止的子进程,则当前进程进入睡眠状态, + * 直到有子进程终止或者没有子进程可等待时返回错误代码 + */ int do_wait(int pid, int *code_store) { + // 获取当前进程的内存描述符 struct mm_struct *mm = current->mm; + // 如果code_store不为NULL,检查其指向的用户内存区域是否有效 if (code_store != NULL) { if (!user_mem_check(mm, (uintptr_t)code_store, sizeof(int), 1)) { return -E_INVAL; } } - + // 定义指向进程结构的指针以及布尔变量用于控制流程 struct proc_struct *proc; bool intr_flag, haskid; repeat: +// 初始化haskid为0,表示尚未找到可等待的子进程 haskid = 0; + + // 如果pid不为0,寻找指定的子进程 if (pid != 0) { proc = find_proc(pid); if (proc != NULL && proc->parent == current) { @@ -684,6 +955,7 @@ repeat: } } } + // 如果pid为0,遍历所有子进程寻找已终止的子进程 else { proc = current->cptr; for (; proc != NULL; proc = proc->optr) { @@ -693,6 +965,7 @@ repeat: } } } + // 如果有子进程但都不是已终止状态,当前进程进入睡眠状态等待 if (haskid) { current->state = PROC_SLEEPING; current->wait_state = WT_CHILD; @@ -702,23 +975,31 @@ repeat: } goto repeat; } + // 如果没有子进程可等待,返回错误代码 return -E_BAD_PROC; found: +// 确保找到的进程不是idleproc或initproc,因为它们不应该被等待 if (proc == idleproc || proc == initproc) { panic("wait idleproc or initproc.\n"); } + // 如果需要,存储子进程的退出状态码到code_store指向的内存位置 if (code_store != NULL) { *code_store = proc->exit_code; } + // 保存中断标志并临时禁用中断,以确保操作的原子性 local_intr_save(intr_flag); { + // 从进程哈希表中移除进程,并移除其与其他进程的链接 unhash_proc(proc); remove_links(proc); } + // 恢复中断状态 local_intr_restore(intr_flag); + // 释放进程的内核栈和内存资源 put_kstack(proc); kfree(proc); + // 成功完成等待操作,返回0 return 0; } @@ -740,6 +1021,20 @@ do_kill(int pid) { } // kernel_execve - do SYS_exec syscall to exec a user program called by user_main kernel_thread +/** + * 执行一个新程序 + * + * 该函数通过触发系统调用来执行一个新的程序它将程序的名称、二进制代码及其大小 + * 作为参数传递给操作系统,以便加载并执行新程序 + * + * @param name 程序的名称,用于标识要执行的程序 + * @param binary 程序的二进制代码,将被加载到内存中执行 + * @param size 二进制代码的大小,以字节为单位 + * + * @return 返回系统调用的结果如果成功,通常返回0;如果失败,返回错误码 + * + * 注意:该函数使用内联汇编来触发系统调用,这是一种低级操作,需要对系统调用和汇编语言有深入的了解 + */ static int kernel_execve(const char *name, unsigned char *binary, size_t size) { int ret, len = strlen(name); @@ -777,32 +1072,58 @@ user_main(void *arg) { #ifdef TEST KERNEL_EXECVE2(TEST, TESTSTART, TESTSIZE); #else - KERNEL_EXECVE(exit); + KERNEL_EXECVE(hello); #endif panic("user_main execve failed.\n"); } // init_main - the second kernel thread used to create user_main kernel threads +/** + * 初始化主函数,负责初始化系统并启动用户模式进程 + * + * 该函数首先保存当前空闲页面和内核分配的内存状态,作为后续比较的基准 + * 然后创建一个内核线程来执行用户主函数(user_main)如果创建失败,系统将陷入恐慌状态 + * + * 接着,函数进入一个循环,通过调度(scheduling)和等待(waiting)机制来管理进程 + * 直到所有用户模式进程结束 + * + * 最后,函数进行一系列断言/assertions来确保系统状态符合预期,包括: + * 1. 当前进程的某些指针为空,表明没有其他进程挂载在当前进程上 + * 2. 进程数量为2,通常是一个空闲进程和当前初始化进程 + * 3. 进程列表的头尾指针正确地指向初始化进程的链表节点 + * + * 如果所有检查通过,函数将打印内存检查通过的消息并返回0 + * + * @param arg 传递给函数的参数,在此函数中未使用 + * @return 返回0表示成功执行 + */ static int init_main(void *arg) { + // 保存当前空闲页面数量和内核已分配内存大小,用于后续检查 size_t nr_free_pages_store = nr_free_pages(); size_t kernel_allocated_store = kallocated(); + // 创建内核线程来执行用户主函数,如果创建失败,则系统陷入恐慌 int pid = kernel_thread(user_main, NULL, 0); if (pid <= 0) { panic("create user_main failed.\n"); } + // 循环等待和调度,直到所有用户模式进程结束 while (do_wait(0, NULL) == 0) { schedule(); } + // 所有用户模式进程结束后,打印消息 cprintf("all user-mode processes have quit.\n"); + + // 断言系统状态符合预期 assert(initproc->cptr == NULL && initproc->yptr == NULL && initproc->optr == NULL); assert(nr_process == 2); assert(list_next(&proc_list) == &(initproc->list_link)); assert(list_prev(&proc_list) == &(initproc->list_link)); + // 如果所有检查通过,打印内存检查通过的消息 cprintf("init check memory pass.\n"); return 0; } @@ -813,15 +1134,20 @@ void proc_init(void) { int i; + // 初始化全局进程列表 list_init(&proc_list); + + // 初始化哈希列表,用于快速查找进程 for (i = 0; i < HASH_LIST_SIZE; i ++) { list_init(hash_list + i); } + // 分配空闲进程idleproc,这是系统中的第一个进程 if ((idleproc = alloc_proc()) == NULL) { panic("cannot alloc idleproc.\n"); } + // 设置idleproc的基本信息 idleproc->pid = 0; idleproc->state = PROC_RUNNABLE; idleproc->kstack = (uintptr_t)bootstack; @@ -829,16 +1155,20 @@ proc_init(void) { set_proc_name(idleproc, "idle"); nr_process ++; + // 将当前进程设置为idleproc current = idleproc; + // 创建初始化进程init_main,这是系统中的第二个进程 int pid = kernel_thread(init_main, NULL, 0); if (pid <= 0) { panic("create init_main failed.\n"); } + // 查找并设置初始化进程initproc initproc = find_proc(pid); set_proc_name(initproc, "init"); + // 断言确保idleproc和initproc正确初始化 assert(idleproc != NULL && idleproc->pid == 0); assert(initproc != NULL && initproc->pid == 1); } @@ -847,6 +1177,7 @@ proc_init(void) { void cpu_idle(void) { while (1) { + //检查当前进程是否需要重新调度 if (current->need_resched) { schedule(); } diff --git a/labcodes/lab5/kern/schedule/sched.c b/labcodes/lab5/kern/schedule/sched.c index 939caf469cb17712d3a7320e481e498fa6935b1e..c27343c7743595a102750687288590e19731c394 100644 --- a/labcodes/lab5/kern/schedule/sched.c +++ b/labcodes/lab5/kern/schedule/sched.c @@ -21,32 +21,53 @@ wakeup_proc(struct proc_struct *proc) { local_intr_restore(intr_flag); } +/** + * schedule是操作系统中的调度函数,用于选择下一个要执行的进程并进行上下文切换。 + * 该函数首先检查当前进程是否需要重新调度,然后在进程列表中查找处于可运行状态的进程。 + * 如果找到可运行的进程,则选择该进程作为下一个要执行的进程,并进行上下文切换。 + * 如果没有找到可运行的进程,则选择空闲进程作为下一个要执行的进程。 + * 最后,恢复中断状态并退出调度函数。 + */ void schedule(void) { + // 保存中断状态标志 bool intr_flag; + // 定义指向进程列表项的指针 list_entry_t *le, *last; + // 定义下一个要执行的进程指针,并初始化为NULL struct proc_struct *next = NULL; + // 保存当前中断状态,并禁止中断 local_intr_save(intr_flag); { + // 标记当前进程不需要重新调度 current->need_resched = 0; + // 确定进程列表的最后一个元素 last = (current == idleproc) ? &proc_list : &(current->list_link); + // 从最后一个元素开始遍历进程列表 le = last; do { + // 如果不是进程列表的末尾,则继续查找下一个可运行的进程 if ((le = list_next(le)) != &proc_list) { + // 获取当前列表项对应的进程结构体 next = le2proc(le, list_link); + // 如果进程处于可运行状态,则停止查找 if (next->state == PROC_RUNNABLE) { break; } } } while (le != last); + // 如果没有找到可运行的进程,则选择空闲进程作为下一个要执行的进程 if (next == NULL || next->state != PROC_RUNNABLE) { next = idleproc; } + // 增加下一个要执行的进程的运行次数 next->runs ++; + // 如果下一个要执行的进程不是当前进程,则进行上下文切换 if (next != current) { proc_run(next); } } + // 恢复中断状态 local_intr_restore(intr_flag); } diff --git a/labcodes/lab5/kern/syscall/syscall.c b/labcodes/lab5/kern/syscall/syscall.c index 7a7e4e25498a49b17e0810c9adeffd8f0c71735f..c48667e11b58d61d77fae436b548963b7b8d7438 100644 --- a/labcodes/lab5/kern/syscall/syscall.c +++ b/labcodes/lab5/kern/syscall/syscall.c @@ -12,6 +12,7 @@ sys_exit(uint32_t arg[]) { return do_exit(error_code); } +//实现进程的创建 static int sys_fork(uint32_t arg[]) { struct trapframe *tf = current->tf; @@ -26,6 +27,7 @@ sys_wait(uint32_t arg[]) { return do_wait(pid, store); } +//执行一个系统调用 static int sys_exec(uint32_t arg[]) { const char *name = (const char *)arg[0]; @@ -46,6 +48,7 @@ sys_kill(uint32_t arg[]) { return do_kill(pid); } +//获取当前进程的进程ID(PID) static int sys_getpid(uint32_t arg[]) { return current->pid; @@ -54,13 +57,13 @@ sys_getpid(uint32_t arg[]) { static int sys_putc(uint32_t arg[]) { int c = (int)arg[0]; - cputchar(c); + cputchar(c);//将字符 c 输出到控制台 return 0; } static int sys_pgdir(uint32_t arg[]) { - print_pgdir(); + print_pgdir();//打印页目录信息 return 0; } @@ -78,12 +81,18 @@ static int (*syscalls[])(uint32_t arg[]) = { #define NUM_SYSCALLS ((sizeof(syscalls)) / (sizeof(syscalls[0]))) +//系统调用处理函数,1、获取当前线程的陷阱帧;2、提取系统调用号; +//3、如果系统调用号有效且对应的处理函数存在,则调用该处理函数并返回结果。 void syscall(void) { + //获取当前线程的陷阱帧 struct trapframe *tf = current->tf; uint32_t arg[5]; + //提取系统调用号 int num = tf->tf_regs.reg_eax; + //检查系统调用号的有效性 if (num >= 0 && num < NUM_SYSCALLS) { + //调用相应的系统调用处理函数 if (syscalls[num] != NULL) { arg[0] = tf->tf_regs.reg_edx; arg[1] = tf->tf_regs.reg_ecx; @@ -95,6 +104,7 @@ syscall(void) { } } print_trapframe(tf); + //处理无效系统调用 panic("undefined syscall %d, pid = %d, name = %s.\n", num, current->pid, current->name); } diff --git a/labcodes/lab5/kern/trap/trap.c b/labcodes/lab5/kern/trap/trap.c index 1efe3892f91910fe8665ada4d35cbf2b8125f8b6..b361e7ab664280e3da555d589bd17c091dd4f646 100644 --- a/labcodes/lab5/kern/trap/trap.c +++ b/labcodes/lab5/kern/trap/trap.c @@ -22,7 +22,7 @@ static void print_ticks() { cprintf("%d ticks\n",TICK_NUM); #ifdef DEBUG_GRADE cprintf("End of Test.\n"); - panic("EOT: kernel seems ok."); + panic("EOT: kernel seems ok.");//panic 是一个用于处理内核崩溃的函数,它会打印出错误信息并导致系统停止运行。 #endif } @@ -32,8 +32,11 @@ static void print_ticks() { * Must be built at run time because shifted function addresses can't * be represented in relocation records. * */ +//这行代码定义了一个名为 idt 的静态数组,其类型为 struct gatedesc,长度为 256。 +//gatedesc 通常表示中断门描述符,包含有关中断的各种信息 static struct gatedesc idt[256] = {{0}}; +//静态变量 idt_pd,它的类型为 struct pseudodesc。这个结构通常用于描述 IDT 的位置和大小,以便 CPU 知道如何加载 IDT。 static struct pseudodesc idt_pd = { sizeof(idt) - 1, (uintptr_t)idt }; @@ -53,6 +56,20 @@ idt_init(void) { * You don't know the meaning of this instruction? just google it! and check the libs/x86.h to know more. * Notice: the argument of lidt is idt_pd. try to find it! */ + extern uintptr_t __vectors[];//声明了一个外部数组 __vectors,该数组存储中断服务例程(ISR)的地址。 + int i; + for (i = 0; i < sizeof(idt) / sizeof(struct gatedesc); i ++) { + SETGATE(idt[i], 0, GD_KTEXT, __vectors[i], DPL_KERNEL); + } + //宏用于配置每个 IDT 条目.0 表示最高特权级(内核级)GD_KTEXT: 指向内核代码段的选择子,确保 ISR 在内核代码段中执行。 + //__vectors[i]: 对应中断的 ISR 地址,DPL_KERNEL: 描述符特权级,表示该中断只能由内核级代码触发。 + // set for switch from user to kernel + //SETGATE 这行代码特别设置了 T_SWITCH_TOK(一个特定的中断向量,用于用户态到内核态的切换)的 IDT 条目。 + //DPL_USER 表示该中断可以由用户态代码触发 + SETGATE(idt[T_SYSCALL], 1, GD_KTEXT, __vectors[T_SYSCALL], DPL_USER); + // load the IDT + //使用 lidt 指令将 IDT 描述符加载到 CPU 中 + lidt(&idt_pd); /* LAB5 YOUR CODE */ //you should update your lab1 code (just add ONE or TWO lines of code), let user app to use syscall to get the service of ucore //so you should setup the syscall interrupt gate in here @@ -82,10 +99,11 @@ trapname(int trapno) { "Machine-Check", "SIMD Floating-Point Exception" }; - + //如果 trapno 小于数组长度,则返回对应的异常名称。 if (trapno < sizeof(excnames)/sizeof(const char * const)) { return excnames[trapno]; } + //如果 trapno 在 IRQ_OFFSET 和 IRQ_OFFSET + 16 之间,表示它是一个硬件中断 if (trapno >= IRQ_OFFSET && trapno < IRQ_OFFSET + 16) { return "Hardware Interrupt"; } @@ -96,48 +114,56 @@ trapname(int trapno) { bool trap_in_kernel(struct trapframe *tf) { return (tf->tf_cs == (uint16_t)KERNEL_CS); + //函数通过检查 tf 中的 tf_cs 字段来判断当前处于哪个特权级,tf_cs 存储了当前代码段选择子的值 + //当 tf->tf_cs 等于 KERNEL_CS 时,表示陷阱发生在内核模式下 } - +//数组中的字符串分别表示 IA-32 架构中的不同标志位: static const char *IA32flags[] = { "CF", NULL, "PF", NULL, "AF", NULL, "ZF", "SF", "TF", "IF", "DF", "OF", NULL, NULL, "NT", NULL, "RF", "VM", "AC", "VIF", "VIP", "ID", NULL, NULL, }; +//struct trapframe *tf,一个指向 trapframe 结构的指针,包含有关陷阱发生时的 CPU 状态的信息。 void print_trapframe(struct trapframe *tf) { - cprintf("trapframe at %p\n", tf); - print_regs(&tf->tf_regs); + cprintf("trapframe at %p\n", tf); //打印陷阱框架地址 + print_regs(&tf->tf_regs); //打印寄存器状态 + //打印数据段(DS)、扩展段(ES)、文件段(FS)、通用段(GS)的值。 cprintf(" ds 0x----%04x\n", tf->tf_ds); cprintf(" es 0x----%04x\n", tf->tf_es); cprintf(" fs 0x----%04x\n", tf->tf_fs); cprintf(" gs 0x----%04x\n", tf->tf_gs); + // 打印陷阱号(trap number)及其对应的名称,通过调用 trapname 函数获取。 cprintf(" trap 0x%08x %s\n", tf->tf_trapno, trapname(tf->tf_trapno)); - cprintf(" err 0x%08x\n", tf->tf_err); - cprintf(" eip 0x%08x\n", tf->tf_eip); - cprintf(" cs 0x----%04x\n", tf->tf_cs); - cprintf(" flag 0x%08x ", tf->tf_eflags); - + cprintf(" err 0x%08x\n", tf->tf_err);// 如果有错误代码,打印该字段的值。 + cprintf(" eip 0x%08x\n", tf->tf_eip);//打印当前执行的指令指针(EIP),指向出错或中断的指令。 + cprintf(" cs 0x----%04x\n", tf->tf_cs);//打印代码段寄存器(CS)的值。 + cprintf(" flag 0x%08x ", tf->tf_eflags);// 打印标志寄存器(EFLAGS)的值 + //使用循环遍历 IA32flags 数组,j 表示当前标志位的位掩码。 int i, j; for (i = 0, j = 1; i < sizeof(IA32flags) / sizeof(IA32flags[0]); i ++, j <<= 1) { if ((tf->tf_eflags & j) && IA32flags[i] != NULL) { cprintf("%s,", IA32flags[i]); } } + //通过位掩码 FL_IOPL_MASK 获取和打印当前的 I/O 特权级别。 cprintf("IOPL=%d\n", (tf->tf_eflags & FL_IOPL_MASK) >> 12); - + //如果陷阱不是在内核中发生的(通过 trap_in_kernel 判断), + //则打印栈指针(ESP)和栈段(SS)寄存器的值。 if (!trap_in_kernel(tf)) { cprintf(" esp 0x%08x\n", tf->tf_esp); cprintf(" ss 0x----%04x\n", tf->tf_ss); } } - +//定义了一个名为 print_regs 的函数, +//打印出存储在 struct pushregs 结构体中的寄存器值。 void print_regs(struct pushregs *regs) { cprintf(" edi 0x%08x\n", regs->reg_edi); cprintf(" esi 0x%08x\n", regs->reg_esi); cprintf(" ebp 0x%08x\n", regs->reg_ebp); - cprintf(" oesp 0x%08x\n", regs->reg_oesp); + cprintf(" oesp 0x%08x\n", regs->reg_oesp);//打印旧的栈指针(OESP),这个寄存器通常在陷阱或中断发生时用于记录上一个栈指针。 cprintf(" ebx 0x%08x\n", regs->reg_ebx); cprintf(" edx 0x%08x\n", regs->reg_edx); cprintf(" ecx 0x%08x\n", regs->reg_ecx); @@ -151,6 +177,11 @@ print_pgfault(struct trapframe *tf) { * bit 1 == 0 means read, 1 means write * bit 2 == 0 means kernel, 1 means user * */ + /* error_code: + * bit 0 == 0 表示未找到页面,1 表示保护故障 + * bit 1 == 0 表示读操作,1 表示写操作 + * bit 2 == 0 表示内核模式,1 表示用户模式 + * */ cprintf("page fault at 0x%08x: %c/%c [%s].\n", rcr2(), (tf->tf_err & 4) ? 'U' : 'K', (tf->tf_err & 2) ? 'W' : 'R', @@ -223,7 +254,12 @@ trap_dispatch(struct trapframe *tf) { /* you should upate you lab1 code (just add ONE or TWO lines of code): * Every TICK_NUM cycle, you should set current process's current->need_resched = 1 */ - + ticks ++; //记录中断事件 + if (ticks % TICK_NUM == 0) + { + assert(current != NULL); + current->need_resched = 1; + }//每经过 TICK_NUM 次周期时,调用 print_ticks() 打印信息 break; case IRQ_OFFSET + IRQ_COM1: c = cons_getc(); diff --git a/labcodes/lab5/kern/trap/trapentry.S b/labcodes/lab5/kern/trap/trapentry.S index 3565ec8e9968768e106e11289eacf4634becbdba..ad9313d17911539b9c17ac9773341ededa4247a3 100644 --- a/labcodes/lab5/kern/trap/trapentry.S +++ b/labcodes/lab5/kern/trap/trapentry.S @@ -1,11 +1,13 @@ #include # vectors.S sends all traps here. +# 定义了一个全局标签 __alltraps,这是处理所有异常的入口点。 .text .globl __alltraps __alltraps: # push registers to build a trap frame # therefore make the stack look like a struct trapframe + # 通过 push 指令,将数据段寄存器和所有通用寄存器(使用 pushal)的值压入栈中,以保存当前状态。 pushl %ds pushl %es pushl %fs @@ -13,32 +15,39 @@ __alltraps: pushal # load GD_KDATA into %ds and %es to set up data segments for kernel + # 将常量 GD_KDATA 加载到 %eax 中,然后将其值复制到 %ds 和 %es 中,设置内核的数据段。 movl $GD_KDATA, %eax movw %ax, %ds movw %ax, %es # push %esp to pass a pointer to the trapframe as an argument to trap() + # 将 %esp 压栈,以将指向 trapframe 的指针作为参数传递给 trap() pushl %esp # call trap(tf), where tf=%esp + # 调用 trap(tf),其中 tf=%esp call trap - # pop the pushed stack pointer + # pop the pushed stack pointer弹出之前压入的栈指针 popl %esp # return falls through to trapret... + # 返回后继续执行到 trapret... .globl __trapret __trapret: # restore registers from stack + # 定义了返回的入口点 __trapret。 popal # restore %ds, %es, %fs and %gs + # 这里会恢复之前保存的寄存器 popl %gs popl %fs popl %es popl %ds # get rid of the trap number and error code + # 通过 iret 指令返回中断处理 addl $0x8, %esp iret diff --git a/labcodes/lab5/obj/__user_badarg.out b/labcodes/lab5/obj/__user_badarg.out new file mode 100755 index 0000000000000000000000000000000000000000..430e8f9043b5398ccc06bda268eea3407001e3d6 Binary files /dev/null and b/labcodes/lab5/obj/__user_badarg.out differ diff --git a/labcodes/lab5/obj/__user_badsegment.out b/labcodes/lab5/obj/__user_badsegment.out new file mode 100755 index 0000000000000000000000000000000000000000..3d9bebf56ad759444ba2f7d3282be62138ae9e2b Binary files /dev/null and b/labcodes/lab5/obj/__user_badsegment.out differ diff --git a/labcodes/lab5/obj/__user_divzero.out b/labcodes/lab5/obj/__user_divzero.out new file mode 100755 index 0000000000000000000000000000000000000000..5a3256deadd72b9d98253d75f12a18abab7c9a54 Binary files /dev/null and b/labcodes/lab5/obj/__user_divzero.out differ diff --git a/labcodes/lab5/obj/__user_exit.out b/labcodes/lab5/obj/__user_exit.out new file mode 100755 index 0000000000000000000000000000000000000000..2e7a0ce9dd4708d4df00a918f5f0c480d77deed5 Binary files /dev/null and b/labcodes/lab5/obj/__user_exit.out differ diff --git a/labcodes/lab5/obj/__user_faultread.out b/labcodes/lab5/obj/__user_faultread.out new file mode 100755 index 0000000000000000000000000000000000000000..ee7b9f2ee6cfe7face2f5aa18411a147308b5235 Binary files /dev/null and b/labcodes/lab5/obj/__user_faultread.out differ diff --git a/labcodes/lab5/obj/__user_faultreadkernel.out b/labcodes/lab5/obj/__user_faultreadkernel.out new file mode 100755 index 0000000000000000000000000000000000000000..b9289920681687d532b38ae77df7247927918653 Binary files /dev/null and b/labcodes/lab5/obj/__user_faultreadkernel.out differ diff --git a/labcodes/lab5/obj/__user_forktest.out b/labcodes/lab5/obj/__user_forktest.out new file mode 100755 index 0000000000000000000000000000000000000000..c1c3f3160c60ce5a0f8da37c72acc20a11c83ed5 Binary files /dev/null and b/labcodes/lab5/obj/__user_forktest.out differ diff --git a/labcodes/lab5/obj/__user_forktree.out b/labcodes/lab5/obj/__user_forktree.out new file mode 100755 index 0000000000000000000000000000000000000000..c465a2c3512b677ee3a8e6b4267d3771cdacc635 Binary files /dev/null and b/labcodes/lab5/obj/__user_forktree.out differ diff --git a/labcodes/lab5/obj/__user_hello.out b/labcodes/lab5/obj/__user_hello.out new file mode 100755 index 0000000000000000000000000000000000000000..db02393a3060b21e01db07fd3efd18e6c1537aad Binary files /dev/null and b/labcodes/lab5/obj/__user_hello.out differ diff --git a/labcodes/lab5/obj/__user_pgdir.out b/labcodes/lab5/obj/__user_pgdir.out new file mode 100755 index 0000000000000000000000000000000000000000..8fa054f3e01d863a0b3020dcba38f51d2d616908 Binary files /dev/null and b/labcodes/lab5/obj/__user_pgdir.out differ diff --git a/labcodes/lab5/obj/__user_softint.out b/labcodes/lab5/obj/__user_softint.out new file mode 100755 index 0000000000000000000000000000000000000000..dd07ef22fdd601730793f359758fb106cd084ce5 Binary files /dev/null and b/labcodes/lab5/obj/__user_softint.out differ diff --git a/labcodes/lab5/obj/__user_spin.out b/labcodes/lab5/obj/__user_spin.out new file mode 100755 index 0000000000000000000000000000000000000000..16189274c4c229319b9cf645876a52d15fd10875 Binary files /dev/null and b/labcodes/lab5/obj/__user_spin.out differ diff --git a/labcodes/lab5/obj/__user_testbss.out b/labcodes/lab5/obj/__user_testbss.out new file mode 100755 index 0000000000000000000000000000000000000000..802094bea6156baa5f91ad612fbd137d42eea0a5 Binary files /dev/null and b/labcodes/lab5/obj/__user_testbss.out differ diff --git a/labcodes/lab5/obj/__user_waitkill.out b/labcodes/lab5/obj/__user_waitkill.out new file mode 100755 index 0000000000000000000000000000000000000000..8a3f0d1b50703e2678bef375817e383d4843bea6 Binary files /dev/null and b/labcodes/lab5/obj/__user_waitkill.out differ diff --git a/labcodes/lab5/obj/__user_yield.out b/labcodes/lab5/obj/__user_yield.out new file mode 100755 index 0000000000000000000000000000000000000000..abf8f8fd84b31a4a6a0fea8d5c7e76fb2512bda9 Binary files /dev/null and b/labcodes/lab5/obj/__user_yield.out differ diff --git a/labcodes/lab5/obj/boot/bootasm.d b/labcodes/lab5/obj/boot/bootasm.d new file mode 100644 index 0000000000000000000000000000000000000000..0814674615b0e7471d87201075118ec74cb33a79 --- /dev/null +++ b/labcodes/lab5/obj/boot/bootasm.d @@ -0,0 +1 @@ +obj/boot/bootasm.o obj/boot/bootasm.d: boot/bootasm.S boot/asm.h diff --git a/labcodes/lab5/obj/boot/bootasm.o b/labcodes/lab5/obj/boot/bootasm.o new file mode 100644 index 0000000000000000000000000000000000000000..6b8ff77b97811142c4e4064a29aaceb364816082 Binary files /dev/null and b/labcodes/lab5/obj/boot/bootasm.o differ diff --git a/labcodes/lab5/obj/boot/bootmain.d b/labcodes/lab5/obj/boot/bootmain.d new file mode 100644 index 0000000000000000000000000000000000000000..c0d98e63cd309eaf0c4e92439e4ea83bd1c9acc0 --- /dev/null +++ b/labcodes/lab5/obj/boot/bootmain.d @@ -0,0 +1,2 @@ +obj/boot/bootmain.o obj/boot/bootmain.d: boot/bootmain.c libs/defs.h \ + libs/x86.h libs/elf.h diff --git a/labcodes/lab5/obj/boot/bootmain.o b/labcodes/lab5/obj/boot/bootmain.o new file mode 100644 index 0000000000000000000000000000000000000000..c72e25d0a0da0d07b6a528c4edddda1156d4be4d Binary files /dev/null and b/labcodes/lab5/obj/boot/bootmain.o differ diff --git a/labcodes/lab5/obj/bootblock.asm b/labcodes/lab5/obj/bootblock.asm new file mode 100644 index 0000000000000000000000000000000000000000..b7395761d3d8de444c9d945b869c828c8a645ba2 --- /dev/null +++ b/labcodes/lab5/obj/bootblock.asm @@ -0,0 +1,354 @@ + +obj/bootblock.o: file format elf32-i386 + + +Disassembly of section .startup: + +00007c00 : + +# start address should be 0:7c00, in real mode, the beginning address of the running bootloader +.globl start +start: +.code16 # Assemble for 16-bit mode + cli # Disable interrupts + 7c00: fa cli + cld # String operations increment + 7c01: fc cld + + # Set up the important data segment registers (DS, ES, SS). + xorw %ax, %ax # Segment number zero + 7c02: 31 c0 xor %eax,%eax + movw %ax, %ds # -> Data Segment + 7c04: 8e d8 mov %eax,%ds + movw %ax, %es # -> Extra Segment + 7c06: 8e c0 mov %eax,%es + movw %ax, %ss # -> Stack Segment + 7c08: 8e d0 mov %eax,%ss + +00007c0a : + # Enable A20: + # For backwards compatibility with the earliest PCs, physical + # address line 20 is tied low, so that addresses higher than + # 1MB wrap around to zero by default. This code undoes this. +seta20.1: + inb $0x64, %al # Wait for not busy(8042 input buffer empty). + 7c0a: e4 64 in $0x64,%al + testb $0x2, %al + 7c0c: a8 02 test $0x2,%al + jnz seta20.1 + 7c0e: 75 fa jne 7c0a + + movb $0xd1, %al # 0xd1 -> port 0x64 + 7c10: b0 d1 mov $0xd1,%al + outb %al, $0x64 # 0xd1 means: write data to 8042's P2 port + 7c12: e6 64 out %al,$0x64 + +00007c14 : + +seta20.2: + inb $0x64, %al # Wait for not busy(8042 input buffer empty). + 7c14: e4 64 in $0x64,%al + testb $0x2, %al + 7c16: a8 02 test $0x2,%al + jnz seta20.2 + 7c18: 75 fa jne 7c14 + + movb $0xdf, %al # 0xdf -> port 0x60 + 7c1a: b0 df mov $0xdf,%al + outb %al, $0x60 # 0xdf = 11011111, means set P2's A20 bit(the 1 bit) to 1 + 7c1c: e6 60 out %al,$0x60 + +00007c1e : + +probe_memory: + movl $0, 0x8000 + 7c1e: 66 c7 06 00 80 movw $0x8000,(%esi) + 7c23: 00 00 add %al,(%eax) + 7c25: 00 00 add %al,(%eax) + xorl %ebx, %ebx + 7c27: 66 31 db xor %bx,%bx + movw $0x8004, %di + 7c2a: bf .byte 0xbf + 7c2b: 04 80 add $0x80,%al + +00007c2d : +start_probe: + movl $0xE820, %eax + 7c2d: 66 b8 20 e8 mov $0xe820,%ax + 7c31: 00 00 add %al,(%eax) + movl $20, %ecx + 7c33: 66 b9 14 00 mov $0x14,%cx + 7c37: 00 00 add %al,(%eax) + movl $SMAP, %edx + 7c39: 66 ba 50 41 mov $0x4150,%dx + 7c3d: 4d dec %ebp + 7c3e: 53 push %ebx + int $0x15 + 7c3f: cd 15 int $0x15 + jnc cont + 7c41: 73 08 jae 7c4b + movw $12345, 0x8000 + 7c43: c7 06 00 80 39 30 movl $0x30398000,(%esi) + jmp finish_probe + 7c49: eb 0e jmp 7c59 + +00007c4b : +cont: + addw $20, %di + 7c4b: 83 c7 14 add $0x14,%edi + incl 0x8000 + 7c4e: 66 ff 06 incw (%esi) + 7c51: 00 80 66 83 fb 00 add %al,0xfb8366(%eax) + cmpl $0, %ebx + jnz start_probe + 7c57: 75 d4 jne 7c2d + +00007c59 : + + # Switch from real to protected mode, using a bootstrap GDT + # and segment translation that makes virtual addresses + # identical to physical addresses, so that the + # effective memory map does not change during the switch. + lgdt gdtdesc + 7c59: 0f 01 16 lgdtl (%esi) + 7c5c: b8 7d 0f 20 c0 mov $0xc0200f7d,%eax + movl %cr0, %eax + orl $CR0_PE_ON, %eax + 7c61: 66 83 c8 01 or $0x1,%ax + movl %eax, %cr0 + 7c65: 0f 22 c0 mov %eax,%cr0 + + # Jump to next instruction, but in 32-bit code segment. + # Switches processor into 32-bit mode. + ljmp $PROT_MODE_CSEG, $protcseg + 7c68: ea .byte 0xea + 7c69: 6d insl (%dx),%es:(%edi) + 7c6a: 7c 08 jl 7c74 + ... + +00007c6d : + +.code32 # Assemble for 32-bit mode +protcseg: + # Set up the protected-mode data segment registers + movw $PROT_MODE_DSEG, %ax # Our data segment selector + 7c6d: 66 b8 10 00 mov $0x10,%ax + movw %ax, %ds # -> DS: Data Segment + 7c71: 8e d8 mov %eax,%ds + movw %ax, %es # -> ES: Extra Segment + 7c73: 8e c0 mov %eax,%es + movw %ax, %fs # -> FS + 7c75: 8e e0 mov %eax,%fs + movw %ax, %gs # -> GS + 7c77: 8e e8 mov %eax,%gs + movw %ax, %ss # -> SS: Stack Segment + 7c79: 8e d0 mov %eax,%ss + + # Set up the stack pointer and call into C. The stack region is from 0--start(0x7c00) + movl $0x0, %ebp + 7c7b: bd 00 00 00 00 mov $0x0,%ebp + movl $start, %esp + 7c80: bc 00 7c 00 00 mov $0x7c00,%esp + call bootmain + 7c85: e8 a1 00 00 00 call 7d2b + +00007c8a : + + # If bootmain returns (it shouldn't), loop. +spin: + jmp spin + 7c8a: eb fe jmp 7c8a + +Disassembly of section .text: + +00007c8c : +/* * + * readseg - read @count bytes at @offset from kernel into virtual address @va, + * might copy more than asked. + * */ +static void +readseg(uintptr_t va, uint32_t count, uint32_t offset) { + 7c8c: 55 push %ebp + 7c8d: 89 e5 mov %esp,%ebp + 7c8f: 57 push %edi + uintptr_t end_va = va + count; + 7c90: 8d 3c 10 lea (%eax,%edx,1),%edi + + // round down to sector boundary + va -= offset % SECTSIZE; + 7c93: 89 ca mov %ecx,%edx +readseg(uintptr_t va, uint32_t count, uint32_t offset) { + 7c95: 56 push %esi + va -= offset % SECTSIZE; + 7c96: 81 e2 ff 01 00 00 and $0x1ff,%edx + + // translate from bytes to sectors; kernel starts at sector 1 + uint32_t secno = (offset / SECTSIZE) + 1; + 7c9c: c1 e9 09 shr $0x9,%ecx + va -= offset % SECTSIZE; + 7c9f: 29 d0 sub %edx,%eax +readseg(uintptr_t va, uint32_t count, uint32_t offset) { + 7ca1: 53 push %ebx + va -= offset % SECTSIZE; + 7ca2: 89 c6 mov %eax,%esi + uint32_t secno = (offset / SECTSIZE) + 1; + 7ca4: 8d 41 01 lea 0x1(%ecx),%eax +readseg(uintptr_t va, uint32_t count, uint32_t offset) { + 7ca7: 83 ec 08 sub $0x8,%esp + uintptr_t end_va = va + count; + 7caa: 89 7d ec mov %edi,-0x14(%ebp) +static inline void invlpg(void *addr) __attribute__((always_inline)); + +static inline uint8_t +inb(uint16_t port) { + uint8_t data; + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); + 7cad: bb f7 01 00 00 mov $0x1f7,%ebx + uint32_t secno = (offset / SECTSIZE) + 1; + 7cb2: 89 45 f0 mov %eax,-0x10(%ebp) + + // If this is too slow, we could read lots of sectors at a time. + // We'd write more to memory than asked, but it doesn't matter -- + // we load in increasing order. + for (; va < end_va; va += SECTSIZE, secno ++) { + 7cb5: 3b 75 ec cmp -0x14(%ebp),%esi + 7cb8: 73 6a jae 7d24 + 7cba: 89 da mov %ebx,%edx + 7cbc: ec in (%dx),%al + while ((inb(0x1F7) & 0xC0) != 0x40) + 7cbd: 24 c0 and $0xc0,%al + 7cbf: 3c 40 cmp $0x40,%al + 7cc1: 75 f7 jne 7cba + : "memory", "cc"); +} + +static inline void +outb(uint16_t port, uint8_t data) { + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 7cc3: ba f2 01 00 00 mov $0x1f2,%edx + 7cc8: b0 01 mov $0x1,%al + 7cca: ee out %al,(%dx) + 7ccb: ba f3 01 00 00 mov $0x1f3,%edx + 7cd0: 8a 45 f0 mov -0x10(%ebp),%al + 7cd3: ee out %al,(%dx) + outb(0x1F4, (secno >> 8) & 0xFF); + 7cd4: 8b 45 f0 mov -0x10(%ebp),%eax + 7cd7: ba f4 01 00 00 mov $0x1f4,%edx + 7cdc: c1 e8 08 shr $0x8,%eax + 7cdf: ee out %al,(%dx) + outb(0x1F5, (secno >> 16) & 0xFF); + 7ce0: 8b 45 f0 mov -0x10(%ebp),%eax + 7ce3: ba f5 01 00 00 mov $0x1f5,%edx + 7ce8: c1 e8 10 shr $0x10,%eax + 7ceb: ee out %al,(%dx) + outb(0x1F6, ((secno >> 24) & 0xF) | 0xE0); + 7cec: 8b 45 f0 mov -0x10(%ebp),%eax + 7cef: ba f6 01 00 00 mov $0x1f6,%edx + 7cf4: c1 e8 18 shr $0x18,%eax + 7cf7: 24 0f and $0xf,%al + 7cf9: 0c e0 or $0xe0,%al + 7cfb: ee out %al,(%dx) + 7cfc: b0 20 mov $0x20,%al + 7cfe: 89 da mov %ebx,%edx + 7d00: ee out %al,(%dx) + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); + 7d01: 89 da mov %ebx,%edx + 7d03: ec in (%dx),%al + while ((inb(0x1F7) & 0xC0) != 0x40) + 7d04: 24 c0 and $0xc0,%al + 7d06: 3c 40 cmp $0x40,%al + 7d08: 75 f7 jne 7d01 + asm volatile ( + 7d0a: 89 f7 mov %esi,%edi + 7d0c: b9 80 00 00 00 mov $0x80,%ecx + 7d11: ba f0 01 00 00 mov $0x1f0,%edx + 7d16: fc cld + 7d17: f2 6d repnz insl (%dx),%es:(%edi) + for (; va < end_va; va += SECTSIZE, secno ++) { + 7d19: ff 45 f0 incl -0x10(%ebp) + 7d1c: 81 c6 00 02 00 00 add $0x200,%esi + 7d22: eb 91 jmp 7cb5 + readsect((void *)va, secno); + } +} + 7d24: 58 pop %eax + 7d25: 5a pop %edx + 7d26: 5b pop %ebx + 7d27: 5e pop %esi + 7d28: 5f pop %edi + 7d29: 5d pop %ebp + 7d2a: c3 ret + +00007d2b : + +/* bootmain - the entry of bootloader */ +void +bootmain(void) { + 7d2b: 55 push %ebp + // read the 1st page off disk + readseg((uintptr_t)ELFHDR, SECTSIZE * 8, 0); + 7d2c: 31 c9 xor %ecx,%ecx +bootmain(void) { + 7d2e: 89 e5 mov %esp,%ebp + readseg((uintptr_t)ELFHDR, SECTSIZE * 8, 0); + 7d30: ba 00 10 00 00 mov $0x1000,%edx +bootmain(void) { + 7d35: 56 push %esi + readseg((uintptr_t)ELFHDR, SECTSIZE * 8, 0); + 7d36: b8 00 00 01 00 mov $0x10000,%eax +bootmain(void) { + 7d3b: 53 push %ebx + readseg((uintptr_t)ELFHDR, SECTSIZE * 8, 0); + 7d3c: e8 4b ff ff ff call 7c8c + + // is this a valid ELF? + if (ELFHDR->e_magic != ELF_MAGIC) { + 7d41: 81 3d 00 00 01 00 7f cmpl $0x464c457f,0x10000 + 7d48: 45 4c 46 + 7d4b: 75 3f jne 7d8c + } + + struct proghdr *ph, *eph; + + // load each program segment (ignores ph flags) + ph = (struct proghdr *)((uintptr_t)ELFHDR + ELFHDR->e_phoff); + 7d4d: a1 1c 00 01 00 mov 0x1001c,%eax + eph = ph + ELFHDR->e_phnum; + 7d52: 0f b7 35 2c 00 01 00 movzwl 0x1002c,%esi + ph = (struct proghdr *)((uintptr_t)ELFHDR + ELFHDR->e_phoff); + 7d59: 8d 98 00 00 01 00 lea 0x10000(%eax),%ebx + eph = ph + ELFHDR->e_phnum; + 7d5f: c1 e6 05 shl $0x5,%esi + 7d62: 01 de add %ebx,%esi + for (; ph < eph; ph ++) { + 7d64: 39 f3 cmp %esi,%ebx + 7d66: 73 18 jae 7d80 + readseg(ph->p_va & 0xFFFFFF, ph->p_memsz, ph->p_offset); + 7d68: 8b 43 08 mov 0x8(%ebx),%eax + for (; ph < eph; ph ++) { + 7d6b: 83 c3 20 add $0x20,%ebx + readseg(ph->p_va & 0xFFFFFF, ph->p_memsz, ph->p_offset); + 7d6e: 8b 4b e4 mov -0x1c(%ebx),%ecx + 7d71: 8b 53 f4 mov -0xc(%ebx),%edx + 7d74: 25 ff ff ff 00 and $0xffffff,%eax + 7d79: e8 0e ff ff ff call 7c8c + 7d7e: eb e4 jmp 7d64 + } + + // call the entry point from the ELF header + // note: does not return + ((void (*)(void))(ELFHDR->e_entry & 0xFFFFFF))(); + 7d80: a1 18 00 01 00 mov 0x10018,%eax + 7d85: 25 ff ff ff 00 and $0xffffff,%eax + 7d8a: ff d0 call *%eax +} + +static inline void +outw(uint16_t port, uint16_t data) { + asm volatile ("outw %0, %1" :: "a" (data), "d" (port) : "memory"); + 7d8c: ba 00 8a ff ff mov $0xffff8a00,%edx + 7d91: 89 d0 mov %edx,%eax + 7d93: 66 ef out %ax,(%dx) + 7d95: b8 00 8e ff ff mov $0xffff8e00,%eax + 7d9a: 66 ef out %ax,(%dx) + 7d9c: eb fe jmp 7d9c diff --git a/labcodes/lab5/obj/bootblock.o b/labcodes/lab5/obj/bootblock.o new file mode 100755 index 0000000000000000000000000000000000000000..ff4803e4018ce267feef69b24698f85cd3e4a4bd Binary files /dev/null and b/labcodes/lab5/obj/bootblock.o differ diff --git a/labcodes/lab5/obj/bootblock.out b/labcodes/lab5/obj/bootblock.out new file mode 100755 index 0000000000000000000000000000000000000000..4bbb6755d2289c820b5c874c4ecdfe0a93460849 Binary files /dev/null and b/labcodes/lab5/obj/bootblock.out differ diff --git a/labcodes/lab5/obj/kern/debug/kdebug.d b/labcodes/lab5/obj/kern/debug/kdebug.d new file mode 100644 index 0000000000000000000000000000000000000000..e7273a7597545c77d15b480326472bd1e26bc8a4 --- /dev/null +++ b/labcodes/lab5/obj/kern/debug/kdebug.d @@ -0,0 +1,6 @@ +obj/kern/debug/kdebug.o obj/kern/debug/kdebug.d: kern/debug/kdebug.c \ + libs/defs.h libs/x86.h kern/debug/stab.h libs/stdio.h libs/stdarg.h \ + libs/string.h kern/mm/memlayout.h libs/atomic.h libs/list.h \ + kern/sync/sync.h kern/driver/intr.h kern/mm/mmu.h kern/debug/assert.h \ + kern/schedule/sched.h kern/process/proc.h kern/trap/trap.h kern/mm/vmm.h \ + kern/debug/kdebug.h kern/debug/kmonitor.h diff --git a/labcodes/lab5/obj/kern/debug/kdebug.o b/labcodes/lab5/obj/kern/debug/kdebug.o new file mode 100644 index 0000000000000000000000000000000000000000..93f02e06450a1ed16affeb3494de42a69e2155dc Binary files /dev/null and b/labcodes/lab5/obj/kern/debug/kdebug.o differ diff --git a/labcodes/lab5/obj/kern/debug/kmonitor.d b/labcodes/lab5/obj/kern/debug/kmonitor.d new file mode 100644 index 0000000000000000000000000000000000000000..11c2af26a538a8fae989f8ac595edba72ba9fdb0 --- /dev/null +++ b/labcodes/lab5/obj/kern/debug/kmonitor.d @@ -0,0 +1,4 @@ +obj/kern/debug/kmonitor.o obj/kern/debug/kmonitor.d: \ + kern/debug/kmonitor.c libs/stdio.h libs/defs.h libs/stdarg.h \ + libs/string.h kern/mm/mmu.h kern/trap/trap.h kern/debug/kmonitor.h \ + kern/debug/kdebug.h diff --git a/labcodes/lab5/obj/kern/debug/kmonitor.o b/labcodes/lab5/obj/kern/debug/kmonitor.o new file mode 100644 index 0000000000000000000000000000000000000000..c017d8b574656587ef3fa54b8fb2a3eefa687c2e Binary files /dev/null and b/labcodes/lab5/obj/kern/debug/kmonitor.o differ diff --git a/labcodes/lab5/obj/kern/debug/panic.d b/labcodes/lab5/obj/kern/debug/panic.d new file mode 100644 index 0000000000000000000000000000000000000000..084ebb66bb08c9eec69fc03aac82918ef9b8ae9e --- /dev/null +++ b/labcodes/lab5/obj/kern/debug/panic.d @@ -0,0 +1,3 @@ +obj/kern/debug/panic.o obj/kern/debug/panic.d: kern/debug/panic.c \ + libs/defs.h libs/stdio.h libs/stdarg.h kern/driver/intr.h \ + kern/debug/kmonitor.h kern/trap/trap.h diff --git a/labcodes/lab5/obj/kern/debug/panic.o b/labcodes/lab5/obj/kern/debug/panic.o new file mode 100644 index 0000000000000000000000000000000000000000..b96eab54e3e8c064ff8fbc46dcf963bc98851cd9 Binary files /dev/null and b/labcodes/lab5/obj/kern/debug/panic.o differ diff --git a/labcodes/lab5/obj/kern/driver/clock.d b/labcodes/lab5/obj/kern/driver/clock.d new file mode 100644 index 0000000000000000000000000000000000000000..bdff3ffda4b8e673a5a6103b981d74b45f82c665 --- /dev/null +++ b/labcodes/lab5/obj/kern/driver/clock.d @@ -0,0 +1,3 @@ +obj/kern/driver/clock.o obj/kern/driver/clock.d: kern/driver/clock.c \ + libs/x86.h libs/defs.h kern/trap/trap.h libs/stdio.h libs/stdarg.h \ + kern/driver/picirq.h diff --git a/labcodes/lab5/obj/kern/driver/clock.o b/labcodes/lab5/obj/kern/driver/clock.o new file mode 100644 index 0000000000000000000000000000000000000000..621e9a16d966fcd3554e8567fa51fcae9eeb6ffb Binary files /dev/null and b/labcodes/lab5/obj/kern/driver/clock.o differ diff --git a/labcodes/lab5/obj/kern/driver/console.d b/labcodes/lab5/obj/kern/driver/console.d new file mode 100644 index 0000000000000000000000000000000000000000..ed8cc8c02baef47546b4bec2e9dba96006f1bfb2 --- /dev/null +++ b/labcodes/lab5/obj/kern/driver/console.d @@ -0,0 +1,6 @@ +obj/kern/driver/console.o obj/kern/driver/console.d: \ + kern/driver/console.c libs/defs.h libs/x86.h libs/stdio.h libs/stdarg.h \ + libs/string.h kern/driver/kbdreg.h kern/driver/picirq.h kern/trap/trap.h \ + kern/mm/memlayout.h libs/atomic.h libs/list.h kern/sync/sync.h \ + kern/driver/intr.h kern/mm/mmu.h kern/debug/assert.h \ + kern/schedule/sched.h kern/process/proc.h diff --git a/labcodes/lab5/obj/kern/driver/console.o b/labcodes/lab5/obj/kern/driver/console.o new file mode 100644 index 0000000000000000000000000000000000000000..55495cde614887d7b152fb63ac4f303314bc71dd Binary files /dev/null and b/labcodes/lab5/obj/kern/driver/console.o differ diff --git a/labcodes/lab5/obj/kern/driver/ide.d b/labcodes/lab5/obj/kern/driver/ide.d new file mode 100644 index 0000000000000000000000000000000000000000..8b6e6cf004553e071f0200416015ca08654780c0 --- /dev/null +++ b/labcodes/lab5/obj/kern/driver/ide.d @@ -0,0 +1,4 @@ +obj/kern/driver/ide.o obj/kern/driver/ide.d: kern/driver/ide.c \ + libs/defs.h libs/stdio.h libs/stdarg.h kern/trap/trap.h \ + kern/driver/picirq.h kern/fs/fs.h kern/mm/mmu.h kern/driver/ide.h \ + libs/x86.h kern/debug/assert.h diff --git a/labcodes/lab5/obj/kern/driver/ide.o b/labcodes/lab5/obj/kern/driver/ide.o new file mode 100644 index 0000000000000000000000000000000000000000..ff1525f333f8d9f6f585ebfa29a2c7dd9ee8d1c5 Binary files /dev/null and b/labcodes/lab5/obj/kern/driver/ide.o differ diff --git a/labcodes/lab5/obj/kern/driver/intr.d b/labcodes/lab5/obj/kern/driver/intr.d new file mode 100644 index 0000000000000000000000000000000000000000..d0f9177c9eaeab75af2601390be216c9e6129ec8 --- /dev/null +++ b/labcodes/lab5/obj/kern/driver/intr.d @@ -0,0 +1,2 @@ +obj/kern/driver/intr.o obj/kern/driver/intr.d: kern/driver/intr.c \ + libs/x86.h libs/defs.h kern/driver/intr.h diff --git a/labcodes/lab5/obj/kern/driver/intr.o b/labcodes/lab5/obj/kern/driver/intr.o new file mode 100644 index 0000000000000000000000000000000000000000..ae30eda041cbc61fe690d88a4c1694d2a98aa496 Binary files /dev/null and b/labcodes/lab5/obj/kern/driver/intr.o differ diff --git a/labcodes/lab5/obj/kern/driver/picirq.d b/labcodes/lab5/obj/kern/driver/picirq.d new file mode 100644 index 0000000000000000000000000000000000000000..2de8ab1899f9f2be93bd10d4b213864803b6e5b9 --- /dev/null +++ b/labcodes/lab5/obj/kern/driver/picirq.d @@ -0,0 +1,2 @@ +obj/kern/driver/picirq.o obj/kern/driver/picirq.d: kern/driver/picirq.c \ + libs/defs.h libs/x86.h kern/driver/picirq.h diff --git a/labcodes/lab5/obj/kern/driver/picirq.o b/labcodes/lab5/obj/kern/driver/picirq.o new file mode 100644 index 0000000000000000000000000000000000000000..ace5347e92cc594c1b60313b8f6615275b5e4439 Binary files /dev/null and b/labcodes/lab5/obj/kern/driver/picirq.o differ diff --git a/labcodes/lab5/obj/kern/fs/swapfs.d b/labcodes/lab5/obj/kern/fs/swapfs.d new file mode 100644 index 0000000000000000000000000000000000000000..0b9252355ddaaedec75a8d9c16dd3456e2509c4d --- /dev/null +++ b/labcodes/lab5/obj/kern/fs/swapfs.d @@ -0,0 +1,6 @@ +obj/kern/fs/swapfs.o obj/kern/fs/swapfs.d: kern/fs/swapfs.c \ + kern/mm/swap.h libs/defs.h kern/mm/memlayout.h libs/atomic.h libs/list.h \ + kern/mm/pmm.h kern/mm/mmu.h kern/debug/assert.h kern/mm/vmm.h \ + kern/sync/sync.h libs/x86.h kern/driver/intr.h kern/schedule/sched.h \ + kern/process/proc.h kern/trap/trap.h kern/fs/swapfs.h kern/fs/fs.h \ + kern/driver/ide.h diff --git a/labcodes/lab5/obj/kern/fs/swapfs.o b/labcodes/lab5/obj/kern/fs/swapfs.o new file mode 100644 index 0000000000000000000000000000000000000000..1f55a4995aa18369b6a7cef4909b5a57d6f16964 Binary files /dev/null and b/labcodes/lab5/obj/kern/fs/swapfs.o differ diff --git a/labcodes/lab5/obj/kern/init/entry.d b/labcodes/lab5/obj/kern/init/entry.d new file mode 100644 index 0000000000000000000000000000000000000000..c6b2d371d41761b6f69cfb032098321e2ec91c41 --- /dev/null +++ b/labcodes/lab5/obj/kern/init/entry.d @@ -0,0 +1,2 @@ +obj/kern/init/entry.o obj/kern/init/entry.d: kern/init/entry.S \ + kern/mm/mmu.h kern/mm/memlayout.h diff --git a/labcodes/lab5/obj/kern/init/entry.o b/labcodes/lab5/obj/kern/init/entry.o new file mode 100644 index 0000000000000000000000000000000000000000..67db0a18d9a48e4e0777e370d1c07c3cc1bc7362 Binary files /dev/null and b/labcodes/lab5/obj/kern/init/entry.o differ diff --git a/labcodes/lab5/obj/kern/init/init.d b/labcodes/lab5/obj/kern/init/init.d new file mode 100644 index 0000000000000000000000000000000000000000..0502d9493755b849bffb926ef6ef9a047738d666 --- /dev/null +++ b/labcodes/lab5/obj/kern/init/init.d @@ -0,0 +1,8 @@ +obj/kern/init/init.o obj/kern/init/init.d: kern/init/init.c libs/defs.h \ + libs/stdio.h libs/stdarg.h libs/string.h kern/driver/console.h \ + kern/debug/kdebug.h kern/trap/trap.h kern/driver/picirq.h \ + kern/driver/clock.h kern/driver/intr.h kern/mm/pmm.h kern/mm/mmu.h \ + kern/mm/memlayout.h libs/atomic.h libs/list.h kern/debug/assert.h \ + kern/mm/vmm.h kern/sync/sync.h libs/x86.h kern/schedule/sched.h \ + kern/process/proc.h kern/driver/ide.h kern/mm/swap.h \ + kern/debug/kmonitor.h diff --git a/labcodes/lab5/obj/kern/init/init.o b/labcodes/lab5/obj/kern/init/init.o new file mode 100644 index 0000000000000000000000000000000000000000..de8ec0fc174289dc44e8a1447996002241632063 Binary files /dev/null and b/labcodes/lab5/obj/kern/init/init.o differ diff --git a/labcodes/lab5/obj/kern/libs/readline.d b/labcodes/lab5/obj/kern/libs/readline.d new file mode 100644 index 0000000000000000000000000000000000000000..656abf96b4c816940c02189bdc6490372dfc3c49 --- /dev/null +++ b/labcodes/lab5/obj/kern/libs/readline.d @@ -0,0 +1,2 @@ +obj/kern/libs/readline.o obj/kern/libs/readline.d: kern/libs/readline.c \ + libs/stdio.h libs/defs.h libs/stdarg.h diff --git a/labcodes/lab5/obj/kern/libs/readline.o b/labcodes/lab5/obj/kern/libs/readline.o new file mode 100644 index 0000000000000000000000000000000000000000..ff86b2d49d90136bac3939da6bc1486807bd25d6 Binary files /dev/null and b/labcodes/lab5/obj/kern/libs/readline.o differ diff --git a/labcodes/lab5/obj/kern/libs/stdio.d b/labcodes/lab5/obj/kern/libs/stdio.d new file mode 100644 index 0000000000000000000000000000000000000000..5e205ace5babb64121955473f1af46dbc8b90e51 --- /dev/null +++ b/labcodes/lab5/obj/kern/libs/stdio.d @@ -0,0 +1,2 @@ +obj/kern/libs/stdio.o obj/kern/libs/stdio.d: kern/libs/stdio.c \ + libs/defs.h libs/stdio.h libs/stdarg.h kern/driver/console.h diff --git a/labcodes/lab5/obj/kern/libs/stdio.o b/labcodes/lab5/obj/kern/libs/stdio.o new file mode 100644 index 0000000000000000000000000000000000000000..11b8d8ca228c5be48a85dacc97347b50c7b57379 Binary files /dev/null and b/labcodes/lab5/obj/kern/libs/stdio.o differ diff --git a/labcodes/lab5/obj/kern/mm/default_pmm.d b/labcodes/lab5/obj/kern/mm/default_pmm.d new file mode 100644 index 0000000000000000000000000000000000000000..8c415bfea7b5a19a92a142688e8c23e11882b103 --- /dev/null +++ b/labcodes/lab5/obj/kern/mm/default_pmm.d @@ -0,0 +1,4 @@ +obj/kern/mm/default_pmm.o obj/kern/mm/default_pmm.d: \ + kern/mm/default_pmm.c kern/mm/pmm.h libs/defs.h kern/mm/mmu.h \ + kern/mm/memlayout.h libs/atomic.h libs/list.h kern/debug/assert.h \ + libs/string.h kern/mm/default_pmm.h diff --git a/labcodes/lab5/obj/kern/mm/default_pmm.o b/labcodes/lab5/obj/kern/mm/default_pmm.o new file mode 100644 index 0000000000000000000000000000000000000000..08bfe5d1aa5f1f0ff3a13049381f696073e7ef47 Binary files /dev/null and b/labcodes/lab5/obj/kern/mm/default_pmm.o differ diff --git a/labcodes/lab5/obj/kern/mm/kmalloc.d b/labcodes/lab5/obj/kern/mm/kmalloc.d new file mode 100644 index 0000000000000000000000000000000000000000..24521088f3c7b346d14c4b3adde3cb7a472109e7 --- /dev/null +++ b/labcodes/lab5/obj/kern/mm/kmalloc.d @@ -0,0 +1,6 @@ +obj/kern/mm/kmalloc.o obj/kern/mm/kmalloc.d: kern/mm/kmalloc.c \ + libs/defs.h libs/list.h kern/mm/memlayout.h libs/atomic.h \ + kern/debug/assert.h kern/mm/kmalloc.h kern/sync/sync.h libs/x86.h \ + kern/driver/intr.h kern/mm/mmu.h kern/schedule/sched.h \ + kern/process/proc.h kern/trap/trap.h kern/mm/pmm.h libs/stdio.h \ + libs/stdarg.h diff --git a/labcodes/lab5/obj/kern/mm/kmalloc.o b/labcodes/lab5/obj/kern/mm/kmalloc.o new file mode 100644 index 0000000000000000000000000000000000000000..035ed228a28ad688ac8e6f001a496f621d6a4dd8 Binary files /dev/null and b/labcodes/lab5/obj/kern/mm/kmalloc.o differ diff --git a/labcodes/lab5/obj/kern/mm/pmm.d b/labcodes/lab5/obj/kern/mm/pmm.d new file mode 100644 index 0000000000000000000000000000000000000000..185d6c481572e7e39554377ae041d5060f115161 --- /dev/null +++ b/labcodes/lab5/obj/kern/mm/pmm.d @@ -0,0 +1,7 @@ +obj/kern/mm/pmm.o obj/kern/mm/pmm.d: kern/mm/pmm.c libs/defs.h libs/x86.h \ + libs/stdio.h libs/stdarg.h libs/string.h kern/mm/mmu.h \ + kern/mm/memlayout.h libs/atomic.h libs/list.h kern/mm/pmm.h \ + kern/debug/assert.h kern/mm/default_pmm.h kern/sync/sync.h \ + kern/driver/intr.h kern/schedule/sched.h kern/process/proc.h \ + kern/trap/trap.h libs/error.h kern/mm/swap.h kern/mm/vmm.h \ + kern/mm/kmalloc.h diff --git a/labcodes/lab5/obj/kern/mm/pmm.o b/labcodes/lab5/obj/kern/mm/pmm.o new file mode 100644 index 0000000000000000000000000000000000000000..f47720c3de931ce0944395098377e227fe02562f Binary files /dev/null and b/labcodes/lab5/obj/kern/mm/pmm.o differ diff --git a/labcodes/lab5/obj/kern/mm/swap.d b/labcodes/lab5/obj/kern/mm/swap.d new file mode 100644 index 0000000000000000000000000000000000000000..eab1cf99ac8b9b6ec437045cafd486dd54d9e416 --- /dev/null +++ b/labcodes/lab5/obj/kern/mm/swap.d @@ -0,0 +1,6 @@ +obj/kern/mm/swap.o obj/kern/mm/swap.d: kern/mm/swap.c kern/mm/swap.h \ + libs/defs.h kern/mm/memlayout.h libs/atomic.h libs/list.h kern/mm/pmm.h \ + kern/mm/mmu.h kern/debug/assert.h kern/mm/vmm.h kern/sync/sync.h \ + libs/x86.h kern/driver/intr.h kern/schedule/sched.h kern/process/proc.h \ + kern/trap/trap.h kern/fs/swapfs.h kern/mm/swap_fifo.h libs/stdio.h \ + libs/stdarg.h libs/string.h kern/mm/default_pmm.h kern/debug/kdebug.h diff --git a/labcodes/lab5/obj/kern/mm/swap.o b/labcodes/lab5/obj/kern/mm/swap.o new file mode 100644 index 0000000000000000000000000000000000000000..f07b7942db841e526b7c640fb4a461fc0c72b934 Binary files /dev/null and b/labcodes/lab5/obj/kern/mm/swap.o differ diff --git a/labcodes/lab5/obj/kern/mm/swap_fifo.d b/labcodes/lab5/obj/kern/mm/swap_fifo.d new file mode 100644 index 0000000000000000000000000000000000000000..eb2fae933624a284b13bf98896db1cd735c14c8c --- /dev/null +++ b/labcodes/lab5/obj/kern/mm/swap_fifo.d @@ -0,0 +1,6 @@ +obj/kern/mm/swap_fifo.o obj/kern/mm/swap_fifo.d: kern/mm/swap_fifo.c \ + libs/defs.h libs/x86.h libs/stdio.h libs/stdarg.h libs/string.h \ + kern/mm/swap.h kern/mm/memlayout.h libs/atomic.h libs/list.h \ + kern/mm/pmm.h kern/mm/mmu.h kern/debug/assert.h kern/mm/vmm.h \ + kern/sync/sync.h kern/driver/intr.h kern/schedule/sched.h \ + kern/process/proc.h kern/trap/trap.h kern/mm/swap_fifo.h diff --git a/labcodes/lab5/obj/kern/mm/swap_fifo.o b/labcodes/lab5/obj/kern/mm/swap_fifo.o new file mode 100644 index 0000000000000000000000000000000000000000..88d7e766869d1e11c69072612d5a7014c6d96285 Binary files /dev/null and b/labcodes/lab5/obj/kern/mm/swap_fifo.o differ diff --git a/labcodes/lab5/obj/kern/mm/vmm.d b/labcodes/lab5/obj/kern/mm/vmm.d new file mode 100644 index 0000000000000000000000000000000000000000..5c81826f2bf4867603b315f4345079267c2bbdab --- /dev/null +++ b/labcodes/lab5/obj/kern/mm/vmm.d @@ -0,0 +1,6 @@ +obj/kern/mm/vmm.o obj/kern/mm/vmm.d: kern/mm/vmm.c kern/mm/vmm.h \ + libs/defs.h libs/list.h kern/mm/memlayout.h libs/atomic.h \ + kern/sync/sync.h libs/x86.h kern/driver/intr.h kern/mm/mmu.h \ + kern/debug/assert.h kern/schedule/sched.h kern/process/proc.h \ + kern/trap/trap.h libs/string.h libs/stdio.h libs/stdarg.h libs/error.h \ + kern/mm/pmm.h kern/mm/swap.h kern/mm/kmalloc.h diff --git a/labcodes/lab5/obj/kern/mm/vmm.o b/labcodes/lab5/obj/kern/mm/vmm.o new file mode 100644 index 0000000000000000000000000000000000000000..8e91d545406cb07fa8efed195390e8c90294b267 Binary files /dev/null and b/labcodes/lab5/obj/kern/mm/vmm.o differ diff --git a/labcodes/lab5/obj/kern/process/entry.d b/labcodes/lab5/obj/kern/process/entry.d new file mode 100644 index 0000000000000000000000000000000000000000..e1ff346dbe02214a048189f7b001b75e156d4973 --- /dev/null +++ b/labcodes/lab5/obj/kern/process/entry.d @@ -0,0 +1 @@ +obj/kern/process/entry.o obj/kern/process/entry.d: kern/process/entry.S diff --git a/labcodes/lab5/obj/kern/process/entry.o b/labcodes/lab5/obj/kern/process/entry.o new file mode 100644 index 0000000000000000000000000000000000000000..09a23179c632b858bbc590869811075aa7694b3f Binary files /dev/null and b/labcodes/lab5/obj/kern/process/entry.o differ diff --git a/labcodes/lab5/obj/kern/process/proc.d b/labcodes/lab5/obj/kern/process/proc.d new file mode 100644 index 0000000000000000000000000000000000000000..294e036bafbc6c8a2c7c8b837a7ba8adc6d1c437 --- /dev/null +++ b/labcodes/lab5/obj/kern/process/proc.d @@ -0,0 +1,7 @@ +obj/kern/process/proc.o obj/kern/process/proc.d: kern/process/proc.c \ + kern/process/proc.h libs/defs.h libs/list.h kern/trap/trap.h \ + kern/mm/memlayout.h libs/atomic.h kern/mm/kmalloc.h libs/string.h \ + kern/sync/sync.h libs/x86.h kern/driver/intr.h kern/mm/mmu.h \ + kern/debug/assert.h kern/schedule/sched.h kern/mm/pmm.h libs/error.h \ + libs/elf.h kern/mm/vmm.h libs/stdio.h libs/stdarg.h libs/stdlib.h \ + libs/unistd.h diff --git a/labcodes/lab5/obj/kern/process/proc.o b/labcodes/lab5/obj/kern/process/proc.o new file mode 100644 index 0000000000000000000000000000000000000000..4199d3c37a6e9cb4714b5983bbe7027cc7e53b29 Binary files /dev/null and b/labcodes/lab5/obj/kern/process/proc.o differ diff --git a/labcodes/lab5/obj/kern/process/switch.d b/labcodes/lab5/obj/kern/process/switch.d new file mode 100644 index 0000000000000000000000000000000000000000..dcc0fd77fea3a38f19adad14637bd9e017581d4f --- /dev/null +++ b/labcodes/lab5/obj/kern/process/switch.d @@ -0,0 +1,2 @@ +obj/kern/process/switch.o obj/kern/process/switch.d: \ + kern/process/switch.S diff --git a/labcodes/lab5/obj/kern/process/switch.o b/labcodes/lab5/obj/kern/process/switch.o new file mode 100644 index 0000000000000000000000000000000000000000..9af237de163b5000b7d76025f7808965a1743b19 Binary files /dev/null and b/labcodes/lab5/obj/kern/process/switch.o differ diff --git a/labcodes/lab5/obj/kern/schedule/sched.d b/labcodes/lab5/obj/kern/schedule/sched.d new file mode 100644 index 0000000000000000000000000000000000000000..1bfaf692b317916d95ccf48f904db4ef80dd10c9 --- /dev/null +++ b/labcodes/lab5/obj/kern/schedule/sched.d @@ -0,0 +1,5 @@ +obj/kern/schedule/sched.o obj/kern/schedule/sched.d: \ + kern/schedule/sched.c libs/list.h libs/defs.h kern/sync/sync.h \ + libs/x86.h kern/driver/intr.h kern/mm/mmu.h kern/debug/assert.h \ + libs/atomic.h kern/schedule/sched.h kern/process/proc.h kern/trap/trap.h \ + kern/mm/memlayout.h diff --git a/labcodes/lab5/obj/kern/schedule/sched.o b/labcodes/lab5/obj/kern/schedule/sched.o new file mode 100644 index 0000000000000000000000000000000000000000..4eaa7613c3b8ded970abc9df859af729baa5df83 Binary files /dev/null and b/labcodes/lab5/obj/kern/schedule/sched.o differ diff --git a/labcodes/lab5/obj/kern/syscall/syscall.d b/labcodes/lab5/obj/kern/syscall/syscall.d new file mode 100644 index 0000000000000000000000000000000000000000..3162572052dc2ad57d2ef77aeddaeb05b74428be --- /dev/null +++ b/labcodes/lab5/obj/kern/syscall/syscall.d @@ -0,0 +1,5 @@ +obj/kern/syscall/syscall.o obj/kern/syscall/syscall.d: \ + kern/syscall/syscall.c libs/unistd.h kern/process/proc.h libs/defs.h \ + libs/list.h kern/trap/trap.h kern/mm/memlayout.h libs/atomic.h \ + kern/syscall/syscall.h libs/stdio.h libs/stdarg.h kern/mm/pmm.h \ + kern/mm/mmu.h kern/debug/assert.h diff --git a/labcodes/lab5/obj/kern/syscall/syscall.o b/labcodes/lab5/obj/kern/syscall/syscall.o new file mode 100644 index 0000000000000000000000000000000000000000..01a843d9573760f799719918085f34808bdcb501 Binary files /dev/null and b/labcodes/lab5/obj/kern/syscall/syscall.o differ diff --git a/labcodes/lab5/obj/kern/trap/trap.d b/labcodes/lab5/obj/kern/trap/trap.d new file mode 100644 index 0000000000000000000000000000000000000000..142c6c712632c4a68cfa3a9f8feb4896212902d8 --- /dev/null +++ b/labcodes/lab5/obj/kern/trap/trap.d @@ -0,0 +1,7 @@ +obj/kern/trap/trap.o obj/kern/trap/trap.d: kern/trap/trap.c libs/defs.h \ + kern/mm/mmu.h kern/mm/memlayout.h libs/atomic.h libs/list.h \ + kern/driver/clock.h kern/trap/trap.h libs/x86.h libs/stdio.h \ + libs/stdarg.h kern/debug/assert.h kern/driver/console.h kern/mm/vmm.h \ + kern/sync/sync.h kern/driver/intr.h kern/schedule/sched.h \ + kern/process/proc.h kern/mm/swap.h kern/mm/pmm.h kern/debug/kdebug.h \ + libs/unistd.h kern/syscall/syscall.h libs/error.h diff --git a/labcodes/lab5/obj/kern/trap/trap.o b/labcodes/lab5/obj/kern/trap/trap.o new file mode 100644 index 0000000000000000000000000000000000000000..36dfced6d48d940475456f35ae756cfba399f00c Binary files /dev/null and b/labcodes/lab5/obj/kern/trap/trap.o differ diff --git a/labcodes/lab5/obj/kern/trap/trapentry.d b/labcodes/lab5/obj/kern/trap/trapentry.d new file mode 100644 index 0000000000000000000000000000000000000000..f37d596cc0396e7d31650d6b287624a3bdcdfdbb --- /dev/null +++ b/labcodes/lab5/obj/kern/trap/trapentry.d @@ -0,0 +1,2 @@ +obj/kern/trap/trapentry.o obj/kern/trap/trapentry.d: \ + kern/trap/trapentry.S kern/mm/memlayout.h diff --git a/labcodes/lab5/obj/kern/trap/trapentry.o b/labcodes/lab5/obj/kern/trap/trapentry.o new file mode 100644 index 0000000000000000000000000000000000000000..1756ff7d140c147a8c1629baba3deea2ec245667 Binary files /dev/null and b/labcodes/lab5/obj/kern/trap/trapentry.o differ diff --git a/labcodes/lab5/obj/kern/trap/vectors.d b/labcodes/lab5/obj/kern/trap/vectors.d new file mode 100644 index 0000000000000000000000000000000000000000..e5813e7765cbb429b0beea10b102bb5b7897e374 --- /dev/null +++ b/labcodes/lab5/obj/kern/trap/vectors.d @@ -0,0 +1 @@ +obj/kern/trap/vectors.o obj/kern/trap/vectors.d: kern/trap/vectors.S diff --git a/labcodes/lab5/obj/kern/trap/vectors.o b/labcodes/lab5/obj/kern/trap/vectors.o new file mode 100644 index 0000000000000000000000000000000000000000..1ebab518e427510c03b2ed5c6be1bdca0bf56c3d Binary files /dev/null and b/labcodes/lab5/obj/kern/trap/vectors.o differ diff --git a/labcodes/lab5/obj/kernel.asm b/labcodes/lab5/obj/kernel.asm new file mode 100644 index 0000000000000000000000000000000000000000..18ecbf73edc0ec163e50c386ae7168acff729be6 --- /dev/null +++ b/labcodes/lab5/obj/kernel.asm @@ -0,0 +1,22974 @@ + +bin/kernel: file format elf32-i386 + + +Disassembly of section .text: + +c0100000 : + +.text +.globl kern_entry +kern_entry: + # load pa of boot pgdir + movl $REALLOC(__boot_pgdir), %eax +c0100000: b8 00 10 1a 00 mov $0x1a1000,%eax + movl %eax, %cr3 +c0100005: 0f 22 d8 mov %eax,%cr3 + + # enable paging + movl %cr0, %eax +c0100008: 0f 20 c0 mov %cr0,%eax + orl $(CR0_PE | CR0_PG | CR0_AM | CR0_WP | CR0_NE | CR0_TS | CR0_EM | CR0_MP), %eax +c010000b: 0d 2f 00 05 80 or $0x8005002f,%eax + andl $~(CR0_TS | CR0_EM), %eax +c0100010: 83 e0 f3 and $0xfffffff3,%eax + movl %eax, %cr0 +c0100013: 0f 22 c0 mov %eax,%cr0 + + # update eip + # now, eip = 0x1..... + leal next, %eax +c0100016: 8d 05 1e 00 10 c0 lea 0xc010001e,%eax + # set eip = KERNBASE + 0x1..... + jmp *%eax +c010001c: ff e0 jmp *%eax + +c010001e : +next: + + # unmap va 0 ~ 4M, it's temporary mapping + xorl %eax, %eax +c010001e: 31 c0 xor %eax,%eax + movl %eax, __boot_pgdir +c0100020: a3 00 10 1a c0 mov %eax,0xc01a1000 + + # set ebp, esp + movl $0x0, %ebp +c0100025: bd 00 00 00 00 mov $0x0,%ebp + # the kernel stack region is from bootstack -- bootstacktop, + # the kernel stack size is KSTACKSIZE (8KB)defined in memlayout.h + movl $bootstacktop, %esp +c010002a: bc 00 f0 12 c0 mov $0xc012f000,%esp + # now kernel stack is ready , call the first C function + call kern_init +c010002f: e8 02 00 00 00 call c0100036 + +c0100034 : + +# should never get here +spin: + jmp spin +c0100034: eb fe jmp c0100034 + +c0100036 : +void grade_backtrace(void); +static void lab1_switch_test(void); + + + int +kern_init(void) { +c0100036: 55 push %ebp +c0100037: 89 e5 mov %esp,%ebp +c0100039: 83 ec 28 sub $0x28,%esp + extern char edata[], end[]; //声明外部变量 edata 和 end + memset(edata, 0, end - edata); // 将数据段清零 +c010003c: b8 54 61 1a c0 mov $0xc01a6154,%eax +c0100041: 2d 00 30 1a c0 sub $0xc01a3000,%eax +c0100046: 89 44 24 08 mov %eax,0x8(%esp) +c010004a: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) +c0100051: 00 +c0100052: c7 04 24 00 30 1a c0 movl $0xc01a3000,(%esp) +c0100059: e8 93 bd 00 00 call c010bdf1 + + cons_init(); // init the console 初始化控制台 +c010005e: e8 4a 16 00 00 call c01016ad + + const char *message = "(THU.CST) os is loading ..."; +c0100063: c7 45 f4 80 bf 10 c0 movl $0xc010bf80,-0xc(%ebp) + cprintf("%s\n\n", message);// 将消息输出到控制台 +c010006a: 8b 45 f4 mov -0xc(%ebp),%eax +c010006d: 89 44 24 04 mov %eax,0x4(%esp) +c0100071: c7 04 24 9c bf 10 c0 movl $0xc010bf9c,(%esp) +c0100078: e8 fb 02 00 00 call c0100378 + + print_kerninfo();// 输出内核信息的函数 +c010007d: e8 0f 09 00 00 call c0100991 + + grade_backtrace(); //调用回溯函数,通常用于调试,显示函数调用栈。 +c0100082: e8 a7 00 00 00 call c010012e + + pmm_init(); // init physical memory management初始化物理内存管理 +c0100087: e8 c3 56 00 00 call c010574f + + pic_init(); // init interrupt controller初始化可编程中断控制器 +c010008c: e8 fa 1f 00 00 call c010208b + idt_init(); // init interrupt descriptor table初始化中断描述符表 +c0100091: e8 5e 21 00 00 call c01021f4 + + vmm_init(); // init virtual memory management 初始化虚拟内存管理 +c0100096: e8 95 86 00 00 call c0108730 + + proc_init(); // init process table +c010009b: e8 02 ad 00 00 call c010ada2 + + ide_init(); // init ide devices初始化IDE设备 +c01000a0: e8 42 17 00 00 call c01017e7 + swap_init(); // init swap 初始化交换分区 +c01000a5: e8 5d 6d 00 00 call c0106e07 + + clock_init(); // init clock interrupt 初始化时钟中断 +c01000aa: e8 5d 0d 00 00 call c0100e0c + intr_enable(); // enable irq interrupt +c01000af: e8 35 1f 00 00 call c0101fe9 + + //LAB1: CAHLLENGE 1 If you try to do it, uncomment lab1_switch_test() + // user/kernel mode switch test + //lab1_switch_test(); + + cpu_idle(); // run idle process 运行空闲进程 +c01000b4: e8 aa ae 00 00 call c010af63 + +c01000b9 : +} + +//不进行内联的回溯函数,调用 mon_backtrace 显示当前的调用栈。 +void __attribute__((noinline)) +grade_backtrace2(int arg0, int arg1, int arg2, int arg3) { +c01000b9: 55 push %ebp +c01000ba: 89 e5 mov %esp,%ebp +c01000bc: 83 ec 18 sub $0x18,%esp + mon_backtrace(0, NULL, NULL); +c01000bf: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) +c01000c6: 00 +c01000c7: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) +c01000ce: 00 +c01000cf: c7 04 24 00 00 00 00 movl $0x0,(%esp) +c01000d6: e8 4c 0c 00 00 call c0100d27 +} +c01000db: 90 nop +c01000dc: 89 ec mov %ebp,%esp +c01000de: 5d pop %ebp +c01000df: c3 ret + +c01000e0 : +//不进行内联的回溯函数,传递参数到 grade_backtrace2 +void __attribute__((noinline)) +grade_backtrace1(int arg0, int arg1) { +c01000e0: 55 push %ebp +c01000e1: 89 e5 mov %esp,%ebp +c01000e3: 83 ec 18 sub $0x18,%esp +c01000e6: 89 5d fc mov %ebx,-0x4(%ebp) + grade_backtrace2(arg0, (int)&arg0, arg1, (int)&arg1); +c01000e9: 8d 4d 0c lea 0xc(%ebp),%ecx +c01000ec: 8b 55 0c mov 0xc(%ebp),%edx +c01000ef: 8d 5d 08 lea 0x8(%ebp),%ebx +c01000f2: 8b 45 08 mov 0x8(%ebp),%eax +c01000f5: 89 4c 24 0c mov %ecx,0xc(%esp) +c01000f9: 89 54 24 08 mov %edx,0x8(%esp) +c01000fd: 89 5c 24 04 mov %ebx,0x4(%esp) +c0100101: 89 04 24 mov %eax,(%esp) +c0100104: e8 b0 ff ff ff call c01000b9 +} +c0100109: 90 nop +c010010a: 8b 5d fc mov -0x4(%ebp),%ebx +c010010d: 89 ec mov %ebp,%esp +c010010f: 5d pop %ebp +c0100110: c3 ret + +c0100111 : +//不进行内联的回溯函数,传递参数到 grade_backtrace1 +void __attribute__((noinline)) +grade_backtrace0(int arg0, int arg1, int arg2) { +c0100111: 55 push %ebp +c0100112: 89 e5 mov %esp,%ebp +c0100114: 83 ec 18 sub $0x18,%esp + grade_backtrace1(arg0, arg2); +c0100117: 8b 45 10 mov 0x10(%ebp),%eax +c010011a: 89 44 24 04 mov %eax,0x4(%esp) +c010011e: 8b 45 08 mov 0x8(%ebp),%eax +c0100121: 89 04 24 mov %eax,(%esp) +c0100124: e8 b7 ff ff ff call c01000e0 +} +c0100129: 90 nop +c010012a: 89 ec mov %ebp,%esp +c010012c: 5d pop %ebp +c010012d: c3 ret + +c010012e : +//触发回溯的起始点,传递初始化函数地址。 +void +grade_backtrace(void) { +c010012e: 55 push %ebp +c010012f: 89 e5 mov %esp,%ebp +c0100131: 83 ec 18 sub $0x18,%esp + grade_backtrace0(0, (int)kern_init, 0xffff0000); +c0100134: b8 36 00 10 c0 mov $0xc0100036,%eax +c0100139: c7 44 24 08 00 00 ff movl $0xffff0000,0x8(%esp) +c0100140: ff +c0100141: 89 44 24 04 mov %eax,0x4(%esp) +c0100145: c7 04 24 00 00 00 00 movl $0x0,(%esp) +c010014c: e8 c0 ff ff ff call c0100111 +} +c0100151: 90 nop +c0100152: 89 ec mov %ebp,%esp +c0100154: 5d pop %ebp +c0100155: c3 ret + +c0100156 : +//打印当前的段寄存器状态。 +static void +lab1_print_cur_status(void) { +c0100156: 55 push %ebp +c0100157: 89 e5 mov %esp,%ebp +c0100159: 83 ec 28 sub $0x28,%esp + static int round = 0; + uint16_t reg1, reg2, reg3, reg4; + //嵌入汇编代码,确保编译器不优化这些代码。 + asm volatile ( +c010015c: 8c 4d f6 mov %cs,-0xa(%ebp) +c010015f: 8c 5d f4 mov %ds,-0xc(%ebp) +c0100162: 8c 45 f2 mov %es,-0xe(%ebp) +c0100165: 8c 55 f0 mov %ss,-0x10(%ebp) + "mov %%cs, %0;"// 将当前代码段寄存器的值移动到 reg1 + "mov %%ds, %1;" + "mov %%es, %2;" + "mov %%ss, %3;" + : "=m"(reg1), "=m"(reg2), "=m"(reg3), "=m"(reg4)); + cprintf("%d: @ring %d\n", round, reg1 & 3);//打印当前的 round、权限级(ring)和各段寄存器的值。 +c0100168: 0f b7 45 f6 movzwl -0xa(%ebp),%eax +c010016c: 83 e0 03 and $0x3,%eax +c010016f: 89 c2 mov %eax,%edx +c0100171: a1 00 30 1a c0 mov 0xc01a3000,%eax +c0100176: 89 54 24 08 mov %edx,0x8(%esp) +c010017a: 89 44 24 04 mov %eax,0x4(%esp) +c010017e: c7 04 24 a1 bf 10 c0 movl $0xc010bfa1,(%esp) +c0100185: e8 ee 01 00 00 call c0100378 + cprintf("%d: cs = %x\n", round, reg1); +c010018a: 0f b7 45 f6 movzwl -0xa(%ebp),%eax +c010018e: 89 c2 mov %eax,%edx +c0100190: a1 00 30 1a c0 mov 0xc01a3000,%eax +c0100195: 89 54 24 08 mov %edx,0x8(%esp) +c0100199: 89 44 24 04 mov %eax,0x4(%esp) +c010019d: c7 04 24 af bf 10 c0 movl $0xc010bfaf,(%esp) +c01001a4: e8 cf 01 00 00 call c0100378 + cprintf("%d: ds = %x\n", round, reg2); +c01001a9: 0f b7 45 f4 movzwl -0xc(%ebp),%eax +c01001ad: 89 c2 mov %eax,%edx +c01001af: a1 00 30 1a c0 mov 0xc01a3000,%eax +c01001b4: 89 54 24 08 mov %edx,0x8(%esp) +c01001b8: 89 44 24 04 mov %eax,0x4(%esp) +c01001bc: c7 04 24 bd bf 10 c0 movl $0xc010bfbd,(%esp) +c01001c3: e8 b0 01 00 00 call c0100378 + cprintf("%d: es = %x\n", round, reg3); +c01001c8: 0f b7 45 f2 movzwl -0xe(%ebp),%eax +c01001cc: 89 c2 mov %eax,%edx +c01001ce: a1 00 30 1a c0 mov 0xc01a3000,%eax +c01001d3: 89 54 24 08 mov %edx,0x8(%esp) +c01001d7: 89 44 24 04 mov %eax,0x4(%esp) +c01001db: c7 04 24 cb bf 10 c0 movl $0xc010bfcb,(%esp) +c01001e2: e8 91 01 00 00 call c0100378 + cprintf("%d: ss = %x\n", round, reg4); +c01001e7: 0f b7 45 f0 movzwl -0x10(%ebp),%eax +c01001eb: 89 c2 mov %eax,%edx +c01001ed: a1 00 30 1a c0 mov 0xc01a3000,%eax +c01001f2: 89 54 24 08 mov %edx,0x8(%esp) +c01001f6: 89 44 24 04 mov %eax,0x4(%esp) +c01001fa: c7 04 24 d9 bf 10 c0 movl $0xc010bfd9,(%esp) +c0100201: e8 72 01 00 00 call c0100378 + round ++;//将 round 增加1,以便每次调用时记录状态。 +c0100206: a1 00 30 1a c0 mov 0xc01a3000,%eax +c010020b: 40 inc %eax +c010020c: a3 00 30 1a c0 mov %eax,0xc01a3000 +} +c0100211: 90 nop +c0100212: 89 ec mov %ebp,%esp +c0100214: 5d pop %ebp +c0100215: c3 ret + +c0100216 : + +static void +lab1_switch_to_user(void) { +c0100216: 55 push %ebp +c0100217: 89 e5 mov %esp,%ebp + // 从内核模式切换到用户模式 + //LAB1 CHALLENGE 1 : TODO + asm volatile ( +c0100219: 83 ec 08 sub $0x8,%esp +c010021c: cd 78 int $0x78 +c010021e: 89 ec mov %ebp,%esp + "int %0 \n"//通过触发一个中断,将控制权转移到内核,切换到用户模式。 + "movl %%ebp, %%esp"// 将基指针(EBP)值移动到堆栈指针(ESP),恢复堆栈指针。 + : + : "i"(T_SWITCH_TOU)//T_SWITCH_TOU是一个常量,表示切换到用户态的中断号。传入常量 T_SWITCH_TOU + ); +} +c0100220: 90 nop +c0100221: 5d pop %ebp +c0100222: c3 ret + +c0100223 : + +static void +lab1_switch_to_kernel(void) { +c0100223: 55 push %ebp +c0100224: 89 e5 mov %esp,%ebp + // 从用户模式切换到内核模式 + //LAB1 CHALLENGE 1 : TODO + asm volatile ( +c0100226: cd 79 int $0x79 +c0100228: 89 ec mov %ebp,%esp + "int %0 \n"// 同样触发中断,这里用的是 T_SWITCH_TOK,从用户态切换回内核态。 + "movl %%ebp, %%esp \n"//恢复堆栈指针 + : + : "i"(T_SWITCH_TOK)//传入常量 T_SWITCH_TOU + ); +} +c010022a: 90 nop +c010022b: 5d pop %ebp +c010022c: c3 ret + +c010022d : + +//测试用户模式和内核模式切换。 +//调用 lab1_print_cur_status 打印当前状态,进行模式切换,然后再次打印状态。 +static void +lab1_switch_test(void) { +c010022d: 55 push %ebp +c010022e: 89 e5 mov %esp,%ebp +c0100230: 83 ec 18 sub $0x18,%esp + lab1_print_cur_status(); +c0100233: e8 1e ff ff ff call c0100156 + cprintf("+++ switch to user mode +++\n"); +c0100238: c7 04 24 e8 bf 10 c0 movl $0xc010bfe8,(%esp) +c010023f: e8 34 01 00 00 call c0100378 + lab1_switch_to_user(); +c0100244: e8 cd ff ff ff call c0100216 + lab1_print_cur_status(); +c0100249: e8 08 ff ff ff call c0100156 + cprintf("+++ switch to kernel mode +++\n"); +c010024e: c7 04 24 08 c0 10 c0 movl $0xc010c008,(%esp) +c0100255: e8 1e 01 00 00 call c0100378 + lab1_switch_to_kernel(); +c010025a: e8 c4 ff ff ff call c0100223 + lab1_print_cur_status(); +c010025f: e8 f2 fe ff ff call c0100156 +c0100264: 90 nop +c0100265: 89 ec mov %ebp,%esp +c0100267: 5d pop %ebp +c0100268: c3 ret + +c0100269 : + * The readline() function returns the text of the line read. If some errors + * are happened, NULL is returned. The return value is a global variable, + * thus it should be copied before it is used. + * */ +char * +readline(const char *prompt) { +c0100269: 55 push %ebp +c010026a: 89 e5 mov %esp,%ebp +c010026c: 83 ec 28 sub $0x28,%esp + if (prompt != NULL) { +c010026f: 83 7d 08 00 cmpl $0x0,0x8(%ebp) +c0100273: 74 13 je c0100288 + cprintf("%s", prompt); +c0100275: 8b 45 08 mov 0x8(%ebp),%eax +c0100278: 89 44 24 04 mov %eax,0x4(%esp) +c010027c: c7 04 24 27 c0 10 c0 movl $0xc010c027,(%esp) +c0100283: e8 f0 00 00 00 call c0100378 + } + int i = 0, c; +c0100288: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + while (1) { + c = getchar(); +c010028f: e8 73 01 00 00 call c0100407 +c0100294: 89 45 f0 mov %eax,-0x10(%ebp) + if (c < 0) { +c0100297: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) +c010029b: 79 07 jns c01002a4 + return NULL; +c010029d: b8 00 00 00 00 mov $0x0,%eax +c01002a2: eb 78 jmp c010031c + } + else if (c >= ' ' && i < BUFSIZE - 1) { +c01002a4: 83 7d f0 1f cmpl $0x1f,-0x10(%ebp) +c01002a8: 7e 28 jle c01002d2 +c01002aa: 81 7d f4 fe 03 00 00 cmpl $0x3fe,-0xc(%ebp) +c01002b1: 7f 1f jg c01002d2 + cputchar(c); +c01002b3: 8b 45 f0 mov -0x10(%ebp),%eax +c01002b6: 89 04 24 mov %eax,(%esp) +c01002b9: e8 e2 00 00 00 call c01003a0 + buf[i ++] = c; +c01002be: 8b 45 f4 mov -0xc(%ebp),%eax +c01002c1: 8d 50 01 lea 0x1(%eax),%edx +c01002c4: 89 55 f4 mov %edx,-0xc(%ebp) +c01002c7: 8b 55 f0 mov -0x10(%ebp),%edx +c01002ca: 88 90 20 30 1a c0 mov %dl,-0x3fe5cfe0(%eax) +c01002d0: eb 45 jmp c0100317 + } + else if (c == '\b' && i > 0) { +c01002d2: 83 7d f0 08 cmpl $0x8,-0x10(%ebp) +c01002d6: 75 16 jne c01002ee +c01002d8: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c01002dc: 7e 10 jle c01002ee + cputchar(c); +c01002de: 8b 45 f0 mov -0x10(%ebp),%eax +c01002e1: 89 04 24 mov %eax,(%esp) +c01002e4: e8 b7 00 00 00 call c01003a0 + i --; +c01002e9: ff 4d f4 decl -0xc(%ebp) +c01002ec: eb 29 jmp c0100317 + } + else if (c == '\n' || c == '\r') { +c01002ee: 83 7d f0 0a cmpl $0xa,-0x10(%ebp) +c01002f2: 74 06 je c01002fa +c01002f4: 83 7d f0 0d cmpl $0xd,-0x10(%ebp) +c01002f8: 75 95 jne c010028f + cputchar(c); +c01002fa: 8b 45 f0 mov -0x10(%ebp),%eax +c01002fd: 89 04 24 mov %eax,(%esp) +c0100300: e8 9b 00 00 00 call c01003a0 + buf[i] = '\0'; +c0100305: 8b 45 f4 mov -0xc(%ebp),%eax +c0100308: 05 20 30 1a c0 add $0xc01a3020,%eax +c010030d: c6 00 00 movb $0x0,(%eax) + return buf; +c0100310: b8 20 30 1a c0 mov $0xc01a3020,%eax +c0100315: eb 05 jmp c010031c + c = getchar(); +c0100317: e9 73 ff ff ff jmp c010028f + } + } +} +c010031c: 89 ec mov %ebp,%esp +c010031e: 5d pop %ebp +c010031f: c3 ret + +c0100320 : +/* * + * cputch - writes a single character @c to stdout, and it will + * increace the value of counter pointed by @cnt. + * */ +static void +cputch(int c, int *cnt) { +c0100320: 55 push %ebp +c0100321: 89 e5 mov %esp,%ebp +c0100323: 83 ec 18 sub $0x18,%esp + cons_putc(c); +c0100326: 8b 45 08 mov 0x8(%ebp),%eax +c0100329: 89 04 24 mov %eax,(%esp) +c010032c: e8 ab 13 00 00 call c01016dc + (*cnt) ++; +c0100331: 8b 45 0c mov 0xc(%ebp),%eax +c0100334: 8b 00 mov (%eax),%eax +c0100336: 8d 50 01 lea 0x1(%eax),%edx +c0100339: 8b 45 0c mov 0xc(%ebp),%eax +c010033c: 89 10 mov %edx,(%eax) +} +c010033e: 90 nop +c010033f: 89 ec mov %ebp,%esp +c0100341: 5d pop %ebp +c0100342: c3 ret + +c0100343 : + * + * Call this function if you are already dealing with a va_list. + * Or you probably want cprintf() instead. + * */ +int +vcprintf(const char *fmt, va_list ap) { +c0100343: 55 push %ebp +c0100344: 89 e5 mov %esp,%ebp +c0100346: 83 ec 28 sub $0x28,%esp + int cnt = 0; +c0100349: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + vprintfmt((void*)cputch, &cnt, fmt, ap); +c0100350: 8b 45 0c mov 0xc(%ebp),%eax +c0100353: 89 44 24 0c mov %eax,0xc(%esp) +c0100357: 8b 45 08 mov 0x8(%ebp),%eax +c010035a: 89 44 24 08 mov %eax,0x8(%esp) +c010035e: 8d 45 f4 lea -0xc(%ebp),%eax +c0100361: 89 44 24 04 mov %eax,0x4(%esp) +c0100365: c7 04 24 20 03 10 c0 movl $0xc0100320,(%esp) +c010036c: e8 d3 b1 00 00 call c010b544 + return cnt; +c0100371: 8b 45 f4 mov -0xc(%ebp),%eax +} +c0100374: 89 ec mov %ebp,%esp +c0100376: 5d pop %ebp +c0100377: c3 ret + +c0100378 : + * + * The return value is the number of characters which would be + * written to stdout. + * */ +int +cprintf(const char *fmt, ...) { +c0100378: 55 push %ebp +c0100379: 89 e5 mov %esp,%ebp +c010037b: 83 ec 28 sub $0x28,%esp + va_list ap; + int cnt; + va_start(ap, fmt); +c010037e: 8d 45 0c lea 0xc(%ebp),%eax +c0100381: 89 45 f0 mov %eax,-0x10(%ebp) + cnt = vcprintf(fmt, ap); +c0100384: 8b 45 f0 mov -0x10(%ebp),%eax +c0100387: 89 44 24 04 mov %eax,0x4(%esp) +c010038b: 8b 45 08 mov 0x8(%ebp),%eax +c010038e: 89 04 24 mov %eax,(%esp) +c0100391: e8 ad ff ff ff call c0100343 +c0100396: 89 45 f4 mov %eax,-0xc(%ebp) + va_end(ap); + return cnt; +c0100399: 8b 45 f4 mov -0xc(%ebp),%eax +} +c010039c: 89 ec mov %ebp,%esp +c010039e: 5d pop %ebp +c010039f: c3 ret + +c01003a0 : + +/* cputchar - writes a single character to stdout */ +void +cputchar(int c) { +c01003a0: 55 push %ebp +c01003a1: 89 e5 mov %esp,%ebp +c01003a3: 83 ec 18 sub $0x18,%esp + cons_putc(c); +c01003a6: 8b 45 08 mov 0x8(%ebp),%eax +c01003a9: 89 04 24 mov %eax,(%esp) +c01003ac: e8 2b 13 00 00 call c01016dc +} +c01003b1: 90 nop +c01003b2: 89 ec mov %ebp,%esp +c01003b4: 5d pop %ebp +c01003b5: c3 ret + +c01003b6 : +/* * + * cputs- writes the string pointed by @str to stdout and + * appends a newline character. + * */ +int +cputs(const char *str) { +c01003b6: 55 push %ebp +c01003b7: 89 e5 mov %esp,%ebp +c01003b9: 83 ec 28 sub $0x28,%esp + int cnt = 0; +c01003bc: c7 45 f0 00 00 00 00 movl $0x0,-0x10(%ebp) + char c; + while ((c = *str ++) != '\0') { +c01003c3: eb 13 jmp c01003d8 + cputch(c, &cnt); +c01003c5: 0f be 45 f7 movsbl -0x9(%ebp),%eax +c01003c9: 8d 55 f0 lea -0x10(%ebp),%edx +c01003cc: 89 54 24 04 mov %edx,0x4(%esp) +c01003d0: 89 04 24 mov %eax,(%esp) +c01003d3: e8 48 ff ff ff call c0100320 + while ((c = *str ++) != '\0') { +c01003d8: 8b 45 08 mov 0x8(%ebp),%eax +c01003db: 8d 50 01 lea 0x1(%eax),%edx +c01003de: 89 55 08 mov %edx,0x8(%ebp) +c01003e1: 0f b6 00 movzbl (%eax),%eax +c01003e4: 88 45 f7 mov %al,-0x9(%ebp) +c01003e7: 80 7d f7 00 cmpb $0x0,-0x9(%ebp) +c01003eb: 75 d8 jne c01003c5 + } + cputch('\n', &cnt); +c01003ed: 8d 45 f0 lea -0x10(%ebp),%eax +c01003f0: 89 44 24 04 mov %eax,0x4(%esp) +c01003f4: c7 04 24 0a 00 00 00 movl $0xa,(%esp) +c01003fb: e8 20 ff ff ff call c0100320 + return cnt; +c0100400: 8b 45 f0 mov -0x10(%ebp),%eax +} +c0100403: 89 ec mov %ebp,%esp +c0100405: 5d pop %ebp +c0100406: c3 ret + +c0100407 : + +/* getchar - reads a single non-zero character from stdin */ +int +getchar(void) { +c0100407: 55 push %ebp +c0100408: 89 e5 mov %esp,%ebp +c010040a: 83 ec 18 sub $0x18,%esp + int c; + while ((c = cons_getc()) == 0) +c010040d: 90 nop +c010040e: e8 08 13 00 00 call c010171b +c0100413: 89 45 f4 mov %eax,-0xc(%ebp) +c0100416: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c010041a: 74 f2 je c010040e + /* do nothing */; + return c; +c010041c: 8b 45 f4 mov -0xc(%ebp),%eax +} +c010041f: 89 ec mov %ebp,%esp +c0100421: 5d pop %ebp +c0100422: c3 ret + +c0100423 : + * stab_binsearch(stabs, &left, &right, N_SO, 0xf0100184); + * will exit setting left = 118, right = 554. + * */ +static void +stab_binsearch(const struct stab *stabs, int *region_left, int *region_right, + int type, uintptr_t addr) { +c0100423: 55 push %ebp +c0100424: 89 e5 mov %esp,%ebp +c0100426: 83 ec 20 sub $0x20,%esp + int l = *region_left, r = *region_right, any_matches = 0; +c0100429: 8b 45 0c mov 0xc(%ebp),%eax +c010042c: 8b 00 mov (%eax),%eax +c010042e: 89 45 fc mov %eax,-0x4(%ebp) +c0100431: 8b 45 10 mov 0x10(%ebp),%eax +c0100434: 8b 00 mov (%eax),%eax +c0100436: 89 45 f8 mov %eax,-0x8(%ebp) +c0100439: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + + while (l <= r) { +c0100440: e9 ca 00 00 00 jmp c010050f + int true_m = (l + r) / 2, m = true_m; +c0100445: 8b 55 fc mov -0x4(%ebp),%edx +c0100448: 8b 45 f8 mov -0x8(%ebp),%eax +c010044b: 01 d0 add %edx,%eax +c010044d: 89 c2 mov %eax,%edx +c010044f: c1 ea 1f shr $0x1f,%edx +c0100452: 01 d0 add %edx,%eax +c0100454: d1 f8 sar %eax +c0100456: 89 45 ec mov %eax,-0x14(%ebp) +c0100459: 8b 45 ec mov -0x14(%ebp),%eax +c010045c: 89 45 f0 mov %eax,-0x10(%ebp) + + // search for earliest stab with right type + while (m >= l && stabs[m].n_type != type) { +c010045f: eb 03 jmp c0100464 + m --; +c0100461: ff 4d f0 decl -0x10(%ebp) + while (m >= l && stabs[m].n_type != type) { +c0100464: 8b 45 f0 mov -0x10(%ebp),%eax +c0100467: 3b 45 fc cmp -0x4(%ebp),%eax +c010046a: 7c 1f jl c010048b +c010046c: 8b 55 f0 mov -0x10(%ebp),%edx +c010046f: 89 d0 mov %edx,%eax +c0100471: 01 c0 add %eax,%eax +c0100473: 01 d0 add %edx,%eax +c0100475: c1 e0 02 shl $0x2,%eax +c0100478: 89 c2 mov %eax,%edx +c010047a: 8b 45 08 mov 0x8(%ebp),%eax +c010047d: 01 d0 add %edx,%eax +c010047f: 0f b6 40 04 movzbl 0x4(%eax),%eax +c0100483: 0f b6 c0 movzbl %al,%eax +c0100486: 39 45 14 cmp %eax,0x14(%ebp) +c0100489: 75 d6 jne c0100461 + } + if (m < l) { // no match in [l, m] +c010048b: 8b 45 f0 mov -0x10(%ebp),%eax +c010048e: 3b 45 fc cmp -0x4(%ebp),%eax +c0100491: 7d 09 jge c010049c + l = true_m + 1; +c0100493: 8b 45 ec mov -0x14(%ebp),%eax +c0100496: 40 inc %eax +c0100497: 89 45 fc mov %eax,-0x4(%ebp) + continue; +c010049a: eb 73 jmp c010050f + } + + // actual binary search + any_matches = 1; +c010049c: c7 45 f4 01 00 00 00 movl $0x1,-0xc(%ebp) + if (stabs[m].n_value < addr) { +c01004a3: 8b 55 f0 mov -0x10(%ebp),%edx +c01004a6: 89 d0 mov %edx,%eax +c01004a8: 01 c0 add %eax,%eax +c01004aa: 01 d0 add %edx,%eax +c01004ac: c1 e0 02 shl $0x2,%eax +c01004af: 89 c2 mov %eax,%edx +c01004b1: 8b 45 08 mov 0x8(%ebp),%eax +c01004b4: 01 d0 add %edx,%eax +c01004b6: 8b 40 08 mov 0x8(%eax),%eax +c01004b9: 39 45 18 cmp %eax,0x18(%ebp) +c01004bc: 76 11 jbe c01004cf + *region_left = m; +c01004be: 8b 45 0c mov 0xc(%ebp),%eax +c01004c1: 8b 55 f0 mov -0x10(%ebp),%edx +c01004c4: 89 10 mov %edx,(%eax) + l = true_m + 1; +c01004c6: 8b 45 ec mov -0x14(%ebp),%eax +c01004c9: 40 inc %eax +c01004ca: 89 45 fc mov %eax,-0x4(%ebp) +c01004cd: eb 40 jmp c010050f + } else if (stabs[m].n_value > addr) { +c01004cf: 8b 55 f0 mov -0x10(%ebp),%edx +c01004d2: 89 d0 mov %edx,%eax +c01004d4: 01 c0 add %eax,%eax +c01004d6: 01 d0 add %edx,%eax +c01004d8: c1 e0 02 shl $0x2,%eax +c01004db: 89 c2 mov %eax,%edx +c01004dd: 8b 45 08 mov 0x8(%ebp),%eax +c01004e0: 01 d0 add %edx,%eax +c01004e2: 8b 40 08 mov 0x8(%eax),%eax +c01004e5: 39 45 18 cmp %eax,0x18(%ebp) +c01004e8: 73 14 jae c01004fe + *region_right = m - 1; +c01004ea: 8b 45 f0 mov -0x10(%ebp),%eax +c01004ed: 8d 50 ff lea -0x1(%eax),%edx +c01004f0: 8b 45 10 mov 0x10(%ebp),%eax +c01004f3: 89 10 mov %edx,(%eax) + r = m - 1; +c01004f5: 8b 45 f0 mov -0x10(%ebp),%eax +c01004f8: 48 dec %eax +c01004f9: 89 45 f8 mov %eax,-0x8(%ebp) +c01004fc: eb 11 jmp c010050f + } else { + // exact match for 'addr', but continue loop to find + // *region_right + *region_left = m; +c01004fe: 8b 45 0c mov 0xc(%ebp),%eax +c0100501: 8b 55 f0 mov -0x10(%ebp),%edx +c0100504: 89 10 mov %edx,(%eax) + l = m; +c0100506: 8b 45 f0 mov -0x10(%ebp),%eax +c0100509: 89 45 fc mov %eax,-0x4(%ebp) + addr ++; +c010050c: ff 45 18 incl 0x18(%ebp) + while (l <= r) { +c010050f: 8b 45 fc mov -0x4(%ebp),%eax +c0100512: 3b 45 f8 cmp -0x8(%ebp),%eax +c0100515: 0f 8e 2a ff ff ff jle c0100445 + } + } + + if (!any_matches) { +c010051b: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c010051f: 75 0f jne c0100530 + *region_right = *region_left - 1; +c0100521: 8b 45 0c mov 0xc(%ebp),%eax +c0100524: 8b 00 mov (%eax),%eax +c0100526: 8d 50 ff lea -0x1(%eax),%edx +c0100529: 8b 45 10 mov 0x10(%ebp),%eax +c010052c: 89 10 mov %edx,(%eax) + l = *region_right; + for (; l > *region_left && stabs[l].n_type != type; l --) + /* do nothing */; + *region_left = l; + } +} +c010052e: eb 3e jmp c010056e + l = *region_right; +c0100530: 8b 45 10 mov 0x10(%ebp),%eax +c0100533: 8b 00 mov (%eax),%eax +c0100535: 89 45 fc mov %eax,-0x4(%ebp) + for (; l > *region_left && stabs[l].n_type != type; l --) +c0100538: eb 03 jmp c010053d +c010053a: ff 4d fc decl -0x4(%ebp) +c010053d: 8b 45 0c mov 0xc(%ebp),%eax +c0100540: 8b 00 mov (%eax),%eax +c0100542: 39 45 fc cmp %eax,-0x4(%ebp) +c0100545: 7e 1f jle c0100566 +c0100547: 8b 55 fc mov -0x4(%ebp),%edx +c010054a: 89 d0 mov %edx,%eax +c010054c: 01 c0 add %eax,%eax +c010054e: 01 d0 add %edx,%eax +c0100550: c1 e0 02 shl $0x2,%eax +c0100553: 89 c2 mov %eax,%edx +c0100555: 8b 45 08 mov 0x8(%ebp),%eax +c0100558: 01 d0 add %edx,%eax +c010055a: 0f b6 40 04 movzbl 0x4(%eax),%eax +c010055e: 0f b6 c0 movzbl %al,%eax +c0100561: 39 45 14 cmp %eax,0x14(%ebp) +c0100564: 75 d4 jne c010053a + *region_left = l; +c0100566: 8b 45 0c mov 0xc(%ebp),%eax +c0100569: 8b 55 fc mov -0x4(%ebp),%edx +c010056c: 89 10 mov %edx,(%eax) +} +c010056e: 90 nop +c010056f: 89 ec mov %ebp,%esp +c0100571: 5d pop %ebp +c0100572: c3 ret + +c0100573 : + * the specified instruction address, @addr. Returns 0 if information + * was found, and negative if not. But even if it returns negative it + * has stored some information into '*info'. + * */ +int +debuginfo_eip(uintptr_t addr, struct eipdebuginfo *info) { +c0100573: 55 push %ebp +c0100574: 89 e5 mov %esp,%ebp +c0100576: 83 ec 58 sub $0x58,%esp + const struct stab *stabs, *stab_end; + const char *stabstr, *stabstr_end; + + info->eip_file = ""; +c0100579: 8b 45 0c mov 0xc(%ebp),%eax +c010057c: c7 00 2c c0 10 c0 movl $0xc010c02c,(%eax) + info->eip_line = 0; +c0100582: 8b 45 0c mov 0xc(%ebp),%eax +c0100585: c7 40 04 00 00 00 00 movl $0x0,0x4(%eax) + info->eip_fn_name = ""; +c010058c: 8b 45 0c mov 0xc(%ebp),%eax +c010058f: c7 40 08 2c c0 10 c0 movl $0xc010c02c,0x8(%eax) + info->eip_fn_namelen = 9; +c0100596: 8b 45 0c mov 0xc(%ebp),%eax +c0100599: c7 40 0c 09 00 00 00 movl $0x9,0xc(%eax) + info->eip_fn_addr = addr; +c01005a0: 8b 45 0c mov 0xc(%ebp),%eax +c01005a3: 8b 55 08 mov 0x8(%ebp),%edx +c01005a6: 89 50 10 mov %edx,0x10(%eax) + info->eip_fn_narg = 0; +c01005a9: 8b 45 0c mov 0xc(%ebp),%eax +c01005ac: c7 40 14 00 00 00 00 movl $0x0,0x14(%eax) + + // find the relevant set of stabs + if (addr >= KERNBASE) { +c01005b3: 81 7d 08 ff ff ff bf cmpl $0xbfffffff,0x8(%ebp) +c01005ba: 76 21 jbe c01005dd + stabs = __STAB_BEGIN__; +c01005bc: c7 45 f4 e0 e7 10 c0 movl $0xc010e7e0,-0xc(%ebp) + stab_end = __STAB_END__; +c01005c3: c7 45 f0 5c 4c 12 c0 movl $0xc0124c5c,-0x10(%ebp) + stabstr = __STABSTR_BEGIN__; +c01005ca: c7 45 ec 5d 4c 12 c0 movl $0xc0124c5d,-0x14(%ebp) + stabstr_end = __STABSTR_END__; +c01005d1: c7 45 e8 8d c9 12 c0 movl $0xc012c98d,-0x18(%ebp) +c01005d8: e9 e8 00 00 00 jmp c01006c5 + } + else { + // user-program linker script, tools/user.ld puts the information about the + // program's stabs (included __STAB_BEGIN__, __STAB_END__, __STABSTR_BEGIN__, + // and __STABSTR_END__) in a structure located at virtual address USTAB. + const struct userstabdata *usd = (struct userstabdata *)USTAB; +c01005dd: c7 45 e4 00 00 20 00 movl $0x200000,-0x1c(%ebp) + + // make sure that debugger (current process) can access this memory + struct mm_struct *mm; + if (current == NULL || (mm = current->mm) == NULL) { +c01005e4: a1 30 41 1a c0 mov 0xc01a4130,%eax +c01005e9: 85 c0 test %eax,%eax +c01005eb: 74 11 je c01005fe +c01005ed: a1 30 41 1a c0 mov 0xc01a4130,%eax +c01005f2: 8b 40 18 mov 0x18(%eax),%eax +c01005f5: 89 45 e0 mov %eax,-0x20(%ebp) +c01005f8: 83 7d e0 00 cmpl $0x0,-0x20(%ebp) +c01005fc: 75 0a jne c0100608 + return -1; +c01005fe: b8 ff ff ff ff mov $0xffffffff,%eax +c0100603: e9 85 03 00 00 jmp c010098d + } + if (!user_mem_check(mm, (uintptr_t)usd, sizeof(struct userstabdata), 0)) { +c0100608: 8b 45 e4 mov -0x1c(%ebp),%eax +c010060b: c7 44 24 0c 00 00 00 movl $0x0,0xc(%esp) +c0100612: 00 +c0100613: c7 44 24 08 10 00 00 movl $0x10,0x8(%esp) +c010061a: 00 +c010061b: 89 44 24 04 mov %eax,0x4(%esp) +c010061f: 8b 45 e0 mov -0x20(%ebp),%eax +c0100622: 89 04 24 mov %eax,(%esp) +c0100625: e8 30 8a 00 00 call c010905a +c010062a: 85 c0 test %eax,%eax +c010062c: 75 0a jne c0100638 + return -1; +c010062e: b8 ff ff ff ff mov $0xffffffff,%eax +c0100633: e9 55 03 00 00 jmp c010098d + } + + stabs = usd->stabs; +c0100638: 8b 45 e4 mov -0x1c(%ebp),%eax +c010063b: 8b 00 mov (%eax),%eax +c010063d: 89 45 f4 mov %eax,-0xc(%ebp) + stab_end = usd->stab_end; +c0100640: 8b 45 e4 mov -0x1c(%ebp),%eax +c0100643: 8b 40 04 mov 0x4(%eax),%eax +c0100646: 89 45 f0 mov %eax,-0x10(%ebp) + stabstr = usd->stabstr; +c0100649: 8b 45 e4 mov -0x1c(%ebp),%eax +c010064c: 8b 40 08 mov 0x8(%eax),%eax +c010064f: 89 45 ec mov %eax,-0x14(%ebp) + stabstr_end = usd->stabstr_end; +c0100652: 8b 45 e4 mov -0x1c(%ebp),%eax +c0100655: 8b 40 0c mov 0xc(%eax),%eax +c0100658: 89 45 e8 mov %eax,-0x18(%ebp) + + // make sure the STABS and string table memory is valid + if (!user_mem_check(mm, (uintptr_t)stabs, (uintptr_t)stab_end - (uintptr_t)stabs, 0)) { +c010065b: 8b 45 f0 mov -0x10(%ebp),%eax +c010065e: 8b 4d f4 mov -0xc(%ebp),%ecx +c0100661: 29 c8 sub %ecx,%eax +c0100663: 89 c2 mov %eax,%edx +c0100665: 8b 45 f4 mov -0xc(%ebp),%eax +c0100668: c7 44 24 0c 00 00 00 movl $0x0,0xc(%esp) +c010066f: 00 +c0100670: 89 54 24 08 mov %edx,0x8(%esp) +c0100674: 89 44 24 04 mov %eax,0x4(%esp) +c0100678: 8b 45 e0 mov -0x20(%ebp),%eax +c010067b: 89 04 24 mov %eax,(%esp) +c010067e: e8 d7 89 00 00 call c010905a +c0100683: 85 c0 test %eax,%eax +c0100685: 75 0a jne c0100691 + return -1; +c0100687: b8 ff ff ff ff mov $0xffffffff,%eax +c010068c: e9 fc 02 00 00 jmp c010098d + } + if (!user_mem_check(mm, (uintptr_t)stabstr, stabstr_end - stabstr, 0)) { +c0100691: 8b 45 e8 mov -0x18(%ebp),%eax +c0100694: 2b 45 ec sub -0x14(%ebp),%eax +c0100697: 89 c2 mov %eax,%edx +c0100699: 8b 45 ec mov -0x14(%ebp),%eax +c010069c: c7 44 24 0c 00 00 00 movl $0x0,0xc(%esp) +c01006a3: 00 +c01006a4: 89 54 24 08 mov %edx,0x8(%esp) +c01006a8: 89 44 24 04 mov %eax,0x4(%esp) +c01006ac: 8b 45 e0 mov -0x20(%ebp),%eax +c01006af: 89 04 24 mov %eax,(%esp) +c01006b2: e8 a3 89 00 00 call c010905a +c01006b7: 85 c0 test %eax,%eax +c01006b9: 75 0a jne c01006c5 + return -1; +c01006bb: b8 ff ff ff ff mov $0xffffffff,%eax +c01006c0: e9 c8 02 00 00 jmp c010098d + } + } + + // String table validity checks + if (stabstr_end <= stabstr || stabstr_end[-1] != 0) { +c01006c5: 8b 45 e8 mov -0x18(%ebp),%eax +c01006c8: 3b 45 ec cmp -0x14(%ebp),%eax +c01006cb: 76 0b jbe c01006d8 +c01006cd: 8b 45 e8 mov -0x18(%ebp),%eax +c01006d0: 48 dec %eax +c01006d1: 0f b6 00 movzbl (%eax),%eax +c01006d4: 84 c0 test %al,%al +c01006d6: 74 0a je c01006e2 + return -1; +c01006d8: b8 ff ff ff ff mov $0xffffffff,%eax +c01006dd: e9 ab 02 00 00 jmp c010098d + // 'eip'. First, we find the basic source file containing 'eip'. + // Then, we look in that source file for the function. Then we look + // for the line number. + + // Search the entire set of stabs for the source file (type N_SO). + int lfile = 0, rfile = (stab_end - stabs) - 1; +c01006e2: c7 45 dc 00 00 00 00 movl $0x0,-0x24(%ebp) +c01006e9: 8b 45 f0 mov -0x10(%ebp),%eax +c01006ec: 2b 45 f4 sub -0xc(%ebp),%eax +c01006ef: c1 f8 02 sar $0x2,%eax +c01006f2: 69 c0 ab aa aa aa imul $0xaaaaaaab,%eax,%eax +c01006f8: 48 dec %eax +c01006f9: 89 45 d8 mov %eax,-0x28(%ebp) + stab_binsearch(stabs, &lfile, &rfile, N_SO, addr); +c01006fc: 8b 45 08 mov 0x8(%ebp),%eax +c01006ff: 89 44 24 10 mov %eax,0x10(%esp) +c0100703: c7 44 24 0c 64 00 00 movl $0x64,0xc(%esp) +c010070a: 00 +c010070b: 8d 45 d8 lea -0x28(%ebp),%eax +c010070e: 89 44 24 08 mov %eax,0x8(%esp) +c0100712: 8d 45 dc lea -0x24(%ebp),%eax +c0100715: 89 44 24 04 mov %eax,0x4(%esp) +c0100719: 8b 45 f4 mov -0xc(%ebp),%eax +c010071c: 89 04 24 mov %eax,(%esp) +c010071f: e8 ff fc ff ff call c0100423 + if (lfile == 0) +c0100724: 8b 45 dc mov -0x24(%ebp),%eax +c0100727: 85 c0 test %eax,%eax +c0100729: 75 0a jne c0100735 + return -1; +c010072b: b8 ff ff ff ff mov $0xffffffff,%eax +c0100730: e9 58 02 00 00 jmp c010098d + + // Search within that file's stabs for the function definition + // (N_FUN). + int lfun = lfile, rfun = rfile; +c0100735: 8b 45 dc mov -0x24(%ebp),%eax +c0100738: 89 45 d4 mov %eax,-0x2c(%ebp) +c010073b: 8b 45 d8 mov -0x28(%ebp),%eax +c010073e: 89 45 d0 mov %eax,-0x30(%ebp) + int lline, rline; + stab_binsearch(stabs, &lfun, &rfun, N_FUN, addr); +c0100741: 8b 45 08 mov 0x8(%ebp),%eax +c0100744: 89 44 24 10 mov %eax,0x10(%esp) +c0100748: c7 44 24 0c 24 00 00 movl $0x24,0xc(%esp) +c010074f: 00 +c0100750: 8d 45 d0 lea -0x30(%ebp),%eax +c0100753: 89 44 24 08 mov %eax,0x8(%esp) +c0100757: 8d 45 d4 lea -0x2c(%ebp),%eax +c010075a: 89 44 24 04 mov %eax,0x4(%esp) +c010075e: 8b 45 f4 mov -0xc(%ebp),%eax +c0100761: 89 04 24 mov %eax,(%esp) +c0100764: e8 ba fc ff ff call c0100423 + + if (lfun <= rfun) { +c0100769: 8b 55 d4 mov -0x2c(%ebp),%edx +c010076c: 8b 45 d0 mov -0x30(%ebp),%eax +c010076f: 39 c2 cmp %eax,%edx +c0100771: 7f 78 jg c01007eb + // stabs[lfun] points to the function name + // in the string table, but check bounds just in case. + if (stabs[lfun].n_strx < stabstr_end - stabstr) { +c0100773: 8b 45 d4 mov -0x2c(%ebp),%eax +c0100776: 89 c2 mov %eax,%edx +c0100778: 89 d0 mov %edx,%eax +c010077a: 01 c0 add %eax,%eax +c010077c: 01 d0 add %edx,%eax +c010077e: c1 e0 02 shl $0x2,%eax +c0100781: 89 c2 mov %eax,%edx +c0100783: 8b 45 f4 mov -0xc(%ebp),%eax +c0100786: 01 d0 add %edx,%eax +c0100788: 8b 10 mov (%eax),%edx +c010078a: 8b 45 e8 mov -0x18(%ebp),%eax +c010078d: 2b 45 ec sub -0x14(%ebp),%eax +c0100790: 39 c2 cmp %eax,%edx +c0100792: 73 22 jae c01007b6 + info->eip_fn_name = stabstr + stabs[lfun].n_strx; +c0100794: 8b 45 d4 mov -0x2c(%ebp),%eax +c0100797: 89 c2 mov %eax,%edx +c0100799: 89 d0 mov %edx,%eax +c010079b: 01 c0 add %eax,%eax +c010079d: 01 d0 add %edx,%eax +c010079f: c1 e0 02 shl $0x2,%eax +c01007a2: 89 c2 mov %eax,%edx +c01007a4: 8b 45 f4 mov -0xc(%ebp),%eax +c01007a7: 01 d0 add %edx,%eax +c01007a9: 8b 10 mov (%eax),%edx +c01007ab: 8b 45 ec mov -0x14(%ebp),%eax +c01007ae: 01 c2 add %eax,%edx +c01007b0: 8b 45 0c mov 0xc(%ebp),%eax +c01007b3: 89 50 08 mov %edx,0x8(%eax) + } + info->eip_fn_addr = stabs[lfun].n_value; +c01007b6: 8b 45 d4 mov -0x2c(%ebp),%eax +c01007b9: 89 c2 mov %eax,%edx +c01007bb: 89 d0 mov %edx,%eax +c01007bd: 01 c0 add %eax,%eax +c01007bf: 01 d0 add %edx,%eax +c01007c1: c1 e0 02 shl $0x2,%eax +c01007c4: 89 c2 mov %eax,%edx +c01007c6: 8b 45 f4 mov -0xc(%ebp),%eax +c01007c9: 01 d0 add %edx,%eax +c01007cb: 8b 50 08 mov 0x8(%eax),%edx +c01007ce: 8b 45 0c mov 0xc(%ebp),%eax +c01007d1: 89 50 10 mov %edx,0x10(%eax) + addr -= info->eip_fn_addr; +c01007d4: 8b 45 0c mov 0xc(%ebp),%eax +c01007d7: 8b 40 10 mov 0x10(%eax),%eax +c01007da: 29 45 08 sub %eax,0x8(%ebp) + // Search within the function definition for the line number. + lline = lfun; +c01007dd: 8b 45 d4 mov -0x2c(%ebp),%eax +c01007e0: 89 45 cc mov %eax,-0x34(%ebp) + rline = rfun; +c01007e3: 8b 45 d0 mov -0x30(%ebp),%eax +c01007e6: 89 45 c8 mov %eax,-0x38(%ebp) +c01007e9: eb 15 jmp c0100800 + } else { + // Couldn't find function stab! Maybe we're in an assembly + // file. Search the whole file for the line number. + info->eip_fn_addr = addr; +c01007eb: 8b 45 0c mov 0xc(%ebp),%eax +c01007ee: 8b 55 08 mov 0x8(%ebp),%edx +c01007f1: 89 50 10 mov %edx,0x10(%eax) + lline = lfile; +c01007f4: 8b 45 dc mov -0x24(%ebp),%eax +c01007f7: 89 45 cc mov %eax,-0x34(%ebp) + rline = rfile; +c01007fa: 8b 45 d8 mov -0x28(%ebp),%eax +c01007fd: 89 45 c8 mov %eax,-0x38(%ebp) + } + info->eip_fn_namelen = strfind(info->eip_fn_name, ':') - info->eip_fn_name; +c0100800: 8b 45 0c mov 0xc(%ebp),%eax +c0100803: 8b 40 08 mov 0x8(%eax),%eax +c0100806: c7 44 24 04 3a 00 00 movl $0x3a,0x4(%esp) +c010080d: 00 +c010080e: 89 04 24 mov %eax,(%esp) +c0100811: e8 53 b4 00 00 call c010bc69 +c0100816: 8b 55 0c mov 0xc(%ebp),%edx +c0100819: 8b 4a 08 mov 0x8(%edx),%ecx +c010081c: 29 c8 sub %ecx,%eax +c010081e: 89 c2 mov %eax,%edx +c0100820: 8b 45 0c mov 0xc(%ebp),%eax +c0100823: 89 50 0c mov %edx,0xc(%eax) + + // Search within [lline, rline] for the line number stab. + // If found, set info->eip_line to the right line number. + // If not found, return -1. + stab_binsearch(stabs, &lline, &rline, N_SLINE, addr); +c0100826: 8b 45 08 mov 0x8(%ebp),%eax +c0100829: 89 44 24 10 mov %eax,0x10(%esp) +c010082d: c7 44 24 0c 44 00 00 movl $0x44,0xc(%esp) +c0100834: 00 +c0100835: 8d 45 c8 lea -0x38(%ebp),%eax +c0100838: 89 44 24 08 mov %eax,0x8(%esp) +c010083c: 8d 45 cc lea -0x34(%ebp),%eax +c010083f: 89 44 24 04 mov %eax,0x4(%esp) +c0100843: 8b 45 f4 mov -0xc(%ebp),%eax +c0100846: 89 04 24 mov %eax,(%esp) +c0100849: e8 d5 fb ff ff call c0100423 + if (lline <= rline) { +c010084e: 8b 55 cc mov -0x34(%ebp),%edx +c0100851: 8b 45 c8 mov -0x38(%ebp),%eax +c0100854: 39 c2 cmp %eax,%edx +c0100856: 7f 23 jg c010087b + info->eip_line = stabs[rline].n_desc; +c0100858: 8b 45 c8 mov -0x38(%ebp),%eax +c010085b: 89 c2 mov %eax,%edx +c010085d: 89 d0 mov %edx,%eax +c010085f: 01 c0 add %eax,%eax +c0100861: 01 d0 add %edx,%eax +c0100863: c1 e0 02 shl $0x2,%eax +c0100866: 89 c2 mov %eax,%edx +c0100868: 8b 45 f4 mov -0xc(%ebp),%eax +c010086b: 01 d0 add %edx,%eax +c010086d: 0f b7 40 06 movzwl 0x6(%eax),%eax +c0100871: 89 c2 mov %eax,%edx +c0100873: 8b 45 0c mov 0xc(%ebp),%eax +c0100876: 89 50 04 mov %edx,0x4(%eax) + + // Search backwards from the line number for the relevant filename stab. + // We can't just use the "lfile" stab because inlined functions + // can interpolate code from a different file! + // Such included source files use the N_SOL stab type. + while (lline >= lfile +c0100879: eb 11 jmp c010088c + return -1; +c010087b: b8 ff ff ff ff mov $0xffffffff,%eax +c0100880: e9 08 01 00 00 jmp c010098d + && stabs[lline].n_type != N_SOL + && (stabs[lline].n_type != N_SO || !stabs[lline].n_value)) { + lline --; +c0100885: 8b 45 cc mov -0x34(%ebp),%eax +c0100888: 48 dec %eax +c0100889: 89 45 cc mov %eax,-0x34(%ebp) + while (lline >= lfile +c010088c: 8b 55 cc mov -0x34(%ebp),%edx +c010088f: 8b 45 dc mov -0x24(%ebp),%eax + && (stabs[lline].n_type != N_SO || !stabs[lline].n_value)) { +c0100892: 39 c2 cmp %eax,%edx +c0100894: 7c 56 jl c01008ec + && stabs[lline].n_type != N_SOL +c0100896: 8b 45 cc mov -0x34(%ebp),%eax +c0100899: 89 c2 mov %eax,%edx +c010089b: 89 d0 mov %edx,%eax +c010089d: 01 c0 add %eax,%eax +c010089f: 01 d0 add %edx,%eax +c01008a1: c1 e0 02 shl $0x2,%eax +c01008a4: 89 c2 mov %eax,%edx +c01008a6: 8b 45 f4 mov -0xc(%ebp),%eax +c01008a9: 01 d0 add %edx,%eax +c01008ab: 0f b6 40 04 movzbl 0x4(%eax),%eax +c01008af: 3c 84 cmp $0x84,%al +c01008b1: 74 39 je c01008ec + && (stabs[lline].n_type != N_SO || !stabs[lline].n_value)) { +c01008b3: 8b 45 cc mov -0x34(%ebp),%eax +c01008b6: 89 c2 mov %eax,%edx +c01008b8: 89 d0 mov %edx,%eax +c01008ba: 01 c0 add %eax,%eax +c01008bc: 01 d0 add %edx,%eax +c01008be: c1 e0 02 shl $0x2,%eax +c01008c1: 89 c2 mov %eax,%edx +c01008c3: 8b 45 f4 mov -0xc(%ebp),%eax +c01008c6: 01 d0 add %edx,%eax +c01008c8: 0f b6 40 04 movzbl 0x4(%eax),%eax +c01008cc: 3c 64 cmp $0x64,%al +c01008ce: 75 b5 jne c0100885 +c01008d0: 8b 45 cc mov -0x34(%ebp),%eax +c01008d3: 89 c2 mov %eax,%edx +c01008d5: 89 d0 mov %edx,%eax +c01008d7: 01 c0 add %eax,%eax +c01008d9: 01 d0 add %edx,%eax +c01008db: c1 e0 02 shl $0x2,%eax +c01008de: 89 c2 mov %eax,%edx +c01008e0: 8b 45 f4 mov -0xc(%ebp),%eax +c01008e3: 01 d0 add %edx,%eax +c01008e5: 8b 40 08 mov 0x8(%eax),%eax +c01008e8: 85 c0 test %eax,%eax +c01008ea: 74 99 je c0100885 + } + if (lline >= lfile && stabs[lline].n_strx < stabstr_end - stabstr) { +c01008ec: 8b 55 cc mov -0x34(%ebp),%edx +c01008ef: 8b 45 dc mov -0x24(%ebp),%eax +c01008f2: 39 c2 cmp %eax,%edx +c01008f4: 7c 42 jl c0100938 +c01008f6: 8b 45 cc mov -0x34(%ebp),%eax +c01008f9: 89 c2 mov %eax,%edx +c01008fb: 89 d0 mov %edx,%eax +c01008fd: 01 c0 add %eax,%eax +c01008ff: 01 d0 add %edx,%eax +c0100901: c1 e0 02 shl $0x2,%eax +c0100904: 89 c2 mov %eax,%edx +c0100906: 8b 45 f4 mov -0xc(%ebp),%eax +c0100909: 01 d0 add %edx,%eax +c010090b: 8b 10 mov (%eax),%edx +c010090d: 8b 45 e8 mov -0x18(%ebp),%eax +c0100910: 2b 45 ec sub -0x14(%ebp),%eax +c0100913: 39 c2 cmp %eax,%edx +c0100915: 73 21 jae c0100938 + info->eip_file = stabstr + stabs[lline].n_strx; +c0100917: 8b 45 cc mov -0x34(%ebp),%eax +c010091a: 89 c2 mov %eax,%edx +c010091c: 89 d0 mov %edx,%eax +c010091e: 01 c0 add %eax,%eax +c0100920: 01 d0 add %edx,%eax +c0100922: c1 e0 02 shl $0x2,%eax +c0100925: 89 c2 mov %eax,%edx +c0100927: 8b 45 f4 mov -0xc(%ebp),%eax +c010092a: 01 d0 add %edx,%eax +c010092c: 8b 10 mov (%eax),%edx +c010092e: 8b 45 ec mov -0x14(%ebp),%eax +c0100931: 01 c2 add %eax,%edx +c0100933: 8b 45 0c mov 0xc(%ebp),%eax +c0100936: 89 10 mov %edx,(%eax) + } + + // Set eip_fn_narg to the number of arguments taken by the function, + // or 0 if there was no containing function. + if (lfun < rfun) { +c0100938: 8b 55 d4 mov -0x2c(%ebp),%edx +c010093b: 8b 45 d0 mov -0x30(%ebp),%eax +c010093e: 39 c2 cmp %eax,%edx +c0100940: 7d 46 jge c0100988 + for (lline = lfun + 1; +c0100942: 8b 45 d4 mov -0x2c(%ebp),%eax +c0100945: 40 inc %eax +c0100946: 89 45 cc mov %eax,-0x34(%ebp) +c0100949: eb 16 jmp c0100961 + lline < rfun && stabs[lline].n_type == N_PSYM; + lline ++) { + info->eip_fn_narg ++; +c010094b: 8b 45 0c mov 0xc(%ebp),%eax +c010094e: 8b 40 14 mov 0x14(%eax),%eax +c0100951: 8d 50 01 lea 0x1(%eax),%edx +c0100954: 8b 45 0c mov 0xc(%ebp),%eax +c0100957: 89 50 14 mov %edx,0x14(%eax) + lline ++) { +c010095a: 8b 45 cc mov -0x34(%ebp),%eax +c010095d: 40 inc %eax +c010095e: 89 45 cc mov %eax,-0x34(%ebp) + lline < rfun && stabs[lline].n_type == N_PSYM; +c0100961: 8b 55 cc mov -0x34(%ebp),%edx +c0100964: 8b 45 d0 mov -0x30(%ebp),%eax +c0100967: 39 c2 cmp %eax,%edx +c0100969: 7d 1d jge c0100988 +c010096b: 8b 45 cc mov -0x34(%ebp),%eax +c010096e: 89 c2 mov %eax,%edx +c0100970: 89 d0 mov %edx,%eax +c0100972: 01 c0 add %eax,%eax +c0100974: 01 d0 add %edx,%eax +c0100976: c1 e0 02 shl $0x2,%eax +c0100979: 89 c2 mov %eax,%edx +c010097b: 8b 45 f4 mov -0xc(%ebp),%eax +c010097e: 01 d0 add %edx,%eax +c0100980: 0f b6 40 04 movzbl 0x4(%eax),%eax +c0100984: 3c a0 cmp $0xa0,%al +c0100986: 74 c3 je c010094b + } + } + return 0; +c0100988: b8 00 00 00 00 mov $0x0,%eax +} +c010098d: 89 ec mov %ebp,%esp +c010098f: 5d pop %ebp +c0100990: c3 ret + +c0100991 : + * print_kerninfo - print the information about kernel, including the location + * of kernel entry, the start addresses of data and text segements, the start + * address of free memory and how many memory that kernel has used. + * */ +void +print_kerninfo(void) { +c0100991: 55 push %ebp +c0100992: 89 e5 mov %esp,%ebp +c0100994: 83 ec 18 sub $0x18,%esp + extern char etext[], edata[], end[], kern_init[]; + cprintf("Special kernel symbols:\n"); +c0100997: c7 04 24 36 c0 10 c0 movl $0xc010c036,(%esp) +c010099e: e8 d5 f9 ff ff call c0100378 + cprintf(" entry 0x%08x (phys)\n", kern_init); +c01009a3: c7 44 24 04 36 00 10 movl $0xc0100036,0x4(%esp) +c01009aa: c0 +c01009ab: c7 04 24 4f c0 10 c0 movl $0xc010c04f,(%esp) +c01009b2: e8 c1 f9 ff ff call c0100378 + cprintf(" etext 0x%08x (phys)\n", etext); +c01009b7: c7 44 24 04 7d bf 10 movl $0xc010bf7d,0x4(%esp) +c01009be: c0 +c01009bf: c7 04 24 67 c0 10 c0 movl $0xc010c067,(%esp) +c01009c6: e8 ad f9 ff ff call c0100378 + cprintf(" edata 0x%08x (phys)\n", edata); +c01009cb: c7 44 24 04 00 30 1a movl $0xc01a3000,0x4(%esp) +c01009d2: c0 +c01009d3: c7 04 24 7f c0 10 c0 movl $0xc010c07f,(%esp) +c01009da: e8 99 f9 ff ff call c0100378 + cprintf(" end 0x%08x (phys)\n", end); +c01009df: c7 44 24 04 54 61 1a movl $0xc01a6154,0x4(%esp) +c01009e6: c0 +c01009e7: c7 04 24 97 c0 10 c0 movl $0xc010c097,(%esp) +c01009ee: e8 85 f9 ff ff call c0100378 + cprintf("Kernel executable memory footprint: %dKB\n", (end - kern_init + 1023)/1024); +c01009f3: b8 54 61 1a c0 mov $0xc01a6154,%eax +c01009f8: 2d 36 00 10 c0 sub $0xc0100036,%eax +c01009fd: 05 ff 03 00 00 add $0x3ff,%eax +c0100a02: 8d 90 ff 03 00 00 lea 0x3ff(%eax),%edx +c0100a08: 85 c0 test %eax,%eax +c0100a0a: 0f 48 c2 cmovs %edx,%eax +c0100a0d: c1 f8 0a sar $0xa,%eax +c0100a10: 89 44 24 04 mov %eax,0x4(%esp) +c0100a14: c7 04 24 b0 c0 10 c0 movl $0xc010c0b0,(%esp) +c0100a1b: e8 58 f9 ff ff call c0100378 +} +c0100a20: 90 nop +c0100a21: 89 ec mov %ebp,%esp +c0100a23: 5d pop %ebp +c0100a24: c3 ret + +c0100a25 : +/* * + * print_debuginfo - read and print the stat information for the address @eip, + * and info.eip_fn_addr should be the first address of the related function. + * */ +void +print_debuginfo(uintptr_t eip) { +c0100a25: 55 push %ebp +c0100a26: 89 e5 mov %esp,%ebp +c0100a28: 81 ec 48 01 00 00 sub $0x148,%esp + struct eipdebuginfo info; + if (debuginfo_eip(eip, &info) != 0) { +c0100a2e: 8d 45 dc lea -0x24(%ebp),%eax +c0100a31: 89 44 24 04 mov %eax,0x4(%esp) +c0100a35: 8b 45 08 mov 0x8(%ebp),%eax +c0100a38: 89 04 24 mov %eax,(%esp) +c0100a3b: e8 33 fb ff ff call c0100573 +c0100a40: 85 c0 test %eax,%eax +c0100a42: 74 15 je c0100a59 + cprintf(" : -- 0x%08x --\n", eip); +c0100a44: 8b 45 08 mov 0x8(%ebp),%eax +c0100a47: 89 44 24 04 mov %eax,0x4(%esp) +c0100a4b: c7 04 24 da c0 10 c0 movl $0xc010c0da,(%esp) +c0100a52: e8 21 f9 ff ff call c0100378 + } + fnname[j] = '\0'; + cprintf(" %s:%d: %s+%d\n", info.eip_file, info.eip_line, + fnname, eip - info.eip_fn_addr); + } +} +c0100a57: eb 6c jmp c0100ac5 + for (j = 0; j < info.eip_fn_namelen; j ++) { +c0100a59: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) +c0100a60: eb 1b jmp c0100a7d + fnname[j] = info.eip_fn_name[j]; +c0100a62: 8b 55 e4 mov -0x1c(%ebp),%edx +c0100a65: 8b 45 f4 mov -0xc(%ebp),%eax +c0100a68: 01 d0 add %edx,%eax +c0100a6a: 0f b6 10 movzbl (%eax),%edx +c0100a6d: 8d 8d dc fe ff ff lea -0x124(%ebp),%ecx +c0100a73: 8b 45 f4 mov -0xc(%ebp),%eax +c0100a76: 01 c8 add %ecx,%eax +c0100a78: 88 10 mov %dl,(%eax) + for (j = 0; j < info.eip_fn_namelen; j ++) { +c0100a7a: ff 45 f4 incl -0xc(%ebp) +c0100a7d: 8b 45 e8 mov -0x18(%ebp),%eax +c0100a80: 39 45 f4 cmp %eax,-0xc(%ebp) +c0100a83: 7c dd jl c0100a62 + fnname[j] = '\0'; +c0100a85: 8d 95 dc fe ff ff lea -0x124(%ebp),%edx +c0100a8b: 8b 45 f4 mov -0xc(%ebp),%eax +c0100a8e: 01 d0 add %edx,%eax +c0100a90: c6 00 00 movb $0x0,(%eax) + fnname, eip - info.eip_fn_addr); +c0100a93: 8b 55 ec mov -0x14(%ebp),%edx + cprintf(" %s:%d: %s+%d\n", info.eip_file, info.eip_line, +c0100a96: 8b 45 08 mov 0x8(%ebp),%eax +c0100a99: 29 d0 sub %edx,%eax +c0100a9b: 89 c1 mov %eax,%ecx +c0100a9d: 8b 55 e0 mov -0x20(%ebp),%edx +c0100aa0: 8b 45 dc mov -0x24(%ebp),%eax +c0100aa3: 89 4c 24 10 mov %ecx,0x10(%esp) +c0100aa7: 8d 8d dc fe ff ff lea -0x124(%ebp),%ecx +c0100aad: 89 4c 24 0c mov %ecx,0xc(%esp) +c0100ab1: 89 54 24 08 mov %edx,0x8(%esp) +c0100ab5: 89 44 24 04 mov %eax,0x4(%esp) +c0100ab9: c7 04 24 f6 c0 10 c0 movl $0xc010c0f6,(%esp) +c0100ac0: e8 b3 f8 ff ff call c0100378 +} +c0100ac5: 90 nop +c0100ac6: 89 ec mov %ebp,%esp +c0100ac8: 5d pop %ebp +c0100ac9: c3 ret + +c0100aca : + +static __noinline uint32_t +read_eip(void) { +c0100aca: 55 push %ebp +c0100acb: 89 e5 mov %esp,%ebp +c0100acd: 83 ec 10 sub $0x10,%esp + uint32_t eip; + asm volatile("movl 4(%%ebp), %0" : "=r" (eip)); +c0100ad0: 8b 45 04 mov 0x4(%ebp),%eax +c0100ad3: 89 45 fc mov %eax,-0x4(%ebp) + return eip; +c0100ad6: 8b 45 fc mov -0x4(%ebp),%eax +} +c0100ad9: 89 ec mov %ebp,%esp +c0100adb: 5d pop %ebp +c0100adc: c3 ret + +c0100add : + * + * Note that, the length of ebp-chain is limited. In boot/bootasm.S, before jumping + * to the kernel entry, the value of ebp has been set to zero, that's the boundary. + * */ +void +print_stackframe(void) { +c0100add: 55 push %ebp +c0100ade: 89 e5 mov %esp,%ebp + * (3.4) call print_debuginfo(eip-1) to print the C calling function name and line number, etc. + * (3.5) popup a calling stackframe + * NOTICE: the calling funciton's return addr eip = ss:[ebp+4] + * the calling funciton's ebp = ss:[ebp] + */ +} +c0100ae0: 90 nop +c0100ae1: 5d pop %ebp +c0100ae2: c3 ret + +c0100ae3 : +#define MAXARGS 16 +#define WHITESPACE " \t\n\r" + +/* parse - parse the command buffer into whitespace-separated arguments */ +static int +parse(char *buf, char **argv) { +c0100ae3: 55 push %ebp +c0100ae4: 89 e5 mov %esp,%ebp +c0100ae6: 83 ec 28 sub $0x28,%esp + int argc = 0; +c0100ae9: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + while (1) { + // find global whitespace + while (*buf != '\0' && strchr(WHITESPACE, *buf) != NULL) { +c0100af0: eb 0c jmp c0100afe + *buf ++ = '\0'; +c0100af2: 8b 45 08 mov 0x8(%ebp),%eax +c0100af5: 8d 50 01 lea 0x1(%eax),%edx +c0100af8: 89 55 08 mov %edx,0x8(%ebp) +c0100afb: c6 00 00 movb $0x0,(%eax) + while (*buf != '\0' && strchr(WHITESPACE, *buf) != NULL) { +c0100afe: 8b 45 08 mov 0x8(%ebp),%eax +c0100b01: 0f b6 00 movzbl (%eax),%eax +c0100b04: 84 c0 test %al,%al +c0100b06: 74 1d je c0100b25 +c0100b08: 8b 45 08 mov 0x8(%ebp),%eax +c0100b0b: 0f b6 00 movzbl (%eax),%eax +c0100b0e: 0f be c0 movsbl %al,%eax +c0100b11: 89 44 24 04 mov %eax,0x4(%esp) +c0100b15: c7 04 24 88 c1 10 c0 movl $0xc010c188,(%esp) +c0100b1c: e8 14 b1 00 00 call c010bc35 +c0100b21: 85 c0 test %eax,%eax +c0100b23: 75 cd jne c0100af2 + } + if (*buf == '\0') { +c0100b25: 8b 45 08 mov 0x8(%ebp),%eax +c0100b28: 0f b6 00 movzbl (%eax),%eax +c0100b2b: 84 c0 test %al,%al +c0100b2d: 74 65 je c0100b94 + break; + } + + // save and scan past next arg + if (argc == MAXARGS - 1) { +c0100b2f: 83 7d f4 0f cmpl $0xf,-0xc(%ebp) +c0100b33: 75 14 jne c0100b49 + cprintf("Too many arguments (max %d).\n", MAXARGS); +c0100b35: c7 44 24 04 10 00 00 movl $0x10,0x4(%esp) +c0100b3c: 00 +c0100b3d: c7 04 24 8d c1 10 c0 movl $0xc010c18d,(%esp) +c0100b44: e8 2f f8 ff ff call c0100378 + } + argv[argc ++] = buf; +c0100b49: 8b 45 f4 mov -0xc(%ebp),%eax +c0100b4c: 8d 50 01 lea 0x1(%eax),%edx +c0100b4f: 89 55 f4 mov %edx,-0xc(%ebp) +c0100b52: 8d 14 85 00 00 00 00 lea 0x0(,%eax,4),%edx +c0100b59: 8b 45 0c mov 0xc(%ebp),%eax +c0100b5c: 01 c2 add %eax,%edx +c0100b5e: 8b 45 08 mov 0x8(%ebp),%eax +c0100b61: 89 02 mov %eax,(%edx) + while (*buf != '\0' && strchr(WHITESPACE, *buf) == NULL) { +c0100b63: eb 03 jmp c0100b68 + buf ++; +c0100b65: ff 45 08 incl 0x8(%ebp) + while (*buf != '\0' && strchr(WHITESPACE, *buf) == NULL) { +c0100b68: 8b 45 08 mov 0x8(%ebp),%eax +c0100b6b: 0f b6 00 movzbl (%eax),%eax +c0100b6e: 84 c0 test %al,%al +c0100b70: 74 8c je c0100afe +c0100b72: 8b 45 08 mov 0x8(%ebp),%eax +c0100b75: 0f b6 00 movzbl (%eax),%eax +c0100b78: 0f be c0 movsbl %al,%eax +c0100b7b: 89 44 24 04 mov %eax,0x4(%esp) +c0100b7f: c7 04 24 88 c1 10 c0 movl $0xc010c188,(%esp) +c0100b86: e8 aa b0 00 00 call c010bc35 +c0100b8b: 85 c0 test %eax,%eax +c0100b8d: 74 d6 je c0100b65 + while (*buf != '\0' && strchr(WHITESPACE, *buf) != NULL) { +c0100b8f: e9 6a ff ff ff jmp c0100afe + break; +c0100b94: 90 nop + } + } + return argc; +c0100b95: 8b 45 f4 mov -0xc(%ebp),%eax +} +c0100b98: 89 ec mov %ebp,%esp +c0100b9a: 5d pop %ebp +c0100b9b: c3 ret + +c0100b9c : +/* * + * runcmd - parse the input string, split it into separated arguments + * and then lookup and invoke some related commands/ + * */ +static int +runcmd(char *buf, struct trapframe *tf) { +c0100b9c: 55 push %ebp +c0100b9d: 89 e5 mov %esp,%ebp +c0100b9f: 83 ec 68 sub $0x68,%esp +c0100ba2: 89 5d fc mov %ebx,-0x4(%ebp) + char *argv[MAXARGS]; + int argc = parse(buf, argv); +c0100ba5: 8d 45 b0 lea -0x50(%ebp),%eax +c0100ba8: 89 44 24 04 mov %eax,0x4(%esp) +c0100bac: 8b 45 08 mov 0x8(%ebp),%eax +c0100baf: 89 04 24 mov %eax,(%esp) +c0100bb2: e8 2c ff ff ff call c0100ae3 +c0100bb7: 89 45 f0 mov %eax,-0x10(%ebp) + if (argc == 0) { +c0100bba: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) +c0100bbe: 75 0a jne c0100bca + return 0; +c0100bc0: b8 00 00 00 00 mov $0x0,%eax +c0100bc5: e9 83 00 00 00 jmp c0100c4d + } + int i; + for (i = 0; i < NCOMMANDS; i ++) { +c0100bca: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) +c0100bd1: eb 5a jmp c0100c2d + if (strcmp(commands[i].name, argv[0]) == 0) { +c0100bd3: 8b 55 b0 mov -0x50(%ebp),%edx +c0100bd6: 8b 4d f4 mov -0xc(%ebp),%ecx +c0100bd9: 89 c8 mov %ecx,%eax +c0100bdb: 01 c0 add %eax,%eax +c0100bdd: 01 c8 add %ecx,%eax +c0100bdf: c1 e0 02 shl $0x2,%eax +c0100be2: 05 00 f0 12 c0 add $0xc012f000,%eax +c0100be7: 8b 00 mov (%eax),%eax +c0100be9: 89 54 24 04 mov %edx,0x4(%esp) +c0100bed: 89 04 24 mov %eax,(%esp) +c0100bf0: e8 a4 af 00 00 call c010bb99 +c0100bf5: 85 c0 test %eax,%eax +c0100bf7: 75 31 jne c0100c2a + return commands[i].func(argc - 1, argv + 1, tf); +c0100bf9: 8b 55 f4 mov -0xc(%ebp),%edx +c0100bfc: 89 d0 mov %edx,%eax +c0100bfe: 01 c0 add %eax,%eax +c0100c00: 01 d0 add %edx,%eax +c0100c02: c1 e0 02 shl $0x2,%eax +c0100c05: 05 08 f0 12 c0 add $0xc012f008,%eax +c0100c0a: 8b 10 mov (%eax),%edx +c0100c0c: 8d 45 b0 lea -0x50(%ebp),%eax +c0100c0f: 83 c0 04 add $0x4,%eax +c0100c12: 8b 4d f0 mov -0x10(%ebp),%ecx +c0100c15: 8d 59 ff lea -0x1(%ecx),%ebx +c0100c18: 8b 4d 0c mov 0xc(%ebp),%ecx +c0100c1b: 89 4c 24 08 mov %ecx,0x8(%esp) +c0100c1f: 89 44 24 04 mov %eax,0x4(%esp) +c0100c23: 89 1c 24 mov %ebx,(%esp) +c0100c26: ff d2 call *%edx +c0100c28: eb 23 jmp c0100c4d + for (i = 0; i < NCOMMANDS; i ++) { +c0100c2a: ff 45 f4 incl -0xc(%ebp) +c0100c2d: 8b 45 f4 mov -0xc(%ebp),%eax +c0100c30: 83 f8 02 cmp $0x2,%eax +c0100c33: 76 9e jbe c0100bd3 + } + } + cprintf("Unknown command '%s'\n", argv[0]); +c0100c35: 8b 45 b0 mov -0x50(%ebp),%eax +c0100c38: 89 44 24 04 mov %eax,0x4(%esp) +c0100c3c: c7 04 24 ab c1 10 c0 movl $0xc010c1ab,(%esp) +c0100c43: e8 30 f7 ff ff call c0100378 + return 0; +c0100c48: b8 00 00 00 00 mov $0x0,%eax +} +c0100c4d: 8b 5d fc mov -0x4(%ebp),%ebx +c0100c50: 89 ec mov %ebp,%esp +c0100c52: 5d pop %ebp +c0100c53: c3 ret + +c0100c54 : + +/***** Implementations of basic kernel monitor commands *****/ + +void +kmonitor(struct trapframe *tf) { +c0100c54: 55 push %ebp +c0100c55: 89 e5 mov %esp,%ebp +c0100c57: 83 ec 28 sub $0x28,%esp + cprintf("Welcome to the kernel debug monitor!!\n"); +c0100c5a: c7 04 24 c4 c1 10 c0 movl $0xc010c1c4,(%esp) +c0100c61: e8 12 f7 ff ff call c0100378 + cprintf("Type 'help' for a list of commands.\n"); +c0100c66: c7 04 24 ec c1 10 c0 movl $0xc010c1ec,(%esp) +c0100c6d: e8 06 f7 ff ff call c0100378 + + if (tf != NULL) { +c0100c72: 83 7d 08 00 cmpl $0x0,0x8(%ebp) +c0100c76: 74 0b je c0100c83 + print_trapframe(tf); +c0100c78: 8b 45 08 mov 0x8(%ebp),%eax +c0100c7b: 89 04 24 mov %eax,(%esp) +c0100c7e: e8 2a 17 00 00 call c01023ad + } + + char *buf; + while (1) { + if ((buf = readline("K> ")) != NULL) { +c0100c83: c7 04 24 11 c2 10 c0 movl $0xc010c211,(%esp) +c0100c8a: e8 da f5 ff ff call c0100269 +c0100c8f: 89 45 f4 mov %eax,-0xc(%ebp) +c0100c92: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c0100c96: 74 eb je c0100c83 + if (runcmd(buf, tf) < 0) { +c0100c98: 8b 45 08 mov 0x8(%ebp),%eax +c0100c9b: 89 44 24 04 mov %eax,0x4(%esp) +c0100c9f: 8b 45 f4 mov -0xc(%ebp),%eax +c0100ca2: 89 04 24 mov %eax,(%esp) +c0100ca5: e8 f2 fe ff ff call c0100b9c +c0100caa: 85 c0 test %eax,%eax +c0100cac: 78 02 js c0100cb0 + if ((buf = readline("K> ")) != NULL) { +c0100cae: eb d3 jmp c0100c83 + break; +c0100cb0: 90 nop + } + } + } +} +c0100cb1: 90 nop +c0100cb2: 89 ec mov %ebp,%esp +c0100cb4: 5d pop %ebp +c0100cb5: c3 ret + +c0100cb6 : + +/* mon_help - print the information about mon_* functions */ +int +mon_help(int argc, char **argv, struct trapframe *tf) { +c0100cb6: 55 push %ebp +c0100cb7: 89 e5 mov %esp,%ebp +c0100cb9: 83 ec 28 sub $0x28,%esp + int i; + for (i = 0; i < NCOMMANDS; i ++) { +c0100cbc: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) +c0100cc3: eb 3d jmp c0100d02 + cprintf("%s - %s\n", commands[i].name, commands[i].desc); +c0100cc5: 8b 55 f4 mov -0xc(%ebp),%edx +c0100cc8: 89 d0 mov %edx,%eax +c0100cca: 01 c0 add %eax,%eax +c0100ccc: 01 d0 add %edx,%eax +c0100cce: c1 e0 02 shl $0x2,%eax +c0100cd1: 05 04 f0 12 c0 add $0xc012f004,%eax +c0100cd6: 8b 10 mov (%eax),%edx +c0100cd8: 8b 4d f4 mov -0xc(%ebp),%ecx +c0100cdb: 89 c8 mov %ecx,%eax +c0100cdd: 01 c0 add %eax,%eax +c0100cdf: 01 c8 add %ecx,%eax +c0100ce1: c1 e0 02 shl $0x2,%eax +c0100ce4: 05 00 f0 12 c0 add $0xc012f000,%eax +c0100ce9: 8b 00 mov (%eax),%eax +c0100ceb: 89 54 24 08 mov %edx,0x8(%esp) +c0100cef: 89 44 24 04 mov %eax,0x4(%esp) +c0100cf3: c7 04 24 15 c2 10 c0 movl $0xc010c215,(%esp) +c0100cfa: e8 79 f6 ff ff call c0100378 + for (i = 0; i < NCOMMANDS; i ++) { +c0100cff: ff 45 f4 incl -0xc(%ebp) +c0100d02: 8b 45 f4 mov -0xc(%ebp),%eax +c0100d05: 83 f8 02 cmp $0x2,%eax +c0100d08: 76 bb jbe c0100cc5 + } + return 0; +c0100d0a: b8 00 00 00 00 mov $0x0,%eax +} +c0100d0f: 89 ec mov %ebp,%esp +c0100d11: 5d pop %ebp +c0100d12: c3 ret + +c0100d13 : +/* * + * mon_kerninfo - call print_kerninfo in kern/debug/kdebug.c to + * print the memory occupancy in kernel. + * */ +int +mon_kerninfo(int argc, char **argv, struct trapframe *tf) { +c0100d13: 55 push %ebp +c0100d14: 89 e5 mov %esp,%ebp +c0100d16: 83 ec 08 sub $0x8,%esp + print_kerninfo(); +c0100d19: e8 73 fc ff ff call c0100991 + return 0; +c0100d1e: b8 00 00 00 00 mov $0x0,%eax +} +c0100d23: 89 ec mov %ebp,%esp +c0100d25: 5d pop %ebp +c0100d26: c3 ret + +c0100d27 : +/* * + * mon_backtrace - call print_stackframe in kern/debug/kdebug.c to + * print a backtrace of the stack. + * */ +int +mon_backtrace(int argc, char **argv, struct trapframe *tf) { +c0100d27: 55 push %ebp +c0100d28: 89 e5 mov %esp,%ebp +c0100d2a: 83 ec 08 sub $0x8,%esp + print_stackframe(); +c0100d2d: e8 ab fd ff ff call c0100add + return 0; +c0100d32: b8 00 00 00 00 mov $0x0,%eax +} +c0100d37: 89 ec mov %ebp,%esp +c0100d39: 5d pop %ebp +c0100d3a: c3 ret + +c0100d3b <__panic>: +/* * + * __panic - __panic is called on unresolvable fatal errors. it prints + * "panic: 'message'", and then enters the kernel monitor. + * */ +void +__panic(const char *file, int line, const char *fmt, ...) { +c0100d3b: 55 push %ebp +c0100d3c: 89 e5 mov %esp,%ebp +c0100d3e: 83 ec 28 sub $0x28,%esp + if (is_panic) { +c0100d41: a1 20 34 1a c0 mov 0xc01a3420,%eax +c0100d46: 85 c0 test %eax,%eax +c0100d48: 75 5b jne c0100da5 <__panic+0x6a> + goto panic_dead; + } + is_panic = 1; +c0100d4a: c7 05 20 34 1a c0 01 movl $0x1,0xc01a3420 +c0100d51: 00 00 00 + + // print the 'message' + va_list ap; + va_start(ap, fmt); +c0100d54: 8d 45 14 lea 0x14(%ebp),%eax +c0100d57: 89 45 f4 mov %eax,-0xc(%ebp) + cprintf("kernel panic at %s:%d:\n ", file, line); +c0100d5a: 8b 45 0c mov 0xc(%ebp),%eax +c0100d5d: 89 44 24 08 mov %eax,0x8(%esp) +c0100d61: 8b 45 08 mov 0x8(%ebp),%eax +c0100d64: 89 44 24 04 mov %eax,0x4(%esp) +c0100d68: c7 04 24 1e c2 10 c0 movl $0xc010c21e,(%esp) +c0100d6f: e8 04 f6 ff ff call c0100378 + vcprintf(fmt, ap); +c0100d74: 8b 45 f4 mov -0xc(%ebp),%eax +c0100d77: 89 44 24 04 mov %eax,0x4(%esp) +c0100d7b: 8b 45 10 mov 0x10(%ebp),%eax +c0100d7e: 89 04 24 mov %eax,(%esp) +c0100d81: e8 bd f5 ff ff call c0100343 + cprintf("\n"); +c0100d86: c7 04 24 3a c2 10 c0 movl $0xc010c23a,(%esp) +c0100d8d: e8 e6 f5 ff ff call c0100378 + + cprintf("stack trackback:\n"); +c0100d92: c7 04 24 3c c2 10 c0 movl $0xc010c23c,(%esp) +c0100d99: e8 da f5 ff ff call c0100378 + print_stackframe(); +c0100d9e: e8 3a fd ff ff call c0100add +c0100da3: eb 01 jmp c0100da6 <__panic+0x6b> + goto panic_dead; +c0100da5: 90 nop + + va_end(ap); + +panic_dead: + intr_disable(); +c0100da6: e8 46 12 00 00 call c0101ff1 + while (1) { + kmonitor(NULL); +c0100dab: c7 04 24 00 00 00 00 movl $0x0,(%esp) +c0100db2: e8 9d fe ff ff call c0100c54 +c0100db7: eb f2 jmp c0100dab <__panic+0x70> + +c0100db9 <__warn>: + } +} + +/* __warn - like panic, but don't */ +void +__warn(const char *file, int line, const char *fmt, ...) { +c0100db9: 55 push %ebp +c0100dba: 89 e5 mov %esp,%ebp +c0100dbc: 83 ec 28 sub $0x28,%esp + va_list ap; + va_start(ap, fmt); +c0100dbf: 8d 45 14 lea 0x14(%ebp),%eax +c0100dc2: 89 45 f4 mov %eax,-0xc(%ebp) + cprintf("kernel warning at %s:%d:\n ", file, line); +c0100dc5: 8b 45 0c mov 0xc(%ebp),%eax +c0100dc8: 89 44 24 08 mov %eax,0x8(%esp) +c0100dcc: 8b 45 08 mov 0x8(%ebp),%eax +c0100dcf: 89 44 24 04 mov %eax,0x4(%esp) +c0100dd3: c7 04 24 4e c2 10 c0 movl $0xc010c24e,(%esp) +c0100dda: e8 99 f5 ff ff call c0100378 + vcprintf(fmt, ap); +c0100ddf: 8b 45 f4 mov -0xc(%ebp),%eax +c0100de2: 89 44 24 04 mov %eax,0x4(%esp) +c0100de6: 8b 45 10 mov 0x10(%ebp),%eax +c0100de9: 89 04 24 mov %eax,(%esp) +c0100dec: e8 52 f5 ff ff call c0100343 + cprintf("\n"); +c0100df1: c7 04 24 3a c2 10 c0 movl $0xc010c23a,(%esp) +c0100df8: e8 7b f5 ff ff call c0100378 + va_end(ap); +} +c0100dfd: 90 nop +c0100dfe: 89 ec mov %ebp,%esp +c0100e00: 5d pop %ebp +c0100e01: c3 ret + +c0100e02 : + +bool +is_kernel_panic(void) { +c0100e02: 55 push %ebp +c0100e03: 89 e5 mov %esp,%ebp + return is_panic; +c0100e05: a1 20 34 1a c0 mov 0xc01a3420,%eax +} +c0100e0a: 5d pop %ebp +c0100e0b: c3 ret + +c0100e0c : +/* * + * clock_init - initialize 8253 clock to interrupt 100 times per second, + * and then enable IRQ_TIMER. + * */ +void +clock_init(void) { +c0100e0c: 55 push %ebp +c0100e0d: 89 e5 mov %esp,%ebp +c0100e0f: 83 ec 28 sub $0x28,%esp +c0100e12: 66 c7 45 ee 43 00 movw $0x43,-0x12(%ebp) +c0100e18: c6 45 ed 34 movb $0x34,-0x13(%ebp) + : "memory", "cc"); +} + +static inline void +outb(uint16_t port, uint8_t data) { + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0100e1c: 0f b6 45 ed movzbl -0x13(%ebp),%eax +c0100e20: 0f b7 55 ee movzwl -0x12(%ebp),%edx +c0100e24: ee out %al,(%dx) +} +c0100e25: 90 nop +c0100e26: 66 c7 45 f2 40 00 movw $0x40,-0xe(%ebp) +c0100e2c: c6 45 f1 9c movb $0x9c,-0xf(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0100e30: 0f b6 45 f1 movzbl -0xf(%ebp),%eax +c0100e34: 0f b7 55 f2 movzwl -0xe(%ebp),%edx +c0100e38: ee out %al,(%dx) +} +c0100e39: 90 nop +c0100e3a: 66 c7 45 f6 40 00 movw $0x40,-0xa(%ebp) +c0100e40: c6 45 f5 2e movb $0x2e,-0xb(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0100e44: 0f b6 45 f5 movzbl -0xb(%ebp),%eax +c0100e48: 0f b7 55 f6 movzwl -0xa(%ebp),%edx +c0100e4c: ee out %al,(%dx) +} +c0100e4d: 90 nop + outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); + outb(IO_TIMER1, TIMER_DIV(100) % 256); + outb(IO_TIMER1, TIMER_DIV(100) / 256); + + // initialize time counter 'ticks' to zero + ticks = 0; +c0100e4e: c7 05 24 34 1a c0 00 movl $0x0,0xc01a3424 +c0100e55: 00 00 00 + + cprintf("++ setup timer interrupts\n"); +c0100e58: c7 04 24 6c c2 10 c0 movl $0xc010c26c,(%esp) +c0100e5f: e8 14 f5 ff ff call c0100378 + pic_enable(IRQ_TIMER); +c0100e64: c7 04 24 00 00 00 00 movl $0x0,(%esp) +c0100e6b: e8 e6 11 00 00 call c0102056 +} +c0100e70: 90 nop +c0100e71: 89 ec mov %ebp,%esp +c0100e73: 5d pop %ebp +c0100e74: c3 ret + +c0100e75 <__intr_save>: +#include +#include +#include + +static inline bool +__intr_save(void) { +c0100e75: 55 push %ebp +c0100e76: 89 e5 mov %esp,%ebp +c0100e78: 83 ec 18 sub $0x18,%esp +} + +static inline uint32_t +read_eflags(void) { + uint32_t eflags; + asm volatile ("pushfl; popl %0" : "=r" (eflags)); +c0100e7b: 9c pushf +c0100e7c: 58 pop %eax +c0100e7d: 89 45 f4 mov %eax,-0xc(%ebp) + return eflags; +c0100e80: 8b 45 f4 mov -0xc(%ebp),%eax + if (read_eflags() & FL_IF) { +c0100e83: 25 00 02 00 00 and $0x200,%eax +c0100e88: 85 c0 test %eax,%eax +c0100e8a: 74 0c je c0100e98 <__intr_save+0x23> + intr_disable(); +c0100e8c: e8 60 11 00 00 call c0101ff1 + return 1; +c0100e91: b8 01 00 00 00 mov $0x1,%eax +c0100e96: eb 05 jmp c0100e9d <__intr_save+0x28> + } + return 0; +c0100e98: b8 00 00 00 00 mov $0x0,%eax +} +c0100e9d: 89 ec mov %ebp,%esp +c0100e9f: 5d pop %ebp +c0100ea0: c3 ret + +c0100ea1 <__intr_restore>: + +static inline void +__intr_restore(bool flag) { +c0100ea1: 55 push %ebp +c0100ea2: 89 e5 mov %esp,%ebp +c0100ea4: 83 ec 08 sub $0x8,%esp + if (flag) { +c0100ea7: 83 7d 08 00 cmpl $0x0,0x8(%ebp) +c0100eab: 74 05 je c0100eb2 <__intr_restore+0x11> + intr_enable(); +c0100ead: e8 37 11 00 00 call c0101fe9 + } +} +c0100eb2: 90 nop +c0100eb3: 89 ec mov %ebp,%esp +c0100eb5: 5d pop %ebp +c0100eb6: c3 ret + +c0100eb7 : +#include +#include + +/* stupid I/O delay routine necessitated by historical PC design flaws */ +static void +delay(void) { +c0100eb7: 55 push %ebp +c0100eb8: 89 e5 mov %esp,%ebp +c0100eba: 83 ec 10 sub $0x10,%esp +c0100ebd: 66 c7 45 f2 84 00 movw $0x84,-0xe(%ebp) + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); +c0100ec3: 0f b7 45 f2 movzwl -0xe(%ebp),%eax +c0100ec7: 89 c2 mov %eax,%edx +c0100ec9: ec in (%dx),%al +c0100eca: 88 45 f1 mov %al,-0xf(%ebp) +c0100ecd: 66 c7 45 f6 84 00 movw $0x84,-0xa(%ebp) +c0100ed3: 0f b7 45 f6 movzwl -0xa(%ebp),%eax +c0100ed7: 89 c2 mov %eax,%edx +c0100ed9: ec in (%dx),%al +c0100eda: 88 45 f5 mov %al,-0xb(%ebp) +c0100edd: 66 c7 45 fa 84 00 movw $0x84,-0x6(%ebp) +c0100ee3: 0f b7 45 fa movzwl -0x6(%ebp),%eax +c0100ee7: 89 c2 mov %eax,%edx +c0100ee9: ec in (%dx),%al +c0100eea: 88 45 f9 mov %al,-0x7(%ebp) +c0100eed: 66 c7 45 fe 84 00 movw $0x84,-0x2(%ebp) +c0100ef3: 0f b7 45 fe movzwl -0x2(%ebp),%eax +c0100ef7: 89 c2 mov %eax,%edx +c0100ef9: ec in (%dx),%al +c0100efa: 88 45 fd mov %al,-0x3(%ebp) + inb(0x84); + inb(0x84); + inb(0x84); + inb(0x84); +} +c0100efd: 90 nop +c0100efe: 89 ec mov %ebp,%esp +c0100f00: 5d pop %ebp +c0100f01: c3 ret + +c0100f02 : +static uint16_t addr_6845; + +/* TEXT-mode CGA/VGA display output */ + +static void +cga_init(void) { +c0100f02: 55 push %ebp +c0100f03: 89 e5 mov %esp,%ebp +c0100f05: 83 ec 20 sub $0x20,%esp + volatile uint16_t *cp = (uint16_t *)(CGA_BUF + KERNBASE); +c0100f08: c7 45 fc 00 80 0b c0 movl $0xc00b8000,-0x4(%ebp) + uint16_t was = *cp; +c0100f0f: 8b 45 fc mov -0x4(%ebp),%eax +c0100f12: 0f b7 00 movzwl (%eax),%eax +c0100f15: 66 89 45 fa mov %ax,-0x6(%ebp) + *cp = (uint16_t) 0xA55A; +c0100f19: 8b 45 fc mov -0x4(%ebp),%eax +c0100f1c: 66 c7 00 5a a5 movw $0xa55a,(%eax) + if (*cp != 0xA55A) { +c0100f21: 8b 45 fc mov -0x4(%ebp),%eax +c0100f24: 0f b7 00 movzwl (%eax),%eax +c0100f27: 0f b7 c0 movzwl %ax,%eax +c0100f2a: 3d 5a a5 00 00 cmp $0xa55a,%eax +c0100f2f: 74 12 je c0100f43 + cp = (uint16_t*)(MONO_BUF + KERNBASE); +c0100f31: c7 45 fc 00 00 0b c0 movl $0xc00b0000,-0x4(%ebp) + addr_6845 = MONO_BASE; +c0100f38: 66 c7 05 46 34 1a c0 movw $0x3b4,0xc01a3446 +c0100f3f: b4 03 +c0100f41: eb 13 jmp c0100f56 + } else { + *cp = was; +c0100f43: 8b 45 fc mov -0x4(%ebp),%eax +c0100f46: 0f b7 55 fa movzwl -0x6(%ebp),%edx +c0100f4a: 66 89 10 mov %dx,(%eax) + addr_6845 = CGA_BASE; +c0100f4d: 66 c7 05 46 34 1a c0 movw $0x3d4,0xc01a3446 +c0100f54: d4 03 + } + + // Extract cursor location + uint32_t pos; + outb(addr_6845, 14); +c0100f56: 0f b7 05 46 34 1a c0 movzwl 0xc01a3446,%eax +c0100f5d: 66 89 45 e6 mov %ax,-0x1a(%ebp) +c0100f61: c6 45 e5 0e movb $0xe,-0x1b(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0100f65: 0f b6 45 e5 movzbl -0x1b(%ebp),%eax +c0100f69: 0f b7 55 e6 movzwl -0x1a(%ebp),%edx +c0100f6d: ee out %al,(%dx) +} +c0100f6e: 90 nop + pos = inb(addr_6845 + 1) << 8; +c0100f6f: 0f b7 05 46 34 1a c0 movzwl 0xc01a3446,%eax +c0100f76: 40 inc %eax +c0100f77: 0f b7 c0 movzwl %ax,%eax +c0100f7a: 66 89 45 ea mov %ax,-0x16(%ebp) + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); +c0100f7e: 0f b7 45 ea movzwl -0x16(%ebp),%eax +c0100f82: 89 c2 mov %eax,%edx +c0100f84: ec in (%dx),%al +c0100f85: 88 45 e9 mov %al,-0x17(%ebp) + return data; +c0100f88: 0f b6 45 e9 movzbl -0x17(%ebp),%eax +c0100f8c: 0f b6 c0 movzbl %al,%eax +c0100f8f: c1 e0 08 shl $0x8,%eax +c0100f92: 89 45 f4 mov %eax,-0xc(%ebp) + outb(addr_6845, 15); +c0100f95: 0f b7 05 46 34 1a c0 movzwl 0xc01a3446,%eax +c0100f9c: 66 89 45 ee mov %ax,-0x12(%ebp) +c0100fa0: c6 45 ed 0f movb $0xf,-0x13(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0100fa4: 0f b6 45 ed movzbl -0x13(%ebp),%eax +c0100fa8: 0f b7 55 ee movzwl -0x12(%ebp),%edx +c0100fac: ee out %al,(%dx) +} +c0100fad: 90 nop + pos |= inb(addr_6845 + 1); +c0100fae: 0f b7 05 46 34 1a c0 movzwl 0xc01a3446,%eax +c0100fb5: 40 inc %eax +c0100fb6: 0f b7 c0 movzwl %ax,%eax +c0100fb9: 66 89 45 f2 mov %ax,-0xe(%ebp) + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); +c0100fbd: 0f b7 45 f2 movzwl -0xe(%ebp),%eax +c0100fc1: 89 c2 mov %eax,%edx +c0100fc3: ec in (%dx),%al +c0100fc4: 88 45 f1 mov %al,-0xf(%ebp) + return data; +c0100fc7: 0f b6 45 f1 movzbl -0xf(%ebp),%eax +c0100fcb: 0f b6 c0 movzbl %al,%eax +c0100fce: 09 45 f4 or %eax,-0xc(%ebp) + + crt_buf = (uint16_t*) cp; +c0100fd1: 8b 45 fc mov -0x4(%ebp),%eax +c0100fd4: a3 40 34 1a c0 mov %eax,0xc01a3440 + crt_pos = pos; +c0100fd9: 8b 45 f4 mov -0xc(%ebp),%eax +c0100fdc: 0f b7 c0 movzwl %ax,%eax +c0100fdf: 66 a3 44 34 1a c0 mov %ax,0xc01a3444 +} +c0100fe5: 90 nop +c0100fe6: 89 ec mov %ebp,%esp +c0100fe8: 5d pop %ebp +c0100fe9: c3 ret + +c0100fea : + +static bool serial_exists = 0; + +static void +serial_init(void) { +c0100fea: 55 push %ebp +c0100feb: 89 e5 mov %esp,%ebp +c0100fed: 83 ec 48 sub $0x48,%esp +c0100ff0: 66 c7 45 d2 fa 03 movw $0x3fa,-0x2e(%ebp) +c0100ff6: c6 45 d1 00 movb $0x0,-0x2f(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0100ffa: 0f b6 45 d1 movzbl -0x2f(%ebp),%eax +c0100ffe: 0f b7 55 d2 movzwl -0x2e(%ebp),%edx +c0101002: ee out %al,(%dx) +} +c0101003: 90 nop +c0101004: 66 c7 45 d6 fb 03 movw $0x3fb,-0x2a(%ebp) +c010100a: c6 45 d5 80 movb $0x80,-0x2b(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c010100e: 0f b6 45 d5 movzbl -0x2b(%ebp),%eax +c0101012: 0f b7 55 d6 movzwl -0x2a(%ebp),%edx +c0101016: ee out %al,(%dx) +} +c0101017: 90 nop +c0101018: 66 c7 45 da f8 03 movw $0x3f8,-0x26(%ebp) +c010101e: c6 45 d9 0c movb $0xc,-0x27(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101022: 0f b6 45 d9 movzbl -0x27(%ebp),%eax +c0101026: 0f b7 55 da movzwl -0x26(%ebp),%edx +c010102a: ee out %al,(%dx) +} +c010102b: 90 nop +c010102c: 66 c7 45 de f9 03 movw $0x3f9,-0x22(%ebp) +c0101032: c6 45 dd 00 movb $0x0,-0x23(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101036: 0f b6 45 dd movzbl -0x23(%ebp),%eax +c010103a: 0f b7 55 de movzwl -0x22(%ebp),%edx +c010103e: ee out %al,(%dx) +} +c010103f: 90 nop +c0101040: 66 c7 45 e2 fb 03 movw $0x3fb,-0x1e(%ebp) +c0101046: c6 45 e1 03 movb $0x3,-0x1f(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c010104a: 0f b6 45 e1 movzbl -0x1f(%ebp),%eax +c010104e: 0f b7 55 e2 movzwl -0x1e(%ebp),%edx +c0101052: ee out %al,(%dx) +} +c0101053: 90 nop +c0101054: 66 c7 45 e6 fc 03 movw $0x3fc,-0x1a(%ebp) +c010105a: c6 45 e5 00 movb $0x0,-0x1b(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c010105e: 0f b6 45 e5 movzbl -0x1b(%ebp),%eax +c0101062: 0f b7 55 e6 movzwl -0x1a(%ebp),%edx +c0101066: ee out %al,(%dx) +} +c0101067: 90 nop +c0101068: 66 c7 45 ea f9 03 movw $0x3f9,-0x16(%ebp) +c010106e: c6 45 e9 01 movb $0x1,-0x17(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101072: 0f b6 45 e9 movzbl -0x17(%ebp),%eax +c0101076: 0f b7 55 ea movzwl -0x16(%ebp),%edx +c010107a: ee out %al,(%dx) +} +c010107b: 90 nop +c010107c: 66 c7 45 ee fd 03 movw $0x3fd,-0x12(%ebp) + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); +c0101082: 0f b7 45 ee movzwl -0x12(%ebp),%eax +c0101086: 89 c2 mov %eax,%edx +c0101088: ec in (%dx),%al +c0101089: 88 45 ed mov %al,-0x13(%ebp) + return data; +c010108c: 0f b6 45 ed movzbl -0x13(%ebp),%eax + // Enable rcv interrupts + outb(COM1 + COM_IER, COM_IER_RDI); + + // Clear any preexisting overrun indications and interrupts + // Serial port doesn't exist if COM_LSR returns 0xFF + serial_exists = (inb(COM1 + COM_LSR) != 0xFF); +c0101090: 3c ff cmp $0xff,%al +c0101092: 0f 95 c0 setne %al +c0101095: 0f b6 c0 movzbl %al,%eax +c0101098: a3 48 34 1a c0 mov %eax,0xc01a3448 +c010109d: 66 c7 45 f2 fa 03 movw $0x3fa,-0xe(%ebp) + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); +c01010a3: 0f b7 45 f2 movzwl -0xe(%ebp),%eax +c01010a7: 89 c2 mov %eax,%edx +c01010a9: ec in (%dx),%al +c01010aa: 88 45 f1 mov %al,-0xf(%ebp) +c01010ad: 66 c7 45 f6 f8 03 movw $0x3f8,-0xa(%ebp) +c01010b3: 0f b7 45 f6 movzwl -0xa(%ebp),%eax +c01010b7: 89 c2 mov %eax,%edx +c01010b9: ec in (%dx),%al +c01010ba: 88 45 f5 mov %al,-0xb(%ebp) + (void) inb(COM1+COM_IIR); + (void) inb(COM1+COM_RX); + + if (serial_exists) { +c01010bd: a1 48 34 1a c0 mov 0xc01a3448,%eax +c01010c2: 85 c0 test %eax,%eax +c01010c4: 74 0c je c01010d2 + pic_enable(IRQ_COM1); +c01010c6: c7 04 24 04 00 00 00 movl $0x4,(%esp) +c01010cd: e8 84 0f 00 00 call c0102056 + } +} +c01010d2: 90 nop +c01010d3: 89 ec mov %ebp,%esp +c01010d5: 5d pop %ebp +c01010d6: c3 ret + +c01010d7 : + +static void +lpt_putc_sub(int c) { +c01010d7: 55 push %ebp +c01010d8: 89 e5 mov %esp,%ebp +c01010da: 83 ec 20 sub $0x20,%esp + int i; + for (i = 0; !(inb(LPTPORT + 1) & 0x80) && i < 12800; i ++) { +c01010dd: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) +c01010e4: eb 08 jmp c01010ee + delay(); +c01010e6: e8 cc fd ff ff call c0100eb7 + for (i = 0; !(inb(LPTPORT + 1) & 0x80) && i < 12800; i ++) { +c01010eb: ff 45 fc incl -0x4(%ebp) +c01010ee: 66 c7 45 fa 79 03 movw $0x379,-0x6(%ebp) +c01010f4: 0f b7 45 fa movzwl -0x6(%ebp),%eax +c01010f8: 89 c2 mov %eax,%edx +c01010fa: ec in (%dx),%al +c01010fb: 88 45 f9 mov %al,-0x7(%ebp) + return data; +c01010fe: 0f b6 45 f9 movzbl -0x7(%ebp),%eax +c0101102: 84 c0 test %al,%al +c0101104: 78 09 js c010110f +c0101106: 81 7d fc ff 31 00 00 cmpl $0x31ff,-0x4(%ebp) +c010110d: 7e d7 jle c01010e6 + } + outb(LPTPORT + 0, c); +c010110f: 8b 45 08 mov 0x8(%ebp),%eax +c0101112: 0f b6 c0 movzbl %al,%eax +c0101115: 66 c7 45 ee 78 03 movw $0x378,-0x12(%ebp) +c010111b: 88 45 ed mov %al,-0x13(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c010111e: 0f b6 45 ed movzbl -0x13(%ebp),%eax +c0101122: 0f b7 55 ee movzwl -0x12(%ebp),%edx +c0101126: ee out %al,(%dx) +} +c0101127: 90 nop +c0101128: 66 c7 45 f2 7a 03 movw $0x37a,-0xe(%ebp) +c010112e: c6 45 f1 0d movb $0xd,-0xf(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101132: 0f b6 45 f1 movzbl -0xf(%ebp),%eax +c0101136: 0f b7 55 f2 movzwl -0xe(%ebp),%edx +c010113a: ee out %al,(%dx) +} +c010113b: 90 nop +c010113c: 66 c7 45 f6 7a 03 movw $0x37a,-0xa(%ebp) +c0101142: c6 45 f5 08 movb $0x8,-0xb(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101146: 0f b6 45 f5 movzbl -0xb(%ebp),%eax +c010114a: 0f b7 55 f6 movzwl -0xa(%ebp),%edx +c010114e: ee out %al,(%dx) +} +c010114f: 90 nop + outb(LPTPORT + 2, 0x08 | 0x04 | 0x01); + outb(LPTPORT + 2, 0x08); +} +c0101150: 90 nop +c0101151: 89 ec mov %ebp,%esp +c0101153: 5d pop %ebp +c0101154: c3 ret + +c0101155 : + +/* lpt_putc - copy console output to parallel port */ +static void +lpt_putc(int c) { +c0101155: 55 push %ebp +c0101156: 89 e5 mov %esp,%ebp +c0101158: 83 ec 04 sub $0x4,%esp + if (c != '\b') { +c010115b: 83 7d 08 08 cmpl $0x8,0x8(%ebp) +c010115f: 74 0d je c010116e + lpt_putc_sub(c); +c0101161: 8b 45 08 mov 0x8(%ebp),%eax +c0101164: 89 04 24 mov %eax,(%esp) +c0101167: e8 6b ff ff ff call c01010d7 + else { + lpt_putc_sub('\b'); + lpt_putc_sub(' '); + lpt_putc_sub('\b'); + } +} +c010116c: eb 24 jmp c0101192 + lpt_putc_sub('\b'); +c010116e: c7 04 24 08 00 00 00 movl $0x8,(%esp) +c0101175: e8 5d ff ff ff call c01010d7 + lpt_putc_sub(' '); +c010117a: c7 04 24 20 00 00 00 movl $0x20,(%esp) +c0101181: e8 51 ff ff ff call c01010d7 + lpt_putc_sub('\b'); +c0101186: c7 04 24 08 00 00 00 movl $0x8,(%esp) +c010118d: e8 45 ff ff ff call c01010d7 +} +c0101192: 90 nop +c0101193: 89 ec mov %ebp,%esp +c0101195: 5d pop %ebp +c0101196: c3 ret + +c0101197 : + +/* cga_putc - print character to console */ +static void +cga_putc(int c) { +c0101197: 55 push %ebp +c0101198: 89 e5 mov %esp,%ebp +c010119a: 83 ec 38 sub $0x38,%esp +c010119d: 89 5d fc mov %ebx,-0x4(%ebp) + // set black on white + if (!(c & ~0xFF)) { +c01011a0: 8b 45 08 mov 0x8(%ebp),%eax +c01011a3: 25 00 ff ff ff and $0xffffff00,%eax +c01011a8: 85 c0 test %eax,%eax +c01011aa: 75 07 jne c01011b3 + c |= 0x0700; +c01011ac: 81 4d 08 00 07 00 00 orl $0x700,0x8(%ebp) + } + + switch (c & 0xff) { +c01011b3: 8b 45 08 mov 0x8(%ebp),%eax +c01011b6: 0f b6 c0 movzbl %al,%eax +c01011b9: 83 f8 0d cmp $0xd,%eax +c01011bc: 74 72 je c0101230 +c01011be: 83 f8 0d cmp $0xd,%eax +c01011c1: 0f 8f a3 00 00 00 jg c010126a +c01011c7: 83 f8 08 cmp $0x8,%eax +c01011ca: 74 0a je c01011d6 +c01011cc: 83 f8 0a cmp $0xa,%eax +c01011cf: 74 4c je c010121d +c01011d1: e9 94 00 00 00 jmp c010126a + case '\b': + if (crt_pos > 0) { +c01011d6: 0f b7 05 44 34 1a c0 movzwl 0xc01a3444,%eax +c01011dd: 85 c0 test %eax,%eax +c01011df: 0f 84 af 00 00 00 je c0101294 + crt_pos --; +c01011e5: 0f b7 05 44 34 1a c0 movzwl 0xc01a3444,%eax +c01011ec: 48 dec %eax +c01011ed: 0f b7 c0 movzwl %ax,%eax +c01011f0: 66 a3 44 34 1a c0 mov %ax,0xc01a3444 + crt_buf[crt_pos] = (c & ~0xff) | ' '; +c01011f6: 8b 45 08 mov 0x8(%ebp),%eax +c01011f9: 98 cwtl +c01011fa: 25 00 ff ff ff and $0xffffff00,%eax +c01011ff: 98 cwtl +c0101200: 83 c8 20 or $0x20,%eax +c0101203: 98 cwtl +c0101204: 8b 0d 40 34 1a c0 mov 0xc01a3440,%ecx +c010120a: 0f b7 15 44 34 1a c0 movzwl 0xc01a3444,%edx +c0101211: 01 d2 add %edx,%edx +c0101213: 01 ca add %ecx,%edx +c0101215: 0f b7 c0 movzwl %ax,%eax +c0101218: 66 89 02 mov %ax,(%edx) + } + break; +c010121b: eb 77 jmp c0101294 + case '\n': + crt_pos += CRT_COLS; +c010121d: 0f b7 05 44 34 1a c0 movzwl 0xc01a3444,%eax +c0101224: 83 c0 50 add $0x50,%eax +c0101227: 0f b7 c0 movzwl %ax,%eax +c010122a: 66 a3 44 34 1a c0 mov %ax,0xc01a3444 + case '\r': + crt_pos -= (crt_pos % CRT_COLS); +c0101230: 0f b7 1d 44 34 1a c0 movzwl 0xc01a3444,%ebx +c0101237: 0f b7 0d 44 34 1a c0 movzwl 0xc01a3444,%ecx +c010123e: ba cd cc cc cc mov $0xcccccccd,%edx +c0101243: 89 c8 mov %ecx,%eax +c0101245: f7 e2 mul %edx +c0101247: c1 ea 06 shr $0x6,%edx +c010124a: 89 d0 mov %edx,%eax +c010124c: c1 e0 02 shl $0x2,%eax +c010124f: 01 d0 add %edx,%eax +c0101251: c1 e0 04 shl $0x4,%eax +c0101254: 29 c1 sub %eax,%ecx +c0101256: 89 ca mov %ecx,%edx +c0101258: 0f b7 d2 movzwl %dx,%edx +c010125b: 89 d8 mov %ebx,%eax +c010125d: 29 d0 sub %edx,%eax +c010125f: 0f b7 c0 movzwl %ax,%eax +c0101262: 66 a3 44 34 1a c0 mov %ax,0xc01a3444 + break; +c0101268: eb 2b jmp c0101295 + default: + crt_buf[crt_pos ++] = c; // write the character +c010126a: 8b 0d 40 34 1a c0 mov 0xc01a3440,%ecx +c0101270: 0f b7 05 44 34 1a c0 movzwl 0xc01a3444,%eax +c0101277: 8d 50 01 lea 0x1(%eax),%edx +c010127a: 0f b7 d2 movzwl %dx,%edx +c010127d: 66 89 15 44 34 1a c0 mov %dx,0xc01a3444 +c0101284: 01 c0 add %eax,%eax +c0101286: 8d 14 01 lea (%ecx,%eax,1),%edx +c0101289: 8b 45 08 mov 0x8(%ebp),%eax +c010128c: 0f b7 c0 movzwl %ax,%eax +c010128f: 66 89 02 mov %ax,(%edx) + break; +c0101292: eb 01 jmp c0101295 + break; +c0101294: 90 nop + } + + // What is the purpose of this? + if (crt_pos >= CRT_SIZE) { +c0101295: 0f b7 05 44 34 1a c0 movzwl 0xc01a3444,%eax +c010129c: 3d cf 07 00 00 cmp $0x7cf,%eax +c01012a1: 76 5e jbe c0101301 + int i; + memmove(crt_buf, crt_buf + CRT_COLS, (CRT_SIZE - CRT_COLS) * sizeof(uint16_t)); +c01012a3: a1 40 34 1a c0 mov 0xc01a3440,%eax +c01012a8: 8d 90 a0 00 00 00 lea 0xa0(%eax),%edx +c01012ae: a1 40 34 1a c0 mov 0xc01a3440,%eax +c01012b3: c7 44 24 08 00 0f 00 movl $0xf00,0x8(%esp) +c01012ba: 00 +c01012bb: 89 54 24 04 mov %edx,0x4(%esp) +c01012bf: 89 04 24 mov %eax,(%esp) +c01012c2: e8 6c ab 00 00 call c010be33 + for (i = CRT_SIZE - CRT_COLS; i < CRT_SIZE; i ++) { +c01012c7: c7 45 f4 80 07 00 00 movl $0x780,-0xc(%ebp) +c01012ce: eb 15 jmp c01012e5 + crt_buf[i] = 0x0700 | ' '; +c01012d0: 8b 15 40 34 1a c0 mov 0xc01a3440,%edx +c01012d6: 8b 45 f4 mov -0xc(%ebp),%eax +c01012d9: 01 c0 add %eax,%eax +c01012db: 01 d0 add %edx,%eax +c01012dd: 66 c7 00 20 07 movw $0x720,(%eax) + for (i = CRT_SIZE - CRT_COLS; i < CRT_SIZE; i ++) { +c01012e2: ff 45 f4 incl -0xc(%ebp) +c01012e5: 81 7d f4 cf 07 00 00 cmpl $0x7cf,-0xc(%ebp) +c01012ec: 7e e2 jle c01012d0 + } + crt_pos -= CRT_COLS; +c01012ee: 0f b7 05 44 34 1a c0 movzwl 0xc01a3444,%eax +c01012f5: 83 e8 50 sub $0x50,%eax +c01012f8: 0f b7 c0 movzwl %ax,%eax +c01012fb: 66 a3 44 34 1a c0 mov %ax,0xc01a3444 + } + + // move that little blinky thing + outb(addr_6845, 14); +c0101301: 0f b7 05 46 34 1a c0 movzwl 0xc01a3446,%eax +c0101308: 66 89 45 e6 mov %ax,-0x1a(%ebp) +c010130c: c6 45 e5 0e movb $0xe,-0x1b(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101310: 0f b6 45 e5 movzbl -0x1b(%ebp),%eax +c0101314: 0f b7 55 e6 movzwl -0x1a(%ebp),%edx +c0101318: ee out %al,(%dx) +} +c0101319: 90 nop + outb(addr_6845 + 1, crt_pos >> 8); +c010131a: 0f b7 05 44 34 1a c0 movzwl 0xc01a3444,%eax +c0101321: c1 e8 08 shr $0x8,%eax +c0101324: 0f b7 c0 movzwl %ax,%eax +c0101327: 0f b6 c0 movzbl %al,%eax +c010132a: 0f b7 15 46 34 1a c0 movzwl 0xc01a3446,%edx +c0101331: 42 inc %edx +c0101332: 0f b7 d2 movzwl %dx,%edx +c0101335: 66 89 55 ea mov %dx,-0x16(%ebp) +c0101339: 88 45 e9 mov %al,-0x17(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c010133c: 0f b6 45 e9 movzbl -0x17(%ebp),%eax +c0101340: 0f b7 55 ea movzwl -0x16(%ebp),%edx +c0101344: ee out %al,(%dx) +} +c0101345: 90 nop + outb(addr_6845, 15); +c0101346: 0f b7 05 46 34 1a c0 movzwl 0xc01a3446,%eax +c010134d: 66 89 45 ee mov %ax,-0x12(%ebp) +c0101351: c6 45 ed 0f movb $0xf,-0x13(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101355: 0f b6 45 ed movzbl -0x13(%ebp),%eax +c0101359: 0f b7 55 ee movzwl -0x12(%ebp),%edx +c010135d: ee out %al,(%dx) +} +c010135e: 90 nop + outb(addr_6845 + 1, crt_pos); +c010135f: 0f b7 05 44 34 1a c0 movzwl 0xc01a3444,%eax +c0101366: 0f b6 c0 movzbl %al,%eax +c0101369: 0f b7 15 46 34 1a c0 movzwl 0xc01a3446,%edx +c0101370: 42 inc %edx +c0101371: 0f b7 d2 movzwl %dx,%edx +c0101374: 66 89 55 f2 mov %dx,-0xe(%ebp) +c0101378: 88 45 f1 mov %al,-0xf(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c010137b: 0f b6 45 f1 movzbl -0xf(%ebp),%eax +c010137f: 0f b7 55 f2 movzwl -0xe(%ebp),%edx +c0101383: ee out %al,(%dx) +} +c0101384: 90 nop +} +c0101385: 90 nop +c0101386: 8b 5d fc mov -0x4(%ebp),%ebx +c0101389: 89 ec mov %ebp,%esp +c010138b: 5d pop %ebp +c010138c: c3 ret + +c010138d : + +static void +serial_putc_sub(int c) { +c010138d: 55 push %ebp +c010138e: 89 e5 mov %esp,%ebp +c0101390: 83 ec 10 sub $0x10,%esp + int i; + for (i = 0; !(inb(COM1 + COM_LSR) & COM_LSR_TXRDY) && i < 12800; i ++) { +c0101393: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) +c010139a: eb 08 jmp c01013a4 + delay(); +c010139c: e8 16 fb ff ff call c0100eb7 + for (i = 0; !(inb(COM1 + COM_LSR) & COM_LSR_TXRDY) && i < 12800; i ++) { +c01013a1: ff 45 fc incl -0x4(%ebp) +c01013a4: 66 c7 45 fa fd 03 movw $0x3fd,-0x6(%ebp) + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); +c01013aa: 0f b7 45 fa movzwl -0x6(%ebp),%eax +c01013ae: 89 c2 mov %eax,%edx +c01013b0: ec in (%dx),%al +c01013b1: 88 45 f9 mov %al,-0x7(%ebp) + return data; +c01013b4: 0f b6 45 f9 movzbl -0x7(%ebp),%eax +c01013b8: 0f b6 c0 movzbl %al,%eax +c01013bb: 83 e0 20 and $0x20,%eax +c01013be: 85 c0 test %eax,%eax +c01013c0: 75 09 jne c01013cb +c01013c2: 81 7d fc ff 31 00 00 cmpl $0x31ff,-0x4(%ebp) +c01013c9: 7e d1 jle c010139c + } + outb(COM1 + COM_TX, c); +c01013cb: 8b 45 08 mov 0x8(%ebp),%eax +c01013ce: 0f b6 c0 movzbl %al,%eax +c01013d1: 66 c7 45 f6 f8 03 movw $0x3f8,-0xa(%ebp) +c01013d7: 88 45 f5 mov %al,-0xb(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c01013da: 0f b6 45 f5 movzbl -0xb(%ebp),%eax +c01013de: 0f b7 55 f6 movzwl -0xa(%ebp),%edx +c01013e2: ee out %al,(%dx) +} +c01013e3: 90 nop +} +c01013e4: 90 nop +c01013e5: 89 ec mov %ebp,%esp +c01013e7: 5d pop %ebp +c01013e8: c3 ret + +c01013e9 : + +/* serial_putc - print character to serial port */ +static void +serial_putc(int c) { +c01013e9: 55 push %ebp +c01013ea: 89 e5 mov %esp,%ebp +c01013ec: 83 ec 04 sub $0x4,%esp + if (c != '\b') { +c01013ef: 83 7d 08 08 cmpl $0x8,0x8(%ebp) +c01013f3: 74 0d je c0101402 + serial_putc_sub(c); +c01013f5: 8b 45 08 mov 0x8(%ebp),%eax +c01013f8: 89 04 24 mov %eax,(%esp) +c01013fb: e8 8d ff ff ff call c010138d + else { + serial_putc_sub('\b'); + serial_putc_sub(' '); + serial_putc_sub('\b'); + } +} +c0101400: eb 24 jmp c0101426 + serial_putc_sub('\b'); +c0101402: c7 04 24 08 00 00 00 movl $0x8,(%esp) +c0101409: e8 7f ff ff ff call c010138d + serial_putc_sub(' '); +c010140e: c7 04 24 20 00 00 00 movl $0x20,(%esp) +c0101415: e8 73 ff ff ff call c010138d + serial_putc_sub('\b'); +c010141a: c7 04 24 08 00 00 00 movl $0x8,(%esp) +c0101421: e8 67 ff ff ff call c010138d +} +c0101426: 90 nop +c0101427: 89 ec mov %ebp,%esp +c0101429: 5d pop %ebp +c010142a: c3 ret + +c010142b : +/* * + * cons_intr - called by device interrupt routines to feed input + * characters into the circular console input buffer. + * */ +static void +cons_intr(int (*proc)(void)) { +c010142b: 55 push %ebp +c010142c: 89 e5 mov %esp,%ebp +c010142e: 83 ec 18 sub $0x18,%esp + int c; + while ((c = (*proc)()) != -1) { +c0101431: eb 33 jmp c0101466 + if (c != 0) { +c0101433: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c0101437: 74 2d je c0101466 + cons.buf[cons.wpos ++] = c; +c0101439: a1 64 36 1a c0 mov 0xc01a3664,%eax +c010143e: 8d 50 01 lea 0x1(%eax),%edx +c0101441: 89 15 64 36 1a c0 mov %edx,0xc01a3664 +c0101447: 8b 55 f4 mov -0xc(%ebp),%edx +c010144a: 88 90 60 34 1a c0 mov %dl,-0x3fe5cba0(%eax) + if (cons.wpos == CONSBUFSIZE) { +c0101450: a1 64 36 1a c0 mov 0xc01a3664,%eax +c0101455: 3d 00 02 00 00 cmp $0x200,%eax +c010145a: 75 0a jne c0101466 + cons.wpos = 0; +c010145c: c7 05 64 36 1a c0 00 movl $0x0,0xc01a3664 +c0101463: 00 00 00 + while ((c = (*proc)()) != -1) { +c0101466: 8b 45 08 mov 0x8(%ebp),%eax +c0101469: ff d0 call *%eax +c010146b: 89 45 f4 mov %eax,-0xc(%ebp) +c010146e: 83 7d f4 ff cmpl $0xffffffff,-0xc(%ebp) +c0101472: 75 bf jne c0101433 + } + } + } +} +c0101474: 90 nop +c0101475: 90 nop +c0101476: 89 ec mov %ebp,%esp +c0101478: 5d pop %ebp +c0101479: c3 ret + +c010147a : + +/* serial_proc_data - get data from serial port */ +static int +serial_proc_data(void) { +c010147a: 55 push %ebp +c010147b: 89 e5 mov %esp,%ebp +c010147d: 83 ec 10 sub $0x10,%esp +c0101480: 66 c7 45 fa fd 03 movw $0x3fd,-0x6(%ebp) + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); +c0101486: 0f b7 45 fa movzwl -0x6(%ebp),%eax +c010148a: 89 c2 mov %eax,%edx +c010148c: ec in (%dx),%al +c010148d: 88 45 f9 mov %al,-0x7(%ebp) + return data; +c0101490: 0f b6 45 f9 movzbl -0x7(%ebp),%eax + if (!(inb(COM1 + COM_LSR) & COM_LSR_DATA)) { +c0101494: 0f b6 c0 movzbl %al,%eax +c0101497: 83 e0 01 and $0x1,%eax +c010149a: 85 c0 test %eax,%eax +c010149c: 75 07 jne c01014a5 + return -1; +c010149e: b8 ff ff ff ff mov $0xffffffff,%eax +c01014a3: eb 2a jmp c01014cf +c01014a5: 66 c7 45 f6 f8 03 movw $0x3f8,-0xa(%ebp) + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); +c01014ab: 0f b7 45 f6 movzwl -0xa(%ebp),%eax +c01014af: 89 c2 mov %eax,%edx +c01014b1: ec in (%dx),%al +c01014b2: 88 45 f5 mov %al,-0xb(%ebp) + return data; +c01014b5: 0f b6 45 f5 movzbl -0xb(%ebp),%eax + } + int c = inb(COM1 + COM_RX); +c01014b9: 0f b6 c0 movzbl %al,%eax +c01014bc: 89 45 fc mov %eax,-0x4(%ebp) + if (c == 127) { +c01014bf: 83 7d fc 7f cmpl $0x7f,-0x4(%ebp) +c01014c3: 75 07 jne c01014cc + c = '\b'; +c01014c5: c7 45 fc 08 00 00 00 movl $0x8,-0x4(%ebp) + } + return c; +c01014cc: 8b 45 fc mov -0x4(%ebp),%eax +} +c01014cf: 89 ec mov %ebp,%esp +c01014d1: 5d pop %ebp +c01014d2: c3 ret + +c01014d3 : + +/* serial_intr - try to feed input characters from serial port */ +void +serial_intr(void) { +c01014d3: 55 push %ebp +c01014d4: 89 e5 mov %esp,%ebp +c01014d6: 83 ec 18 sub $0x18,%esp + if (serial_exists) { +c01014d9: a1 48 34 1a c0 mov 0xc01a3448,%eax +c01014de: 85 c0 test %eax,%eax +c01014e0: 74 0c je c01014ee + cons_intr(serial_proc_data); +c01014e2: c7 04 24 7a 14 10 c0 movl $0xc010147a,(%esp) +c01014e9: e8 3d ff ff ff call c010142b + } +} +c01014ee: 90 nop +c01014ef: 89 ec mov %ebp,%esp +c01014f1: 5d pop %ebp +c01014f2: c3 ret + +c01014f3 : + * + * The kbd_proc_data() function gets data from the keyboard. + * If we finish a character, return it, else 0. And return -1 if no data. + * */ +static int +kbd_proc_data(void) { +c01014f3: 55 push %ebp +c01014f4: 89 e5 mov %esp,%ebp +c01014f6: 83 ec 38 sub $0x38,%esp +c01014f9: 66 c7 45 f0 64 00 movw $0x64,-0x10(%ebp) + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); +c01014ff: 8b 45 f0 mov -0x10(%ebp),%eax +c0101502: 89 c2 mov %eax,%edx +c0101504: ec in (%dx),%al +c0101505: 88 45 ef mov %al,-0x11(%ebp) + return data; +c0101508: 0f b6 45 ef movzbl -0x11(%ebp),%eax + int c; + uint8_t data; + static uint32_t shift; + + if ((inb(KBSTATP) & KBS_DIB) == 0) { +c010150c: 0f b6 c0 movzbl %al,%eax +c010150f: 83 e0 01 and $0x1,%eax +c0101512: 85 c0 test %eax,%eax +c0101514: 75 0a jne c0101520 + return -1; +c0101516: b8 ff ff ff ff mov $0xffffffff,%eax +c010151b: e9 56 01 00 00 jmp c0101676 +c0101520: 66 c7 45 ec 60 00 movw $0x60,-0x14(%ebp) + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); +c0101526: 8b 45 ec mov -0x14(%ebp),%eax +c0101529: 89 c2 mov %eax,%edx +c010152b: ec in (%dx),%al +c010152c: 88 45 eb mov %al,-0x15(%ebp) + return data; +c010152f: 0f b6 45 eb movzbl -0x15(%ebp),%eax + } + + data = inb(KBDATAP); +c0101533: 88 45 f3 mov %al,-0xd(%ebp) + + if (data == 0xE0) { +c0101536: 80 7d f3 e0 cmpb $0xe0,-0xd(%ebp) +c010153a: 75 17 jne c0101553 + // E0 escape character + shift |= E0ESC; +c010153c: a1 68 36 1a c0 mov 0xc01a3668,%eax +c0101541: 83 c8 40 or $0x40,%eax +c0101544: a3 68 36 1a c0 mov %eax,0xc01a3668 + return 0; +c0101549: b8 00 00 00 00 mov $0x0,%eax +c010154e: e9 23 01 00 00 jmp c0101676 + } else if (data & 0x80) { +c0101553: 0f b6 45 f3 movzbl -0xd(%ebp),%eax +c0101557: 84 c0 test %al,%al +c0101559: 79 45 jns c01015a0 + // Key released + data = (shift & E0ESC ? data : data & 0x7F); +c010155b: a1 68 36 1a c0 mov 0xc01a3668,%eax +c0101560: 83 e0 40 and $0x40,%eax +c0101563: 85 c0 test %eax,%eax +c0101565: 75 08 jne c010156f +c0101567: 0f b6 45 f3 movzbl -0xd(%ebp),%eax +c010156b: 24 7f and $0x7f,%al +c010156d: eb 04 jmp c0101573 +c010156f: 0f b6 45 f3 movzbl -0xd(%ebp),%eax +c0101573: 88 45 f3 mov %al,-0xd(%ebp) + shift &= ~(shiftcode[data] | E0ESC); +c0101576: 0f b6 45 f3 movzbl -0xd(%ebp),%eax +c010157a: 0f b6 80 40 f0 12 c0 movzbl -0x3fed0fc0(%eax),%eax +c0101581: 0c 40 or $0x40,%al +c0101583: 0f b6 c0 movzbl %al,%eax +c0101586: f7 d0 not %eax +c0101588: 89 c2 mov %eax,%edx +c010158a: a1 68 36 1a c0 mov 0xc01a3668,%eax +c010158f: 21 d0 and %edx,%eax +c0101591: a3 68 36 1a c0 mov %eax,0xc01a3668 + return 0; +c0101596: b8 00 00 00 00 mov $0x0,%eax +c010159b: e9 d6 00 00 00 jmp c0101676 + } else if (shift & E0ESC) { +c01015a0: a1 68 36 1a c0 mov 0xc01a3668,%eax +c01015a5: 83 e0 40 and $0x40,%eax +c01015a8: 85 c0 test %eax,%eax +c01015aa: 74 11 je c01015bd + // Last character was an E0 escape; or with 0x80 + data |= 0x80; +c01015ac: 80 4d f3 80 orb $0x80,-0xd(%ebp) + shift &= ~E0ESC; +c01015b0: a1 68 36 1a c0 mov 0xc01a3668,%eax +c01015b5: 83 e0 bf and $0xffffffbf,%eax +c01015b8: a3 68 36 1a c0 mov %eax,0xc01a3668 + } + + shift |= shiftcode[data]; +c01015bd: 0f b6 45 f3 movzbl -0xd(%ebp),%eax +c01015c1: 0f b6 80 40 f0 12 c0 movzbl -0x3fed0fc0(%eax),%eax +c01015c8: 0f b6 d0 movzbl %al,%edx +c01015cb: a1 68 36 1a c0 mov 0xc01a3668,%eax +c01015d0: 09 d0 or %edx,%eax +c01015d2: a3 68 36 1a c0 mov %eax,0xc01a3668 + shift ^= togglecode[data]; +c01015d7: 0f b6 45 f3 movzbl -0xd(%ebp),%eax +c01015db: 0f b6 80 40 f1 12 c0 movzbl -0x3fed0ec0(%eax),%eax +c01015e2: 0f b6 d0 movzbl %al,%edx +c01015e5: a1 68 36 1a c0 mov 0xc01a3668,%eax +c01015ea: 31 d0 xor %edx,%eax +c01015ec: a3 68 36 1a c0 mov %eax,0xc01a3668 + + c = charcode[shift & (CTL | SHIFT)][data]; +c01015f1: a1 68 36 1a c0 mov 0xc01a3668,%eax +c01015f6: 83 e0 03 and $0x3,%eax +c01015f9: 8b 14 85 40 f5 12 c0 mov -0x3fed0ac0(,%eax,4),%edx +c0101600: 0f b6 45 f3 movzbl -0xd(%ebp),%eax +c0101604: 01 d0 add %edx,%eax +c0101606: 0f b6 00 movzbl (%eax),%eax +c0101609: 0f b6 c0 movzbl %al,%eax +c010160c: 89 45 f4 mov %eax,-0xc(%ebp) + if (shift & CAPSLOCK) { +c010160f: a1 68 36 1a c0 mov 0xc01a3668,%eax +c0101614: 83 e0 08 and $0x8,%eax +c0101617: 85 c0 test %eax,%eax +c0101619: 74 22 je c010163d + if ('a' <= c && c <= 'z') +c010161b: 83 7d f4 60 cmpl $0x60,-0xc(%ebp) +c010161f: 7e 0c jle c010162d +c0101621: 83 7d f4 7a cmpl $0x7a,-0xc(%ebp) +c0101625: 7f 06 jg c010162d + c += 'A' - 'a'; +c0101627: 83 6d f4 20 subl $0x20,-0xc(%ebp) +c010162b: eb 10 jmp c010163d + else if ('A' <= c && c <= 'Z') +c010162d: 83 7d f4 40 cmpl $0x40,-0xc(%ebp) +c0101631: 7e 0a jle c010163d +c0101633: 83 7d f4 5a cmpl $0x5a,-0xc(%ebp) +c0101637: 7f 04 jg c010163d + c += 'a' - 'A'; +c0101639: 83 45 f4 20 addl $0x20,-0xc(%ebp) + } + + // Process special keys + // Ctrl-Alt-Del: reboot + if (!(~shift & (CTL | ALT)) && c == KEY_DEL) { +c010163d: a1 68 36 1a c0 mov 0xc01a3668,%eax +c0101642: f7 d0 not %eax +c0101644: 83 e0 06 and $0x6,%eax +c0101647: 85 c0 test %eax,%eax +c0101649: 75 28 jne c0101673 +c010164b: 81 7d f4 e9 00 00 00 cmpl $0xe9,-0xc(%ebp) +c0101652: 75 1f jne c0101673 + cprintf("Rebooting!\n"); +c0101654: c7 04 24 87 c2 10 c0 movl $0xc010c287,(%esp) +c010165b: e8 18 ed ff ff call c0100378 +c0101660: 66 c7 45 e8 92 00 movw $0x92,-0x18(%ebp) +c0101666: c6 45 e7 03 movb $0x3,-0x19(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c010166a: 0f b6 45 e7 movzbl -0x19(%ebp),%eax +c010166e: 8b 55 e8 mov -0x18(%ebp),%edx +c0101671: ee out %al,(%dx) +} +c0101672: 90 nop + outb(0x92, 0x3); // courtesy of Chris Frost + } + return c; +c0101673: 8b 45 f4 mov -0xc(%ebp),%eax +} +c0101676: 89 ec mov %ebp,%esp +c0101678: 5d pop %ebp +c0101679: c3 ret + +c010167a : + +/* kbd_intr - try to feed input characters from keyboard */ +static void +kbd_intr(void) { +c010167a: 55 push %ebp +c010167b: 89 e5 mov %esp,%ebp +c010167d: 83 ec 18 sub $0x18,%esp + cons_intr(kbd_proc_data); +c0101680: c7 04 24 f3 14 10 c0 movl $0xc01014f3,(%esp) +c0101687: e8 9f fd ff ff call c010142b +} +c010168c: 90 nop +c010168d: 89 ec mov %ebp,%esp +c010168f: 5d pop %ebp +c0101690: c3 ret + +c0101691 : + +static void +kbd_init(void) { +c0101691: 55 push %ebp +c0101692: 89 e5 mov %esp,%ebp +c0101694: 83 ec 18 sub $0x18,%esp + // drain the kbd buffer + kbd_intr(); +c0101697: e8 de ff ff ff call c010167a + pic_enable(IRQ_KBD); +c010169c: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c01016a3: e8 ae 09 00 00 call c0102056 +} +c01016a8: 90 nop +c01016a9: 89 ec mov %ebp,%esp +c01016ab: 5d pop %ebp +c01016ac: c3 ret + +c01016ad : + +/* cons_init - initializes the console devices */ +void +cons_init(void) { +c01016ad: 55 push %ebp +c01016ae: 89 e5 mov %esp,%ebp +c01016b0: 83 ec 18 sub $0x18,%esp + cga_init(); +c01016b3: e8 4a f8 ff ff call c0100f02 + serial_init(); +c01016b8: e8 2d f9 ff ff call c0100fea + kbd_init(); +c01016bd: e8 cf ff ff ff call c0101691 + if (!serial_exists) { +c01016c2: a1 48 34 1a c0 mov 0xc01a3448,%eax +c01016c7: 85 c0 test %eax,%eax +c01016c9: 75 0c jne c01016d7 + cprintf("serial port does not exist!!\n"); +c01016cb: c7 04 24 93 c2 10 c0 movl $0xc010c293,(%esp) +c01016d2: e8 a1 ec ff ff call c0100378 + } +} +c01016d7: 90 nop +c01016d8: 89 ec mov %ebp,%esp +c01016da: 5d pop %ebp +c01016db: c3 ret + +c01016dc : + +/* cons_putc - print a single character @c to console devices */ +void +cons_putc(int c) { +c01016dc: 55 push %ebp +c01016dd: 89 e5 mov %esp,%ebp +c01016df: 83 ec 28 sub $0x28,%esp + bool intr_flag; + local_intr_save(intr_flag); +c01016e2: e8 8e f7 ff ff call c0100e75 <__intr_save> +c01016e7: 89 45 f4 mov %eax,-0xc(%ebp) + { + lpt_putc(c); +c01016ea: 8b 45 08 mov 0x8(%ebp),%eax +c01016ed: 89 04 24 mov %eax,(%esp) +c01016f0: e8 60 fa ff ff call c0101155 + cga_putc(c); +c01016f5: 8b 45 08 mov 0x8(%ebp),%eax +c01016f8: 89 04 24 mov %eax,(%esp) +c01016fb: e8 97 fa ff ff call c0101197 + serial_putc(c); +c0101700: 8b 45 08 mov 0x8(%ebp),%eax +c0101703: 89 04 24 mov %eax,(%esp) +c0101706: e8 de fc ff ff call c01013e9 + } + local_intr_restore(intr_flag); +c010170b: 8b 45 f4 mov -0xc(%ebp),%eax +c010170e: 89 04 24 mov %eax,(%esp) +c0101711: e8 8b f7 ff ff call c0100ea1 <__intr_restore> +} +c0101716: 90 nop +c0101717: 89 ec mov %ebp,%esp +c0101719: 5d pop %ebp +c010171a: c3 ret + +c010171b : +/* * + * cons_getc - return the next input character from console, + * or 0 if none waiting. + * */ +int +cons_getc(void) { +c010171b: 55 push %ebp +c010171c: 89 e5 mov %esp,%ebp +c010171e: 83 ec 28 sub $0x28,%esp + int c = 0; +c0101721: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + bool intr_flag; + local_intr_save(intr_flag); +c0101728: e8 48 f7 ff ff call c0100e75 <__intr_save> +c010172d: 89 45 f0 mov %eax,-0x10(%ebp) + { + // poll for any pending input characters, + // so that this function works even when interrupts are disabled + // (e.g., when called from the kernel monitor). + serial_intr(); +c0101730: e8 9e fd ff ff call c01014d3 + kbd_intr(); +c0101735: e8 40 ff ff ff call c010167a + + // grab the next character from the input buffer. + if (cons.rpos != cons.wpos) { +c010173a: 8b 15 60 36 1a c0 mov 0xc01a3660,%edx +c0101740: a1 64 36 1a c0 mov 0xc01a3664,%eax +c0101745: 39 c2 cmp %eax,%edx +c0101747: 74 31 je c010177a + c = cons.buf[cons.rpos ++]; +c0101749: a1 60 36 1a c0 mov 0xc01a3660,%eax +c010174e: 8d 50 01 lea 0x1(%eax),%edx +c0101751: 89 15 60 36 1a c0 mov %edx,0xc01a3660 +c0101757: 0f b6 80 60 34 1a c0 movzbl -0x3fe5cba0(%eax),%eax +c010175e: 0f b6 c0 movzbl %al,%eax +c0101761: 89 45 f4 mov %eax,-0xc(%ebp) + if (cons.rpos == CONSBUFSIZE) { +c0101764: a1 60 36 1a c0 mov 0xc01a3660,%eax +c0101769: 3d 00 02 00 00 cmp $0x200,%eax +c010176e: 75 0a jne c010177a + cons.rpos = 0; +c0101770: c7 05 60 36 1a c0 00 movl $0x0,0xc01a3660 +c0101777: 00 00 00 + } + } + } + local_intr_restore(intr_flag); +c010177a: 8b 45 f0 mov -0x10(%ebp),%eax +c010177d: 89 04 24 mov %eax,(%esp) +c0101780: e8 1c f7 ff ff call c0100ea1 <__intr_restore> + return c; +c0101785: 8b 45 f4 mov -0xc(%ebp),%eax +} +c0101788: 89 ec mov %ebp,%esp +c010178a: 5d pop %ebp +c010178b: c3 ret + +c010178c : + unsigned int size; // Size in Sectors + unsigned char model[41]; // Model in String +} ide_devices[MAX_IDE]; + +static int +ide_wait_ready(unsigned short iobase, bool check_error) { +c010178c: 55 push %ebp +c010178d: 89 e5 mov %esp,%ebp +c010178f: 83 ec 14 sub $0x14,%esp +c0101792: 8b 45 08 mov 0x8(%ebp),%eax +c0101795: 66 89 45 ec mov %ax,-0x14(%ebp) + int r; + while ((r = inb(iobase + ISA_STATUS)) & IDE_BSY) +c0101799: 90 nop +c010179a: 8b 45 ec mov -0x14(%ebp),%eax +c010179d: 83 c0 07 add $0x7,%eax +c01017a0: 0f b7 c0 movzwl %ax,%eax +c01017a3: 66 89 45 fa mov %ax,-0x6(%ebp) + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); +c01017a7: 0f b7 45 fa movzwl -0x6(%ebp),%eax +c01017ab: 89 c2 mov %eax,%edx +c01017ad: ec in (%dx),%al +c01017ae: 88 45 f9 mov %al,-0x7(%ebp) + return data; +c01017b1: 0f b6 45 f9 movzbl -0x7(%ebp),%eax +c01017b5: 0f b6 c0 movzbl %al,%eax +c01017b8: 89 45 fc mov %eax,-0x4(%ebp) +c01017bb: 8b 45 fc mov -0x4(%ebp),%eax +c01017be: 25 80 00 00 00 and $0x80,%eax +c01017c3: 85 c0 test %eax,%eax +c01017c5: 75 d3 jne c010179a + /* nothing */; + if (check_error && (r & (IDE_DF | IDE_ERR)) != 0) { +c01017c7: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) +c01017cb: 74 11 je c01017de +c01017cd: 8b 45 fc mov -0x4(%ebp),%eax +c01017d0: 83 e0 21 and $0x21,%eax +c01017d3: 85 c0 test %eax,%eax +c01017d5: 74 07 je c01017de + return -1; +c01017d7: b8 ff ff ff ff mov $0xffffffff,%eax +c01017dc: eb 05 jmp c01017e3 + } + return 0; +c01017de: b8 00 00 00 00 mov $0x0,%eax +} +c01017e3: 89 ec mov %ebp,%esp +c01017e5: 5d pop %ebp +c01017e6: c3 ret + +c01017e7 : + +void +ide_init(void) { +c01017e7: 55 push %ebp +c01017e8: 89 e5 mov %esp,%ebp +c01017ea: 57 push %edi +c01017eb: 53 push %ebx +c01017ec: 81 ec 50 02 00 00 sub $0x250,%esp + static_assert((SECTSIZE % 4) == 0); + unsigned short ideno, iobase; + for (ideno = 0; ideno < MAX_IDE; ideno ++) { +c01017f2: 66 c7 45 f6 00 00 movw $0x0,-0xa(%ebp) +c01017f8: e9 bd 02 00 00 jmp c0101aba + /* assume that no device here */ + ide_devices[ideno].valid = 0; +c01017fd: 0f b7 55 f6 movzwl -0xa(%ebp),%edx +c0101801: 89 d0 mov %edx,%eax +c0101803: c1 e0 03 shl $0x3,%eax +c0101806: 29 d0 sub %edx,%eax +c0101808: c1 e0 03 shl $0x3,%eax +c010180b: 05 80 36 1a c0 add $0xc01a3680,%eax +c0101810: c6 00 00 movb $0x0,(%eax) + + iobase = IO_BASE(ideno); +c0101813: 0f b7 45 f6 movzwl -0xa(%ebp),%eax +c0101817: d1 e8 shr %eax +c0101819: 0f b7 c0 movzwl %ax,%eax +c010181c: 8b 04 85 b4 c2 10 c0 mov -0x3fef3d4c(,%eax,4),%eax +c0101823: 66 89 45 ea mov %ax,-0x16(%ebp) + + /* wait device ready */ + ide_wait_ready(iobase, 0); +c0101827: 0f b7 45 ea movzwl -0x16(%ebp),%eax +c010182b: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) +c0101832: 00 +c0101833: 89 04 24 mov %eax,(%esp) +c0101836: e8 51 ff ff ff call c010178c + + /* step1: select drive */ + outb(iobase + ISA_SDH, 0xE0 | ((ideno & 1) << 4)); +c010183b: 0f b7 45 f6 movzwl -0xa(%ebp),%eax +c010183f: c1 e0 04 shl $0x4,%eax +c0101842: 24 10 and $0x10,%al +c0101844: 0c e0 or $0xe0,%al +c0101846: 0f b6 c0 movzbl %al,%eax +c0101849: 0f b7 55 ea movzwl -0x16(%ebp),%edx +c010184d: 83 c2 06 add $0x6,%edx +c0101850: 0f b7 d2 movzwl %dx,%edx +c0101853: 66 89 55 ca mov %dx,-0x36(%ebp) +c0101857: 88 45 c9 mov %al,-0x37(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c010185a: 0f b6 45 c9 movzbl -0x37(%ebp),%eax +c010185e: 0f b7 55 ca movzwl -0x36(%ebp),%edx +c0101862: ee out %al,(%dx) +} +c0101863: 90 nop + ide_wait_ready(iobase, 0); +c0101864: 0f b7 45 ea movzwl -0x16(%ebp),%eax +c0101868: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) +c010186f: 00 +c0101870: 89 04 24 mov %eax,(%esp) +c0101873: e8 14 ff ff ff call c010178c + + /* step2: send ATA identify command */ + outb(iobase + ISA_COMMAND, IDE_CMD_IDENTIFY); +c0101878: 0f b7 45 ea movzwl -0x16(%ebp),%eax +c010187c: 83 c0 07 add $0x7,%eax +c010187f: 0f b7 c0 movzwl %ax,%eax +c0101882: 66 89 45 ce mov %ax,-0x32(%ebp) +c0101886: c6 45 cd ec movb $0xec,-0x33(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c010188a: 0f b6 45 cd movzbl -0x33(%ebp),%eax +c010188e: 0f b7 55 ce movzwl -0x32(%ebp),%edx +c0101892: ee out %al,(%dx) +} +c0101893: 90 nop + ide_wait_ready(iobase, 0); +c0101894: 0f b7 45 ea movzwl -0x16(%ebp),%eax +c0101898: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) +c010189f: 00 +c01018a0: 89 04 24 mov %eax,(%esp) +c01018a3: e8 e4 fe ff ff call c010178c + + /* step3: polling */ + if (inb(iobase + ISA_STATUS) == 0 || ide_wait_ready(iobase, 1) != 0) { +c01018a8: 0f b7 45 ea movzwl -0x16(%ebp),%eax +c01018ac: 83 c0 07 add $0x7,%eax +c01018af: 0f b7 c0 movzwl %ax,%eax +c01018b2: 66 89 45 d2 mov %ax,-0x2e(%ebp) + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); +c01018b6: 0f b7 45 d2 movzwl -0x2e(%ebp),%eax +c01018ba: 89 c2 mov %eax,%edx +c01018bc: ec in (%dx),%al +c01018bd: 88 45 d1 mov %al,-0x2f(%ebp) + return data; +c01018c0: 0f b6 45 d1 movzbl -0x2f(%ebp),%eax +c01018c4: 84 c0 test %al,%al +c01018c6: 0f 84 e4 01 00 00 je c0101ab0 +c01018cc: 0f b7 45 ea movzwl -0x16(%ebp),%eax +c01018d0: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c01018d7: 00 +c01018d8: 89 04 24 mov %eax,(%esp) +c01018db: e8 ac fe ff ff call c010178c +c01018e0: 85 c0 test %eax,%eax +c01018e2: 0f 85 c8 01 00 00 jne c0101ab0 + continue ; + } + + /* device is ok */ + ide_devices[ideno].valid = 1; +c01018e8: 0f b7 55 f6 movzwl -0xa(%ebp),%edx +c01018ec: 89 d0 mov %edx,%eax +c01018ee: c1 e0 03 shl $0x3,%eax +c01018f1: 29 d0 sub %edx,%eax +c01018f3: c1 e0 03 shl $0x3,%eax +c01018f6: 05 80 36 1a c0 add $0xc01a3680,%eax +c01018fb: c6 00 01 movb $0x1,(%eax) + + /* read identification space of the device */ + unsigned int buffer[128]; + insl(iobase + ISA_DATA, buffer, sizeof(buffer) / sizeof(unsigned int)); +c01018fe: 0f b7 45 ea movzwl -0x16(%ebp),%eax +c0101902: 89 45 c4 mov %eax,-0x3c(%ebp) +c0101905: 8d 85 bc fd ff ff lea -0x244(%ebp),%eax +c010190b: 89 45 c0 mov %eax,-0x40(%ebp) +c010190e: c7 45 bc 80 00 00 00 movl $0x80,-0x44(%ebp) + asm volatile ( +c0101915: 8b 55 c4 mov -0x3c(%ebp),%edx +c0101918: 8b 4d c0 mov -0x40(%ebp),%ecx +c010191b: 8b 45 bc mov -0x44(%ebp),%eax +c010191e: 89 cb mov %ecx,%ebx +c0101920: 89 df mov %ebx,%edi +c0101922: 89 c1 mov %eax,%ecx +c0101924: fc cld +c0101925: f2 6d repnz insl (%dx),%es:(%edi) +c0101927: 89 c8 mov %ecx,%eax +c0101929: 89 fb mov %edi,%ebx +c010192b: 89 5d c0 mov %ebx,-0x40(%ebp) +c010192e: 89 45 bc mov %eax,-0x44(%ebp) +} +c0101931: 90 nop + + unsigned char *ident = (unsigned char *)buffer; +c0101932: 8d 85 bc fd ff ff lea -0x244(%ebp),%eax +c0101938: 89 45 e4 mov %eax,-0x1c(%ebp) + unsigned int sectors; + unsigned int cmdsets = *(unsigned int *)(ident + IDE_IDENT_CMDSETS); +c010193b: 8b 45 e4 mov -0x1c(%ebp),%eax +c010193e: 8b 80 a4 00 00 00 mov 0xa4(%eax),%eax +c0101944: 89 45 e0 mov %eax,-0x20(%ebp) + /* device use 48-bits or 28-bits addressing */ + if (cmdsets & (1 << 26)) { +c0101947: 8b 45 e0 mov -0x20(%ebp),%eax +c010194a: 25 00 00 00 04 and $0x4000000,%eax +c010194f: 85 c0 test %eax,%eax +c0101951: 74 0e je c0101961 + sectors = *(unsigned int *)(ident + IDE_IDENT_MAX_LBA_EXT); +c0101953: 8b 45 e4 mov -0x1c(%ebp),%eax +c0101956: 8b 80 c8 00 00 00 mov 0xc8(%eax),%eax +c010195c: 89 45 f0 mov %eax,-0x10(%ebp) +c010195f: eb 09 jmp c010196a + } + else { + sectors = *(unsigned int *)(ident + IDE_IDENT_MAX_LBA); +c0101961: 8b 45 e4 mov -0x1c(%ebp),%eax +c0101964: 8b 40 78 mov 0x78(%eax),%eax +c0101967: 89 45 f0 mov %eax,-0x10(%ebp) + } + ide_devices[ideno].sets = cmdsets; +c010196a: 0f b7 55 f6 movzwl -0xa(%ebp),%edx +c010196e: 89 d0 mov %edx,%eax +c0101970: c1 e0 03 shl $0x3,%eax +c0101973: 29 d0 sub %edx,%eax +c0101975: c1 e0 03 shl $0x3,%eax +c0101978: 8d 90 84 36 1a c0 lea -0x3fe5c97c(%eax),%edx +c010197e: 8b 45 e0 mov -0x20(%ebp),%eax +c0101981: 89 02 mov %eax,(%edx) + ide_devices[ideno].size = sectors; +c0101983: 0f b7 55 f6 movzwl -0xa(%ebp),%edx +c0101987: 89 d0 mov %edx,%eax +c0101989: c1 e0 03 shl $0x3,%eax +c010198c: 29 d0 sub %edx,%eax +c010198e: c1 e0 03 shl $0x3,%eax +c0101991: 8d 90 88 36 1a c0 lea -0x3fe5c978(%eax),%edx +c0101997: 8b 45 f0 mov -0x10(%ebp),%eax +c010199a: 89 02 mov %eax,(%edx) + + /* check if supports LBA */ + assert((*(unsigned short *)(ident + IDE_IDENT_CAPABILITIES) & 0x200) != 0); +c010199c: 8b 45 e4 mov -0x1c(%ebp),%eax +c010199f: 83 c0 62 add $0x62,%eax +c01019a2: 0f b7 00 movzwl (%eax),%eax +c01019a5: 25 00 02 00 00 and $0x200,%eax +c01019aa: 85 c0 test %eax,%eax +c01019ac: 75 24 jne c01019d2 +c01019ae: c7 44 24 0c bc c2 10 movl $0xc010c2bc,0xc(%esp) +c01019b5: c0 +c01019b6: c7 44 24 08 ff c2 10 movl $0xc010c2ff,0x8(%esp) +c01019bd: c0 +c01019be: c7 44 24 04 7d 00 00 movl $0x7d,0x4(%esp) +c01019c5: 00 +c01019c6: c7 04 24 14 c3 10 c0 movl $0xc010c314,(%esp) +c01019cd: e8 69 f3 ff ff call c0100d3b <__panic> + + unsigned char *model = ide_devices[ideno].model, *data = ident + IDE_IDENT_MODEL; +c01019d2: 0f b7 55 f6 movzwl -0xa(%ebp),%edx +c01019d6: 89 d0 mov %edx,%eax +c01019d8: c1 e0 03 shl $0x3,%eax +c01019db: 29 d0 sub %edx,%eax +c01019dd: c1 e0 03 shl $0x3,%eax +c01019e0: 05 80 36 1a c0 add $0xc01a3680,%eax +c01019e5: 83 c0 0c add $0xc,%eax +c01019e8: 89 45 dc mov %eax,-0x24(%ebp) +c01019eb: 8b 45 e4 mov -0x1c(%ebp),%eax +c01019ee: 83 c0 36 add $0x36,%eax +c01019f1: 89 45 d8 mov %eax,-0x28(%ebp) + unsigned int i, length = 40; +c01019f4: c7 45 d4 28 00 00 00 movl $0x28,-0x2c(%ebp) + for (i = 0; i < length; i += 2) { +c01019fb: c7 45 ec 00 00 00 00 movl $0x0,-0x14(%ebp) +c0101a02: eb 34 jmp c0101a38 + model[i] = data[i + 1], model[i + 1] = data[i]; +c0101a04: 8b 45 ec mov -0x14(%ebp),%eax +c0101a07: 8d 50 01 lea 0x1(%eax),%edx +c0101a0a: 8b 45 d8 mov -0x28(%ebp),%eax +c0101a0d: 01 c2 add %eax,%edx +c0101a0f: 8b 4d dc mov -0x24(%ebp),%ecx +c0101a12: 8b 45 ec mov -0x14(%ebp),%eax +c0101a15: 01 c8 add %ecx,%eax +c0101a17: 0f b6 12 movzbl (%edx),%edx +c0101a1a: 88 10 mov %dl,(%eax) +c0101a1c: 8b 55 d8 mov -0x28(%ebp),%edx +c0101a1f: 8b 45 ec mov -0x14(%ebp),%eax +c0101a22: 01 c2 add %eax,%edx +c0101a24: 8b 45 ec mov -0x14(%ebp),%eax +c0101a27: 8d 48 01 lea 0x1(%eax),%ecx +c0101a2a: 8b 45 dc mov -0x24(%ebp),%eax +c0101a2d: 01 c8 add %ecx,%eax +c0101a2f: 0f b6 12 movzbl (%edx),%edx +c0101a32: 88 10 mov %dl,(%eax) + for (i = 0; i < length; i += 2) { +c0101a34: 83 45 ec 02 addl $0x2,-0x14(%ebp) +c0101a38: 8b 45 ec mov -0x14(%ebp),%eax +c0101a3b: 3b 45 d4 cmp -0x2c(%ebp),%eax +c0101a3e: 72 c4 jb c0101a04 + } + do { + model[i] = '\0'; +c0101a40: 8b 55 dc mov -0x24(%ebp),%edx +c0101a43: 8b 45 ec mov -0x14(%ebp),%eax +c0101a46: 01 d0 add %edx,%eax +c0101a48: c6 00 00 movb $0x0,(%eax) + } while (i -- > 0 && model[i] == ' '); +c0101a4b: 8b 45 ec mov -0x14(%ebp),%eax +c0101a4e: 8d 50 ff lea -0x1(%eax),%edx +c0101a51: 89 55 ec mov %edx,-0x14(%ebp) +c0101a54: 85 c0 test %eax,%eax +c0101a56: 74 0f je c0101a67 +c0101a58: 8b 55 dc mov -0x24(%ebp),%edx +c0101a5b: 8b 45 ec mov -0x14(%ebp),%eax +c0101a5e: 01 d0 add %edx,%eax +c0101a60: 0f b6 00 movzbl (%eax),%eax +c0101a63: 3c 20 cmp $0x20,%al +c0101a65: 74 d9 je c0101a40 + + cprintf("ide %d: %10u(sectors), '%s'.\n", ideno, ide_devices[ideno].size, ide_devices[ideno].model); +c0101a67: 0f b7 55 f6 movzwl -0xa(%ebp),%edx +c0101a6b: 89 d0 mov %edx,%eax +c0101a6d: c1 e0 03 shl $0x3,%eax +c0101a70: 29 d0 sub %edx,%eax +c0101a72: c1 e0 03 shl $0x3,%eax +c0101a75: 05 80 36 1a c0 add $0xc01a3680,%eax +c0101a7a: 8d 48 0c lea 0xc(%eax),%ecx +c0101a7d: 0f b7 55 f6 movzwl -0xa(%ebp),%edx +c0101a81: 89 d0 mov %edx,%eax +c0101a83: c1 e0 03 shl $0x3,%eax +c0101a86: 29 d0 sub %edx,%eax +c0101a88: c1 e0 03 shl $0x3,%eax +c0101a8b: 05 88 36 1a c0 add $0xc01a3688,%eax +c0101a90: 8b 10 mov (%eax),%edx +c0101a92: 0f b7 45 f6 movzwl -0xa(%ebp),%eax +c0101a96: 89 4c 24 0c mov %ecx,0xc(%esp) +c0101a9a: 89 54 24 08 mov %edx,0x8(%esp) +c0101a9e: 89 44 24 04 mov %eax,0x4(%esp) +c0101aa2: c7 04 24 26 c3 10 c0 movl $0xc010c326,(%esp) +c0101aa9: e8 ca e8 ff ff call c0100378 +c0101aae: eb 01 jmp c0101ab1 + continue ; +c0101ab0: 90 nop + for (ideno = 0; ideno < MAX_IDE; ideno ++) { +c0101ab1: 0f b7 45 f6 movzwl -0xa(%ebp),%eax +c0101ab5: 40 inc %eax +c0101ab6: 66 89 45 f6 mov %ax,-0xa(%ebp) +c0101aba: 0f b7 45 f6 movzwl -0xa(%ebp),%eax +c0101abe: 83 f8 03 cmp $0x3,%eax +c0101ac1: 0f 86 36 fd ff ff jbe c01017fd + } + + // enable ide interrupt + pic_enable(IRQ_IDE1); +c0101ac7: c7 04 24 0e 00 00 00 movl $0xe,(%esp) +c0101ace: e8 83 05 00 00 call c0102056 + pic_enable(IRQ_IDE2); +c0101ad3: c7 04 24 0f 00 00 00 movl $0xf,(%esp) +c0101ada: e8 77 05 00 00 call c0102056 +} +c0101adf: 90 nop +c0101ae0: 81 c4 50 02 00 00 add $0x250,%esp +c0101ae6: 5b pop %ebx +c0101ae7: 5f pop %edi +c0101ae8: 5d pop %ebp +c0101ae9: c3 ret + +c0101aea : + +bool +ide_device_valid(unsigned short ideno) { +c0101aea: 55 push %ebp +c0101aeb: 89 e5 mov %esp,%ebp +c0101aed: 83 ec 04 sub $0x4,%esp +c0101af0: 8b 45 08 mov 0x8(%ebp),%eax +c0101af3: 66 89 45 fc mov %ax,-0x4(%ebp) + return VALID_IDE(ideno); +c0101af7: 0f b7 45 fc movzwl -0x4(%ebp),%eax +c0101afb: 83 f8 03 cmp $0x3,%eax +c0101afe: 77 21 ja c0101b21 +c0101b00: 0f b7 55 fc movzwl -0x4(%ebp),%edx +c0101b04: 89 d0 mov %edx,%eax +c0101b06: c1 e0 03 shl $0x3,%eax +c0101b09: 29 d0 sub %edx,%eax +c0101b0b: c1 e0 03 shl $0x3,%eax +c0101b0e: 05 80 36 1a c0 add $0xc01a3680,%eax +c0101b13: 0f b6 00 movzbl (%eax),%eax +c0101b16: 84 c0 test %al,%al +c0101b18: 74 07 je c0101b21 +c0101b1a: b8 01 00 00 00 mov $0x1,%eax +c0101b1f: eb 05 jmp c0101b26 +c0101b21: b8 00 00 00 00 mov $0x0,%eax +} +c0101b26: 89 ec mov %ebp,%esp +c0101b28: 5d pop %ebp +c0101b29: c3 ret + +c0101b2a : + +size_t +ide_device_size(unsigned short ideno) { +c0101b2a: 55 push %ebp +c0101b2b: 89 e5 mov %esp,%ebp +c0101b2d: 83 ec 08 sub $0x8,%esp +c0101b30: 8b 45 08 mov 0x8(%ebp),%eax +c0101b33: 66 89 45 fc mov %ax,-0x4(%ebp) + if (ide_device_valid(ideno)) { +c0101b37: 0f b7 45 fc movzwl -0x4(%ebp),%eax +c0101b3b: 89 04 24 mov %eax,(%esp) +c0101b3e: e8 a7 ff ff ff call c0101aea +c0101b43: 85 c0 test %eax,%eax +c0101b45: 74 17 je c0101b5e + return ide_devices[ideno].size; +c0101b47: 0f b7 55 fc movzwl -0x4(%ebp),%edx +c0101b4b: 89 d0 mov %edx,%eax +c0101b4d: c1 e0 03 shl $0x3,%eax +c0101b50: 29 d0 sub %edx,%eax +c0101b52: c1 e0 03 shl $0x3,%eax +c0101b55: 05 88 36 1a c0 add $0xc01a3688,%eax +c0101b5a: 8b 00 mov (%eax),%eax +c0101b5c: eb 05 jmp c0101b63 + } + return 0; +c0101b5e: b8 00 00 00 00 mov $0x0,%eax +} +c0101b63: 89 ec mov %ebp,%esp +c0101b65: 5d pop %ebp +c0101b66: c3 ret + +c0101b67 : + +int +ide_read_secs(unsigned short ideno, uint32_t secno, void *dst, size_t nsecs) { +c0101b67: 55 push %ebp +c0101b68: 89 e5 mov %esp,%ebp +c0101b6a: 57 push %edi +c0101b6b: 53 push %ebx +c0101b6c: 83 ec 50 sub $0x50,%esp +c0101b6f: 8b 45 08 mov 0x8(%ebp),%eax +c0101b72: 66 89 45 c4 mov %ax,-0x3c(%ebp) + assert(nsecs <= MAX_NSECS && VALID_IDE(ideno)); +c0101b76: 81 7d 14 80 00 00 00 cmpl $0x80,0x14(%ebp) +c0101b7d: 77 23 ja c0101ba2 +c0101b7f: 0f b7 45 c4 movzwl -0x3c(%ebp),%eax +c0101b83: 83 f8 03 cmp $0x3,%eax +c0101b86: 77 1a ja c0101ba2 +c0101b88: 0f b7 55 c4 movzwl -0x3c(%ebp),%edx +c0101b8c: 89 d0 mov %edx,%eax +c0101b8e: c1 e0 03 shl $0x3,%eax +c0101b91: 29 d0 sub %edx,%eax +c0101b93: c1 e0 03 shl $0x3,%eax +c0101b96: 05 80 36 1a c0 add $0xc01a3680,%eax +c0101b9b: 0f b6 00 movzbl (%eax),%eax +c0101b9e: 84 c0 test %al,%al +c0101ba0: 75 24 jne c0101bc6 +c0101ba2: c7 44 24 0c 44 c3 10 movl $0xc010c344,0xc(%esp) +c0101ba9: c0 +c0101baa: c7 44 24 08 ff c2 10 movl $0xc010c2ff,0x8(%esp) +c0101bb1: c0 +c0101bb2: c7 44 24 04 9f 00 00 movl $0x9f,0x4(%esp) +c0101bb9: 00 +c0101bba: c7 04 24 14 c3 10 c0 movl $0xc010c314,(%esp) +c0101bc1: e8 75 f1 ff ff call c0100d3b <__panic> + assert(secno < MAX_DISK_NSECS && secno + nsecs <= MAX_DISK_NSECS); +c0101bc6: 81 7d 0c ff ff ff 0f cmpl $0xfffffff,0xc(%ebp) +c0101bcd: 77 0f ja c0101bde +c0101bcf: 8b 55 0c mov 0xc(%ebp),%edx +c0101bd2: 8b 45 14 mov 0x14(%ebp),%eax +c0101bd5: 01 d0 add %edx,%eax +c0101bd7: 3d 00 00 00 10 cmp $0x10000000,%eax +c0101bdc: 76 24 jbe c0101c02 +c0101bde: c7 44 24 0c 6c c3 10 movl $0xc010c36c,0xc(%esp) +c0101be5: c0 +c0101be6: c7 44 24 08 ff c2 10 movl $0xc010c2ff,0x8(%esp) +c0101bed: c0 +c0101bee: c7 44 24 04 a0 00 00 movl $0xa0,0x4(%esp) +c0101bf5: 00 +c0101bf6: c7 04 24 14 c3 10 c0 movl $0xc010c314,(%esp) +c0101bfd: e8 39 f1 ff ff call c0100d3b <__panic> + unsigned short iobase = IO_BASE(ideno), ioctrl = IO_CTRL(ideno); +c0101c02: 0f b7 45 c4 movzwl -0x3c(%ebp),%eax +c0101c06: d1 e8 shr %eax +c0101c08: 0f b7 c0 movzwl %ax,%eax +c0101c0b: 8b 04 85 b4 c2 10 c0 mov -0x3fef3d4c(,%eax,4),%eax +c0101c12: 66 89 45 f2 mov %ax,-0xe(%ebp) +c0101c16: 0f b7 45 c4 movzwl -0x3c(%ebp),%eax +c0101c1a: d1 e8 shr %eax +c0101c1c: 0f b7 c0 movzwl %ax,%eax +c0101c1f: 0f b7 04 85 b6 c2 10 movzwl -0x3fef3d4a(,%eax,4),%eax +c0101c26: c0 +c0101c27: 66 89 45 f0 mov %ax,-0x10(%ebp) + + ide_wait_ready(iobase, 0); +c0101c2b: 0f b7 45 f2 movzwl -0xe(%ebp),%eax +c0101c2f: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) +c0101c36: 00 +c0101c37: 89 04 24 mov %eax,(%esp) +c0101c3a: e8 4d fb ff ff call c010178c + + // generate interrupt + outb(ioctrl + ISA_CTRL, 0); +c0101c3f: 8b 45 f0 mov -0x10(%ebp),%eax +c0101c42: 83 c0 02 add $0x2,%eax +c0101c45: 0f b7 c0 movzwl %ax,%eax +c0101c48: 66 89 45 d6 mov %ax,-0x2a(%ebp) +c0101c4c: c6 45 d5 00 movb $0x0,-0x2b(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101c50: 0f b6 45 d5 movzbl -0x2b(%ebp),%eax +c0101c54: 0f b7 55 d6 movzwl -0x2a(%ebp),%edx +c0101c58: ee out %al,(%dx) +} +c0101c59: 90 nop + outb(iobase + ISA_SECCNT, nsecs); +c0101c5a: 8b 45 14 mov 0x14(%ebp),%eax +c0101c5d: 0f b6 c0 movzbl %al,%eax +c0101c60: 0f b7 55 f2 movzwl -0xe(%ebp),%edx +c0101c64: 83 c2 02 add $0x2,%edx +c0101c67: 0f b7 d2 movzwl %dx,%edx +c0101c6a: 66 89 55 da mov %dx,-0x26(%ebp) +c0101c6e: 88 45 d9 mov %al,-0x27(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101c71: 0f b6 45 d9 movzbl -0x27(%ebp),%eax +c0101c75: 0f b7 55 da movzwl -0x26(%ebp),%edx +c0101c79: ee out %al,(%dx) +} +c0101c7a: 90 nop + outb(iobase + ISA_SECTOR, secno & 0xFF); +c0101c7b: 8b 45 0c mov 0xc(%ebp),%eax +c0101c7e: 0f b6 c0 movzbl %al,%eax +c0101c81: 0f b7 55 f2 movzwl -0xe(%ebp),%edx +c0101c85: 83 c2 03 add $0x3,%edx +c0101c88: 0f b7 d2 movzwl %dx,%edx +c0101c8b: 66 89 55 de mov %dx,-0x22(%ebp) +c0101c8f: 88 45 dd mov %al,-0x23(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101c92: 0f b6 45 dd movzbl -0x23(%ebp),%eax +c0101c96: 0f b7 55 de movzwl -0x22(%ebp),%edx +c0101c9a: ee out %al,(%dx) +} +c0101c9b: 90 nop + outb(iobase + ISA_CYL_LO, (secno >> 8) & 0xFF); +c0101c9c: 8b 45 0c mov 0xc(%ebp),%eax +c0101c9f: c1 e8 08 shr $0x8,%eax +c0101ca2: 0f b6 c0 movzbl %al,%eax +c0101ca5: 0f b7 55 f2 movzwl -0xe(%ebp),%edx +c0101ca9: 83 c2 04 add $0x4,%edx +c0101cac: 0f b7 d2 movzwl %dx,%edx +c0101caf: 66 89 55 e2 mov %dx,-0x1e(%ebp) +c0101cb3: 88 45 e1 mov %al,-0x1f(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101cb6: 0f b6 45 e1 movzbl -0x1f(%ebp),%eax +c0101cba: 0f b7 55 e2 movzwl -0x1e(%ebp),%edx +c0101cbe: ee out %al,(%dx) +} +c0101cbf: 90 nop + outb(iobase + ISA_CYL_HI, (secno >> 16) & 0xFF); +c0101cc0: 8b 45 0c mov 0xc(%ebp),%eax +c0101cc3: c1 e8 10 shr $0x10,%eax +c0101cc6: 0f b6 c0 movzbl %al,%eax +c0101cc9: 0f b7 55 f2 movzwl -0xe(%ebp),%edx +c0101ccd: 83 c2 05 add $0x5,%edx +c0101cd0: 0f b7 d2 movzwl %dx,%edx +c0101cd3: 66 89 55 e6 mov %dx,-0x1a(%ebp) +c0101cd7: 88 45 e5 mov %al,-0x1b(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101cda: 0f b6 45 e5 movzbl -0x1b(%ebp),%eax +c0101cde: 0f b7 55 e6 movzwl -0x1a(%ebp),%edx +c0101ce2: ee out %al,(%dx) +} +c0101ce3: 90 nop + outb(iobase + ISA_SDH, 0xE0 | ((ideno & 1) << 4) | ((secno >> 24) & 0xF)); +c0101ce4: 8b 45 c4 mov -0x3c(%ebp),%eax +c0101ce7: c0 e0 04 shl $0x4,%al +c0101cea: 24 10 and $0x10,%al +c0101cec: 88 c2 mov %al,%dl +c0101cee: 8b 45 0c mov 0xc(%ebp),%eax +c0101cf1: c1 e8 18 shr $0x18,%eax +c0101cf4: 24 0f and $0xf,%al +c0101cf6: 08 d0 or %dl,%al +c0101cf8: 0c e0 or $0xe0,%al +c0101cfa: 0f b6 c0 movzbl %al,%eax +c0101cfd: 0f b7 55 f2 movzwl -0xe(%ebp),%edx +c0101d01: 83 c2 06 add $0x6,%edx +c0101d04: 0f b7 d2 movzwl %dx,%edx +c0101d07: 66 89 55 ea mov %dx,-0x16(%ebp) +c0101d0b: 88 45 e9 mov %al,-0x17(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101d0e: 0f b6 45 e9 movzbl -0x17(%ebp),%eax +c0101d12: 0f b7 55 ea movzwl -0x16(%ebp),%edx +c0101d16: ee out %al,(%dx) +} +c0101d17: 90 nop + outb(iobase + ISA_COMMAND, IDE_CMD_READ); +c0101d18: 0f b7 45 f2 movzwl -0xe(%ebp),%eax +c0101d1c: 83 c0 07 add $0x7,%eax +c0101d1f: 0f b7 c0 movzwl %ax,%eax +c0101d22: 66 89 45 ee mov %ax,-0x12(%ebp) +c0101d26: c6 45 ed 20 movb $0x20,-0x13(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101d2a: 0f b6 45 ed movzbl -0x13(%ebp),%eax +c0101d2e: 0f b7 55 ee movzwl -0x12(%ebp),%edx +c0101d32: ee out %al,(%dx) +} +c0101d33: 90 nop + + int ret = 0; +c0101d34: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + for (; nsecs > 0; nsecs --, dst += SECTSIZE) { +c0101d3b: eb 58 jmp c0101d95 + if ((ret = ide_wait_ready(iobase, 1)) != 0) { +c0101d3d: 0f b7 45 f2 movzwl -0xe(%ebp),%eax +c0101d41: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c0101d48: 00 +c0101d49: 89 04 24 mov %eax,(%esp) +c0101d4c: e8 3b fa ff ff call c010178c +c0101d51: 89 45 f4 mov %eax,-0xc(%ebp) +c0101d54: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c0101d58: 75 43 jne c0101d9d + goto out; + } + insl(iobase, dst, SECTSIZE / sizeof(uint32_t)); +c0101d5a: 0f b7 45 f2 movzwl -0xe(%ebp),%eax +c0101d5e: 89 45 d0 mov %eax,-0x30(%ebp) +c0101d61: 8b 45 10 mov 0x10(%ebp),%eax +c0101d64: 89 45 cc mov %eax,-0x34(%ebp) +c0101d67: c7 45 c8 80 00 00 00 movl $0x80,-0x38(%ebp) + asm volatile ( +c0101d6e: 8b 55 d0 mov -0x30(%ebp),%edx +c0101d71: 8b 4d cc mov -0x34(%ebp),%ecx +c0101d74: 8b 45 c8 mov -0x38(%ebp),%eax +c0101d77: 89 cb mov %ecx,%ebx +c0101d79: 89 df mov %ebx,%edi +c0101d7b: 89 c1 mov %eax,%ecx +c0101d7d: fc cld +c0101d7e: f2 6d repnz insl (%dx),%es:(%edi) +c0101d80: 89 c8 mov %ecx,%eax +c0101d82: 89 fb mov %edi,%ebx +c0101d84: 89 5d cc mov %ebx,-0x34(%ebp) +c0101d87: 89 45 c8 mov %eax,-0x38(%ebp) +} +c0101d8a: 90 nop + for (; nsecs > 0; nsecs --, dst += SECTSIZE) { +c0101d8b: ff 4d 14 decl 0x14(%ebp) +c0101d8e: 81 45 10 00 02 00 00 addl $0x200,0x10(%ebp) +c0101d95: 83 7d 14 00 cmpl $0x0,0x14(%ebp) +c0101d99: 75 a2 jne c0101d3d + } + +out: +c0101d9b: eb 01 jmp c0101d9e + goto out; +c0101d9d: 90 nop + return ret; +c0101d9e: 8b 45 f4 mov -0xc(%ebp),%eax +} +c0101da1: 83 c4 50 add $0x50,%esp +c0101da4: 5b pop %ebx +c0101da5: 5f pop %edi +c0101da6: 5d pop %ebp +c0101da7: c3 ret + +c0101da8 : + +int +ide_write_secs(unsigned short ideno, uint32_t secno, const void *src, size_t nsecs) { +c0101da8: 55 push %ebp +c0101da9: 89 e5 mov %esp,%ebp +c0101dab: 56 push %esi +c0101dac: 53 push %ebx +c0101dad: 83 ec 50 sub $0x50,%esp +c0101db0: 8b 45 08 mov 0x8(%ebp),%eax +c0101db3: 66 89 45 c4 mov %ax,-0x3c(%ebp) + assert(nsecs <= MAX_NSECS && VALID_IDE(ideno)); +c0101db7: 81 7d 14 80 00 00 00 cmpl $0x80,0x14(%ebp) +c0101dbe: 77 23 ja c0101de3 +c0101dc0: 0f b7 45 c4 movzwl -0x3c(%ebp),%eax +c0101dc4: 83 f8 03 cmp $0x3,%eax +c0101dc7: 77 1a ja c0101de3 +c0101dc9: 0f b7 55 c4 movzwl -0x3c(%ebp),%edx +c0101dcd: 89 d0 mov %edx,%eax +c0101dcf: c1 e0 03 shl $0x3,%eax +c0101dd2: 29 d0 sub %edx,%eax +c0101dd4: c1 e0 03 shl $0x3,%eax +c0101dd7: 05 80 36 1a c0 add $0xc01a3680,%eax +c0101ddc: 0f b6 00 movzbl (%eax),%eax +c0101ddf: 84 c0 test %al,%al +c0101de1: 75 24 jne c0101e07 +c0101de3: c7 44 24 0c 44 c3 10 movl $0xc010c344,0xc(%esp) +c0101dea: c0 +c0101deb: c7 44 24 08 ff c2 10 movl $0xc010c2ff,0x8(%esp) +c0101df2: c0 +c0101df3: c7 44 24 04 bc 00 00 movl $0xbc,0x4(%esp) +c0101dfa: 00 +c0101dfb: c7 04 24 14 c3 10 c0 movl $0xc010c314,(%esp) +c0101e02: e8 34 ef ff ff call c0100d3b <__panic> + assert(secno < MAX_DISK_NSECS && secno + nsecs <= MAX_DISK_NSECS); +c0101e07: 81 7d 0c ff ff ff 0f cmpl $0xfffffff,0xc(%ebp) +c0101e0e: 77 0f ja c0101e1f +c0101e10: 8b 55 0c mov 0xc(%ebp),%edx +c0101e13: 8b 45 14 mov 0x14(%ebp),%eax +c0101e16: 01 d0 add %edx,%eax +c0101e18: 3d 00 00 00 10 cmp $0x10000000,%eax +c0101e1d: 76 24 jbe c0101e43 +c0101e1f: c7 44 24 0c 6c c3 10 movl $0xc010c36c,0xc(%esp) +c0101e26: c0 +c0101e27: c7 44 24 08 ff c2 10 movl $0xc010c2ff,0x8(%esp) +c0101e2e: c0 +c0101e2f: c7 44 24 04 bd 00 00 movl $0xbd,0x4(%esp) +c0101e36: 00 +c0101e37: c7 04 24 14 c3 10 c0 movl $0xc010c314,(%esp) +c0101e3e: e8 f8 ee ff ff call c0100d3b <__panic> + unsigned short iobase = IO_BASE(ideno), ioctrl = IO_CTRL(ideno); +c0101e43: 0f b7 45 c4 movzwl -0x3c(%ebp),%eax +c0101e47: d1 e8 shr %eax +c0101e49: 0f b7 c0 movzwl %ax,%eax +c0101e4c: 8b 04 85 b4 c2 10 c0 mov -0x3fef3d4c(,%eax,4),%eax +c0101e53: 66 89 45 f2 mov %ax,-0xe(%ebp) +c0101e57: 0f b7 45 c4 movzwl -0x3c(%ebp),%eax +c0101e5b: d1 e8 shr %eax +c0101e5d: 0f b7 c0 movzwl %ax,%eax +c0101e60: 0f b7 04 85 b6 c2 10 movzwl -0x3fef3d4a(,%eax,4),%eax +c0101e67: c0 +c0101e68: 66 89 45 f0 mov %ax,-0x10(%ebp) + + ide_wait_ready(iobase, 0); +c0101e6c: 0f b7 45 f2 movzwl -0xe(%ebp),%eax +c0101e70: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) +c0101e77: 00 +c0101e78: 89 04 24 mov %eax,(%esp) +c0101e7b: e8 0c f9 ff ff call c010178c + + // generate interrupt + outb(ioctrl + ISA_CTRL, 0); +c0101e80: 8b 45 f0 mov -0x10(%ebp),%eax +c0101e83: 83 c0 02 add $0x2,%eax +c0101e86: 0f b7 c0 movzwl %ax,%eax +c0101e89: 66 89 45 d6 mov %ax,-0x2a(%ebp) +c0101e8d: c6 45 d5 00 movb $0x0,-0x2b(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101e91: 0f b6 45 d5 movzbl -0x2b(%ebp),%eax +c0101e95: 0f b7 55 d6 movzwl -0x2a(%ebp),%edx +c0101e99: ee out %al,(%dx) +} +c0101e9a: 90 nop + outb(iobase + ISA_SECCNT, nsecs); +c0101e9b: 8b 45 14 mov 0x14(%ebp),%eax +c0101e9e: 0f b6 c0 movzbl %al,%eax +c0101ea1: 0f b7 55 f2 movzwl -0xe(%ebp),%edx +c0101ea5: 83 c2 02 add $0x2,%edx +c0101ea8: 0f b7 d2 movzwl %dx,%edx +c0101eab: 66 89 55 da mov %dx,-0x26(%ebp) +c0101eaf: 88 45 d9 mov %al,-0x27(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101eb2: 0f b6 45 d9 movzbl -0x27(%ebp),%eax +c0101eb6: 0f b7 55 da movzwl -0x26(%ebp),%edx +c0101eba: ee out %al,(%dx) +} +c0101ebb: 90 nop + outb(iobase + ISA_SECTOR, secno & 0xFF); +c0101ebc: 8b 45 0c mov 0xc(%ebp),%eax +c0101ebf: 0f b6 c0 movzbl %al,%eax +c0101ec2: 0f b7 55 f2 movzwl -0xe(%ebp),%edx +c0101ec6: 83 c2 03 add $0x3,%edx +c0101ec9: 0f b7 d2 movzwl %dx,%edx +c0101ecc: 66 89 55 de mov %dx,-0x22(%ebp) +c0101ed0: 88 45 dd mov %al,-0x23(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101ed3: 0f b6 45 dd movzbl -0x23(%ebp),%eax +c0101ed7: 0f b7 55 de movzwl -0x22(%ebp),%edx +c0101edb: ee out %al,(%dx) +} +c0101edc: 90 nop + outb(iobase + ISA_CYL_LO, (secno >> 8) & 0xFF); +c0101edd: 8b 45 0c mov 0xc(%ebp),%eax +c0101ee0: c1 e8 08 shr $0x8,%eax +c0101ee3: 0f b6 c0 movzbl %al,%eax +c0101ee6: 0f b7 55 f2 movzwl -0xe(%ebp),%edx +c0101eea: 83 c2 04 add $0x4,%edx +c0101eed: 0f b7 d2 movzwl %dx,%edx +c0101ef0: 66 89 55 e2 mov %dx,-0x1e(%ebp) +c0101ef4: 88 45 e1 mov %al,-0x1f(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101ef7: 0f b6 45 e1 movzbl -0x1f(%ebp),%eax +c0101efb: 0f b7 55 e2 movzwl -0x1e(%ebp),%edx +c0101eff: ee out %al,(%dx) +} +c0101f00: 90 nop + outb(iobase + ISA_CYL_HI, (secno >> 16) & 0xFF); +c0101f01: 8b 45 0c mov 0xc(%ebp),%eax +c0101f04: c1 e8 10 shr $0x10,%eax +c0101f07: 0f b6 c0 movzbl %al,%eax +c0101f0a: 0f b7 55 f2 movzwl -0xe(%ebp),%edx +c0101f0e: 83 c2 05 add $0x5,%edx +c0101f11: 0f b7 d2 movzwl %dx,%edx +c0101f14: 66 89 55 e6 mov %dx,-0x1a(%ebp) +c0101f18: 88 45 e5 mov %al,-0x1b(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101f1b: 0f b6 45 e5 movzbl -0x1b(%ebp),%eax +c0101f1f: 0f b7 55 e6 movzwl -0x1a(%ebp),%edx +c0101f23: ee out %al,(%dx) +} +c0101f24: 90 nop + outb(iobase + ISA_SDH, 0xE0 | ((ideno & 1) << 4) | ((secno >> 24) & 0xF)); +c0101f25: 8b 45 c4 mov -0x3c(%ebp),%eax +c0101f28: c0 e0 04 shl $0x4,%al +c0101f2b: 24 10 and $0x10,%al +c0101f2d: 88 c2 mov %al,%dl +c0101f2f: 8b 45 0c mov 0xc(%ebp),%eax +c0101f32: c1 e8 18 shr $0x18,%eax +c0101f35: 24 0f and $0xf,%al +c0101f37: 08 d0 or %dl,%al +c0101f39: 0c e0 or $0xe0,%al +c0101f3b: 0f b6 c0 movzbl %al,%eax +c0101f3e: 0f b7 55 f2 movzwl -0xe(%ebp),%edx +c0101f42: 83 c2 06 add $0x6,%edx +c0101f45: 0f b7 d2 movzwl %dx,%edx +c0101f48: 66 89 55 ea mov %dx,-0x16(%ebp) +c0101f4c: 88 45 e9 mov %al,-0x17(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101f4f: 0f b6 45 e9 movzbl -0x17(%ebp),%eax +c0101f53: 0f b7 55 ea movzwl -0x16(%ebp),%edx +c0101f57: ee out %al,(%dx) +} +c0101f58: 90 nop + outb(iobase + ISA_COMMAND, IDE_CMD_WRITE); +c0101f59: 0f b7 45 f2 movzwl -0xe(%ebp),%eax +c0101f5d: 83 c0 07 add $0x7,%eax +c0101f60: 0f b7 c0 movzwl %ax,%eax +c0101f63: 66 89 45 ee mov %ax,-0x12(%ebp) +c0101f67: c6 45 ed 30 movb $0x30,-0x13(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101f6b: 0f b6 45 ed movzbl -0x13(%ebp),%eax +c0101f6f: 0f b7 55 ee movzwl -0x12(%ebp),%edx +c0101f73: ee out %al,(%dx) +} +c0101f74: 90 nop + + int ret = 0; +c0101f75: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + for (; nsecs > 0; nsecs --, src += SECTSIZE) { +c0101f7c: eb 58 jmp c0101fd6 + if ((ret = ide_wait_ready(iobase, 1)) != 0) { +c0101f7e: 0f b7 45 f2 movzwl -0xe(%ebp),%eax +c0101f82: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c0101f89: 00 +c0101f8a: 89 04 24 mov %eax,(%esp) +c0101f8d: e8 fa f7 ff ff call c010178c +c0101f92: 89 45 f4 mov %eax,-0xc(%ebp) +c0101f95: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c0101f99: 75 43 jne c0101fde + goto out; + } + outsl(iobase, src, SECTSIZE / sizeof(uint32_t)); +c0101f9b: 0f b7 45 f2 movzwl -0xe(%ebp),%eax +c0101f9f: 89 45 d0 mov %eax,-0x30(%ebp) +c0101fa2: 8b 45 10 mov 0x10(%ebp),%eax +c0101fa5: 89 45 cc mov %eax,-0x34(%ebp) +c0101fa8: c7 45 c8 80 00 00 00 movl $0x80,-0x38(%ebp) + asm volatile ( +c0101faf: 8b 55 d0 mov -0x30(%ebp),%edx +c0101fb2: 8b 4d cc mov -0x34(%ebp),%ecx +c0101fb5: 8b 45 c8 mov -0x38(%ebp),%eax +c0101fb8: 89 cb mov %ecx,%ebx +c0101fba: 89 de mov %ebx,%esi +c0101fbc: 89 c1 mov %eax,%ecx +c0101fbe: fc cld +c0101fbf: f2 6f repnz outsl %ds:(%esi),(%dx) +c0101fc1: 89 c8 mov %ecx,%eax +c0101fc3: 89 f3 mov %esi,%ebx +c0101fc5: 89 5d cc mov %ebx,-0x34(%ebp) +c0101fc8: 89 45 c8 mov %eax,-0x38(%ebp) +} +c0101fcb: 90 nop + for (; nsecs > 0; nsecs --, src += SECTSIZE) { +c0101fcc: ff 4d 14 decl 0x14(%ebp) +c0101fcf: 81 45 10 00 02 00 00 addl $0x200,0x10(%ebp) +c0101fd6: 83 7d 14 00 cmpl $0x0,0x14(%ebp) +c0101fda: 75 a2 jne c0101f7e + } + +out: +c0101fdc: eb 01 jmp c0101fdf + goto out; +c0101fde: 90 nop + return ret; +c0101fdf: 8b 45 f4 mov -0xc(%ebp),%eax +} +c0101fe2: 83 c4 50 add $0x50,%esp +c0101fe5: 5b pop %ebx +c0101fe6: 5e pop %esi +c0101fe7: 5d pop %ebp +c0101fe8: c3 ret + +c0101fe9 : +#include +#include + +/* intr_enable - enable irq interrupt */ +void +intr_enable(void) { +c0101fe9: 55 push %ebp +c0101fea: 89 e5 mov %esp,%ebp + asm volatile ("sti"); +c0101fec: fb sti +} +c0101fed: 90 nop + sti(); +} +c0101fee: 90 nop +c0101fef: 5d pop %ebp +c0101ff0: c3 ret + +c0101ff1 : + +/* intr_disable - disable irq interrupt */ +void +intr_disable(void) { +c0101ff1: 55 push %ebp +c0101ff2: 89 e5 mov %esp,%ebp + asm volatile ("cli" ::: "memory"); +c0101ff4: fa cli +} +c0101ff5: 90 nop + cli(); +} +c0101ff6: 90 nop +c0101ff7: 5d pop %ebp +c0101ff8: c3 ret + +c0101ff9 : +// Initial IRQ mask has interrupt 2 enabled (for slave 8259A). +static uint16_t irq_mask = 0xFFFF & ~(1 << IRQ_SLAVE); +static bool did_init = 0; + +static void +pic_setmask(uint16_t mask) { +c0101ff9: 55 push %ebp +c0101ffa: 89 e5 mov %esp,%ebp +c0101ffc: 83 ec 14 sub $0x14,%esp +c0101fff: 8b 45 08 mov 0x8(%ebp),%eax +c0102002: 66 89 45 ec mov %ax,-0x14(%ebp) + irq_mask = mask; +c0102006: 8b 45 ec mov -0x14(%ebp),%eax +c0102009: 66 a3 50 f5 12 c0 mov %ax,0xc012f550 + if (did_init) { +c010200f: a1 60 37 1a c0 mov 0xc01a3760,%eax +c0102014: 85 c0 test %eax,%eax +c0102016: 74 39 je c0102051 + outb(IO_PIC1 + 1, mask); +c0102018: 8b 45 ec mov -0x14(%ebp),%eax +c010201b: 0f b6 c0 movzbl %al,%eax +c010201e: 66 c7 45 fa 21 00 movw $0x21,-0x6(%ebp) +c0102024: 88 45 f9 mov %al,-0x7(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0102027: 0f b6 45 f9 movzbl -0x7(%ebp),%eax +c010202b: 0f b7 55 fa movzwl -0x6(%ebp),%edx +c010202f: ee out %al,(%dx) +} +c0102030: 90 nop + outb(IO_PIC2 + 1, mask >> 8); +c0102031: 0f b7 45 ec movzwl -0x14(%ebp),%eax +c0102035: c1 e8 08 shr $0x8,%eax +c0102038: 0f b7 c0 movzwl %ax,%eax +c010203b: 0f b6 c0 movzbl %al,%eax +c010203e: 66 c7 45 fe a1 00 movw $0xa1,-0x2(%ebp) +c0102044: 88 45 fd mov %al,-0x3(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0102047: 0f b6 45 fd movzbl -0x3(%ebp),%eax +c010204b: 0f b7 55 fe movzwl -0x2(%ebp),%edx +c010204f: ee out %al,(%dx) +} +c0102050: 90 nop + } +} +c0102051: 90 nop +c0102052: 89 ec mov %ebp,%esp +c0102054: 5d pop %ebp +c0102055: c3 ret + +c0102056 : + +void +pic_enable(unsigned int irq) { +c0102056: 55 push %ebp +c0102057: 89 e5 mov %esp,%ebp +c0102059: 83 ec 04 sub $0x4,%esp + pic_setmask(irq_mask & ~(1 << irq)); +c010205c: 8b 45 08 mov 0x8(%ebp),%eax +c010205f: ba 01 00 00 00 mov $0x1,%edx +c0102064: 88 c1 mov %al,%cl +c0102066: d3 e2 shl %cl,%edx +c0102068: 89 d0 mov %edx,%eax +c010206a: 98 cwtl +c010206b: f7 d0 not %eax +c010206d: 0f bf d0 movswl %ax,%edx +c0102070: 0f b7 05 50 f5 12 c0 movzwl 0xc012f550,%eax +c0102077: 98 cwtl +c0102078: 21 d0 and %edx,%eax +c010207a: 98 cwtl +c010207b: 0f b7 c0 movzwl %ax,%eax +c010207e: 89 04 24 mov %eax,(%esp) +c0102081: e8 73 ff ff ff call c0101ff9 +} +c0102086: 90 nop +c0102087: 89 ec mov %ebp,%esp +c0102089: 5d pop %ebp +c010208a: c3 ret + +c010208b : + +/* pic_init - initialize the 8259A interrupt controllers */ +void +pic_init(void) { +c010208b: 55 push %ebp +c010208c: 89 e5 mov %esp,%ebp +c010208e: 83 ec 44 sub $0x44,%esp + did_init = 1; +c0102091: c7 05 60 37 1a c0 01 movl $0x1,0xc01a3760 +c0102098: 00 00 00 +c010209b: 66 c7 45 ca 21 00 movw $0x21,-0x36(%ebp) +c01020a1: c6 45 c9 ff movb $0xff,-0x37(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c01020a5: 0f b6 45 c9 movzbl -0x37(%ebp),%eax +c01020a9: 0f b7 55 ca movzwl -0x36(%ebp),%edx +c01020ad: ee out %al,(%dx) +} +c01020ae: 90 nop +c01020af: 66 c7 45 ce a1 00 movw $0xa1,-0x32(%ebp) +c01020b5: c6 45 cd ff movb $0xff,-0x33(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c01020b9: 0f b6 45 cd movzbl -0x33(%ebp),%eax +c01020bd: 0f b7 55 ce movzwl -0x32(%ebp),%edx +c01020c1: ee out %al,(%dx) +} +c01020c2: 90 nop +c01020c3: 66 c7 45 d2 20 00 movw $0x20,-0x2e(%ebp) +c01020c9: c6 45 d1 11 movb $0x11,-0x2f(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c01020cd: 0f b6 45 d1 movzbl -0x2f(%ebp),%eax +c01020d1: 0f b7 55 d2 movzwl -0x2e(%ebp),%edx +c01020d5: ee out %al,(%dx) +} +c01020d6: 90 nop +c01020d7: 66 c7 45 d6 21 00 movw $0x21,-0x2a(%ebp) +c01020dd: c6 45 d5 20 movb $0x20,-0x2b(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c01020e1: 0f b6 45 d5 movzbl -0x2b(%ebp),%eax +c01020e5: 0f b7 55 d6 movzwl -0x2a(%ebp),%edx +c01020e9: ee out %al,(%dx) +} +c01020ea: 90 nop +c01020eb: 66 c7 45 da 21 00 movw $0x21,-0x26(%ebp) +c01020f1: c6 45 d9 04 movb $0x4,-0x27(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c01020f5: 0f b6 45 d9 movzbl -0x27(%ebp),%eax +c01020f9: 0f b7 55 da movzwl -0x26(%ebp),%edx +c01020fd: ee out %al,(%dx) +} +c01020fe: 90 nop +c01020ff: 66 c7 45 de 21 00 movw $0x21,-0x22(%ebp) +c0102105: c6 45 dd 03 movb $0x3,-0x23(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0102109: 0f b6 45 dd movzbl -0x23(%ebp),%eax +c010210d: 0f b7 55 de movzwl -0x22(%ebp),%edx +c0102111: ee out %al,(%dx) +} +c0102112: 90 nop +c0102113: 66 c7 45 e2 a0 00 movw $0xa0,-0x1e(%ebp) +c0102119: c6 45 e1 11 movb $0x11,-0x1f(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c010211d: 0f b6 45 e1 movzbl -0x1f(%ebp),%eax +c0102121: 0f b7 55 e2 movzwl -0x1e(%ebp),%edx +c0102125: ee out %al,(%dx) +} +c0102126: 90 nop +c0102127: 66 c7 45 e6 a1 00 movw $0xa1,-0x1a(%ebp) +c010212d: c6 45 e5 28 movb $0x28,-0x1b(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0102131: 0f b6 45 e5 movzbl -0x1b(%ebp),%eax +c0102135: 0f b7 55 e6 movzwl -0x1a(%ebp),%edx +c0102139: ee out %al,(%dx) +} +c010213a: 90 nop +c010213b: 66 c7 45 ea a1 00 movw $0xa1,-0x16(%ebp) +c0102141: c6 45 e9 02 movb $0x2,-0x17(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0102145: 0f b6 45 e9 movzbl -0x17(%ebp),%eax +c0102149: 0f b7 55 ea movzwl -0x16(%ebp),%edx +c010214d: ee out %al,(%dx) +} +c010214e: 90 nop +c010214f: 66 c7 45 ee a1 00 movw $0xa1,-0x12(%ebp) +c0102155: c6 45 ed 03 movb $0x3,-0x13(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0102159: 0f b6 45 ed movzbl -0x13(%ebp),%eax +c010215d: 0f b7 55 ee movzwl -0x12(%ebp),%edx +c0102161: ee out %al,(%dx) +} +c0102162: 90 nop +c0102163: 66 c7 45 f2 20 00 movw $0x20,-0xe(%ebp) +c0102169: c6 45 f1 68 movb $0x68,-0xf(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c010216d: 0f b6 45 f1 movzbl -0xf(%ebp),%eax +c0102171: 0f b7 55 f2 movzwl -0xe(%ebp),%edx +c0102175: ee out %al,(%dx) +} +c0102176: 90 nop +c0102177: 66 c7 45 f6 20 00 movw $0x20,-0xa(%ebp) +c010217d: c6 45 f5 0a movb $0xa,-0xb(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0102181: 0f b6 45 f5 movzbl -0xb(%ebp),%eax +c0102185: 0f b7 55 f6 movzwl -0xa(%ebp),%edx +c0102189: ee out %al,(%dx) +} +c010218a: 90 nop +c010218b: 66 c7 45 fa a0 00 movw $0xa0,-0x6(%ebp) +c0102191: c6 45 f9 68 movb $0x68,-0x7(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0102195: 0f b6 45 f9 movzbl -0x7(%ebp),%eax +c0102199: 0f b7 55 fa movzwl -0x6(%ebp),%edx +c010219d: ee out %al,(%dx) +} +c010219e: 90 nop +c010219f: 66 c7 45 fe a0 00 movw $0xa0,-0x2(%ebp) +c01021a5: c6 45 fd 0a movb $0xa,-0x3(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c01021a9: 0f b6 45 fd movzbl -0x3(%ebp),%eax +c01021ad: 0f b7 55 fe movzwl -0x2(%ebp),%edx +c01021b1: ee out %al,(%dx) +} +c01021b2: 90 nop + outb(IO_PIC1, 0x0a); // read IRR by default + + outb(IO_PIC2, 0x68); // OCW3 + outb(IO_PIC2, 0x0a); // OCW3 + + if (irq_mask != 0xFFFF) { +c01021b3: 0f b7 05 50 f5 12 c0 movzwl 0xc012f550,%eax +c01021ba: 3d ff ff 00 00 cmp $0xffff,%eax +c01021bf: 74 0f je c01021d0 + pic_setmask(irq_mask); +c01021c1: 0f b7 05 50 f5 12 c0 movzwl 0xc012f550,%eax +c01021c8: 89 04 24 mov %eax,(%esp) +c01021cb: e8 29 fe ff ff call c0101ff9 + } +} +c01021d0: 90 nop +c01021d1: 89 ec mov %ebp,%esp +c01021d3: 5d pop %ebp +c01021d4: c3 ret + +c01021d5 : +#include +#include + +#define TICK_NUM 100 + +static void print_ticks() { +c01021d5: 55 push %ebp +c01021d6: 89 e5 mov %esp,%ebp +c01021d8: 83 ec 18 sub $0x18,%esp + cprintf("%d ticks\n",TICK_NUM); +c01021db: c7 44 24 04 64 00 00 movl $0x64,0x4(%esp) +c01021e2: 00 +c01021e3: c7 04 24 c0 c3 10 c0 movl $0xc010c3c0,(%esp) +c01021ea: e8 89 e1 ff ff call c0100378 +#ifdef DEBUG_GRADE + cprintf("End of Test.\n"); + panic("EOT: kernel seems ok.");//panic 是一个用于处理内核崩溃的函数,它会打印出错误信息并导致系统停止运行。 +#endif +} +c01021ef: 90 nop +c01021f0: 89 ec mov %ebp,%esp +c01021f2: 5d pop %ebp +c01021f3: c3 ret + +c01021f4 : + sizeof(idt) - 1, (uintptr_t)idt +}; + +/* idt_init - initialize IDT to each of the entry points in kern/trap/vectors.S */ +void +idt_init(void) { +c01021f4: 55 push %ebp +c01021f5: 89 e5 mov %esp,%ebp +c01021f7: 83 ec 10 sub $0x10,%esp + * You don't know the meaning of this instruction? just google it! and check the libs/x86.h to know more. + * Notice: the argument of lidt is idt_pd. try to find it! + */ + extern uintptr_t __vectors[];//声明了一个外部数组 __vectors,该数组存储中断服务例程(ISR)的地址。 + int i; + for (i = 0; i < sizeof(idt) / sizeof(struct gatedesc); i ++) { +c01021fa: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) +c0102201: e9 c4 00 00 00 jmp c01022ca + SETGATE(idt[i], 0, GD_KTEXT, __vectors[i], DPL_KERNEL); +c0102206: 8b 45 fc mov -0x4(%ebp),%eax +c0102209: 8b 04 85 e0 f5 12 c0 mov -0x3fed0a20(,%eax,4),%eax +c0102210: 0f b7 d0 movzwl %ax,%edx +c0102213: 8b 45 fc mov -0x4(%ebp),%eax +c0102216: 66 89 14 c5 80 37 1a mov %dx,-0x3fe5c880(,%eax,8) +c010221d: c0 +c010221e: 8b 45 fc mov -0x4(%ebp),%eax +c0102221: 66 c7 04 c5 82 37 1a movw $0x8,-0x3fe5c87e(,%eax,8) +c0102228: c0 08 00 +c010222b: 8b 45 fc mov -0x4(%ebp),%eax +c010222e: 0f b6 14 c5 84 37 1a movzbl -0x3fe5c87c(,%eax,8),%edx +c0102235: c0 +c0102236: 80 e2 e0 and $0xe0,%dl +c0102239: 88 14 c5 84 37 1a c0 mov %dl,-0x3fe5c87c(,%eax,8) +c0102240: 8b 45 fc mov -0x4(%ebp),%eax +c0102243: 0f b6 14 c5 84 37 1a movzbl -0x3fe5c87c(,%eax,8),%edx +c010224a: c0 +c010224b: 80 e2 1f and $0x1f,%dl +c010224e: 88 14 c5 84 37 1a c0 mov %dl,-0x3fe5c87c(,%eax,8) +c0102255: 8b 45 fc mov -0x4(%ebp),%eax +c0102258: 0f b6 14 c5 85 37 1a movzbl -0x3fe5c87b(,%eax,8),%edx +c010225f: c0 +c0102260: 80 e2 f0 and $0xf0,%dl +c0102263: 80 ca 0e or $0xe,%dl +c0102266: 88 14 c5 85 37 1a c0 mov %dl,-0x3fe5c87b(,%eax,8) +c010226d: 8b 45 fc mov -0x4(%ebp),%eax +c0102270: 0f b6 14 c5 85 37 1a movzbl -0x3fe5c87b(,%eax,8),%edx +c0102277: c0 +c0102278: 80 e2 ef and $0xef,%dl +c010227b: 88 14 c5 85 37 1a c0 mov %dl,-0x3fe5c87b(,%eax,8) +c0102282: 8b 45 fc mov -0x4(%ebp),%eax +c0102285: 0f b6 14 c5 85 37 1a movzbl -0x3fe5c87b(,%eax,8),%edx +c010228c: c0 +c010228d: 80 e2 9f and $0x9f,%dl +c0102290: 88 14 c5 85 37 1a c0 mov %dl,-0x3fe5c87b(,%eax,8) +c0102297: 8b 45 fc mov -0x4(%ebp),%eax +c010229a: 0f b6 14 c5 85 37 1a movzbl -0x3fe5c87b(,%eax,8),%edx +c01022a1: c0 +c01022a2: 80 ca 80 or $0x80,%dl +c01022a5: 88 14 c5 85 37 1a c0 mov %dl,-0x3fe5c87b(,%eax,8) +c01022ac: 8b 45 fc mov -0x4(%ebp),%eax +c01022af: 8b 04 85 e0 f5 12 c0 mov -0x3fed0a20(,%eax,4),%eax +c01022b6: c1 e8 10 shr $0x10,%eax +c01022b9: 0f b7 d0 movzwl %ax,%edx +c01022bc: 8b 45 fc mov -0x4(%ebp),%eax +c01022bf: 66 89 14 c5 86 37 1a mov %dx,-0x3fe5c87a(,%eax,8) +c01022c6: c0 + for (i = 0; i < sizeof(idt) / sizeof(struct gatedesc); i ++) { +c01022c7: ff 45 fc incl -0x4(%ebp) +c01022ca: 8b 45 fc mov -0x4(%ebp),%eax +c01022cd: 3d ff 00 00 00 cmp $0xff,%eax +c01022d2: 0f 86 2e ff ff ff jbe c0102206 + //宏用于配置每个 IDT 条目.0 表示最高特权级(内核级)GD_KTEXT: 指向内核代码段的选择子,确保 ISR 在内核代码段中执行。 + //__vectors[i]: 对应中断的 ISR 地址,DPL_KERNEL: 描述符特权级,表示该中断只能由内核级代码触发。 + // set for switch from user to kernel + //SETGATE 这行代码特别设置了 T_SWITCH_TOK(一个特定的中断向量,用于用户态到内核态的切换)的 IDT 条目。 + //DPL_USER 表示该中断可以由用户态代码触发 + SETGATE(idt[T_SYSCALL], 1, GD_KTEXT, __vectors[T_SYSCALL], DPL_USER); +c01022d8: a1 e0 f7 12 c0 mov 0xc012f7e0,%eax +c01022dd: 0f b7 c0 movzwl %ax,%eax +c01022e0: 66 a3 80 3b 1a c0 mov %ax,0xc01a3b80 +c01022e6: 66 c7 05 82 3b 1a c0 movw $0x8,0xc01a3b82 +c01022ed: 08 00 +c01022ef: 0f b6 05 84 3b 1a c0 movzbl 0xc01a3b84,%eax +c01022f6: 24 e0 and $0xe0,%al +c01022f8: a2 84 3b 1a c0 mov %al,0xc01a3b84 +c01022fd: 0f b6 05 84 3b 1a c0 movzbl 0xc01a3b84,%eax +c0102304: 24 1f and $0x1f,%al +c0102306: a2 84 3b 1a c0 mov %al,0xc01a3b84 +c010230b: 0f b6 05 85 3b 1a c0 movzbl 0xc01a3b85,%eax +c0102312: 0c 0f or $0xf,%al +c0102314: a2 85 3b 1a c0 mov %al,0xc01a3b85 +c0102319: 0f b6 05 85 3b 1a c0 movzbl 0xc01a3b85,%eax +c0102320: 24 ef and $0xef,%al +c0102322: a2 85 3b 1a c0 mov %al,0xc01a3b85 +c0102327: 0f b6 05 85 3b 1a c0 movzbl 0xc01a3b85,%eax +c010232e: 0c 60 or $0x60,%al +c0102330: a2 85 3b 1a c0 mov %al,0xc01a3b85 +c0102335: 0f b6 05 85 3b 1a c0 movzbl 0xc01a3b85,%eax +c010233c: 0c 80 or $0x80,%al +c010233e: a2 85 3b 1a c0 mov %al,0xc01a3b85 +c0102343: a1 e0 f7 12 c0 mov 0xc012f7e0,%eax +c0102348: c1 e8 10 shr $0x10,%eax +c010234b: 0f b7 c0 movzwl %ax,%eax +c010234e: 66 a3 86 3b 1a c0 mov %ax,0xc01a3b86 +c0102354: c7 45 f8 60 f5 12 c0 movl $0xc012f560,-0x8(%ebp) + asm volatile ("lidt (%0)" :: "r" (pd) : "memory"); +c010235b: 8b 45 f8 mov -0x8(%ebp),%eax +c010235e: 0f 01 18 lidtl (%eax) +} +c0102361: 90 nop + //使用 lidt 指令将 IDT 描述符加载到 CPU 中 + lidt(&idt_pd); + /* LAB5 YOUR CODE */ + //you should update your lab1 code (just add ONE or TWO lines of code), let user app to use syscall to get the service of ucore + //so you should setup the syscall interrupt gate in here +} +c0102362: 90 nop +c0102363: 89 ec mov %ebp,%esp +c0102365: 5d pop %ebp +c0102366: c3 ret + +c0102367 : + +static const char * +trapname(int trapno) { +c0102367: 55 push %ebp +c0102368: 89 e5 mov %esp,%ebp + "Alignment Check", + "Machine-Check", + "SIMD Floating-Point Exception" + }; + //如果 trapno 小于数组长度,则返回对应的异常名称。 + if (trapno < sizeof(excnames)/sizeof(const char * const)) { +c010236a: 8b 45 08 mov 0x8(%ebp),%eax +c010236d: 83 f8 13 cmp $0x13,%eax +c0102370: 77 0c ja c010237e + return excnames[trapno]; +c0102372: 8b 45 08 mov 0x8(%ebp),%eax +c0102375: 8b 04 85 e0 c8 10 c0 mov -0x3fef3720(,%eax,4),%eax +c010237c: eb 18 jmp c0102396 + } + //如果 trapno 在 IRQ_OFFSET 和 IRQ_OFFSET + 16 之间,表示它是一个硬件中断 + if (trapno >= IRQ_OFFSET && trapno < IRQ_OFFSET + 16) { +c010237e: 83 7d 08 1f cmpl $0x1f,0x8(%ebp) +c0102382: 7e 0d jle c0102391 +c0102384: 83 7d 08 2f cmpl $0x2f,0x8(%ebp) +c0102388: 7f 07 jg c0102391 + return "Hardware Interrupt"; +c010238a: b8 ca c3 10 c0 mov $0xc010c3ca,%eax +c010238f: eb 05 jmp c0102396 + } + return "(unknown trap)"; +c0102391: b8 dd c3 10 c0 mov $0xc010c3dd,%eax +} +c0102396: 5d pop %ebp +c0102397: c3 ret + +c0102398 : + +/* trap_in_kernel - test if trap happened in kernel */ +bool +trap_in_kernel(struct trapframe *tf) { +c0102398: 55 push %ebp +c0102399: 89 e5 mov %esp,%ebp + return (tf->tf_cs == (uint16_t)KERNEL_CS); +c010239b: 8b 45 08 mov 0x8(%ebp),%eax +c010239e: 0f b7 40 3c movzwl 0x3c(%eax),%eax +c01023a2: 83 f8 08 cmp $0x8,%eax +c01023a5: 0f 94 c0 sete %al +c01023a8: 0f b6 c0 movzbl %al,%eax + //函数通过检查 tf 中的 tf_cs 字段来判断当前处于哪个特权级,tf_cs 存储了当前代码段选择子的值 + //当 tf->tf_cs 等于 KERNEL_CS 时,表示陷阱发生在内核模式下 +} +c01023ab: 5d pop %ebp +c01023ac: c3 ret + +c01023ad : + "RF", "VM", "AC", "VIF", "VIP", "ID", NULL, NULL, +}; + +//struct trapframe *tf,一个指向 trapframe 结构的指针,包含有关陷阱发生时的 CPU 状态的信息。 +void +print_trapframe(struct trapframe *tf) { +c01023ad: 55 push %ebp +c01023ae: 89 e5 mov %esp,%ebp +c01023b0: 83 ec 28 sub $0x28,%esp + cprintf("trapframe at %p\n", tf); //打印陷阱框架地址 +c01023b3: 8b 45 08 mov 0x8(%ebp),%eax +c01023b6: 89 44 24 04 mov %eax,0x4(%esp) +c01023ba: c7 04 24 1e c4 10 c0 movl $0xc010c41e,(%esp) +c01023c1: e8 b2 df ff ff call c0100378 + print_regs(&tf->tf_regs); //打印寄存器状态 +c01023c6: 8b 45 08 mov 0x8(%ebp),%eax +c01023c9: 89 04 24 mov %eax,(%esp) +c01023cc: e8 8f 01 00 00 call c0102560 + //打印数据段(DS)、扩展段(ES)、文件段(FS)、通用段(GS)的值。 + cprintf(" ds 0x----%04x\n", tf->tf_ds); +c01023d1: 8b 45 08 mov 0x8(%ebp),%eax +c01023d4: 0f b7 40 2c movzwl 0x2c(%eax),%eax +c01023d8: 89 44 24 04 mov %eax,0x4(%esp) +c01023dc: c7 04 24 2f c4 10 c0 movl $0xc010c42f,(%esp) +c01023e3: e8 90 df ff ff call c0100378 + cprintf(" es 0x----%04x\n", tf->tf_es); +c01023e8: 8b 45 08 mov 0x8(%ebp),%eax +c01023eb: 0f b7 40 28 movzwl 0x28(%eax),%eax +c01023ef: 89 44 24 04 mov %eax,0x4(%esp) +c01023f3: c7 04 24 42 c4 10 c0 movl $0xc010c442,(%esp) +c01023fa: e8 79 df ff ff call c0100378 + cprintf(" fs 0x----%04x\n", tf->tf_fs); +c01023ff: 8b 45 08 mov 0x8(%ebp),%eax +c0102402: 0f b7 40 24 movzwl 0x24(%eax),%eax +c0102406: 89 44 24 04 mov %eax,0x4(%esp) +c010240a: c7 04 24 55 c4 10 c0 movl $0xc010c455,(%esp) +c0102411: e8 62 df ff ff call c0100378 + cprintf(" gs 0x----%04x\n", tf->tf_gs); +c0102416: 8b 45 08 mov 0x8(%ebp),%eax +c0102419: 0f b7 40 20 movzwl 0x20(%eax),%eax +c010241d: 89 44 24 04 mov %eax,0x4(%esp) +c0102421: c7 04 24 68 c4 10 c0 movl $0xc010c468,(%esp) +c0102428: e8 4b df ff ff call c0100378 + // 打印陷阱号(trap number)及其对应的名称,通过调用 trapname 函数获取。 + cprintf(" trap 0x%08x %s\n", tf->tf_trapno, trapname(tf->tf_trapno)); +c010242d: 8b 45 08 mov 0x8(%ebp),%eax +c0102430: 8b 40 30 mov 0x30(%eax),%eax +c0102433: 89 04 24 mov %eax,(%esp) +c0102436: e8 2c ff ff ff call c0102367 +c010243b: 8b 55 08 mov 0x8(%ebp),%edx +c010243e: 8b 52 30 mov 0x30(%edx),%edx +c0102441: 89 44 24 08 mov %eax,0x8(%esp) +c0102445: 89 54 24 04 mov %edx,0x4(%esp) +c0102449: c7 04 24 7b c4 10 c0 movl $0xc010c47b,(%esp) +c0102450: e8 23 df ff ff call c0100378 + cprintf(" err 0x%08x\n", tf->tf_err);// 如果有错误代码,打印该字段的值。 +c0102455: 8b 45 08 mov 0x8(%ebp),%eax +c0102458: 8b 40 34 mov 0x34(%eax),%eax +c010245b: 89 44 24 04 mov %eax,0x4(%esp) +c010245f: c7 04 24 8d c4 10 c0 movl $0xc010c48d,(%esp) +c0102466: e8 0d df ff ff call c0100378 + cprintf(" eip 0x%08x\n", tf->tf_eip);//打印当前执行的指令指针(EIP),指向出错或中断的指令。 +c010246b: 8b 45 08 mov 0x8(%ebp),%eax +c010246e: 8b 40 38 mov 0x38(%eax),%eax +c0102471: 89 44 24 04 mov %eax,0x4(%esp) +c0102475: c7 04 24 9c c4 10 c0 movl $0xc010c49c,(%esp) +c010247c: e8 f7 de ff ff call c0100378 + cprintf(" cs 0x----%04x\n", tf->tf_cs);//打印代码段寄存器(CS)的值。 +c0102481: 8b 45 08 mov 0x8(%ebp),%eax +c0102484: 0f b7 40 3c movzwl 0x3c(%eax),%eax +c0102488: 89 44 24 04 mov %eax,0x4(%esp) +c010248c: c7 04 24 ab c4 10 c0 movl $0xc010c4ab,(%esp) +c0102493: e8 e0 de ff ff call c0100378 + cprintf(" flag 0x%08x ", tf->tf_eflags);// 打印标志寄存器(EFLAGS)的值 +c0102498: 8b 45 08 mov 0x8(%ebp),%eax +c010249b: 8b 40 40 mov 0x40(%eax),%eax +c010249e: 89 44 24 04 mov %eax,0x4(%esp) +c01024a2: c7 04 24 be c4 10 c0 movl $0xc010c4be,(%esp) +c01024a9: e8 ca de ff ff call c0100378 + //使用循环遍历 IA32flags 数组,j 表示当前标志位的位掩码。 + int i, j; + for (i = 0, j = 1; i < sizeof(IA32flags) / sizeof(IA32flags[0]); i ++, j <<= 1) { +c01024ae: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) +c01024b5: c7 45 f0 01 00 00 00 movl $0x1,-0x10(%ebp) +c01024bc: eb 3d jmp c01024fb + if ((tf->tf_eflags & j) && IA32flags[i] != NULL) { +c01024be: 8b 45 08 mov 0x8(%ebp),%eax +c01024c1: 8b 50 40 mov 0x40(%eax),%edx +c01024c4: 8b 45 f0 mov -0x10(%ebp),%eax +c01024c7: 21 d0 and %edx,%eax +c01024c9: 85 c0 test %eax,%eax +c01024cb: 74 28 je c01024f5 +c01024cd: 8b 45 f4 mov -0xc(%ebp),%eax +c01024d0: 8b 04 85 80 f5 12 c0 mov -0x3fed0a80(,%eax,4),%eax +c01024d7: 85 c0 test %eax,%eax +c01024d9: 74 1a je c01024f5 + cprintf("%s,", IA32flags[i]); +c01024db: 8b 45 f4 mov -0xc(%ebp),%eax +c01024de: 8b 04 85 80 f5 12 c0 mov -0x3fed0a80(,%eax,4),%eax +c01024e5: 89 44 24 04 mov %eax,0x4(%esp) +c01024e9: c7 04 24 cd c4 10 c0 movl $0xc010c4cd,(%esp) +c01024f0: e8 83 de ff ff call c0100378 + for (i = 0, j = 1; i < sizeof(IA32flags) / sizeof(IA32flags[0]); i ++, j <<= 1) { +c01024f5: ff 45 f4 incl -0xc(%ebp) +c01024f8: d1 65 f0 shll -0x10(%ebp) +c01024fb: 8b 45 f4 mov -0xc(%ebp),%eax +c01024fe: 83 f8 17 cmp $0x17,%eax +c0102501: 76 bb jbe c01024be + } + } + //通过位掩码 FL_IOPL_MASK 获取和打印当前的 I/O 特权级别。 + cprintf("IOPL=%d\n", (tf->tf_eflags & FL_IOPL_MASK) >> 12); +c0102503: 8b 45 08 mov 0x8(%ebp),%eax +c0102506: 8b 40 40 mov 0x40(%eax),%eax +c0102509: c1 e8 0c shr $0xc,%eax +c010250c: 83 e0 03 and $0x3,%eax +c010250f: 89 44 24 04 mov %eax,0x4(%esp) +c0102513: c7 04 24 d1 c4 10 c0 movl $0xc010c4d1,(%esp) +c010251a: e8 59 de ff ff call c0100378 + //如果陷阱不是在内核中发生的(通过 trap_in_kernel 判断), + //则打印栈指针(ESP)和栈段(SS)寄存器的值。 + if (!trap_in_kernel(tf)) { +c010251f: 8b 45 08 mov 0x8(%ebp),%eax +c0102522: 89 04 24 mov %eax,(%esp) +c0102525: e8 6e fe ff ff call c0102398 +c010252a: 85 c0 test %eax,%eax +c010252c: 75 2d jne c010255b + cprintf(" esp 0x%08x\n", tf->tf_esp); +c010252e: 8b 45 08 mov 0x8(%ebp),%eax +c0102531: 8b 40 44 mov 0x44(%eax),%eax +c0102534: 89 44 24 04 mov %eax,0x4(%esp) +c0102538: c7 04 24 da c4 10 c0 movl $0xc010c4da,(%esp) +c010253f: e8 34 de ff ff call c0100378 + cprintf(" ss 0x----%04x\n", tf->tf_ss); +c0102544: 8b 45 08 mov 0x8(%ebp),%eax +c0102547: 0f b7 40 48 movzwl 0x48(%eax),%eax +c010254b: 89 44 24 04 mov %eax,0x4(%esp) +c010254f: c7 04 24 e9 c4 10 c0 movl $0xc010c4e9,(%esp) +c0102556: e8 1d de ff ff call c0100378 + } +} +c010255b: 90 nop +c010255c: 89 ec mov %ebp,%esp +c010255e: 5d pop %ebp +c010255f: c3 ret + +c0102560 : +//定义了一个名为 print_regs 的函数, +//打印出存储在 struct pushregs 结构体中的寄存器值。 +void +print_regs(struct pushregs *regs) { +c0102560: 55 push %ebp +c0102561: 89 e5 mov %esp,%ebp +c0102563: 83 ec 18 sub $0x18,%esp + cprintf(" edi 0x%08x\n", regs->reg_edi); +c0102566: 8b 45 08 mov 0x8(%ebp),%eax +c0102569: 8b 00 mov (%eax),%eax +c010256b: 89 44 24 04 mov %eax,0x4(%esp) +c010256f: c7 04 24 fc c4 10 c0 movl $0xc010c4fc,(%esp) +c0102576: e8 fd dd ff ff call c0100378 + cprintf(" esi 0x%08x\n", regs->reg_esi); +c010257b: 8b 45 08 mov 0x8(%ebp),%eax +c010257e: 8b 40 04 mov 0x4(%eax),%eax +c0102581: 89 44 24 04 mov %eax,0x4(%esp) +c0102585: c7 04 24 0b c5 10 c0 movl $0xc010c50b,(%esp) +c010258c: e8 e7 dd ff ff call c0100378 + cprintf(" ebp 0x%08x\n", regs->reg_ebp); +c0102591: 8b 45 08 mov 0x8(%ebp),%eax +c0102594: 8b 40 08 mov 0x8(%eax),%eax +c0102597: 89 44 24 04 mov %eax,0x4(%esp) +c010259b: c7 04 24 1a c5 10 c0 movl $0xc010c51a,(%esp) +c01025a2: e8 d1 dd ff ff call c0100378 + cprintf(" oesp 0x%08x\n", regs->reg_oesp);//打印旧的栈指针(OESP),这个寄存器通常在陷阱或中断发生时用于记录上一个栈指针。 +c01025a7: 8b 45 08 mov 0x8(%ebp),%eax +c01025aa: 8b 40 0c mov 0xc(%eax),%eax +c01025ad: 89 44 24 04 mov %eax,0x4(%esp) +c01025b1: c7 04 24 29 c5 10 c0 movl $0xc010c529,(%esp) +c01025b8: e8 bb dd ff ff call c0100378 + cprintf(" ebx 0x%08x\n", regs->reg_ebx); +c01025bd: 8b 45 08 mov 0x8(%ebp),%eax +c01025c0: 8b 40 10 mov 0x10(%eax),%eax +c01025c3: 89 44 24 04 mov %eax,0x4(%esp) +c01025c7: c7 04 24 38 c5 10 c0 movl $0xc010c538,(%esp) +c01025ce: e8 a5 dd ff ff call c0100378 + cprintf(" edx 0x%08x\n", regs->reg_edx); +c01025d3: 8b 45 08 mov 0x8(%ebp),%eax +c01025d6: 8b 40 14 mov 0x14(%eax),%eax +c01025d9: 89 44 24 04 mov %eax,0x4(%esp) +c01025dd: c7 04 24 47 c5 10 c0 movl $0xc010c547,(%esp) +c01025e4: e8 8f dd ff ff call c0100378 + cprintf(" ecx 0x%08x\n", regs->reg_ecx); +c01025e9: 8b 45 08 mov 0x8(%ebp),%eax +c01025ec: 8b 40 18 mov 0x18(%eax),%eax +c01025ef: 89 44 24 04 mov %eax,0x4(%esp) +c01025f3: c7 04 24 56 c5 10 c0 movl $0xc010c556,(%esp) +c01025fa: e8 79 dd ff ff call c0100378 + cprintf(" eax 0x%08x\n", regs->reg_eax); +c01025ff: 8b 45 08 mov 0x8(%ebp),%eax +c0102602: 8b 40 1c mov 0x1c(%eax),%eax +c0102605: 89 44 24 04 mov %eax,0x4(%esp) +c0102609: c7 04 24 65 c5 10 c0 movl $0xc010c565,(%esp) +c0102610: e8 63 dd ff ff call c0100378 +} +c0102615: 90 nop +c0102616: 89 ec mov %ebp,%esp +c0102618: 5d pop %ebp +c0102619: c3 ret + +c010261a : + +static inline void +print_pgfault(struct trapframe *tf) { +c010261a: 55 push %ebp +c010261b: 89 e5 mov %esp,%ebp +c010261d: 83 ec 38 sub $0x38,%esp +c0102620: 89 5d fc mov %ebx,-0x4(%ebp) + * bit 2 == 0 表示内核模式,1 表示用户模式 + * */ + cprintf("page fault at 0x%08x: %c/%c [%s].\n", rcr2(), + (tf->tf_err & 4) ? 'U' : 'K', + (tf->tf_err & 2) ? 'W' : 'R', + (tf->tf_err & 1) ? "protection fault" : "no page found"); +c0102623: 8b 45 08 mov 0x8(%ebp),%eax +c0102626: 8b 40 34 mov 0x34(%eax),%eax +c0102629: 83 e0 01 and $0x1,%eax + cprintf("page fault at 0x%08x: %c/%c [%s].\n", rcr2(), +c010262c: 85 c0 test %eax,%eax +c010262e: 74 07 je c0102637 +c0102630: bb 74 c5 10 c0 mov $0xc010c574,%ebx +c0102635: eb 05 jmp c010263c +c0102637: bb 85 c5 10 c0 mov $0xc010c585,%ebx + (tf->tf_err & 2) ? 'W' : 'R', +c010263c: 8b 45 08 mov 0x8(%ebp),%eax +c010263f: 8b 40 34 mov 0x34(%eax),%eax +c0102642: 83 e0 02 and $0x2,%eax + cprintf("page fault at 0x%08x: %c/%c [%s].\n", rcr2(), +c0102645: 85 c0 test %eax,%eax +c0102647: 74 07 je c0102650 +c0102649: b9 57 00 00 00 mov $0x57,%ecx +c010264e: eb 05 jmp c0102655 +c0102650: b9 52 00 00 00 mov $0x52,%ecx + (tf->tf_err & 4) ? 'U' : 'K', +c0102655: 8b 45 08 mov 0x8(%ebp),%eax +c0102658: 8b 40 34 mov 0x34(%eax),%eax +c010265b: 83 e0 04 and $0x4,%eax + cprintf("page fault at 0x%08x: %c/%c [%s].\n", rcr2(), +c010265e: 85 c0 test %eax,%eax +c0102660: 74 07 je c0102669 +c0102662: ba 55 00 00 00 mov $0x55,%edx +c0102667: eb 05 jmp c010266e +c0102669: ba 4b 00 00 00 mov $0x4b,%edx +} + +static inline uintptr_t +rcr2(void) { + uintptr_t cr2; + asm volatile ("mov %%cr2, %0" : "=r" (cr2) :: "memory"); +c010266e: 0f 20 d0 mov %cr2,%eax +c0102671: 89 45 f4 mov %eax,-0xc(%ebp) + return cr2; +c0102674: 8b 45 f4 mov -0xc(%ebp),%eax +c0102677: 89 5c 24 10 mov %ebx,0x10(%esp) +c010267b: 89 4c 24 0c mov %ecx,0xc(%esp) +c010267f: 89 54 24 08 mov %edx,0x8(%esp) +c0102683: 89 44 24 04 mov %eax,0x4(%esp) +c0102687: c7 04 24 94 c5 10 c0 movl $0xc010c594,(%esp) +c010268e: e8 e5 dc ff ff call c0100378 +} +c0102693: 90 nop +c0102694: 8b 5d fc mov -0x4(%ebp),%ebx +c0102697: 89 ec mov %ebp,%esp +c0102699: 5d pop %ebp +c010269a: c3 ret + +c010269b : + +static int +pgfault_handler(struct trapframe *tf) { +c010269b: 55 push %ebp +c010269c: 89 e5 mov %esp,%ebp +c010269e: 83 ec 28 sub $0x28,%esp + extern struct mm_struct *check_mm_struct; + if(check_mm_struct !=NULL) { //used for test check_swap +c01026a1: a1 0c 41 1a c0 mov 0xc01a410c,%eax +c01026a6: 85 c0 test %eax,%eax +c01026a8: 74 0b je c01026b5 + print_pgfault(tf); +c01026aa: 8b 45 08 mov 0x8(%ebp),%eax +c01026ad: 89 04 24 mov %eax,(%esp) +c01026b0: e8 65 ff ff ff call c010261a + } + struct mm_struct *mm; + if (check_mm_struct != NULL) { +c01026b5: a1 0c 41 1a c0 mov 0xc01a410c,%eax +c01026ba: 85 c0 test %eax,%eax +c01026bc: 74 3d je c01026fb + assert(current == idleproc); +c01026be: 8b 15 30 41 1a c0 mov 0xc01a4130,%edx +c01026c4: a1 28 41 1a c0 mov 0xc01a4128,%eax +c01026c9: 39 c2 cmp %eax,%edx +c01026cb: 74 24 je c01026f1 +c01026cd: c7 44 24 0c b7 c5 10 movl $0xc010c5b7,0xc(%esp) +c01026d4: c0 +c01026d5: c7 44 24 08 cb c5 10 movl $0xc010c5cb,0x8(%esp) +c01026dc: c0 +c01026dd: c7 44 24 04 c7 00 00 movl $0xc7,0x4(%esp) +c01026e4: 00 +c01026e5: c7 04 24 e0 c5 10 c0 movl $0xc010c5e0,(%esp) +c01026ec: e8 4a e6 ff ff call c0100d3b <__panic> + mm = check_mm_struct; +c01026f1: a1 0c 41 1a c0 mov 0xc01a410c,%eax +c01026f6: 89 45 f4 mov %eax,-0xc(%ebp) +c01026f9: eb 46 jmp c0102741 + } + else { + if (current == NULL) { +c01026fb: a1 30 41 1a c0 mov 0xc01a4130,%eax +c0102700: 85 c0 test %eax,%eax +c0102702: 75 32 jne c0102736 + print_trapframe(tf); +c0102704: 8b 45 08 mov 0x8(%ebp),%eax +c0102707: 89 04 24 mov %eax,(%esp) +c010270a: e8 9e fc ff ff call c01023ad + print_pgfault(tf); +c010270f: 8b 45 08 mov 0x8(%ebp),%eax +c0102712: 89 04 24 mov %eax,(%esp) +c0102715: e8 00 ff ff ff call c010261a + panic("unhandled page fault.\n"); +c010271a: c7 44 24 08 f1 c5 10 movl $0xc010c5f1,0x8(%esp) +c0102721: c0 +c0102722: c7 44 24 04 ce 00 00 movl $0xce,0x4(%esp) +c0102729: 00 +c010272a: c7 04 24 e0 c5 10 c0 movl $0xc010c5e0,(%esp) +c0102731: e8 05 e6 ff ff call c0100d3b <__panic> + } + mm = current->mm; +c0102736: a1 30 41 1a c0 mov 0xc01a4130,%eax +c010273b: 8b 40 18 mov 0x18(%eax),%eax +c010273e: 89 45 f4 mov %eax,-0xc(%ebp) + asm volatile ("mov %%cr2, %0" : "=r" (cr2) :: "memory"); +c0102741: 0f 20 d0 mov %cr2,%eax +c0102744: 89 45 f0 mov %eax,-0x10(%ebp) + return cr2; +c0102747: 8b 55 f0 mov -0x10(%ebp),%edx + } + return do_pgfault(mm, tf->tf_err, rcr2()); +c010274a: 8b 45 08 mov 0x8(%ebp),%eax +c010274d: 8b 40 34 mov 0x34(%eax),%eax +c0102750: 89 54 24 08 mov %edx,0x8(%esp) +c0102754: 89 44 24 04 mov %eax,0x4(%esp) +c0102758: 8b 45 f4 mov -0xc(%ebp),%eax +c010275b: 89 04 24 mov %eax,(%esp) +c010275e: e8 e0 66 00 00 call c0108e43 +} +c0102763: 89 ec mov %ebp,%esp +c0102765: 5d pop %ebp +c0102766: c3 ret + +c0102767 : + +static volatile int in_swap_tick_event = 0; +extern struct mm_struct *check_mm_struct; + +static void +trap_dispatch(struct trapframe *tf) { +c0102767: 55 push %ebp +c0102768: 89 e5 mov %esp,%ebp +c010276a: 83 ec 28 sub $0x28,%esp + char c; + + int ret=0; +c010276d: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + + switch (tf->tf_trapno) { +c0102774: 8b 45 08 mov 0x8(%ebp),%eax +c0102777: 8b 40 30 mov 0x30(%eax),%eax +c010277a: 3d 80 00 00 00 cmp $0x80,%eax +c010277f: 0f 84 ef 00 00 00 je c0102874 +c0102785: 3d 80 00 00 00 cmp $0x80,%eax +c010278a: 0f 87 d3 01 00 00 ja c0102963 +c0102790: 83 f8 2f cmp $0x2f,%eax +c0102793: 77 1e ja c01027b3 +c0102795: 83 f8 0e cmp $0xe,%eax +c0102798: 0f 82 c5 01 00 00 jb c0102963 +c010279e: 83 e8 0e sub $0xe,%eax +c01027a1: 83 f8 21 cmp $0x21,%eax +c01027a4: 0f 87 b9 01 00 00 ja c0102963 +c01027aa: 8b 04 85 04 c7 10 c0 mov -0x3fef38fc(,%eax,4),%eax +c01027b1: ff e0 jmp *%eax +c01027b3: 83 e8 78 sub $0x78,%eax +c01027b6: 83 f8 01 cmp $0x1,%eax +c01027b9: 0f 87 a4 01 00 00 ja c0102963 +c01027bf: e9 83 01 00 00 jmp c0102947 + case T_PGFLT: //page fault + if ((ret = pgfault_handler(tf)) != 0) { +c01027c4: 8b 45 08 mov 0x8(%ebp),%eax +c01027c7: 89 04 24 mov %eax,(%esp) +c01027ca: e8 cc fe ff ff call c010269b +c01027cf: 89 45 f4 mov %eax,-0xc(%ebp) +c01027d2: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c01027d6: 0f 84 d2 01 00 00 je c01029ae + print_trapframe(tf); +c01027dc: 8b 45 08 mov 0x8(%ebp),%eax +c01027df: 89 04 24 mov %eax,(%esp) +c01027e2: e8 c6 fb ff ff call c01023ad + if (current == NULL) { +c01027e7: a1 30 41 1a c0 mov 0xc01a4130,%eax +c01027ec: 85 c0 test %eax,%eax +c01027ee: 75 23 jne c0102813 + panic("handle pgfault failed. ret=%d\n", ret); +c01027f0: 8b 45 f4 mov -0xc(%ebp),%eax +c01027f3: 89 44 24 0c mov %eax,0xc(%esp) +c01027f7: c7 44 24 08 08 c6 10 movl $0xc010c608,0x8(%esp) +c01027fe: c0 +c01027ff: c7 44 24 04 e3 00 00 movl $0xe3,0x4(%esp) +c0102806: 00 +c0102807: c7 04 24 e0 c5 10 c0 movl $0xc010c5e0,(%esp) +c010280e: e8 28 e5 ff ff call c0100d3b <__panic> + } + else { + if (trap_in_kernel(tf)) { +c0102813: 8b 45 08 mov 0x8(%ebp),%eax +c0102816: 89 04 24 mov %eax,(%esp) +c0102819: e8 7a fb ff ff call c0102398 +c010281e: 85 c0 test %eax,%eax +c0102820: 74 23 je c0102845 + panic("handle pgfault failed in kernel mode. ret=%d\n", ret); +c0102822: 8b 45 f4 mov -0xc(%ebp),%eax +c0102825: 89 44 24 0c mov %eax,0xc(%esp) +c0102829: c7 44 24 08 28 c6 10 movl $0xc010c628,0x8(%esp) +c0102830: c0 +c0102831: c7 44 24 04 e7 00 00 movl $0xe7,0x4(%esp) +c0102838: 00 +c0102839: c7 04 24 e0 c5 10 c0 movl $0xc010c5e0,(%esp) +c0102840: e8 f6 e4 ff ff call c0100d3b <__panic> + } + cprintf("killed by kernel.\n"); +c0102845: c7 04 24 56 c6 10 c0 movl $0xc010c656,(%esp) +c010284c: e8 27 db ff ff call c0100378 + panic("handle user mode pgfault failed. ret=%d\n", ret); +c0102851: 8b 45 f4 mov -0xc(%ebp),%eax +c0102854: 89 44 24 0c mov %eax,0xc(%esp) +c0102858: c7 44 24 08 6c c6 10 movl $0xc010c66c,0x8(%esp) +c010285f: c0 +c0102860: c7 44 24 04 ea 00 00 movl $0xea,0x4(%esp) +c0102867: 00 +c0102868: c7 04 24 e0 c5 10 c0 movl $0xc010c5e0,(%esp) +c010286f: e8 c7 e4 ff ff call c0100d3b <__panic> + do_exit(-E_KILLED); + } + } + break; + case T_SYSCALL: + syscall(); +c0102874: e8 13 8a 00 00 call c010b28c + break; +c0102879: e9 34 01 00 00 jmp c01029b2 + */ + /* LAB5 YOUR CODE */ + /* you should upate you lab1 code (just add ONE or TWO lines of code): + * Every TICK_NUM cycle, you should set current process's current->need_resched = 1 + */ + ticks ++; //记录中断事件 +c010287e: a1 24 34 1a c0 mov 0xc01a3424,%eax +c0102883: 40 inc %eax +c0102884: a3 24 34 1a c0 mov %eax,0xc01a3424 + if (ticks % TICK_NUM == 0) +c0102889: 8b 0d 24 34 1a c0 mov 0xc01a3424,%ecx +c010288f: ba 1f 85 eb 51 mov $0x51eb851f,%edx +c0102894: 89 c8 mov %ecx,%eax +c0102896: f7 e2 mul %edx +c0102898: c1 ea 05 shr $0x5,%edx +c010289b: 89 d0 mov %edx,%eax +c010289d: c1 e0 02 shl $0x2,%eax +c01028a0: 01 d0 add %edx,%eax +c01028a2: 8d 14 85 00 00 00 00 lea 0x0(,%eax,4),%edx +c01028a9: 01 d0 add %edx,%eax +c01028ab: c1 e0 02 shl $0x2,%eax +c01028ae: 29 c1 sub %eax,%ecx +c01028b0: 89 ca mov %ecx,%edx +c01028b2: 85 d2 test %edx,%edx +c01028b4: 0f 85 f7 00 00 00 jne c01029b1 + { + assert(current != NULL); +c01028ba: a1 30 41 1a c0 mov 0xc01a4130,%eax +c01028bf: 85 c0 test %eax,%eax +c01028c1: 75 24 jne c01028e7 +c01028c3: c7 44 24 0c 95 c6 10 movl $0xc010c695,0xc(%esp) +c01028ca: c0 +c01028cb: c7 44 24 08 cb c5 10 movl $0xc010c5cb,0x8(%esp) +c01028d2: c0 +c01028d3: c7 44 24 04 04 01 00 movl $0x104,0x4(%esp) +c01028da: 00 +c01028db: c7 04 24 e0 c5 10 c0 movl $0xc010c5e0,(%esp) +c01028e2: e8 54 e4 ff ff call c0100d3b <__panic> + current->need_resched = 1; +c01028e7: a1 30 41 1a c0 mov 0xc01a4130,%eax +c01028ec: c7 40 10 01 00 00 00 movl $0x1,0x10(%eax) + }//每经过 TICK_NUM 次周期时,调用 print_ticks() 打印信息 + break; +c01028f3: e9 b9 00 00 00 jmp c01029b1 + case IRQ_OFFSET + IRQ_COM1: + c = cons_getc(); +c01028f8: e8 1e ee ff ff call c010171b +c01028fd: 88 45 f3 mov %al,-0xd(%ebp) + cprintf("serial [%03d] %c\n", c, c); +c0102900: 0f be 55 f3 movsbl -0xd(%ebp),%edx +c0102904: 0f be 45 f3 movsbl -0xd(%ebp),%eax +c0102908: 89 54 24 08 mov %edx,0x8(%esp) +c010290c: 89 44 24 04 mov %eax,0x4(%esp) +c0102910: c7 04 24 a5 c6 10 c0 movl $0xc010c6a5,(%esp) +c0102917: e8 5c da ff ff call c0100378 + break; +c010291c: e9 91 00 00 00 jmp c01029b2 + case IRQ_OFFSET + IRQ_KBD: + c = cons_getc(); +c0102921: e8 f5 ed ff ff call c010171b +c0102926: 88 45 f3 mov %al,-0xd(%ebp) + cprintf("kbd [%03d] %c\n", c, c); +c0102929: 0f be 55 f3 movsbl -0xd(%ebp),%edx +c010292d: 0f be 45 f3 movsbl -0xd(%ebp),%eax +c0102931: 89 54 24 08 mov %edx,0x8(%esp) +c0102935: 89 44 24 04 mov %eax,0x4(%esp) +c0102939: c7 04 24 b7 c6 10 c0 movl $0xc010c6b7,(%esp) +c0102940: e8 33 da ff ff call c0100378 + break; +c0102945: eb 6b jmp c01029b2 + //LAB1 CHALLENGE 1 : YOUR CODE you should modify below codes. + case T_SWITCH_TOU: + case T_SWITCH_TOK: + panic("T_SWITCH_** ??\n"); +c0102947: c7 44 24 08 c6 c6 10 movl $0xc010c6c6,0x8(%esp) +c010294e: c0 +c010294f: c7 44 24 04 13 01 00 movl $0x113,0x4(%esp) +c0102956: 00 +c0102957: c7 04 24 e0 c5 10 c0 movl $0xc010c5e0,(%esp) +c010295e: e8 d8 e3 ff ff call c0100d3b <__panic> + case IRQ_OFFSET + IRQ_IDE1: + case IRQ_OFFSET + IRQ_IDE2: + /* do nothing */ + break; + default: + print_trapframe(tf); +c0102963: 8b 45 08 mov 0x8(%ebp),%eax +c0102966: 89 04 24 mov %eax,(%esp) +c0102969: e8 3f fa ff ff call c01023ad + if (current != NULL) { +c010296e: a1 30 41 1a c0 mov 0xc01a4130,%eax +c0102973: 85 c0 test %eax,%eax +c0102975: 74 18 je c010298f + cprintf("unhandled trap.\n"); +c0102977: c7 04 24 d6 c6 10 c0 movl $0xc010c6d6,(%esp) +c010297e: e8 f5 d9 ff ff call c0100378 + do_exit(-E_KILLED); +c0102983: c7 04 24 f7 ff ff ff movl $0xfffffff7,(%esp) +c010298a: e8 81 76 00 00 call c010a010 + } + // in kernel, it must be a mistake + panic("unexpected trap in kernel.\n"); +c010298f: c7 44 24 08 e7 c6 10 movl $0xc010c6e7,0x8(%esp) +c0102996: c0 +c0102997: c7 44 24 04 20 01 00 movl $0x120,0x4(%esp) +c010299e: 00 +c010299f: c7 04 24 e0 c5 10 c0 movl $0xc010c5e0,(%esp) +c01029a6: e8 90 e3 ff ff call c0100d3b <__panic> + break; +c01029ab: 90 nop +c01029ac: eb 04 jmp c01029b2 + break; +c01029ae: 90 nop +c01029af: eb 01 jmp c01029b2 + break; +c01029b1: 90 nop + + } +} +c01029b2: 90 nop +c01029b3: 89 ec mov %ebp,%esp +c01029b5: 5d pop %ebp +c01029b6: c3 ret + +c01029b7 : + * trap - handles or dispatches an exception/interrupt. if and when trap() returns, + * the code in kern/trap/trapentry.S restores the old CPU state saved in the + * trapframe and then uses the iret instruction to return from the exception. + * */ +void +trap(struct trapframe *tf) { +c01029b7: 55 push %ebp +c01029b8: 89 e5 mov %esp,%ebp +c01029ba: 83 ec 28 sub $0x28,%esp + // dispatch based on what type of trap occurred + // used for previous projects + if (current == NULL) { +c01029bd: a1 30 41 1a c0 mov 0xc01a4130,%eax +c01029c2: 85 c0 test %eax,%eax +c01029c4: 75 0d jne c01029d3 + trap_dispatch(tf); +c01029c6: 8b 45 08 mov 0x8(%ebp),%eax +c01029c9: 89 04 24 mov %eax,(%esp) +c01029cc: e8 96 fd ff ff call c0102767 + if (current->need_resched) { + schedule(); + } + } + } +} +c01029d1: eb 6c jmp c0102a3f + struct trapframe *otf = current->tf; +c01029d3: a1 30 41 1a c0 mov 0xc01a4130,%eax +c01029d8: 8b 40 3c mov 0x3c(%eax),%eax +c01029db: 89 45 f4 mov %eax,-0xc(%ebp) + current->tf = tf; +c01029de: a1 30 41 1a c0 mov 0xc01a4130,%eax +c01029e3: 8b 55 08 mov 0x8(%ebp),%edx +c01029e6: 89 50 3c mov %edx,0x3c(%eax) + bool in_kernel = trap_in_kernel(tf); +c01029e9: 8b 45 08 mov 0x8(%ebp),%eax +c01029ec: 89 04 24 mov %eax,(%esp) +c01029ef: e8 a4 f9 ff ff call c0102398 +c01029f4: 89 45 f0 mov %eax,-0x10(%ebp) + trap_dispatch(tf); +c01029f7: 8b 45 08 mov 0x8(%ebp),%eax +c01029fa: 89 04 24 mov %eax,(%esp) +c01029fd: e8 65 fd ff ff call c0102767 + current->tf = otf; +c0102a02: a1 30 41 1a c0 mov 0xc01a4130,%eax +c0102a07: 8b 55 f4 mov -0xc(%ebp),%edx +c0102a0a: 89 50 3c mov %edx,0x3c(%eax) + if (!in_kernel) { +c0102a0d: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) +c0102a11: 75 2c jne c0102a3f + if (current->flags & PF_EXITING) { +c0102a13: a1 30 41 1a c0 mov 0xc01a4130,%eax +c0102a18: 8b 40 44 mov 0x44(%eax),%eax +c0102a1b: 83 e0 01 and $0x1,%eax +c0102a1e: 85 c0 test %eax,%eax +c0102a20: 74 0c je c0102a2e + do_exit(-E_KILLED); +c0102a22: c7 04 24 f7 ff ff ff movl $0xfffffff7,(%esp) +c0102a29: e8 e2 75 00 00 call c010a010 + if (current->need_resched) { +c0102a2e: a1 30 41 1a c0 mov 0xc01a4130,%eax +c0102a33: 8b 40 10 mov 0x10(%eax),%eax +c0102a36: 85 c0 test %eax,%eax +c0102a38: 74 05 je c0102a3f + schedule(); +c0102a3a: e8 3d 86 00 00 call c010b07c +} +c0102a3f: 90 nop +c0102a40: 89 ec mov %ebp,%esp +c0102a42: 5d pop %ebp +c0102a43: c3 ret + +c0102a44 <__alltraps>: +.globl __alltraps +__alltraps: + # push registers to build a trap frame + # therefore make the stack look like a struct trapframe + # 通过 push 指令,将数据段寄存器和所有通用寄存器(使用 pushal)的值压入栈中,以保存当前状态。 + pushl %ds +c0102a44: 1e push %ds + pushl %es +c0102a45: 06 push %es + pushl %fs +c0102a46: 0f a0 push %fs + pushl %gs +c0102a48: 0f a8 push %gs + pushal +c0102a4a: 60 pusha + + # load GD_KDATA into %ds and %es to set up data segments for kernel + # 将常量 GD_KDATA 加载到 %eax 中,然后将其值复制到 %ds 和 %es 中,设置内核的数据段。 + movl $GD_KDATA, %eax +c0102a4b: b8 10 00 00 00 mov $0x10,%eax + movw %ax, %ds +c0102a50: 8e d8 mov %eax,%ds + movw %ax, %es +c0102a52: 8e c0 mov %eax,%es + + # push %esp to pass a pointer to the trapframe as an argument to trap() + # 将 %esp 压栈,以将指向 trapframe 的指针作为参数传递给 trap() + pushl %esp +c0102a54: 54 push %esp + + # call trap(tf), where tf=%esp + # 调用 trap(tf),其中 tf=%esp + call trap +c0102a55: e8 5d ff ff ff call c01029b7 + + # pop the pushed stack pointer弹出之前压入的栈指针 + popl %esp +c0102a5a: 5c pop %esp + +c0102a5b <__trapret>: + # 返回后继续执行到 trapret... +.globl __trapret +__trapret: + # restore registers from stack + # 定义了返回的入口点 __trapret。 + popal +c0102a5b: 61 popa + + # restore %ds, %es, %fs and %gs + # 这里会恢复之前保存的寄存器 + popl %gs +c0102a5c: 0f a9 pop %gs + popl %fs +c0102a5e: 0f a1 pop %fs + popl %es +c0102a60: 07 pop %es + popl %ds +c0102a61: 1f pop %ds + + # get rid of the trap number and error code + # 通过 iret 指令返回中断处理 + addl $0x8, %esp +c0102a62: 83 c4 08 add $0x8,%esp + iret +c0102a65: cf iret + +c0102a66 : + +.globl forkrets +forkrets: + # set stack to this new process's trapframe + movl 4(%esp), %esp +c0102a66: 8b 64 24 04 mov 0x4(%esp),%esp + jmp __trapret +c0102a6a: eb ef jmp c0102a5b <__trapret> + +c0102a6c : +# handler +.text +.globl __alltraps +.globl vector0 +vector0: + pushl $0 +c0102a6c: 6a 00 push $0x0 + pushl $0 +c0102a6e: 6a 00 push $0x0 + jmp __alltraps +c0102a70: e9 cf ff ff ff jmp c0102a44 <__alltraps> + +c0102a75 : +.globl vector1 +vector1: + pushl $0 +c0102a75: 6a 00 push $0x0 + pushl $1 +c0102a77: 6a 01 push $0x1 + jmp __alltraps +c0102a79: e9 c6 ff ff ff jmp c0102a44 <__alltraps> + +c0102a7e : +.globl vector2 +vector2: + pushl $0 +c0102a7e: 6a 00 push $0x0 + pushl $2 +c0102a80: 6a 02 push $0x2 + jmp __alltraps +c0102a82: e9 bd ff ff ff jmp c0102a44 <__alltraps> + +c0102a87 : +.globl vector3 +vector3: + pushl $0 +c0102a87: 6a 00 push $0x0 + pushl $3 +c0102a89: 6a 03 push $0x3 + jmp __alltraps +c0102a8b: e9 b4 ff ff ff jmp c0102a44 <__alltraps> + +c0102a90 : +.globl vector4 +vector4: + pushl $0 +c0102a90: 6a 00 push $0x0 + pushl $4 +c0102a92: 6a 04 push $0x4 + jmp __alltraps +c0102a94: e9 ab ff ff ff jmp c0102a44 <__alltraps> + +c0102a99 : +.globl vector5 +vector5: + pushl $0 +c0102a99: 6a 00 push $0x0 + pushl $5 +c0102a9b: 6a 05 push $0x5 + jmp __alltraps +c0102a9d: e9 a2 ff ff ff jmp c0102a44 <__alltraps> + +c0102aa2 : +.globl vector6 +vector6: + pushl $0 +c0102aa2: 6a 00 push $0x0 + pushl $6 +c0102aa4: 6a 06 push $0x6 + jmp __alltraps +c0102aa6: e9 99 ff ff ff jmp c0102a44 <__alltraps> + +c0102aab : +.globl vector7 +vector7: + pushl $0 +c0102aab: 6a 00 push $0x0 + pushl $7 +c0102aad: 6a 07 push $0x7 + jmp __alltraps +c0102aaf: e9 90 ff ff ff jmp c0102a44 <__alltraps> + +c0102ab4 : +.globl vector8 +vector8: + pushl $8 +c0102ab4: 6a 08 push $0x8 + jmp __alltraps +c0102ab6: e9 89 ff ff ff jmp c0102a44 <__alltraps> + +c0102abb : +.globl vector9 +vector9: + pushl $0 +c0102abb: 6a 00 push $0x0 + pushl $9 +c0102abd: 6a 09 push $0x9 + jmp __alltraps +c0102abf: e9 80 ff ff ff jmp c0102a44 <__alltraps> + +c0102ac4 : +.globl vector10 +vector10: + pushl $10 +c0102ac4: 6a 0a push $0xa + jmp __alltraps +c0102ac6: e9 79 ff ff ff jmp c0102a44 <__alltraps> + +c0102acb : +.globl vector11 +vector11: + pushl $11 +c0102acb: 6a 0b push $0xb + jmp __alltraps +c0102acd: e9 72 ff ff ff jmp c0102a44 <__alltraps> + +c0102ad2 : +.globl vector12 +vector12: + pushl $12 +c0102ad2: 6a 0c push $0xc + jmp __alltraps +c0102ad4: e9 6b ff ff ff jmp c0102a44 <__alltraps> + +c0102ad9 : +.globl vector13 +vector13: + pushl $13 +c0102ad9: 6a 0d push $0xd + jmp __alltraps +c0102adb: e9 64 ff ff ff jmp c0102a44 <__alltraps> + +c0102ae0 : +.globl vector14 +vector14: + pushl $14 +c0102ae0: 6a 0e push $0xe + jmp __alltraps +c0102ae2: e9 5d ff ff ff jmp c0102a44 <__alltraps> + +c0102ae7 : +.globl vector15 +vector15: + pushl $0 +c0102ae7: 6a 00 push $0x0 + pushl $15 +c0102ae9: 6a 0f push $0xf + jmp __alltraps +c0102aeb: e9 54 ff ff ff jmp c0102a44 <__alltraps> + +c0102af0 : +.globl vector16 +vector16: + pushl $0 +c0102af0: 6a 00 push $0x0 + pushl $16 +c0102af2: 6a 10 push $0x10 + jmp __alltraps +c0102af4: e9 4b ff ff ff jmp c0102a44 <__alltraps> + +c0102af9 : +.globl vector17 +vector17: + pushl $17 +c0102af9: 6a 11 push $0x11 + jmp __alltraps +c0102afb: e9 44 ff ff ff jmp c0102a44 <__alltraps> + +c0102b00 : +.globl vector18 +vector18: + pushl $0 +c0102b00: 6a 00 push $0x0 + pushl $18 +c0102b02: 6a 12 push $0x12 + jmp __alltraps +c0102b04: e9 3b ff ff ff jmp c0102a44 <__alltraps> + +c0102b09 : +.globl vector19 +vector19: + pushl $0 +c0102b09: 6a 00 push $0x0 + pushl $19 +c0102b0b: 6a 13 push $0x13 + jmp __alltraps +c0102b0d: e9 32 ff ff ff jmp c0102a44 <__alltraps> + +c0102b12 : +.globl vector20 +vector20: + pushl $0 +c0102b12: 6a 00 push $0x0 + pushl $20 +c0102b14: 6a 14 push $0x14 + jmp __alltraps +c0102b16: e9 29 ff ff ff jmp c0102a44 <__alltraps> + +c0102b1b : +.globl vector21 +vector21: + pushl $0 +c0102b1b: 6a 00 push $0x0 + pushl $21 +c0102b1d: 6a 15 push $0x15 + jmp __alltraps +c0102b1f: e9 20 ff ff ff jmp c0102a44 <__alltraps> + +c0102b24 : +.globl vector22 +vector22: + pushl $0 +c0102b24: 6a 00 push $0x0 + pushl $22 +c0102b26: 6a 16 push $0x16 + jmp __alltraps +c0102b28: e9 17 ff ff ff jmp c0102a44 <__alltraps> + +c0102b2d : +.globl vector23 +vector23: + pushl $0 +c0102b2d: 6a 00 push $0x0 + pushl $23 +c0102b2f: 6a 17 push $0x17 + jmp __alltraps +c0102b31: e9 0e ff ff ff jmp c0102a44 <__alltraps> + +c0102b36 : +.globl vector24 +vector24: + pushl $0 +c0102b36: 6a 00 push $0x0 + pushl $24 +c0102b38: 6a 18 push $0x18 + jmp __alltraps +c0102b3a: e9 05 ff ff ff jmp c0102a44 <__alltraps> + +c0102b3f : +.globl vector25 +vector25: + pushl $0 +c0102b3f: 6a 00 push $0x0 + pushl $25 +c0102b41: 6a 19 push $0x19 + jmp __alltraps +c0102b43: e9 fc fe ff ff jmp c0102a44 <__alltraps> + +c0102b48 : +.globl vector26 +vector26: + pushl $0 +c0102b48: 6a 00 push $0x0 + pushl $26 +c0102b4a: 6a 1a push $0x1a + jmp __alltraps +c0102b4c: e9 f3 fe ff ff jmp c0102a44 <__alltraps> + +c0102b51 : +.globl vector27 +vector27: + pushl $0 +c0102b51: 6a 00 push $0x0 + pushl $27 +c0102b53: 6a 1b push $0x1b + jmp __alltraps +c0102b55: e9 ea fe ff ff jmp c0102a44 <__alltraps> + +c0102b5a : +.globl vector28 +vector28: + pushl $0 +c0102b5a: 6a 00 push $0x0 + pushl $28 +c0102b5c: 6a 1c push $0x1c + jmp __alltraps +c0102b5e: e9 e1 fe ff ff jmp c0102a44 <__alltraps> + +c0102b63 : +.globl vector29 +vector29: + pushl $0 +c0102b63: 6a 00 push $0x0 + pushl $29 +c0102b65: 6a 1d push $0x1d + jmp __alltraps +c0102b67: e9 d8 fe ff ff jmp c0102a44 <__alltraps> + +c0102b6c : +.globl vector30 +vector30: + pushl $0 +c0102b6c: 6a 00 push $0x0 + pushl $30 +c0102b6e: 6a 1e push $0x1e + jmp __alltraps +c0102b70: e9 cf fe ff ff jmp c0102a44 <__alltraps> + +c0102b75 : +.globl vector31 +vector31: + pushl $0 +c0102b75: 6a 00 push $0x0 + pushl $31 +c0102b77: 6a 1f push $0x1f + jmp __alltraps +c0102b79: e9 c6 fe ff ff jmp c0102a44 <__alltraps> + +c0102b7e : +.globl vector32 +vector32: + pushl $0 +c0102b7e: 6a 00 push $0x0 + pushl $32 +c0102b80: 6a 20 push $0x20 + jmp __alltraps +c0102b82: e9 bd fe ff ff jmp c0102a44 <__alltraps> + +c0102b87 : +.globl vector33 +vector33: + pushl $0 +c0102b87: 6a 00 push $0x0 + pushl $33 +c0102b89: 6a 21 push $0x21 + jmp __alltraps +c0102b8b: e9 b4 fe ff ff jmp c0102a44 <__alltraps> + +c0102b90 : +.globl vector34 +vector34: + pushl $0 +c0102b90: 6a 00 push $0x0 + pushl $34 +c0102b92: 6a 22 push $0x22 + jmp __alltraps +c0102b94: e9 ab fe ff ff jmp c0102a44 <__alltraps> + +c0102b99 : +.globl vector35 +vector35: + pushl $0 +c0102b99: 6a 00 push $0x0 + pushl $35 +c0102b9b: 6a 23 push $0x23 + jmp __alltraps +c0102b9d: e9 a2 fe ff ff jmp c0102a44 <__alltraps> + +c0102ba2 : +.globl vector36 +vector36: + pushl $0 +c0102ba2: 6a 00 push $0x0 + pushl $36 +c0102ba4: 6a 24 push $0x24 + jmp __alltraps +c0102ba6: e9 99 fe ff ff jmp c0102a44 <__alltraps> + +c0102bab : +.globl vector37 +vector37: + pushl $0 +c0102bab: 6a 00 push $0x0 + pushl $37 +c0102bad: 6a 25 push $0x25 + jmp __alltraps +c0102baf: e9 90 fe ff ff jmp c0102a44 <__alltraps> + +c0102bb4 : +.globl vector38 +vector38: + pushl $0 +c0102bb4: 6a 00 push $0x0 + pushl $38 +c0102bb6: 6a 26 push $0x26 + jmp __alltraps +c0102bb8: e9 87 fe ff ff jmp c0102a44 <__alltraps> + +c0102bbd : +.globl vector39 +vector39: + pushl $0 +c0102bbd: 6a 00 push $0x0 + pushl $39 +c0102bbf: 6a 27 push $0x27 + jmp __alltraps +c0102bc1: e9 7e fe ff ff jmp c0102a44 <__alltraps> + +c0102bc6 : +.globl vector40 +vector40: + pushl $0 +c0102bc6: 6a 00 push $0x0 + pushl $40 +c0102bc8: 6a 28 push $0x28 + jmp __alltraps +c0102bca: e9 75 fe ff ff jmp c0102a44 <__alltraps> + +c0102bcf : +.globl vector41 +vector41: + pushl $0 +c0102bcf: 6a 00 push $0x0 + pushl $41 +c0102bd1: 6a 29 push $0x29 + jmp __alltraps +c0102bd3: e9 6c fe ff ff jmp c0102a44 <__alltraps> + +c0102bd8 : +.globl vector42 +vector42: + pushl $0 +c0102bd8: 6a 00 push $0x0 + pushl $42 +c0102bda: 6a 2a push $0x2a + jmp __alltraps +c0102bdc: e9 63 fe ff ff jmp c0102a44 <__alltraps> + +c0102be1 : +.globl vector43 +vector43: + pushl $0 +c0102be1: 6a 00 push $0x0 + pushl $43 +c0102be3: 6a 2b push $0x2b + jmp __alltraps +c0102be5: e9 5a fe ff ff jmp c0102a44 <__alltraps> + +c0102bea : +.globl vector44 +vector44: + pushl $0 +c0102bea: 6a 00 push $0x0 + pushl $44 +c0102bec: 6a 2c push $0x2c + jmp __alltraps +c0102bee: e9 51 fe ff ff jmp c0102a44 <__alltraps> + +c0102bf3 : +.globl vector45 +vector45: + pushl $0 +c0102bf3: 6a 00 push $0x0 + pushl $45 +c0102bf5: 6a 2d push $0x2d + jmp __alltraps +c0102bf7: e9 48 fe ff ff jmp c0102a44 <__alltraps> + +c0102bfc : +.globl vector46 +vector46: + pushl $0 +c0102bfc: 6a 00 push $0x0 + pushl $46 +c0102bfe: 6a 2e push $0x2e + jmp __alltraps +c0102c00: e9 3f fe ff ff jmp c0102a44 <__alltraps> + +c0102c05 : +.globl vector47 +vector47: + pushl $0 +c0102c05: 6a 00 push $0x0 + pushl $47 +c0102c07: 6a 2f push $0x2f + jmp __alltraps +c0102c09: e9 36 fe ff ff jmp c0102a44 <__alltraps> + +c0102c0e : +.globl vector48 +vector48: + pushl $0 +c0102c0e: 6a 00 push $0x0 + pushl $48 +c0102c10: 6a 30 push $0x30 + jmp __alltraps +c0102c12: e9 2d fe ff ff jmp c0102a44 <__alltraps> + +c0102c17 : +.globl vector49 +vector49: + pushl $0 +c0102c17: 6a 00 push $0x0 + pushl $49 +c0102c19: 6a 31 push $0x31 + jmp __alltraps +c0102c1b: e9 24 fe ff ff jmp c0102a44 <__alltraps> + +c0102c20 : +.globl vector50 +vector50: + pushl $0 +c0102c20: 6a 00 push $0x0 + pushl $50 +c0102c22: 6a 32 push $0x32 + jmp __alltraps +c0102c24: e9 1b fe ff ff jmp c0102a44 <__alltraps> + +c0102c29 : +.globl vector51 +vector51: + pushl $0 +c0102c29: 6a 00 push $0x0 + pushl $51 +c0102c2b: 6a 33 push $0x33 + jmp __alltraps +c0102c2d: e9 12 fe ff ff jmp c0102a44 <__alltraps> + +c0102c32 : +.globl vector52 +vector52: + pushl $0 +c0102c32: 6a 00 push $0x0 + pushl $52 +c0102c34: 6a 34 push $0x34 + jmp __alltraps +c0102c36: e9 09 fe ff ff jmp c0102a44 <__alltraps> + +c0102c3b : +.globl vector53 +vector53: + pushl $0 +c0102c3b: 6a 00 push $0x0 + pushl $53 +c0102c3d: 6a 35 push $0x35 + jmp __alltraps +c0102c3f: e9 00 fe ff ff jmp c0102a44 <__alltraps> + +c0102c44 : +.globl vector54 +vector54: + pushl $0 +c0102c44: 6a 00 push $0x0 + pushl $54 +c0102c46: 6a 36 push $0x36 + jmp __alltraps +c0102c48: e9 f7 fd ff ff jmp c0102a44 <__alltraps> + +c0102c4d : +.globl vector55 +vector55: + pushl $0 +c0102c4d: 6a 00 push $0x0 + pushl $55 +c0102c4f: 6a 37 push $0x37 + jmp __alltraps +c0102c51: e9 ee fd ff ff jmp c0102a44 <__alltraps> + +c0102c56 : +.globl vector56 +vector56: + pushl $0 +c0102c56: 6a 00 push $0x0 + pushl $56 +c0102c58: 6a 38 push $0x38 + jmp __alltraps +c0102c5a: e9 e5 fd ff ff jmp c0102a44 <__alltraps> + +c0102c5f : +.globl vector57 +vector57: + pushl $0 +c0102c5f: 6a 00 push $0x0 + pushl $57 +c0102c61: 6a 39 push $0x39 + jmp __alltraps +c0102c63: e9 dc fd ff ff jmp c0102a44 <__alltraps> + +c0102c68 : +.globl vector58 +vector58: + pushl $0 +c0102c68: 6a 00 push $0x0 + pushl $58 +c0102c6a: 6a 3a push $0x3a + jmp __alltraps +c0102c6c: e9 d3 fd ff ff jmp c0102a44 <__alltraps> + +c0102c71 : +.globl vector59 +vector59: + pushl $0 +c0102c71: 6a 00 push $0x0 + pushl $59 +c0102c73: 6a 3b push $0x3b + jmp __alltraps +c0102c75: e9 ca fd ff ff jmp c0102a44 <__alltraps> + +c0102c7a : +.globl vector60 +vector60: + pushl $0 +c0102c7a: 6a 00 push $0x0 + pushl $60 +c0102c7c: 6a 3c push $0x3c + jmp __alltraps +c0102c7e: e9 c1 fd ff ff jmp c0102a44 <__alltraps> + +c0102c83 : +.globl vector61 +vector61: + pushl $0 +c0102c83: 6a 00 push $0x0 + pushl $61 +c0102c85: 6a 3d push $0x3d + jmp __alltraps +c0102c87: e9 b8 fd ff ff jmp c0102a44 <__alltraps> + +c0102c8c : +.globl vector62 +vector62: + pushl $0 +c0102c8c: 6a 00 push $0x0 + pushl $62 +c0102c8e: 6a 3e push $0x3e + jmp __alltraps +c0102c90: e9 af fd ff ff jmp c0102a44 <__alltraps> + +c0102c95 : +.globl vector63 +vector63: + pushl $0 +c0102c95: 6a 00 push $0x0 + pushl $63 +c0102c97: 6a 3f push $0x3f + jmp __alltraps +c0102c99: e9 a6 fd ff ff jmp c0102a44 <__alltraps> + +c0102c9e : +.globl vector64 +vector64: + pushl $0 +c0102c9e: 6a 00 push $0x0 + pushl $64 +c0102ca0: 6a 40 push $0x40 + jmp __alltraps +c0102ca2: e9 9d fd ff ff jmp c0102a44 <__alltraps> + +c0102ca7 : +.globl vector65 +vector65: + pushl $0 +c0102ca7: 6a 00 push $0x0 + pushl $65 +c0102ca9: 6a 41 push $0x41 + jmp __alltraps +c0102cab: e9 94 fd ff ff jmp c0102a44 <__alltraps> + +c0102cb0 : +.globl vector66 +vector66: + pushl $0 +c0102cb0: 6a 00 push $0x0 + pushl $66 +c0102cb2: 6a 42 push $0x42 + jmp __alltraps +c0102cb4: e9 8b fd ff ff jmp c0102a44 <__alltraps> + +c0102cb9 : +.globl vector67 +vector67: + pushl $0 +c0102cb9: 6a 00 push $0x0 + pushl $67 +c0102cbb: 6a 43 push $0x43 + jmp __alltraps +c0102cbd: e9 82 fd ff ff jmp c0102a44 <__alltraps> + +c0102cc2 : +.globl vector68 +vector68: + pushl $0 +c0102cc2: 6a 00 push $0x0 + pushl $68 +c0102cc4: 6a 44 push $0x44 + jmp __alltraps +c0102cc6: e9 79 fd ff ff jmp c0102a44 <__alltraps> + +c0102ccb : +.globl vector69 +vector69: + pushl $0 +c0102ccb: 6a 00 push $0x0 + pushl $69 +c0102ccd: 6a 45 push $0x45 + jmp __alltraps +c0102ccf: e9 70 fd ff ff jmp c0102a44 <__alltraps> + +c0102cd4 : +.globl vector70 +vector70: + pushl $0 +c0102cd4: 6a 00 push $0x0 + pushl $70 +c0102cd6: 6a 46 push $0x46 + jmp __alltraps +c0102cd8: e9 67 fd ff ff jmp c0102a44 <__alltraps> + +c0102cdd : +.globl vector71 +vector71: + pushl $0 +c0102cdd: 6a 00 push $0x0 + pushl $71 +c0102cdf: 6a 47 push $0x47 + jmp __alltraps +c0102ce1: e9 5e fd ff ff jmp c0102a44 <__alltraps> + +c0102ce6 : +.globl vector72 +vector72: + pushl $0 +c0102ce6: 6a 00 push $0x0 + pushl $72 +c0102ce8: 6a 48 push $0x48 + jmp __alltraps +c0102cea: e9 55 fd ff ff jmp c0102a44 <__alltraps> + +c0102cef : +.globl vector73 +vector73: + pushl $0 +c0102cef: 6a 00 push $0x0 + pushl $73 +c0102cf1: 6a 49 push $0x49 + jmp __alltraps +c0102cf3: e9 4c fd ff ff jmp c0102a44 <__alltraps> + +c0102cf8 : +.globl vector74 +vector74: + pushl $0 +c0102cf8: 6a 00 push $0x0 + pushl $74 +c0102cfa: 6a 4a push $0x4a + jmp __alltraps +c0102cfc: e9 43 fd ff ff jmp c0102a44 <__alltraps> + +c0102d01 : +.globl vector75 +vector75: + pushl $0 +c0102d01: 6a 00 push $0x0 + pushl $75 +c0102d03: 6a 4b push $0x4b + jmp __alltraps +c0102d05: e9 3a fd ff ff jmp c0102a44 <__alltraps> + +c0102d0a : +.globl vector76 +vector76: + pushl $0 +c0102d0a: 6a 00 push $0x0 + pushl $76 +c0102d0c: 6a 4c push $0x4c + jmp __alltraps +c0102d0e: e9 31 fd ff ff jmp c0102a44 <__alltraps> + +c0102d13 : +.globl vector77 +vector77: + pushl $0 +c0102d13: 6a 00 push $0x0 + pushl $77 +c0102d15: 6a 4d push $0x4d + jmp __alltraps +c0102d17: e9 28 fd ff ff jmp c0102a44 <__alltraps> + +c0102d1c : +.globl vector78 +vector78: + pushl $0 +c0102d1c: 6a 00 push $0x0 + pushl $78 +c0102d1e: 6a 4e push $0x4e + jmp __alltraps +c0102d20: e9 1f fd ff ff jmp c0102a44 <__alltraps> + +c0102d25 : +.globl vector79 +vector79: + pushl $0 +c0102d25: 6a 00 push $0x0 + pushl $79 +c0102d27: 6a 4f push $0x4f + jmp __alltraps +c0102d29: e9 16 fd ff ff jmp c0102a44 <__alltraps> + +c0102d2e : +.globl vector80 +vector80: + pushl $0 +c0102d2e: 6a 00 push $0x0 + pushl $80 +c0102d30: 6a 50 push $0x50 + jmp __alltraps +c0102d32: e9 0d fd ff ff jmp c0102a44 <__alltraps> + +c0102d37 : +.globl vector81 +vector81: + pushl $0 +c0102d37: 6a 00 push $0x0 + pushl $81 +c0102d39: 6a 51 push $0x51 + jmp __alltraps +c0102d3b: e9 04 fd ff ff jmp c0102a44 <__alltraps> + +c0102d40 : +.globl vector82 +vector82: + pushl $0 +c0102d40: 6a 00 push $0x0 + pushl $82 +c0102d42: 6a 52 push $0x52 + jmp __alltraps +c0102d44: e9 fb fc ff ff jmp c0102a44 <__alltraps> + +c0102d49 : +.globl vector83 +vector83: + pushl $0 +c0102d49: 6a 00 push $0x0 + pushl $83 +c0102d4b: 6a 53 push $0x53 + jmp __alltraps +c0102d4d: e9 f2 fc ff ff jmp c0102a44 <__alltraps> + +c0102d52 : +.globl vector84 +vector84: + pushl $0 +c0102d52: 6a 00 push $0x0 + pushl $84 +c0102d54: 6a 54 push $0x54 + jmp __alltraps +c0102d56: e9 e9 fc ff ff jmp c0102a44 <__alltraps> + +c0102d5b : +.globl vector85 +vector85: + pushl $0 +c0102d5b: 6a 00 push $0x0 + pushl $85 +c0102d5d: 6a 55 push $0x55 + jmp __alltraps +c0102d5f: e9 e0 fc ff ff jmp c0102a44 <__alltraps> + +c0102d64 : +.globl vector86 +vector86: + pushl $0 +c0102d64: 6a 00 push $0x0 + pushl $86 +c0102d66: 6a 56 push $0x56 + jmp __alltraps +c0102d68: e9 d7 fc ff ff jmp c0102a44 <__alltraps> + +c0102d6d : +.globl vector87 +vector87: + pushl $0 +c0102d6d: 6a 00 push $0x0 + pushl $87 +c0102d6f: 6a 57 push $0x57 + jmp __alltraps +c0102d71: e9 ce fc ff ff jmp c0102a44 <__alltraps> + +c0102d76 : +.globl vector88 +vector88: + pushl $0 +c0102d76: 6a 00 push $0x0 + pushl $88 +c0102d78: 6a 58 push $0x58 + jmp __alltraps +c0102d7a: e9 c5 fc ff ff jmp c0102a44 <__alltraps> + +c0102d7f : +.globl vector89 +vector89: + pushl $0 +c0102d7f: 6a 00 push $0x0 + pushl $89 +c0102d81: 6a 59 push $0x59 + jmp __alltraps +c0102d83: e9 bc fc ff ff jmp c0102a44 <__alltraps> + +c0102d88 : +.globl vector90 +vector90: + pushl $0 +c0102d88: 6a 00 push $0x0 + pushl $90 +c0102d8a: 6a 5a push $0x5a + jmp __alltraps +c0102d8c: e9 b3 fc ff ff jmp c0102a44 <__alltraps> + +c0102d91 : +.globl vector91 +vector91: + pushl $0 +c0102d91: 6a 00 push $0x0 + pushl $91 +c0102d93: 6a 5b push $0x5b + jmp __alltraps +c0102d95: e9 aa fc ff ff jmp c0102a44 <__alltraps> + +c0102d9a : +.globl vector92 +vector92: + pushl $0 +c0102d9a: 6a 00 push $0x0 + pushl $92 +c0102d9c: 6a 5c push $0x5c + jmp __alltraps +c0102d9e: e9 a1 fc ff ff jmp c0102a44 <__alltraps> + +c0102da3 : +.globl vector93 +vector93: + pushl $0 +c0102da3: 6a 00 push $0x0 + pushl $93 +c0102da5: 6a 5d push $0x5d + jmp __alltraps +c0102da7: e9 98 fc ff ff jmp c0102a44 <__alltraps> + +c0102dac : +.globl vector94 +vector94: + pushl $0 +c0102dac: 6a 00 push $0x0 + pushl $94 +c0102dae: 6a 5e push $0x5e + jmp __alltraps +c0102db0: e9 8f fc ff ff jmp c0102a44 <__alltraps> + +c0102db5 : +.globl vector95 +vector95: + pushl $0 +c0102db5: 6a 00 push $0x0 + pushl $95 +c0102db7: 6a 5f push $0x5f + jmp __alltraps +c0102db9: e9 86 fc ff ff jmp c0102a44 <__alltraps> + +c0102dbe : +.globl vector96 +vector96: + pushl $0 +c0102dbe: 6a 00 push $0x0 + pushl $96 +c0102dc0: 6a 60 push $0x60 + jmp __alltraps +c0102dc2: e9 7d fc ff ff jmp c0102a44 <__alltraps> + +c0102dc7 : +.globl vector97 +vector97: + pushl $0 +c0102dc7: 6a 00 push $0x0 + pushl $97 +c0102dc9: 6a 61 push $0x61 + jmp __alltraps +c0102dcb: e9 74 fc ff ff jmp c0102a44 <__alltraps> + +c0102dd0 : +.globl vector98 +vector98: + pushl $0 +c0102dd0: 6a 00 push $0x0 + pushl $98 +c0102dd2: 6a 62 push $0x62 + jmp __alltraps +c0102dd4: e9 6b fc ff ff jmp c0102a44 <__alltraps> + +c0102dd9 : +.globl vector99 +vector99: + pushl $0 +c0102dd9: 6a 00 push $0x0 + pushl $99 +c0102ddb: 6a 63 push $0x63 + jmp __alltraps +c0102ddd: e9 62 fc ff ff jmp c0102a44 <__alltraps> + +c0102de2 : +.globl vector100 +vector100: + pushl $0 +c0102de2: 6a 00 push $0x0 + pushl $100 +c0102de4: 6a 64 push $0x64 + jmp __alltraps +c0102de6: e9 59 fc ff ff jmp c0102a44 <__alltraps> + +c0102deb : +.globl vector101 +vector101: + pushl $0 +c0102deb: 6a 00 push $0x0 + pushl $101 +c0102ded: 6a 65 push $0x65 + jmp __alltraps +c0102def: e9 50 fc ff ff jmp c0102a44 <__alltraps> + +c0102df4 : +.globl vector102 +vector102: + pushl $0 +c0102df4: 6a 00 push $0x0 + pushl $102 +c0102df6: 6a 66 push $0x66 + jmp __alltraps +c0102df8: e9 47 fc ff ff jmp c0102a44 <__alltraps> + +c0102dfd : +.globl vector103 +vector103: + pushl $0 +c0102dfd: 6a 00 push $0x0 + pushl $103 +c0102dff: 6a 67 push $0x67 + jmp __alltraps +c0102e01: e9 3e fc ff ff jmp c0102a44 <__alltraps> + +c0102e06 : +.globl vector104 +vector104: + pushl $0 +c0102e06: 6a 00 push $0x0 + pushl $104 +c0102e08: 6a 68 push $0x68 + jmp __alltraps +c0102e0a: e9 35 fc ff ff jmp c0102a44 <__alltraps> + +c0102e0f : +.globl vector105 +vector105: + pushl $0 +c0102e0f: 6a 00 push $0x0 + pushl $105 +c0102e11: 6a 69 push $0x69 + jmp __alltraps +c0102e13: e9 2c fc ff ff jmp c0102a44 <__alltraps> + +c0102e18 : +.globl vector106 +vector106: + pushl $0 +c0102e18: 6a 00 push $0x0 + pushl $106 +c0102e1a: 6a 6a push $0x6a + jmp __alltraps +c0102e1c: e9 23 fc ff ff jmp c0102a44 <__alltraps> + +c0102e21 : +.globl vector107 +vector107: + pushl $0 +c0102e21: 6a 00 push $0x0 + pushl $107 +c0102e23: 6a 6b push $0x6b + jmp __alltraps +c0102e25: e9 1a fc ff ff jmp c0102a44 <__alltraps> + +c0102e2a : +.globl vector108 +vector108: + pushl $0 +c0102e2a: 6a 00 push $0x0 + pushl $108 +c0102e2c: 6a 6c push $0x6c + jmp __alltraps +c0102e2e: e9 11 fc ff ff jmp c0102a44 <__alltraps> + +c0102e33 : +.globl vector109 +vector109: + pushl $0 +c0102e33: 6a 00 push $0x0 + pushl $109 +c0102e35: 6a 6d push $0x6d + jmp __alltraps +c0102e37: e9 08 fc ff ff jmp c0102a44 <__alltraps> + +c0102e3c : +.globl vector110 +vector110: + pushl $0 +c0102e3c: 6a 00 push $0x0 + pushl $110 +c0102e3e: 6a 6e push $0x6e + jmp __alltraps +c0102e40: e9 ff fb ff ff jmp c0102a44 <__alltraps> + +c0102e45 : +.globl vector111 +vector111: + pushl $0 +c0102e45: 6a 00 push $0x0 + pushl $111 +c0102e47: 6a 6f push $0x6f + jmp __alltraps +c0102e49: e9 f6 fb ff ff jmp c0102a44 <__alltraps> + +c0102e4e : +.globl vector112 +vector112: + pushl $0 +c0102e4e: 6a 00 push $0x0 + pushl $112 +c0102e50: 6a 70 push $0x70 + jmp __alltraps +c0102e52: e9 ed fb ff ff jmp c0102a44 <__alltraps> + +c0102e57 : +.globl vector113 +vector113: + pushl $0 +c0102e57: 6a 00 push $0x0 + pushl $113 +c0102e59: 6a 71 push $0x71 + jmp __alltraps +c0102e5b: e9 e4 fb ff ff jmp c0102a44 <__alltraps> + +c0102e60 : +.globl vector114 +vector114: + pushl $0 +c0102e60: 6a 00 push $0x0 + pushl $114 +c0102e62: 6a 72 push $0x72 + jmp __alltraps +c0102e64: e9 db fb ff ff jmp c0102a44 <__alltraps> + +c0102e69 : +.globl vector115 +vector115: + pushl $0 +c0102e69: 6a 00 push $0x0 + pushl $115 +c0102e6b: 6a 73 push $0x73 + jmp __alltraps +c0102e6d: e9 d2 fb ff ff jmp c0102a44 <__alltraps> + +c0102e72 : +.globl vector116 +vector116: + pushl $0 +c0102e72: 6a 00 push $0x0 + pushl $116 +c0102e74: 6a 74 push $0x74 + jmp __alltraps +c0102e76: e9 c9 fb ff ff jmp c0102a44 <__alltraps> + +c0102e7b : +.globl vector117 +vector117: + pushl $0 +c0102e7b: 6a 00 push $0x0 + pushl $117 +c0102e7d: 6a 75 push $0x75 + jmp __alltraps +c0102e7f: e9 c0 fb ff ff jmp c0102a44 <__alltraps> + +c0102e84 : +.globl vector118 +vector118: + pushl $0 +c0102e84: 6a 00 push $0x0 + pushl $118 +c0102e86: 6a 76 push $0x76 + jmp __alltraps +c0102e88: e9 b7 fb ff ff jmp c0102a44 <__alltraps> + +c0102e8d : +.globl vector119 +vector119: + pushl $0 +c0102e8d: 6a 00 push $0x0 + pushl $119 +c0102e8f: 6a 77 push $0x77 + jmp __alltraps +c0102e91: e9 ae fb ff ff jmp c0102a44 <__alltraps> + +c0102e96 : +.globl vector120 +vector120: + pushl $0 +c0102e96: 6a 00 push $0x0 + pushl $120 +c0102e98: 6a 78 push $0x78 + jmp __alltraps +c0102e9a: e9 a5 fb ff ff jmp c0102a44 <__alltraps> + +c0102e9f : +.globl vector121 +vector121: + pushl $0 +c0102e9f: 6a 00 push $0x0 + pushl $121 +c0102ea1: 6a 79 push $0x79 + jmp __alltraps +c0102ea3: e9 9c fb ff ff jmp c0102a44 <__alltraps> + +c0102ea8 : +.globl vector122 +vector122: + pushl $0 +c0102ea8: 6a 00 push $0x0 + pushl $122 +c0102eaa: 6a 7a push $0x7a + jmp __alltraps +c0102eac: e9 93 fb ff ff jmp c0102a44 <__alltraps> + +c0102eb1 : +.globl vector123 +vector123: + pushl $0 +c0102eb1: 6a 00 push $0x0 + pushl $123 +c0102eb3: 6a 7b push $0x7b + jmp __alltraps +c0102eb5: e9 8a fb ff ff jmp c0102a44 <__alltraps> + +c0102eba : +.globl vector124 +vector124: + pushl $0 +c0102eba: 6a 00 push $0x0 + pushl $124 +c0102ebc: 6a 7c push $0x7c + jmp __alltraps +c0102ebe: e9 81 fb ff ff jmp c0102a44 <__alltraps> + +c0102ec3 : +.globl vector125 +vector125: + pushl $0 +c0102ec3: 6a 00 push $0x0 + pushl $125 +c0102ec5: 6a 7d push $0x7d + jmp __alltraps +c0102ec7: e9 78 fb ff ff jmp c0102a44 <__alltraps> + +c0102ecc : +.globl vector126 +vector126: + pushl $0 +c0102ecc: 6a 00 push $0x0 + pushl $126 +c0102ece: 6a 7e push $0x7e + jmp __alltraps +c0102ed0: e9 6f fb ff ff jmp c0102a44 <__alltraps> + +c0102ed5 : +.globl vector127 +vector127: + pushl $0 +c0102ed5: 6a 00 push $0x0 + pushl $127 +c0102ed7: 6a 7f push $0x7f + jmp __alltraps +c0102ed9: e9 66 fb ff ff jmp c0102a44 <__alltraps> + +c0102ede : +.globl vector128 +vector128: + pushl $0 +c0102ede: 6a 00 push $0x0 + pushl $128 +c0102ee0: 68 80 00 00 00 push $0x80 + jmp __alltraps +c0102ee5: e9 5a fb ff ff jmp c0102a44 <__alltraps> + +c0102eea : +.globl vector129 +vector129: + pushl $0 +c0102eea: 6a 00 push $0x0 + pushl $129 +c0102eec: 68 81 00 00 00 push $0x81 + jmp __alltraps +c0102ef1: e9 4e fb ff ff jmp c0102a44 <__alltraps> + +c0102ef6 : +.globl vector130 +vector130: + pushl $0 +c0102ef6: 6a 00 push $0x0 + pushl $130 +c0102ef8: 68 82 00 00 00 push $0x82 + jmp __alltraps +c0102efd: e9 42 fb ff ff jmp c0102a44 <__alltraps> + +c0102f02 : +.globl vector131 +vector131: + pushl $0 +c0102f02: 6a 00 push $0x0 + pushl $131 +c0102f04: 68 83 00 00 00 push $0x83 + jmp __alltraps +c0102f09: e9 36 fb ff ff jmp c0102a44 <__alltraps> + +c0102f0e : +.globl vector132 +vector132: + pushl $0 +c0102f0e: 6a 00 push $0x0 + pushl $132 +c0102f10: 68 84 00 00 00 push $0x84 + jmp __alltraps +c0102f15: e9 2a fb ff ff jmp c0102a44 <__alltraps> + +c0102f1a : +.globl vector133 +vector133: + pushl $0 +c0102f1a: 6a 00 push $0x0 + pushl $133 +c0102f1c: 68 85 00 00 00 push $0x85 + jmp __alltraps +c0102f21: e9 1e fb ff ff jmp c0102a44 <__alltraps> + +c0102f26 : +.globl vector134 +vector134: + pushl $0 +c0102f26: 6a 00 push $0x0 + pushl $134 +c0102f28: 68 86 00 00 00 push $0x86 + jmp __alltraps +c0102f2d: e9 12 fb ff ff jmp c0102a44 <__alltraps> + +c0102f32 : +.globl vector135 +vector135: + pushl $0 +c0102f32: 6a 00 push $0x0 + pushl $135 +c0102f34: 68 87 00 00 00 push $0x87 + jmp __alltraps +c0102f39: e9 06 fb ff ff jmp c0102a44 <__alltraps> + +c0102f3e : +.globl vector136 +vector136: + pushl $0 +c0102f3e: 6a 00 push $0x0 + pushl $136 +c0102f40: 68 88 00 00 00 push $0x88 + jmp __alltraps +c0102f45: e9 fa fa ff ff jmp c0102a44 <__alltraps> + +c0102f4a : +.globl vector137 +vector137: + pushl $0 +c0102f4a: 6a 00 push $0x0 + pushl $137 +c0102f4c: 68 89 00 00 00 push $0x89 + jmp __alltraps +c0102f51: e9 ee fa ff ff jmp c0102a44 <__alltraps> + +c0102f56 : +.globl vector138 +vector138: + pushl $0 +c0102f56: 6a 00 push $0x0 + pushl $138 +c0102f58: 68 8a 00 00 00 push $0x8a + jmp __alltraps +c0102f5d: e9 e2 fa ff ff jmp c0102a44 <__alltraps> + +c0102f62 : +.globl vector139 +vector139: + pushl $0 +c0102f62: 6a 00 push $0x0 + pushl $139 +c0102f64: 68 8b 00 00 00 push $0x8b + jmp __alltraps +c0102f69: e9 d6 fa ff ff jmp c0102a44 <__alltraps> + +c0102f6e : +.globl vector140 +vector140: + pushl $0 +c0102f6e: 6a 00 push $0x0 + pushl $140 +c0102f70: 68 8c 00 00 00 push $0x8c + jmp __alltraps +c0102f75: e9 ca fa ff ff jmp c0102a44 <__alltraps> + +c0102f7a : +.globl vector141 +vector141: + pushl $0 +c0102f7a: 6a 00 push $0x0 + pushl $141 +c0102f7c: 68 8d 00 00 00 push $0x8d + jmp __alltraps +c0102f81: e9 be fa ff ff jmp c0102a44 <__alltraps> + +c0102f86 : +.globl vector142 +vector142: + pushl $0 +c0102f86: 6a 00 push $0x0 + pushl $142 +c0102f88: 68 8e 00 00 00 push $0x8e + jmp __alltraps +c0102f8d: e9 b2 fa ff ff jmp c0102a44 <__alltraps> + +c0102f92 : +.globl vector143 +vector143: + pushl $0 +c0102f92: 6a 00 push $0x0 + pushl $143 +c0102f94: 68 8f 00 00 00 push $0x8f + jmp __alltraps +c0102f99: e9 a6 fa ff ff jmp c0102a44 <__alltraps> + +c0102f9e : +.globl vector144 +vector144: + pushl $0 +c0102f9e: 6a 00 push $0x0 + pushl $144 +c0102fa0: 68 90 00 00 00 push $0x90 + jmp __alltraps +c0102fa5: e9 9a fa ff ff jmp c0102a44 <__alltraps> + +c0102faa : +.globl vector145 +vector145: + pushl $0 +c0102faa: 6a 00 push $0x0 + pushl $145 +c0102fac: 68 91 00 00 00 push $0x91 + jmp __alltraps +c0102fb1: e9 8e fa ff ff jmp c0102a44 <__alltraps> + +c0102fb6 : +.globl vector146 +vector146: + pushl $0 +c0102fb6: 6a 00 push $0x0 + pushl $146 +c0102fb8: 68 92 00 00 00 push $0x92 + jmp __alltraps +c0102fbd: e9 82 fa ff ff jmp c0102a44 <__alltraps> + +c0102fc2 : +.globl vector147 +vector147: + pushl $0 +c0102fc2: 6a 00 push $0x0 + pushl $147 +c0102fc4: 68 93 00 00 00 push $0x93 + jmp __alltraps +c0102fc9: e9 76 fa ff ff jmp c0102a44 <__alltraps> + +c0102fce : +.globl vector148 +vector148: + pushl $0 +c0102fce: 6a 00 push $0x0 + pushl $148 +c0102fd0: 68 94 00 00 00 push $0x94 + jmp __alltraps +c0102fd5: e9 6a fa ff ff jmp c0102a44 <__alltraps> + +c0102fda : +.globl vector149 +vector149: + pushl $0 +c0102fda: 6a 00 push $0x0 + pushl $149 +c0102fdc: 68 95 00 00 00 push $0x95 + jmp __alltraps +c0102fe1: e9 5e fa ff ff jmp c0102a44 <__alltraps> + +c0102fe6 : +.globl vector150 +vector150: + pushl $0 +c0102fe6: 6a 00 push $0x0 + pushl $150 +c0102fe8: 68 96 00 00 00 push $0x96 + jmp __alltraps +c0102fed: e9 52 fa ff ff jmp c0102a44 <__alltraps> + +c0102ff2 : +.globl vector151 +vector151: + pushl $0 +c0102ff2: 6a 00 push $0x0 + pushl $151 +c0102ff4: 68 97 00 00 00 push $0x97 + jmp __alltraps +c0102ff9: e9 46 fa ff ff jmp c0102a44 <__alltraps> + +c0102ffe : +.globl vector152 +vector152: + pushl $0 +c0102ffe: 6a 00 push $0x0 + pushl $152 +c0103000: 68 98 00 00 00 push $0x98 + jmp __alltraps +c0103005: e9 3a fa ff ff jmp c0102a44 <__alltraps> + +c010300a : +.globl vector153 +vector153: + pushl $0 +c010300a: 6a 00 push $0x0 + pushl $153 +c010300c: 68 99 00 00 00 push $0x99 + jmp __alltraps +c0103011: e9 2e fa ff ff jmp c0102a44 <__alltraps> + +c0103016 : +.globl vector154 +vector154: + pushl $0 +c0103016: 6a 00 push $0x0 + pushl $154 +c0103018: 68 9a 00 00 00 push $0x9a + jmp __alltraps +c010301d: e9 22 fa ff ff jmp c0102a44 <__alltraps> + +c0103022 : +.globl vector155 +vector155: + pushl $0 +c0103022: 6a 00 push $0x0 + pushl $155 +c0103024: 68 9b 00 00 00 push $0x9b + jmp __alltraps +c0103029: e9 16 fa ff ff jmp c0102a44 <__alltraps> + +c010302e : +.globl vector156 +vector156: + pushl $0 +c010302e: 6a 00 push $0x0 + pushl $156 +c0103030: 68 9c 00 00 00 push $0x9c + jmp __alltraps +c0103035: e9 0a fa ff ff jmp c0102a44 <__alltraps> + +c010303a : +.globl vector157 +vector157: + pushl $0 +c010303a: 6a 00 push $0x0 + pushl $157 +c010303c: 68 9d 00 00 00 push $0x9d + jmp __alltraps +c0103041: e9 fe f9 ff ff jmp c0102a44 <__alltraps> + +c0103046 : +.globl vector158 +vector158: + pushl $0 +c0103046: 6a 00 push $0x0 + pushl $158 +c0103048: 68 9e 00 00 00 push $0x9e + jmp __alltraps +c010304d: e9 f2 f9 ff ff jmp c0102a44 <__alltraps> + +c0103052 : +.globl vector159 +vector159: + pushl $0 +c0103052: 6a 00 push $0x0 + pushl $159 +c0103054: 68 9f 00 00 00 push $0x9f + jmp __alltraps +c0103059: e9 e6 f9 ff ff jmp c0102a44 <__alltraps> + +c010305e : +.globl vector160 +vector160: + pushl $0 +c010305e: 6a 00 push $0x0 + pushl $160 +c0103060: 68 a0 00 00 00 push $0xa0 + jmp __alltraps +c0103065: e9 da f9 ff ff jmp c0102a44 <__alltraps> + +c010306a : +.globl vector161 +vector161: + pushl $0 +c010306a: 6a 00 push $0x0 + pushl $161 +c010306c: 68 a1 00 00 00 push $0xa1 + jmp __alltraps +c0103071: e9 ce f9 ff ff jmp c0102a44 <__alltraps> + +c0103076 : +.globl vector162 +vector162: + pushl $0 +c0103076: 6a 00 push $0x0 + pushl $162 +c0103078: 68 a2 00 00 00 push $0xa2 + jmp __alltraps +c010307d: e9 c2 f9 ff ff jmp c0102a44 <__alltraps> + +c0103082 : +.globl vector163 +vector163: + pushl $0 +c0103082: 6a 00 push $0x0 + pushl $163 +c0103084: 68 a3 00 00 00 push $0xa3 + jmp __alltraps +c0103089: e9 b6 f9 ff ff jmp c0102a44 <__alltraps> + +c010308e : +.globl vector164 +vector164: + pushl $0 +c010308e: 6a 00 push $0x0 + pushl $164 +c0103090: 68 a4 00 00 00 push $0xa4 + jmp __alltraps +c0103095: e9 aa f9 ff ff jmp c0102a44 <__alltraps> + +c010309a : +.globl vector165 +vector165: + pushl $0 +c010309a: 6a 00 push $0x0 + pushl $165 +c010309c: 68 a5 00 00 00 push $0xa5 + jmp __alltraps +c01030a1: e9 9e f9 ff ff jmp c0102a44 <__alltraps> + +c01030a6 : +.globl vector166 +vector166: + pushl $0 +c01030a6: 6a 00 push $0x0 + pushl $166 +c01030a8: 68 a6 00 00 00 push $0xa6 + jmp __alltraps +c01030ad: e9 92 f9 ff ff jmp c0102a44 <__alltraps> + +c01030b2 : +.globl vector167 +vector167: + pushl $0 +c01030b2: 6a 00 push $0x0 + pushl $167 +c01030b4: 68 a7 00 00 00 push $0xa7 + jmp __alltraps +c01030b9: e9 86 f9 ff ff jmp c0102a44 <__alltraps> + +c01030be : +.globl vector168 +vector168: + pushl $0 +c01030be: 6a 00 push $0x0 + pushl $168 +c01030c0: 68 a8 00 00 00 push $0xa8 + jmp __alltraps +c01030c5: e9 7a f9 ff ff jmp c0102a44 <__alltraps> + +c01030ca : +.globl vector169 +vector169: + pushl $0 +c01030ca: 6a 00 push $0x0 + pushl $169 +c01030cc: 68 a9 00 00 00 push $0xa9 + jmp __alltraps +c01030d1: e9 6e f9 ff ff jmp c0102a44 <__alltraps> + +c01030d6 : +.globl vector170 +vector170: + pushl $0 +c01030d6: 6a 00 push $0x0 + pushl $170 +c01030d8: 68 aa 00 00 00 push $0xaa + jmp __alltraps +c01030dd: e9 62 f9 ff ff jmp c0102a44 <__alltraps> + +c01030e2 : +.globl vector171 +vector171: + pushl $0 +c01030e2: 6a 00 push $0x0 + pushl $171 +c01030e4: 68 ab 00 00 00 push $0xab + jmp __alltraps +c01030e9: e9 56 f9 ff ff jmp c0102a44 <__alltraps> + +c01030ee : +.globl vector172 +vector172: + pushl $0 +c01030ee: 6a 00 push $0x0 + pushl $172 +c01030f0: 68 ac 00 00 00 push $0xac + jmp __alltraps +c01030f5: e9 4a f9 ff ff jmp c0102a44 <__alltraps> + +c01030fa : +.globl vector173 +vector173: + pushl $0 +c01030fa: 6a 00 push $0x0 + pushl $173 +c01030fc: 68 ad 00 00 00 push $0xad + jmp __alltraps +c0103101: e9 3e f9 ff ff jmp c0102a44 <__alltraps> + +c0103106 : +.globl vector174 +vector174: + pushl $0 +c0103106: 6a 00 push $0x0 + pushl $174 +c0103108: 68 ae 00 00 00 push $0xae + jmp __alltraps +c010310d: e9 32 f9 ff ff jmp c0102a44 <__alltraps> + +c0103112 : +.globl vector175 +vector175: + pushl $0 +c0103112: 6a 00 push $0x0 + pushl $175 +c0103114: 68 af 00 00 00 push $0xaf + jmp __alltraps +c0103119: e9 26 f9 ff ff jmp c0102a44 <__alltraps> + +c010311e : +.globl vector176 +vector176: + pushl $0 +c010311e: 6a 00 push $0x0 + pushl $176 +c0103120: 68 b0 00 00 00 push $0xb0 + jmp __alltraps +c0103125: e9 1a f9 ff ff jmp c0102a44 <__alltraps> + +c010312a : +.globl vector177 +vector177: + pushl $0 +c010312a: 6a 00 push $0x0 + pushl $177 +c010312c: 68 b1 00 00 00 push $0xb1 + jmp __alltraps +c0103131: e9 0e f9 ff ff jmp c0102a44 <__alltraps> + +c0103136 : +.globl vector178 +vector178: + pushl $0 +c0103136: 6a 00 push $0x0 + pushl $178 +c0103138: 68 b2 00 00 00 push $0xb2 + jmp __alltraps +c010313d: e9 02 f9 ff ff jmp c0102a44 <__alltraps> + +c0103142 : +.globl vector179 +vector179: + pushl $0 +c0103142: 6a 00 push $0x0 + pushl $179 +c0103144: 68 b3 00 00 00 push $0xb3 + jmp __alltraps +c0103149: e9 f6 f8 ff ff jmp c0102a44 <__alltraps> + +c010314e : +.globl vector180 +vector180: + pushl $0 +c010314e: 6a 00 push $0x0 + pushl $180 +c0103150: 68 b4 00 00 00 push $0xb4 + jmp __alltraps +c0103155: e9 ea f8 ff ff jmp c0102a44 <__alltraps> + +c010315a : +.globl vector181 +vector181: + pushl $0 +c010315a: 6a 00 push $0x0 + pushl $181 +c010315c: 68 b5 00 00 00 push $0xb5 + jmp __alltraps +c0103161: e9 de f8 ff ff jmp c0102a44 <__alltraps> + +c0103166 : +.globl vector182 +vector182: + pushl $0 +c0103166: 6a 00 push $0x0 + pushl $182 +c0103168: 68 b6 00 00 00 push $0xb6 + jmp __alltraps +c010316d: e9 d2 f8 ff ff jmp c0102a44 <__alltraps> + +c0103172 : +.globl vector183 +vector183: + pushl $0 +c0103172: 6a 00 push $0x0 + pushl $183 +c0103174: 68 b7 00 00 00 push $0xb7 + jmp __alltraps +c0103179: e9 c6 f8 ff ff jmp c0102a44 <__alltraps> + +c010317e : +.globl vector184 +vector184: + pushl $0 +c010317e: 6a 00 push $0x0 + pushl $184 +c0103180: 68 b8 00 00 00 push $0xb8 + jmp __alltraps +c0103185: e9 ba f8 ff ff jmp c0102a44 <__alltraps> + +c010318a : +.globl vector185 +vector185: + pushl $0 +c010318a: 6a 00 push $0x0 + pushl $185 +c010318c: 68 b9 00 00 00 push $0xb9 + jmp __alltraps +c0103191: e9 ae f8 ff ff jmp c0102a44 <__alltraps> + +c0103196 : +.globl vector186 +vector186: + pushl $0 +c0103196: 6a 00 push $0x0 + pushl $186 +c0103198: 68 ba 00 00 00 push $0xba + jmp __alltraps +c010319d: e9 a2 f8 ff ff jmp c0102a44 <__alltraps> + +c01031a2 : +.globl vector187 +vector187: + pushl $0 +c01031a2: 6a 00 push $0x0 + pushl $187 +c01031a4: 68 bb 00 00 00 push $0xbb + jmp __alltraps +c01031a9: e9 96 f8 ff ff jmp c0102a44 <__alltraps> + +c01031ae : +.globl vector188 +vector188: + pushl $0 +c01031ae: 6a 00 push $0x0 + pushl $188 +c01031b0: 68 bc 00 00 00 push $0xbc + jmp __alltraps +c01031b5: e9 8a f8 ff ff jmp c0102a44 <__alltraps> + +c01031ba : +.globl vector189 +vector189: + pushl $0 +c01031ba: 6a 00 push $0x0 + pushl $189 +c01031bc: 68 bd 00 00 00 push $0xbd + jmp __alltraps +c01031c1: e9 7e f8 ff ff jmp c0102a44 <__alltraps> + +c01031c6 : +.globl vector190 +vector190: + pushl $0 +c01031c6: 6a 00 push $0x0 + pushl $190 +c01031c8: 68 be 00 00 00 push $0xbe + jmp __alltraps +c01031cd: e9 72 f8 ff ff jmp c0102a44 <__alltraps> + +c01031d2 : +.globl vector191 +vector191: + pushl $0 +c01031d2: 6a 00 push $0x0 + pushl $191 +c01031d4: 68 bf 00 00 00 push $0xbf + jmp __alltraps +c01031d9: e9 66 f8 ff ff jmp c0102a44 <__alltraps> + +c01031de : +.globl vector192 +vector192: + pushl $0 +c01031de: 6a 00 push $0x0 + pushl $192 +c01031e0: 68 c0 00 00 00 push $0xc0 + jmp __alltraps +c01031e5: e9 5a f8 ff ff jmp c0102a44 <__alltraps> + +c01031ea : +.globl vector193 +vector193: + pushl $0 +c01031ea: 6a 00 push $0x0 + pushl $193 +c01031ec: 68 c1 00 00 00 push $0xc1 + jmp __alltraps +c01031f1: e9 4e f8 ff ff jmp c0102a44 <__alltraps> + +c01031f6 : +.globl vector194 +vector194: + pushl $0 +c01031f6: 6a 00 push $0x0 + pushl $194 +c01031f8: 68 c2 00 00 00 push $0xc2 + jmp __alltraps +c01031fd: e9 42 f8 ff ff jmp c0102a44 <__alltraps> + +c0103202 : +.globl vector195 +vector195: + pushl $0 +c0103202: 6a 00 push $0x0 + pushl $195 +c0103204: 68 c3 00 00 00 push $0xc3 + jmp __alltraps +c0103209: e9 36 f8 ff ff jmp c0102a44 <__alltraps> + +c010320e : +.globl vector196 +vector196: + pushl $0 +c010320e: 6a 00 push $0x0 + pushl $196 +c0103210: 68 c4 00 00 00 push $0xc4 + jmp __alltraps +c0103215: e9 2a f8 ff ff jmp c0102a44 <__alltraps> + +c010321a : +.globl vector197 +vector197: + pushl $0 +c010321a: 6a 00 push $0x0 + pushl $197 +c010321c: 68 c5 00 00 00 push $0xc5 + jmp __alltraps +c0103221: e9 1e f8 ff ff jmp c0102a44 <__alltraps> + +c0103226 : +.globl vector198 +vector198: + pushl $0 +c0103226: 6a 00 push $0x0 + pushl $198 +c0103228: 68 c6 00 00 00 push $0xc6 + jmp __alltraps +c010322d: e9 12 f8 ff ff jmp c0102a44 <__alltraps> + +c0103232 : +.globl vector199 +vector199: + pushl $0 +c0103232: 6a 00 push $0x0 + pushl $199 +c0103234: 68 c7 00 00 00 push $0xc7 + jmp __alltraps +c0103239: e9 06 f8 ff ff jmp c0102a44 <__alltraps> + +c010323e : +.globl vector200 +vector200: + pushl $0 +c010323e: 6a 00 push $0x0 + pushl $200 +c0103240: 68 c8 00 00 00 push $0xc8 + jmp __alltraps +c0103245: e9 fa f7 ff ff jmp c0102a44 <__alltraps> + +c010324a : +.globl vector201 +vector201: + pushl $0 +c010324a: 6a 00 push $0x0 + pushl $201 +c010324c: 68 c9 00 00 00 push $0xc9 + jmp __alltraps +c0103251: e9 ee f7 ff ff jmp c0102a44 <__alltraps> + +c0103256 : +.globl vector202 +vector202: + pushl $0 +c0103256: 6a 00 push $0x0 + pushl $202 +c0103258: 68 ca 00 00 00 push $0xca + jmp __alltraps +c010325d: e9 e2 f7 ff ff jmp c0102a44 <__alltraps> + +c0103262 : +.globl vector203 +vector203: + pushl $0 +c0103262: 6a 00 push $0x0 + pushl $203 +c0103264: 68 cb 00 00 00 push $0xcb + jmp __alltraps +c0103269: e9 d6 f7 ff ff jmp c0102a44 <__alltraps> + +c010326e : +.globl vector204 +vector204: + pushl $0 +c010326e: 6a 00 push $0x0 + pushl $204 +c0103270: 68 cc 00 00 00 push $0xcc + jmp __alltraps +c0103275: e9 ca f7 ff ff jmp c0102a44 <__alltraps> + +c010327a : +.globl vector205 +vector205: + pushl $0 +c010327a: 6a 00 push $0x0 + pushl $205 +c010327c: 68 cd 00 00 00 push $0xcd + jmp __alltraps +c0103281: e9 be f7 ff ff jmp c0102a44 <__alltraps> + +c0103286 : +.globl vector206 +vector206: + pushl $0 +c0103286: 6a 00 push $0x0 + pushl $206 +c0103288: 68 ce 00 00 00 push $0xce + jmp __alltraps +c010328d: e9 b2 f7 ff ff jmp c0102a44 <__alltraps> + +c0103292 : +.globl vector207 +vector207: + pushl $0 +c0103292: 6a 00 push $0x0 + pushl $207 +c0103294: 68 cf 00 00 00 push $0xcf + jmp __alltraps +c0103299: e9 a6 f7 ff ff jmp c0102a44 <__alltraps> + +c010329e : +.globl vector208 +vector208: + pushl $0 +c010329e: 6a 00 push $0x0 + pushl $208 +c01032a0: 68 d0 00 00 00 push $0xd0 + jmp __alltraps +c01032a5: e9 9a f7 ff ff jmp c0102a44 <__alltraps> + +c01032aa : +.globl vector209 +vector209: + pushl $0 +c01032aa: 6a 00 push $0x0 + pushl $209 +c01032ac: 68 d1 00 00 00 push $0xd1 + jmp __alltraps +c01032b1: e9 8e f7 ff ff jmp c0102a44 <__alltraps> + +c01032b6 : +.globl vector210 +vector210: + pushl $0 +c01032b6: 6a 00 push $0x0 + pushl $210 +c01032b8: 68 d2 00 00 00 push $0xd2 + jmp __alltraps +c01032bd: e9 82 f7 ff ff jmp c0102a44 <__alltraps> + +c01032c2 : +.globl vector211 +vector211: + pushl $0 +c01032c2: 6a 00 push $0x0 + pushl $211 +c01032c4: 68 d3 00 00 00 push $0xd3 + jmp __alltraps +c01032c9: e9 76 f7 ff ff jmp c0102a44 <__alltraps> + +c01032ce : +.globl vector212 +vector212: + pushl $0 +c01032ce: 6a 00 push $0x0 + pushl $212 +c01032d0: 68 d4 00 00 00 push $0xd4 + jmp __alltraps +c01032d5: e9 6a f7 ff ff jmp c0102a44 <__alltraps> + +c01032da : +.globl vector213 +vector213: + pushl $0 +c01032da: 6a 00 push $0x0 + pushl $213 +c01032dc: 68 d5 00 00 00 push $0xd5 + jmp __alltraps +c01032e1: e9 5e f7 ff ff jmp c0102a44 <__alltraps> + +c01032e6 : +.globl vector214 +vector214: + pushl $0 +c01032e6: 6a 00 push $0x0 + pushl $214 +c01032e8: 68 d6 00 00 00 push $0xd6 + jmp __alltraps +c01032ed: e9 52 f7 ff ff jmp c0102a44 <__alltraps> + +c01032f2 : +.globl vector215 +vector215: + pushl $0 +c01032f2: 6a 00 push $0x0 + pushl $215 +c01032f4: 68 d7 00 00 00 push $0xd7 + jmp __alltraps +c01032f9: e9 46 f7 ff ff jmp c0102a44 <__alltraps> + +c01032fe : +.globl vector216 +vector216: + pushl $0 +c01032fe: 6a 00 push $0x0 + pushl $216 +c0103300: 68 d8 00 00 00 push $0xd8 + jmp __alltraps +c0103305: e9 3a f7 ff ff jmp c0102a44 <__alltraps> + +c010330a : +.globl vector217 +vector217: + pushl $0 +c010330a: 6a 00 push $0x0 + pushl $217 +c010330c: 68 d9 00 00 00 push $0xd9 + jmp __alltraps +c0103311: e9 2e f7 ff ff jmp c0102a44 <__alltraps> + +c0103316 : +.globl vector218 +vector218: + pushl $0 +c0103316: 6a 00 push $0x0 + pushl $218 +c0103318: 68 da 00 00 00 push $0xda + jmp __alltraps +c010331d: e9 22 f7 ff ff jmp c0102a44 <__alltraps> + +c0103322 : +.globl vector219 +vector219: + pushl $0 +c0103322: 6a 00 push $0x0 + pushl $219 +c0103324: 68 db 00 00 00 push $0xdb + jmp __alltraps +c0103329: e9 16 f7 ff ff jmp c0102a44 <__alltraps> + +c010332e : +.globl vector220 +vector220: + pushl $0 +c010332e: 6a 00 push $0x0 + pushl $220 +c0103330: 68 dc 00 00 00 push $0xdc + jmp __alltraps +c0103335: e9 0a f7 ff ff jmp c0102a44 <__alltraps> + +c010333a : +.globl vector221 +vector221: + pushl $0 +c010333a: 6a 00 push $0x0 + pushl $221 +c010333c: 68 dd 00 00 00 push $0xdd + jmp __alltraps +c0103341: e9 fe f6 ff ff jmp c0102a44 <__alltraps> + +c0103346 : +.globl vector222 +vector222: + pushl $0 +c0103346: 6a 00 push $0x0 + pushl $222 +c0103348: 68 de 00 00 00 push $0xde + jmp __alltraps +c010334d: e9 f2 f6 ff ff jmp c0102a44 <__alltraps> + +c0103352 : +.globl vector223 +vector223: + pushl $0 +c0103352: 6a 00 push $0x0 + pushl $223 +c0103354: 68 df 00 00 00 push $0xdf + jmp __alltraps +c0103359: e9 e6 f6 ff ff jmp c0102a44 <__alltraps> + +c010335e : +.globl vector224 +vector224: + pushl $0 +c010335e: 6a 00 push $0x0 + pushl $224 +c0103360: 68 e0 00 00 00 push $0xe0 + jmp __alltraps +c0103365: e9 da f6 ff ff jmp c0102a44 <__alltraps> + +c010336a : +.globl vector225 +vector225: + pushl $0 +c010336a: 6a 00 push $0x0 + pushl $225 +c010336c: 68 e1 00 00 00 push $0xe1 + jmp __alltraps +c0103371: e9 ce f6 ff ff jmp c0102a44 <__alltraps> + +c0103376 : +.globl vector226 +vector226: + pushl $0 +c0103376: 6a 00 push $0x0 + pushl $226 +c0103378: 68 e2 00 00 00 push $0xe2 + jmp __alltraps +c010337d: e9 c2 f6 ff ff jmp c0102a44 <__alltraps> + +c0103382 : +.globl vector227 +vector227: + pushl $0 +c0103382: 6a 00 push $0x0 + pushl $227 +c0103384: 68 e3 00 00 00 push $0xe3 + jmp __alltraps +c0103389: e9 b6 f6 ff ff jmp c0102a44 <__alltraps> + +c010338e : +.globl vector228 +vector228: + pushl $0 +c010338e: 6a 00 push $0x0 + pushl $228 +c0103390: 68 e4 00 00 00 push $0xe4 + jmp __alltraps +c0103395: e9 aa f6 ff ff jmp c0102a44 <__alltraps> + +c010339a : +.globl vector229 +vector229: + pushl $0 +c010339a: 6a 00 push $0x0 + pushl $229 +c010339c: 68 e5 00 00 00 push $0xe5 + jmp __alltraps +c01033a1: e9 9e f6 ff ff jmp c0102a44 <__alltraps> + +c01033a6 : +.globl vector230 +vector230: + pushl $0 +c01033a6: 6a 00 push $0x0 + pushl $230 +c01033a8: 68 e6 00 00 00 push $0xe6 + jmp __alltraps +c01033ad: e9 92 f6 ff ff jmp c0102a44 <__alltraps> + +c01033b2 : +.globl vector231 +vector231: + pushl $0 +c01033b2: 6a 00 push $0x0 + pushl $231 +c01033b4: 68 e7 00 00 00 push $0xe7 + jmp __alltraps +c01033b9: e9 86 f6 ff ff jmp c0102a44 <__alltraps> + +c01033be : +.globl vector232 +vector232: + pushl $0 +c01033be: 6a 00 push $0x0 + pushl $232 +c01033c0: 68 e8 00 00 00 push $0xe8 + jmp __alltraps +c01033c5: e9 7a f6 ff ff jmp c0102a44 <__alltraps> + +c01033ca : +.globl vector233 +vector233: + pushl $0 +c01033ca: 6a 00 push $0x0 + pushl $233 +c01033cc: 68 e9 00 00 00 push $0xe9 + jmp __alltraps +c01033d1: e9 6e f6 ff ff jmp c0102a44 <__alltraps> + +c01033d6 : +.globl vector234 +vector234: + pushl $0 +c01033d6: 6a 00 push $0x0 + pushl $234 +c01033d8: 68 ea 00 00 00 push $0xea + jmp __alltraps +c01033dd: e9 62 f6 ff ff jmp c0102a44 <__alltraps> + +c01033e2 : +.globl vector235 +vector235: + pushl $0 +c01033e2: 6a 00 push $0x0 + pushl $235 +c01033e4: 68 eb 00 00 00 push $0xeb + jmp __alltraps +c01033e9: e9 56 f6 ff ff jmp c0102a44 <__alltraps> + +c01033ee : +.globl vector236 +vector236: + pushl $0 +c01033ee: 6a 00 push $0x0 + pushl $236 +c01033f0: 68 ec 00 00 00 push $0xec + jmp __alltraps +c01033f5: e9 4a f6 ff ff jmp c0102a44 <__alltraps> + +c01033fa : +.globl vector237 +vector237: + pushl $0 +c01033fa: 6a 00 push $0x0 + pushl $237 +c01033fc: 68 ed 00 00 00 push $0xed + jmp __alltraps +c0103401: e9 3e f6 ff ff jmp c0102a44 <__alltraps> + +c0103406 : +.globl vector238 +vector238: + pushl $0 +c0103406: 6a 00 push $0x0 + pushl $238 +c0103408: 68 ee 00 00 00 push $0xee + jmp __alltraps +c010340d: e9 32 f6 ff ff jmp c0102a44 <__alltraps> + +c0103412 : +.globl vector239 +vector239: + pushl $0 +c0103412: 6a 00 push $0x0 + pushl $239 +c0103414: 68 ef 00 00 00 push $0xef + jmp __alltraps +c0103419: e9 26 f6 ff ff jmp c0102a44 <__alltraps> + +c010341e : +.globl vector240 +vector240: + pushl $0 +c010341e: 6a 00 push $0x0 + pushl $240 +c0103420: 68 f0 00 00 00 push $0xf0 + jmp __alltraps +c0103425: e9 1a f6 ff ff jmp c0102a44 <__alltraps> + +c010342a : +.globl vector241 +vector241: + pushl $0 +c010342a: 6a 00 push $0x0 + pushl $241 +c010342c: 68 f1 00 00 00 push $0xf1 + jmp __alltraps +c0103431: e9 0e f6 ff ff jmp c0102a44 <__alltraps> + +c0103436 : +.globl vector242 +vector242: + pushl $0 +c0103436: 6a 00 push $0x0 + pushl $242 +c0103438: 68 f2 00 00 00 push $0xf2 + jmp __alltraps +c010343d: e9 02 f6 ff ff jmp c0102a44 <__alltraps> + +c0103442 : +.globl vector243 +vector243: + pushl $0 +c0103442: 6a 00 push $0x0 + pushl $243 +c0103444: 68 f3 00 00 00 push $0xf3 + jmp __alltraps +c0103449: e9 f6 f5 ff ff jmp c0102a44 <__alltraps> + +c010344e : +.globl vector244 +vector244: + pushl $0 +c010344e: 6a 00 push $0x0 + pushl $244 +c0103450: 68 f4 00 00 00 push $0xf4 + jmp __alltraps +c0103455: e9 ea f5 ff ff jmp c0102a44 <__alltraps> + +c010345a : +.globl vector245 +vector245: + pushl $0 +c010345a: 6a 00 push $0x0 + pushl $245 +c010345c: 68 f5 00 00 00 push $0xf5 + jmp __alltraps +c0103461: e9 de f5 ff ff jmp c0102a44 <__alltraps> + +c0103466 : +.globl vector246 +vector246: + pushl $0 +c0103466: 6a 00 push $0x0 + pushl $246 +c0103468: 68 f6 00 00 00 push $0xf6 + jmp __alltraps +c010346d: e9 d2 f5 ff ff jmp c0102a44 <__alltraps> + +c0103472 : +.globl vector247 +vector247: + pushl $0 +c0103472: 6a 00 push $0x0 + pushl $247 +c0103474: 68 f7 00 00 00 push $0xf7 + jmp __alltraps +c0103479: e9 c6 f5 ff ff jmp c0102a44 <__alltraps> + +c010347e : +.globl vector248 +vector248: + pushl $0 +c010347e: 6a 00 push $0x0 + pushl $248 +c0103480: 68 f8 00 00 00 push $0xf8 + jmp __alltraps +c0103485: e9 ba f5 ff ff jmp c0102a44 <__alltraps> + +c010348a : +.globl vector249 +vector249: + pushl $0 +c010348a: 6a 00 push $0x0 + pushl $249 +c010348c: 68 f9 00 00 00 push $0xf9 + jmp __alltraps +c0103491: e9 ae f5 ff ff jmp c0102a44 <__alltraps> + +c0103496 : +.globl vector250 +vector250: + pushl $0 +c0103496: 6a 00 push $0x0 + pushl $250 +c0103498: 68 fa 00 00 00 push $0xfa + jmp __alltraps +c010349d: e9 a2 f5 ff ff jmp c0102a44 <__alltraps> + +c01034a2 : +.globl vector251 +vector251: + pushl $0 +c01034a2: 6a 00 push $0x0 + pushl $251 +c01034a4: 68 fb 00 00 00 push $0xfb + jmp __alltraps +c01034a9: e9 96 f5 ff ff jmp c0102a44 <__alltraps> + +c01034ae : +.globl vector252 +vector252: + pushl $0 +c01034ae: 6a 00 push $0x0 + pushl $252 +c01034b0: 68 fc 00 00 00 push $0xfc + jmp __alltraps +c01034b5: e9 8a f5 ff ff jmp c0102a44 <__alltraps> + +c01034ba : +.globl vector253 +vector253: + pushl $0 +c01034ba: 6a 00 push $0x0 + pushl $253 +c01034bc: 68 fd 00 00 00 push $0xfd + jmp __alltraps +c01034c1: e9 7e f5 ff ff jmp c0102a44 <__alltraps> + +c01034c6 : +.globl vector254 +vector254: + pushl $0 +c01034c6: 6a 00 push $0x0 + pushl $254 +c01034c8: 68 fe 00 00 00 push $0xfe + jmp __alltraps +c01034cd: e9 72 f5 ff ff jmp c0102a44 <__alltraps> + +c01034d2 : +.globl vector255 +vector255: + pushl $0 +c01034d2: 6a 00 push $0x0 + pushl $255 +c01034d4: 68 ff 00 00 00 push $0xff + jmp __alltraps +c01034d9: e9 66 f5 ff ff jmp c0102a44 <__alltraps> + +c01034de : + +extern struct Page *pages; +extern size_t npage; + +static inline ppn_t +page2ppn(struct Page *page) { +c01034de: 55 push %ebp +c01034df: 89 e5 mov %esp,%ebp + return page - pages; +c01034e1: 8b 15 a0 3f 1a c0 mov 0xc01a3fa0,%edx +c01034e7: 8b 45 08 mov 0x8(%ebp),%eax +c01034ea: 29 d0 sub %edx,%eax +c01034ec: c1 f8 05 sar $0x5,%eax +} +c01034ef: 5d pop %ebp +c01034f0: c3 ret + +c01034f1 : + +static inline uintptr_t +page2pa(struct Page *page) { +c01034f1: 55 push %ebp +c01034f2: 89 e5 mov %esp,%ebp +c01034f4: 83 ec 04 sub $0x4,%esp + return page2ppn(page) << PGSHIFT; +c01034f7: 8b 45 08 mov 0x8(%ebp),%eax +c01034fa: 89 04 24 mov %eax,(%esp) +c01034fd: e8 dc ff ff ff call c01034de +c0103502: c1 e0 0c shl $0xc,%eax +} +c0103505: 89 ec mov %ebp,%esp +c0103507: 5d pop %ebp +c0103508: c3 ret + +c0103509 : +pde2page(pde_t pde) { + return pa2page(PDE_ADDR(pde)); +} + +static inline int +page_ref(struct Page *page) { +c0103509: 55 push %ebp +c010350a: 89 e5 mov %esp,%ebp + return page->ref; +c010350c: 8b 45 08 mov 0x8(%ebp),%eax +c010350f: 8b 00 mov (%eax),%eax +} +c0103511: 5d pop %ebp +c0103512: c3 ret + +c0103513 : + +static inline void +set_page_ref(struct Page *page, int val) { +c0103513: 55 push %ebp +c0103514: 89 e5 mov %esp,%ebp + page->ref = val; +c0103516: 8b 45 08 mov 0x8(%ebp),%eax +c0103519: 8b 55 0c mov 0xc(%ebp),%edx +c010351c: 89 10 mov %edx,(%eax) +} +c010351e: 90 nop +c010351f: 5d pop %ebp +c0103520: c3 ret + +c0103521 : +#define nr_free (free_area.nr_free) + +//free_list` 用于记录空闲内存块,nr_free` 是空闲内存块的总数。 +//用default_init函数来初始化 `free_list`,并将 `nr_free` 设置为 0。 +static void +default_init(void) { +c0103521: 55 push %ebp +c0103522: 89 e5 mov %esp,%ebp +c0103524: 83 ec 10 sub $0x10,%esp +c0103527: c7 45 fc 84 3f 1a c0 movl $0xc01a3f84,-0x4(%ebp) + * list_init - initialize a new entry + * @elm: new entry to be initialized + * */ +static inline void +list_init(list_entry_t *elm) { + elm->prev = elm->next = elm; +c010352e: 8b 45 fc mov -0x4(%ebp),%eax +c0103531: 8b 55 fc mov -0x4(%ebp),%edx +c0103534: 89 50 04 mov %edx,0x4(%eax) +c0103537: 8b 45 fc mov -0x4(%ebp),%eax +c010353a: 8b 50 04 mov 0x4(%eax),%edx +c010353d: 8b 45 fc mov -0x4(%ebp),%eax +c0103540: 89 10 mov %edx,(%eax) +} +c0103542: 90 nop + list_init(&free_list); + nr_free = 0; +c0103543: c7 05 8c 3f 1a c0 00 movl $0x0,0xc01a3f8c +c010354a: 00 00 00 +} +c010354d: 90 nop +c010354e: 89 ec mov %ebp,%esp +c0103550: 5d pop %ebp +c0103551: c3 ret + +c0103552 : + +//用于初始化一段连续的物理页,并将它们加入到空闲内存管理系统中. +//struct Page *base:指向要初始化的页块的起始地址。size_t n:要初始化的页的数量。 +static void +default_init_memmap(struct Page *base, size_t n) { +c0103552: 55 push %ebp +c0103553: 89 e5 mov %esp,%ebp +c0103555: 83 ec 48 sub $0x48,%esp + assert(n > 0);// 确保请求的页数大于零 +c0103558: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) +c010355c: 75 24 jne c0103582 +c010355e: c7 44 24 0c 30 c9 10 movl $0xc010c930,0xc(%esp) +c0103565: c0 +c0103566: c7 44 24 08 36 c9 10 movl $0xc010c936,0x8(%esp) +c010356d: c0 +c010356e: c7 44 24 04 9a 00 00 movl $0x9a,0x4(%esp) +c0103575: 00 +c0103576: c7 04 24 4b c9 10 c0 movl $0xc010c94b,(%esp) +c010357d: e8 b9 d7 ff ff call c0100d3b <__panic> + struct Page *p = base;// 指向当前初始化的页 +c0103582: 8b 45 08 mov 0x8(%ebp),%eax +c0103585: 89 45 f4 mov %eax,-0xc(%ebp) + // 遍历每一页,设置其状态 + for (; p != base + n; p ++) { +c0103588: eb 7d jmp c0103607 + assert(PageReserved(p));//检查每个页是否被标记为“保留”。若没有被保留,函数将抛出错误。 +c010358a: 8b 45 f4 mov -0xc(%ebp),%eax +c010358d: 83 c0 04 add $0x4,%eax +c0103590: c7 45 f0 00 00 00 00 movl $0x0,-0x10(%ebp) +c0103597: 89 45 ec mov %eax,-0x14(%ebp) + * @addr: the address to count from + * */ +static inline bool +test_bit(int nr, volatile void *addr) { + int oldbit; + asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr)); +c010359a: 8b 45 ec mov -0x14(%ebp),%eax +c010359d: 8b 55 f0 mov -0x10(%ebp),%edx +c01035a0: 0f a3 10 bt %edx,(%eax) +c01035a3: 19 c0 sbb %eax,%eax +c01035a5: 89 45 e8 mov %eax,-0x18(%ebp) + return oldbit != 0; +c01035a8: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) +c01035ac: 0f 95 c0 setne %al +c01035af: 0f b6 c0 movzbl %al,%eax +c01035b2: 85 c0 test %eax,%eax +c01035b4: 75 24 jne c01035da +c01035b6: c7 44 24 0c 61 c9 10 movl $0xc010c961,0xc(%esp) +c01035bd: c0 +c01035be: c7 44 24 08 36 c9 10 movl $0xc010c936,0x8(%esp) +c01035c5: c0 +c01035c6: c7 44 24 04 9e 00 00 movl $0x9e,0x4(%esp) +c01035cd: 00 +c01035ce: c7 04 24 4b c9 10 c0 movl $0xc010c94b,(%esp) +c01035d5: e8 61 d7 ff ff call c0100d3b <__panic> + p->flags = p->property = 0;//将页的 flags 和 property 字段设置为 0,表示该页未分配、未使用。 +c01035da: 8b 45 f4 mov -0xc(%ebp),%eax +c01035dd: c7 40 08 00 00 00 00 movl $0x0,0x8(%eax) +c01035e4: 8b 45 f4 mov -0xc(%ebp),%eax +c01035e7: 8b 50 08 mov 0x8(%eax),%edx +c01035ea: 8b 45 f4 mov -0xc(%ebp),%eax +c01035ed: 89 50 04 mov %edx,0x4(%eax) + set_page_ref(p, 0);//将页的引用计数设置为 0,表明没有任何引用指向此页。 +c01035f0: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) +c01035f7: 00 +c01035f8: 8b 45 f4 mov -0xc(%ebp),%eax +c01035fb: 89 04 24 mov %eax,(%esp) +c01035fe: e8 10 ff ff ff call c0103513 + for (; p != base + n; p ++) { +c0103603: 83 45 f4 20 addl $0x20,-0xc(%ebp) +c0103607: 8b 45 0c mov 0xc(%ebp),%eax +c010360a: c1 e0 05 shl $0x5,%eax +c010360d: 89 c2 mov %eax,%edx +c010360f: 8b 45 08 mov 0x8(%ebp),%eax +c0103612: 01 d0 add %edx,%eax +c0103614: 39 45 f4 cmp %eax,-0xc(%ebp) +c0103617: 0f 85 6d ff ff ff jne c010358a + } + // 设置第一个页的 property 为块的总数 + base->property = n; +c010361d: 8b 45 08 mov 0x8(%ebp),%eax +c0103620: 8b 55 0c mov 0xc(%ebp),%edx +c0103623: 89 50 08 mov %edx,0x8(%eax) + SetPageProperty(base);// 设置当前页的有效标志 +c0103626: 8b 45 08 mov 0x8(%ebp),%eax +c0103629: 83 c0 04 add $0x4,%eax +c010362c: c7 45 d0 01 00 00 00 movl $0x1,-0x30(%ebp) +c0103633: 89 45 cc mov %eax,-0x34(%ebp) + asm volatile ("btsl %1, %0" :"=m" (*(volatile long *)addr) : "Ir" (nr)); +c0103636: 8b 45 cc mov -0x34(%ebp),%eax +c0103639: 8b 55 d0 mov -0x30(%ebp),%edx +c010363c: 0f ab 10 bts %edx,(%eax) +} +c010363f: 90 nop + nr_free += n;// 更新空闲页计数 +c0103640: 8b 15 8c 3f 1a c0 mov 0xc01a3f8c,%edx +c0103646: 8b 45 0c mov 0xc(%ebp),%eax +c0103649: 01 d0 add %edx,%eax +c010364b: a3 8c 3f 1a c0 mov %eax,0xc01a3f8c + list_add_before(&free_list, &(base->page_link));// 将该块添加到空闲列表中 +c0103650: 8b 45 08 mov 0x8(%ebp),%eax +c0103653: 83 c0 0c add $0xc,%eax +c0103656: c7 45 e4 84 3f 1a c0 movl $0xc01a3f84,-0x1c(%ebp) +c010365d: 89 45 e0 mov %eax,-0x20(%ebp) + * Insert the new element @elm *before* the element @listelm which + * is already in the list. + * */ +static inline void +list_add_before(list_entry_t *listelm, list_entry_t *elm) { + __list_add(elm, listelm->prev, listelm); +c0103660: 8b 45 e4 mov -0x1c(%ebp),%eax +c0103663: 8b 00 mov (%eax),%eax +c0103665: 8b 55 e0 mov -0x20(%ebp),%edx +c0103668: 89 55 dc mov %edx,-0x24(%ebp) +c010366b: 89 45 d8 mov %eax,-0x28(%ebp) +c010366e: 8b 45 e4 mov -0x1c(%ebp),%eax +c0103671: 89 45 d4 mov %eax,-0x2c(%ebp) + * This is only for internal list manipulation where we know + * the prev/next entries already! + * */ +static inline void +__list_add(list_entry_t *elm, list_entry_t *prev, list_entry_t *next) { + prev->next = next->prev = elm; +c0103674: 8b 45 d4 mov -0x2c(%ebp),%eax +c0103677: 8b 55 dc mov -0x24(%ebp),%edx +c010367a: 89 10 mov %edx,(%eax) +c010367c: 8b 45 d4 mov -0x2c(%ebp),%eax +c010367f: 8b 10 mov (%eax),%edx +c0103681: 8b 45 d8 mov -0x28(%ebp),%eax +c0103684: 89 50 04 mov %edx,0x4(%eax) + elm->next = next; +c0103687: 8b 45 dc mov -0x24(%ebp),%eax +c010368a: 8b 55 d4 mov -0x2c(%ebp),%edx +c010368d: 89 50 04 mov %edx,0x4(%eax) + elm->prev = prev; +c0103690: 8b 45 dc mov -0x24(%ebp),%eax +c0103693: 8b 55 d8 mov -0x28(%ebp),%edx +c0103696: 89 10 mov %edx,(%eax) +} +c0103698: 90 nop +} +c0103699: 90 nop +} +c010369a: 90 nop +c010369b: 89 ec mov %ebp,%esp +c010369d: 5d pop %ebp +c010369e: c3 ret + +c010369f : + +//用于分配指定数量的连续物理页。该函数实现了首次适应内存分配算法。 +static struct Page * +default_alloc_pages(size_t n) { +c010369f: 55 push %ebp +c01036a0: 89 e5 mov %esp,%ebp +c01036a2: 83 ec 68 sub $0x68,%esp + assert(n > 0);// 确保请求的页数大于零 +c01036a5: 83 7d 08 00 cmpl $0x0,0x8(%ebp) +c01036a9: 75 24 jne c01036cf +c01036ab: c7 44 24 0c 30 c9 10 movl $0xc010c930,0xc(%esp) +c01036b2: c0 +c01036b3: c7 44 24 08 36 c9 10 movl $0xc010c936,0x8(%esp) +c01036ba: c0 +c01036bb: c7 44 24 04 ac 00 00 movl $0xac,0x4(%esp) +c01036c2: 00 +c01036c3: c7 04 24 4b c9 10 c0 movl $0xc010c94b,(%esp) +c01036ca: e8 6c d6 ff ff call c0100d3b <__panic> + if (n > nr_free) {// 检查请求的页数是否超过空闲页数 +c01036cf: a1 8c 3f 1a c0 mov 0xc01a3f8c,%eax +c01036d4: 39 45 08 cmp %eax,0x8(%ebp) +c01036d7: 76 0a jbe c01036e3 + return NULL; +c01036d9: b8 00 00 00 00 mov $0x0,%eax +c01036de: e9 3c 01 00 00 jmp c010381f + } + struct Page *page = NULL;// 初始化分配的页指针 +c01036e3: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + list_entry_t *le = &free_list;// 初始化链表迭代器 +c01036ea: c7 45 f0 84 3f 1a c0 movl $0xc01a3f84,-0x10(%ebp) + // 遍历空闲列表,寻找第一个满足条件的块 + while ((le = list_next(le)) != &free_list) { +c01036f1: eb 1c jmp c010370f + struct Page *p = le2page(le, page_link);// 将链表节点转换为 Page 结构体 +c01036f3: 8b 45 f0 mov -0x10(%ebp),%eax +c01036f6: 83 e8 0c sub $0xc,%eax +c01036f9: 89 45 ec mov %eax,-0x14(%ebp) + if (p->property >= n) {// 检查当前块的页数是否满足请求 +c01036fc: 8b 45 ec mov -0x14(%ebp),%eax +c01036ff: 8b 40 08 mov 0x8(%eax),%eax +c0103702: 39 45 08 cmp %eax,0x8(%ebp) +c0103705: 77 08 ja c010370f + page = p;// 找到合适的块 +c0103707: 8b 45 ec mov -0x14(%ebp),%eax +c010370a: 89 45 f4 mov %eax,-0xc(%ebp) + break;// 退出循环 +c010370d: eb 18 jmp c0103727 +c010370f: 8b 45 f0 mov -0x10(%ebp),%eax +c0103712: 89 45 e4 mov %eax,-0x1c(%ebp) + return listelm->next; +c0103715: 8b 45 e4 mov -0x1c(%ebp),%eax +c0103718: 8b 40 04 mov 0x4(%eax),%eax + while ((le = list_next(le)) != &free_list) { +c010371b: 89 45 f0 mov %eax,-0x10(%ebp) +c010371e: 81 7d f0 84 3f 1a c0 cmpl $0xc01a3f84,-0x10(%ebp) +c0103725: 75 cc jne c01036f3 + } + } + if (page != NULL) {// 如果找到合适的块 +c0103727: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c010372b: 0f 84 eb 00 00 00 je c010381c + //list_del(&(page->page_link));// 从空闲列表中删除该块 + if (page->property > n) { +c0103731: 8b 45 f4 mov -0xc(%ebp),%eax +c0103734: 8b 40 08 mov 0x8(%eax),%eax +c0103737: 39 45 08 cmp %eax,0x8(%ebp) +c010373a: 0f 83 88 00 00 00 jae c01037c8 + struct Page *p = page + n;// 指向剩余的页 +c0103740: 8b 45 08 mov 0x8(%ebp),%eax +c0103743: c1 e0 05 shl $0x5,%eax +c0103746: 89 c2 mov %eax,%edx +c0103748: 8b 45 f4 mov -0xc(%ebp),%eax +c010374b: 01 d0 add %edx,%eax +c010374d: 89 45 e8 mov %eax,-0x18(%ebp) + p->property = page->property - n;// 更新剩余块的页数 +c0103750: 8b 45 f4 mov -0xc(%ebp),%eax +c0103753: 8b 40 08 mov 0x8(%eax),%eax +c0103756: 2b 45 08 sub 0x8(%ebp),%eax +c0103759: 89 c2 mov %eax,%edx +c010375b: 8b 45 e8 mov -0x18(%ebp),%eax +c010375e: 89 50 08 mov %edx,0x8(%eax) + SetPageProperty(p); +c0103761: 8b 45 e8 mov -0x18(%ebp),%eax +c0103764: 83 c0 04 add $0x4,%eax +c0103767: c7 45 cc 01 00 00 00 movl $0x1,-0x34(%ebp) +c010376e: 89 45 c8 mov %eax,-0x38(%ebp) + asm volatile ("btsl %1, %0" :"=m" (*(volatile long *)addr) : "Ir" (nr)); +c0103771: 8b 45 c8 mov -0x38(%ebp),%eax +c0103774: 8b 55 cc mov -0x34(%ebp),%edx +c0103777: 0f ab 10 bts %edx,(%eax) +} +c010377a: 90 nop + list_add_after(&(page->page_link), &(p->page_link));// 将剩余块添加回空闲列表 +c010377b: 8b 45 e8 mov -0x18(%ebp),%eax +c010377e: 83 c0 0c add $0xc,%eax +c0103781: 8b 55 f4 mov -0xc(%ebp),%edx +c0103784: 83 c2 0c add $0xc,%edx +c0103787: 89 55 e0 mov %edx,-0x20(%ebp) +c010378a: 89 45 dc mov %eax,-0x24(%ebp) + __list_add(elm, listelm, listelm->next); +c010378d: 8b 45 e0 mov -0x20(%ebp),%eax +c0103790: 8b 40 04 mov 0x4(%eax),%eax +c0103793: 8b 55 dc mov -0x24(%ebp),%edx +c0103796: 89 55 d8 mov %edx,-0x28(%ebp) +c0103799: 8b 55 e0 mov -0x20(%ebp),%edx +c010379c: 89 55 d4 mov %edx,-0x2c(%ebp) +c010379f: 89 45 d0 mov %eax,-0x30(%ebp) + prev->next = next->prev = elm; +c01037a2: 8b 45 d0 mov -0x30(%ebp),%eax +c01037a5: 8b 55 d8 mov -0x28(%ebp),%edx +c01037a8: 89 10 mov %edx,(%eax) +c01037aa: 8b 45 d0 mov -0x30(%ebp),%eax +c01037ad: 8b 10 mov (%eax),%edx +c01037af: 8b 45 d4 mov -0x2c(%ebp),%eax +c01037b2: 89 50 04 mov %edx,0x4(%eax) + elm->next = next; +c01037b5: 8b 45 d8 mov -0x28(%ebp),%eax +c01037b8: 8b 55 d0 mov -0x30(%ebp),%edx +c01037bb: 89 50 04 mov %edx,0x4(%eax) + elm->prev = prev; +c01037be: 8b 45 d8 mov -0x28(%ebp),%eax +c01037c1: 8b 55 d4 mov -0x2c(%ebp),%edx +c01037c4: 89 10 mov %edx,(%eax) +} +c01037c6: 90 nop +} +c01037c7: 90 nop + } + list_del(&(page->page_link)); +c01037c8: 8b 45 f4 mov -0xc(%ebp),%eax +c01037cb: 83 c0 0c add $0xc,%eax +c01037ce: 89 45 bc mov %eax,-0x44(%ebp) + __list_del(listelm->prev, listelm->next); +c01037d1: 8b 45 bc mov -0x44(%ebp),%eax +c01037d4: 8b 40 04 mov 0x4(%eax),%eax +c01037d7: 8b 55 bc mov -0x44(%ebp),%edx +c01037da: 8b 12 mov (%edx),%edx +c01037dc: 89 55 b8 mov %edx,-0x48(%ebp) +c01037df: 89 45 b4 mov %eax,-0x4c(%ebp) + * This is only for internal list manipulation where we know + * the prev/next entries already! + * */ +static inline void +__list_del(list_entry_t *prev, list_entry_t *next) { + prev->next = next; +c01037e2: 8b 45 b8 mov -0x48(%ebp),%eax +c01037e5: 8b 55 b4 mov -0x4c(%ebp),%edx +c01037e8: 89 50 04 mov %edx,0x4(%eax) + next->prev = prev; +c01037eb: 8b 45 b4 mov -0x4c(%ebp),%eax +c01037ee: 8b 55 b8 mov -0x48(%ebp),%edx +c01037f1: 89 10 mov %edx,(%eax) +} +c01037f3: 90 nop +} +c01037f4: 90 nop + nr_free -= n;// 减少空闲页的计数 +c01037f5: a1 8c 3f 1a c0 mov 0xc01a3f8c,%eax +c01037fa: 2b 45 08 sub 0x8(%ebp),%eax +c01037fd: a3 8c 3f 1a c0 mov %eax,0xc01a3f8c + ClearPageProperty(page);// 清除已分配页的属性 +c0103802: 8b 45 f4 mov -0xc(%ebp),%eax +c0103805: 83 c0 04 add $0x4,%eax +c0103808: c7 45 c4 01 00 00 00 movl $0x1,-0x3c(%ebp) +c010380f: 89 45 c0 mov %eax,-0x40(%ebp) + asm volatile ("btrl %1, %0" :"=m" (*(volatile long *)addr) : "Ir" (nr)); +c0103812: 8b 45 c0 mov -0x40(%ebp),%eax +c0103815: 8b 55 c4 mov -0x3c(%ebp),%edx +c0103818: 0f b3 10 btr %edx,(%eax) +} +c010381b: 90 nop + } + return page;// 返回分配的页块 +c010381c: 8b 45 f4 mov -0xc(%ebp),%eax +} +c010381f: 89 ec mov %ebp,%esp +c0103821: 5d pop %ebp +c0103822: c3 ret + +c0103823 : + +static void +default_free_pages(struct Page *base, size_t n) { +c0103823: 55 push %ebp +c0103824: 89 e5 mov %esp,%ebp +c0103826: 81 ec 98 00 00 00 sub $0x98,%esp + assert(n > 0);// 确保请求释放的页数大于零 +c010382c: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) +c0103830: 75 24 jne c0103856 +c0103832: c7 44 24 0c 30 c9 10 movl $0xc010c930,0xc(%esp) +c0103839: c0 +c010383a: c7 44 24 08 36 c9 10 movl $0xc010c936,0x8(%esp) +c0103841: c0 +c0103842: c7 44 24 04 cb 00 00 movl $0xcb,0x4(%esp) +c0103849: 00 +c010384a: c7 04 24 4b c9 10 c0 movl $0xc010c94b,(%esp) +c0103851: e8 e5 d4 ff ff call c0100d3b <__panic> + struct Page *p = base; +c0103856: 8b 45 08 mov 0x8(%ebp),%eax +c0103859: 89 45 f4 mov %eax,-0xc(%ebp) + // 遍历释放的页,检查状态并重置 + for (; p != base + n; p ++) { +c010385c: e9 9d 00 00 00 jmp c01038fe + assert(!PageReserved(p) && !PageProperty(p));// 确保页没有被保留并且没有属性 +c0103861: 8b 45 f4 mov -0xc(%ebp),%eax +c0103864: 83 c0 04 add $0x4,%eax +c0103867: c7 45 ec 00 00 00 00 movl $0x0,-0x14(%ebp) +c010386e: 89 45 e8 mov %eax,-0x18(%ebp) + asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr)); +c0103871: 8b 45 e8 mov -0x18(%ebp),%eax +c0103874: 8b 55 ec mov -0x14(%ebp),%edx +c0103877: 0f a3 10 bt %edx,(%eax) +c010387a: 19 c0 sbb %eax,%eax +c010387c: 89 45 e4 mov %eax,-0x1c(%ebp) + return oldbit != 0; +c010387f: 83 7d e4 00 cmpl $0x0,-0x1c(%ebp) +c0103883: 0f 95 c0 setne %al +c0103886: 0f b6 c0 movzbl %al,%eax +c0103889: 85 c0 test %eax,%eax +c010388b: 75 2c jne c01038b9 +c010388d: 8b 45 f4 mov -0xc(%ebp),%eax +c0103890: 83 c0 04 add $0x4,%eax +c0103893: c7 45 e0 01 00 00 00 movl $0x1,-0x20(%ebp) +c010389a: 89 45 dc mov %eax,-0x24(%ebp) + asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr)); +c010389d: 8b 45 dc mov -0x24(%ebp),%eax +c01038a0: 8b 55 e0 mov -0x20(%ebp),%edx +c01038a3: 0f a3 10 bt %edx,(%eax) +c01038a6: 19 c0 sbb %eax,%eax +c01038a8: 89 45 d8 mov %eax,-0x28(%ebp) + return oldbit != 0; +c01038ab: 83 7d d8 00 cmpl $0x0,-0x28(%ebp) +c01038af: 0f 95 c0 setne %al +c01038b2: 0f b6 c0 movzbl %al,%eax +c01038b5: 85 c0 test %eax,%eax +c01038b7: 74 24 je c01038dd +c01038b9: c7 44 24 0c 74 c9 10 movl $0xc010c974,0xc(%esp) +c01038c0: c0 +c01038c1: c7 44 24 08 36 c9 10 movl $0xc010c936,0x8(%esp) +c01038c8: c0 +c01038c9: c7 44 24 04 cf 00 00 movl $0xcf,0x4(%esp) +c01038d0: 00 +c01038d1: c7 04 24 4b c9 10 c0 movl $0xc010c94b,(%esp) +c01038d8: e8 5e d4 ff ff call c0100d3b <__panic> + p->flags = 0;// 清除 flags 字段 +c01038dd: 8b 45 f4 mov -0xc(%ebp),%eax +c01038e0: c7 40 04 00 00 00 00 movl $0x0,0x4(%eax) + set_page_ref(p, 0);// 清除引用计数 +c01038e7: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) +c01038ee: 00 +c01038ef: 8b 45 f4 mov -0xc(%ebp),%eax +c01038f2: 89 04 24 mov %eax,(%esp) +c01038f5: e8 19 fc ff ff call c0103513 + for (; p != base + n; p ++) { +c01038fa: 83 45 f4 20 addl $0x20,-0xc(%ebp) +c01038fe: 8b 45 0c mov 0xc(%ebp),%eax +c0103901: c1 e0 05 shl $0x5,%eax +c0103904: 89 c2 mov %eax,%edx +c0103906: 8b 45 08 mov 0x8(%ebp),%eax +c0103909: 01 d0 add %edx,%eax +c010390b: 39 45 f4 cmp %eax,-0xc(%ebp) +c010390e: 0f 85 4d ff ff ff jne c0103861 + } + // 设置基页的属性为释放的页数 + base->property = n; +c0103914: 8b 45 08 mov 0x8(%ebp),%eax +c0103917: 8b 55 0c mov 0xc(%ebp),%edx +c010391a: 89 50 08 mov %edx,0x8(%eax) + SetPageProperty(base);// 设置页的有效标志 +c010391d: 8b 45 08 mov 0x8(%ebp),%eax +c0103920: 83 c0 04 add $0x4,%eax +c0103923: c7 45 d0 01 00 00 00 movl $0x1,-0x30(%ebp) +c010392a: 89 45 cc mov %eax,-0x34(%ebp) + asm volatile ("btsl %1, %0" :"=m" (*(volatile long *)addr) : "Ir" (nr)); +c010392d: 8b 45 cc mov -0x34(%ebp),%eax +c0103930: 8b 55 d0 mov -0x30(%ebp),%edx +c0103933: 0f ab 10 bts %edx,(%eax) +} +c0103936: 90 nop +c0103937: c7 45 d4 84 3f 1a c0 movl $0xc01a3f84,-0x2c(%ebp) + return listelm->next; +c010393e: 8b 45 d4 mov -0x2c(%ebp),%eax +c0103941: 8b 40 04 mov 0x4(%eax),%eax + // 遍历空闲列表,检查是否需要合并 + list_entry_t *le = list_next(&free_list); +c0103944: 89 45 f0 mov %eax,-0x10(%ebp) + while (le != &free_list) { +c0103947: e9 00 01 00 00 jmp c0103a4c + p = le2page(le, page_link); +c010394c: 8b 45 f0 mov -0x10(%ebp),%eax +c010394f: 83 e8 0c sub $0xc,%eax +c0103952: 89 45 f4 mov %eax,-0xc(%ebp) +c0103955: 8b 45 f0 mov -0x10(%ebp),%eax +c0103958: 89 45 c8 mov %eax,-0x38(%ebp) +c010395b: 8b 45 c8 mov -0x38(%ebp),%eax +c010395e: 8b 40 04 mov 0x4(%eax),%eax + le = list_next(le); +c0103961: 89 45 f0 mov %eax,-0x10(%ebp) + // 如果当前页块与释放的页块相邻,合并 + if (base + base->property == p) { +c0103964: 8b 45 08 mov 0x8(%ebp),%eax +c0103967: 8b 40 08 mov 0x8(%eax),%eax +c010396a: c1 e0 05 shl $0x5,%eax +c010396d: 89 c2 mov %eax,%edx +c010396f: 8b 45 08 mov 0x8(%ebp),%eax +c0103972: 01 d0 add %edx,%eax +c0103974: 39 45 f4 cmp %eax,-0xc(%ebp) +c0103977: 75 5d jne c01039d6 + base->property += p->property;// 合并当前页块 +c0103979: 8b 45 08 mov 0x8(%ebp),%eax +c010397c: 8b 50 08 mov 0x8(%eax),%edx +c010397f: 8b 45 f4 mov -0xc(%ebp),%eax +c0103982: 8b 40 08 mov 0x8(%eax),%eax +c0103985: 01 c2 add %eax,%edx +c0103987: 8b 45 08 mov 0x8(%ebp),%eax +c010398a: 89 50 08 mov %edx,0x8(%eax) + ClearPageProperty(p);// 清除合并页的属性 +c010398d: 8b 45 f4 mov -0xc(%ebp),%eax +c0103990: 83 c0 04 add $0x4,%eax +c0103993: c7 45 b8 01 00 00 00 movl $0x1,-0x48(%ebp) +c010399a: 89 45 b4 mov %eax,-0x4c(%ebp) + asm volatile ("btrl %1, %0" :"=m" (*(volatile long *)addr) : "Ir" (nr)); +c010399d: 8b 45 b4 mov -0x4c(%ebp),%eax +c01039a0: 8b 55 b8 mov -0x48(%ebp),%edx +c01039a3: 0f b3 10 btr %edx,(%eax) +} +c01039a6: 90 nop + list_del(&(p->page_link));// 从空闲列表中删除合并页 +c01039a7: 8b 45 f4 mov -0xc(%ebp),%eax +c01039aa: 83 c0 0c add $0xc,%eax +c01039ad: 89 45 c4 mov %eax,-0x3c(%ebp) + __list_del(listelm->prev, listelm->next); +c01039b0: 8b 45 c4 mov -0x3c(%ebp),%eax +c01039b3: 8b 40 04 mov 0x4(%eax),%eax +c01039b6: 8b 55 c4 mov -0x3c(%ebp),%edx +c01039b9: 8b 12 mov (%edx),%edx +c01039bb: 89 55 c0 mov %edx,-0x40(%ebp) +c01039be: 89 45 bc mov %eax,-0x44(%ebp) + prev->next = next; +c01039c1: 8b 45 c0 mov -0x40(%ebp),%eax +c01039c4: 8b 55 bc mov -0x44(%ebp),%edx +c01039c7: 89 50 04 mov %edx,0x4(%eax) + next->prev = prev; +c01039ca: 8b 45 bc mov -0x44(%ebp),%eax +c01039cd: 8b 55 c0 mov -0x40(%ebp),%edx +c01039d0: 89 10 mov %edx,(%eax) +} +c01039d2: 90 nop +} +c01039d3: 90 nop +c01039d4: eb 76 jmp c0103a4c + } + else if (p + p->property == base) { +c01039d6: 8b 45 f4 mov -0xc(%ebp),%eax +c01039d9: 8b 40 08 mov 0x8(%eax),%eax +c01039dc: c1 e0 05 shl $0x5,%eax +c01039df: 89 c2 mov %eax,%edx +c01039e1: 8b 45 f4 mov -0xc(%ebp),%eax +c01039e4: 01 d0 add %edx,%eax +c01039e6: 39 45 08 cmp %eax,0x8(%ebp) +c01039e9: 75 61 jne c0103a4c + p->property += base->property;// 合并前一个页块 +c01039eb: 8b 45 f4 mov -0xc(%ebp),%eax +c01039ee: 8b 50 08 mov 0x8(%eax),%edx +c01039f1: 8b 45 08 mov 0x8(%ebp),%eax +c01039f4: 8b 40 08 mov 0x8(%eax),%eax +c01039f7: 01 c2 add %eax,%edx +c01039f9: 8b 45 f4 mov -0xc(%ebp),%eax +c01039fc: 89 50 08 mov %edx,0x8(%eax) + ClearPageProperty(base);// 清除当前页的属性 +c01039ff: 8b 45 08 mov 0x8(%ebp),%eax +c0103a02: 83 c0 04 add $0x4,%eax +c0103a05: c7 45 a4 01 00 00 00 movl $0x1,-0x5c(%ebp) +c0103a0c: 89 45 a0 mov %eax,-0x60(%ebp) + asm volatile ("btrl %1, %0" :"=m" (*(volatile long *)addr) : "Ir" (nr)); +c0103a0f: 8b 45 a0 mov -0x60(%ebp),%eax +c0103a12: 8b 55 a4 mov -0x5c(%ebp),%edx +c0103a15: 0f b3 10 btr %edx,(%eax) +} +c0103a18: 90 nop + base = p;// 更新 base 指针 +c0103a19: 8b 45 f4 mov -0xc(%ebp),%eax +c0103a1c: 89 45 08 mov %eax,0x8(%ebp) + list_del(&(p->page_link));// 从空闲列表中删除当前页 +c0103a1f: 8b 45 f4 mov -0xc(%ebp),%eax +c0103a22: 83 c0 0c add $0xc,%eax +c0103a25: 89 45 b0 mov %eax,-0x50(%ebp) + __list_del(listelm->prev, listelm->next); +c0103a28: 8b 45 b0 mov -0x50(%ebp),%eax +c0103a2b: 8b 40 04 mov 0x4(%eax),%eax +c0103a2e: 8b 55 b0 mov -0x50(%ebp),%edx +c0103a31: 8b 12 mov (%edx),%edx +c0103a33: 89 55 ac mov %edx,-0x54(%ebp) +c0103a36: 89 45 a8 mov %eax,-0x58(%ebp) + prev->next = next; +c0103a39: 8b 45 ac mov -0x54(%ebp),%eax +c0103a3c: 8b 55 a8 mov -0x58(%ebp),%edx +c0103a3f: 89 50 04 mov %edx,0x4(%eax) + next->prev = prev; +c0103a42: 8b 45 a8 mov -0x58(%ebp),%eax +c0103a45: 8b 55 ac mov -0x54(%ebp),%edx +c0103a48: 89 10 mov %edx,(%eax) +} +c0103a4a: 90 nop +} +c0103a4b: 90 nop + while (le != &free_list) { +c0103a4c: 81 7d f0 84 3f 1a c0 cmpl $0xc01a3f84,-0x10(%ebp) +c0103a53: 0f 85 f3 fe ff ff jne c010394c + } + } + nr_free += n;// 更新空闲页的计数 +c0103a59: 8b 15 8c 3f 1a c0 mov 0xc01a3f8c,%edx +c0103a5f: 8b 45 0c mov 0xc(%ebp),%eax +c0103a62: 01 d0 add %edx,%eax +c0103a64: a3 8c 3f 1a c0 mov %eax,0xc01a3f8c +c0103a69: c7 45 9c 84 3f 1a c0 movl $0xc01a3f84,-0x64(%ebp) + return listelm->next; +c0103a70: 8b 45 9c mov -0x64(%ebp),%eax +c0103a73: 8b 40 04 mov 0x4(%eax),%eax + le = list_next(&free_list); +c0103a76: 89 45 f0 mov %eax,-0x10(%ebp) + while (le != &free_list) +c0103a79: eb 66 jmp c0103ae1 + { + p = le2page(le, page_link); +c0103a7b: 8b 45 f0 mov -0x10(%ebp),%eax +c0103a7e: 83 e8 0c sub $0xc,%eax +c0103a81: 89 45 f4 mov %eax,-0xc(%ebp) + if (base + base->property <= p) +c0103a84: 8b 45 08 mov 0x8(%ebp),%eax +c0103a87: 8b 40 08 mov 0x8(%eax),%eax +c0103a8a: c1 e0 05 shl $0x5,%eax +c0103a8d: 89 c2 mov %eax,%edx +c0103a8f: 8b 45 08 mov 0x8(%ebp),%eax +c0103a92: 01 d0 add %edx,%eax +c0103a94: 39 45 f4 cmp %eax,-0xc(%ebp) +c0103a97: 72 39 jb c0103ad2 + { + assert(base + base->property != p); +c0103a99: 8b 45 08 mov 0x8(%ebp),%eax +c0103a9c: 8b 40 08 mov 0x8(%eax),%eax +c0103a9f: c1 e0 05 shl $0x5,%eax +c0103aa2: 89 c2 mov %eax,%edx +c0103aa4: 8b 45 08 mov 0x8(%ebp),%eax +c0103aa7: 01 d0 add %edx,%eax +c0103aa9: 39 45 f4 cmp %eax,-0xc(%ebp) +c0103aac: 75 3e jne c0103aec +c0103aae: c7 44 24 0c 99 c9 10 movl $0xc010c999,0xc(%esp) +c0103ab5: c0 +c0103ab6: c7 44 24 08 36 c9 10 movl $0xc010c936,0x8(%esp) +c0103abd: c0 +c0103abe: c7 44 24 04 ef 00 00 movl $0xef,0x4(%esp) +c0103ac5: 00 +c0103ac6: c7 04 24 4b c9 10 c0 movl $0xc010c94b,(%esp) +c0103acd: e8 69 d2 ff ff call c0100d3b <__panic> +c0103ad2: 8b 45 f0 mov -0x10(%ebp),%eax +c0103ad5: 89 45 98 mov %eax,-0x68(%ebp) +c0103ad8: 8b 45 98 mov -0x68(%ebp),%eax +c0103adb: 8b 40 04 mov 0x4(%eax),%eax + break; + } + le = list_next(le); +c0103ade: 89 45 f0 mov %eax,-0x10(%ebp) + while (le != &free_list) +c0103ae1: 81 7d f0 84 3f 1a c0 cmpl $0xc01a3f84,-0x10(%ebp) +c0103ae8: 75 91 jne c0103a7b +c0103aea: eb 01 jmp c0103aed + break; +c0103aec: 90 nop + } + + list_add_before(le, &(base->page_link));// 将释放的页块添加到空闲列表中 +c0103aed: 8b 45 08 mov 0x8(%ebp),%eax +c0103af0: 8d 50 0c lea 0xc(%eax),%edx +c0103af3: 8b 45 f0 mov -0x10(%ebp),%eax +c0103af6: 89 45 94 mov %eax,-0x6c(%ebp) +c0103af9: 89 55 90 mov %edx,-0x70(%ebp) + __list_add(elm, listelm->prev, listelm); +c0103afc: 8b 45 94 mov -0x6c(%ebp),%eax +c0103aff: 8b 00 mov (%eax),%eax +c0103b01: 8b 55 90 mov -0x70(%ebp),%edx +c0103b04: 89 55 8c mov %edx,-0x74(%ebp) +c0103b07: 89 45 88 mov %eax,-0x78(%ebp) +c0103b0a: 8b 45 94 mov -0x6c(%ebp),%eax +c0103b0d: 89 45 84 mov %eax,-0x7c(%ebp) + prev->next = next->prev = elm; +c0103b10: 8b 45 84 mov -0x7c(%ebp),%eax +c0103b13: 8b 55 8c mov -0x74(%ebp),%edx +c0103b16: 89 10 mov %edx,(%eax) +c0103b18: 8b 45 84 mov -0x7c(%ebp),%eax +c0103b1b: 8b 10 mov (%eax),%edx +c0103b1d: 8b 45 88 mov -0x78(%ebp),%eax +c0103b20: 89 50 04 mov %edx,0x4(%eax) + elm->next = next; +c0103b23: 8b 45 8c mov -0x74(%ebp),%eax +c0103b26: 8b 55 84 mov -0x7c(%ebp),%edx +c0103b29: 89 50 04 mov %edx,0x4(%eax) + elm->prev = prev; +c0103b2c: 8b 45 8c mov -0x74(%ebp),%eax +c0103b2f: 8b 55 88 mov -0x78(%ebp),%edx +c0103b32: 89 10 mov %edx,(%eax) +} +c0103b34: 90 nop +} +c0103b35: 90 nop +} +c0103b36: 90 nop +c0103b37: 89 ec mov %ebp,%esp +c0103b39: 5d pop %ebp +c0103b3a: c3 ret + +c0103b3b : + +//用于返回当前系统中可用的空闲页的数量。 +static size_t +default_nr_free_pages(void) { +c0103b3b: 55 push %ebp +c0103b3c: 89 e5 mov %esp,%ebp + return nr_free;// 返回当前空闲页的数量 +c0103b3e: a1 8c 3f 1a c0 mov 0xc01a3f8c,%eax +} +c0103b43: 5d pop %ebp +c0103b44: c3 ret + +c0103b45 : + +//basic_check 函数用于测试内存分配和释放的基本功能, +//确保在不同情况下内存管理系统的正确性,包括分配、释放、合并和引用计数等操作。 +static void +basic_check(void) { +c0103b45: 55 push %ebp +c0103b46: 89 e5 mov %esp,%ebp +c0103b48: 83 ec 48 sub $0x48,%esp + struct Page *p0, *p1, *p2; + p0 = p1 = p2 = NULL; +c0103b4b: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) +c0103b52: 8b 45 f4 mov -0xc(%ebp),%eax +c0103b55: 89 45 f0 mov %eax,-0x10(%ebp) +c0103b58: 8b 45 f0 mov -0x10(%ebp),%eax +c0103b5b: 89 45 ec mov %eax,-0x14(%ebp) + // 分配三个页面 + assert((p0 = alloc_page()) != NULL); +c0103b5e: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c0103b65: e8 17 16 00 00 call c0105181 +c0103b6a: 89 45 ec mov %eax,-0x14(%ebp) +c0103b6d: 83 7d ec 00 cmpl $0x0,-0x14(%ebp) +c0103b71: 75 24 jne c0103b97 +c0103b73: c7 44 24 0c b4 c9 10 movl $0xc010c9b4,0xc(%esp) +c0103b7a: c0 +c0103b7b: c7 44 24 08 36 c9 10 movl $0xc010c936,0x8(%esp) +c0103b82: c0 +c0103b83: c7 44 24 04 05 01 00 movl $0x105,0x4(%esp) +c0103b8a: 00 +c0103b8b: c7 04 24 4b c9 10 c0 movl $0xc010c94b,(%esp) +c0103b92: e8 a4 d1 ff ff call c0100d3b <__panic> + assert((p1 = alloc_page()) != NULL); +c0103b97: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c0103b9e: e8 de 15 00 00 call c0105181 +c0103ba3: 89 45 f0 mov %eax,-0x10(%ebp) +c0103ba6: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) +c0103baa: 75 24 jne c0103bd0 +c0103bac: c7 44 24 0c d0 c9 10 movl $0xc010c9d0,0xc(%esp) +c0103bb3: c0 +c0103bb4: c7 44 24 08 36 c9 10 movl $0xc010c936,0x8(%esp) +c0103bbb: c0 +c0103bbc: c7 44 24 04 06 01 00 movl $0x106,0x4(%esp) +c0103bc3: 00 +c0103bc4: c7 04 24 4b c9 10 c0 movl $0xc010c94b,(%esp) +c0103bcb: e8 6b d1 ff ff call c0100d3b <__panic> + assert((p2 = alloc_page()) != NULL); +c0103bd0: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c0103bd7: e8 a5 15 00 00 call c0105181 +c0103bdc: 89 45 f4 mov %eax,-0xc(%ebp) +c0103bdf: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c0103be3: 75 24 jne c0103c09 +c0103be5: c7 44 24 0c ec c9 10 movl $0xc010c9ec,0xc(%esp) +c0103bec: c0 +c0103bed: c7 44 24 08 36 c9 10 movl $0xc010c936,0x8(%esp) +c0103bf4: c0 +c0103bf5: c7 44 24 04 07 01 00 movl $0x107,0x4(%esp) +c0103bfc: 00 +c0103bfd: c7 04 24 4b c9 10 c0 movl $0xc010c94b,(%esp) +c0103c04: e8 32 d1 ff ff call c0100d3b <__panic> + // 确保所有分配的页面是不同的 + assert(p0 != p1 && p0 != p2 && p1 != p2); +c0103c09: 8b 45 ec mov -0x14(%ebp),%eax +c0103c0c: 3b 45 f0 cmp -0x10(%ebp),%eax +c0103c0f: 74 10 je c0103c21 +c0103c11: 8b 45 ec mov -0x14(%ebp),%eax +c0103c14: 3b 45 f4 cmp -0xc(%ebp),%eax +c0103c17: 74 08 je c0103c21 +c0103c19: 8b 45 f0 mov -0x10(%ebp),%eax +c0103c1c: 3b 45 f4 cmp -0xc(%ebp),%eax +c0103c1f: 75 24 jne c0103c45 +c0103c21: c7 44 24 0c 08 ca 10 movl $0xc010ca08,0xc(%esp) +c0103c28: c0 +c0103c29: c7 44 24 08 36 c9 10 movl $0xc010c936,0x8(%esp) +c0103c30: c0 +c0103c31: c7 44 24 04 09 01 00 movl $0x109,0x4(%esp) +c0103c38: 00 +c0103c39: c7 04 24 4b c9 10 c0 movl $0xc010c94b,(%esp) +c0103c40: e8 f6 d0 ff ff call c0100d3b <__panic> + // 确保页面的引用计数为 0 + assert(page_ref(p0) == 0 && page_ref(p1) == 0 && page_ref(p2) == 0); +c0103c45: 8b 45 ec mov -0x14(%ebp),%eax +c0103c48: 89 04 24 mov %eax,(%esp) +c0103c4b: e8 b9 f8 ff ff call c0103509 +c0103c50: 85 c0 test %eax,%eax +c0103c52: 75 1e jne c0103c72 +c0103c54: 8b 45 f0 mov -0x10(%ebp),%eax +c0103c57: 89 04 24 mov %eax,(%esp) +c0103c5a: e8 aa f8 ff ff call c0103509 +c0103c5f: 85 c0 test %eax,%eax +c0103c61: 75 0f jne c0103c72 +c0103c63: 8b 45 f4 mov -0xc(%ebp),%eax +c0103c66: 89 04 24 mov %eax,(%esp) +c0103c69: e8 9b f8 ff ff call c0103509 +c0103c6e: 85 c0 test %eax,%eax +c0103c70: 74 24 je c0103c96 +c0103c72: c7 44 24 0c 2c ca 10 movl $0xc010ca2c,0xc(%esp) +c0103c79: c0 +c0103c7a: c7 44 24 08 36 c9 10 movl $0xc010c936,0x8(%esp) +c0103c81: c0 +c0103c82: c7 44 24 04 0b 01 00 movl $0x10b,0x4(%esp) +c0103c89: 00 +c0103c8a: c7 04 24 4b c9 10 c0 movl $0xc010c94b,(%esp) +c0103c91: e8 a5 d0 ff ff call c0100d3b <__panic> + // 确保页面地址在合法范围内 + assert(page2pa(p0) < npage * PGSIZE); +c0103c96: 8b 45 ec mov -0x14(%ebp),%eax +c0103c99: 89 04 24 mov %eax,(%esp) +c0103c9c: e8 50 f8 ff ff call c01034f1 +c0103ca1: 8b 15 a4 3f 1a c0 mov 0xc01a3fa4,%edx +c0103ca7: c1 e2 0c shl $0xc,%edx +c0103caa: 39 d0 cmp %edx,%eax +c0103cac: 72 24 jb c0103cd2 +c0103cae: c7 44 24 0c 68 ca 10 movl $0xc010ca68,0xc(%esp) +c0103cb5: c0 +c0103cb6: c7 44 24 08 36 c9 10 movl $0xc010c936,0x8(%esp) +c0103cbd: c0 +c0103cbe: c7 44 24 04 0d 01 00 movl $0x10d,0x4(%esp) +c0103cc5: 00 +c0103cc6: c7 04 24 4b c9 10 c0 movl $0xc010c94b,(%esp) +c0103ccd: e8 69 d0 ff ff call c0100d3b <__panic> + assert(page2pa(p1) < npage * PGSIZE); +c0103cd2: 8b 45 f0 mov -0x10(%ebp),%eax +c0103cd5: 89 04 24 mov %eax,(%esp) +c0103cd8: e8 14 f8 ff ff call c01034f1 +c0103cdd: 8b 15 a4 3f 1a c0 mov 0xc01a3fa4,%edx +c0103ce3: c1 e2 0c shl $0xc,%edx +c0103ce6: 39 d0 cmp %edx,%eax +c0103ce8: 72 24 jb c0103d0e +c0103cea: c7 44 24 0c 85 ca 10 movl $0xc010ca85,0xc(%esp) +c0103cf1: c0 +c0103cf2: c7 44 24 08 36 c9 10 movl $0xc010c936,0x8(%esp) +c0103cf9: c0 +c0103cfa: c7 44 24 04 0e 01 00 movl $0x10e,0x4(%esp) +c0103d01: 00 +c0103d02: c7 04 24 4b c9 10 c0 movl $0xc010c94b,(%esp) +c0103d09: e8 2d d0 ff ff call c0100d3b <__panic> + assert(page2pa(p2) < npage * PGSIZE); +c0103d0e: 8b 45 f4 mov -0xc(%ebp),%eax +c0103d11: 89 04 24 mov %eax,(%esp) +c0103d14: e8 d8 f7 ff ff call c01034f1 +c0103d19: 8b 15 a4 3f 1a c0 mov 0xc01a3fa4,%edx +c0103d1f: c1 e2 0c shl $0xc,%edx +c0103d22: 39 d0 cmp %edx,%eax +c0103d24: 72 24 jb c0103d4a +c0103d26: c7 44 24 0c a2 ca 10 movl $0xc010caa2,0xc(%esp) +c0103d2d: c0 +c0103d2e: c7 44 24 08 36 c9 10 movl $0xc010c936,0x8(%esp) +c0103d35: c0 +c0103d36: c7 44 24 04 0f 01 00 movl $0x10f,0x4(%esp) +c0103d3d: 00 +c0103d3e: c7 04 24 4b c9 10 c0 movl $0xc010c94b,(%esp) +c0103d45: e8 f1 cf ff ff call c0100d3b <__panic> + // 保存当前的空闲页面链表和数量 + list_entry_t free_list_store = free_list; +c0103d4a: a1 84 3f 1a c0 mov 0xc01a3f84,%eax +c0103d4f: 8b 15 88 3f 1a c0 mov 0xc01a3f88,%edx +c0103d55: 89 45 d0 mov %eax,-0x30(%ebp) +c0103d58: 89 55 d4 mov %edx,-0x2c(%ebp) +c0103d5b: c7 45 dc 84 3f 1a c0 movl $0xc01a3f84,-0x24(%ebp) + elm->prev = elm->next = elm; +c0103d62: 8b 45 dc mov -0x24(%ebp),%eax +c0103d65: 8b 55 dc mov -0x24(%ebp),%edx +c0103d68: 89 50 04 mov %edx,0x4(%eax) +c0103d6b: 8b 45 dc mov -0x24(%ebp),%eax +c0103d6e: 8b 50 04 mov 0x4(%eax),%edx +c0103d71: 8b 45 dc mov -0x24(%ebp),%eax +c0103d74: 89 10 mov %edx,(%eax) +} +c0103d76: 90 nop +c0103d77: c7 45 e0 84 3f 1a c0 movl $0xc01a3f84,-0x20(%ebp) + return list->next == list; +c0103d7e: 8b 45 e0 mov -0x20(%ebp),%eax +c0103d81: 8b 40 04 mov 0x4(%eax),%eax +c0103d84: 39 45 e0 cmp %eax,-0x20(%ebp) +c0103d87: 0f 94 c0 sete %al +c0103d8a: 0f b6 c0 movzbl %al,%eax + list_init(&free_list);// 初始化空闲列表 + assert(list_empty(&free_list));// 确保空闲列表为空 +c0103d8d: 85 c0 test %eax,%eax +c0103d8f: 75 24 jne c0103db5 +c0103d91: c7 44 24 0c bf ca 10 movl $0xc010cabf,0xc(%esp) +c0103d98: c0 +c0103d99: c7 44 24 08 36 c9 10 movl $0xc010c936,0x8(%esp) +c0103da0: c0 +c0103da1: c7 44 24 04 13 01 00 movl $0x113,0x4(%esp) +c0103da8: 00 +c0103da9: c7 04 24 4b c9 10 c0 movl $0xc010c94b,(%esp) +c0103db0: e8 86 cf ff ff call c0100d3b <__panic> + + unsigned int nr_free_store = nr_free;// 保存当前空闲页数量 +c0103db5: a1 8c 3f 1a c0 mov 0xc01a3f8c,%eax +c0103dba: 89 45 e8 mov %eax,-0x18(%ebp) + nr_free = 0;// 将空闲页数量设为 0 +c0103dbd: c7 05 8c 3f 1a c0 00 movl $0x0,0xc01a3f8c +c0103dc4: 00 00 00 + // 请求分配页面,但当前没有空闲页面 + assert(alloc_page() == NULL); +c0103dc7: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c0103dce: e8 ae 13 00 00 call c0105181 +c0103dd3: 85 c0 test %eax,%eax +c0103dd5: 74 24 je c0103dfb +c0103dd7: c7 44 24 0c d6 ca 10 movl $0xc010cad6,0xc(%esp) +c0103dde: c0 +c0103ddf: c7 44 24 08 36 c9 10 movl $0xc010c936,0x8(%esp) +c0103de6: c0 +c0103de7: c7 44 24 04 18 01 00 movl $0x118,0x4(%esp) +c0103dee: 00 +c0103def: c7 04 24 4b c9 10 c0 movl $0xc010c94b,(%esp) +c0103df6: e8 40 cf ff ff call c0100d3b <__panic> + // 释放之前分配的页面 + free_page(p0); +c0103dfb: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c0103e02: 00 +c0103e03: 8b 45 ec mov -0x14(%ebp),%eax +c0103e06: 89 04 24 mov %eax,(%esp) +c0103e09: e8 e0 13 00 00 call c01051ee + free_page(p1); +c0103e0e: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c0103e15: 00 +c0103e16: 8b 45 f0 mov -0x10(%ebp),%eax +c0103e19: 89 04 24 mov %eax,(%esp) +c0103e1c: e8 cd 13 00 00 call c01051ee + free_page(p2); +c0103e21: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c0103e28: 00 +c0103e29: 8b 45 f4 mov -0xc(%ebp),%eax +c0103e2c: 89 04 24 mov %eax,(%esp) +c0103e2f: e8 ba 13 00 00 call c01051ee + assert(nr_free == 3);// 确保释放后空闲页数量为 3 +c0103e34: a1 8c 3f 1a c0 mov 0xc01a3f8c,%eax +c0103e39: 83 f8 03 cmp $0x3,%eax +c0103e3c: 74 24 je c0103e62 +c0103e3e: c7 44 24 0c eb ca 10 movl $0xc010caeb,0xc(%esp) +c0103e45: c0 +c0103e46: c7 44 24 08 36 c9 10 movl $0xc010c936,0x8(%esp) +c0103e4d: c0 +c0103e4e: c7 44 24 04 1d 01 00 movl $0x11d,0x4(%esp) +c0103e55: 00 +c0103e56: c7 04 24 4b c9 10 c0 movl $0xc010c94b,(%esp) +c0103e5d: e8 d9 ce ff ff call c0100d3b <__panic> + // 再次分配三个页面 + assert((p0 = alloc_page()) != NULL); +c0103e62: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c0103e69: e8 13 13 00 00 call c0105181 +c0103e6e: 89 45 ec mov %eax,-0x14(%ebp) +c0103e71: 83 7d ec 00 cmpl $0x0,-0x14(%ebp) +c0103e75: 75 24 jne c0103e9b +c0103e77: c7 44 24 0c b4 c9 10 movl $0xc010c9b4,0xc(%esp) +c0103e7e: c0 +c0103e7f: c7 44 24 08 36 c9 10 movl $0xc010c936,0x8(%esp) +c0103e86: c0 +c0103e87: c7 44 24 04 1f 01 00 movl $0x11f,0x4(%esp) +c0103e8e: 00 +c0103e8f: c7 04 24 4b c9 10 c0 movl $0xc010c94b,(%esp) +c0103e96: e8 a0 ce ff ff call c0100d3b <__panic> + assert((p1 = alloc_page()) != NULL); +c0103e9b: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c0103ea2: e8 da 12 00 00 call c0105181 +c0103ea7: 89 45 f0 mov %eax,-0x10(%ebp) +c0103eaa: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) +c0103eae: 75 24 jne c0103ed4 +c0103eb0: c7 44 24 0c d0 c9 10 movl $0xc010c9d0,0xc(%esp) +c0103eb7: c0 +c0103eb8: c7 44 24 08 36 c9 10 movl $0xc010c936,0x8(%esp) +c0103ebf: c0 +c0103ec0: c7 44 24 04 20 01 00 movl $0x120,0x4(%esp) +c0103ec7: 00 +c0103ec8: c7 04 24 4b c9 10 c0 movl $0xc010c94b,(%esp) +c0103ecf: e8 67 ce ff ff call c0100d3b <__panic> + assert((p2 = alloc_page()) != NULL); +c0103ed4: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c0103edb: e8 a1 12 00 00 call c0105181 +c0103ee0: 89 45 f4 mov %eax,-0xc(%ebp) +c0103ee3: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c0103ee7: 75 24 jne c0103f0d +c0103ee9: c7 44 24 0c ec c9 10 movl $0xc010c9ec,0xc(%esp) +c0103ef0: c0 +c0103ef1: c7 44 24 08 36 c9 10 movl $0xc010c936,0x8(%esp) +c0103ef8: c0 +c0103ef9: c7 44 24 04 21 01 00 movl $0x121,0x4(%esp) +c0103f00: 00 +c0103f01: c7 04 24 4b c9 10 c0 movl $0xc010c94b,(%esp) +c0103f08: e8 2e ce ff ff call c0100d3b <__panic> + // 测试空闲页面是否不足 + assert(alloc_page() == NULL); +c0103f0d: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c0103f14: e8 68 12 00 00 call c0105181 +c0103f19: 85 c0 test %eax,%eax +c0103f1b: 74 24 je c0103f41 +c0103f1d: c7 44 24 0c d6 ca 10 movl $0xc010cad6,0xc(%esp) +c0103f24: c0 +c0103f25: c7 44 24 08 36 c9 10 movl $0xc010c936,0x8(%esp) +c0103f2c: c0 +c0103f2d: c7 44 24 04 23 01 00 movl $0x123,0x4(%esp) +c0103f34: 00 +c0103f35: c7 04 24 4b c9 10 c0 movl $0xc010c94b,(%esp) +c0103f3c: e8 fa cd ff ff call c0100d3b <__panic> + // 释放 p0,并检查空闲列表 + free_page(p0); +c0103f41: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c0103f48: 00 +c0103f49: 8b 45 ec mov -0x14(%ebp),%eax +c0103f4c: 89 04 24 mov %eax,(%esp) +c0103f4f: e8 9a 12 00 00 call c01051ee +c0103f54: c7 45 d8 84 3f 1a c0 movl $0xc01a3f84,-0x28(%ebp) +c0103f5b: 8b 45 d8 mov -0x28(%ebp),%eax +c0103f5e: 8b 40 04 mov 0x4(%eax),%eax +c0103f61: 39 45 d8 cmp %eax,-0x28(%ebp) +c0103f64: 0f 94 c0 sete %al +c0103f67: 0f b6 c0 movzbl %al,%eax + assert(!list_empty(&free_list));// 确保空闲列表不为空 +c0103f6a: 85 c0 test %eax,%eax +c0103f6c: 74 24 je c0103f92 +c0103f6e: c7 44 24 0c f8 ca 10 movl $0xc010caf8,0xc(%esp) +c0103f75: c0 +c0103f76: c7 44 24 08 36 c9 10 movl $0xc010c936,0x8(%esp) +c0103f7d: c0 +c0103f7e: c7 44 24 04 26 01 00 movl $0x126,0x4(%esp) +c0103f85: 00 +c0103f86: c7 04 24 4b c9 10 c0 movl $0xc010c94b,(%esp) +c0103f8d: e8 a9 cd ff ff call c0100d3b <__panic> + + struct Page *p; + // 重新分配 p0,确保取回的是相同的页面 + assert((p = alloc_page()) == p0); +c0103f92: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c0103f99: e8 e3 11 00 00 call c0105181 +c0103f9e: 89 45 e4 mov %eax,-0x1c(%ebp) +c0103fa1: 8b 45 e4 mov -0x1c(%ebp),%eax +c0103fa4: 3b 45 ec cmp -0x14(%ebp),%eax +c0103fa7: 74 24 je c0103fcd +c0103fa9: c7 44 24 0c 10 cb 10 movl $0xc010cb10,0xc(%esp) +c0103fb0: c0 +c0103fb1: c7 44 24 08 36 c9 10 movl $0xc010c936,0x8(%esp) +c0103fb8: c0 +c0103fb9: c7 44 24 04 2a 01 00 movl $0x12a,0x4(%esp) +c0103fc0: 00 +c0103fc1: c7 04 24 4b c9 10 c0 movl $0xc010c94b,(%esp) +c0103fc8: e8 6e cd ff ff call c0100d3b <__panic> + assert(alloc_page() == NULL);// 确保没有更多的页面可分配 +c0103fcd: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c0103fd4: e8 a8 11 00 00 call c0105181 +c0103fd9: 85 c0 test %eax,%eax +c0103fdb: 74 24 je c0104001 +c0103fdd: c7 44 24 0c d6 ca 10 movl $0xc010cad6,0xc(%esp) +c0103fe4: c0 +c0103fe5: c7 44 24 08 36 c9 10 movl $0xc010c936,0x8(%esp) +c0103fec: c0 +c0103fed: c7 44 24 04 2b 01 00 movl $0x12b,0x4(%esp) +c0103ff4: 00 +c0103ff5: c7 04 24 4b c9 10 c0 movl $0xc010c94b,(%esp) +c0103ffc: e8 3a cd ff ff call c0100d3b <__panic> + + assert(nr_free == 0);// 确保当前空闲页面数量为 0 +c0104001: a1 8c 3f 1a c0 mov 0xc01a3f8c,%eax +c0104006: 85 c0 test %eax,%eax +c0104008: 74 24 je c010402e +c010400a: c7 44 24 0c 29 cb 10 movl $0xc010cb29,0xc(%esp) +c0104011: c0 +c0104012: c7 44 24 08 36 c9 10 movl $0xc010c936,0x8(%esp) +c0104019: c0 +c010401a: c7 44 24 04 2d 01 00 movl $0x12d,0x4(%esp) +c0104021: 00 +c0104022: c7 04 24 4b c9 10 c0 movl $0xc010c94b,(%esp) +c0104029: e8 0d cd ff ff call c0100d3b <__panic> + // 恢复之前的空闲页面链表和数量 + free_list = free_list_store; +c010402e: 8b 45 d0 mov -0x30(%ebp),%eax +c0104031: 8b 55 d4 mov -0x2c(%ebp),%edx +c0104034: a3 84 3f 1a c0 mov %eax,0xc01a3f84 +c0104039: 89 15 88 3f 1a c0 mov %edx,0xc01a3f88 + nr_free = nr_free_store; +c010403f: 8b 45 e8 mov -0x18(%ebp),%eax +c0104042: a3 8c 3f 1a c0 mov %eax,0xc01a3f8c + // 释放最后的页面 + free_page(p); +c0104047: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c010404e: 00 +c010404f: 8b 45 e4 mov -0x1c(%ebp),%eax +c0104052: 89 04 24 mov %eax,(%esp) +c0104055: e8 94 11 00 00 call c01051ee + free_page(p1); +c010405a: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c0104061: 00 +c0104062: 8b 45 f0 mov -0x10(%ebp),%eax +c0104065: 89 04 24 mov %eax,(%esp) +c0104068: e8 81 11 00 00 call c01051ee + free_page(p2); +c010406d: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c0104074: 00 +c0104075: 8b 45 f4 mov -0xc(%ebp),%eax +c0104078: 89 04 24 mov %eax,(%esp) +c010407b: e8 6e 11 00 00 call c01051ee +} +c0104080: 90 nop +c0104081: 89 ec mov %ebp,%esp +c0104083: 5d pop %ebp +c0104084: c3 ret + +c0104085 : + +// LAB2: below code is used to check the first fit allocation algorithm (your EXERCISE 1) +// NOTICE: You SHOULD NOT CHANGE basic_check, default_check functions! +static void +default_check(void) { +c0104085: 55 push %ebp +c0104086: 89 e5 mov %esp,%ebp +c0104088: 81 ec 98 00 00 00 sub $0x98,%esp + int count = 0, total = 0; +c010408e: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) +c0104095: c7 45 f0 00 00 00 00 movl $0x0,-0x10(%ebp) + list_entry_t *le = &free_list; +c010409c: c7 45 ec 84 3f 1a c0 movl $0xc01a3f84,-0x14(%ebp) + // 遍历空闲列表,计算空闲页面的数量和总属性值 + while ((le = list_next(le)) != &free_list) { +c01040a3: eb 6a jmp c010410f + struct Page *p = le2page(le, page_link); +c01040a5: 8b 45 ec mov -0x14(%ebp),%eax +c01040a8: 83 e8 0c sub $0xc,%eax +c01040ab: 89 45 d4 mov %eax,-0x2c(%ebp) + assert(PageProperty(p));// 确保每个页面的属性是有效的 +c01040ae: 8b 45 d4 mov -0x2c(%ebp),%eax +c01040b1: 83 c0 04 add $0x4,%eax +c01040b4: c7 45 d0 01 00 00 00 movl $0x1,-0x30(%ebp) +c01040bb: 89 45 cc mov %eax,-0x34(%ebp) + asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr)); +c01040be: 8b 45 cc mov -0x34(%ebp),%eax +c01040c1: 8b 55 d0 mov -0x30(%ebp),%edx +c01040c4: 0f a3 10 bt %edx,(%eax) +c01040c7: 19 c0 sbb %eax,%eax +c01040c9: 89 45 c8 mov %eax,-0x38(%ebp) + return oldbit != 0; +c01040cc: 83 7d c8 00 cmpl $0x0,-0x38(%ebp) +c01040d0: 0f 95 c0 setne %al +c01040d3: 0f b6 c0 movzbl %al,%eax +c01040d6: 85 c0 test %eax,%eax +c01040d8: 75 24 jne c01040fe +c01040da: c7 44 24 0c 36 cb 10 movl $0xc010cb36,0xc(%esp) +c01040e1: c0 +c01040e2: c7 44 24 08 36 c9 10 movl $0xc010c936,0x8(%esp) +c01040e9: c0 +c01040ea: c7 44 24 04 40 01 00 movl $0x140,0x4(%esp) +c01040f1: 00 +c01040f2: c7 04 24 4b c9 10 c0 movl $0xc010c94b,(%esp) +c01040f9: e8 3d cc ff ff call c0100d3b <__panic> + count ++, total += p->property;// 累加页面属性 +c01040fe: ff 45 f4 incl -0xc(%ebp) +c0104101: 8b 45 d4 mov -0x2c(%ebp),%eax +c0104104: 8b 50 08 mov 0x8(%eax),%edx +c0104107: 8b 45 f0 mov -0x10(%ebp),%eax +c010410a: 01 d0 add %edx,%eax +c010410c: 89 45 f0 mov %eax,-0x10(%ebp) +c010410f: 8b 45 ec mov -0x14(%ebp),%eax +c0104112: 89 45 c4 mov %eax,-0x3c(%ebp) + return listelm->next; +c0104115: 8b 45 c4 mov -0x3c(%ebp),%eax +c0104118: 8b 40 04 mov 0x4(%eax),%eax + while ((le = list_next(le)) != &free_list) { +c010411b: 89 45 ec mov %eax,-0x14(%ebp) +c010411e: 81 7d ec 84 3f 1a c0 cmpl $0xc01a3f84,-0x14(%ebp) +c0104125: 0f 85 7a ff ff ff jne c01040a5 + } + // 确保总属性值与空闲页面数量匹配 + assert(total == nr_free_pages()); +c010412b: e8 f3 10 00 00 call c0105223 +c0104130: 8b 55 f0 mov -0x10(%ebp),%edx +c0104133: 39 d0 cmp %edx,%eax +c0104135: 74 24 je c010415b +c0104137: c7 44 24 0c 46 cb 10 movl $0xc010cb46,0xc(%esp) +c010413e: c0 +c010413f: c7 44 24 08 36 c9 10 movl $0xc010c936,0x8(%esp) +c0104146: c0 +c0104147: c7 44 24 04 44 01 00 movl $0x144,0x4(%esp) +c010414e: 00 +c010414f: c7 04 24 4b c9 10 c0 movl $0xc010c94b,(%esp) +c0104156: e8 e0 cb ff ff call c0100d3b <__panic> + // 调用 basic_check 以验证基本的内存管理功能 + basic_check(); +c010415b: e8 e5 f9 ff ff call c0103b45 + // 分配 5 个页面 + struct Page *p0 = alloc_pages(5), *p1, *p2; +c0104160: c7 04 24 05 00 00 00 movl $0x5,(%esp) +c0104167: e8 15 10 00 00 call c0105181 +c010416c: 89 45 e8 mov %eax,-0x18(%ebp) + assert(p0 != NULL);// 确保成功分配 +c010416f: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) +c0104173: 75 24 jne c0104199 +c0104175: c7 44 24 0c 5f cb 10 movl $0xc010cb5f,0xc(%esp) +c010417c: c0 +c010417d: c7 44 24 08 36 c9 10 movl $0xc010c936,0x8(%esp) +c0104184: c0 +c0104185: c7 44 24 04 49 01 00 movl $0x149,0x4(%esp) +c010418c: 00 +c010418d: c7 04 24 4b c9 10 c0 movl $0xc010c94b,(%esp) +c0104194: e8 a2 cb ff ff call c0100d3b <__panic> + assert(!PageProperty(p0));// 确保分配的页面不带属性 +c0104199: 8b 45 e8 mov -0x18(%ebp),%eax +c010419c: 83 c0 04 add $0x4,%eax +c010419f: c7 45 c0 01 00 00 00 movl $0x1,-0x40(%ebp) +c01041a6: 89 45 bc mov %eax,-0x44(%ebp) + asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr)); +c01041a9: 8b 45 bc mov -0x44(%ebp),%eax +c01041ac: 8b 55 c0 mov -0x40(%ebp),%edx +c01041af: 0f a3 10 bt %edx,(%eax) +c01041b2: 19 c0 sbb %eax,%eax +c01041b4: 89 45 b8 mov %eax,-0x48(%ebp) + return oldbit != 0; +c01041b7: 83 7d b8 00 cmpl $0x0,-0x48(%ebp) +c01041bb: 0f 95 c0 setne %al +c01041be: 0f b6 c0 movzbl %al,%eax +c01041c1: 85 c0 test %eax,%eax +c01041c3: 74 24 je c01041e9 +c01041c5: c7 44 24 0c 6a cb 10 movl $0xc010cb6a,0xc(%esp) +c01041cc: c0 +c01041cd: c7 44 24 08 36 c9 10 movl $0xc010c936,0x8(%esp) +c01041d4: c0 +c01041d5: c7 44 24 04 4a 01 00 movl $0x14a,0x4(%esp) +c01041dc: 00 +c01041dd: c7 04 24 4b c9 10 c0 movl $0xc010c94b,(%esp) +c01041e4: e8 52 cb ff ff call c0100d3b <__panic> + // 初始化并检查空闲列表 + list_entry_t free_list_store = free_list; +c01041e9: a1 84 3f 1a c0 mov 0xc01a3f84,%eax +c01041ee: 8b 15 88 3f 1a c0 mov 0xc01a3f88,%edx +c01041f4: 89 45 80 mov %eax,-0x80(%ebp) +c01041f7: 89 55 84 mov %edx,-0x7c(%ebp) +c01041fa: c7 45 b0 84 3f 1a c0 movl $0xc01a3f84,-0x50(%ebp) + elm->prev = elm->next = elm; +c0104201: 8b 45 b0 mov -0x50(%ebp),%eax +c0104204: 8b 55 b0 mov -0x50(%ebp),%edx +c0104207: 89 50 04 mov %edx,0x4(%eax) +c010420a: 8b 45 b0 mov -0x50(%ebp),%eax +c010420d: 8b 50 04 mov 0x4(%eax),%edx +c0104210: 8b 45 b0 mov -0x50(%ebp),%eax +c0104213: 89 10 mov %edx,(%eax) +} +c0104215: 90 nop +c0104216: c7 45 b4 84 3f 1a c0 movl $0xc01a3f84,-0x4c(%ebp) + return list->next == list; +c010421d: 8b 45 b4 mov -0x4c(%ebp),%eax +c0104220: 8b 40 04 mov 0x4(%eax),%eax +c0104223: 39 45 b4 cmp %eax,-0x4c(%ebp) +c0104226: 0f 94 c0 sete %al +c0104229: 0f b6 c0 movzbl %al,%eax + list_init(&free_list); + assert(list_empty(&free_list));// 确保空闲列表为空 +c010422c: 85 c0 test %eax,%eax +c010422e: 75 24 jne c0104254 +c0104230: c7 44 24 0c bf ca 10 movl $0xc010cabf,0xc(%esp) +c0104237: c0 +c0104238: c7 44 24 08 36 c9 10 movl $0xc010c936,0x8(%esp) +c010423f: c0 +c0104240: c7 44 24 04 4e 01 00 movl $0x14e,0x4(%esp) +c0104247: 00 +c0104248: c7 04 24 4b c9 10 c0 movl $0xc010c94b,(%esp) +c010424f: e8 e7 ca ff ff call c0100d3b <__panic> + assert(alloc_page() == NULL);// 确保没有页面可分配 +c0104254: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c010425b: e8 21 0f 00 00 call c0105181 +c0104260: 85 c0 test %eax,%eax +c0104262: 74 24 je c0104288 +c0104264: c7 44 24 0c d6 ca 10 movl $0xc010cad6,0xc(%esp) +c010426b: c0 +c010426c: c7 44 24 08 36 c9 10 movl $0xc010c936,0x8(%esp) +c0104273: c0 +c0104274: c7 44 24 04 4f 01 00 movl $0x14f,0x4(%esp) +c010427b: 00 +c010427c: c7 04 24 4b c9 10 c0 movl $0xc010c94b,(%esp) +c0104283: e8 b3 ca ff ff call c0100d3b <__panic> + + unsigned int nr_free_store = nr_free;// 保存当前空闲页数 +c0104288: a1 8c 3f 1a c0 mov 0xc01a3f8c,%eax +c010428d: 89 45 e4 mov %eax,-0x1c(%ebp) + nr_free = 0;// 将空闲页数设为 0 +c0104290: c7 05 8c 3f 1a c0 00 movl $0x0,0xc01a3f8c +c0104297: 00 00 00 + // 释放 3 个页面并确保分配页面时没有足够的空闲页 + free_pages(p0 + 2, 3); +c010429a: 8b 45 e8 mov -0x18(%ebp),%eax +c010429d: 83 c0 40 add $0x40,%eax +c01042a0: c7 44 24 04 03 00 00 movl $0x3,0x4(%esp) +c01042a7: 00 +c01042a8: 89 04 24 mov %eax,(%esp) +c01042ab: e8 3e 0f 00 00 call c01051ee + assert(alloc_pages(4) == NULL);// 确保无法分配 4 个页面 +c01042b0: c7 04 24 04 00 00 00 movl $0x4,(%esp) +c01042b7: e8 c5 0e 00 00 call c0105181 +c01042bc: 85 c0 test %eax,%eax +c01042be: 74 24 je c01042e4 +c01042c0: c7 44 24 0c 7c cb 10 movl $0xc010cb7c,0xc(%esp) +c01042c7: c0 +c01042c8: c7 44 24 08 36 c9 10 movl $0xc010c936,0x8(%esp) +c01042cf: c0 +c01042d0: c7 44 24 04 55 01 00 movl $0x155,0x4(%esp) +c01042d7: 00 +c01042d8: c7 04 24 4b c9 10 c0 movl $0xc010c94b,(%esp) +c01042df: e8 57 ca ff ff call c0100d3b <__panic> + assert(PageProperty(p0 + 2) && p0[2].property == 3);// 检查页面属性 +c01042e4: 8b 45 e8 mov -0x18(%ebp),%eax +c01042e7: 83 c0 40 add $0x40,%eax +c01042ea: 83 c0 04 add $0x4,%eax +c01042ed: c7 45 ac 01 00 00 00 movl $0x1,-0x54(%ebp) +c01042f4: 89 45 a8 mov %eax,-0x58(%ebp) + asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr)); +c01042f7: 8b 45 a8 mov -0x58(%ebp),%eax +c01042fa: 8b 55 ac mov -0x54(%ebp),%edx +c01042fd: 0f a3 10 bt %edx,(%eax) +c0104300: 19 c0 sbb %eax,%eax +c0104302: 89 45 a4 mov %eax,-0x5c(%ebp) + return oldbit != 0; +c0104305: 83 7d a4 00 cmpl $0x0,-0x5c(%ebp) +c0104309: 0f 95 c0 setne %al +c010430c: 0f b6 c0 movzbl %al,%eax +c010430f: 85 c0 test %eax,%eax +c0104311: 74 0e je c0104321 +c0104313: 8b 45 e8 mov -0x18(%ebp),%eax +c0104316: 83 c0 40 add $0x40,%eax +c0104319: 8b 40 08 mov 0x8(%eax),%eax +c010431c: 83 f8 03 cmp $0x3,%eax +c010431f: 74 24 je c0104345 +c0104321: c7 44 24 0c 94 cb 10 movl $0xc010cb94,0xc(%esp) +c0104328: c0 +c0104329: c7 44 24 08 36 c9 10 movl $0xc010c936,0x8(%esp) +c0104330: c0 +c0104331: c7 44 24 04 56 01 00 movl $0x156,0x4(%esp) +c0104338: 00 +c0104339: c7 04 24 4b c9 10 c0 movl $0xc010c94b,(%esp) +c0104340: e8 f6 c9 ff ff call c0100d3b <__panic> + assert((p1 = alloc_pages(3)) != NULL);// 再次分配 3 个页面 +c0104345: c7 04 24 03 00 00 00 movl $0x3,(%esp) +c010434c: e8 30 0e 00 00 call c0105181 +c0104351: 89 45 e0 mov %eax,-0x20(%ebp) +c0104354: 83 7d e0 00 cmpl $0x0,-0x20(%ebp) +c0104358: 75 24 jne c010437e +c010435a: c7 44 24 0c c0 cb 10 movl $0xc010cbc0,0xc(%esp) +c0104361: c0 +c0104362: c7 44 24 08 36 c9 10 movl $0xc010c936,0x8(%esp) +c0104369: c0 +c010436a: c7 44 24 04 57 01 00 movl $0x157,0x4(%esp) +c0104371: 00 +c0104372: c7 04 24 4b c9 10 c0 movl $0xc010c94b,(%esp) +c0104379: e8 bd c9 ff ff call c0100d3b <__panic> + assert(alloc_page() == NULL);// 确保没有页面可分配 +c010437e: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c0104385: e8 f7 0d 00 00 call c0105181 +c010438a: 85 c0 test %eax,%eax +c010438c: 74 24 je c01043b2 +c010438e: c7 44 24 0c d6 ca 10 movl $0xc010cad6,0xc(%esp) +c0104395: c0 +c0104396: c7 44 24 08 36 c9 10 movl $0xc010c936,0x8(%esp) +c010439d: c0 +c010439e: c7 44 24 04 58 01 00 movl $0x158,0x4(%esp) +c01043a5: 00 +c01043a6: c7 04 24 4b c9 10 c0 movl $0xc010c94b,(%esp) +c01043ad: e8 89 c9 ff ff call c0100d3b <__panic> + assert(p0 + 2 == p1);// 确保分配的页面是释放的页面 +c01043b2: 8b 45 e8 mov -0x18(%ebp),%eax +c01043b5: 83 c0 40 add $0x40,%eax +c01043b8: 39 45 e0 cmp %eax,-0x20(%ebp) +c01043bb: 74 24 je c01043e1 +c01043bd: c7 44 24 0c de cb 10 movl $0xc010cbde,0xc(%esp) +c01043c4: c0 +c01043c5: c7 44 24 08 36 c9 10 movl $0xc010c936,0x8(%esp) +c01043cc: c0 +c01043cd: c7 44 24 04 59 01 00 movl $0x159,0x4(%esp) +c01043d4: 00 +c01043d5: c7 04 24 4b c9 10 c0 movl $0xc010c94b,(%esp) +c01043dc: e8 5a c9 ff ff call c0100d3b <__panic> + + p2 = p0 + 1;// 设置 p2 为 p0 的下一个页面 +c01043e1: 8b 45 e8 mov -0x18(%ebp),%eax +c01043e4: 83 c0 20 add $0x20,%eax +c01043e7: 89 45 dc mov %eax,-0x24(%ebp) + free_page(p0);// 释放 p0 页面 +c01043ea: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c01043f1: 00 +c01043f2: 8b 45 e8 mov -0x18(%ebp),%eax +c01043f5: 89 04 24 mov %eax,(%esp) +c01043f8: e8 f1 0d 00 00 call c01051ee + free_pages(p1, 3);// 释放 p1 指向的页面 +c01043fd: c7 44 24 04 03 00 00 movl $0x3,0x4(%esp) +c0104404: 00 +c0104405: 8b 45 e0 mov -0x20(%ebp),%eax +c0104408: 89 04 24 mov %eax,(%esp) +c010440b: e8 de 0d 00 00 call c01051ee + assert(PageProperty(p0) && p0->property == 1);// 检查 p0 属性 +c0104410: 8b 45 e8 mov -0x18(%ebp),%eax +c0104413: 83 c0 04 add $0x4,%eax +c0104416: c7 45 a0 01 00 00 00 movl $0x1,-0x60(%ebp) +c010441d: 89 45 9c mov %eax,-0x64(%ebp) + asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr)); +c0104420: 8b 45 9c mov -0x64(%ebp),%eax +c0104423: 8b 55 a0 mov -0x60(%ebp),%edx +c0104426: 0f a3 10 bt %edx,(%eax) +c0104429: 19 c0 sbb %eax,%eax +c010442b: 89 45 98 mov %eax,-0x68(%ebp) + return oldbit != 0; +c010442e: 83 7d 98 00 cmpl $0x0,-0x68(%ebp) +c0104432: 0f 95 c0 setne %al +c0104435: 0f b6 c0 movzbl %al,%eax +c0104438: 85 c0 test %eax,%eax +c010443a: 74 0b je c0104447 +c010443c: 8b 45 e8 mov -0x18(%ebp),%eax +c010443f: 8b 40 08 mov 0x8(%eax),%eax +c0104442: 83 f8 01 cmp $0x1,%eax +c0104445: 74 24 je c010446b +c0104447: c7 44 24 0c ec cb 10 movl $0xc010cbec,0xc(%esp) +c010444e: c0 +c010444f: c7 44 24 08 36 c9 10 movl $0xc010c936,0x8(%esp) +c0104456: c0 +c0104457: c7 44 24 04 5e 01 00 movl $0x15e,0x4(%esp) +c010445e: 00 +c010445f: c7 04 24 4b c9 10 c0 movl $0xc010c94b,(%esp) +c0104466: e8 d0 c8 ff ff call c0100d3b <__panic> + assert(PageProperty(p1) && p1->property == 3);// 检查 p1 属性 +c010446b: 8b 45 e0 mov -0x20(%ebp),%eax +c010446e: 83 c0 04 add $0x4,%eax +c0104471: c7 45 94 01 00 00 00 movl $0x1,-0x6c(%ebp) +c0104478: 89 45 90 mov %eax,-0x70(%ebp) + asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr)); +c010447b: 8b 45 90 mov -0x70(%ebp),%eax +c010447e: 8b 55 94 mov -0x6c(%ebp),%edx +c0104481: 0f a3 10 bt %edx,(%eax) +c0104484: 19 c0 sbb %eax,%eax +c0104486: 89 45 8c mov %eax,-0x74(%ebp) + return oldbit != 0; +c0104489: 83 7d 8c 00 cmpl $0x0,-0x74(%ebp) +c010448d: 0f 95 c0 setne %al +c0104490: 0f b6 c0 movzbl %al,%eax +c0104493: 85 c0 test %eax,%eax +c0104495: 74 0b je c01044a2 +c0104497: 8b 45 e0 mov -0x20(%ebp),%eax +c010449a: 8b 40 08 mov 0x8(%eax),%eax +c010449d: 83 f8 03 cmp $0x3,%eax +c01044a0: 74 24 je c01044c6 +c01044a2: c7 44 24 0c 14 cc 10 movl $0xc010cc14,0xc(%esp) +c01044a9: c0 +c01044aa: c7 44 24 08 36 c9 10 movl $0xc010c936,0x8(%esp) +c01044b1: c0 +c01044b2: c7 44 24 04 5f 01 00 movl $0x15f,0x4(%esp) +c01044b9: 00 +c01044ba: c7 04 24 4b c9 10 c0 movl $0xc010c94b,(%esp) +c01044c1: e8 75 c8 ff ff call c0100d3b <__panic> + // 确保重分配的页面是之前释放的页面 + assert((p0 = alloc_page()) == p2 - 1); +c01044c6: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c01044cd: e8 af 0c 00 00 call c0105181 +c01044d2: 89 45 e8 mov %eax,-0x18(%ebp) +c01044d5: 8b 45 dc mov -0x24(%ebp),%eax +c01044d8: 83 e8 20 sub $0x20,%eax +c01044db: 39 45 e8 cmp %eax,-0x18(%ebp) +c01044de: 74 24 je c0104504 +c01044e0: c7 44 24 0c 3a cc 10 movl $0xc010cc3a,0xc(%esp) +c01044e7: c0 +c01044e8: c7 44 24 08 36 c9 10 movl $0xc010c936,0x8(%esp) +c01044ef: c0 +c01044f0: c7 44 24 04 61 01 00 movl $0x161,0x4(%esp) +c01044f7: 00 +c01044f8: c7 04 24 4b c9 10 c0 movl $0xc010c94b,(%esp) +c01044ff: e8 37 c8 ff ff call c0100d3b <__panic> + free_page(p0);// 释放分配的页面 +c0104504: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c010450b: 00 +c010450c: 8b 45 e8 mov -0x18(%ebp),%eax +c010450f: 89 04 24 mov %eax,(%esp) +c0104512: e8 d7 0c 00 00 call c01051ee + assert((p0 = alloc_pages(2)) == p2 + 1);// 分配 2 个页面并检查 +c0104517: c7 04 24 02 00 00 00 movl $0x2,(%esp) +c010451e: e8 5e 0c 00 00 call c0105181 +c0104523: 89 45 e8 mov %eax,-0x18(%ebp) +c0104526: 8b 45 dc mov -0x24(%ebp),%eax +c0104529: 83 c0 20 add $0x20,%eax +c010452c: 39 45 e8 cmp %eax,-0x18(%ebp) +c010452f: 74 24 je c0104555 +c0104531: c7 44 24 0c 58 cc 10 movl $0xc010cc58,0xc(%esp) +c0104538: c0 +c0104539: c7 44 24 08 36 c9 10 movl $0xc010c936,0x8(%esp) +c0104540: c0 +c0104541: c7 44 24 04 63 01 00 movl $0x163,0x4(%esp) +c0104548: 00 +c0104549: c7 04 24 4b c9 10 c0 movl $0xc010c94b,(%esp) +c0104550: e8 e6 c7 ff ff call c0100d3b <__panic> + // 释放页面并检查空闲状态 + free_pages(p0, 2); +c0104555: c7 44 24 04 02 00 00 movl $0x2,0x4(%esp) +c010455c: 00 +c010455d: 8b 45 e8 mov -0x18(%ebp),%eax +c0104560: 89 04 24 mov %eax,(%esp) +c0104563: e8 86 0c 00 00 call c01051ee + free_page(p2); +c0104568: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c010456f: 00 +c0104570: 8b 45 dc mov -0x24(%ebp),%eax +c0104573: 89 04 24 mov %eax,(%esp) +c0104576: e8 73 0c 00 00 call c01051ee + // 再次分配 5 个页面 + assert((p0 = alloc_pages(5)) != NULL); +c010457b: c7 04 24 05 00 00 00 movl $0x5,(%esp) +c0104582: e8 fa 0b 00 00 call c0105181 +c0104587: 89 45 e8 mov %eax,-0x18(%ebp) +c010458a: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) +c010458e: 75 24 jne c01045b4 +c0104590: c7 44 24 0c 78 cc 10 movl $0xc010cc78,0xc(%esp) +c0104597: c0 +c0104598: c7 44 24 08 36 c9 10 movl $0xc010c936,0x8(%esp) +c010459f: c0 +c01045a0: c7 44 24 04 68 01 00 movl $0x168,0x4(%esp) +c01045a7: 00 +c01045a8: c7 04 24 4b c9 10 c0 movl $0xc010c94b,(%esp) +c01045af: e8 87 c7 ff ff call c0100d3b <__panic> + assert(alloc_page() == NULL);// 确保没有额外页面可分配 +c01045b4: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c01045bb: e8 c1 0b 00 00 call c0105181 +c01045c0: 85 c0 test %eax,%eax +c01045c2: 74 24 je c01045e8 +c01045c4: c7 44 24 0c d6 ca 10 movl $0xc010cad6,0xc(%esp) +c01045cb: c0 +c01045cc: c7 44 24 08 36 c9 10 movl $0xc010c936,0x8(%esp) +c01045d3: c0 +c01045d4: c7 44 24 04 69 01 00 movl $0x169,0x4(%esp) +c01045db: 00 +c01045dc: c7 04 24 4b c9 10 c0 movl $0xc010c94b,(%esp) +c01045e3: e8 53 c7 ff ff call c0100d3b <__panic> + + assert(nr_free == 0);// 确保空闲页数为 0 +c01045e8: a1 8c 3f 1a c0 mov 0xc01a3f8c,%eax +c01045ed: 85 c0 test %eax,%eax +c01045ef: 74 24 je c0104615 +c01045f1: c7 44 24 0c 29 cb 10 movl $0xc010cb29,0xc(%esp) +c01045f8: c0 +c01045f9: c7 44 24 08 36 c9 10 movl $0xc010c936,0x8(%esp) +c0104600: c0 +c0104601: c7 44 24 04 6b 01 00 movl $0x16b,0x4(%esp) +c0104608: 00 +c0104609: c7 04 24 4b c9 10 c0 movl $0xc010c94b,(%esp) +c0104610: e8 26 c7 ff ff call c0100d3b <__panic> + nr_free = nr_free_store;// 恢复空闲页数 +c0104615: 8b 45 e4 mov -0x1c(%ebp),%eax +c0104618: a3 8c 3f 1a c0 mov %eax,0xc01a3f8c + // 恢复空闲列表状态 + free_list = free_list_store; +c010461d: 8b 45 80 mov -0x80(%ebp),%eax +c0104620: 8b 55 84 mov -0x7c(%ebp),%edx +c0104623: a3 84 3f 1a c0 mov %eax,0xc01a3f84 +c0104628: 89 15 88 3f 1a c0 mov %edx,0xc01a3f88 + free_pages(p0, 5);// 释放所有分配的页面 +c010462e: c7 44 24 04 05 00 00 movl $0x5,0x4(%esp) +c0104635: 00 +c0104636: 8b 45 e8 mov -0x18(%ebp),%eax +c0104639: 89 04 24 mov %eax,(%esp) +c010463c: e8 ad 0b 00 00 call c01051ee + // 验证空闲列表的一致性 + le = &free_list; +c0104641: c7 45 ec 84 3f 1a c0 movl $0xc01a3f84,-0x14(%ebp) + while ((le = list_next(le)) != &free_list) { +c0104648: eb 1c jmp c0104666 + struct Page *p = le2page(le, page_link); +c010464a: 8b 45 ec mov -0x14(%ebp),%eax +c010464d: 83 e8 0c sub $0xc,%eax +c0104650: 89 45 d8 mov %eax,-0x28(%ebp) + count --, total -= p->property; +c0104653: ff 4d f4 decl -0xc(%ebp) +c0104656: 8b 55 f0 mov -0x10(%ebp),%edx +c0104659: 8b 45 d8 mov -0x28(%ebp),%eax +c010465c: 8b 48 08 mov 0x8(%eax),%ecx +c010465f: 89 d0 mov %edx,%eax +c0104661: 29 c8 sub %ecx,%eax +c0104663: 89 45 f0 mov %eax,-0x10(%ebp) +c0104666: 8b 45 ec mov -0x14(%ebp),%eax +c0104669: 89 45 88 mov %eax,-0x78(%ebp) + return listelm->next; +c010466c: 8b 45 88 mov -0x78(%ebp),%eax +c010466f: 8b 40 04 mov 0x4(%eax),%eax + while ((le = list_next(le)) != &free_list) { +c0104672: 89 45 ec mov %eax,-0x14(%ebp) +c0104675: 81 7d ec 84 3f 1a c0 cmpl $0xc01a3f84,-0x14(%ebp) +c010467c: 75 cc jne c010464a + } + assert(count == 0);// 确保所有页面都已处理 +c010467e: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c0104682: 74 24 je c01046a8 +c0104684: c7 44 24 0c 96 cc 10 movl $0xc010cc96,0xc(%esp) +c010468b: c0 +c010468c: c7 44 24 08 36 c9 10 movl $0xc010c936,0x8(%esp) +c0104693: c0 +c0104694: c7 44 24 04 76 01 00 movl $0x176,0x4(%esp) +c010469b: 00 +c010469c: c7 04 24 4b c9 10 c0 movl $0xc010c94b,(%esp) +c01046a3: e8 93 c6 ff ff call c0100d3b <__panic> + assert(total == 0);// 确保总属性值为 0 +c01046a8: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) +c01046ac: 74 24 je c01046d2 +c01046ae: c7 44 24 0c a1 cc 10 movl $0xc010cca1,0xc(%esp) +c01046b5: c0 +c01046b6: c7 44 24 08 36 c9 10 movl $0xc010c936,0x8(%esp) +c01046bd: c0 +c01046be: c7 44 24 04 77 01 00 movl $0x177,0x4(%esp) +c01046c5: 00 +c01046c6: c7 04 24 4b c9 10 c0 movl $0xc010c94b,(%esp) +c01046cd: e8 69 c6 ff ff call c0100d3b <__panic> +} +c01046d2: 90 nop +c01046d3: 89 ec mov %ebp,%esp +c01046d5: 5d pop %ebp +c01046d6: c3 ret + +c01046d7 <__intr_save>: +__intr_save(void) { +c01046d7: 55 push %ebp +c01046d8: 89 e5 mov %esp,%ebp +c01046da: 83 ec 18 sub $0x18,%esp + asm volatile ("pushfl; popl %0" : "=r" (eflags)); +c01046dd: 9c pushf +c01046de: 58 pop %eax +c01046df: 89 45 f4 mov %eax,-0xc(%ebp) + return eflags; +c01046e2: 8b 45 f4 mov -0xc(%ebp),%eax + if (read_eflags() & FL_IF) { +c01046e5: 25 00 02 00 00 and $0x200,%eax +c01046ea: 85 c0 test %eax,%eax +c01046ec: 74 0c je c01046fa <__intr_save+0x23> + intr_disable(); +c01046ee: e8 fe d8 ff ff call c0101ff1 + return 1; +c01046f3: b8 01 00 00 00 mov $0x1,%eax +c01046f8: eb 05 jmp c01046ff <__intr_save+0x28> + return 0; +c01046fa: b8 00 00 00 00 mov $0x0,%eax +} +c01046ff: 89 ec mov %ebp,%esp +c0104701: 5d pop %ebp +c0104702: c3 ret + +c0104703 <__intr_restore>: +__intr_restore(bool flag) { +c0104703: 55 push %ebp +c0104704: 89 e5 mov %esp,%ebp +c0104706: 83 ec 08 sub $0x8,%esp + if (flag) { +c0104709: 83 7d 08 00 cmpl $0x0,0x8(%ebp) +c010470d: 74 05 je c0104714 <__intr_restore+0x11> + intr_enable(); +c010470f: e8 d5 d8 ff ff call c0101fe9 +} +c0104714: 90 nop +c0104715: 89 ec mov %ebp,%esp +c0104717: 5d pop %ebp +c0104718: c3 ret + +c0104719 : +page2ppn(struct Page *page) { +c0104719: 55 push %ebp +c010471a: 89 e5 mov %esp,%ebp + return page - pages; +c010471c: 8b 15 a0 3f 1a c0 mov 0xc01a3fa0,%edx +c0104722: 8b 45 08 mov 0x8(%ebp),%eax +c0104725: 29 d0 sub %edx,%eax +c0104727: c1 f8 05 sar $0x5,%eax +} +c010472a: 5d pop %ebp +c010472b: c3 ret + +c010472c : +page2pa(struct Page *page) { +c010472c: 55 push %ebp +c010472d: 89 e5 mov %esp,%ebp +c010472f: 83 ec 04 sub $0x4,%esp + return page2ppn(page) << PGSHIFT; +c0104732: 8b 45 08 mov 0x8(%ebp),%eax +c0104735: 89 04 24 mov %eax,(%esp) +c0104738: e8 dc ff ff ff call c0104719 +c010473d: c1 e0 0c shl $0xc,%eax +} +c0104740: 89 ec mov %ebp,%esp +c0104742: 5d pop %ebp +c0104743: c3 ret + +c0104744 : +pa2page(uintptr_t pa) { +c0104744: 55 push %ebp +c0104745: 89 e5 mov %esp,%ebp +c0104747: 83 ec 18 sub $0x18,%esp + if (PPN(pa) >= npage) { +c010474a: 8b 45 08 mov 0x8(%ebp),%eax +c010474d: c1 e8 0c shr $0xc,%eax +c0104750: 89 c2 mov %eax,%edx +c0104752: a1 a4 3f 1a c0 mov 0xc01a3fa4,%eax +c0104757: 39 c2 cmp %eax,%edx +c0104759: 72 1c jb c0104777 + panic("pa2page called with invalid pa"); +c010475b: c7 44 24 08 dc cc 10 movl $0xc010ccdc,0x8(%esp) +c0104762: c0 +c0104763: c7 44 24 04 5e 00 00 movl $0x5e,0x4(%esp) +c010476a: 00 +c010476b: c7 04 24 fb cc 10 c0 movl $0xc010ccfb,(%esp) +c0104772: e8 c4 c5 ff ff call c0100d3b <__panic> + return &pages[PPN(pa)]; +c0104777: 8b 15 a0 3f 1a c0 mov 0xc01a3fa0,%edx +c010477d: 8b 45 08 mov 0x8(%ebp),%eax +c0104780: c1 e8 0c shr $0xc,%eax +c0104783: c1 e0 05 shl $0x5,%eax +c0104786: 01 d0 add %edx,%eax +} +c0104788: 89 ec mov %ebp,%esp +c010478a: 5d pop %ebp +c010478b: c3 ret + +c010478c : +page2kva(struct Page *page) { +c010478c: 55 push %ebp +c010478d: 89 e5 mov %esp,%ebp +c010478f: 83 ec 28 sub $0x28,%esp + return KADDR(page2pa(page)); +c0104792: 8b 45 08 mov 0x8(%ebp),%eax +c0104795: 89 04 24 mov %eax,(%esp) +c0104798: e8 8f ff ff ff call c010472c +c010479d: 89 45 f4 mov %eax,-0xc(%ebp) +c01047a0: 8b 45 f4 mov -0xc(%ebp),%eax +c01047a3: c1 e8 0c shr $0xc,%eax +c01047a6: 89 45 f0 mov %eax,-0x10(%ebp) +c01047a9: a1 a4 3f 1a c0 mov 0xc01a3fa4,%eax +c01047ae: 39 45 f0 cmp %eax,-0x10(%ebp) +c01047b1: 72 23 jb c01047d6 +c01047b3: 8b 45 f4 mov -0xc(%ebp),%eax +c01047b6: 89 44 24 0c mov %eax,0xc(%esp) +c01047ba: c7 44 24 08 0c cd 10 movl $0xc010cd0c,0x8(%esp) +c01047c1: c0 +c01047c2: c7 44 24 04 65 00 00 movl $0x65,0x4(%esp) +c01047c9: 00 +c01047ca: c7 04 24 fb cc 10 c0 movl $0xc010ccfb,(%esp) +c01047d1: e8 65 c5 ff ff call c0100d3b <__panic> +c01047d6: 8b 45 f4 mov -0xc(%ebp),%eax +c01047d9: 2d 00 00 00 40 sub $0x40000000,%eax +} +c01047de: 89 ec mov %ebp,%esp +c01047e0: 5d pop %ebp +c01047e1: c3 ret + +c01047e2 : +kva2page(void *kva) { +c01047e2: 55 push %ebp +c01047e3: 89 e5 mov %esp,%ebp +c01047e5: 83 ec 28 sub $0x28,%esp + return pa2page(PADDR(kva)); +c01047e8: 8b 45 08 mov 0x8(%ebp),%eax +c01047eb: 89 45 f4 mov %eax,-0xc(%ebp) +c01047ee: 81 7d f4 ff ff ff bf cmpl $0xbfffffff,-0xc(%ebp) +c01047f5: 77 23 ja c010481a +c01047f7: 8b 45 f4 mov -0xc(%ebp),%eax +c01047fa: 89 44 24 0c mov %eax,0xc(%esp) +c01047fe: c7 44 24 08 30 cd 10 movl $0xc010cd30,0x8(%esp) +c0104805: c0 +c0104806: c7 44 24 04 6a 00 00 movl $0x6a,0x4(%esp) +c010480d: 00 +c010480e: c7 04 24 fb cc 10 c0 movl $0xc010ccfb,(%esp) +c0104815: e8 21 c5 ff ff call c0100d3b <__panic> +c010481a: 8b 45 f4 mov -0xc(%ebp),%eax +c010481d: 05 00 00 00 40 add $0x40000000,%eax +c0104822: 89 04 24 mov %eax,(%esp) +c0104825: e8 1a ff ff ff call c0104744 +} +c010482a: 89 ec mov %ebp,%esp +c010482c: 5d pop %ebp +c010482d: c3 ret + +c010482e <__slob_get_free_pages>: +static slob_t *slobfree = &arena; +static bigblock_t *bigblocks; + + +static void* __slob_get_free_pages(gfp_t gfp, int order) +{ +c010482e: 55 push %ebp +c010482f: 89 e5 mov %esp,%ebp +c0104831: 83 ec 28 sub $0x28,%esp + struct Page * page = alloc_pages(1 << order); +c0104834: 8b 45 0c mov 0xc(%ebp),%eax +c0104837: ba 01 00 00 00 mov $0x1,%edx +c010483c: 88 c1 mov %al,%cl +c010483e: d3 e2 shl %cl,%edx +c0104840: 89 d0 mov %edx,%eax +c0104842: 89 04 24 mov %eax,(%esp) +c0104845: e8 37 09 00 00 call c0105181 +c010484a: 89 45 f4 mov %eax,-0xc(%ebp) + if(!page) +c010484d: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c0104851: 75 07 jne c010485a <__slob_get_free_pages+0x2c> + return NULL; +c0104853: b8 00 00 00 00 mov $0x0,%eax +c0104858: eb 0b jmp c0104865 <__slob_get_free_pages+0x37> + return page2kva(page); +c010485a: 8b 45 f4 mov -0xc(%ebp),%eax +c010485d: 89 04 24 mov %eax,(%esp) +c0104860: e8 27 ff ff ff call c010478c +} +c0104865: 89 ec mov %ebp,%esp +c0104867: 5d pop %ebp +c0104868: c3 ret + +c0104869 <__slob_free_pages>: + +#define __slob_get_free_page(gfp) __slob_get_free_pages(gfp, 0) + +static inline void __slob_free_pages(unsigned long kva, int order) +{ +c0104869: 55 push %ebp +c010486a: 89 e5 mov %esp,%ebp +c010486c: 83 ec 18 sub $0x18,%esp +c010486f: 89 5d fc mov %ebx,-0x4(%ebp) + free_pages(kva2page(kva), 1 << order); +c0104872: 8b 45 0c mov 0xc(%ebp),%eax +c0104875: ba 01 00 00 00 mov $0x1,%edx +c010487a: 88 c1 mov %al,%cl +c010487c: d3 e2 shl %cl,%edx +c010487e: 89 d0 mov %edx,%eax +c0104880: 89 c3 mov %eax,%ebx +c0104882: 8b 45 08 mov 0x8(%ebp),%eax +c0104885: 89 04 24 mov %eax,(%esp) +c0104888: e8 55 ff ff ff call c01047e2 +c010488d: 89 5c 24 04 mov %ebx,0x4(%esp) +c0104891: 89 04 24 mov %eax,(%esp) +c0104894: e8 55 09 00 00 call c01051ee +} +c0104899: 90 nop +c010489a: 8b 5d fc mov -0x4(%ebp),%ebx +c010489d: 89 ec mov %ebp,%esp +c010489f: 5d pop %ebp +c01048a0: c3 ret + +c01048a1 : + +static void slob_free(void *b, int size); + +static void *slob_alloc(size_t size, gfp_t gfp, int align) +{ +c01048a1: 55 push %ebp +c01048a2: 89 e5 mov %esp,%ebp +c01048a4: 83 ec 38 sub $0x38,%esp + assert( (size + SLOB_UNIT) < PAGE_SIZE ); +c01048a7: 8b 45 08 mov 0x8(%ebp),%eax +c01048aa: 83 c0 08 add $0x8,%eax +c01048ad: 3d ff 0f 00 00 cmp $0xfff,%eax +c01048b2: 76 24 jbe c01048d8 +c01048b4: c7 44 24 0c 54 cd 10 movl $0xc010cd54,0xc(%esp) +c01048bb: c0 +c01048bc: c7 44 24 08 73 cd 10 movl $0xc010cd73,0x8(%esp) +c01048c3: c0 +c01048c4: c7 44 24 04 64 00 00 movl $0x64,0x4(%esp) +c01048cb: 00 +c01048cc: c7 04 24 88 cd 10 c0 movl $0xc010cd88,(%esp) +c01048d3: e8 63 c4 ff ff call c0100d3b <__panic> + + slob_t *prev, *cur, *aligned = 0; +c01048d8: c7 45 ec 00 00 00 00 movl $0x0,-0x14(%ebp) + int delta = 0, units = SLOB_UNITS(size); +c01048df: c7 45 e8 00 00 00 00 movl $0x0,-0x18(%ebp) +c01048e6: 8b 45 08 mov 0x8(%ebp),%eax +c01048e9: 83 c0 07 add $0x7,%eax +c01048ec: c1 e8 03 shr $0x3,%eax +c01048ef: 89 45 e0 mov %eax,-0x20(%ebp) + unsigned long flags; + + spin_lock_irqsave(&slob_lock, flags); +c01048f2: e8 e0 fd ff ff call c01046d7 <__intr_save> +c01048f7: 89 45 e4 mov %eax,-0x1c(%ebp) + prev = slobfree; +c01048fa: a1 e8 f9 12 c0 mov 0xc012f9e8,%eax +c01048ff: 89 45 f4 mov %eax,-0xc(%ebp) + for (cur = prev->next; ; prev = cur, cur = cur->next) { +c0104902: 8b 45 f4 mov -0xc(%ebp),%eax +c0104905: 8b 40 04 mov 0x4(%eax),%eax +c0104908: 89 45 f0 mov %eax,-0x10(%ebp) + if (align) { +c010490b: 83 7d 10 00 cmpl $0x0,0x10(%ebp) +c010490f: 74 21 je c0104932 + aligned = (slob_t *)ALIGN((unsigned long)cur, align); +c0104911: 8b 55 f0 mov -0x10(%ebp),%edx +c0104914: 8b 45 10 mov 0x10(%ebp),%eax +c0104917: 01 d0 add %edx,%eax +c0104919: 8d 50 ff lea -0x1(%eax),%edx +c010491c: 8b 45 10 mov 0x10(%ebp),%eax +c010491f: f7 d8 neg %eax +c0104921: 21 d0 and %edx,%eax +c0104923: 89 45 ec mov %eax,-0x14(%ebp) + delta = aligned - cur; +c0104926: 8b 45 ec mov -0x14(%ebp),%eax +c0104929: 2b 45 f0 sub -0x10(%ebp),%eax +c010492c: c1 f8 03 sar $0x3,%eax +c010492f: 89 45 e8 mov %eax,-0x18(%ebp) + } + if (cur->units >= units + delta) { /* room enough? */ +c0104932: 8b 45 f0 mov -0x10(%ebp),%eax +c0104935: 8b 00 mov (%eax),%eax +c0104937: 8b 4d e0 mov -0x20(%ebp),%ecx +c010493a: 8b 55 e8 mov -0x18(%ebp),%edx +c010493d: 01 ca add %ecx,%edx +c010493f: 39 d0 cmp %edx,%eax +c0104941: 0f 8c aa 00 00 00 jl c01049f1 + if (delta) { /* need to fragment head to align? */ +c0104947: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) +c010494b: 74 38 je c0104985 + aligned->units = cur->units - delta; +c010494d: 8b 45 f0 mov -0x10(%ebp),%eax +c0104950: 8b 00 mov (%eax),%eax +c0104952: 2b 45 e8 sub -0x18(%ebp),%eax +c0104955: 89 c2 mov %eax,%edx +c0104957: 8b 45 ec mov -0x14(%ebp),%eax +c010495a: 89 10 mov %edx,(%eax) + aligned->next = cur->next; +c010495c: 8b 45 f0 mov -0x10(%ebp),%eax +c010495f: 8b 50 04 mov 0x4(%eax),%edx +c0104962: 8b 45 ec mov -0x14(%ebp),%eax +c0104965: 89 50 04 mov %edx,0x4(%eax) + cur->next = aligned; +c0104968: 8b 45 f0 mov -0x10(%ebp),%eax +c010496b: 8b 55 ec mov -0x14(%ebp),%edx +c010496e: 89 50 04 mov %edx,0x4(%eax) + cur->units = delta; +c0104971: 8b 45 f0 mov -0x10(%ebp),%eax +c0104974: 8b 55 e8 mov -0x18(%ebp),%edx +c0104977: 89 10 mov %edx,(%eax) + prev = cur; +c0104979: 8b 45 f0 mov -0x10(%ebp),%eax +c010497c: 89 45 f4 mov %eax,-0xc(%ebp) + cur = aligned; +c010497f: 8b 45 ec mov -0x14(%ebp),%eax +c0104982: 89 45 f0 mov %eax,-0x10(%ebp) + } + + if (cur->units == units) /* exact fit? */ +c0104985: 8b 45 f0 mov -0x10(%ebp),%eax +c0104988: 8b 00 mov (%eax),%eax +c010498a: 39 45 e0 cmp %eax,-0x20(%ebp) +c010498d: 75 0e jne c010499d + prev->next = cur->next; /* unlink */ +c010498f: 8b 45 f0 mov -0x10(%ebp),%eax +c0104992: 8b 50 04 mov 0x4(%eax),%edx +c0104995: 8b 45 f4 mov -0xc(%ebp),%eax +c0104998: 89 50 04 mov %edx,0x4(%eax) +c010499b: eb 3c jmp c01049d9 + else { /* fragment */ + prev->next = cur + units; +c010499d: 8b 45 e0 mov -0x20(%ebp),%eax +c01049a0: 8d 14 c5 00 00 00 00 lea 0x0(,%eax,8),%edx +c01049a7: 8b 45 f0 mov -0x10(%ebp),%eax +c01049aa: 01 c2 add %eax,%edx +c01049ac: 8b 45 f4 mov -0xc(%ebp),%eax +c01049af: 89 50 04 mov %edx,0x4(%eax) + prev->next->units = cur->units - units; +c01049b2: 8b 45 f0 mov -0x10(%ebp),%eax +c01049b5: 8b 10 mov (%eax),%edx +c01049b7: 8b 45 f4 mov -0xc(%ebp),%eax +c01049ba: 8b 40 04 mov 0x4(%eax),%eax +c01049bd: 2b 55 e0 sub -0x20(%ebp),%edx +c01049c0: 89 10 mov %edx,(%eax) + prev->next->next = cur->next; +c01049c2: 8b 45 f4 mov -0xc(%ebp),%eax +c01049c5: 8b 40 04 mov 0x4(%eax),%eax +c01049c8: 8b 55 f0 mov -0x10(%ebp),%edx +c01049cb: 8b 52 04 mov 0x4(%edx),%edx +c01049ce: 89 50 04 mov %edx,0x4(%eax) + cur->units = units; +c01049d1: 8b 45 f0 mov -0x10(%ebp),%eax +c01049d4: 8b 55 e0 mov -0x20(%ebp),%edx +c01049d7: 89 10 mov %edx,(%eax) + } + + slobfree = prev; +c01049d9: 8b 45 f4 mov -0xc(%ebp),%eax +c01049dc: a3 e8 f9 12 c0 mov %eax,0xc012f9e8 + spin_unlock_irqrestore(&slob_lock, flags); +c01049e1: 8b 45 e4 mov -0x1c(%ebp),%eax +c01049e4: 89 04 24 mov %eax,(%esp) +c01049e7: e8 17 fd ff ff call c0104703 <__intr_restore> + return cur; +c01049ec: 8b 45 f0 mov -0x10(%ebp),%eax +c01049ef: eb 7f jmp c0104a70 + } + if (cur == slobfree) { +c01049f1: a1 e8 f9 12 c0 mov 0xc012f9e8,%eax +c01049f6: 39 45 f0 cmp %eax,-0x10(%ebp) +c01049f9: 75 61 jne c0104a5c + spin_unlock_irqrestore(&slob_lock, flags); +c01049fb: 8b 45 e4 mov -0x1c(%ebp),%eax +c01049fe: 89 04 24 mov %eax,(%esp) +c0104a01: e8 fd fc ff ff call c0104703 <__intr_restore> + + if (size == PAGE_SIZE) /* trying to shrink arena? */ +c0104a06: 81 7d 08 00 10 00 00 cmpl $0x1000,0x8(%ebp) +c0104a0d: 75 07 jne c0104a16 + return 0; +c0104a0f: b8 00 00 00 00 mov $0x0,%eax +c0104a14: eb 5a jmp c0104a70 + + cur = (slob_t *)__slob_get_free_page(gfp); +c0104a16: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) +c0104a1d: 00 +c0104a1e: 8b 45 0c mov 0xc(%ebp),%eax +c0104a21: 89 04 24 mov %eax,(%esp) +c0104a24: e8 05 fe ff ff call c010482e <__slob_get_free_pages> +c0104a29: 89 45 f0 mov %eax,-0x10(%ebp) + if (!cur) +c0104a2c: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) +c0104a30: 75 07 jne c0104a39 + return 0; +c0104a32: b8 00 00 00 00 mov $0x0,%eax +c0104a37: eb 37 jmp c0104a70 + + slob_free(cur, PAGE_SIZE); +c0104a39: c7 44 24 04 00 10 00 movl $0x1000,0x4(%esp) +c0104a40: 00 +c0104a41: 8b 45 f0 mov -0x10(%ebp),%eax +c0104a44: 89 04 24 mov %eax,(%esp) +c0104a47: e8 28 00 00 00 call c0104a74 + spin_lock_irqsave(&slob_lock, flags); +c0104a4c: e8 86 fc ff ff call c01046d7 <__intr_save> +c0104a51: 89 45 e4 mov %eax,-0x1c(%ebp) + cur = slobfree; +c0104a54: a1 e8 f9 12 c0 mov 0xc012f9e8,%eax +c0104a59: 89 45 f0 mov %eax,-0x10(%ebp) + for (cur = prev->next; ; prev = cur, cur = cur->next) { +c0104a5c: 8b 45 f0 mov -0x10(%ebp),%eax +c0104a5f: 89 45 f4 mov %eax,-0xc(%ebp) +c0104a62: 8b 45 f0 mov -0x10(%ebp),%eax +c0104a65: 8b 40 04 mov 0x4(%eax),%eax +c0104a68: 89 45 f0 mov %eax,-0x10(%ebp) + if (align) { +c0104a6b: e9 9b fe ff ff jmp c010490b + } + } +} +c0104a70: 89 ec mov %ebp,%esp +c0104a72: 5d pop %ebp +c0104a73: c3 ret + +c0104a74 : + +static void slob_free(void *block, int size) +{ +c0104a74: 55 push %ebp +c0104a75: 89 e5 mov %esp,%ebp +c0104a77: 83 ec 28 sub $0x28,%esp + slob_t *cur, *b = (slob_t *)block; +c0104a7a: 8b 45 08 mov 0x8(%ebp),%eax +c0104a7d: 89 45 f0 mov %eax,-0x10(%ebp) + unsigned long flags; + + if (!block) +c0104a80: 83 7d 08 00 cmpl $0x0,0x8(%ebp) +c0104a84: 0f 84 01 01 00 00 je c0104b8b + return; + + if (size) +c0104a8a: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) +c0104a8e: 74 10 je c0104aa0 + b->units = SLOB_UNITS(size); +c0104a90: 8b 45 0c mov 0xc(%ebp),%eax +c0104a93: 83 c0 07 add $0x7,%eax +c0104a96: c1 e8 03 shr $0x3,%eax +c0104a99: 89 c2 mov %eax,%edx +c0104a9b: 8b 45 f0 mov -0x10(%ebp),%eax +c0104a9e: 89 10 mov %edx,(%eax) + + /* Find reinsertion point */ + spin_lock_irqsave(&slob_lock, flags); +c0104aa0: e8 32 fc ff ff call c01046d7 <__intr_save> +c0104aa5: 89 45 ec mov %eax,-0x14(%ebp) + for (cur = slobfree; !(b > cur && b < cur->next); cur = cur->next) +c0104aa8: a1 e8 f9 12 c0 mov 0xc012f9e8,%eax +c0104aad: 89 45 f4 mov %eax,-0xc(%ebp) +c0104ab0: eb 27 jmp c0104ad9 + if (cur >= cur->next && (b > cur || b < cur->next)) +c0104ab2: 8b 45 f4 mov -0xc(%ebp),%eax +c0104ab5: 8b 40 04 mov 0x4(%eax),%eax +c0104ab8: 39 45 f4 cmp %eax,-0xc(%ebp) +c0104abb: 72 13 jb c0104ad0 +c0104abd: 8b 45 f0 mov -0x10(%ebp),%eax +c0104ac0: 3b 45 f4 cmp -0xc(%ebp),%eax +c0104ac3: 77 27 ja c0104aec +c0104ac5: 8b 45 f4 mov -0xc(%ebp),%eax +c0104ac8: 8b 40 04 mov 0x4(%eax),%eax +c0104acb: 39 45 f0 cmp %eax,-0x10(%ebp) +c0104ace: 72 1c jb c0104aec + for (cur = slobfree; !(b > cur && b < cur->next); cur = cur->next) +c0104ad0: 8b 45 f4 mov -0xc(%ebp),%eax +c0104ad3: 8b 40 04 mov 0x4(%eax),%eax +c0104ad6: 89 45 f4 mov %eax,-0xc(%ebp) +c0104ad9: 8b 45 f0 mov -0x10(%ebp),%eax +c0104adc: 3b 45 f4 cmp -0xc(%ebp),%eax +c0104adf: 76 d1 jbe c0104ab2 +c0104ae1: 8b 45 f4 mov -0xc(%ebp),%eax +c0104ae4: 8b 40 04 mov 0x4(%eax),%eax +c0104ae7: 39 45 f0 cmp %eax,-0x10(%ebp) +c0104aea: 73 c6 jae c0104ab2 + break; + + if (b + b->units == cur->next) { +c0104aec: 8b 45 f0 mov -0x10(%ebp),%eax +c0104aef: 8b 00 mov (%eax),%eax +c0104af1: 8d 14 c5 00 00 00 00 lea 0x0(,%eax,8),%edx +c0104af8: 8b 45 f0 mov -0x10(%ebp),%eax +c0104afb: 01 c2 add %eax,%edx +c0104afd: 8b 45 f4 mov -0xc(%ebp),%eax +c0104b00: 8b 40 04 mov 0x4(%eax),%eax +c0104b03: 39 c2 cmp %eax,%edx +c0104b05: 75 25 jne c0104b2c + b->units += cur->next->units; +c0104b07: 8b 45 f0 mov -0x10(%ebp),%eax +c0104b0a: 8b 10 mov (%eax),%edx +c0104b0c: 8b 45 f4 mov -0xc(%ebp),%eax +c0104b0f: 8b 40 04 mov 0x4(%eax),%eax +c0104b12: 8b 00 mov (%eax),%eax +c0104b14: 01 c2 add %eax,%edx +c0104b16: 8b 45 f0 mov -0x10(%ebp),%eax +c0104b19: 89 10 mov %edx,(%eax) + b->next = cur->next->next; +c0104b1b: 8b 45 f4 mov -0xc(%ebp),%eax +c0104b1e: 8b 40 04 mov 0x4(%eax),%eax +c0104b21: 8b 50 04 mov 0x4(%eax),%edx +c0104b24: 8b 45 f0 mov -0x10(%ebp),%eax +c0104b27: 89 50 04 mov %edx,0x4(%eax) +c0104b2a: eb 0c jmp c0104b38 + } else + b->next = cur->next; +c0104b2c: 8b 45 f4 mov -0xc(%ebp),%eax +c0104b2f: 8b 50 04 mov 0x4(%eax),%edx +c0104b32: 8b 45 f0 mov -0x10(%ebp),%eax +c0104b35: 89 50 04 mov %edx,0x4(%eax) + + if (cur + cur->units == b) { +c0104b38: 8b 45 f4 mov -0xc(%ebp),%eax +c0104b3b: 8b 00 mov (%eax),%eax +c0104b3d: 8d 14 c5 00 00 00 00 lea 0x0(,%eax,8),%edx +c0104b44: 8b 45 f4 mov -0xc(%ebp),%eax +c0104b47: 01 d0 add %edx,%eax +c0104b49: 39 45 f0 cmp %eax,-0x10(%ebp) +c0104b4c: 75 1f jne c0104b6d + cur->units += b->units; +c0104b4e: 8b 45 f4 mov -0xc(%ebp),%eax +c0104b51: 8b 10 mov (%eax),%edx +c0104b53: 8b 45 f0 mov -0x10(%ebp),%eax +c0104b56: 8b 00 mov (%eax),%eax +c0104b58: 01 c2 add %eax,%edx +c0104b5a: 8b 45 f4 mov -0xc(%ebp),%eax +c0104b5d: 89 10 mov %edx,(%eax) + cur->next = b->next; +c0104b5f: 8b 45 f0 mov -0x10(%ebp),%eax +c0104b62: 8b 50 04 mov 0x4(%eax),%edx +c0104b65: 8b 45 f4 mov -0xc(%ebp),%eax +c0104b68: 89 50 04 mov %edx,0x4(%eax) +c0104b6b: eb 09 jmp c0104b76 + } else + cur->next = b; +c0104b6d: 8b 45 f4 mov -0xc(%ebp),%eax +c0104b70: 8b 55 f0 mov -0x10(%ebp),%edx +c0104b73: 89 50 04 mov %edx,0x4(%eax) + + slobfree = cur; +c0104b76: 8b 45 f4 mov -0xc(%ebp),%eax +c0104b79: a3 e8 f9 12 c0 mov %eax,0xc012f9e8 + + spin_unlock_irqrestore(&slob_lock, flags); +c0104b7e: 8b 45 ec mov -0x14(%ebp),%eax +c0104b81: 89 04 24 mov %eax,(%esp) +c0104b84: e8 7a fb ff ff call c0104703 <__intr_restore> +c0104b89: eb 01 jmp c0104b8c + return; +c0104b8b: 90 nop +} +c0104b8c: 89 ec mov %ebp,%esp +c0104b8e: 5d pop %ebp +c0104b8f: c3 ret + +c0104b90 : + + + +void +slob_init(void) { +c0104b90: 55 push %ebp +c0104b91: 89 e5 mov %esp,%ebp +c0104b93: 83 ec 18 sub $0x18,%esp + cprintf("use SLOB allocator\n"); +c0104b96: c7 04 24 9a cd 10 c0 movl $0xc010cd9a,(%esp) +c0104b9d: e8 d6 b7 ff ff call c0100378 +} +c0104ba2: 90 nop +c0104ba3: 89 ec mov %ebp,%esp +c0104ba5: 5d pop %ebp +c0104ba6: c3 ret + +c0104ba7 : + +inline void +kmalloc_init(void) { +c0104ba7: 55 push %ebp +c0104ba8: 89 e5 mov %esp,%ebp +c0104baa: 83 ec 18 sub $0x18,%esp + slob_init(); +c0104bad: e8 de ff ff ff call c0104b90 + cprintf("kmalloc_init() succeeded!\n"); +c0104bb2: c7 04 24 ae cd 10 c0 movl $0xc010cdae,(%esp) +c0104bb9: e8 ba b7 ff ff call c0100378 +} +c0104bbe: 90 nop +c0104bbf: 89 ec mov %ebp,%esp +c0104bc1: 5d pop %ebp +c0104bc2: c3 ret + +c0104bc3 : + +size_t +slob_allocated(void) { +c0104bc3: 55 push %ebp +c0104bc4: 89 e5 mov %esp,%ebp + return 0; +c0104bc6: b8 00 00 00 00 mov $0x0,%eax +} +c0104bcb: 5d pop %ebp +c0104bcc: c3 ret + +c0104bcd : + +size_t +kallocated(void) { +c0104bcd: 55 push %ebp +c0104bce: 89 e5 mov %esp,%ebp + return slob_allocated(); +c0104bd0: e8 ee ff ff ff call c0104bc3 +} +c0104bd5: 5d pop %ebp +c0104bd6: c3 ret + +c0104bd7 : + +static int find_order(int size) +{ +c0104bd7: 55 push %ebp +c0104bd8: 89 e5 mov %esp,%ebp +c0104bda: 83 ec 10 sub $0x10,%esp + int order = 0; +c0104bdd: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + for ( ; size > 4096 ; size >>=1) +c0104be4: eb 06 jmp c0104bec + order++; +c0104be6: ff 45 fc incl -0x4(%ebp) + for ( ; size > 4096 ; size >>=1) +c0104be9: d1 7d 08 sarl 0x8(%ebp) +c0104bec: 81 7d 08 00 10 00 00 cmpl $0x1000,0x8(%ebp) +c0104bf3: 7f f1 jg c0104be6 + return order; +c0104bf5: 8b 45 fc mov -0x4(%ebp),%eax +} +c0104bf8: 89 ec mov %ebp,%esp +c0104bfa: 5d pop %ebp +c0104bfb: c3 ret + +c0104bfc <__kmalloc>: + +static void *__kmalloc(size_t size, gfp_t gfp) +{ +c0104bfc: 55 push %ebp +c0104bfd: 89 e5 mov %esp,%ebp +c0104bff: 83 ec 28 sub $0x28,%esp + slob_t *m; + bigblock_t *bb; + unsigned long flags; + + if (size < PAGE_SIZE - SLOB_UNIT) { +c0104c02: 81 7d 08 f7 0f 00 00 cmpl $0xff7,0x8(%ebp) +c0104c09: 77 3b ja c0104c46 <__kmalloc+0x4a> + m = slob_alloc(size + SLOB_UNIT, gfp, 0); +c0104c0b: 8b 45 08 mov 0x8(%ebp),%eax +c0104c0e: 8d 50 08 lea 0x8(%eax),%edx +c0104c11: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) +c0104c18: 00 +c0104c19: 8b 45 0c mov 0xc(%ebp),%eax +c0104c1c: 89 44 24 04 mov %eax,0x4(%esp) +c0104c20: 89 14 24 mov %edx,(%esp) +c0104c23: e8 79 fc ff ff call c01048a1 +c0104c28: 89 45 ec mov %eax,-0x14(%ebp) + return m ? (void *)(m + 1) : 0; +c0104c2b: 83 7d ec 00 cmpl $0x0,-0x14(%ebp) +c0104c2f: 74 0b je c0104c3c <__kmalloc+0x40> +c0104c31: 8b 45 ec mov -0x14(%ebp),%eax +c0104c34: 83 c0 08 add $0x8,%eax +c0104c37: e9 b0 00 00 00 jmp c0104cec <__kmalloc+0xf0> +c0104c3c: b8 00 00 00 00 mov $0x0,%eax +c0104c41: e9 a6 00 00 00 jmp c0104cec <__kmalloc+0xf0> + } + + bb = slob_alloc(sizeof(bigblock_t), gfp, 0); +c0104c46: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) +c0104c4d: 00 +c0104c4e: 8b 45 0c mov 0xc(%ebp),%eax +c0104c51: 89 44 24 04 mov %eax,0x4(%esp) +c0104c55: c7 04 24 0c 00 00 00 movl $0xc,(%esp) +c0104c5c: e8 40 fc ff ff call c01048a1 +c0104c61: 89 45 f4 mov %eax,-0xc(%ebp) + if (!bb) +c0104c64: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c0104c68: 75 07 jne c0104c71 <__kmalloc+0x75> + return 0; +c0104c6a: b8 00 00 00 00 mov $0x0,%eax +c0104c6f: eb 7b jmp c0104cec <__kmalloc+0xf0> + + bb->order = find_order(size); +c0104c71: 8b 45 08 mov 0x8(%ebp),%eax +c0104c74: 89 04 24 mov %eax,(%esp) +c0104c77: e8 5b ff ff ff call c0104bd7 +c0104c7c: 8b 55 f4 mov -0xc(%ebp),%edx +c0104c7f: 89 02 mov %eax,(%edx) + bb->pages = (void *)__slob_get_free_pages(gfp, bb->order); +c0104c81: 8b 45 f4 mov -0xc(%ebp),%eax +c0104c84: 8b 00 mov (%eax),%eax +c0104c86: 89 44 24 04 mov %eax,0x4(%esp) +c0104c8a: 8b 45 0c mov 0xc(%ebp),%eax +c0104c8d: 89 04 24 mov %eax,(%esp) +c0104c90: e8 99 fb ff ff call c010482e <__slob_get_free_pages> +c0104c95: 8b 55 f4 mov -0xc(%ebp),%edx +c0104c98: 89 42 04 mov %eax,0x4(%edx) + + if (bb->pages) { +c0104c9b: 8b 45 f4 mov -0xc(%ebp),%eax +c0104c9e: 8b 40 04 mov 0x4(%eax),%eax +c0104ca1: 85 c0 test %eax,%eax +c0104ca3: 74 2f je c0104cd4 <__kmalloc+0xd8> + spin_lock_irqsave(&block_lock, flags); +c0104ca5: e8 2d fa ff ff call c01046d7 <__intr_save> +c0104caa: 89 45 f0 mov %eax,-0x10(%ebp) + bb->next = bigblocks; +c0104cad: 8b 15 90 3f 1a c0 mov 0xc01a3f90,%edx +c0104cb3: 8b 45 f4 mov -0xc(%ebp),%eax +c0104cb6: 89 50 08 mov %edx,0x8(%eax) + bigblocks = bb; +c0104cb9: 8b 45 f4 mov -0xc(%ebp),%eax +c0104cbc: a3 90 3f 1a c0 mov %eax,0xc01a3f90 + spin_unlock_irqrestore(&block_lock, flags); +c0104cc1: 8b 45 f0 mov -0x10(%ebp),%eax +c0104cc4: 89 04 24 mov %eax,(%esp) +c0104cc7: e8 37 fa ff ff call c0104703 <__intr_restore> + return bb->pages; +c0104ccc: 8b 45 f4 mov -0xc(%ebp),%eax +c0104ccf: 8b 40 04 mov 0x4(%eax),%eax +c0104cd2: eb 18 jmp c0104cec <__kmalloc+0xf0> + } + + slob_free(bb, sizeof(bigblock_t)); +c0104cd4: c7 44 24 04 0c 00 00 movl $0xc,0x4(%esp) +c0104cdb: 00 +c0104cdc: 8b 45 f4 mov -0xc(%ebp),%eax +c0104cdf: 89 04 24 mov %eax,(%esp) +c0104ce2: e8 8d fd ff ff call c0104a74 + return 0; +c0104ce7: b8 00 00 00 00 mov $0x0,%eax +} +c0104cec: 89 ec mov %ebp,%esp +c0104cee: 5d pop %ebp +c0104cef: c3 ret + +c0104cf0 : + +void * +kmalloc(size_t size) +{ +c0104cf0: 55 push %ebp +c0104cf1: 89 e5 mov %esp,%ebp +c0104cf3: 83 ec 18 sub $0x18,%esp + return __kmalloc(size, 0); +c0104cf6: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) +c0104cfd: 00 +c0104cfe: 8b 45 08 mov 0x8(%ebp),%eax +c0104d01: 89 04 24 mov %eax,(%esp) +c0104d04: e8 f3 fe ff ff call c0104bfc <__kmalloc> +} +c0104d09: 89 ec mov %ebp,%esp +c0104d0b: 5d pop %ebp +c0104d0c: c3 ret + +c0104d0d : + + +void kfree(void *block) +{ +c0104d0d: 55 push %ebp +c0104d0e: 89 e5 mov %esp,%ebp +c0104d10: 83 ec 28 sub $0x28,%esp + bigblock_t *bb, **last = &bigblocks; +c0104d13: c7 45 f0 90 3f 1a c0 movl $0xc01a3f90,-0x10(%ebp) + unsigned long flags; + + if (!block) +c0104d1a: 83 7d 08 00 cmpl $0x0,0x8(%ebp) +c0104d1e: 0f 84 a3 00 00 00 je c0104dc7 + return; + + if (!((unsigned long)block & (PAGE_SIZE-1))) { +c0104d24: 8b 45 08 mov 0x8(%ebp),%eax +c0104d27: 25 ff 0f 00 00 and $0xfff,%eax +c0104d2c: 85 c0 test %eax,%eax +c0104d2e: 75 7f jne c0104daf + /* might be on the big block list */ + spin_lock_irqsave(&block_lock, flags); +c0104d30: e8 a2 f9 ff ff call c01046d7 <__intr_save> +c0104d35: 89 45 ec mov %eax,-0x14(%ebp) + for (bb = bigblocks; bb; last = &bb->next, bb = bb->next) { +c0104d38: a1 90 3f 1a c0 mov 0xc01a3f90,%eax +c0104d3d: 89 45 f4 mov %eax,-0xc(%ebp) +c0104d40: eb 5c jmp c0104d9e + if (bb->pages == block) { +c0104d42: 8b 45 f4 mov -0xc(%ebp),%eax +c0104d45: 8b 40 04 mov 0x4(%eax),%eax +c0104d48: 39 45 08 cmp %eax,0x8(%ebp) +c0104d4b: 75 3f jne c0104d8c + *last = bb->next; +c0104d4d: 8b 45 f4 mov -0xc(%ebp),%eax +c0104d50: 8b 50 08 mov 0x8(%eax),%edx +c0104d53: 8b 45 f0 mov -0x10(%ebp),%eax +c0104d56: 89 10 mov %edx,(%eax) + spin_unlock_irqrestore(&block_lock, flags); +c0104d58: 8b 45 ec mov -0x14(%ebp),%eax +c0104d5b: 89 04 24 mov %eax,(%esp) +c0104d5e: e8 a0 f9 ff ff call c0104703 <__intr_restore> + __slob_free_pages((unsigned long)block, bb->order); +c0104d63: 8b 45 f4 mov -0xc(%ebp),%eax +c0104d66: 8b 10 mov (%eax),%edx +c0104d68: 8b 45 08 mov 0x8(%ebp),%eax +c0104d6b: 89 54 24 04 mov %edx,0x4(%esp) +c0104d6f: 89 04 24 mov %eax,(%esp) +c0104d72: e8 f2 fa ff ff call c0104869 <__slob_free_pages> + slob_free(bb, sizeof(bigblock_t)); +c0104d77: c7 44 24 04 0c 00 00 movl $0xc,0x4(%esp) +c0104d7e: 00 +c0104d7f: 8b 45 f4 mov -0xc(%ebp),%eax +c0104d82: 89 04 24 mov %eax,(%esp) +c0104d85: e8 ea fc ff ff call c0104a74 + return; +c0104d8a: eb 3c jmp c0104dc8 + for (bb = bigblocks; bb; last = &bb->next, bb = bb->next) { +c0104d8c: 8b 45 f4 mov -0xc(%ebp),%eax +c0104d8f: 83 c0 08 add $0x8,%eax +c0104d92: 89 45 f0 mov %eax,-0x10(%ebp) +c0104d95: 8b 45 f4 mov -0xc(%ebp),%eax +c0104d98: 8b 40 08 mov 0x8(%eax),%eax +c0104d9b: 89 45 f4 mov %eax,-0xc(%ebp) +c0104d9e: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c0104da2: 75 9e jne c0104d42 + } + } + spin_unlock_irqrestore(&block_lock, flags); +c0104da4: 8b 45 ec mov -0x14(%ebp),%eax +c0104da7: 89 04 24 mov %eax,(%esp) +c0104daa: e8 54 f9 ff ff call c0104703 <__intr_restore> + } + + slob_free((slob_t *)block - 1, 0); +c0104daf: 8b 45 08 mov 0x8(%ebp),%eax +c0104db2: 83 e8 08 sub $0x8,%eax +c0104db5: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) +c0104dbc: 00 +c0104dbd: 89 04 24 mov %eax,(%esp) +c0104dc0: e8 af fc ff ff call c0104a74 + return; +c0104dc5: eb 01 jmp c0104dc8 + return; +c0104dc7: 90 nop +} +c0104dc8: 89 ec mov %ebp,%esp +c0104dca: 5d pop %ebp +c0104dcb: c3 ret + +c0104dcc : + + +unsigned int ksize(const void *block) +{ +c0104dcc: 55 push %ebp +c0104dcd: 89 e5 mov %esp,%ebp +c0104dcf: 83 ec 28 sub $0x28,%esp + bigblock_t *bb; + unsigned long flags; + + if (!block) +c0104dd2: 83 7d 08 00 cmpl $0x0,0x8(%ebp) +c0104dd6: 75 07 jne c0104ddf + return 0; +c0104dd8: b8 00 00 00 00 mov $0x0,%eax +c0104ddd: eb 6b jmp c0104e4a + + if (!((unsigned long)block & (PAGE_SIZE-1))) { +c0104ddf: 8b 45 08 mov 0x8(%ebp),%eax +c0104de2: 25 ff 0f 00 00 and $0xfff,%eax +c0104de7: 85 c0 test %eax,%eax +c0104de9: 75 54 jne c0104e3f + spin_lock_irqsave(&block_lock, flags); +c0104deb: e8 e7 f8 ff ff call c01046d7 <__intr_save> +c0104df0: 89 45 f0 mov %eax,-0x10(%ebp) + for (bb = bigblocks; bb; bb = bb->next) +c0104df3: a1 90 3f 1a c0 mov 0xc01a3f90,%eax +c0104df8: 89 45 f4 mov %eax,-0xc(%ebp) +c0104dfb: eb 31 jmp c0104e2e + if (bb->pages == block) { +c0104dfd: 8b 45 f4 mov -0xc(%ebp),%eax +c0104e00: 8b 40 04 mov 0x4(%eax),%eax +c0104e03: 39 45 08 cmp %eax,0x8(%ebp) +c0104e06: 75 1d jne c0104e25 + spin_unlock_irqrestore(&slob_lock, flags); +c0104e08: 8b 45 f0 mov -0x10(%ebp),%eax +c0104e0b: 89 04 24 mov %eax,(%esp) +c0104e0e: e8 f0 f8 ff ff call c0104703 <__intr_restore> + return PAGE_SIZE << bb->order; +c0104e13: 8b 45 f4 mov -0xc(%ebp),%eax +c0104e16: 8b 00 mov (%eax),%eax +c0104e18: ba 00 10 00 00 mov $0x1000,%edx +c0104e1d: 88 c1 mov %al,%cl +c0104e1f: d3 e2 shl %cl,%edx +c0104e21: 89 d0 mov %edx,%eax +c0104e23: eb 25 jmp c0104e4a + for (bb = bigblocks; bb; bb = bb->next) +c0104e25: 8b 45 f4 mov -0xc(%ebp),%eax +c0104e28: 8b 40 08 mov 0x8(%eax),%eax +c0104e2b: 89 45 f4 mov %eax,-0xc(%ebp) +c0104e2e: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c0104e32: 75 c9 jne c0104dfd + } + spin_unlock_irqrestore(&block_lock, flags); +c0104e34: 8b 45 f0 mov -0x10(%ebp),%eax +c0104e37: 89 04 24 mov %eax,(%esp) +c0104e3a: e8 c4 f8 ff ff call c0104703 <__intr_restore> + } + + return ((slob_t *)block - 1)->units * SLOB_UNIT; +c0104e3f: 8b 45 08 mov 0x8(%ebp),%eax +c0104e42: 83 e8 08 sub $0x8,%eax +c0104e45: 8b 00 mov (%eax),%eax +c0104e47: c1 e0 03 shl $0x3,%eax +} +c0104e4a: 89 ec mov %ebp,%esp +c0104e4c: 5d pop %ebp +c0104e4d: c3 ret + +c0104e4e : +page2ppn(struct Page *page) { +c0104e4e: 55 push %ebp +c0104e4f: 89 e5 mov %esp,%ebp + return page - pages; +c0104e51: 8b 15 a0 3f 1a c0 mov 0xc01a3fa0,%edx +c0104e57: 8b 45 08 mov 0x8(%ebp),%eax +c0104e5a: 29 d0 sub %edx,%eax +c0104e5c: c1 f8 05 sar $0x5,%eax +} +c0104e5f: 5d pop %ebp +c0104e60: c3 ret + +c0104e61 : +page2pa(struct Page *page) { +c0104e61: 55 push %ebp +c0104e62: 89 e5 mov %esp,%ebp +c0104e64: 83 ec 04 sub $0x4,%esp + return page2ppn(page) << PGSHIFT; +c0104e67: 8b 45 08 mov 0x8(%ebp),%eax +c0104e6a: 89 04 24 mov %eax,(%esp) +c0104e6d: e8 dc ff ff ff call c0104e4e +c0104e72: c1 e0 0c shl $0xc,%eax +} +c0104e75: 89 ec mov %ebp,%esp +c0104e77: 5d pop %ebp +c0104e78: c3 ret + +c0104e79 : +pa2page(uintptr_t pa) { +c0104e79: 55 push %ebp +c0104e7a: 89 e5 mov %esp,%ebp +c0104e7c: 83 ec 18 sub $0x18,%esp + if (PPN(pa) >= npage) { +c0104e7f: 8b 45 08 mov 0x8(%ebp),%eax +c0104e82: c1 e8 0c shr $0xc,%eax +c0104e85: 89 c2 mov %eax,%edx +c0104e87: a1 a4 3f 1a c0 mov 0xc01a3fa4,%eax +c0104e8c: 39 c2 cmp %eax,%edx +c0104e8e: 72 1c jb c0104eac + panic("pa2page called with invalid pa"); +c0104e90: c7 44 24 08 cc cd 10 movl $0xc010cdcc,0x8(%esp) +c0104e97: c0 +c0104e98: c7 44 24 04 5e 00 00 movl $0x5e,0x4(%esp) +c0104e9f: 00 +c0104ea0: c7 04 24 eb cd 10 c0 movl $0xc010cdeb,(%esp) +c0104ea7: e8 8f be ff ff call c0100d3b <__panic> + return &pages[PPN(pa)]; +c0104eac: 8b 15 a0 3f 1a c0 mov 0xc01a3fa0,%edx +c0104eb2: 8b 45 08 mov 0x8(%ebp),%eax +c0104eb5: c1 e8 0c shr $0xc,%eax +c0104eb8: c1 e0 05 shl $0x5,%eax +c0104ebb: 01 d0 add %edx,%eax +} +c0104ebd: 89 ec mov %ebp,%esp +c0104ebf: 5d pop %ebp +c0104ec0: c3 ret + +c0104ec1 : +page2kva(struct Page *page) { +c0104ec1: 55 push %ebp +c0104ec2: 89 e5 mov %esp,%ebp +c0104ec4: 83 ec 28 sub $0x28,%esp + return KADDR(page2pa(page)); +c0104ec7: 8b 45 08 mov 0x8(%ebp),%eax +c0104eca: 89 04 24 mov %eax,(%esp) +c0104ecd: e8 8f ff ff ff call c0104e61 +c0104ed2: 89 45 f4 mov %eax,-0xc(%ebp) +c0104ed5: 8b 45 f4 mov -0xc(%ebp),%eax +c0104ed8: c1 e8 0c shr $0xc,%eax +c0104edb: 89 45 f0 mov %eax,-0x10(%ebp) +c0104ede: a1 a4 3f 1a c0 mov 0xc01a3fa4,%eax +c0104ee3: 39 45 f0 cmp %eax,-0x10(%ebp) +c0104ee6: 72 23 jb c0104f0b +c0104ee8: 8b 45 f4 mov -0xc(%ebp),%eax +c0104eeb: 89 44 24 0c mov %eax,0xc(%esp) +c0104eef: c7 44 24 08 fc cd 10 movl $0xc010cdfc,0x8(%esp) +c0104ef6: c0 +c0104ef7: c7 44 24 04 65 00 00 movl $0x65,0x4(%esp) +c0104efe: 00 +c0104eff: c7 04 24 eb cd 10 c0 movl $0xc010cdeb,(%esp) +c0104f06: e8 30 be ff ff call c0100d3b <__panic> +c0104f0b: 8b 45 f4 mov -0xc(%ebp),%eax +c0104f0e: 2d 00 00 00 40 sub $0x40000000,%eax +} +c0104f13: 89 ec mov %ebp,%esp +c0104f15: 5d pop %ebp +c0104f16: c3 ret + +c0104f17 : +pte2page(pte_t pte) { +c0104f17: 55 push %ebp +c0104f18: 89 e5 mov %esp,%ebp +c0104f1a: 83 ec 18 sub $0x18,%esp + if (!(pte & PTE_P)) { +c0104f1d: 8b 45 08 mov 0x8(%ebp),%eax +c0104f20: 83 e0 01 and $0x1,%eax +c0104f23: 85 c0 test %eax,%eax +c0104f25: 75 1c jne c0104f43 + panic("pte2page called with invalid pte"); +c0104f27: c7 44 24 08 20 ce 10 movl $0xc010ce20,0x8(%esp) +c0104f2e: c0 +c0104f2f: c7 44 24 04 70 00 00 movl $0x70,0x4(%esp) +c0104f36: 00 +c0104f37: c7 04 24 eb cd 10 c0 movl $0xc010cdeb,(%esp) +c0104f3e: e8 f8 bd ff ff call c0100d3b <__panic> + return pa2page(PTE_ADDR(pte)); +c0104f43: 8b 45 08 mov 0x8(%ebp),%eax +c0104f46: 25 00 f0 ff ff and $0xfffff000,%eax +c0104f4b: 89 04 24 mov %eax,(%esp) +c0104f4e: e8 26 ff ff ff call c0104e79 +} +c0104f53: 89 ec mov %ebp,%esp +c0104f55: 5d pop %ebp +c0104f56: c3 ret + +c0104f57 : +pde2page(pde_t pde) { +c0104f57: 55 push %ebp +c0104f58: 89 e5 mov %esp,%ebp +c0104f5a: 83 ec 18 sub $0x18,%esp + return pa2page(PDE_ADDR(pde)); +c0104f5d: 8b 45 08 mov 0x8(%ebp),%eax +c0104f60: 25 00 f0 ff ff and $0xfffff000,%eax +c0104f65: 89 04 24 mov %eax,(%esp) +c0104f68: e8 0c ff ff ff call c0104e79 +} +c0104f6d: 89 ec mov %ebp,%esp +c0104f6f: 5d pop %ebp +c0104f70: c3 ret + +c0104f71 : +page_ref(struct Page *page) { +c0104f71: 55 push %ebp +c0104f72: 89 e5 mov %esp,%ebp + return page->ref; +c0104f74: 8b 45 08 mov 0x8(%ebp),%eax +c0104f77: 8b 00 mov (%eax),%eax +} +c0104f79: 5d pop %ebp +c0104f7a: c3 ret + +c0104f7b : +set_page_ref(struct Page *page, int val) { +c0104f7b: 55 push %ebp +c0104f7c: 89 e5 mov %esp,%ebp + page->ref = val; +c0104f7e: 8b 45 08 mov 0x8(%ebp),%eax +c0104f81: 8b 55 0c mov 0xc(%ebp),%edx +c0104f84: 89 10 mov %edx,(%eax) +} +c0104f86: 90 nop +c0104f87: 5d pop %ebp +c0104f88: c3 ret + +c0104f89 : + +static inline int +page_ref_inc(struct Page *page) { +c0104f89: 55 push %ebp +c0104f8a: 89 e5 mov %esp,%ebp + page->ref += 1; +c0104f8c: 8b 45 08 mov 0x8(%ebp),%eax +c0104f8f: 8b 00 mov (%eax),%eax +c0104f91: 8d 50 01 lea 0x1(%eax),%edx +c0104f94: 8b 45 08 mov 0x8(%ebp),%eax +c0104f97: 89 10 mov %edx,(%eax) + return page->ref; +c0104f99: 8b 45 08 mov 0x8(%ebp),%eax +c0104f9c: 8b 00 mov (%eax),%eax +} +c0104f9e: 5d pop %ebp +c0104f9f: c3 ret + +c0104fa0 : + +static inline int +page_ref_dec(struct Page *page) { +c0104fa0: 55 push %ebp +c0104fa1: 89 e5 mov %esp,%ebp + page->ref -= 1; +c0104fa3: 8b 45 08 mov 0x8(%ebp),%eax +c0104fa6: 8b 00 mov (%eax),%eax +c0104fa8: 8d 50 ff lea -0x1(%eax),%edx +c0104fab: 8b 45 08 mov 0x8(%ebp),%eax +c0104fae: 89 10 mov %edx,(%eax) + return page->ref; +c0104fb0: 8b 45 08 mov 0x8(%ebp),%eax +c0104fb3: 8b 00 mov (%eax),%eax +} +c0104fb5: 5d pop %ebp +c0104fb6: c3 ret + +c0104fb7 <__intr_save>: +__intr_save(void) { +c0104fb7: 55 push %ebp +c0104fb8: 89 e5 mov %esp,%ebp +c0104fba: 83 ec 18 sub $0x18,%esp + asm volatile ("pushfl; popl %0" : "=r" (eflags)); +c0104fbd: 9c pushf +c0104fbe: 58 pop %eax +c0104fbf: 89 45 f4 mov %eax,-0xc(%ebp) + return eflags; +c0104fc2: 8b 45 f4 mov -0xc(%ebp),%eax + if (read_eflags() & FL_IF) { +c0104fc5: 25 00 02 00 00 and $0x200,%eax +c0104fca: 85 c0 test %eax,%eax +c0104fcc: 74 0c je c0104fda <__intr_save+0x23> + intr_disable(); +c0104fce: e8 1e d0 ff ff call c0101ff1 + return 1; +c0104fd3: b8 01 00 00 00 mov $0x1,%eax +c0104fd8: eb 05 jmp c0104fdf <__intr_save+0x28> + return 0; +c0104fda: b8 00 00 00 00 mov $0x0,%eax +} +c0104fdf: 89 ec mov %ebp,%esp +c0104fe1: 5d pop %ebp +c0104fe2: c3 ret + +c0104fe3 <__intr_restore>: +__intr_restore(bool flag) { +c0104fe3: 55 push %ebp +c0104fe4: 89 e5 mov %esp,%ebp +c0104fe6: 83 ec 08 sub $0x8,%esp + if (flag) { +c0104fe9: 83 7d 08 00 cmpl $0x0,0x8(%ebp) +c0104fed: 74 05 je c0104ff4 <__intr_restore+0x11> + intr_enable(); +c0104fef: e8 f5 cf ff ff call c0101fe9 +} +c0104ff4: 90 nop +c0104ff5: 89 ec mov %ebp,%esp +c0104ff7: 5d pop %ebp +c0104ff8: c3 ret + +c0104ff9 : + * data/code segement registers for kernel. + * lgdt - 加载全局描述符表寄存器并重置内核的数据/代码段寄存器。 + * */ +//定义了一个静态内联函数 lgdt,接收一个指向伪描述符(struct pseudodesc)的指针 pd +static inline void +lgdt(struct pseudodesc *pd) { +c0104ff9: 55 push %ebp +c0104ffa: 89 e5 mov %esp,%ebp + //这行汇编代码使用 lgdt 指令加载 GDT。%0 被替换为指向 pd 的指针,告诉处理器 GDT 的地址。 + asm volatile ("lgdt (%0)" :: "r" (pd)); +c0104ffc: 8b 45 08 mov 0x8(%ebp),%eax +c0104fff: 0f 01 10 lgdtl (%eax) + asm volatile ("movw %%ax, %%gs" :: "a" (USER_DS));//将 USER_DS(用户数据段)的值移动到 gs 段寄存器。 +c0105002: b8 23 00 00 00 mov $0x23,%eax +c0105007: 8e e8 mov %eax,%gs + asm volatile ("movw %%ax, %%fs" :: "a" (USER_DS));//将 USER_DS 的值移动到 fs 段寄存器。 +c0105009: b8 23 00 00 00 mov $0x23,%eax +c010500e: 8e e0 mov %eax,%fs + asm volatile ("movw %%ax, %%es" :: "a" (KERNEL_DS));//将 KERNEL_DS(内核数据段)的值移动到 es 段寄存器。 +c0105010: b8 10 00 00 00 mov $0x10,%eax +c0105015: 8e c0 mov %eax,%es + asm volatile ("movw %%ax, %%ds" :: "a" (KERNEL_DS));//将 KERNEL_DS 的值移动到 ds 段寄存器 +c0105017: b8 10 00 00 00 mov $0x10,%eax +c010501c: 8e d8 mov %eax,%ds + asm volatile ("movw %%ax, %%ss" :: "a" (KERNEL_DS));//将 KERNEL_DS 的值移动到 ss 段寄存器 +c010501e: b8 10 00 00 00 mov $0x10,%eax +c0105023: 8e d0 mov %eax,%ss + // reload cs + //通过 ljmp 指令重新加载代码段寄存器 cs,并跳转到标签 1。 + asm volatile ("ljmp %0, $1f\n 1:\n" :: "i" (KERNEL_CS)); +c0105025: ea 2c 50 10 c0 08 00 ljmp $0x8,$0xc010502c +} +c010502c: 90 nop +c010502d: 5d pop %ebp +c010502e: c3 ret + +c010502f : + * load_esp0 - 修改默认任务状态段中的 ESP0,以便在从用户态陷入内核态时能够使用不同的内核栈。 + * */ +//uintptr_t esp0:这是新的堆栈指针,通常指向内核栈的顶部。 +//修改当前任务状态段(TSS)中的 ESP0 值。ESP0 是在从用户态切换到内核态时,CPU 使用的内核栈指针。 +void +load_esp0(uintptr_t esp0) { +c010502f: 55 push %ebp +c0105030: 89 e5 mov %esp,%ebp + ts.ts_esp0 = esp0; +c0105032: 8b 45 08 mov 0x8(%ebp),%eax +c0105035: a3 c4 3f 1a c0 mov %eax,0xc01a3fc4 +} +c010503a: 90 nop +c010503b: 5d pop %ebp +c010503c: c3 ret + +c010503d : + +/* gdt_init - initialize the default GDT and TSS */ +/* gdt_init - 初始化默认的 GDT 和 TSS */ +static void +gdt_init(void) { +c010503d: 55 push %ebp +c010503e: 89 e5 mov %esp,%ebp +c0105040: 83 ec 14 sub $0x14,%esp + // 设置启动内核栈和默认的 SS0 + // set boot kernel stack and default SS0 + load_esp0((uintptr_t)bootstacktop); +c0105043: b8 00 f0 12 c0 mov $0xc012f000,%eax +c0105048: 89 04 24 mov %eax,(%esp) +c010504b: e8 df ff ff ff call c010502f + ts.ts_ss0 = KERNEL_DS; +c0105050: 66 c7 05 c8 3f 1a c0 movw $0x10,0xc01a3fc8 +c0105057: 10 00 + // 初始化 GDT 中的 TSS 字段 + // initialize the TSS filed of the gdt + gdt[SEG_TSS] = SEGTSS(STS_T32A, (uintptr_t)&ts, sizeof(ts), DPL_KERNEL); +c0105059: 66 c7 05 48 fa 12 c0 movw $0x68,0xc012fa48 +c0105060: 68 00 +c0105062: b8 c0 3f 1a c0 mov $0xc01a3fc0,%eax +c0105067: 0f b7 c0 movzwl %ax,%eax +c010506a: 66 a3 4a fa 12 c0 mov %ax,0xc012fa4a +c0105070: b8 c0 3f 1a c0 mov $0xc01a3fc0,%eax +c0105075: c1 e8 10 shr $0x10,%eax +c0105078: a2 4c fa 12 c0 mov %al,0xc012fa4c +c010507d: 0f b6 05 4d fa 12 c0 movzbl 0xc012fa4d,%eax +c0105084: 24 f0 and $0xf0,%al +c0105086: 0c 09 or $0x9,%al +c0105088: a2 4d fa 12 c0 mov %al,0xc012fa4d +c010508d: 0f b6 05 4d fa 12 c0 movzbl 0xc012fa4d,%eax +c0105094: 24 ef and $0xef,%al +c0105096: a2 4d fa 12 c0 mov %al,0xc012fa4d +c010509b: 0f b6 05 4d fa 12 c0 movzbl 0xc012fa4d,%eax +c01050a2: 24 9f and $0x9f,%al +c01050a4: a2 4d fa 12 c0 mov %al,0xc012fa4d +c01050a9: 0f b6 05 4d fa 12 c0 movzbl 0xc012fa4d,%eax +c01050b0: 0c 80 or $0x80,%al +c01050b2: a2 4d fa 12 c0 mov %al,0xc012fa4d +c01050b7: 0f b6 05 4e fa 12 c0 movzbl 0xc012fa4e,%eax +c01050be: 24 f0 and $0xf0,%al +c01050c0: a2 4e fa 12 c0 mov %al,0xc012fa4e +c01050c5: 0f b6 05 4e fa 12 c0 movzbl 0xc012fa4e,%eax +c01050cc: 24 ef and $0xef,%al +c01050ce: a2 4e fa 12 c0 mov %al,0xc012fa4e +c01050d3: 0f b6 05 4e fa 12 c0 movzbl 0xc012fa4e,%eax +c01050da: 24 df and $0xdf,%al +c01050dc: a2 4e fa 12 c0 mov %al,0xc012fa4e +c01050e1: 0f b6 05 4e fa 12 c0 movzbl 0xc012fa4e,%eax +c01050e8: 0c 40 or $0x40,%al +c01050ea: a2 4e fa 12 c0 mov %al,0xc012fa4e +c01050ef: 0f b6 05 4e fa 12 c0 movzbl 0xc012fa4e,%eax +c01050f6: 24 7f and $0x7f,%al +c01050f8: a2 4e fa 12 c0 mov %al,0xc012fa4e +c01050fd: b8 c0 3f 1a c0 mov $0xc01a3fc0,%eax +c0105102: c1 e8 18 shr $0x18,%eax +c0105105: a2 4f fa 12 c0 mov %al,0xc012fa4f + // 使用lgdt加载全局描述符表,更新所有段寄存器 + // reload all segment registers + lgdt(&gdt_pd); +c010510a: c7 04 24 50 fa 12 c0 movl $0xc012fa50,(%esp) +c0105111: e8 e3 fe ff ff call c0104ff9 +c0105116: 66 c7 45 fe 28 00 movw $0x28,-0x2(%ebp) + asm volatile ("ltr %0" :: "r" (sel) : "memory"); +c010511c: 0f b7 45 fe movzwl -0x2(%ebp),%eax +c0105120: 0f 00 d8 ltr %ax +} +c0105123: 90 nop + // 加载 TSS,使 CPU 在进行特权级切换时能够正确使用 TSS。 + // load the TSS + ltr(GD_TSS); +} +c0105124: 90 nop +c0105125: 89 ec mov %ebp,%esp +c0105127: 5d pop %ebp +c0105128: c3 ret + +c0105129 : + +//init_pmm_manager - initialize a pmm_manager instance +//初始化一个 pmm_manager 实例 +static void +init_pmm_manager(void) { +c0105129: 55 push %ebp +c010512a: 89 e5 mov %esp,%ebp +c010512c: 83 ec 18 sub $0x18,%esp + //将 pmm_manager 指向默认的 PMM 管理器实例。 + pmm_manager = &default_pmm_manager; +c010512f: c7 05 ac 3f 1a c0 c0 movl $0xc010ccc0,0xc01a3fac +c0105136: cc 10 c0 + //使用 cprintf 打印当前内存管理器的名称。 + cprintf("memory management: %s\n", pmm_manager->name); +c0105139: a1 ac 3f 1a c0 mov 0xc01a3fac,%eax +c010513e: 8b 00 mov (%eax),%eax +c0105140: 89 44 24 04 mov %eax,0x4(%esp) +c0105144: c7 04 24 4c ce 10 c0 movl $0xc010ce4c,(%esp) +c010514b: e8 28 b2 ff ff call c0100378 + //调用 PMM 管理器的初始化函数,以设置和准备内存管理的相关数据结构。 + pmm_manager->init(); +c0105150: a1 ac 3f 1a c0 mov 0xc01a3fac,%eax +c0105155: 8b 40 04 mov 0x4(%eax),%eax +c0105158: ff d0 call *%eax +} +c010515a: 90 nop +c010515b: 89 ec mov %ebp,%esp +c010515d: 5d pop %ebp +c010515e: c3 ret + +c010515f : + +//init_memmap - call pmm->init_memmap to build Page struct for free memory +// init_memmap - 调用 pmm->init_memmap 构建空闲内存的 Page 结构 +//struct Page *base:指向内存页的基础地址。 size_t n:要初始化的页数。 +static void +init_memmap(struct Page *base, size_t n) { +c010515f: 55 push %ebp +c0105160: 89 e5 mov %esp,%ebp +c0105162: 83 ec 18 sub $0x18,%esp + pmm_manager->init_memmap(base, n); +c0105165: a1 ac 3f 1a c0 mov 0xc01a3fac,%eax +c010516a: 8b 40 08 mov 0x8(%eax),%eax +c010516d: 8b 55 0c mov 0xc(%ebp),%edx +c0105170: 89 54 24 04 mov %edx,0x4(%esp) +c0105174: 8b 55 08 mov 0x8(%ebp),%edx +c0105177: 89 14 24 mov %edx,(%esp) +c010517a: ff d0 call *%eax +} +c010517c: 90 nop +c010517d: 89 ec mov %ebp,%esp +c010517f: 5d pop %ebp +c0105180: c3 ret + +c0105181 : + +//alloc_pages - call pmm->alloc_pages to allocate a continuous n*PAGESIZE memory +// alloc_pages - 调用 pmm->alloc_pages 分配连续的 n*PAGESIZE 内存 +struct Page * +alloc_pages(size_t n) { +c0105181: 55 push %ebp +c0105182: 89 e5 mov %esp,%ebp +c0105184: 83 ec 28 sub $0x28,%esp + struct Page *page=NULL; +c0105187: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + bool intr_flag; + //使用 local_intr_save 保存当前的中断状态,以避免在分配内存时发生中断。 + while (1) + { + local_intr_save(intr_flag); +c010518e: e8 24 fe ff ff call c0104fb7 <__intr_save> +c0105193: 89 45 f0 mov %eax,-0x10(%ebp) + { + page = pmm_manager->alloc_pages(n);//尝试分配 n 个页面。 +c0105196: a1 ac 3f 1a c0 mov 0xc01a3fac,%eax +c010519b: 8b 40 0c mov 0xc(%eax),%eax +c010519e: 8b 55 08 mov 0x8(%ebp),%edx +c01051a1: 89 14 24 mov %edx,(%esp) +c01051a4: ff d0 call *%eax +c01051a6: 89 45 f4 mov %eax,-0xc(%ebp) + } + local_intr_restore(intr_flag); +c01051a9: 8b 45 f0 mov -0x10(%ebp),%eax +c01051ac: 89 04 24 mov %eax,(%esp) +c01051af: e8 2f fe ff ff call c0104fe3 <__intr_restore> + + if (page != NULL || n > 1 || swap_init_ok == 0) break; +c01051b4: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c01051b8: 75 2d jne c01051e7 +c01051ba: 83 7d 08 01 cmpl $0x1,0x8(%ebp) +c01051be: 77 27 ja c01051e7 +c01051c0: a1 44 40 1a c0 mov 0xc01a4044,%eax +c01051c5: 85 c0 test %eax,%eax +c01051c7: 74 1e je c01051e7 + + extern struct mm_struct *check_mm_struct; + //cprintf("page %x, call swap_out in alloc_pages %d\n",page, n); + swap_out(check_mm_struct, n, 0); +c01051c9: 8b 55 08 mov 0x8(%ebp),%edx +c01051cc: a1 0c 41 1a c0 mov 0xc01a410c,%eax +c01051d1: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) +c01051d8: 00 +c01051d9: 89 54 24 04 mov %edx,0x4(%esp) +c01051dd: 89 04 24 mov %eax,(%esp) +c01051e0: e8 38 1d 00 00 call c0106f1d + { +c01051e5: eb a7 jmp c010518e + } + //cprintf("n %d,get page %x, No %d in alloc_pages\n",n,page,(page-pages)); + return page; +c01051e7: 8b 45 f4 mov -0xc(%ebp),%eax +} +c01051ea: 89 ec mov %ebp,%esp +c01051ec: 5d pop %ebp +c01051ed: c3 ret + +c01051ee : + +//free_pages - call pmm->free_pages to free a continuous n*PAGESIZE memory +// free_pages - 调用 pmm->free_pages 释放连续的 n*PAGESIZE 内存 +//struct Page *base:指向要释放的内存页的基础地址。size_t n:要释放的页数。 +void +free_pages(struct Page *base, size_t n) { +c01051ee: 55 push %ebp +c01051ef: 89 e5 mov %esp,%ebp +c01051f1: 83 ec 28 sub $0x28,%esp + bool intr_flag; + //使用 local_intr_save 保存当前的中断状态,以避免在释放内存时发生中断。 + local_intr_save(intr_flag); +c01051f4: e8 be fd ff ff call c0104fb7 <__intr_save> +c01051f9: 89 45 f4 mov %eax,-0xc(%ebp) + { + //调用物理内存管理器的 free_pages 函数释放 n 页的内存。 + pmm_manager->free_pages(base, n); +c01051fc: a1 ac 3f 1a c0 mov 0xc01a3fac,%eax +c0105201: 8b 40 10 mov 0x10(%eax),%eax +c0105204: 8b 55 0c mov 0xc(%ebp),%edx +c0105207: 89 54 24 04 mov %edx,0x4(%esp) +c010520b: 8b 55 08 mov 0x8(%ebp),%edx +c010520e: 89 14 24 mov %edx,(%esp) +c0105211: ff d0 call *%eax + } + local_intr_restore(intr_flag); +c0105213: 8b 45 f4 mov -0xc(%ebp),%eax +c0105216: 89 04 24 mov %eax,(%esp) +c0105219: e8 c5 fd ff ff call c0104fe3 <__intr_restore> +} +c010521e: 90 nop +c010521f: 89 ec mov %ebp,%esp +c0105221: 5d pop %ebp +c0105222: c3 ret + +c0105223 : + +//nr_free_pages - call pmm->nr_free_pages to get the size (nr*PAGESIZE) +//of current free memory +// nr_free_pages - 调用 pmm->nr_free_pages 获取当前空闲内存的大小 (nr * PAGESIZE) +size_t +nr_free_pages(void) { +c0105223: 55 push %ebp +c0105224: 89 e5 mov %esp,%ebp +c0105226: 83 ec 28 sub $0x28,%esp + size_t ret;// 定义变量 ret 用于存储返回的空闲内存大小 + bool intr_flag;// 定义变量 intr_flag 用于保存中断状态 + local_intr_save(intr_flag);// 保存当前中断状态,并禁用中断 +c0105229: e8 89 fd ff ff call c0104fb7 <__intr_save> +c010522e: 89 45 f4 mov %eax,-0xc(%ebp) + { + ret = pmm_manager->nr_free_pages();// 调用物理内存管理器的函数获取空闲内存页数 +c0105231: a1 ac 3f 1a c0 mov 0xc01a3fac,%eax +c0105236: 8b 40 14 mov 0x14(%eax),%eax +c0105239: ff d0 call *%eax +c010523b: 89 45 f0 mov %eax,-0x10(%ebp) + } + local_intr_restore(intr_flag);// 恢复之前保存的中断状态 +c010523e: 8b 45 f4 mov -0xc(%ebp),%eax +c0105241: 89 04 24 mov %eax,(%esp) +c0105244: e8 9a fd ff ff call c0104fe3 <__intr_restore> + return ret;// 返回空闲内存的大小 +c0105249: 8b 45 f0 mov -0x10(%ebp),%eax +} +c010524c: 89 ec mov %ebp,%esp +c010524e: 5d pop %ebp +c010524f: c3 ret + +c0105250 : + +/* pmm_init - initialize the physical memory management */ +/* pmm_init - 初始化物理内存管理 */ +static void +page_init(void) { +c0105250: 55 push %ebp +c0105251: 89 e5 mov %esp,%ebp +c0105253: 57 push %edi +c0105254: 56 push %esi +c0105255: 53 push %ebx +c0105256: 81 ec 9c 00 00 00 sub $0x9c,%esp + // 获取物理内存映射信息,存于特定地址 + struct e820map *memmap = (struct e820map *)(0x8000 + KERNBASE); +c010525c: c7 45 c4 00 80 00 c0 movl $0xc0008000,-0x3c(%ebp) + uint64_t maxpa = 0;// 初始化最大物理地址为0 +c0105263: c7 45 e0 00 00 00 00 movl $0x0,-0x20(%ebp) +c010526a: c7 45 e4 00 00 00 00 movl $0x0,-0x1c(%ebp) + + cprintf("e820map:\n");// 打印“e820map”标题 +c0105271: c7 04 24 63 ce 10 c0 movl $0xc010ce63,(%esp) +c0105278: e8 fb b0 ff ff call c0100378 + int i; + for (i = 0; i < memmap->nr_map; i ++) {// 遍历内存映射数组 +c010527d: c7 45 dc 00 00 00 00 movl $0x0,-0x24(%ebp) +c0105284: e9 0c 01 00 00 jmp c0105395 + uint64_t begin = memmap->map[i].addr, end = begin + memmap->map[i].size;// 获取每个区域的起始和结束地址 +c0105289: 8b 4d c4 mov -0x3c(%ebp),%ecx +c010528c: 8b 55 dc mov -0x24(%ebp),%edx +c010528f: 89 d0 mov %edx,%eax +c0105291: c1 e0 02 shl $0x2,%eax +c0105294: 01 d0 add %edx,%eax +c0105296: c1 e0 02 shl $0x2,%eax +c0105299: 01 c8 add %ecx,%eax +c010529b: 8b 50 08 mov 0x8(%eax),%edx +c010529e: 8b 40 04 mov 0x4(%eax),%eax +c01052a1: 89 45 a0 mov %eax,-0x60(%ebp) +c01052a4: 89 55 a4 mov %edx,-0x5c(%ebp) +c01052a7: 8b 4d c4 mov -0x3c(%ebp),%ecx +c01052aa: 8b 55 dc mov -0x24(%ebp),%edx +c01052ad: 89 d0 mov %edx,%eax +c01052af: c1 e0 02 shl $0x2,%eax +c01052b2: 01 d0 add %edx,%eax +c01052b4: c1 e0 02 shl $0x2,%eax +c01052b7: 01 c8 add %ecx,%eax +c01052b9: 8b 48 0c mov 0xc(%eax),%ecx +c01052bc: 8b 58 10 mov 0x10(%eax),%ebx +c01052bf: 8b 45 a0 mov -0x60(%ebp),%eax +c01052c2: 8b 55 a4 mov -0x5c(%ebp),%edx +c01052c5: 01 c8 add %ecx,%eax +c01052c7: 11 da adc %ebx,%edx +c01052c9: 89 45 98 mov %eax,-0x68(%ebp) +c01052cc: 89 55 9c mov %edx,-0x64(%ebp) + cprintf(" memory: %08llx, [%08llx, %08llx], type = %d.\n",// 打印内存区域的信息 +c01052cf: 8b 4d c4 mov -0x3c(%ebp),%ecx +c01052d2: 8b 55 dc mov -0x24(%ebp),%edx +c01052d5: 89 d0 mov %edx,%eax +c01052d7: c1 e0 02 shl $0x2,%eax +c01052da: 01 d0 add %edx,%eax +c01052dc: c1 e0 02 shl $0x2,%eax +c01052df: 01 c8 add %ecx,%eax +c01052e1: 83 c0 14 add $0x14,%eax +c01052e4: 8b 00 mov (%eax),%eax +c01052e6: 89 85 7c ff ff ff mov %eax,-0x84(%ebp) +c01052ec: 8b 45 98 mov -0x68(%ebp),%eax +c01052ef: 8b 55 9c mov -0x64(%ebp),%edx +c01052f2: 83 c0 ff add $0xffffffff,%eax +c01052f5: 83 d2 ff adc $0xffffffff,%edx +c01052f8: 89 c6 mov %eax,%esi +c01052fa: 89 d7 mov %edx,%edi +c01052fc: 8b 4d c4 mov -0x3c(%ebp),%ecx +c01052ff: 8b 55 dc mov -0x24(%ebp),%edx +c0105302: 89 d0 mov %edx,%eax +c0105304: c1 e0 02 shl $0x2,%eax +c0105307: 01 d0 add %edx,%eax +c0105309: c1 e0 02 shl $0x2,%eax +c010530c: 01 c8 add %ecx,%eax +c010530e: 8b 48 0c mov 0xc(%eax),%ecx +c0105311: 8b 58 10 mov 0x10(%eax),%ebx +c0105314: 8b 85 7c ff ff ff mov -0x84(%ebp),%eax +c010531a: 89 44 24 1c mov %eax,0x1c(%esp) +c010531e: 89 74 24 14 mov %esi,0x14(%esp) +c0105322: 89 7c 24 18 mov %edi,0x18(%esp) +c0105326: 8b 45 a0 mov -0x60(%ebp),%eax +c0105329: 8b 55 a4 mov -0x5c(%ebp),%edx +c010532c: 89 44 24 0c mov %eax,0xc(%esp) +c0105330: 89 54 24 10 mov %edx,0x10(%esp) +c0105334: 89 4c 24 04 mov %ecx,0x4(%esp) +c0105338: 89 5c 24 08 mov %ebx,0x8(%esp) +c010533c: c7 04 24 70 ce 10 c0 movl $0xc010ce70,(%esp) +c0105343: e8 30 b0 ff ff call c0100378 + memmap->map[i].size, begin, end - 1, memmap->map[i].type); + if (memmap->map[i].type == E820_ARM) {// 检查内存类型是否为可用内存 +c0105348: 8b 4d c4 mov -0x3c(%ebp),%ecx +c010534b: 8b 55 dc mov -0x24(%ebp),%edx +c010534e: 89 d0 mov %edx,%eax +c0105350: c1 e0 02 shl $0x2,%eax +c0105353: 01 d0 add %edx,%eax +c0105355: c1 e0 02 shl $0x2,%eax +c0105358: 01 c8 add %ecx,%eax +c010535a: 83 c0 14 add $0x14,%eax +c010535d: 8b 00 mov (%eax),%eax +c010535f: 83 f8 01 cmp $0x1,%eax +c0105362: 75 2e jne c0105392 + if (maxpa < end && begin < KMEMSIZE) {// 检查当前区域是否在有效范围内 +c0105364: 8b 45 e0 mov -0x20(%ebp),%eax +c0105367: 8b 55 e4 mov -0x1c(%ebp),%edx +c010536a: 3b 45 98 cmp -0x68(%ebp),%eax +c010536d: 89 d0 mov %edx,%eax +c010536f: 1b 45 9c sbb -0x64(%ebp),%eax +c0105372: 73 1e jae c0105392 +c0105374: ba ff ff ff 37 mov $0x37ffffff,%edx +c0105379: b8 00 00 00 00 mov $0x0,%eax +c010537e: 3b 55 a0 cmp -0x60(%ebp),%edx +c0105381: 1b 45 a4 sbb -0x5c(%ebp),%eax +c0105384: 72 0c jb c0105392 + maxpa = end;// 更新最大物理地址 +c0105386: 8b 45 98 mov -0x68(%ebp),%eax +c0105389: 8b 55 9c mov -0x64(%ebp),%edx +c010538c: 89 45 e0 mov %eax,-0x20(%ebp) +c010538f: 89 55 e4 mov %edx,-0x1c(%ebp) + for (i = 0; i < memmap->nr_map; i ++) {// 遍历内存映射数组 +c0105392: ff 45 dc incl -0x24(%ebp) +c0105395: 8b 45 c4 mov -0x3c(%ebp),%eax +c0105398: 8b 00 mov (%eax),%eax +c010539a: 39 45 dc cmp %eax,-0x24(%ebp) +c010539d: 0f 8c e6 fe ff ff jl c0105289 + } + } + } + if (maxpa > KMEMSIZE) {// 如果最大物理地址超过了预定义的内存上限 +c01053a3: ba 00 00 00 38 mov $0x38000000,%edx +c01053a8: b8 00 00 00 00 mov $0x0,%eax +c01053ad: 3b 55 e0 cmp -0x20(%ebp),%edx +c01053b0: 1b 45 e4 sbb -0x1c(%ebp),%eax +c01053b3: 73 0e jae c01053c3 + maxpa = KMEMSIZE;// 将其限制为内存上限 +c01053b5: c7 45 e0 00 00 00 38 movl $0x38000000,-0x20(%ebp) +c01053bc: c7 45 e4 00 00 00 00 movl $0x0,-0x1c(%ebp) + } + + extern char end[];// 引入全局变量 end,指向内存的结束位置 + + npage = maxpa / PGSIZE;// 计算可用页数 +c01053c3: 8b 45 e0 mov -0x20(%ebp),%eax +c01053c6: 8b 55 e4 mov -0x1c(%ebp),%edx +c01053c9: 0f ac d0 0c shrd $0xc,%edx,%eax +c01053cd: c1 ea 0c shr $0xc,%edx +c01053d0: a3 a4 3f 1a c0 mov %eax,0xc01a3fa4 + pages = (struct Page *)ROUNDUP((void *)end, PGSIZE);// 将 end 对齐到页边界,指向页结构数组的开头 +c01053d5: c7 45 c0 00 10 00 00 movl $0x1000,-0x40(%ebp) +c01053dc: b8 54 61 1a c0 mov $0xc01a6154,%eax +c01053e1: 8d 50 ff lea -0x1(%eax),%edx +c01053e4: 8b 45 c0 mov -0x40(%ebp),%eax +c01053e7: 01 d0 add %edx,%eax +c01053e9: 89 45 bc mov %eax,-0x44(%ebp) +c01053ec: 8b 45 bc mov -0x44(%ebp),%eax +c01053ef: ba 00 00 00 00 mov $0x0,%edx +c01053f4: f7 75 c0 divl -0x40(%ebp) +c01053f7: 8b 45 bc mov -0x44(%ebp),%eax +c01053fa: 29 d0 sub %edx,%eax +c01053fc: a3 a0 3f 1a c0 mov %eax,0xc01a3fa0 + + for (i = 0; i < npage; i ++) {// 遍历每一页 +c0105401: c7 45 dc 00 00 00 00 movl $0x0,-0x24(%ebp) +c0105408: eb 28 jmp c0105432 + SetPageReserved(pages + i);// 将每一页标记为保留状态 +c010540a: 8b 15 a0 3f 1a c0 mov 0xc01a3fa0,%edx +c0105410: 8b 45 dc mov -0x24(%ebp),%eax +c0105413: c1 e0 05 shl $0x5,%eax +c0105416: 01 d0 add %edx,%eax +c0105418: 83 c0 04 add $0x4,%eax +c010541b: c7 45 94 00 00 00 00 movl $0x0,-0x6c(%ebp) +c0105422: 89 45 90 mov %eax,-0x70(%ebp) + asm volatile ("btsl %1, %0" :"=m" (*(volatile long *)addr) : "Ir" (nr)); +c0105425: 8b 45 90 mov -0x70(%ebp),%eax +c0105428: 8b 55 94 mov -0x6c(%ebp),%edx +c010542b: 0f ab 10 bts %edx,(%eax) +} +c010542e: 90 nop + for (i = 0; i < npage; i ++) {// 遍历每一页 +c010542f: ff 45 dc incl -0x24(%ebp) +c0105432: 8b 55 dc mov -0x24(%ebp),%edx +c0105435: a1 a4 3f 1a c0 mov 0xc01a3fa4,%eax +c010543a: 39 c2 cmp %eax,%edx +c010543c: 72 cc jb c010540a + } + + uintptr_t freemem = PADDR((uintptr_t)pages + sizeof(struct Page) * npage);// 计算可用内存的起始地址 +c010543e: a1 a4 3f 1a c0 mov 0xc01a3fa4,%eax +c0105443: c1 e0 05 shl $0x5,%eax +c0105446: 89 c2 mov %eax,%edx +c0105448: a1 a0 3f 1a c0 mov 0xc01a3fa0,%eax +c010544d: 01 d0 add %edx,%eax +c010544f: 89 45 b8 mov %eax,-0x48(%ebp) +c0105452: 81 7d b8 ff ff ff bf cmpl $0xbfffffff,-0x48(%ebp) +c0105459: 77 23 ja c010547e +c010545b: 8b 45 b8 mov -0x48(%ebp),%eax +c010545e: 89 44 24 0c mov %eax,0xc(%esp) +c0105462: c7 44 24 08 a0 ce 10 movl $0xc010cea0,0x8(%esp) +c0105469: c0 +c010546a: c7 44 24 04 1a 01 00 movl $0x11a,0x4(%esp) +c0105471: 00 +c0105472: c7 04 24 c4 ce 10 c0 movl $0xc010cec4,(%esp) +c0105479: e8 bd b8 ff ff call c0100d3b <__panic> +c010547e: 8b 45 b8 mov -0x48(%ebp),%eax +c0105481: 05 00 00 00 40 add $0x40000000,%eax +c0105486: 89 45 b4 mov %eax,-0x4c(%ebp) + + for (i = 0; i < memmap->nr_map; i ++) {// 再次遍历内存映射 +c0105489: c7 45 dc 00 00 00 00 movl $0x0,-0x24(%ebp) +c0105490: e9 53 01 00 00 jmp c01055e8 + uint64_t begin = memmap->map[i].addr, end = begin + memmap->map[i].size;// 获取每个区域的起始和结束地址 +c0105495: 8b 4d c4 mov -0x3c(%ebp),%ecx +c0105498: 8b 55 dc mov -0x24(%ebp),%edx +c010549b: 89 d0 mov %edx,%eax +c010549d: c1 e0 02 shl $0x2,%eax +c01054a0: 01 d0 add %edx,%eax +c01054a2: c1 e0 02 shl $0x2,%eax +c01054a5: 01 c8 add %ecx,%eax +c01054a7: 8b 50 08 mov 0x8(%eax),%edx +c01054aa: 8b 40 04 mov 0x4(%eax),%eax +c01054ad: 89 45 d0 mov %eax,-0x30(%ebp) +c01054b0: 89 55 d4 mov %edx,-0x2c(%ebp) +c01054b3: 8b 4d c4 mov -0x3c(%ebp),%ecx +c01054b6: 8b 55 dc mov -0x24(%ebp),%edx +c01054b9: 89 d0 mov %edx,%eax +c01054bb: c1 e0 02 shl $0x2,%eax +c01054be: 01 d0 add %edx,%eax +c01054c0: c1 e0 02 shl $0x2,%eax +c01054c3: 01 c8 add %ecx,%eax +c01054c5: 8b 48 0c mov 0xc(%eax),%ecx +c01054c8: 8b 58 10 mov 0x10(%eax),%ebx +c01054cb: 8b 45 d0 mov -0x30(%ebp),%eax +c01054ce: 8b 55 d4 mov -0x2c(%ebp),%edx +c01054d1: 01 c8 add %ecx,%eax +c01054d3: 11 da adc %ebx,%edx +c01054d5: 89 45 c8 mov %eax,-0x38(%ebp) +c01054d8: 89 55 cc mov %edx,-0x34(%ebp) + if (memmap->map[i].type == E820_ARM) {// 如果区域类型为可用内存 +c01054db: 8b 4d c4 mov -0x3c(%ebp),%ecx +c01054de: 8b 55 dc mov -0x24(%ebp),%edx +c01054e1: 89 d0 mov %edx,%eax +c01054e3: c1 e0 02 shl $0x2,%eax +c01054e6: 01 d0 add %edx,%eax +c01054e8: c1 e0 02 shl $0x2,%eax +c01054eb: 01 c8 add %ecx,%eax +c01054ed: 83 c0 14 add $0x14,%eax +c01054f0: 8b 00 mov (%eax),%eax +c01054f2: 83 f8 01 cmp $0x1,%eax +c01054f5: 0f 85 ea 00 00 00 jne c01055e5 + if (begin < freemem) {// 如果起始地址小于可用内存地址 +c01054fb: 8b 45 b4 mov -0x4c(%ebp),%eax +c01054fe: ba 00 00 00 00 mov $0x0,%edx +c0105503: 8b 4d d4 mov -0x2c(%ebp),%ecx +c0105506: 39 45 d0 cmp %eax,-0x30(%ebp) +c0105509: 19 d1 sbb %edx,%ecx +c010550b: 73 0d jae c010551a + begin = freemem;//将起始地址设置为可用内存地址 +c010550d: 8b 45 b4 mov -0x4c(%ebp),%eax +c0105510: 89 45 d0 mov %eax,-0x30(%ebp) +c0105513: c7 45 d4 00 00 00 00 movl $0x0,-0x2c(%ebp) + } + if (end > KMEMSIZE) {// 如果结束地址超过内存上限 +c010551a: ba 00 00 00 38 mov $0x38000000,%edx +c010551f: b8 00 00 00 00 mov $0x0,%eax +c0105524: 3b 55 c8 cmp -0x38(%ebp),%edx +c0105527: 1b 45 cc sbb -0x34(%ebp),%eax +c010552a: 73 0e jae c010553a + end = KMEMSIZE;// 将其限制为内存上限 +c010552c: c7 45 c8 00 00 00 38 movl $0x38000000,-0x38(%ebp) +c0105533: c7 45 cc 00 00 00 00 movl $0x0,-0x34(%ebp) + } + if (begin < end) {// 如果起始地址小于结束地址 +c010553a: 8b 45 d0 mov -0x30(%ebp),%eax +c010553d: 8b 55 d4 mov -0x2c(%ebp),%edx +c0105540: 3b 45 c8 cmp -0x38(%ebp),%eax +c0105543: 89 d0 mov %edx,%eax +c0105545: 1b 45 cc sbb -0x34(%ebp),%eax +c0105548: 0f 83 97 00 00 00 jae c01055e5 + begin = ROUNDUP(begin, PGSIZE);// 将起始地址对齐到页边界 +c010554e: c7 45 b0 00 10 00 00 movl $0x1000,-0x50(%ebp) +c0105555: 8b 55 d0 mov -0x30(%ebp),%edx +c0105558: 8b 45 b0 mov -0x50(%ebp),%eax +c010555b: 01 d0 add %edx,%eax +c010555d: 48 dec %eax +c010555e: 89 45 ac mov %eax,-0x54(%ebp) +c0105561: 8b 45 ac mov -0x54(%ebp),%eax +c0105564: ba 00 00 00 00 mov $0x0,%edx +c0105569: f7 75 b0 divl -0x50(%ebp) +c010556c: 8b 45 ac mov -0x54(%ebp),%eax +c010556f: 29 d0 sub %edx,%eax +c0105571: ba 00 00 00 00 mov $0x0,%edx +c0105576: 89 45 d0 mov %eax,-0x30(%ebp) +c0105579: 89 55 d4 mov %edx,-0x2c(%ebp) + end = ROUNDDOWN(end, PGSIZE);// 将结束地址对齐到页边界 +c010557c: 8b 45 c8 mov -0x38(%ebp),%eax +c010557f: 89 45 a8 mov %eax,-0x58(%ebp) +c0105582: 8b 45 a8 mov -0x58(%ebp),%eax +c0105585: ba 00 00 00 00 mov $0x0,%edx +c010558a: 89 c7 mov %eax,%edi +c010558c: 81 e7 00 f0 ff ff and $0xfffff000,%edi +c0105592: 89 7d 80 mov %edi,-0x80(%ebp) +c0105595: 89 d0 mov %edx,%eax +c0105597: 83 e0 00 and $0x0,%eax +c010559a: 89 45 84 mov %eax,-0x7c(%ebp) +c010559d: 8b 45 80 mov -0x80(%ebp),%eax +c01055a0: 8b 55 84 mov -0x7c(%ebp),%edx +c01055a3: 89 45 c8 mov %eax,-0x38(%ebp) +c01055a6: 89 55 cc mov %edx,-0x34(%ebp) + if (begin < end) {// 如果调整后的起始地址仍小于结束地址 +c01055a9: 8b 45 d0 mov -0x30(%ebp),%eax +c01055ac: 8b 55 d4 mov -0x2c(%ebp),%edx +c01055af: 3b 45 c8 cmp -0x38(%ebp),%eax +c01055b2: 89 d0 mov %edx,%eax +c01055b4: 1b 45 cc sbb -0x34(%ebp),%eax +c01055b7: 73 2c jae c01055e5 + init_memmap(pa2page(begin), (end - begin) / PGSIZE);// 初始化内存页映射 +c01055b9: 8b 45 c8 mov -0x38(%ebp),%eax +c01055bc: 8b 55 cc mov -0x34(%ebp),%edx +c01055bf: 2b 45 d0 sub -0x30(%ebp),%eax +c01055c2: 1b 55 d4 sbb -0x2c(%ebp),%edx +c01055c5: 0f ac d0 0c shrd $0xc,%edx,%eax +c01055c9: c1 ea 0c shr $0xc,%edx +c01055cc: 89 c3 mov %eax,%ebx +c01055ce: 8b 45 d0 mov -0x30(%ebp),%eax +c01055d1: 89 04 24 mov %eax,(%esp) +c01055d4: e8 a0 f8 ff ff call c0104e79 +c01055d9: 89 5c 24 04 mov %ebx,0x4(%esp) +c01055dd: 89 04 24 mov %eax,(%esp) +c01055e0: e8 7a fb ff ff call c010515f + for (i = 0; i < memmap->nr_map; i ++) {// 再次遍历内存映射 +c01055e5: ff 45 dc incl -0x24(%ebp) +c01055e8: 8b 45 c4 mov -0x3c(%ebp),%eax +c01055eb: 8b 00 mov (%eax),%eax +c01055ed: 39 45 dc cmp %eax,-0x24(%ebp) +c01055f0: 0f 8c 9f fe ff ff jl c0105495 + } + } + } + } +} +c01055f6: 90 nop +c01055f7: 90 nop +c01055f8: 81 c4 9c 00 00 00 add $0x9c,%esp +c01055fe: 5b pop %ebx +c01055ff: 5e pop %esi +c0105600: 5f pop %edi +c0105601: 5d pop %ebp +c0105602: c3 ret + +c0105603 : +//la: 需要映射的线性地址(经过 x86 段映射后的地址) +// size: memory size size: 内存大小 +// pa: physical address of this memory pa:该内存的物理地址 +// perm: permission of this memory perm: 该内存的权限 +static void +boot_map_segment(pde_t *pgdir, uintptr_t la, size_t size, uintptr_t pa, uint32_t perm) { +c0105603: 55 push %ebp +c0105604: 89 e5 mov %esp,%ebp +c0105606: 83 ec 38 sub $0x38,%esp + // 确保线性地址和物理地址的页偏移相同 + assert(PGOFF(la) == PGOFF(pa)); +c0105609: 8b 45 0c mov 0xc(%ebp),%eax +c010560c: 33 45 14 xor 0x14(%ebp),%eax +c010560f: 25 ff 0f 00 00 and $0xfff,%eax +c0105614: 85 c0 test %eax,%eax +c0105616: 74 24 je c010563c +c0105618: c7 44 24 0c d2 ce 10 movl $0xc010ced2,0xc(%esp) +c010561f: c0 +c0105620: c7 44 24 08 e9 ce 10 movl $0xc010cee9,0x8(%esp) +c0105627: c0 +c0105628: c7 44 24 04 3b 01 00 movl $0x13b,0x4(%esp) +c010562f: 00 +c0105630: c7 04 24 c4 ce 10 c0 movl $0xc010cec4,(%esp) +c0105637: e8 ff b6 ff ff call c0100d3b <__panic> + // 计算需要映射的页数,ROUNDUP 将总大小对齐到下一个页大小的边界 + size_t n = ROUNDUP(size + PGOFF(la), PGSIZE) / PGSIZE; +c010563c: c7 45 f0 00 10 00 00 movl $0x1000,-0x10(%ebp) +c0105643: 8b 45 0c mov 0xc(%ebp),%eax +c0105646: 25 ff 0f 00 00 and $0xfff,%eax +c010564b: 89 c2 mov %eax,%edx +c010564d: 8b 45 10 mov 0x10(%ebp),%eax +c0105650: 01 c2 add %eax,%edx +c0105652: 8b 45 f0 mov -0x10(%ebp),%eax +c0105655: 01 d0 add %edx,%eax +c0105657: 48 dec %eax +c0105658: 89 45 ec mov %eax,-0x14(%ebp) +c010565b: 8b 45 ec mov -0x14(%ebp),%eax +c010565e: ba 00 00 00 00 mov $0x0,%edx +c0105663: f7 75 f0 divl -0x10(%ebp) +c0105666: 8b 45 ec mov -0x14(%ebp),%eax +c0105669: 29 d0 sub %edx,%eax +c010566b: c1 e8 0c shr $0xc,%eax +c010566e: 89 45 f4 mov %eax,-0xc(%ebp) + // 将线性地址向下对齐到页边界 + la = ROUNDDOWN(la, PGSIZE); +c0105671: 8b 45 0c mov 0xc(%ebp),%eax +c0105674: 89 45 e8 mov %eax,-0x18(%ebp) +c0105677: 8b 45 e8 mov -0x18(%ebp),%eax +c010567a: 25 00 f0 ff ff and $0xfffff000,%eax +c010567f: 89 45 0c mov %eax,0xc(%ebp) + // 将物理地址向下对齐到页边界 + pa = ROUNDDOWN(pa, PGSIZE); +c0105682: 8b 45 14 mov 0x14(%ebp),%eax +c0105685: 89 45 e4 mov %eax,-0x1c(%ebp) +c0105688: 8b 45 e4 mov -0x1c(%ebp),%eax +c010568b: 25 00 f0 ff ff and $0xfffff000,%eax +c0105690: 89 45 14 mov %eax,0x14(%ebp) + // 循环遍历每一页,直到映射的页数为零 + for (; n > 0; n --, la += PGSIZE, pa += PGSIZE) { +c0105693: eb 68 jmp c01056fd + // 获取当前页的页表项指针,如果不存在则创建新的页表项 + pte_t *ptep = get_pte(pgdir, la, 1); +c0105695: c7 44 24 08 01 00 00 movl $0x1,0x8(%esp) +c010569c: 00 +c010569d: 8b 45 0c mov 0xc(%ebp),%eax +c01056a0: 89 44 24 04 mov %eax,0x4(%esp) +c01056a4: 8b 45 08 mov 0x8(%ebp),%eax +c01056a7: 89 04 24 mov %eax,(%esp) +c01056aa: e8 8d 01 00 00 call c010583c +c01056af: 89 45 e0 mov %eax,-0x20(%ebp) + // 确保页表项指针不为空 + assert(ptep != NULL); +c01056b2: 83 7d e0 00 cmpl $0x0,-0x20(%ebp) +c01056b6: 75 24 jne c01056dc +c01056b8: c7 44 24 0c fe ce 10 movl $0xc010cefe,0xc(%esp) +c01056bf: c0 +c01056c0: c7 44 24 08 e9 ce 10 movl $0xc010cee9,0x8(%esp) +c01056c7: c0 +c01056c8: c7 44 24 04 47 01 00 movl $0x147,0x4(%esp) +c01056cf: 00 +c01056d0: c7 04 24 c4 ce 10 c0 movl $0xc010cec4,(%esp) +c01056d7: e8 5f b6 ff ff call c0100d3b <__panic> + // 设置页表项,包含物理地址、存在位和权限 + *ptep = pa | PTE_P | perm; +c01056dc: 8b 45 14 mov 0x14(%ebp),%eax +c01056df: 0b 45 18 or 0x18(%ebp),%eax +c01056e2: 83 c8 01 or $0x1,%eax +c01056e5: 89 c2 mov %eax,%edx +c01056e7: 8b 45 e0 mov -0x20(%ebp),%eax +c01056ea: 89 10 mov %edx,(%eax) + for (; n > 0; n --, la += PGSIZE, pa += PGSIZE) { +c01056ec: ff 4d f4 decl -0xc(%ebp) +c01056ef: 81 45 0c 00 10 00 00 addl $0x1000,0xc(%ebp) +c01056f6: 81 45 14 00 10 00 00 addl $0x1000,0x14(%ebp) +c01056fd: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c0105701: 75 92 jne c0105695 + } +} +c0105703: 90 nop +c0105704: 90 nop +c0105705: 89 ec mov %ebp,%esp +c0105707: 5d pop %ebp +c0105708: c3 ret + +c0105709 : +// return value: the kernel virtual address of this allocated page +//note: this function is used to get the memory for PDT(Page Directory Table)&PT(Page Table) +//boot_alloc_page - 使用 pmm->alloc_pages(1) 分配一页内存.返回值: 分配的页面的内核虚拟地址 +//注意: 此函数用于获取页目录表(PDT)和页表(PT)的内存 +static void * +boot_alloc_page(void) { +c0105709: 55 push %ebp +c010570a: 89 e5 mov %esp,%ebp +c010570c: 83 ec 28 sub $0x28,%esp + struct Page *p = alloc_page();// 调用分配页面的函数 +c010570f: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c0105716: e8 66 fa ff ff call c0105181 +c010571b: 89 45 f4 mov %eax,-0xc(%ebp) + if (p == NULL) {// 检查分配是否成功 +c010571e: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c0105722: 75 1c jne c0105740 + panic("boot_alloc_page failed.\n");// 如果分配失败,则触发异常 +c0105724: c7 44 24 08 0b cf 10 movl $0xc010cf0b,0x8(%esp) +c010572b: c0 +c010572c: c7 44 24 04 56 01 00 movl $0x156,0x4(%esp) +c0105733: 00 +c0105734: c7 04 24 c4 ce 10 c0 movl $0xc010cec4,(%esp) +c010573b: e8 fb b5 ff ff call c0100d3b <__panic> + } + return page2kva(p);// 返回分配页面的内核虚拟地址 +c0105740: 8b 45 f4 mov -0xc(%ebp),%eax +c0105743: 89 04 24 mov %eax,(%esp) +c0105746: e8 76 f7 ff ff call c0104ec1 +} +c010574b: 89 ec mov %ebp,%esp +c010574d: 5d pop %ebp +c010574e: c3 ret + +c010574f : +//pmm_init - setup a pmm to manage physical memory, build PDT&PT to setup paging mechanism +// - check the correctness of pmm & paging mechanism, print PDT&PT +//pmm_init - 设置物理内存管理器,构建页目录表(PDT)和页表(PT),以设置分页机制 +// - 检查物理内存管理器和分页机制的正确性,打印页目录表和页表 +void +pmm_init(void) { +c010574f: 55 push %ebp +c0105750: 89 e5 mov %esp,%ebp +c0105752: 83 ec 38 sub $0x38,%esp + // We've already enabled paging + // 我们已经启用了分页 + boot_cr3 = PADDR(boot_pgdir); +c0105755: a1 00 fa 12 c0 mov 0xc012fa00,%eax +c010575a: 89 45 f4 mov %eax,-0xc(%ebp) +c010575d: 81 7d f4 ff ff ff bf cmpl $0xbfffffff,-0xc(%ebp) +c0105764: 77 23 ja c0105789 +c0105766: 8b 45 f4 mov -0xc(%ebp),%eax +c0105769: 89 44 24 0c mov %eax,0xc(%esp) +c010576d: c7 44 24 08 a0 ce 10 movl $0xc010cea0,0x8(%esp) +c0105774: c0 +c0105775: c7 44 24 04 63 01 00 movl $0x163,0x4(%esp) +c010577c: 00 +c010577d: c7 04 24 c4 ce 10 c0 movl $0xc010cec4,(%esp) +c0105784: e8 b2 b5 ff ff call c0100d3b <__panic> +c0105789: 8b 45 f4 mov -0xc(%ebp),%eax +c010578c: 05 00 00 00 40 add $0x40000000,%eax +c0105791: a3 a8 3f 1a c0 mov %eax,0xc01a3fa8 + // 我们需要分配/释放物理内存(粒度为 4KB 或其他大小)。 + // 因此在 pmm.h 中定义了物理内存管理器的框架(struct pmm_manager)。 + // 首先,我们应该基于该框架初始化一个物理内存管理器(pmm)。 + // 然后 pmm 可以分配/释放物理内存。 + // 现在,first_fit/best_fit/worst_fit/buddy_system 的 pmm 都可用。 + init_pmm_manager();// 初始化物理内存管理器 +c0105796: e8 8e f9 ff ff call c0105129 + + // detect physical memory space, reserve already used memory, + // then use pmm->init_memmap to create free page list + // 检测物理内存空间,保留已经使用的内存, + // 然后使用 pmm->init_memmap 创建空闲页面列表 + page_init();// 初始化页面管理 +c010579b: e8 b0 fa ff ff call c0105250 + + //use pmm->check to verify the correctness of the alloc/free function in a pmm + // 使用 pmm->check 验证 pmm 中分配/释放函数的正确性 + check_alloc_page();// 检查页面分配功能 +c01057a0: e8 ee 08 00 00 call c0106093 + + check_pgdir();// 检查页目录的状态 +c01057a5: e8 0a 09 00 00 call c01060b4 + + // recursively insert boot_pgdir in itself + // to form a virtual page table at virtual address VPT + // 递归地将 boot_pgdir 插入到自身中 + // 在虚拟地址 VPT 处形成虚拟页表 + boot_pgdir[PDX(VPT)] = PADDR(boot_pgdir) | PTE_P | PTE_W;// 设置页目录项,映射自身 +c01057aa: a1 00 fa 12 c0 mov 0xc012fa00,%eax +c01057af: 89 45 f0 mov %eax,-0x10(%ebp) +c01057b2: 81 7d f0 ff ff ff bf cmpl $0xbfffffff,-0x10(%ebp) +c01057b9: 77 23 ja c01057de +c01057bb: 8b 45 f0 mov -0x10(%ebp),%eax +c01057be: 89 44 24 0c mov %eax,0xc(%esp) +c01057c2: c7 44 24 08 a0 ce 10 movl $0xc010cea0,0x8(%esp) +c01057c9: c0 +c01057ca: c7 44 24 04 83 01 00 movl $0x183,0x4(%esp) +c01057d1: 00 +c01057d2: c7 04 24 c4 ce 10 c0 movl $0xc010cec4,(%esp) +c01057d9: e8 5d b5 ff ff call c0100d3b <__panic> +c01057de: 8b 45 f0 mov -0x10(%ebp),%eax +c01057e1: 8d 90 00 00 00 40 lea 0x40000000(%eax),%edx +c01057e7: a1 00 fa 12 c0 mov 0xc012fa00,%eax +c01057ec: 05 ac 0f 00 00 add $0xfac,%eax +c01057f1: 83 ca 03 or $0x3,%edx +c01057f4: 89 10 mov %edx,(%eax) + + // map all physical memory to linear memory with base linear addr KERNBASE + // linear_addr KERNBASE ~ KERNBASE + KMEMSIZE = phy_addr 0 ~ KMEMSIZE + // 将所有物理内存映射到线性内存,基地址为 KERNBASE + // 线性地址 KERNBASE ~ KERNBASE + KMEMSIZE = 物理地址 0 ~ KMEMSIZE + boot_map_segment(boot_pgdir, KERNBASE, KMEMSIZE, 0, PTE_W);// 映射物理内存 +c01057f6: a1 00 fa 12 c0 mov 0xc012fa00,%eax +c01057fb: c7 44 24 10 02 00 00 movl $0x2,0x10(%esp) +c0105802: 00 +c0105803: c7 44 24 0c 00 00 00 movl $0x0,0xc(%esp) +c010580a: 00 +c010580b: c7 44 24 08 00 00 00 movl $0x38000000,0x8(%esp) +c0105812: 38 +c0105813: c7 44 24 04 00 00 00 movl $0xc0000000,0x4(%esp) +c010581a: c0 +c010581b: 89 04 24 mov %eax,(%esp) +c010581e: e8 e0 fd ff ff call c0105603 + // then set kernel stack (ss:esp) in TSS, setup TSS in gdt, load TSS + // 由于我们正在使用引导加载程序的 GDT, + // 我们应该重新加载 GDT(第二次,也是最后一次),以获取用户段和 TSS + // 映射虚拟地址 0 ~ 4G = 线性地址 0 ~ 4G + // 然后在 TSS 中设置内核栈 (ss:esp),在 gdt 中设置 TSS,加载 TSS + gdt_init();// 初始化全局描述符表 +c0105823: e8 15 f8 ff ff call c010503d + + //now the basic virtual memory map(see memalyout.h) is established. + //check the correctness of the basic virtual memory map. + // 现在基本的虚拟内存映射(见 memlayout.h)已建立。 + // 检查基础虚拟内存映射的正确性。 + check_boot_pgdir(); // 检查页目录的正确性 +c0105828: e8 25 0f 00 00 call c0106752 + + print_pgdir(); // 打印页目录表 +c010582d: e8 cc 13 00 00 call c0106bfe + kmalloc_init(); +c0105832: e8 70 f3 ff ff call c0104ba7 + +} +c0105837: 90 nop +c0105838: 89 ec mov %ebp,%esp +c010583a: 5d pop %ebp +c010583b: c3 ret + +c010583c : +// pgdir: 页目录的内核虚拟基地址 +// la: 需要映射的线性地址 +// create: 一个逻辑值,决定是否为页表分配一页 +// 返回值:该 PTE 的内核虚拟地址 +pte_t * +get_pte(pde_t *pgdir, uintptr_t la, bool create) { +c010583c: 55 push %ebp +c010583d: 89 e5 mov %esp,%ebp +c010583f: 83 ec 38 sub $0x38,%esp + // (7) set page directory entry's permission + } + return NULL; // (8) return page table entry +#endif + // (1) 找到页目录项 + pde_t *pdep = &pgdir[PDX(la)];// 使用 PDX 宏获取页目录索引 +c0105842: 8b 45 0c mov 0xc(%ebp),%eax +c0105845: c1 e8 16 shr $0x16,%eax +c0105848: 8d 14 85 00 00 00 00 lea 0x0(,%eax,4),%edx +c010584f: 8b 45 08 mov 0x8(%ebp),%eax +c0105852: 01 d0 add %edx,%eax +c0105854: 89 45 f4 mov %eax,-0xc(%ebp) + // (2) 检查页目录项是否存在 + if (!(*pdep & PTE_P)) {// 如果页目录项的存在位 PTE_P 没有被设置 +c0105857: 8b 45 f4 mov -0xc(%ebp),%eax +c010585a: 8b 00 mov (%eax),%eax +c010585c: 83 e0 01 and $0x1,%eax +c010585f: 85 c0 test %eax,%eax +c0105861: 0f 85 af 00 00 00 jne c0105916 + struct Page *page;// 声明一个指针,用于指向新分配的页面 + // 检查是否允许创建新页表,或者分配页表失败 + if (!create || (page = alloc_page()) == NULL) {// 如果不允许创建或分配失败 +c0105867: 83 7d 10 00 cmpl $0x0,0x10(%ebp) +c010586b: 74 15 je c0105882 +c010586d: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c0105874: e8 08 f9 ff ff call c0105181 +c0105879: 89 45 f0 mov %eax,-0x10(%ebp) +c010587c: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) +c0105880: 75 0a jne c010588c + return NULL;// 返回 NULL,表示无法获取页表 +c0105882: b8 00 00 00 00 mov $0x0,%eax +c0105887: e9 e7 00 00 00 jmp c0105973 + } + // 设置新分配页面的引用计数为 1 + set_page_ref(page, 1); +c010588c: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c0105893: 00 +c0105894: 8b 45 f0 mov -0x10(%ebp),%eax +c0105897: 89 04 24 mov %eax,(%esp) +c010589a: e8 dc f6 ff ff call c0104f7b + uintptr_t pa = page2pa(page);// 获取新分配页面的物理地址 +c010589f: 8b 45 f0 mov -0x10(%ebp),%eax +c01058a2: 89 04 24 mov %eax,(%esp) +c01058a5: e8 b7 f5 ff ff call c0104e61 +c01058aa: 89 45 ec mov %eax,-0x14(%ebp) + memset(KADDR(pa), 0, PGSIZE);// 清空新分配的页表内容,初始化为零 +c01058ad: 8b 45 ec mov -0x14(%ebp),%eax +c01058b0: 89 45 e8 mov %eax,-0x18(%ebp) +c01058b3: 8b 45 e8 mov -0x18(%ebp),%eax +c01058b6: c1 e8 0c shr $0xc,%eax +c01058b9: 89 45 e4 mov %eax,-0x1c(%ebp) +c01058bc: a1 a4 3f 1a c0 mov 0xc01a3fa4,%eax +c01058c1: 39 45 e4 cmp %eax,-0x1c(%ebp) +c01058c4: 72 23 jb c01058e9 +c01058c6: 8b 45 e8 mov -0x18(%ebp),%eax +c01058c9: 89 44 24 0c mov %eax,0xc(%esp) +c01058cd: c7 44 24 08 fc cd 10 movl $0xc010cdfc,0x8(%esp) +c01058d4: c0 +c01058d5: c7 44 24 04 dd 01 00 movl $0x1dd,0x4(%esp) +c01058dc: 00 +c01058dd: c7 04 24 c4 ce 10 c0 movl $0xc010cec4,(%esp) +c01058e4: e8 52 b4 ff ff call c0100d3b <__panic> +c01058e9: 8b 45 e8 mov -0x18(%ebp),%eax +c01058ec: 2d 00 00 00 40 sub $0x40000000,%eax +c01058f1: c7 44 24 08 00 10 00 movl $0x1000,0x8(%esp) +c01058f8: 00 +c01058f9: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) +c0105900: 00 +c0105901: 89 04 24 mov %eax,(%esp) +c0105904: e8 e8 64 00 00 call c010bdf1 + // 更新页目录项,设置物理地址和权限位 + *pdep = pa | PTE_U | PTE_W | PTE_P;// 将物理地址和权限位(用户可访问、可写、有效)合并设置 +c0105909: 8b 45 ec mov -0x14(%ebp),%eax +c010590c: 83 c8 07 or $0x7,%eax +c010590f: 89 c2 mov %eax,%edx +c0105911: 8b 45 f4 mov -0xc(%ebp),%eax +c0105914: 89 10 mov %edx,(%eax) + } + // 返回指定线性地址 la 对应的页表项的内核虚拟地址 + return &((pte_t *)KADDR(PDE_ADDR(*pdep)))[PTX(la)];// 计算并返回页表项的指针 +c0105916: 8b 45 f4 mov -0xc(%ebp),%eax +c0105919: 8b 00 mov (%eax),%eax +c010591b: 25 00 f0 ff ff and $0xfffff000,%eax +c0105920: 89 45 e0 mov %eax,-0x20(%ebp) +c0105923: 8b 45 e0 mov -0x20(%ebp),%eax +c0105926: c1 e8 0c shr $0xc,%eax +c0105929: 89 45 dc mov %eax,-0x24(%ebp) +c010592c: a1 a4 3f 1a c0 mov 0xc01a3fa4,%eax +c0105931: 39 45 dc cmp %eax,-0x24(%ebp) +c0105934: 72 23 jb c0105959 +c0105936: 8b 45 e0 mov -0x20(%ebp),%eax +c0105939: 89 44 24 0c mov %eax,0xc(%esp) +c010593d: c7 44 24 08 fc cd 10 movl $0xc010cdfc,0x8(%esp) +c0105944: c0 +c0105945: c7 44 24 04 e2 01 00 movl $0x1e2,0x4(%esp) +c010594c: 00 +c010594d: c7 04 24 c4 ce 10 c0 movl $0xc010cec4,(%esp) +c0105954: e8 e2 b3 ff ff call c0100d3b <__panic> +c0105959: 8b 45 e0 mov -0x20(%ebp),%eax +c010595c: 2d 00 00 00 40 sub $0x40000000,%eax +c0105961: 89 c2 mov %eax,%edx +c0105963: 8b 45 0c mov 0xc(%ebp),%eax +c0105966: c1 e8 0c shr $0xc,%eax +c0105969: 25 ff 03 00 00 and $0x3ff,%eax +c010596e: c1 e0 02 shl $0x2,%eax +c0105971: 01 d0 add %edx,%eax +} +c0105973: 89 ec mov %ebp,%esp +c0105975: 5d pop %ebp +c0105976: c3 ret + +c0105977 : + +//get_page - get related Page struct for linear address la using PDT pgdir +// get_page - 获取与线性地址 la 相关的 Page 结构体,使用页目录 pgdir +struct Page * +get_page(pde_t *pgdir, uintptr_t la, pte_t **ptep_store) { +c0105977: 55 push %ebp +c0105978: 89 e5 mov %esp,%ebp +c010597a: 83 ec 28 sub $0x28,%esp + // 调用 get_pte 函数获取对应线性地址 la 的页表项指针 + pte_t *ptep = get_pte(pgdir, la, 0); +c010597d: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) +c0105984: 00 +c0105985: 8b 45 0c mov 0xc(%ebp),%eax +c0105988: 89 44 24 04 mov %eax,0x4(%esp) +c010598c: 8b 45 08 mov 0x8(%ebp),%eax +c010598f: 89 04 24 mov %eax,(%esp) +c0105992: e8 a5 fe ff ff call c010583c +c0105997: 89 45 f4 mov %eax,-0xc(%ebp) + // 如果 ptep_store 指针不为 NULL,将 ptep 存储到 ptep_store 指向的位置 + if (ptep_store != NULL) { +c010599a: 83 7d 10 00 cmpl $0x0,0x10(%ebp) +c010599e: 74 08 je c01059a8 + *ptep_store = ptep; // 存储当前页表项的指针 +c01059a0: 8b 45 10 mov 0x10(%ebp),%eax +c01059a3: 8b 55 f4 mov -0xc(%ebp),%edx +c01059a6: 89 10 mov %edx,(%eax) + } + // 检查 ptep 是否有效以及页表项的存在位 PTE_P 是否被设置 + if (ptep != NULL && *ptep & PTE_P) { +c01059a8: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c01059ac: 74 1b je c01059c9 +c01059ae: 8b 45 f4 mov -0xc(%ebp),%eax +c01059b1: 8b 00 mov (%eax),%eax +c01059b3: 83 e0 01 and $0x1,%eax +c01059b6: 85 c0 test %eax,%eax +c01059b8: 74 0f je c01059c9 + // 返回与页表项对应的 Page 结构体 + return pte2page(*ptep);// 将页表项转换为对应的 Page 结构 +c01059ba: 8b 45 f4 mov -0xc(%ebp),%eax +c01059bd: 8b 00 mov (%eax),%eax +c01059bf: 89 04 24 mov %eax,(%esp) +c01059c2: e8 50 f5 ff ff call c0104f17 +c01059c7: eb 05 jmp c01059ce + } + // 如果未找到有效的页,返回 NULL + return NULL; +c01059c9: b8 00 00 00 00 mov $0x0,%eax +} +c01059ce: 89 ec mov %ebp,%esp +c01059d0: 5d pop %ebp +c01059d1: c3 ret + +c01059d2 : + +//page_remove_pte - free an Page sturct which is related linear address la +// - and clean(invalidate) pte which is related linear address la +//note: PT is changed, so the TLB need to be invalidate +static inline void +page_remove_pte(pde_t *pgdir, uintptr_t la, pte_t *ptep) { +c01059d2: 55 push %ebp +c01059d3: 89 e5 mov %esp,%ebp +c01059d5: 83 ec 28 sub $0x28,%esp + //(4) and free this page when page reference reachs 0 + //(5) clear second page table entry + //(6) flush tlb + } +#endif + if (*ptep & PTE_P) { +c01059d8: 8b 45 10 mov 0x10(%ebp),%eax +c01059db: 8b 00 mov (%eax),%eax +c01059dd: 83 e0 01 and $0x1,%eax +c01059e0: 85 c0 test %eax,%eax +c01059e2: 74 4d je c0105a31 + struct Page *page = pte2page(*ptep);// 找到对应的物理页 +c01059e4: 8b 45 10 mov 0x10(%ebp),%eax +c01059e7: 8b 00 mov (%eax),%eax +c01059e9: 89 04 24 mov %eax,(%esp) +c01059ec: e8 26 f5 ff ff call c0104f17 +c01059f1: 89 45 f4 mov %eax,-0xc(%ebp) + // 减少物理页的引用计数,如果引用计数为零,释放该物理页 + if (page_ref_dec(page) == 0) { +c01059f4: 8b 45 f4 mov -0xc(%ebp),%eax +c01059f7: 89 04 24 mov %eax,(%esp) +c01059fa: e8 a1 f5 ff ff call c0104fa0 +c01059ff: 85 c0 test %eax,%eax +c0105a01: 75 13 jne c0105a16 + free_page(page); +c0105a03: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c0105a0a: 00 +c0105a0b: 8b 45 f4 mov -0xc(%ebp),%eax +c0105a0e: 89 04 24 mov %eax,(%esp) +c0105a11: e8 d8 f7 ff ff call c01051ee + } + *ptep = 0;// 清除页表项 +c0105a16: 8b 45 10 mov 0x10(%ebp),%eax +c0105a19: c7 00 00 00 00 00 movl $0x0,(%eax) + tlb_invalidate(pgdir, la);// 刷新 TLB +c0105a1f: 8b 45 0c mov 0xc(%ebp),%eax +c0105a22: 89 44 24 04 mov %eax,0x4(%esp) +c0105a26: 8b 45 08 mov 0x8(%ebp),%eax +c0105a29: 89 04 24 mov %eax,(%esp) +c0105a2c: e8 2d 05 00 00 call c0105f5e + } +} +c0105a31: 90 nop +c0105a32: 89 ec mov %ebp,%esp +c0105a34: 5d pop %ebp +c0105a35: c3 ret + +c0105a36 : + +void +unmap_range(pde_t *pgdir, uintptr_t start, uintptr_t end) { +c0105a36: 55 push %ebp +c0105a37: 89 e5 mov %esp,%ebp +c0105a39: 83 ec 28 sub $0x28,%esp + assert(start % PGSIZE == 0 && end % PGSIZE == 0); +c0105a3c: 8b 45 0c mov 0xc(%ebp),%eax +c0105a3f: 25 ff 0f 00 00 and $0xfff,%eax +c0105a44: 85 c0 test %eax,%eax +c0105a46: 75 0c jne c0105a54 +c0105a48: 8b 45 10 mov 0x10(%ebp),%eax +c0105a4b: 25 ff 0f 00 00 and $0xfff,%eax +c0105a50: 85 c0 test %eax,%eax +c0105a52: 74 24 je c0105a78 +c0105a54: c7 44 24 0c 24 cf 10 movl $0xc010cf24,0xc(%esp) +c0105a5b: c0 +c0105a5c: c7 44 24 08 e9 ce 10 movl $0xc010cee9,0x8(%esp) +c0105a63: c0 +c0105a64: c7 44 24 04 23 02 00 movl $0x223,0x4(%esp) +c0105a6b: 00 +c0105a6c: c7 04 24 c4 ce 10 c0 movl $0xc010cec4,(%esp) +c0105a73: e8 c3 b2 ff ff call c0100d3b <__panic> + assert(USER_ACCESS(start, end)); +c0105a78: 81 7d 0c ff ff 1f 00 cmpl $0x1fffff,0xc(%ebp) +c0105a7f: 76 11 jbe c0105a92 +c0105a81: 8b 45 0c mov 0xc(%ebp),%eax +c0105a84: 3b 45 10 cmp 0x10(%ebp),%eax +c0105a87: 73 09 jae c0105a92 +c0105a89: 81 7d 10 00 00 00 b0 cmpl $0xb0000000,0x10(%ebp) +c0105a90: 76 24 jbe c0105ab6 +c0105a92: c7 44 24 0c 4d cf 10 movl $0xc010cf4d,0xc(%esp) +c0105a99: c0 +c0105a9a: c7 44 24 08 e9 ce 10 movl $0xc010cee9,0x8(%esp) +c0105aa1: c0 +c0105aa2: c7 44 24 04 24 02 00 movl $0x224,0x4(%esp) +c0105aa9: 00 +c0105aaa: c7 04 24 c4 ce 10 c0 movl $0xc010cec4,(%esp) +c0105ab1: e8 85 b2 ff ff call c0100d3b <__panic> + + do { + pte_t *ptep = get_pte(pgdir, start, 0); +c0105ab6: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) +c0105abd: 00 +c0105abe: 8b 45 0c mov 0xc(%ebp),%eax +c0105ac1: 89 44 24 04 mov %eax,0x4(%esp) +c0105ac5: 8b 45 08 mov 0x8(%ebp),%eax +c0105ac8: 89 04 24 mov %eax,(%esp) +c0105acb: e8 6c fd ff ff call c010583c +c0105ad0: 89 45 f4 mov %eax,-0xc(%ebp) + if (ptep == NULL) { +c0105ad3: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c0105ad7: 75 18 jne c0105af1 + start = ROUNDDOWN(start + PTSIZE, PTSIZE); +c0105ad9: 8b 45 0c mov 0xc(%ebp),%eax +c0105adc: 05 00 00 40 00 add $0x400000,%eax +c0105ae1: 89 45 f0 mov %eax,-0x10(%ebp) +c0105ae4: 8b 45 f0 mov -0x10(%ebp),%eax +c0105ae7: 25 00 00 c0 ff and $0xffc00000,%eax +c0105aec: 89 45 0c mov %eax,0xc(%ebp) + continue ; +c0105aef: eb 29 jmp c0105b1a + } + if (*ptep != 0) { +c0105af1: 8b 45 f4 mov -0xc(%ebp),%eax +c0105af4: 8b 00 mov (%eax),%eax +c0105af6: 85 c0 test %eax,%eax +c0105af8: 74 19 je c0105b13 + page_remove_pte(pgdir, start, ptep); +c0105afa: 8b 45 f4 mov -0xc(%ebp),%eax +c0105afd: 89 44 24 08 mov %eax,0x8(%esp) +c0105b01: 8b 45 0c mov 0xc(%ebp),%eax +c0105b04: 89 44 24 04 mov %eax,0x4(%esp) +c0105b08: 8b 45 08 mov 0x8(%ebp),%eax +c0105b0b: 89 04 24 mov %eax,(%esp) +c0105b0e: e8 bf fe ff ff call c01059d2 + } + start += PGSIZE; +c0105b13: 81 45 0c 00 10 00 00 addl $0x1000,0xc(%ebp) + } while (start != 0 && start < end); +c0105b1a: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) +c0105b1e: 74 08 je c0105b28 +c0105b20: 8b 45 0c mov 0xc(%ebp),%eax +c0105b23: 3b 45 10 cmp 0x10(%ebp),%eax +c0105b26: 72 8e jb c0105ab6 +} +c0105b28: 90 nop +c0105b29: 89 ec mov %ebp,%esp +c0105b2b: 5d pop %ebp +c0105b2c: c3 ret + +c0105b2d : + +void +exit_range(pde_t *pgdir, uintptr_t start, uintptr_t end) { +c0105b2d: 55 push %ebp +c0105b2e: 89 e5 mov %esp,%ebp +c0105b30: 83 ec 28 sub $0x28,%esp + assert(start % PGSIZE == 0 && end % PGSIZE == 0); +c0105b33: 8b 45 0c mov 0xc(%ebp),%eax +c0105b36: 25 ff 0f 00 00 and $0xfff,%eax +c0105b3b: 85 c0 test %eax,%eax +c0105b3d: 75 0c jne c0105b4b +c0105b3f: 8b 45 10 mov 0x10(%ebp),%eax +c0105b42: 25 ff 0f 00 00 and $0xfff,%eax +c0105b47: 85 c0 test %eax,%eax +c0105b49: 74 24 je c0105b6f +c0105b4b: c7 44 24 0c 24 cf 10 movl $0xc010cf24,0xc(%esp) +c0105b52: c0 +c0105b53: c7 44 24 08 e9 ce 10 movl $0xc010cee9,0x8(%esp) +c0105b5a: c0 +c0105b5b: c7 44 24 04 35 02 00 movl $0x235,0x4(%esp) +c0105b62: 00 +c0105b63: c7 04 24 c4 ce 10 c0 movl $0xc010cec4,(%esp) +c0105b6a: e8 cc b1 ff ff call c0100d3b <__panic> + assert(USER_ACCESS(start, end)); +c0105b6f: 81 7d 0c ff ff 1f 00 cmpl $0x1fffff,0xc(%ebp) +c0105b76: 76 11 jbe c0105b89 +c0105b78: 8b 45 0c mov 0xc(%ebp),%eax +c0105b7b: 3b 45 10 cmp 0x10(%ebp),%eax +c0105b7e: 73 09 jae c0105b89 +c0105b80: 81 7d 10 00 00 00 b0 cmpl $0xb0000000,0x10(%ebp) +c0105b87: 76 24 jbe c0105bad +c0105b89: c7 44 24 0c 4d cf 10 movl $0xc010cf4d,0xc(%esp) +c0105b90: c0 +c0105b91: c7 44 24 08 e9 ce 10 movl $0xc010cee9,0x8(%esp) +c0105b98: c0 +c0105b99: c7 44 24 04 36 02 00 movl $0x236,0x4(%esp) +c0105ba0: 00 +c0105ba1: c7 04 24 c4 ce 10 c0 movl $0xc010cec4,(%esp) +c0105ba8: e8 8e b1 ff ff call c0100d3b <__panic> + + start = ROUNDDOWN(start, PTSIZE); +c0105bad: 8b 45 0c mov 0xc(%ebp),%eax +c0105bb0: 89 45 f4 mov %eax,-0xc(%ebp) +c0105bb3: 8b 45 f4 mov -0xc(%ebp),%eax +c0105bb6: 25 00 00 c0 ff and $0xffc00000,%eax +c0105bbb: 89 45 0c mov %eax,0xc(%ebp) + do { + int pde_idx = PDX(start); +c0105bbe: 8b 45 0c mov 0xc(%ebp),%eax +c0105bc1: c1 e8 16 shr $0x16,%eax +c0105bc4: 89 45 f0 mov %eax,-0x10(%ebp) + if (pgdir[pde_idx] & PTE_P) { +c0105bc7: 8b 45 f0 mov -0x10(%ebp),%eax +c0105bca: 8d 14 85 00 00 00 00 lea 0x0(,%eax,4),%edx +c0105bd1: 8b 45 08 mov 0x8(%ebp),%eax +c0105bd4: 01 d0 add %edx,%eax +c0105bd6: 8b 00 mov (%eax),%eax +c0105bd8: 83 e0 01 and $0x1,%eax +c0105bdb: 85 c0 test %eax,%eax +c0105bdd: 74 3e je c0105c1d + free_page(pde2page(pgdir[pde_idx])); +c0105bdf: 8b 45 f0 mov -0x10(%ebp),%eax +c0105be2: 8d 14 85 00 00 00 00 lea 0x0(,%eax,4),%edx +c0105be9: 8b 45 08 mov 0x8(%ebp),%eax +c0105bec: 01 d0 add %edx,%eax +c0105bee: 8b 00 mov (%eax),%eax +c0105bf0: 89 04 24 mov %eax,(%esp) +c0105bf3: e8 5f f3 ff ff call c0104f57 +c0105bf8: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c0105bff: 00 +c0105c00: 89 04 24 mov %eax,(%esp) +c0105c03: e8 e6 f5 ff ff call c01051ee + pgdir[pde_idx] = 0; +c0105c08: 8b 45 f0 mov -0x10(%ebp),%eax +c0105c0b: 8d 14 85 00 00 00 00 lea 0x0(,%eax,4),%edx +c0105c12: 8b 45 08 mov 0x8(%ebp),%eax +c0105c15: 01 d0 add %edx,%eax +c0105c17: c7 00 00 00 00 00 movl $0x0,(%eax) + } + start += PTSIZE; +c0105c1d: 81 45 0c 00 00 40 00 addl $0x400000,0xc(%ebp) + } while (start != 0 && start < end); +c0105c24: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) +c0105c28: 74 08 je c0105c32 +c0105c2a: 8b 45 0c mov 0xc(%ebp),%eax +c0105c2d: 3b 45 10 cmp 0x10(%ebp),%eax +c0105c30: 72 8c jb c0105bbe +} +c0105c32: 90 nop +c0105c33: 89 ec mov %ebp,%esp +c0105c35: 5d pop %ebp +c0105c36: c3 ret + +c0105c37 : + * @param share 是否共享页面。 + * + * @return 成功返回0,失败返回错误码。 + */ +int +copy_range(pde_t *to, pde_t *from, uintptr_t start, uintptr_t end, bool share) { +c0105c37: 55 push %ebp +c0105c38: 89 e5 mov %esp,%ebp +c0105c3a: 83 ec 48 sub $0x48,%esp + //确保起始地址和结束地址都是页对齐的 + assert(start % PGSIZE == 0 && end % PGSIZE == 0); +c0105c3d: 8b 45 10 mov 0x10(%ebp),%eax +c0105c40: 25 ff 0f 00 00 and $0xfff,%eax +c0105c45: 85 c0 test %eax,%eax +c0105c47: 75 0c jne c0105c55 +c0105c49: 8b 45 14 mov 0x14(%ebp),%eax +c0105c4c: 25 ff 0f 00 00 and $0xfff,%eax +c0105c51: 85 c0 test %eax,%eax +c0105c53: 74 24 je c0105c79 +c0105c55: c7 44 24 0c 24 cf 10 movl $0xc010cf24,0xc(%esp) +c0105c5c: c0 +c0105c5d: c7 44 24 08 e9 ce 10 movl $0xc010cee9,0x8(%esp) +c0105c64: c0 +c0105c65: c7 44 24 04 57 02 00 movl $0x257,0x4(%esp) +c0105c6c: 00 +c0105c6d: c7 04 24 c4 ce 10 c0 movl $0xc010cec4,(%esp) +c0105c74: e8 c2 b0 ff ff call c0100d3b <__panic> + // 确保地址范围在用户空间内 + assert(USER_ACCESS(start, end)); +c0105c79: 81 7d 10 ff ff 1f 00 cmpl $0x1fffff,0x10(%ebp) +c0105c80: 76 11 jbe c0105c93 +c0105c82: 8b 45 10 mov 0x10(%ebp),%eax +c0105c85: 3b 45 14 cmp 0x14(%ebp),%eax +c0105c88: 73 09 jae c0105c93 +c0105c8a: 81 7d 14 00 00 00 b0 cmpl $0xb0000000,0x14(%ebp) +c0105c91: 76 24 jbe c0105cb7 +c0105c93: c7 44 24 0c 4d cf 10 movl $0xc010cf4d,0xc(%esp) +c0105c9a: c0 +c0105c9b: c7 44 24 08 e9 ce 10 movl $0xc010cee9,0x8(%esp) +c0105ca2: c0 +c0105ca3: c7 44 24 04 59 02 00 movl $0x259,0x4(%esp) +c0105caa: 00 +c0105cab: c7 04 24 c4 ce 10 c0 movl $0xc010cec4,(%esp) +c0105cb2: e8 84 b0 ff ff call c0100d3b <__panic> + // copy content by page unit. // 按页单位复制内容 + do { + //call get_pte to find process A's pte according to the addr start + // 调用 get_pte 根据起始地址找到进程 A 的页表项 + pte_t *ptep = get_pte(from, start, 0), *nptep; +c0105cb7: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) +c0105cbe: 00 +c0105cbf: 8b 45 10 mov 0x10(%ebp),%eax +c0105cc2: 89 44 24 04 mov %eax,0x4(%esp) +c0105cc6: 8b 45 0c mov 0xc(%ebp),%eax +c0105cc9: 89 04 24 mov %eax,(%esp) +c0105ccc: e8 6b fb ff ff call c010583c +c0105cd1: 89 45 f4 mov %eax,-0xc(%ebp) + if (ptep == NULL) { +c0105cd4: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c0105cd8: 75 1b jne c0105cf5 + // 如果页表项不存在,跳过当前页 + start = ROUNDDOWN(start + PTSIZE, PTSIZE); +c0105cda: 8b 45 10 mov 0x10(%ebp),%eax +c0105cdd: 05 00 00 40 00 add $0x400000,%eax +c0105ce2: 89 45 d4 mov %eax,-0x2c(%ebp) +c0105ce5: 8b 45 d4 mov -0x2c(%ebp),%eax +c0105ce8: 25 00 00 c0 ff and $0xffc00000,%eax +c0105ced: 89 45 10 mov %eax,0x10(%ebp) + continue ; +c0105cf0: e9 4c 01 00 00 jmp c0105e41 + } + //call get_pte to find process B's pte according to the addr start. If pte is NULL, just alloc a PT + // 调用 get_pte 根据起始地址找到进程 B 的页表项。如果页表项不存在,分配一个新的页表 + if (*ptep & PTE_P) { +c0105cf5: 8b 45 f4 mov -0xc(%ebp),%eax +c0105cf8: 8b 00 mov (%eax),%eax +c0105cfa: 83 e0 01 and $0x1,%eax +c0105cfd: 85 c0 test %eax,%eax +c0105cff: 0f 84 35 01 00 00 je c0105e3a + if ((nptep = get_pte(to, start, 1)) == NULL) { +c0105d05: c7 44 24 08 01 00 00 movl $0x1,0x8(%esp) +c0105d0c: 00 +c0105d0d: 8b 45 10 mov 0x10(%ebp),%eax +c0105d10: 89 44 24 04 mov %eax,0x4(%esp) +c0105d14: 8b 45 08 mov 0x8(%ebp),%eax +c0105d17: 89 04 24 mov %eax,(%esp) +c0105d1a: e8 1d fb ff ff call c010583c +c0105d1f: 89 45 f0 mov %eax,-0x10(%ebp) +c0105d22: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) +c0105d26: 75 0a jne c0105d32 + // 分配页表失败,返回内存不足错误 + return -E_NO_MEM; +c0105d28: b8 fc ff ff ff mov $0xfffffffc,%eax +c0105d2d: e9 26 01 00 00 jmp c0105e58 + } + // 获取页表项的权限 + uint32_t perm = (*ptep & PTE_USER); +c0105d32: 8b 45 f4 mov -0xc(%ebp),%eax +c0105d35: 8b 00 mov (%eax),%eax +c0105d37: 83 e0 07 and $0x7,%eax +c0105d3a: 89 45 ec mov %eax,-0x14(%ebp) + //get page from ptep + // 从页表项获取物理页面 + struct Page *page = pte2page(*ptep); +c0105d3d: 8b 45 f4 mov -0xc(%ebp),%eax +c0105d40: 8b 00 mov (%eax),%eax +c0105d42: 89 04 24 mov %eax,(%esp) +c0105d45: e8 cd f1 ff ff call c0104f17 +c0105d4a: 89 45 e8 mov %eax,-0x18(%ebp) + // alloc a page for process B + // 为进程 B 分配一个物理页面 + struct Page *npage=alloc_page(); +c0105d4d: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c0105d54: e8 28 f4 ff ff call c0105181 +c0105d59: 89 45 e4 mov %eax,-0x1c(%ebp) + // 断言页面不为空 + assert(page!=NULL); +c0105d5c: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) +c0105d60: 75 24 jne c0105d86 +c0105d62: c7 44 24 0c 65 cf 10 movl $0xc010cf65,0xc(%esp) +c0105d69: c0 +c0105d6a: c7 44 24 08 e9 ce 10 movl $0xc010cee9,0x8(%esp) +c0105d71: c0 +c0105d72: c7 44 24 04 74 02 00 movl $0x274,0x4(%esp) +c0105d79: 00 +c0105d7a: c7 04 24 c4 ce 10 c0 movl $0xc010cec4,(%esp) +c0105d81: e8 b5 af ff ff call c0100d3b <__panic> + assert(npage!=NULL); +c0105d86: 83 7d e4 00 cmpl $0x0,-0x1c(%ebp) +c0105d8a: 75 24 jne c0105db0 +c0105d8c: c7 44 24 0c 70 cf 10 movl $0xc010cf70,0xc(%esp) +c0105d93: c0 +c0105d94: c7 44 24 08 e9 ce 10 movl $0xc010cee9,0x8(%esp) +c0105d9b: c0 +c0105d9c: c7 44 24 04 75 02 00 movl $0x275,0x4(%esp) +c0105da3: 00 +c0105da4: c7 04 24 c4 ce 10 c0 movl $0xc010cec4,(%esp) +c0105dab: e8 8b af ff ff call c0100d3b <__panic> + int ret=0; +c0105db0: c7 45 e0 00 00 00 00 movl $0x0,-0x20(%ebp) + * (2) 找到 dst_kvaddr: npage 的内核虚拟地址 + * (3) 从 src_kvaddr 复制内存到 dst_kvaddr,大小为 PGSIZE + * (4) 建立 npage 的物理地址与线性地址 start 的映射 + */ + // 获取源页面的内核虚拟地址 + void * kva_src = page2kva(page); +c0105db7: 8b 45 e8 mov -0x18(%ebp),%eax +c0105dba: 89 04 24 mov %eax,(%esp) +c0105dbd: e8 ff f0 ff ff call c0104ec1 +c0105dc2: 89 45 dc mov %eax,-0x24(%ebp) + // 获取目标页面的内核虚拟地址 + void * kva_dst = page2kva(npage); +c0105dc5: 8b 45 e4 mov -0x1c(%ebp),%eax +c0105dc8: 89 04 24 mov %eax,(%esp) +c0105dcb: e8 f1 f0 ff ff call c0104ec1 +c0105dd0: 89 45 d8 mov %eax,-0x28(%ebp) + // 将源页面的内容复制到目标页面 + memcpy(kva_dst, kva_src, PGSIZE); +c0105dd3: c7 44 24 08 00 10 00 movl $0x1000,0x8(%esp) +c0105dda: 00 +c0105ddb: 8b 45 dc mov -0x24(%ebp),%eax +c0105dde: 89 44 24 04 mov %eax,0x4(%esp) +c0105de2: 8b 45 d8 mov -0x28(%ebp),%eax +c0105de5: 89 04 24 mov %eax,(%esp) +c0105de8: e8 e9 60 00 00 call c010bed6 + // 将目标页面插入到目标进程的页表中,映射到线性地址 start,并设置权限 perm + ret = page_insert(to, npage, start, perm); +c0105ded: 8b 45 ec mov -0x14(%ebp),%eax +c0105df0: 89 44 24 0c mov %eax,0xc(%esp) +c0105df4: 8b 45 10 mov 0x10(%ebp),%eax +c0105df7: 89 44 24 08 mov %eax,0x8(%esp) +c0105dfb: 8b 45 e4 mov -0x1c(%ebp),%eax +c0105dfe: 89 44 24 04 mov %eax,0x4(%esp) +c0105e02: 8b 45 08 mov 0x8(%ebp),%eax +c0105e05: 89 04 24 mov %eax,(%esp) +c0105e08: e8 96 00 00 00 call c0105ea3 +c0105e0d: 89 45 e0 mov %eax,-0x20(%ebp) + assert(ret == 0); +c0105e10: 83 7d e0 00 cmpl $0x0,-0x20(%ebp) +c0105e14: 74 24 je c0105e3a +c0105e16: c7 44 24 0c 7c cf 10 movl $0xc010cf7c,0xc(%esp) +c0105e1d: c0 +c0105e1e: c7 44 24 08 e9 ce 10 movl $0xc010cee9,0x8(%esp) +c0105e25: c0 +c0105e26: c7 44 24 04 9b 02 00 movl $0x29b,0x4(%esp) +c0105e2d: 00 +c0105e2e: c7 04 24 c4 ce 10 c0 movl $0xc010cec4,(%esp) +c0105e35: e8 01 af ff ff call c0100d3b <__panic> + } + start += PGSIZE; +c0105e3a: 81 45 10 00 10 00 00 addl $0x1000,0x10(%ebp) + } while (start != 0 && start < end); +c0105e41: 83 7d 10 00 cmpl $0x0,0x10(%ebp) +c0105e45: 74 0c je c0105e53 +c0105e47: 8b 45 10 mov 0x10(%ebp),%eax +c0105e4a: 3b 45 14 cmp 0x14(%ebp),%eax +c0105e4d: 0f 82 64 fe ff ff jb c0105cb7 + return 0; +c0105e53: b8 00 00 00 00 mov $0x0,%eax +} +c0105e58: 89 ec mov %ebp,%esp +c0105e5a: 5d pop %ebp +c0105e5b: c3 ret + +c0105e5c : + +//page_remove - free an Page which is related linear address la and has an validated pte +//移除一个虚拟地址对应的页面 +void +page_remove(pde_t *pgdir, uintptr_t la) { +c0105e5c: 55 push %ebp +c0105e5d: 89 e5 mov %esp,%ebp +c0105e5f: 83 ec 28 sub $0x28,%esp + //调用 get_pte 函数获取给定虚拟地址 la 对应的页表项指针 ptep。 + pte_t *ptep = get_pte(pgdir, la, 0); +c0105e62: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) +c0105e69: 00 +c0105e6a: 8b 45 0c mov 0xc(%ebp),%eax +c0105e6d: 89 44 24 04 mov %eax,0x4(%esp) +c0105e71: 8b 45 08 mov 0x8(%ebp),%eax +c0105e74: 89 04 24 mov %eax,(%esp) +c0105e77: e8 c0 f9 ff ff call c010583c +c0105e7c: 89 45 f4 mov %eax,-0xc(%ebp) + //如果 ptep 不为 NULL,则调用 page_remove_pte 函数移除该页表项。 + if (ptep != NULL) { +c0105e7f: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c0105e83: 74 19 je c0105e9e + page_remove_pte(pgdir, la, ptep); +c0105e85: 8b 45 f4 mov -0xc(%ebp),%eax +c0105e88: 89 44 24 08 mov %eax,0x8(%esp) +c0105e8c: 8b 45 0c mov 0xc(%ebp),%eax +c0105e8f: 89 44 24 04 mov %eax,0x4(%esp) +c0105e93: 8b 45 08 mov 0x8(%ebp),%eax +c0105e96: 89 04 24 mov %eax,(%esp) +c0105e99: e8 34 fb ff ff call c01059d2 + } +} +c0105e9e: 90 nop +c0105e9f: 89 ec mov %ebp,%esp +c0105ea1: 5d pop %ebp +c0105ea2: c3 ret + +c0105ea3 : +// perm: the permission of this Page which is setted in related pte +// return value: always 0 +//note: PT is changed, so the TLB need to be invalidate +//将一个页面插入到页表中。 +int +page_insert(pde_t *pgdir, struct Page *page, uintptr_t la, uint32_t perm) { +c0105ea3: 55 push %ebp +c0105ea4: 89 e5 mov %esp,%ebp +c0105ea6: 83 ec 28 sub $0x28,%esp + //通过 get_pte 函数获取指定虚拟地址 la 对应的页表项指针 ptep。 + pte_t *ptep = get_pte(pgdir, la, 1); +c0105ea9: c7 44 24 08 01 00 00 movl $0x1,0x8(%esp) +c0105eb0: 00 +c0105eb1: 8b 45 10 mov 0x10(%ebp),%eax +c0105eb4: 89 44 24 04 mov %eax,0x4(%esp) +c0105eb8: 8b 45 08 mov 0x8(%ebp),%eax +c0105ebb: 89 04 24 mov %eax,(%esp) +c0105ebe: e8 79 f9 ff ff call c010583c +c0105ec3: 89 45 f4 mov %eax,-0xc(%ebp) + //如果 ptep 为 NULL,表示内存分配失败,返回 -E_NO_MEM。 + if (ptep == NULL) { +c0105ec6: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c0105eca: 75 0a jne c0105ed6 + return -E_NO_MEM; +c0105ecc: b8 fc ff ff ff mov $0xfffffffc,%eax +c0105ed1: e9 84 00 00 00 jmp c0105f5a + } + //调用 page_ref_inc 增加页面的引用计数。 + page_ref_inc(page); +c0105ed6: 8b 45 0c mov 0xc(%ebp),%eax +c0105ed9: 89 04 24 mov %eax,(%esp) +c0105edc: e8 a8 f0 ff ff call c0104f89 + //如果页表项已存在且指向当前页面,则减少页面引用计数。 + if (*ptep & PTE_P) { +c0105ee1: 8b 45 f4 mov -0xc(%ebp),%eax +c0105ee4: 8b 00 mov (%eax),%eax +c0105ee6: 83 e0 01 and $0x1,%eax +c0105ee9: 85 c0 test %eax,%eax +c0105eeb: 74 3e je c0105f2b + struct Page *p = pte2page(*ptep); +c0105eed: 8b 45 f4 mov -0xc(%ebp),%eax +c0105ef0: 8b 00 mov (%eax),%eax +c0105ef2: 89 04 24 mov %eax,(%esp) +c0105ef5: e8 1d f0 ff ff call c0104f17 +c0105efa: 89 45 f0 mov %eax,-0x10(%ebp) + if (p == page) { +c0105efd: 8b 45 f0 mov -0x10(%ebp),%eax +c0105f00: 3b 45 0c cmp 0xc(%ebp),%eax +c0105f03: 75 0d jne c0105f12 + page_ref_dec(page); +c0105f05: 8b 45 0c mov 0xc(%ebp),%eax +c0105f08: 89 04 24 mov %eax,(%esp) +c0105f0b: e8 90 f0 ff ff call c0104fa0 +c0105f10: eb 19 jmp c0105f2b + } + //如果页表项已存在但指向其他页面,则调用 page_remove_pte 移除旧的页表项。 + else { + page_remove_pte(pgdir, la, ptep); +c0105f12: 8b 45 f4 mov -0xc(%ebp),%eax +c0105f15: 89 44 24 08 mov %eax,0x8(%esp) +c0105f19: 8b 45 10 mov 0x10(%ebp),%eax +c0105f1c: 89 44 24 04 mov %eax,0x4(%esp) +c0105f20: 8b 45 08 mov 0x8(%ebp),%eax +c0105f23: 89 04 24 mov %eax,(%esp) +c0105f26: e8 a7 fa ff ff call c01059d2 + } + } + *ptep = page2pa(page) | PTE_P | perm; +c0105f2b: 8b 45 0c mov 0xc(%ebp),%eax +c0105f2e: 89 04 24 mov %eax,(%esp) +c0105f31: e8 2b ef ff ff call c0104e61 +c0105f36: 0b 45 14 or 0x14(%ebp),%eax +c0105f39: 83 c8 01 or $0x1,%eax +c0105f3c: 89 c2 mov %eax,%edx +c0105f3e: 8b 45 f4 mov -0xc(%ebp),%eax +c0105f41: 89 10 mov %edx,(%eax) + tlb_invalidate(pgdir, la);//刷新 TLB +c0105f43: 8b 45 10 mov 0x10(%ebp),%eax +c0105f46: 89 44 24 04 mov %eax,0x4(%esp) +c0105f4a: 8b 45 08 mov 0x8(%ebp),%eax +c0105f4d: 89 04 24 mov %eax,(%esp) +c0105f50: e8 09 00 00 00 call c0105f5e + return 0; +c0105f55: b8 00 00 00 00 mov $0x0,%eax +} +c0105f5a: 89 ec mov %ebp,%esp +c0105f5c: 5d pop %ebp +c0105f5d: c3 ret + +c0105f5e : + +// invalidate a TLB entry, but only if the page tables being +// edited are the ones currently in use by the processor. +//无效化指定地址的TLB条目 +void +tlb_invalidate(pde_t *pgdir, uintptr_t la) { +c0105f5e: 55 push %ebp +c0105f5f: 89 e5 mov %esp,%ebp +c0105f61: 83 ec 28 sub $0x28,%esp +} + +static inline uintptr_t +rcr3(void) { + uintptr_t cr3; + asm volatile ("mov %%cr3, %0" : "=r" (cr3) :: "memory"); +c0105f64: 0f 20 d8 mov %cr3,%eax +c0105f67: 89 45 f0 mov %eax,-0x10(%ebp) + return cr3; +c0105f6a: 8b 55 f0 mov -0x10(%ebp),%edx + //检查当前页目录地址是否与传入的页目录地址相同。 + if (rcr3() == PADDR(pgdir)) { +c0105f6d: 8b 45 08 mov 0x8(%ebp),%eax +c0105f70: 89 45 f4 mov %eax,-0xc(%ebp) +c0105f73: 81 7d f4 ff ff ff bf cmpl $0xbfffffff,-0xc(%ebp) +c0105f7a: 77 23 ja c0105f9f +c0105f7c: 8b 45 f4 mov -0xc(%ebp),%eax +c0105f7f: 89 44 24 0c mov %eax,0xc(%esp) +c0105f83: c7 44 24 08 a0 ce 10 movl $0xc010cea0,0x8(%esp) +c0105f8a: c0 +c0105f8b: c7 44 24 04 d7 02 00 movl $0x2d7,0x4(%esp) +c0105f92: 00 +c0105f93: c7 04 24 c4 ce 10 c0 movl $0xc010cec4,(%esp) +c0105f9a: e8 9c ad ff ff call c0100d3b <__panic> +c0105f9f: 8b 45 f4 mov -0xc(%ebp),%eax +c0105fa2: 05 00 00 00 40 add $0x40000000,%eax +c0105fa7: 39 d0 cmp %edx,%eax +c0105fa9: 75 0d jne c0105fb8 + //如果相同,则调用 invlpg 函数无效化指定线性地址的TLB条目。 + invlpg((void *)la); +c0105fab: 8b 45 0c mov 0xc(%ebp),%eax +c0105fae: 89 45 ec mov %eax,-0x14(%ebp) +} + +static inline void +invlpg(void *addr) { + asm volatile ("invlpg (%0)" :: "r" (addr) : "memory"); +c0105fb1: 8b 45 ec mov -0x14(%ebp),%eax +c0105fb4: 0f 01 38 invlpg (%eax) +} +c0105fb7: 90 nop + } +} +c0105fb8: 90 nop +c0105fb9: 89 ec mov %ebp,%esp +c0105fbb: 5d pop %ebp +c0105fbc: c3 ret + +c0105fbd : + +// pgdir_alloc_page - call alloc_page & page_insert functions to +// - allocate a page size memory & setup an addr map +// - pa<->la with linear address la and the PDT pgdir +struct Page * +pgdir_alloc_page(pde_t *pgdir, uintptr_t la, uint32_t perm) { +c0105fbd: 55 push %ebp +c0105fbe: 89 e5 mov %esp,%ebp +c0105fc0: 83 ec 28 sub $0x28,%esp + struct Page *page = alloc_page();//分配一个新的页面存储在 page 指针中 +c0105fc3: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c0105fca: e8 b2 f1 ff ff call c0105181 +c0105fcf: 89 45 f4 mov %eax,-0xc(%ebp) + if (page != NULL) {//检查 page 是否不为 NULL,即分配是否成功。 +c0105fd2: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c0105fd6: 0f 84 b0 00 00 00 je c010608c + if (page_insert(pgdir, page, la, perm) != 0) {//将页面插入到指定的线性地址 la 处。 +c0105fdc: 8b 45 10 mov 0x10(%ebp),%eax +c0105fdf: 89 44 24 0c mov %eax,0xc(%esp) +c0105fe3: 8b 45 0c mov 0xc(%ebp),%eax +c0105fe6: 89 44 24 08 mov %eax,0x8(%esp) +c0105fea: 8b 45 f4 mov -0xc(%ebp),%eax +c0105fed: 89 44 24 04 mov %eax,0x4(%esp) +c0105ff1: 8b 45 08 mov 0x8(%ebp),%eax +c0105ff4: 89 04 24 mov %eax,(%esp) +c0105ff7: e8 a7 fe ff ff call c0105ea3 +c0105ffc: 85 c0 test %eax,%eax +c0105ffe: 74 1a je c010601a + free_page(page);//释放分配的页面。 +c0106000: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c0106007: 00 +c0106008: 8b 45 f4 mov -0xc(%ebp),%eax +c010600b: 89 04 24 mov %eax,(%esp) +c010600e: e8 db f1 ff ff call c01051ee + return NULL;//返回 NULL,表示页面插入失败。 +c0106013: b8 00 00 00 00 mov $0x0,%eax +c0106018: eb 75 jmp c010608f + } + if (swap_init_ok){//检查交换区是否已初始化成功 +c010601a: a1 44 40 1a c0 mov 0xc01a4044,%eax +c010601f: 85 c0 test %eax,%eax +c0106021: 74 69 je c010608c + if(check_mm_struct!=NULL) { +c0106023: a1 0c 41 1a c0 mov 0xc01a410c,%eax +c0106028: 85 c0 test %eax,%eax +c010602a: 74 60 je c010608c + //将页面映射到交换区 + swap_map_swappable(check_mm_struct, la, page, 0); +c010602c: a1 0c 41 1a c0 mov 0xc01a410c,%eax +c0106031: c7 44 24 0c 00 00 00 movl $0x0,0xc(%esp) +c0106038: 00 +c0106039: 8b 55 f4 mov -0xc(%ebp),%edx +c010603c: 89 54 24 08 mov %edx,0x8(%esp) +c0106040: 8b 55 0c mov 0xc(%ebp),%edx +c0106043: 89 54 24 04 mov %edx,0x4(%esp) +c0106047: 89 04 24 mov %eax,(%esp) +c010604a: e8 7e 0e 00 00 call c0106ecd + //设置页面的虚拟地址 pra_vaddr 为 la + page->pra_vaddr=la; +c010604f: 8b 45 f4 mov -0xc(%ebp),%eax +c0106052: 8b 55 0c mov 0xc(%ebp),%edx +c0106055: 89 50 1c mov %edx,0x1c(%eax) + //断言页面的引用计数为1,确保页面没有被其他地方引用。 + assert(page_ref(page) == 1); +c0106058: 8b 45 f4 mov -0xc(%ebp),%eax +c010605b: 89 04 24 mov %eax,(%esp) +c010605e: e8 0e ef ff ff call c0104f71 +c0106063: 83 f8 01 cmp $0x1,%eax +c0106066: 74 24 je c010608c +c0106068: c7 44 24 0c 85 cf 10 movl $0xc010cf85,0xc(%esp) +c010606f: c0 +c0106070: c7 44 24 08 e9 ce 10 movl $0xc010cee9,0x8(%esp) +c0106077: c0 +c0106078: c7 44 24 04 ef 02 00 movl $0x2ef,0x4(%esp) +c010607f: 00 +c0106080: c7 04 24 c4 ce 10 c0 movl $0xc010cec4,(%esp) +c0106087: e8 af ac ff ff call c0100d3b <__panic> + } + } + + } + + return page; +c010608c: 8b 45 f4 mov -0xc(%ebp),%eax +} +c010608f: 89 ec mov %ebp,%esp +c0106091: 5d pop %ebp +c0106092: c3 ret + +c0106093 : + +static void +check_alloc_page(void) { +c0106093: 55 push %ebp +c0106094: 89 e5 mov %esp,%ebp +c0106096: 83 ec 18 sub $0x18,%esp + //调用内存管理器的 check 方法,用于检查内存分配是否正常。 + pmm_manager->check(); +c0106099: a1 ac 3f 1a c0 mov 0xc01a3fac,%eax +c010609e: 8b 40 18 mov 0x18(%eax),%eax +c01060a1: ff d0 call *%eax + cprintf("check_alloc_page() succeeded!\n"); +c01060a3: c7 04 24 9c cf 10 c0 movl $0xc010cf9c,(%esp) +c01060aa: e8 c9 a2 ff ff call c0100378 +} +c01060af: 90 nop +c01060b0: 89 ec mov %ebp,%esp +c01060b2: 5d pop %ebp +c01060b3: c3 ret + +c01060b4 : + +//用于验证页目录和页表的正确性。 +static void +check_pgdir(void) { +c01060b4: 55 push %ebp +c01060b5: 89 e5 mov %esp,%ebp +c01060b7: 83 ec 38 sub $0x38,%esp + //确保内存页面数量在合理范围内 + assert(npage <= KMEMSIZE / PGSIZE); +c01060ba: a1 a4 3f 1a c0 mov 0xc01a3fa4,%eax +c01060bf: 3d 00 80 03 00 cmp $0x38000,%eax +c01060c4: 76 24 jbe c01060ea +c01060c6: c7 44 24 0c bb cf 10 movl $0xc010cfbb,0xc(%esp) +c01060cd: c0 +c01060ce: c7 44 24 08 e9 ce 10 movl $0xc010cee9,0x8(%esp) +c01060d5: c0 +c01060d6: c7 44 24 04 0a 03 00 movl $0x30a,0x4(%esp) +c01060dd: 00 +c01060de: c7 04 24 c4 ce 10 c0 movl $0xc010cec4,(%esp) +c01060e5: e8 51 ac ff ff call c0100d3b <__panic> + //确保页目录不为空且对齐, + assert(boot_pgdir != NULL && (uint32_t)PGOFF(boot_pgdir) == 0); +c01060ea: a1 00 fa 12 c0 mov 0xc012fa00,%eax +c01060ef: 85 c0 test %eax,%eax +c01060f1: 74 0e je c0106101 +c01060f3: a1 00 fa 12 c0 mov 0xc012fa00,%eax +c01060f8: 25 ff 0f 00 00 and $0xfff,%eax +c01060fd: 85 c0 test %eax,%eax +c01060ff: 74 24 je c0106125 +c0106101: c7 44 24 0c d8 cf 10 movl $0xc010cfd8,0xc(%esp) +c0106108: c0 +c0106109: c7 44 24 08 e9 ce 10 movl $0xc010cee9,0x8(%esp) +c0106110: c0 +c0106111: c7 44 24 04 0c 03 00 movl $0x30c,0x4(%esp) +c0106118: 00 +c0106119: c7 04 24 c4 ce 10 c0 movl $0xc010cec4,(%esp) +c0106120: e8 16 ac ff ff call c0100d3b <__panic> + //确保虚拟地址 0x0 没有映射任何页面 + assert(get_page(boot_pgdir, 0x0, NULL) == NULL); +c0106125: a1 00 fa 12 c0 mov 0xc012fa00,%eax +c010612a: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) +c0106131: 00 +c0106132: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) +c0106139: 00 +c010613a: 89 04 24 mov %eax,(%esp) +c010613d: e8 35 f8 ff ff call c0105977 +c0106142: 85 c0 test %eax,%eax +c0106144: 74 24 je c010616a +c0106146: c7 44 24 0c 10 d0 10 movl $0xc010d010,0xc(%esp) +c010614d: c0 +c010614e: c7 44 24 08 e9 ce 10 movl $0xc010cee9,0x8(%esp) +c0106155: c0 +c0106156: c7 44 24 04 0e 03 00 movl $0x30e,0x4(%esp) +c010615d: 00 +c010615e: c7 04 24 c4 ce 10 c0 movl $0xc010cec4,(%esp) +c0106165: e8 d1 ab ff ff call c0100d3b <__panic> + + //定义两个页面指针 p1 和 p2 + struct Page *p1, *p2; + //分配一个页面 p1 + p1 = alloc_page(); +c010616a: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c0106171: e8 0b f0 ff ff call c0105181 +c0106176: 89 45 f4 mov %eax,-0xc(%ebp) + //将 p1 插入到虚拟地址 0x0 + assert(page_insert(boot_pgdir, p1, 0x0, 0) == 0); +c0106179: a1 00 fa 12 c0 mov 0xc012fa00,%eax +c010617e: c7 44 24 0c 00 00 00 movl $0x0,0xc(%esp) +c0106185: 00 +c0106186: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) +c010618d: 00 +c010618e: 8b 55 f4 mov -0xc(%ebp),%edx +c0106191: 89 54 24 04 mov %edx,0x4(%esp) +c0106195: 89 04 24 mov %eax,(%esp) +c0106198: e8 06 fd ff ff call c0105ea3 +c010619d: 85 c0 test %eax,%eax +c010619f: 74 24 je c01061c5 +c01061a1: c7 44 24 0c 38 d0 10 movl $0xc010d038,0xc(%esp) +c01061a8: c0 +c01061a9: c7 44 24 08 e9 ce 10 movl $0xc010cee9,0x8(%esp) +c01061b0: c0 +c01061b1: c7 44 24 04 15 03 00 movl $0x315,0x4(%esp) +c01061b8: 00 +c01061b9: c7 04 24 c4 ce 10 c0 movl $0xc010cec4,(%esp) +c01061c0: e8 76 ab ff ff call c0100d3b <__panic> + + // 获取虚拟地址 0x0 对应的页表项指针 + pte_t *ptep; + assert((ptep = get_pte(boot_pgdir, 0x0, 0)) != NULL); +c01061c5: a1 00 fa 12 c0 mov 0xc012fa00,%eax +c01061ca: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) +c01061d1: 00 +c01061d2: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) +c01061d9: 00 +c01061da: 89 04 24 mov %eax,(%esp) +c01061dd: e8 5a f6 ff ff call c010583c +c01061e2: 89 45 f0 mov %eax,-0x10(%ebp) +c01061e5: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) +c01061e9: 75 24 jne c010620f +c01061eb: c7 44 24 0c 64 d0 10 movl $0xc010d064,0xc(%esp) +c01061f2: c0 +c01061f3: c7 44 24 08 e9 ce 10 movl $0xc010cee9,0x8(%esp) +c01061fa: c0 +c01061fb: c7 44 24 04 19 03 00 movl $0x319,0x4(%esp) +c0106202: 00 +c0106203: c7 04 24 c4 ce 10 c0 movl $0xc010cec4,(%esp) +c010620a: e8 2c ab ff ff call c0100d3b <__panic> + // 验证页表项对应的页面是 p1 + assert(pte2page(*ptep) == p1); +c010620f: 8b 45 f0 mov -0x10(%ebp),%eax +c0106212: 8b 00 mov (%eax),%eax +c0106214: 89 04 24 mov %eax,(%esp) +c0106217: e8 fb ec ff ff call c0104f17 +c010621c: 39 45 f4 cmp %eax,-0xc(%ebp) +c010621f: 74 24 je c0106245 +c0106221: c7 44 24 0c 91 d0 10 movl $0xc010d091,0xc(%esp) +c0106228: c0 +c0106229: c7 44 24 08 e9 ce 10 movl $0xc010cee9,0x8(%esp) +c0106230: c0 +c0106231: c7 44 24 04 1b 03 00 movl $0x31b,0x4(%esp) +c0106238: 00 +c0106239: c7 04 24 c4 ce 10 c0 movl $0xc010cec4,(%esp) +c0106240: e8 f6 aa ff ff call c0100d3b <__panic> + // 验证 p1 的引用计数为 1 + assert(page_ref(p1) == 1); +c0106245: 8b 45 f4 mov -0xc(%ebp),%eax +c0106248: 89 04 24 mov %eax,(%esp) +c010624b: e8 21 ed ff ff call c0104f71 +c0106250: 83 f8 01 cmp $0x1,%eax +c0106253: 74 24 je c0106279 +c0106255: c7 44 24 0c a7 d0 10 movl $0xc010d0a7,0xc(%esp) +c010625c: c0 +c010625d: c7 44 24 08 e9 ce 10 movl $0xc010cee9,0x8(%esp) +c0106264: c0 +c0106265: c7 44 24 04 1d 03 00 movl $0x31d,0x4(%esp) +c010626c: 00 +c010626d: c7 04 24 c4 ce 10 c0 movl $0xc010cec4,(%esp) +c0106274: e8 c2 aa ff ff call c0100d3b <__panic> + // 获取虚拟地址 PGSIZE 对应的页表项指针 + ptep = &((pte_t *)KADDR(PDE_ADDR(boot_pgdir[0])))[1]; +c0106279: a1 00 fa 12 c0 mov 0xc012fa00,%eax +c010627e: 8b 00 mov (%eax),%eax +c0106280: 25 00 f0 ff ff and $0xfffff000,%eax +c0106285: 89 45 ec mov %eax,-0x14(%ebp) +c0106288: 8b 45 ec mov -0x14(%ebp),%eax +c010628b: c1 e8 0c shr $0xc,%eax +c010628e: 89 45 e8 mov %eax,-0x18(%ebp) +c0106291: a1 a4 3f 1a c0 mov 0xc01a3fa4,%eax +c0106296: 39 45 e8 cmp %eax,-0x18(%ebp) +c0106299: 72 23 jb c01062be +c010629b: 8b 45 ec mov -0x14(%ebp),%eax +c010629e: 89 44 24 0c mov %eax,0xc(%esp) +c01062a2: c7 44 24 08 fc cd 10 movl $0xc010cdfc,0x8(%esp) +c01062a9: c0 +c01062aa: c7 44 24 04 1f 03 00 movl $0x31f,0x4(%esp) +c01062b1: 00 +c01062b2: c7 04 24 c4 ce 10 c0 movl $0xc010cec4,(%esp) +c01062b9: e8 7d aa ff ff call c0100d3b <__panic> +c01062be: 8b 45 ec mov -0x14(%ebp),%eax +c01062c1: 2d 00 00 00 40 sub $0x40000000,%eax +c01062c6: 83 c0 04 add $0x4,%eax +c01062c9: 89 45 f0 mov %eax,-0x10(%ebp) + assert(get_pte(boot_pgdir, PGSIZE, 0) == ptep); +c01062cc: a1 00 fa 12 c0 mov 0xc012fa00,%eax +c01062d1: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) +c01062d8: 00 +c01062d9: c7 44 24 04 00 10 00 movl $0x1000,0x4(%esp) +c01062e0: 00 +c01062e1: 89 04 24 mov %eax,(%esp) +c01062e4: e8 53 f5 ff ff call c010583c +c01062e9: 39 45 f0 cmp %eax,-0x10(%ebp) +c01062ec: 74 24 je c0106312 +c01062ee: c7 44 24 0c bc d0 10 movl $0xc010d0bc,0xc(%esp) +c01062f5: c0 +c01062f6: c7 44 24 08 e9 ce 10 movl $0xc010cee9,0x8(%esp) +c01062fd: c0 +c01062fe: c7 44 24 04 20 03 00 movl $0x320,0x4(%esp) +c0106305: 00 +c0106306: c7 04 24 c4 ce 10 c0 movl $0xc010cec4,(%esp) +c010630d: e8 29 aa ff ff call c0100d3b <__panic> + // 分配一个页面 p2 + p2 = alloc_page(); +c0106312: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c0106319: e8 63 ee ff ff call c0105181 +c010631e: 89 45 e4 mov %eax,-0x1c(%ebp) + // 将 p2 插入到虚拟地址 PGSIZE,并设置用户和写权限 + assert(page_insert(boot_pgdir, p2, PGSIZE, PTE_U | PTE_W) == 0); +c0106321: a1 00 fa 12 c0 mov 0xc012fa00,%eax +c0106326: c7 44 24 0c 06 00 00 movl $0x6,0xc(%esp) +c010632d: 00 +c010632e: c7 44 24 08 00 10 00 movl $0x1000,0x8(%esp) +c0106335: 00 +c0106336: 8b 55 e4 mov -0x1c(%ebp),%edx +c0106339: 89 54 24 04 mov %edx,0x4(%esp) +c010633d: 89 04 24 mov %eax,(%esp) +c0106340: e8 5e fb ff ff call c0105ea3 +c0106345: 85 c0 test %eax,%eax +c0106347: 74 24 je c010636d +c0106349: c7 44 24 0c e4 d0 10 movl $0xc010d0e4,0xc(%esp) +c0106350: c0 +c0106351: c7 44 24 08 e9 ce 10 movl $0xc010cee9,0x8(%esp) +c0106358: c0 +c0106359: c7 44 24 04 24 03 00 movl $0x324,0x4(%esp) +c0106360: 00 +c0106361: c7 04 24 c4 ce 10 c0 movl $0xc010cec4,(%esp) +c0106368: e8 ce a9 ff ff call c0100d3b <__panic> + // 获取虚拟地址 PGSIZE 对应的页表项指针 + assert((ptep = get_pte(boot_pgdir, PGSIZE, 0)) != NULL); +c010636d: a1 00 fa 12 c0 mov 0xc012fa00,%eax +c0106372: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) +c0106379: 00 +c010637a: c7 44 24 04 00 10 00 movl $0x1000,0x4(%esp) +c0106381: 00 +c0106382: 89 04 24 mov %eax,(%esp) +c0106385: e8 b2 f4 ff ff call c010583c +c010638a: 89 45 f0 mov %eax,-0x10(%ebp) +c010638d: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) +c0106391: 75 24 jne c01063b7 +c0106393: c7 44 24 0c 1c d1 10 movl $0xc010d11c,0xc(%esp) +c010639a: c0 +c010639b: c7 44 24 08 e9 ce 10 movl $0xc010cee9,0x8(%esp) +c01063a2: c0 +c01063a3: c7 44 24 04 26 03 00 movl $0x326,0x4(%esp) +c01063aa: 00 +c01063ab: c7 04 24 c4 ce 10 c0 movl $0xc010cec4,(%esp) +c01063b2: e8 84 a9 ff ff call c0100d3b <__panic> + // 验证页表项设置了用户权限 + assert(*ptep & PTE_U); +c01063b7: 8b 45 f0 mov -0x10(%ebp),%eax +c01063ba: 8b 00 mov (%eax),%eax +c01063bc: 83 e0 04 and $0x4,%eax +c01063bf: 85 c0 test %eax,%eax +c01063c1: 75 24 jne c01063e7 +c01063c3: c7 44 24 0c 4c d1 10 movl $0xc010d14c,0xc(%esp) +c01063ca: c0 +c01063cb: c7 44 24 08 e9 ce 10 movl $0xc010cee9,0x8(%esp) +c01063d2: c0 +c01063d3: c7 44 24 04 28 03 00 movl $0x328,0x4(%esp) +c01063da: 00 +c01063db: c7 04 24 c4 ce 10 c0 movl $0xc010cec4,(%esp) +c01063e2: e8 54 a9 ff ff call c0100d3b <__panic> + // 验证页表项设置了写权限 + assert(*ptep & PTE_W); +c01063e7: 8b 45 f0 mov -0x10(%ebp),%eax +c01063ea: 8b 00 mov (%eax),%eax +c01063ec: 83 e0 02 and $0x2,%eax +c01063ef: 85 c0 test %eax,%eax +c01063f1: 75 24 jne c0106417 +c01063f3: c7 44 24 0c 5a d1 10 movl $0xc010d15a,0xc(%esp) +c01063fa: c0 +c01063fb: c7 44 24 08 e9 ce 10 movl $0xc010cee9,0x8(%esp) +c0106402: c0 +c0106403: c7 44 24 04 2a 03 00 movl $0x32a,0x4(%esp) +c010640a: 00 +c010640b: c7 04 24 c4 ce 10 c0 movl $0xc010cec4,(%esp) +c0106412: e8 24 a9 ff ff call c0100d3b <__panic> + // 验证页目录项设置了用户权限 + assert(boot_pgdir[0] & PTE_U); +c0106417: a1 00 fa 12 c0 mov 0xc012fa00,%eax +c010641c: 8b 00 mov (%eax),%eax +c010641e: 83 e0 04 and $0x4,%eax +c0106421: 85 c0 test %eax,%eax +c0106423: 75 24 jne c0106449 +c0106425: c7 44 24 0c 68 d1 10 movl $0xc010d168,0xc(%esp) +c010642c: c0 +c010642d: c7 44 24 08 e9 ce 10 movl $0xc010cee9,0x8(%esp) +c0106434: c0 +c0106435: c7 44 24 04 2c 03 00 movl $0x32c,0x4(%esp) +c010643c: 00 +c010643d: c7 04 24 c4 ce 10 c0 movl $0xc010cec4,(%esp) +c0106444: e8 f2 a8 ff ff call c0100d3b <__panic> + // 验证 p2 的引用计数为 1 + assert(page_ref(p2) == 1); +c0106449: 8b 45 e4 mov -0x1c(%ebp),%eax +c010644c: 89 04 24 mov %eax,(%esp) +c010644f: e8 1d eb ff ff call c0104f71 +c0106454: 83 f8 01 cmp $0x1,%eax +c0106457: 74 24 je c010647d +c0106459: c7 44 24 0c 7e d1 10 movl $0xc010d17e,0xc(%esp) +c0106460: c0 +c0106461: c7 44 24 08 e9 ce 10 movl $0xc010cee9,0x8(%esp) +c0106468: c0 +c0106469: c7 44 24 04 2e 03 00 movl $0x32e,0x4(%esp) +c0106470: 00 +c0106471: c7 04 24 c4 ce 10 c0 movl $0xc010cec4,(%esp) +c0106478: e8 be a8 ff ff call c0100d3b <__panic> + + // 将 p1 插入到虚拟地址 PGSIZE,替换掉 p2 + assert(page_insert(boot_pgdir, p1, PGSIZE, 0) == 0); +c010647d: a1 00 fa 12 c0 mov 0xc012fa00,%eax +c0106482: c7 44 24 0c 00 00 00 movl $0x0,0xc(%esp) +c0106489: 00 +c010648a: c7 44 24 08 00 10 00 movl $0x1000,0x8(%esp) +c0106491: 00 +c0106492: 8b 55 f4 mov -0xc(%ebp),%edx +c0106495: 89 54 24 04 mov %edx,0x4(%esp) +c0106499: 89 04 24 mov %eax,(%esp) +c010649c: e8 02 fa ff ff call c0105ea3 +c01064a1: 85 c0 test %eax,%eax +c01064a3: 74 24 je c01064c9 +c01064a5: c7 44 24 0c 90 d1 10 movl $0xc010d190,0xc(%esp) +c01064ac: c0 +c01064ad: c7 44 24 08 e9 ce 10 movl $0xc010cee9,0x8(%esp) +c01064b4: c0 +c01064b5: c7 44 24 04 31 03 00 movl $0x331,0x4(%esp) +c01064bc: 00 +c01064bd: c7 04 24 c4 ce 10 c0 movl $0xc010cec4,(%esp) +c01064c4: e8 72 a8 ff ff call c0100d3b <__panic> + // 验证 p1 的引用计数增加到 2 + assert(page_ref(p1) == 2); +c01064c9: 8b 45 f4 mov -0xc(%ebp),%eax +c01064cc: 89 04 24 mov %eax,(%esp) +c01064cf: e8 9d ea ff ff call c0104f71 +c01064d4: 83 f8 02 cmp $0x2,%eax +c01064d7: 74 24 je c01064fd +c01064d9: c7 44 24 0c bc d1 10 movl $0xc010d1bc,0xc(%esp) +c01064e0: c0 +c01064e1: c7 44 24 08 e9 ce 10 movl $0xc010cee9,0x8(%esp) +c01064e8: c0 +c01064e9: c7 44 24 04 33 03 00 movl $0x333,0x4(%esp) +c01064f0: 00 +c01064f1: c7 04 24 c4 ce 10 c0 movl $0xc010cec4,(%esp) +c01064f8: e8 3e a8 ff ff call c0100d3b <__panic> + // 验证 p2 的引用计数减少到 0 + assert(page_ref(p2) == 0); +c01064fd: 8b 45 e4 mov -0x1c(%ebp),%eax +c0106500: 89 04 24 mov %eax,(%esp) +c0106503: e8 69 ea ff ff call c0104f71 +c0106508: 85 c0 test %eax,%eax +c010650a: 74 24 je c0106530 +c010650c: c7 44 24 0c ce d1 10 movl $0xc010d1ce,0xc(%esp) +c0106513: c0 +c0106514: c7 44 24 08 e9 ce 10 movl $0xc010cee9,0x8(%esp) +c010651b: c0 +c010651c: c7 44 24 04 35 03 00 movl $0x335,0x4(%esp) +c0106523: 00 +c0106524: c7 04 24 c4 ce 10 c0 movl $0xc010cec4,(%esp) +c010652b: e8 0b a8 ff ff call c0100d3b <__panic> + // 获取虚拟地址 PGSIZE 对应的页表项指针 + assert((ptep = get_pte(boot_pgdir, PGSIZE, 0)) != NULL); +c0106530: a1 00 fa 12 c0 mov 0xc012fa00,%eax +c0106535: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) +c010653c: 00 +c010653d: c7 44 24 04 00 10 00 movl $0x1000,0x4(%esp) +c0106544: 00 +c0106545: 89 04 24 mov %eax,(%esp) +c0106548: e8 ef f2 ff ff call c010583c +c010654d: 89 45 f0 mov %eax,-0x10(%ebp) +c0106550: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) +c0106554: 75 24 jne c010657a +c0106556: c7 44 24 0c 1c d1 10 movl $0xc010d11c,0xc(%esp) +c010655d: c0 +c010655e: c7 44 24 08 e9 ce 10 movl $0xc010cee9,0x8(%esp) +c0106565: c0 +c0106566: c7 44 24 04 37 03 00 movl $0x337,0x4(%esp) +c010656d: 00 +c010656e: c7 04 24 c4 ce 10 c0 movl $0xc010cec4,(%esp) +c0106575: e8 c1 a7 ff ff call c0100d3b <__panic> + // 验证页表项对应的页面是 p1 + assert(pte2page(*ptep) == p1); +c010657a: 8b 45 f0 mov -0x10(%ebp),%eax +c010657d: 8b 00 mov (%eax),%eax +c010657f: 89 04 24 mov %eax,(%esp) +c0106582: e8 90 e9 ff ff call c0104f17 +c0106587: 39 45 f4 cmp %eax,-0xc(%ebp) +c010658a: 74 24 je c01065b0 +c010658c: c7 44 24 0c 91 d0 10 movl $0xc010d091,0xc(%esp) +c0106593: c0 +c0106594: c7 44 24 08 e9 ce 10 movl $0xc010cee9,0x8(%esp) +c010659b: c0 +c010659c: c7 44 24 04 39 03 00 movl $0x339,0x4(%esp) +c01065a3: 00 +c01065a4: c7 04 24 c4 ce 10 c0 movl $0xc010cec4,(%esp) +c01065ab: e8 8b a7 ff ff call c0100d3b <__panic> + // 验证页表项没有设置用户权限 + assert((*ptep & PTE_U) == 0); +c01065b0: 8b 45 f0 mov -0x10(%ebp),%eax +c01065b3: 8b 00 mov (%eax),%eax +c01065b5: 83 e0 04 and $0x4,%eax +c01065b8: 85 c0 test %eax,%eax +c01065ba: 74 24 je c01065e0 +c01065bc: c7 44 24 0c e0 d1 10 movl $0xc010d1e0,0xc(%esp) +c01065c3: c0 +c01065c4: c7 44 24 08 e9 ce 10 movl $0xc010cee9,0x8(%esp) +c01065cb: c0 +c01065cc: c7 44 24 04 3b 03 00 movl $0x33b,0x4(%esp) +c01065d3: 00 +c01065d4: c7 04 24 c4 ce 10 c0 movl $0xc010cec4,(%esp) +c01065db: e8 5b a7 ff ff call c0100d3b <__panic> + + //移除虚拟地址 0x0 的映射, + page_remove(boot_pgdir, 0x0); +c01065e0: a1 00 fa 12 c0 mov 0xc012fa00,%eax +c01065e5: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) +c01065ec: 00 +c01065ed: 89 04 24 mov %eax,(%esp) +c01065f0: e8 67 f8 ff ff call c0105e5c + //验证 p1 的引用计数减少到 1。 + assert(page_ref(p1) == 1); +c01065f5: 8b 45 f4 mov -0xc(%ebp),%eax +c01065f8: 89 04 24 mov %eax,(%esp) +c01065fb: e8 71 e9 ff ff call c0104f71 +c0106600: 83 f8 01 cmp $0x1,%eax +c0106603: 74 24 je c0106629 +c0106605: c7 44 24 0c a7 d0 10 movl $0xc010d0a7,0xc(%esp) +c010660c: c0 +c010660d: c7 44 24 08 e9 ce 10 movl $0xc010cee9,0x8(%esp) +c0106614: c0 +c0106615: c7 44 24 04 40 03 00 movl $0x340,0x4(%esp) +c010661c: 00 +c010661d: c7 04 24 c4 ce 10 c0 movl $0xc010cec4,(%esp) +c0106624: e8 12 a7 ff ff call c0100d3b <__panic> + //验证 p2 的引用计数减少到 0 + assert(page_ref(p2) == 0); +c0106629: 8b 45 e4 mov -0x1c(%ebp),%eax +c010662c: 89 04 24 mov %eax,(%esp) +c010662f: e8 3d e9 ff ff call c0104f71 +c0106634: 85 c0 test %eax,%eax +c0106636: 74 24 je c010665c +c0106638: c7 44 24 0c ce d1 10 movl $0xc010d1ce,0xc(%esp) +c010663f: c0 +c0106640: c7 44 24 08 e9 ce 10 movl $0xc010cee9,0x8(%esp) +c0106647: c0 +c0106648: c7 44 24 04 42 03 00 movl $0x342,0x4(%esp) +c010664f: 00 +c0106650: c7 04 24 c4 ce 10 c0 movl $0xc010cec4,(%esp) +c0106657: e8 df a6 ff ff call c0100d3b <__panic> + + //移除虚拟地址 PGSIZE 的映射, + page_remove(boot_pgdir, PGSIZE); +c010665c: a1 00 fa 12 c0 mov 0xc012fa00,%eax +c0106661: c7 44 24 04 00 10 00 movl $0x1000,0x4(%esp) +c0106668: 00 +c0106669: 89 04 24 mov %eax,(%esp) +c010666c: e8 eb f7 ff ff call c0105e5c + //验证 p1 的引用计数减少到 0 + assert(page_ref(p1) == 0); +c0106671: 8b 45 f4 mov -0xc(%ebp),%eax +c0106674: 89 04 24 mov %eax,(%esp) +c0106677: e8 f5 e8 ff ff call c0104f71 +c010667c: 85 c0 test %eax,%eax +c010667e: 74 24 je c01066a4 +c0106680: c7 44 24 0c f5 d1 10 movl $0xc010d1f5,0xc(%esp) +c0106687: c0 +c0106688: c7 44 24 08 e9 ce 10 movl $0xc010cee9,0x8(%esp) +c010668f: c0 +c0106690: c7 44 24 04 47 03 00 movl $0x347,0x4(%esp) +c0106697: 00 +c0106698: c7 04 24 c4 ce 10 c0 movl $0xc010cec4,(%esp) +c010669f: e8 97 a6 ff ff call c0100d3b <__panic> + //验证 p2 的引用计数减少到 0 + assert(page_ref(p2) == 0); +c01066a4: 8b 45 e4 mov -0x1c(%ebp),%eax +c01066a7: 89 04 24 mov %eax,(%esp) +c01066aa: e8 c2 e8 ff ff call c0104f71 +c01066af: 85 c0 test %eax,%eax +c01066b1: 74 24 je c01066d7 +c01066b3: c7 44 24 0c ce d1 10 movl $0xc010d1ce,0xc(%esp) +c01066ba: c0 +c01066bb: c7 44 24 08 e9 ce 10 movl $0xc010cee9,0x8(%esp) +c01066c2: c0 +c01066c3: c7 44 24 04 49 03 00 movl $0x349,0x4(%esp) +c01066ca: 00 +c01066cb: c7 04 24 c4 ce 10 c0 movl $0xc010cec4,(%esp) +c01066d2: e8 64 a6 ff ff call c0100d3b <__panic> + + //验证页目录的第一页表的引用计数为 1。 + assert(page_ref(pde2page(boot_pgdir[0])) == 1); +c01066d7: a1 00 fa 12 c0 mov 0xc012fa00,%eax +c01066dc: 8b 00 mov (%eax),%eax +c01066de: 89 04 24 mov %eax,(%esp) +c01066e1: e8 71 e8 ff ff call c0104f57 +c01066e6: 89 04 24 mov %eax,(%esp) +c01066e9: e8 83 e8 ff ff call c0104f71 +c01066ee: 83 f8 01 cmp $0x1,%eax +c01066f1: 74 24 je c0106717 +c01066f3: c7 44 24 0c 08 d2 10 movl $0xc010d208,0xc(%esp) +c01066fa: c0 +c01066fb: c7 44 24 08 e9 ce 10 movl $0xc010cee9,0x8(%esp) +c0106702: c0 +c0106703: c7 44 24 04 4c 03 00 movl $0x34c,0x4(%esp) +c010670a: 00 +c010670b: c7 04 24 c4 ce 10 c0 movl $0xc010cec4,(%esp) +c0106712: e8 24 a6 ff ff call c0100d3b <__panic> + //释放页目录的第一页表 + free_page(pde2page(boot_pgdir[0])); +c0106717: a1 00 fa 12 c0 mov 0xc012fa00,%eax +c010671c: 8b 00 mov (%eax),%eax +c010671e: 89 04 24 mov %eax,(%esp) +c0106721: e8 31 e8 ff ff call c0104f57 +c0106726: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c010672d: 00 +c010672e: 89 04 24 mov %eax,(%esp) +c0106731: e8 b8 ea ff ff call c01051ee + //清空页目录的第一页表 + boot_pgdir[0] = 0; +c0106736: a1 00 fa 12 c0 mov 0xc012fa00,%eax +c010673b: c7 00 00 00 00 00 movl $0x0,(%eax) + + cprintf("check_pgdir() succeeded!\n"); +c0106741: c7 04 24 2f d2 10 c0 movl $0xc010d22f,(%esp) +c0106748: e8 2b 9c ff ff call c0100378 +} +c010674d: 90 nop +c010674e: 89 ec mov %ebp,%esp +c0106750: 5d pop %ebp +c0106751: c3 ret + +c0106752 : + +//检查内核页表 boot_pgdir 的正确性 +static void +check_boot_pgdir(void) { +c0106752: 55 push %ebp +c0106753: 89 e5 mov %esp,%ebp +c0106755: 83 ec 38 sub $0x38,%esp + pte_t *ptep;// 定义一个指向页表项的指针 + int i; + for (i = 0; i < npage; i += PGSIZE) {// 遍历所有页面 +c0106758: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) +c010675f: e9 ca 00 00 00 jmp c010682e + // 获取第 i 个页面的页表项,并确保其不为空 + assert((ptep = get_pte(boot_pgdir, (uintptr_t)KADDR(i), 0)) != NULL); +c0106764: 8b 45 f4 mov -0xc(%ebp),%eax +c0106767: 89 45 e4 mov %eax,-0x1c(%ebp) +c010676a: 8b 45 e4 mov -0x1c(%ebp),%eax +c010676d: c1 e8 0c shr $0xc,%eax +c0106770: 89 45 e0 mov %eax,-0x20(%ebp) +c0106773: a1 a4 3f 1a c0 mov 0xc01a3fa4,%eax +c0106778: 39 45 e0 cmp %eax,-0x20(%ebp) +c010677b: 72 23 jb c01067a0 +c010677d: 8b 45 e4 mov -0x1c(%ebp),%eax +c0106780: 89 44 24 0c mov %eax,0xc(%esp) +c0106784: c7 44 24 08 fc cd 10 movl $0xc010cdfc,0x8(%esp) +c010678b: c0 +c010678c: c7 44 24 04 5c 03 00 movl $0x35c,0x4(%esp) +c0106793: 00 +c0106794: c7 04 24 c4 ce 10 c0 movl $0xc010cec4,(%esp) +c010679b: e8 9b a5 ff ff call c0100d3b <__panic> +c01067a0: 8b 45 e4 mov -0x1c(%ebp),%eax +c01067a3: 2d 00 00 00 40 sub $0x40000000,%eax +c01067a8: 89 c2 mov %eax,%edx +c01067aa: a1 00 fa 12 c0 mov 0xc012fa00,%eax +c01067af: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) +c01067b6: 00 +c01067b7: 89 54 24 04 mov %edx,0x4(%esp) +c01067bb: 89 04 24 mov %eax,(%esp) +c01067be: e8 79 f0 ff ff call c010583c +c01067c3: 89 45 dc mov %eax,-0x24(%ebp) +c01067c6: 83 7d dc 00 cmpl $0x0,-0x24(%ebp) +c01067ca: 75 24 jne c01067f0 +c01067cc: c7 44 24 0c 4c d2 10 movl $0xc010d24c,0xc(%esp) +c01067d3: c0 +c01067d4: c7 44 24 08 e9 ce 10 movl $0xc010cee9,0x8(%esp) +c01067db: c0 +c01067dc: c7 44 24 04 5c 03 00 movl $0x35c,0x4(%esp) +c01067e3: 00 +c01067e4: c7 04 24 c4 ce 10 c0 movl $0xc010cec4,(%esp) +c01067eb: e8 4b a5 ff ff call c0100d3b <__panic> + // 验证页表项的物理地址是否正确 + assert(PTE_ADDR(*ptep) == i); +c01067f0: 8b 45 dc mov -0x24(%ebp),%eax +c01067f3: 8b 00 mov (%eax),%eax +c01067f5: 25 00 f0 ff ff and $0xfffff000,%eax +c01067fa: 89 c2 mov %eax,%edx +c01067fc: 8b 45 f4 mov -0xc(%ebp),%eax +c01067ff: 39 c2 cmp %eax,%edx +c0106801: 74 24 je c0106827 +c0106803: c7 44 24 0c 89 d2 10 movl $0xc010d289,0xc(%esp) +c010680a: c0 +c010680b: c7 44 24 08 e9 ce 10 movl $0xc010cee9,0x8(%esp) +c0106812: c0 +c0106813: c7 44 24 04 5e 03 00 movl $0x35e,0x4(%esp) +c010681a: 00 +c010681b: c7 04 24 c4 ce 10 c0 movl $0xc010cec4,(%esp) +c0106822: e8 14 a5 ff ff call c0100d3b <__panic> + for (i = 0; i < npage; i += PGSIZE) {// 遍历所有页面 +c0106827: 81 45 f4 00 10 00 00 addl $0x1000,-0xc(%ebp) +c010682e: 8b 55 f4 mov -0xc(%ebp),%edx +c0106831: a1 a4 3f 1a c0 mov 0xc01a3fa4,%eax +c0106836: 39 c2 cmp %eax,%edx +c0106838: 0f 82 26 ff ff ff jb c0106764 + } + // 验证页目录项的物理地址是否正确 + assert(PDE_ADDR(boot_pgdir[PDX(VPT)]) == PADDR(boot_pgdir)); +c010683e: a1 00 fa 12 c0 mov 0xc012fa00,%eax +c0106843: 05 ac 0f 00 00 add $0xfac,%eax +c0106848: 8b 00 mov (%eax),%eax +c010684a: 25 00 f0 ff ff and $0xfffff000,%eax +c010684f: 89 c2 mov %eax,%edx +c0106851: a1 00 fa 12 c0 mov 0xc012fa00,%eax +c0106856: 89 45 f0 mov %eax,-0x10(%ebp) +c0106859: 81 7d f0 ff ff ff bf cmpl $0xbfffffff,-0x10(%ebp) +c0106860: 77 23 ja c0106885 +c0106862: 8b 45 f0 mov -0x10(%ebp),%eax +c0106865: 89 44 24 0c mov %eax,0xc(%esp) +c0106869: c7 44 24 08 a0 ce 10 movl $0xc010cea0,0x8(%esp) +c0106870: c0 +c0106871: c7 44 24 04 61 03 00 movl $0x361,0x4(%esp) +c0106878: 00 +c0106879: c7 04 24 c4 ce 10 c0 movl $0xc010cec4,(%esp) +c0106880: e8 b6 a4 ff ff call c0100d3b <__panic> +c0106885: 8b 45 f0 mov -0x10(%ebp),%eax +c0106888: 05 00 00 00 40 add $0x40000000,%eax +c010688d: 39 d0 cmp %edx,%eax +c010688f: 74 24 je c01068b5 +c0106891: c7 44 24 0c a0 d2 10 movl $0xc010d2a0,0xc(%esp) +c0106898: c0 +c0106899: c7 44 24 08 e9 ce 10 movl $0xc010cee9,0x8(%esp) +c01068a0: c0 +c01068a1: c7 44 24 04 61 03 00 movl $0x361,0x4(%esp) +c01068a8: 00 +c01068a9: c7 04 24 c4 ce 10 c0 movl $0xc010cec4,(%esp) +c01068b0: e8 86 a4 ff ff call c0100d3b <__panic> + + assert(boot_pgdir[0] == 0);// 确保页目录的第一个项为0 +c01068b5: a1 00 fa 12 c0 mov 0xc012fa00,%eax +c01068ba: 8b 00 mov (%eax),%eax +c01068bc: 85 c0 test %eax,%eax +c01068be: 74 24 je c01068e4 +c01068c0: c7 44 24 0c d4 d2 10 movl $0xc010d2d4,0xc(%esp) +c01068c7: c0 +c01068c8: c7 44 24 08 e9 ce 10 movl $0xc010cee9,0x8(%esp) +c01068cf: c0 +c01068d0: c7 44 24 04 63 03 00 movl $0x363,0x4(%esp) +c01068d7: 00 +c01068d8: c7 04 24 c4 ce 10 c0 movl $0xc010cec4,(%esp) +c01068df: e8 57 a4 ff ff call c0100d3b <__panic> + + struct Page *p;// 定义一个指向页面的指针 + p = alloc_page();// 分配一个页面 +c01068e4: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c01068eb: e8 91 e8 ff ff call c0105181 +c01068f0: 89 45 ec mov %eax,-0x14(%ebp) + // 将页面插入到虚拟地址 0x100,并确保操作成功 + assert(page_insert(boot_pgdir, p, 0x100, PTE_W) == 0); +c01068f3: a1 00 fa 12 c0 mov 0xc012fa00,%eax +c01068f8: c7 44 24 0c 02 00 00 movl $0x2,0xc(%esp) +c01068ff: 00 +c0106900: c7 44 24 08 00 01 00 movl $0x100,0x8(%esp) +c0106907: 00 +c0106908: 8b 55 ec mov -0x14(%ebp),%edx +c010690b: 89 54 24 04 mov %edx,0x4(%esp) +c010690f: 89 04 24 mov %eax,(%esp) +c0106912: e8 8c f5 ff ff call c0105ea3 +c0106917: 85 c0 test %eax,%eax +c0106919: 74 24 je c010693f +c010691b: c7 44 24 0c e8 d2 10 movl $0xc010d2e8,0xc(%esp) +c0106922: c0 +c0106923: c7 44 24 08 e9 ce 10 movl $0xc010cee9,0x8(%esp) +c010692a: c0 +c010692b: c7 44 24 04 68 03 00 movl $0x368,0x4(%esp) +c0106932: 00 +c0106933: c7 04 24 c4 ce 10 c0 movl $0xc010cec4,(%esp) +c010693a: e8 fc a3 ff ff call c0100d3b <__panic> + assert(page_ref(p) == 1);// 验证页面的引用计数为1 +c010693f: 8b 45 ec mov -0x14(%ebp),%eax +c0106942: 89 04 24 mov %eax,(%esp) +c0106945: e8 27 e6 ff ff call c0104f71 +c010694a: 83 f8 01 cmp $0x1,%eax +c010694d: 74 24 je c0106973 +c010694f: c7 44 24 0c 16 d3 10 movl $0xc010d316,0xc(%esp) +c0106956: c0 +c0106957: c7 44 24 08 e9 ce 10 movl $0xc010cee9,0x8(%esp) +c010695e: c0 +c010695f: c7 44 24 04 69 03 00 movl $0x369,0x4(%esp) +c0106966: 00 +c0106967: c7 04 24 c4 ce 10 c0 movl $0xc010cec4,(%esp) +c010696e: e8 c8 a3 ff ff call c0100d3b <__panic> + // 将页面插入到虚拟地址 0x100 + PGSIZE,并确保操作成功 + assert(page_insert(boot_pgdir, p, 0x100 + PGSIZE, PTE_W) == 0); +c0106973: a1 00 fa 12 c0 mov 0xc012fa00,%eax +c0106978: c7 44 24 0c 02 00 00 movl $0x2,0xc(%esp) +c010697f: 00 +c0106980: c7 44 24 08 00 11 00 movl $0x1100,0x8(%esp) +c0106987: 00 +c0106988: 8b 55 ec mov -0x14(%ebp),%edx +c010698b: 89 54 24 04 mov %edx,0x4(%esp) +c010698f: 89 04 24 mov %eax,(%esp) +c0106992: e8 0c f5 ff ff call c0105ea3 +c0106997: 85 c0 test %eax,%eax +c0106999: 74 24 je c01069bf +c010699b: c7 44 24 0c 28 d3 10 movl $0xc010d328,0xc(%esp) +c01069a2: c0 +c01069a3: c7 44 24 08 e9 ce 10 movl $0xc010cee9,0x8(%esp) +c01069aa: c0 +c01069ab: c7 44 24 04 6b 03 00 movl $0x36b,0x4(%esp) +c01069b2: 00 +c01069b3: c7 04 24 c4 ce 10 c0 movl $0xc010cec4,(%esp) +c01069ba: e8 7c a3 ff ff call c0100d3b <__panic> + assert(page_ref(p) == 2);// 验证页面的引用计数为2 +c01069bf: 8b 45 ec mov -0x14(%ebp),%eax +c01069c2: 89 04 24 mov %eax,(%esp) +c01069c5: e8 a7 e5 ff ff call c0104f71 +c01069ca: 83 f8 02 cmp $0x2,%eax +c01069cd: 74 24 je c01069f3 +c01069cf: c7 44 24 0c 5f d3 10 movl $0xc010d35f,0xc(%esp) +c01069d6: c0 +c01069d7: c7 44 24 08 e9 ce 10 movl $0xc010cee9,0x8(%esp) +c01069de: c0 +c01069df: c7 44 24 04 6c 03 00 movl $0x36c,0x4(%esp) +c01069e6: 00 +c01069e7: c7 04 24 c4 ce 10 c0 movl $0xc010cec4,(%esp) +c01069ee: e8 48 a3 ff ff call c0100d3b <__panic> + + const char *str = "ucore: Hello world!!";// 定义一个字符串 +c01069f3: c7 45 e8 70 d3 10 c0 movl $0xc010d370,-0x18(%ebp) + strcpy((void *)0x100, str);// 将字符串复制到虚拟地址 0x100 +c01069fa: 8b 45 e8 mov -0x18(%ebp),%eax +c01069fd: 89 44 24 04 mov %eax,0x4(%esp) +c0106a01: c7 04 24 00 01 00 00 movl $0x100,(%esp) +c0106a08: e8 14 51 00 00 call c010bb21 + // 验证两个映射地址的数据是否一致 + assert(strcmp((void *)0x100, (void *)(0x100 + PGSIZE)) == 0); +c0106a0d: c7 44 24 04 00 11 00 movl $0x1100,0x4(%esp) +c0106a14: 00 +c0106a15: c7 04 24 00 01 00 00 movl $0x100,(%esp) +c0106a1c: e8 78 51 00 00 call c010bb99 +c0106a21: 85 c0 test %eax,%eax +c0106a23: 74 24 je c0106a49 +c0106a25: c7 44 24 0c 88 d3 10 movl $0xc010d388,0xc(%esp) +c0106a2c: c0 +c0106a2d: c7 44 24 08 e9 ce 10 movl $0xc010cee9,0x8(%esp) +c0106a34: c0 +c0106a35: c7 44 24 04 71 03 00 movl $0x371,0x4(%esp) +c0106a3c: 00 +c0106a3d: c7 04 24 c4 ce 10 c0 movl $0xc010cec4,(%esp) +c0106a44: e8 f2 a2 ff ff call c0100d3b <__panic> + // 在页面的 0x100 偏移处设置字符串结束符 + *(char *)(page2kva(p) + 0x100) = '\0'; +c0106a49: 8b 45 ec mov -0x14(%ebp),%eax +c0106a4c: 89 04 24 mov %eax,(%esp) +c0106a4f: e8 6d e4 ff ff call c0104ec1 +c0106a54: 05 00 01 00 00 add $0x100,%eax +c0106a59: c6 00 00 movb $0x0,(%eax) + assert(strlen((const char *)0x100) == 0);// 验证字符串长度为0 +c0106a5c: c7 04 24 00 01 00 00 movl $0x100,(%esp) +c0106a63: e8 5f 50 00 00 call c010bac7 +c0106a68: 85 c0 test %eax,%eax +c0106a6a: 74 24 je c0106a90 +c0106a6c: c7 44 24 0c c0 d3 10 movl $0xc010d3c0,0xc(%esp) +c0106a73: c0 +c0106a74: c7 44 24 08 e9 ce 10 movl $0xc010cee9,0x8(%esp) +c0106a7b: c0 +c0106a7c: c7 44 24 04 74 03 00 movl $0x374,0x4(%esp) +c0106a83: 00 +c0106a84: c7 04 24 c4 ce 10 c0 movl $0xc010cec4,(%esp) +c0106a8b: e8 ab a2 ff ff call c0100d3b <__panic> + + free_page(p);// 释放页面 p +c0106a90: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c0106a97: 00 +c0106a98: 8b 45 ec mov -0x14(%ebp),%eax +c0106a9b: 89 04 24 mov %eax,(%esp) +c0106a9e: e8 4b e7 ff ff call c01051ee + free_page(pde2page(boot_pgdir[0]));// 释放页目录项对应的页面 +c0106aa3: a1 00 fa 12 c0 mov 0xc012fa00,%eax +c0106aa8: 8b 00 mov (%eax),%eax +c0106aaa: 89 04 24 mov %eax,(%esp) +c0106aad: e8 a5 e4 ff ff call c0104f57 +c0106ab2: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c0106ab9: 00 +c0106aba: 89 04 24 mov %eax,(%esp) +c0106abd: e8 2c e7 ff ff call c01051ee + boot_pgdir[0] = 0;// 将页目录的第一个项设为0 +c0106ac2: a1 00 fa 12 c0 mov 0xc012fa00,%eax +c0106ac7: c7 00 00 00 00 00 movl $0x0,(%eax) + + tlb_invalidate(boot_pgdir, 0x100); +c0106acd: a1 00 fa 12 c0 mov 0xc012fa00,%eax +c0106ad2: c7 44 24 04 00 01 00 movl $0x100,0x4(%esp) +c0106ad9: 00 +c0106ada: 89 04 24 mov %eax,(%esp) +c0106add: e8 7c f4 ff ff call c0105f5e + tlb_invalidate(boot_pgdir, 0x100+PGSIZE); +c0106ae2: a1 00 fa 12 c0 mov 0xc012fa00,%eax +c0106ae7: c7 44 24 04 00 11 00 movl $0x1100,0x4(%esp) +c0106aee: 00 +c0106aef: 89 04 24 mov %eax,(%esp) +c0106af2: e8 67 f4 ff ff call c0105f5e + + cprintf("check_boot_pgdir() succeeded!\n"); +c0106af7: c7 04 24 e4 d3 10 c0 movl $0xc010d3e4,(%esp) +c0106afe: e8 75 98 ff ff call c0100378 +} +c0106b03: 90 nop +c0106b04: 89 ec mov %ebp,%esp +c0106b06: 5d pop %ebp +c0106b07: c3 ret + +c0106b08 : + +//perm2str - use string 'u,r,w,-' to present the permission +static const char * +perm2str(int perm) { +c0106b08: 55 push %ebp +c0106b09: 89 e5 mov %esp,%ebp + //定义一个静态字符数组 str,长度为4 + static char str[4]; + //如果 perm 与 PTE_U 按位与的结果不为0,则 str[0] 设置为 'u',否则设置为 '-' + str[0] = (perm & PTE_U) ? 'u' : '-'; +c0106b0b: 8b 45 08 mov 0x8(%ebp),%eax +c0106b0e: 83 e0 04 and $0x4,%eax +c0106b11: 85 c0 test %eax,%eax +c0106b13: 74 04 je c0106b19 +c0106b15: b0 75 mov $0x75,%al +c0106b17: eb 02 jmp c0106b1b +c0106b19: b0 2d mov $0x2d,%al +c0106b1b: a2 28 40 1a c0 mov %al,0xc01a4028 + //str[1] 始终设置为 'r' + str[1] = 'r'; +c0106b20: c6 05 29 40 1a c0 72 movb $0x72,0xc01a4029 + //如果 perm 与 PTE_W 按位与的结果不为0,则 str[2] 设置为 'w',否则设置为 '-' + str[2] = (perm & PTE_W) ? 'w' : '-'; +c0106b27: 8b 45 08 mov 0x8(%ebp),%eax +c0106b2a: 83 e0 02 and $0x2,%eax +c0106b2d: 85 c0 test %eax,%eax +c0106b2f: 74 04 je c0106b35 +c0106b31: b0 77 mov $0x77,%al +c0106b33: eb 02 jmp c0106b37 +c0106b35: b0 2d mov $0x2d,%al +c0106b37: a2 2a 40 1a c0 mov %al,0xc01a402a + //str[3] 设置为字符串结束符 \0 + str[3] = '\0'; +c0106b3c: c6 05 2b 40 1a c0 00 movb $0x0,0xc01a402b + return str; +c0106b43: b8 28 40 1a c0 mov $0xc01a4028,%eax +} +c0106b48: 5d pop %ebp +c0106b49: c3 ret + +c0106b4a : +// left_store: the pointer of the high side of table's next range +// right_store: the pointer of the low side of table's next range +// return value: 0 - not a invalid item range, perm - a valid item range with perm permission +//从页表中获取指定范围内的有效项,并根据权限进行处理。 +static int +get_pgtable_items(size_t left, size_t right, size_t start, uintptr_t *table, size_t *left_store, size_t *right_store) { +c0106b4a: 55 push %ebp +c0106b4b: 89 e5 mov %esp,%ebp +c0106b4d: 83 ec 10 sub $0x10,%esp + if (start >= right) {// 检查起始索引是否超出右边界 +c0106b50: 8b 45 10 mov 0x10(%ebp),%eax +c0106b53: 3b 45 0c cmp 0xc(%ebp),%eax +c0106b56: 72 0d jb c0106b65 + return 0;// 如果超出右边界,返回0 +c0106b58: b8 00 00 00 00 mov $0x0,%eax +c0106b5d: e9 98 00 00 00 jmp c0106bfa + } + while (start < right && !(table[start] & PTE_P)) {// 查找第一个有效项(PTE_P位为1的项) + start ++;// 索引递增 +c0106b62: ff 45 10 incl 0x10(%ebp) + while (start < right && !(table[start] & PTE_P)) {// 查找第一个有效项(PTE_P位为1的项) +c0106b65: 8b 45 10 mov 0x10(%ebp),%eax +c0106b68: 3b 45 0c cmp 0xc(%ebp),%eax +c0106b6b: 73 18 jae c0106b85 +c0106b6d: 8b 45 10 mov 0x10(%ebp),%eax +c0106b70: 8d 14 85 00 00 00 00 lea 0x0(,%eax,4),%edx +c0106b77: 8b 45 14 mov 0x14(%ebp),%eax +c0106b7a: 01 d0 add %edx,%eax +c0106b7c: 8b 00 mov (%eax),%eax +c0106b7e: 83 e0 01 and $0x1,%eax +c0106b81: 85 c0 test %eax,%eax +c0106b83: 74 dd je c0106b62 + } + if (start < right) {// 检查是否找到有效项 +c0106b85: 8b 45 10 mov 0x10(%ebp),%eax +c0106b88: 3b 45 0c cmp 0xc(%ebp),%eax +c0106b8b: 73 68 jae c0106bf5 + if (left_store != NULL) {// 如果left_store不为NULL +c0106b8d: 83 7d 18 00 cmpl $0x0,0x18(%ebp) +c0106b91: 74 08 je c0106b9b + *left_store = start;// 记录左边界索引 +c0106b93: 8b 45 18 mov 0x18(%ebp),%eax +c0106b96: 8b 55 10 mov 0x10(%ebp),%edx +c0106b99: 89 10 mov %edx,(%eax) + } + int perm = (table[start ++] & PTE_USER);// 获取当前项的用户权限位并递增索引 +c0106b9b: 8b 45 10 mov 0x10(%ebp),%eax +c0106b9e: 8d 50 01 lea 0x1(%eax),%edx +c0106ba1: 89 55 10 mov %edx,0x10(%ebp) +c0106ba4: 8d 14 85 00 00 00 00 lea 0x0(,%eax,4),%edx +c0106bab: 8b 45 14 mov 0x14(%ebp),%eax +c0106bae: 01 d0 add %edx,%eax +c0106bb0: 8b 00 mov (%eax),%eax +c0106bb2: 83 e0 07 and $0x7,%eax +c0106bb5: 89 45 fc mov %eax,-0x4(%ebp) + while (start < right && (table[start] & PTE_USER) == perm) {// 查找具有相同用户权限的连续项 +c0106bb8: eb 03 jmp c0106bbd + start ++;// 索引递增 +c0106bba: ff 45 10 incl 0x10(%ebp) + while (start < right && (table[start] & PTE_USER) == perm) {// 查找具有相同用户权限的连续项 +c0106bbd: 8b 45 10 mov 0x10(%ebp),%eax +c0106bc0: 3b 45 0c cmp 0xc(%ebp),%eax +c0106bc3: 73 1d jae c0106be2 +c0106bc5: 8b 45 10 mov 0x10(%ebp),%eax +c0106bc8: 8d 14 85 00 00 00 00 lea 0x0(,%eax,4),%edx +c0106bcf: 8b 45 14 mov 0x14(%ebp),%eax +c0106bd2: 01 d0 add %edx,%eax +c0106bd4: 8b 00 mov (%eax),%eax +c0106bd6: 83 e0 07 and $0x7,%eax +c0106bd9: 89 c2 mov %eax,%edx +c0106bdb: 8b 45 fc mov -0x4(%ebp),%eax +c0106bde: 39 c2 cmp %eax,%edx +c0106be0: 74 d8 je c0106bba + } + if (right_store != NULL) {// 如果right_store不为NULL +c0106be2: 83 7d 1c 00 cmpl $0x0,0x1c(%ebp) +c0106be6: 74 08 je c0106bf0 + *right_store = start;// 记录右边界索引 +c0106be8: 8b 45 1c mov 0x1c(%ebp),%eax +c0106beb: 8b 55 10 mov 0x10(%ebp),%edx +c0106bee: 89 10 mov %edx,(%eax) + } + return perm;// 返回用户权限位 +c0106bf0: 8b 45 fc mov -0x4(%ebp),%eax +c0106bf3: eb 05 jmp c0106bfa + } + return 0;// 如果未找到有效项,返回0 +c0106bf5: b8 00 00 00 00 mov $0x0,%eax +} +c0106bfa: 89 ec mov %ebp,%esp +c0106bfc: 5d pop %ebp +c0106bfd: c3 ret + +c0106bfe : + +//print_pgdir - print the PDT&PT +void +print_pgdir(void) { +c0106bfe: 55 push %ebp +c0106bff: 89 e5 mov %esp,%ebp +c0106c01: 57 push %edi +c0106c02: 56 push %esi +c0106c03: 53 push %ebx +c0106c04: 83 ec 4c sub $0x4c,%esp + cprintf("-------------------- BEGIN --------------------\n"); +c0106c07: c7 04 24 04 d4 10 c0 movl $0xc010d404,(%esp) +c0106c0e: e8 65 97 ff ff call c0100378 + // 定义变量 left, right 和 perm + size_t left, right = 0, perm; +c0106c13: c7 45 dc 00 00 00 00 movl $0x0,-0x24(%ebp) + // 遍历页目录项 + while ((perm = get_pgtable_items(0, NPDEENTRY, right, vpd, &left, &right)) != 0) { +c0106c1a: e9 f2 00 00 00 jmp c0106d11 + // 打印页目录项的信息 + cprintf("PDE(%03x) %08x-%08x %08x %s\n", right - left, +c0106c1f: 8b 45 e4 mov -0x1c(%ebp),%eax +c0106c22: 89 04 24 mov %eax,(%esp) +c0106c25: e8 de fe ff ff call c0106b08 + left * PTSIZE, right * PTSIZE, (right - left) * PTSIZE, perm2str(perm)); +c0106c2a: 8b 55 dc mov -0x24(%ebp),%edx +c0106c2d: 8b 4d e0 mov -0x20(%ebp),%ecx +c0106c30: 29 ca sub %ecx,%edx + cprintf("PDE(%03x) %08x-%08x %08x %s\n", right - left, +c0106c32: 89 d6 mov %edx,%esi +c0106c34: c1 e6 16 shl $0x16,%esi +c0106c37: 8b 55 dc mov -0x24(%ebp),%edx +c0106c3a: 89 d3 mov %edx,%ebx +c0106c3c: c1 e3 16 shl $0x16,%ebx +c0106c3f: 8b 55 e0 mov -0x20(%ebp),%edx +c0106c42: 89 d1 mov %edx,%ecx +c0106c44: c1 e1 16 shl $0x16,%ecx +c0106c47: 8b 55 dc mov -0x24(%ebp),%edx +c0106c4a: 8b 7d e0 mov -0x20(%ebp),%edi +c0106c4d: 29 fa sub %edi,%edx +c0106c4f: 89 44 24 14 mov %eax,0x14(%esp) +c0106c53: 89 74 24 10 mov %esi,0x10(%esp) +c0106c57: 89 5c 24 0c mov %ebx,0xc(%esp) +c0106c5b: 89 4c 24 08 mov %ecx,0x8(%esp) +c0106c5f: 89 54 24 04 mov %edx,0x4(%esp) +c0106c63: c7 04 24 35 d4 10 c0 movl $0xc010d435,(%esp) +c0106c6a: e8 09 97 ff ff call c0100378 + // 计算页表项的起始和结束索引 + size_t l, r = left * NPTEENTRY; +c0106c6f: 8b 45 e0 mov -0x20(%ebp),%eax +c0106c72: c1 e0 0a shl $0xa,%eax +c0106c75: 89 45 d4 mov %eax,-0x2c(%ebp) + // 遍历页表项 + while ((perm = get_pgtable_items(left * NPTEENTRY, right * NPTEENTRY, r, vpt, &l, &r)) != 0) { +c0106c78: eb 50 jmp c0106cca + // 打印页表项的信息 + cprintf(" |-- PTE(%05x) %08x-%08x %08x %s\n", r - l, +c0106c7a: 8b 45 e4 mov -0x1c(%ebp),%eax +c0106c7d: 89 04 24 mov %eax,(%esp) +c0106c80: e8 83 fe ff ff call c0106b08 + l * PGSIZE, r * PGSIZE, (r - l) * PGSIZE, perm2str(perm)); +c0106c85: 8b 55 d4 mov -0x2c(%ebp),%edx +c0106c88: 8b 4d d8 mov -0x28(%ebp),%ecx +c0106c8b: 29 ca sub %ecx,%edx + cprintf(" |-- PTE(%05x) %08x-%08x %08x %s\n", r - l, +c0106c8d: 89 d6 mov %edx,%esi +c0106c8f: c1 e6 0c shl $0xc,%esi +c0106c92: 8b 55 d4 mov -0x2c(%ebp),%edx +c0106c95: 89 d3 mov %edx,%ebx +c0106c97: c1 e3 0c shl $0xc,%ebx +c0106c9a: 8b 55 d8 mov -0x28(%ebp),%edx +c0106c9d: 89 d1 mov %edx,%ecx +c0106c9f: c1 e1 0c shl $0xc,%ecx +c0106ca2: 8b 55 d4 mov -0x2c(%ebp),%edx +c0106ca5: 8b 7d d8 mov -0x28(%ebp),%edi +c0106ca8: 29 fa sub %edi,%edx +c0106caa: 89 44 24 14 mov %eax,0x14(%esp) +c0106cae: 89 74 24 10 mov %esi,0x10(%esp) +c0106cb2: 89 5c 24 0c mov %ebx,0xc(%esp) +c0106cb6: 89 4c 24 08 mov %ecx,0x8(%esp) +c0106cba: 89 54 24 04 mov %edx,0x4(%esp) +c0106cbe: c7 04 24 54 d4 10 c0 movl $0xc010d454,(%esp) +c0106cc5: e8 ae 96 ff ff call c0100378 + while ((perm = get_pgtable_items(left * NPTEENTRY, right * NPTEENTRY, r, vpt, &l, &r)) != 0) { +c0106cca: be 00 00 c0 fa mov $0xfac00000,%esi +c0106ccf: 8b 45 d4 mov -0x2c(%ebp),%eax +c0106cd2: 8b 55 dc mov -0x24(%ebp),%edx +c0106cd5: 89 d3 mov %edx,%ebx +c0106cd7: c1 e3 0a shl $0xa,%ebx +c0106cda: 8b 55 e0 mov -0x20(%ebp),%edx +c0106cdd: 89 d1 mov %edx,%ecx +c0106cdf: c1 e1 0a shl $0xa,%ecx +c0106ce2: 8d 55 d4 lea -0x2c(%ebp),%edx +c0106ce5: 89 54 24 14 mov %edx,0x14(%esp) +c0106ce9: 8d 55 d8 lea -0x28(%ebp),%edx +c0106cec: 89 54 24 10 mov %edx,0x10(%esp) +c0106cf0: 89 74 24 0c mov %esi,0xc(%esp) +c0106cf4: 89 44 24 08 mov %eax,0x8(%esp) +c0106cf8: 89 5c 24 04 mov %ebx,0x4(%esp) +c0106cfc: 89 0c 24 mov %ecx,(%esp) +c0106cff: e8 46 fe ff ff call c0106b4a +c0106d04: 89 45 e4 mov %eax,-0x1c(%ebp) +c0106d07: 83 7d e4 00 cmpl $0x0,-0x1c(%ebp) +c0106d0b: 0f 85 69 ff ff ff jne c0106c7a + while ((perm = get_pgtable_items(0, NPDEENTRY, right, vpd, &left, &right)) != 0) { +c0106d11: b9 00 b0 fe fa mov $0xfafeb000,%ecx +c0106d16: 8b 45 dc mov -0x24(%ebp),%eax +c0106d19: 8d 55 dc lea -0x24(%ebp),%edx +c0106d1c: 89 54 24 14 mov %edx,0x14(%esp) +c0106d20: 8d 55 e0 lea -0x20(%ebp),%edx +c0106d23: 89 54 24 10 mov %edx,0x10(%esp) +c0106d27: 89 4c 24 0c mov %ecx,0xc(%esp) +c0106d2b: 89 44 24 08 mov %eax,0x8(%esp) +c0106d2f: c7 44 24 04 00 04 00 movl $0x400,0x4(%esp) +c0106d36: 00 +c0106d37: c7 04 24 00 00 00 00 movl $0x0,(%esp) +c0106d3e: e8 07 fe ff ff call c0106b4a +c0106d43: 89 45 e4 mov %eax,-0x1c(%ebp) +c0106d46: 83 7d e4 00 cmpl $0x0,-0x1c(%ebp) +c0106d4a: 0f 85 cf fe ff ff jne c0106c1f + } + } + cprintf("--------------------- END ---------------------\n"); +c0106d50: c7 04 24 78 d4 10 c0 movl $0xc010d478,(%esp) +c0106d57: e8 1c 96 ff ff call c0100378 +} +c0106d5c: 90 nop +c0106d5d: 83 c4 4c add $0x4c,%esp +c0106d60: 5b pop %ebx +c0106d61: 5e pop %esi +c0106d62: 5f pop %edi +c0106d63: 5d pop %ebp +c0106d64: c3 ret + +c0106d65 : +pa2page(uintptr_t pa) { +c0106d65: 55 push %ebp +c0106d66: 89 e5 mov %esp,%ebp +c0106d68: 83 ec 18 sub $0x18,%esp + if (PPN(pa) >= npage) { +c0106d6b: 8b 45 08 mov 0x8(%ebp),%eax +c0106d6e: c1 e8 0c shr $0xc,%eax +c0106d71: 89 c2 mov %eax,%edx +c0106d73: a1 a4 3f 1a c0 mov 0xc01a3fa4,%eax +c0106d78: 39 c2 cmp %eax,%edx +c0106d7a: 72 1c jb c0106d98 + panic("pa2page called with invalid pa"); +c0106d7c: c7 44 24 08 ac d4 10 movl $0xc010d4ac,0x8(%esp) +c0106d83: c0 +c0106d84: c7 44 24 04 5e 00 00 movl $0x5e,0x4(%esp) +c0106d8b: 00 +c0106d8c: c7 04 24 cb d4 10 c0 movl $0xc010d4cb,(%esp) +c0106d93: e8 a3 9f ff ff call c0100d3b <__panic> + return &pages[PPN(pa)]; +c0106d98: 8b 15 a0 3f 1a c0 mov 0xc01a3fa0,%edx +c0106d9e: 8b 45 08 mov 0x8(%ebp),%eax +c0106da1: c1 e8 0c shr $0xc,%eax +c0106da4: c1 e0 05 shl $0x5,%eax +c0106da7: 01 d0 add %edx,%eax +} +c0106da9: 89 ec mov %ebp,%esp +c0106dab: 5d pop %ebp +c0106dac: c3 ret + +c0106dad : +pte2page(pte_t pte) { +c0106dad: 55 push %ebp +c0106dae: 89 e5 mov %esp,%ebp +c0106db0: 83 ec 18 sub $0x18,%esp + if (!(pte & PTE_P)) { +c0106db3: 8b 45 08 mov 0x8(%ebp),%eax +c0106db6: 83 e0 01 and $0x1,%eax +c0106db9: 85 c0 test %eax,%eax +c0106dbb: 75 1c jne c0106dd9 + panic("pte2page called with invalid pte"); +c0106dbd: c7 44 24 08 dc d4 10 movl $0xc010d4dc,0x8(%esp) +c0106dc4: c0 +c0106dc5: c7 44 24 04 70 00 00 movl $0x70,0x4(%esp) +c0106dcc: 00 +c0106dcd: c7 04 24 cb d4 10 c0 movl $0xc010d4cb,(%esp) +c0106dd4: e8 62 9f ff ff call c0100d3b <__panic> + return pa2page(PTE_ADDR(pte)); +c0106dd9: 8b 45 08 mov 0x8(%ebp),%eax +c0106ddc: 25 00 f0 ff ff and $0xfffff000,%eax +c0106de1: 89 04 24 mov %eax,(%esp) +c0106de4: e8 7c ff ff ff call c0106d65 +} +c0106de9: 89 ec mov %ebp,%esp +c0106deb: 5d pop %ebp +c0106dec: c3 ret + +c0106ded : +pde2page(pde_t pde) { +c0106ded: 55 push %ebp +c0106dee: 89 e5 mov %esp,%ebp +c0106df0: 83 ec 18 sub $0x18,%esp + return pa2page(PDE_ADDR(pde)); +c0106df3: 8b 45 08 mov 0x8(%ebp),%eax +c0106df6: 25 00 f0 ff ff and $0xfffff000,%eax +c0106dfb: 89 04 24 mov %eax,(%esp) +c0106dfe: e8 62 ff ff ff call c0106d65 +} +c0106e03: 89 ec mov %ebp,%esp +c0106e05: 5d pop %ebp +c0106e06: c3 ret + +c0106e07 : + +static void check_swap(void); + +int +swap_init(void) +{ +c0106e07: 55 push %ebp +c0106e08: 89 e5 mov %esp,%ebp +c0106e0a: 83 ec 28 sub $0x28,%esp + swapfs_init(); +c0106e0d: e8 ee 23 00 00 call c0109200 + + if (!(1024 <= max_swap_offset && max_swap_offset < MAX_SWAP_OFFSET_LIMIT)) +c0106e12: a1 40 40 1a c0 mov 0xc01a4040,%eax +c0106e17: 3d ff 03 00 00 cmp $0x3ff,%eax +c0106e1c: 76 0c jbe c0106e2a +c0106e1e: a1 40 40 1a c0 mov 0xc01a4040,%eax +c0106e23: 3d ff ff ff 00 cmp $0xffffff,%eax +c0106e28: 76 25 jbe c0106e4f + { + panic("bad max_swap_offset %08x.\n", max_swap_offset); +c0106e2a: a1 40 40 1a c0 mov 0xc01a4040,%eax +c0106e2f: 89 44 24 0c mov %eax,0xc(%esp) +c0106e33: c7 44 24 08 fd d4 10 movl $0xc010d4fd,0x8(%esp) +c0106e3a: c0 +c0106e3b: c7 44 24 04 27 00 00 movl $0x27,0x4(%esp) +c0106e42: 00 +c0106e43: c7 04 24 18 d5 10 c0 movl $0xc010d518,(%esp) +c0106e4a: e8 ec 9e ff ff call c0100d3b <__panic> + } + + + sm = &swap_manager_fifo; +c0106e4f: c7 05 00 41 1a c0 60 movl $0xc012fa60,0xc01a4100 +c0106e56: fa 12 c0 + int r = sm->init(); +c0106e59: a1 00 41 1a c0 mov 0xc01a4100,%eax +c0106e5e: 8b 40 04 mov 0x4(%eax),%eax +c0106e61: ff d0 call *%eax +c0106e63: 89 45 f4 mov %eax,-0xc(%ebp) + + if (r == 0) +c0106e66: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c0106e6a: 75 26 jne c0106e92 + { + swap_init_ok = 1; +c0106e6c: c7 05 44 40 1a c0 01 movl $0x1,0xc01a4044 +c0106e73: 00 00 00 + cprintf("SWAP: manager = %s\n", sm->name); +c0106e76: a1 00 41 1a c0 mov 0xc01a4100,%eax +c0106e7b: 8b 00 mov (%eax),%eax +c0106e7d: 89 44 24 04 mov %eax,0x4(%esp) +c0106e81: c7 04 24 27 d5 10 c0 movl $0xc010d527,(%esp) +c0106e88: e8 eb 94 ff ff call c0100378 + check_swap(); +c0106e8d: e8 b0 04 00 00 call c0107342 + } + + return r; +c0106e92: 8b 45 f4 mov -0xc(%ebp),%eax +} +c0106e95: 89 ec mov %ebp,%esp +c0106e97: 5d pop %ebp +c0106e98: c3 ret + +c0106e99 : + +int +swap_init_mm(struct mm_struct *mm) +{ +c0106e99: 55 push %ebp +c0106e9a: 89 e5 mov %esp,%ebp +c0106e9c: 83 ec 18 sub $0x18,%esp + return sm->init_mm(mm); +c0106e9f: a1 00 41 1a c0 mov 0xc01a4100,%eax +c0106ea4: 8b 40 08 mov 0x8(%eax),%eax +c0106ea7: 8b 55 08 mov 0x8(%ebp),%edx +c0106eaa: 89 14 24 mov %edx,(%esp) +c0106ead: ff d0 call *%eax +} +c0106eaf: 89 ec mov %ebp,%esp +c0106eb1: 5d pop %ebp +c0106eb2: c3 ret + +c0106eb3 : + +int +swap_tick_event(struct mm_struct *mm) +{ +c0106eb3: 55 push %ebp +c0106eb4: 89 e5 mov %esp,%ebp +c0106eb6: 83 ec 18 sub $0x18,%esp + return sm->tick_event(mm); +c0106eb9: a1 00 41 1a c0 mov 0xc01a4100,%eax +c0106ebe: 8b 40 0c mov 0xc(%eax),%eax +c0106ec1: 8b 55 08 mov 0x8(%ebp),%edx +c0106ec4: 89 14 24 mov %edx,(%esp) +c0106ec7: ff d0 call *%eax +} +c0106ec9: 89 ec mov %ebp,%esp +c0106ecb: 5d pop %ebp +c0106ecc: c3 ret + +c0106ecd : + +int +swap_map_swappable(struct mm_struct *mm, uintptr_t addr, struct Page *page, int swap_in) +{ +c0106ecd: 55 push %ebp +c0106ece: 89 e5 mov %esp,%ebp +c0106ed0: 83 ec 18 sub $0x18,%esp + return sm->map_swappable(mm, addr, page, swap_in); +c0106ed3: a1 00 41 1a c0 mov 0xc01a4100,%eax +c0106ed8: 8b 40 10 mov 0x10(%eax),%eax +c0106edb: 8b 55 14 mov 0x14(%ebp),%edx +c0106ede: 89 54 24 0c mov %edx,0xc(%esp) +c0106ee2: 8b 55 10 mov 0x10(%ebp),%edx +c0106ee5: 89 54 24 08 mov %edx,0x8(%esp) +c0106ee9: 8b 55 0c mov 0xc(%ebp),%edx +c0106eec: 89 54 24 04 mov %edx,0x4(%esp) +c0106ef0: 8b 55 08 mov 0x8(%ebp),%edx +c0106ef3: 89 14 24 mov %edx,(%esp) +c0106ef6: ff d0 call *%eax +} +c0106ef8: 89 ec mov %ebp,%esp +c0106efa: 5d pop %ebp +c0106efb: c3 ret + +c0106efc : + +int +swap_set_unswappable(struct mm_struct *mm, uintptr_t addr) +{ +c0106efc: 55 push %ebp +c0106efd: 89 e5 mov %esp,%ebp +c0106eff: 83 ec 18 sub $0x18,%esp + return sm->set_unswappable(mm, addr); +c0106f02: a1 00 41 1a c0 mov 0xc01a4100,%eax +c0106f07: 8b 40 14 mov 0x14(%eax),%eax +c0106f0a: 8b 55 0c mov 0xc(%ebp),%edx +c0106f0d: 89 54 24 04 mov %edx,0x4(%esp) +c0106f11: 8b 55 08 mov 0x8(%ebp),%edx +c0106f14: 89 14 24 mov %edx,(%esp) +c0106f17: ff d0 call *%eax +} +c0106f19: 89 ec mov %ebp,%esp +c0106f1b: 5d pop %ebp +c0106f1c: c3 ret + +c0106f1d : + +volatile unsigned int swap_out_num=0; + +int +swap_out(struct mm_struct *mm, int n, int in_tick) +{ +c0106f1d: 55 push %ebp +c0106f1e: 89 e5 mov %esp,%ebp +c0106f20: 83 ec 38 sub $0x38,%esp + int i; + for (i = 0; i != n; ++ i) +c0106f23: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) +c0106f2a: e9 53 01 00 00 jmp c0107082 + { + uintptr_t v; + //struct Page **ptr_page=NULL; + struct Page *page; + // cprintf("i %d, SWAP: call swap_out_victim\n",i); + int r = sm->swap_out_victim(mm, &page, in_tick); +c0106f2f: a1 00 41 1a c0 mov 0xc01a4100,%eax +c0106f34: 8b 40 18 mov 0x18(%eax),%eax +c0106f37: 8b 55 10 mov 0x10(%ebp),%edx +c0106f3a: 89 54 24 08 mov %edx,0x8(%esp) +c0106f3e: 8d 55 e4 lea -0x1c(%ebp),%edx +c0106f41: 89 54 24 04 mov %edx,0x4(%esp) +c0106f45: 8b 55 08 mov 0x8(%ebp),%edx +c0106f48: 89 14 24 mov %edx,(%esp) +c0106f4b: ff d0 call *%eax +c0106f4d: 89 45 f0 mov %eax,-0x10(%ebp) + if (r != 0) { +c0106f50: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) +c0106f54: 74 18 je c0106f6e + cprintf("i %d, swap_out: call swap_out_victim failed\n",i); +c0106f56: 8b 45 f4 mov -0xc(%ebp),%eax +c0106f59: 89 44 24 04 mov %eax,0x4(%esp) +c0106f5d: c7 04 24 3c d5 10 c0 movl $0xc010d53c,(%esp) +c0106f64: e8 0f 94 ff ff call c0100378 +c0106f69: e9 20 01 00 00 jmp c010708e + } + //assert(!PageReserved(page)); + + //cprintf("SWAP: choose victim page 0x%08x\n", page); + + v=page->pra_vaddr; +c0106f6e: 8b 45 e4 mov -0x1c(%ebp),%eax +c0106f71: 8b 40 1c mov 0x1c(%eax),%eax +c0106f74: 89 45 ec mov %eax,-0x14(%ebp) + pte_t *ptep = get_pte(mm->pgdir, v, 0); +c0106f77: 8b 45 08 mov 0x8(%ebp),%eax +c0106f7a: 8b 40 0c mov 0xc(%eax),%eax +c0106f7d: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) +c0106f84: 00 +c0106f85: 8b 55 ec mov -0x14(%ebp),%edx +c0106f88: 89 54 24 04 mov %edx,0x4(%esp) +c0106f8c: 89 04 24 mov %eax,(%esp) +c0106f8f: e8 a8 e8 ff ff call c010583c +c0106f94: 89 45 e8 mov %eax,-0x18(%ebp) + assert((*ptep & PTE_P) != 0); +c0106f97: 8b 45 e8 mov -0x18(%ebp),%eax +c0106f9a: 8b 00 mov (%eax),%eax +c0106f9c: 83 e0 01 and $0x1,%eax +c0106f9f: 85 c0 test %eax,%eax +c0106fa1: 75 24 jne c0106fc7 +c0106fa3: c7 44 24 0c 69 d5 10 movl $0xc010d569,0xc(%esp) +c0106faa: c0 +c0106fab: c7 44 24 08 7e d5 10 movl $0xc010d57e,0x8(%esp) +c0106fb2: c0 +c0106fb3: c7 44 24 04 67 00 00 movl $0x67,0x4(%esp) +c0106fba: 00 +c0106fbb: c7 04 24 18 d5 10 c0 movl $0xc010d518,(%esp) +c0106fc2: e8 74 9d ff ff call c0100d3b <__panic> + + if (swapfs_write( (page->pra_vaddr/PGSIZE+1)<<8, page) != 0) { +c0106fc7: 8b 45 e4 mov -0x1c(%ebp),%eax +c0106fca: 8b 55 e4 mov -0x1c(%ebp),%edx +c0106fcd: 8b 52 1c mov 0x1c(%edx),%edx +c0106fd0: c1 ea 0c shr $0xc,%edx +c0106fd3: 42 inc %edx +c0106fd4: c1 e2 08 shl $0x8,%edx +c0106fd7: 89 44 24 04 mov %eax,0x4(%esp) +c0106fdb: 89 14 24 mov %edx,(%esp) +c0106fde: e8 dc 22 00 00 call c01092bf +c0106fe3: 85 c0 test %eax,%eax +c0106fe5: 74 34 je c010701b + cprintf("SWAP: failed to save\n"); +c0106fe7: c7 04 24 93 d5 10 c0 movl $0xc010d593,(%esp) +c0106fee: e8 85 93 ff ff call c0100378 + sm->map_swappable(mm, v, page, 0); +c0106ff3: a1 00 41 1a c0 mov 0xc01a4100,%eax +c0106ff8: 8b 40 10 mov 0x10(%eax),%eax +c0106ffb: 8b 55 e4 mov -0x1c(%ebp),%edx +c0106ffe: c7 44 24 0c 00 00 00 movl $0x0,0xc(%esp) +c0107005: 00 +c0107006: 89 54 24 08 mov %edx,0x8(%esp) +c010700a: 8b 55 ec mov -0x14(%ebp),%edx +c010700d: 89 54 24 04 mov %edx,0x4(%esp) +c0107011: 8b 55 08 mov 0x8(%ebp),%edx +c0107014: 89 14 24 mov %edx,(%esp) +c0107017: ff d0 call *%eax +c0107019: eb 64 jmp c010707f + continue; + } + else { + cprintf("swap_out: i %d, store page in vaddr 0x%x to disk swap entry %d\n", i, v, page->pra_vaddr/PGSIZE+1); +c010701b: 8b 45 e4 mov -0x1c(%ebp),%eax +c010701e: 8b 40 1c mov 0x1c(%eax),%eax +c0107021: c1 e8 0c shr $0xc,%eax +c0107024: 40 inc %eax +c0107025: 89 44 24 0c mov %eax,0xc(%esp) +c0107029: 8b 45 ec mov -0x14(%ebp),%eax +c010702c: 89 44 24 08 mov %eax,0x8(%esp) +c0107030: 8b 45 f4 mov -0xc(%ebp),%eax +c0107033: 89 44 24 04 mov %eax,0x4(%esp) +c0107037: c7 04 24 ac d5 10 c0 movl $0xc010d5ac,(%esp) +c010703e: e8 35 93 ff ff call c0100378 + *ptep = (page->pra_vaddr/PGSIZE+1)<<8; +c0107043: 8b 45 e4 mov -0x1c(%ebp),%eax +c0107046: 8b 40 1c mov 0x1c(%eax),%eax +c0107049: c1 e8 0c shr $0xc,%eax +c010704c: 40 inc %eax +c010704d: c1 e0 08 shl $0x8,%eax +c0107050: 89 c2 mov %eax,%edx +c0107052: 8b 45 e8 mov -0x18(%ebp),%eax +c0107055: 89 10 mov %edx,(%eax) + free_page(page); +c0107057: 8b 45 e4 mov -0x1c(%ebp),%eax +c010705a: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c0107061: 00 +c0107062: 89 04 24 mov %eax,(%esp) +c0107065: e8 84 e1 ff ff call c01051ee + } + + tlb_invalidate(mm->pgdir, v); +c010706a: 8b 45 08 mov 0x8(%ebp),%eax +c010706d: 8b 40 0c mov 0xc(%eax),%eax +c0107070: 8b 55 ec mov -0x14(%ebp),%edx +c0107073: 89 54 24 04 mov %edx,0x4(%esp) +c0107077: 89 04 24 mov %eax,(%esp) +c010707a: e8 df ee ff ff call c0105f5e + for (i = 0; i != n; ++ i) +c010707f: ff 45 f4 incl -0xc(%ebp) +c0107082: 8b 45 f4 mov -0xc(%ebp),%eax +c0107085: 3b 45 0c cmp 0xc(%ebp),%eax +c0107088: 0f 85 a1 fe ff ff jne c0106f2f + } + return i; +c010708e: 8b 45 f4 mov -0xc(%ebp),%eax +} +c0107091: 89 ec mov %ebp,%esp +c0107093: 5d pop %ebp +c0107094: c3 ret + +c0107095 : + +int +swap_in(struct mm_struct *mm, uintptr_t addr, struct Page **ptr_result) +{ +c0107095: 55 push %ebp +c0107096: 89 e5 mov %esp,%ebp +c0107098: 83 ec 28 sub $0x28,%esp + struct Page *result = alloc_page(); +c010709b: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c01070a2: e8 da e0 ff ff call c0105181 +c01070a7: 89 45 f4 mov %eax,-0xc(%ebp) + assert(result!=NULL); +c01070aa: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c01070ae: 75 24 jne c01070d4 +c01070b0: c7 44 24 0c ec d5 10 movl $0xc010d5ec,0xc(%esp) +c01070b7: c0 +c01070b8: c7 44 24 08 7e d5 10 movl $0xc010d57e,0x8(%esp) +c01070bf: c0 +c01070c0: c7 44 24 04 7d 00 00 movl $0x7d,0x4(%esp) +c01070c7: 00 +c01070c8: c7 04 24 18 d5 10 c0 movl $0xc010d518,(%esp) +c01070cf: e8 67 9c ff ff call c0100d3b <__panic> + + pte_t *ptep = get_pte(mm->pgdir, addr, 0); +c01070d4: 8b 45 08 mov 0x8(%ebp),%eax +c01070d7: 8b 40 0c mov 0xc(%eax),%eax +c01070da: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) +c01070e1: 00 +c01070e2: 8b 55 0c mov 0xc(%ebp),%edx +c01070e5: 89 54 24 04 mov %edx,0x4(%esp) +c01070e9: 89 04 24 mov %eax,(%esp) +c01070ec: e8 4b e7 ff ff call c010583c +c01070f1: 89 45 f0 mov %eax,-0x10(%ebp) + // cprintf("SWAP: load ptep %x swap entry %d to vaddr 0x%08x, page %x, No %d\n", ptep, (*ptep)>>8, addr, result, (result-pages)); + + int r; + if ((r = swapfs_read((*ptep), result)) != 0) +c01070f4: 8b 45 f0 mov -0x10(%ebp),%eax +c01070f7: 8b 00 mov (%eax),%eax +c01070f9: 8b 55 f4 mov -0xc(%ebp),%edx +c01070fc: 89 54 24 04 mov %edx,0x4(%esp) +c0107100: 89 04 24 mov %eax,(%esp) +c0107103: e8 43 21 00 00 call c010924b +c0107108: 89 45 ec mov %eax,-0x14(%ebp) +c010710b: 83 7d ec 00 cmpl $0x0,-0x14(%ebp) +c010710f: 74 2a je c010713b + { + assert(r!=0); +c0107111: 83 7d ec 00 cmpl $0x0,-0x14(%ebp) +c0107115: 75 24 jne c010713b +c0107117: c7 44 24 0c f9 d5 10 movl $0xc010d5f9,0xc(%esp) +c010711e: c0 +c010711f: c7 44 24 08 7e d5 10 movl $0xc010d57e,0x8(%esp) +c0107126: c0 +c0107127: c7 44 24 04 85 00 00 movl $0x85,0x4(%esp) +c010712e: 00 +c010712f: c7 04 24 18 d5 10 c0 movl $0xc010d518,(%esp) +c0107136: e8 00 9c ff ff call c0100d3b <__panic> + } + cprintf("swap_in: load disk swap entry %d with swap_page in vadr 0x%x\n", (*ptep)>>8, addr); +c010713b: 8b 45 f0 mov -0x10(%ebp),%eax +c010713e: 8b 00 mov (%eax),%eax +c0107140: c1 e8 08 shr $0x8,%eax +c0107143: 89 c2 mov %eax,%edx +c0107145: 8b 45 0c mov 0xc(%ebp),%eax +c0107148: 89 44 24 08 mov %eax,0x8(%esp) +c010714c: 89 54 24 04 mov %edx,0x4(%esp) +c0107150: c7 04 24 00 d6 10 c0 movl $0xc010d600,(%esp) +c0107157: e8 1c 92 ff ff call c0100378 + *ptr_result=result; +c010715c: 8b 45 10 mov 0x10(%ebp),%eax +c010715f: 8b 55 f4 mov -0xc(%ebp),%edx +c0107162: 89 10 mov %edx,(%eax) + return 0; +c0107164: b8 00 00 00 00 mov $0x0,%eax +} +c0107169: 89 ec mov %ebp,%esp +c010716b: 5d pop %ebp +c010716c: c3 ret + +c010716d : + + + +static inline void +check_content_set(void) +{ +c010716d: 55 push %ebp +c010716e: 89 e5 mov %esp,%ebp +c0107170: 83 ec 18 sub $0x18,%esp + *(unsigned char *)0x1000 = 0x0a; +c0107173: b8 00 10 00 00 mov $0x1000,%eax +c0107178: c6 00 0a movb $0xa,(%eax) + assert(pgfault_num==1); +c010717b: a1 10 41 1a c0 mov 0xc01a4110,%eax +c0107180: 83 f8 01 cmp $0x1,%eax +c0107183: 74 24 je c01071a9 +c0107185: c7 44 24 0c 3e d6 10 movl $0xc010d63e,0xc(%esp) +c010718c: c0 +c010718d: c7 44 24 08 7e d5 10 movl $0xc010d57e,0x8(%esp) +c0107194: c0 +c0107195: c7 44 24 04 92 00 00 movl $0x92,0x4(%esp) +c010719c: 00 +c010719d: c7 04 24 18 d5 10 c0 movl $0xc010d518,(%esp) +c01071a4: e8 92 9b ff ff call c0100d3b <__panic> + *(unsigned char *)0x1010 = 0x0a; +c01071a9: b8 10 10 00 00 mov $0x1010,%eax +c01071ae: c6 00 0a movb $0xa,(%eax) + assert(pgfault_num==1); +c01071b1: a1 10 41 1a c0 mov 0xc01a4110,%eax +c01071b6: 83 f8 01 cmp $0x1,%eax +c01071b9: 74 24 je c01071df +c01071bb: c7 44 24 0c 3e d6 10 movl $0xc010d63e,0xc(%esp) +c01071c2: c0 +c01071c3: c7 44 24 08 7e d5 10 movl $0xc010d57e,0x8(%esp) +c01071ca: c0 +c01071cb: c7 44 24 04 94 00 00 movl $0x94,0x4(%esp) +c01071d2: 00 +c01071d3: c7 04 24 18 d5 10 c0 movl $0xc010d518,(%esp) +c01071da: e8 5c 9b ff ff call c0100d3b <__panic> + *(unsigned char *)0x2000 = 0x0b; +c01071df: b8 00 20 00 00 mov $0x2000,%eax +c01071e4: c6 00 0b movb $0xb,(%eax) + assert(pgfault_num==2); +c01071e7: a1 10 41 1a c0 mov 0xc01a4110,%eax +c01071ec: 83 f8 02 cmp $0x2,%eax +c01071ef: 74 24 je c0107215 +c01071f1: c7 44 24 0c 4d d6 10 movl $0xc010d64d,0xc(%esp) +c01071f8: c0 +c01071f9: c7 44 24 08 7e d5 10 movl $0xc010d57e,0x8(%esp) +c0107200: c0 +c0107201: c7 44 24 04 96 00 00 movl $0x96,0x4(%esp) +c0107208: 00 +c0107209: c7 04 24 18 d5 10 c0 movl $0xc010d518,(%esp) +c0107210: e8 26 9b ff ff call c0100d3b <__panic> + *(unsigned char *)0x2010 = 0x0b; +c0107215: b8 10 20 00 00 mov $0x2010,%eax +c010721a: c6 00 0b movb $0xb,(%eax) + assert(pgfault_num==2); +c010721d: a1 10 41 1a c0 mov 0xc01a4110,%eax +c0107222: 83 f8 02 cmp $0x2,%eax +c0107225: 74 24 je c010724b +c0107227: c7 44 24 0c 4d d6 10 movl $0xc010d64d,0xc(%esp) +c010722e: c0 +c010722f: c7 44 24 08 7e d5 10 movl $0xc010d57e,0x8(%esp) +c0107236: c0 +c0107237: c7 44 24 04 98 00 00 movl $0x98,0x4(%esp) +c010723e: 00 +c010723f: c7 04 24 18 d5 10 c0 movl $0xc010d518,(%esp) +c0107246: e8 f0 9a ff ff call c0100d3b <__panic> + *(unsigned char *)0x3000 = 0x0c; +c010724b: b8 00 30 00 00 mov $0x3000,%eax +c0107250: c6 00 0c movb $0xc,(%eax) + assert(pgfault_num==3); +c0107253: a1 10 41 1a c0 mov 0xc01a4110,%eax +c0107258: 83 f8 03 cmp $0x3,%eax +c010725b: 74 24 je c0107281 +c010725d: c7 44 24 0c 5c d6 10 movl $0xc010d65c,0xc(%esp) +c0107264: c0 +c0107265: c7 44 24 08 7e d5 10 movl $0xc010d57e,0x8(%esp) +c010726c: c0 +c010726d: c7 44 24 04 9a 00 00 movl $0x9a,0x4(%esp) +c0107274: 00 +c0107275: c7 04 24 18 d5 10 c0 movl $0xc010d518,(%esp) +c010727c: e8 ba 9a ff ff call c0100d3b <__panic> + *(unsigned char *)0x3010 = 0x0c; +c0107281: b8 10 30 00 00 mov $0x3010,%eax +c0107286: c6 00 0c movb $0xc,(%eax) + assert(pgfault_num==3); +c0107289: a1 10 41 1a c0 mov 0xc01a4110,%eax +c010728e: 83 f8 03 cmp $0x3,%eax +c0107291: 74 24 je c01072b7 +c0107293: c7 44 24 0c 5c d6 10 movl $0xc010d65c,0xc(%esp) +c010729a: c0 +c010729b: c7 44 24 08 7e d5 10 movl $0xc010d57e,0x8(%esp) +c01072a2: c0 +c01072a3: c7 44 24 04 9c 00 00 movl $0x9c,0x4(%esp) +c01072aa: 00 +c01072ab: c7 04 24 18 d5 10 c0 movl $0xc010d518,(%esp) +c01072b2: e8 84 9a ff ff call c0100d3b <__panic> + *(unsigned char *)0x4000 = 0x0d; +c01072b7: b8 00 40 00 00 mov $0x4000,%eax +c01072bc: c6 00 0d movb $0xd,(%eax) + assert(pgfault_num==4); +c01072bf: a1 10 41 1a c0 mov 0xc01a4110,%eax +c01072c4: 83 f8 04 cmp $0x4,%eax +c01072c7: 74 24 je c01072ed +c01072c9: c7 44 24 0c 6b d6 10 movl $0xc010d66b,0xc(%esp) +c01072d0: c0 +c01072d1: c7 44 24 08 7e d5 10 movl $0xc010d57e,0x8(%esp) +c01072d8: c0 +c01072d9: c7 44 24 04 9e 00 00 movl $0x9e,0x4(%esp) +c01072e0: 00 +c01072e1: c7 04 24 18 d5 10 c0 movl $0xc010d518,(%esp) +c01072e8: e8 4e 9a ff ff call c0100d3b <__panic> + *(unsigned char *)0x4010 = 0x0d; +c01072ed: b8 10 40 00 00 mov $0x4010,%eax +c01072f2: c6 00 0d movb $0xd,(%eax) + assert(pgfault_num==4); +c01072f5: a1 10 41 1a c0 mov 0xc01a4110,%eax +c01072fa: 83 f8 04 cmp $0x4,%eax +c01072fd: 74 24 je c0107323 +c01072ff: c7 44 24 0c 6b d6 10 movl $0xc010d66b,0xc(%esp) +c0107306: c0 +c0107307: c7 44 24 08 7e d5 10 movl $0xc010d57e,0x8(%esp) +c010730e: c0 +c010730f: c7 44 24 04 a0 00 00 movl $0xa0,0x4(%esp) +c0107316: 00 +c0107317: c7 04 24 18 d5 10 c0 movl $0xc010d518,(%esp) +c010731e: e8 18 9a ff ff call c0100d3b <__panic> +} +c0107323: 90 nop +c0107324: 89 ec mov %ebp,%esp +c0107326: 5d pop %ebp +c0107327: c3 ret + +c0107328 : + +static inline int +check_content_access(void) +{ +c0107328: 55 push %ebp +c0107329: 89 e5 mov %esp,%ebp +c010732b: 83 ec 18 sub $0x18,%esp + int ret = sm->check_swap(); +c010732e: a1 00 41 1a c0 mov 0xc01a4100,%eax +c0107333: 8b 40 1c mov 0x1c(%eax),%eax +c0107336: ff d0 call *%eax +c0107338: 89 45 f4 mov %eax,-0xc(%ebp) + return ret; +c010733b: 8b 45 f4 mov -0xc(%ebp),%eax +} +c010733e: 89 ec mov %ebp,%esp +c0107340: 5d pop %ebp +c0107341: c3 ret + +c0107342 : + +#define free_list (free_area.free_list) +#define nr_free (free_area.nr_free) + +check_swap(void) +{ +c0107342: 55 push %ebp +c0107343: 89 e5 mov %esp,%ebp +c0107345: 83 ec 78 sub $0x78,%esp + //backup mem env// 备份内存环境,确保检查后没有页面丢失 + int ret, count = 0, total = 0, i; +c0107348: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) +c010734f: c7 45 f0 00 00 00 00 movl $0x0,-0x10(%ebp) + list_entry_t *le = &free_list; +c0107356: c7 45 e8 84 3f 1a c0 movl $0xc01a3f84,-0x18(%ebp) + while ((le = list_next(le)) != &free_list) { +c010735d: eb 6a jmp c01073c9 + struct Page *p = le2page(le, page_link);// 将链表条目转换为页面结构 +c010735f: 8b 45 e8 mov -0x18(%ebp),%eax +c0107362: 83 e8 0c sub $0xc,%eax +c0107365: 89 45 c8 mov %eax,-0x38(%ebp) + assert(PageProperty(p));// 断言页面属性有效 +c0107368: 8b 45 c8 mov -0x38(%ebp),%eax +c010736b: 83 c0 04 add $0x4,%eax +c010736e: c7 45 c4 01 00 00 00 movl $0x1,-0x3c(%ebp) +c0107375: 89 45 c0 mov %eax,-0x40(%ebp) + asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr)); +c0107378: 8b 45 c0 mov -0x40(%ebp),%eax +c010737b: 8b 55 c4 mov -0x3c(%ebp),%edx +c010737e: 0f a3 10 bt %edx,(%eax) +c0107381: 19 c0 sbb %eax,%eax +c0107383: 89 45 bc mov %eax,-0x44(%ebp) + return oldbit != 0; +c0107386: 83 7d bc 00 cmpl $0x0,-0x44(%ebp) +c010738a: 0f 95 c0 setne %al +c010738d: 0f b6 c0 movzbl %al,%eax +c0107390: 85 c0 test %eax,%eax +c0107392: 75 24 jne c01073b8 +c0107394: c7 44 24 0c 7a d6 10 movl $0xc010d67a,0xc(%esp) +c010739b: c0 +c010739c: c7 44 24 08 7e d5 10 movl $0xc010d57e,0x8(%esp) +c01073a3: c0 +c01073a4: c7 44 24 04 ba 00 00 movl $0xba,0x4(%esp) +c01073ab: 00 +c01073ac: c7 04 24 18 d5 10 c0 movl $0xc010d518,(%esp) +c01073b3: e8 83 99 ff ff call c0100d3b <__panic> + count ++, total += p->property;// 统计页面数量和属性总和 +c01073b8: ff 45 f4 incl -0xc(%ebp) +c01073bb: 8b 45 c8 mov -0x38(%ebp),%eax +c01073be: 8b 50 08 mov 0x8(%eax),%edx +c01073c1: 8b 45 f0 mov -0x10(%ebp),%eax +c01073c4: 01 d0 add %edx,%eax +c01073c6: 89 45 f0 mov %eax,-0x10(%ebp) +c01073c9: 8b 45 e8 mov -0x18(%ebp),%eax +c01073cc: 89 45 b8 mov %eax,-0x48(%ebp) +c01073cf: 8b 45 b8 mov -0x48(%ebp),%eax +c01073d2: 8b 40 04 mov 0x4(%eax),%eax + while ((le = list_next(le)) != &free_list) { +c01073d5: 89 45 e8 mov %eax,-0x18(%ebp) +c01073d8: 81 7d e8 84 3f 1a c0 cmpl $0xc01a3f84,-0x18(%ebp) +c01073df: 0f 85 7a ff ff ff jne c010735f + } + assert(total == nr_free_pages());// 断言统计的属性总和与空闲页面数一致 +c01073e5: e8 39 de ff ff call c0105223 +c01073ea: 8b 55 f0 mov -0x10(%ebp),%edx +c01073ed: 39 d0 cmp %edx,%eax +c01073ef: 74 24 je c0107415 +c01073f1: c7 44 24 0c 8a d6 10 movl $0xc010d68a,0xc(%esp) +c01073f8: c0 +c01073f9: c7 44 24 08 7e d5 10 movl $0xc010d57e,0x8(%esp) +c0107400: c0 +c0107401: c7 44 24 04 bd 00 00 movl $0xbd,0x4(%esp) +c0107408: 00 +c0107409: c7 04 24 18 d5 10 c0 movl $0xc010d518,(%esp) +c0107410: e8 26 99 ff ff call c0100d3b <__panic> + cprintf("BEGIN check_swap: count %d, total %d\n",count,total);// 打印初始状态 +c0107415: 8b 45 f0 mov -0x10(%ebp),%eax +c0107418: 89 44 24 08 mov %eax,0x8(%esp) +c010741c: 8b 45 f4 mov -0xc(%ebp),%eax +c010741f: 89 44 24 04 mov %eax,0x4(%esp) +c0107423: c7 04 24 a4 d6 10 c0 movl $0xc010d6a4,(%esp) +c010742a: e8 49 8f ff ff call c0100378 + + //now we set the phy pages env // 设置物理页面环境 + struct mm_struct *mm = mm_create();// 创建内存管理结构 +c010742f: e8 81 0b 00 00 call c0107fb5 +c0107434: 89 45 e4 mov %eax,-0x1c(%ebp) + assert(mm != NULL); // 断言内存管理结构创建成功 +c0107437: 83 7d e4 00 cmpl $0x0,-0x1c(%ebp) +c010743b: 75 24 jne c0107461 +c010743d: c7 44 24 0c ca d6 10 movl $0xc010d6ca,0xc(%esp) +c0107444: c0 +c0107445: c7 44 24 08 7e d5 10 movl $0xc010d57e,0x8(%esp) +c010744c: c0 +c010744d: c7 44 24 04 c2 00 00 movl $0xc2,0x4(%esp) +c0107454: 00 +c0107455: c7 04 24 18 d5 10 c0 movl $0xc010d518,(%esp) +c010745c: e8 da 98 ff ff call c0100d3b <__panic> + + extern struct mm_struct *check_mm_struct;// 声明外部变量 + assert(check_mm_struct == NULL);// 断言外部变量为空 +c0107461: a1 0c 41 1a c0 mov 0xc01a410c,%eax +c0107466: 85 c0 test %eax,%eax +c0107468: 74 24 je c010748e +c010746a: c7 44 24 0c d5 d6 10 movl $0xc010d6d5,0xc(%esp) +c0107471: c0 +c0107472: c7 44 24 08 7e d5 10 movl $0xc010d57e,0x8(%esp) +c0107479: c0 +c010747a: c7 44 24 04 c5 00 00 movl $0xc5,0x4(%esp) +c0107481: 00 +c0107482: c7 04 24 18 d5 10 c0 movl $0xc010d518,(%esp) +c0107489: e8 ad 98 ff ff call c0100d3b <__panic> + + // 将新创建的内存管理结构赋值给外部变量 + check_mm_struct = mm; +c010748e: 8b 45 e4 mov -0x1c(%ebp),%eax +c0107491: a3 0c 41 1a c0 mov %eax,0xc01a410c + + pde_t *pgdir = mm->pgdir = boot_pgdir;// 设置页目录 +c0107496: 8b 15 00 fa 12 c0 mov 0xc012fa00,%edx +c010749c: 8b 45 e4 mov -0x1c(%ebp),%eax +c010749f: 89 50 0c mov %edx,0xc(%eax) +c01074a2: 8b 45 e4 mov -0x1c(%ebp),%eax +c01074a5: 8b 40 0c mov 0xc(%eax),%eax +c01074a8: 89 45 e0 mov %eax,-0x20(%ebp) + assert(pgdir[0] == 0);// 断言页目录的第一个条目为空 +c01074ab: 8b 45 e0 mov -0x20(%ebp),%eax +c01074ae: 8b 00 mov (%eax),%eax +c01074b0: 85 c0 test %eax,%eax +c01074b2: 74 24 je c01074d8 +c01074b4: c7 44 24 0c ed d6 10 movl $0xc010d6ed,0xc(%esp) +c01074bb: c0 +c01074bc: c7 44 24 08 7e d5 10 movl $0xc010d57e,0x8(%esp) +c01074c3: c0 +c01074c4: c7 44 24 04 cb 00 00 movl $0xcb,0x4(%esp) +c01074cb: 00 +c01074cc: c7 04 24 18 d5 10 c0 movl $0xc010d518,(%esp) +c01074d3: e8 63 98 ff ff call c0100d3b <__panic> + + // 创建虚拟内存区域 + struct vma_struct *vma = vma_create(BEING_CHECK_VALID_VADDR, CHECK_VALID_VADDR, VM_WRITE | VM_READ); +c01074d8: c7 44 24 08 03 00 00 movl $0x3,0x8(%esp) +c01074df: 00 +c01074e0: c7 44 24 04 00 60 00 movl $0x6000,0x4(%esp) +c01074e7: 00 +c01074e8: c7 04 24 00 10 00 00 movl $0x1000,(%esp) +c01074ef: e8 5d 0b 00 00 call c0108051 +c01074f4: 89 45 dc mov %eax,-0x24(%ebp) + assert(vma != NULL);// 断言虚拟内存区域创建成功 +c01074f7: 83 7d dc 00 cmpl $0x0,-0x24(%ebp) +c01074fb: 75 24 jne c0107521 +c01074fd: c7 44 24 0c fb d6 10 movl $0xc010d6fb,0xc(%esp) +c0107504: c0 +c0107505: c7 44 24 08 7e d5 10 movl $0xc010d57e,0x8(%esp) +c010750c: c0 +c010750d: c7 44 24 04 cf 00 00 movl $0xcf,0x4(%esp) +c0107514: 00 +c0107515: c7 04 24 18 d5 10 c0 movl $0xc010d518,(%esp) +c010751c: e8 1a 98 ff ff call c0100d3b <__panic> + + // 插入虚拟内存区域到内存管理结构 + insert_vma_struct(mm, vma); +c0107521: 8b 45 dc mov -0x24(%ebp),%eax +c0107524: 89 44 24 04 mov %eax,0x4(%esp) +c0107528: 8b 45 e4 mov -0x1c(%ebp),%eax +c010752b: 89 04 24 mov %eax,(%esp) +c010752e: e8 b5 0c 00 00 call c01081e8 + + //setup the temp Page Table vaddr 0~4MB/ 设置临时页表,用于虚拟地址 0~4MB + cprintf("setup Page Table for vaddr 0X1000, so alloc a page\n");// 打印设置页表的信息 +c0107533: c7 04 24 08 d7 10 c0 movl $0xc010d708,(%esp) +c010753a: e8 39 8e ff ff call c0100378 + pte_t *temp_ptep=NULL; +c010753f: c7 45 d8 00 00 00 00 movl $0x0,-0x28(%ebp) + temp_ptep = get_pte(mm->pgdir, BEING_CHECK_VALID_VADDR, 1);// 获取页表项 +c0107546: 8b 45 e4 mov -0x1c(%ebp),%eax +c0107549: 8b 40 0c mov 0xc(%eax),%eax +c010754c: c7 44 24 08 01 00 00 movl $0x1,0x8(%esp) +c0107553: 00 +c0107554: c7 44 24 04 00 10 00 movl $0x1000,0x4(%esp) +c010755b: 00 +c010755c: 89 04 24 mov %eax,(%esp) +c010755f: e8 d8 e2 ff ff call c010583c +c0107564: 89 45 d8 mov %eax,-0x28(%ebp) + assert(temp_ptep!= NULL);// 断言获取页表项成功 +c0107567: 83 7d d8 00 cmpl $0x0,-0x28(%ebp) +c010756b: 75 24 jne c0107591 +c010756d: c7 44 24 0c 3c d7 10 movl $0xc010d73c,0xc(%esp) +c0107574: c0 +c0107575: c7 44 24 08 7e d5 10 movl $0xc010d57e,0x8(%esp) +c010757c: c0 +c010757d: c7 44 24 04 d8 00 00 movl $0xd8,0x4(%esp) +c0107584: 00 +c0107585: c7 04 24 18 d5 10 c0 movl $0xc010d518,(%esp) +c010758c: e8 aa 97 ff ff call c0100d3b <__panic> + cprintf("setup Page Table vaddr 0~4MB OVER!\n");// 打印设置页表完成的信息 +c0107591: c7 04 24 50 d7 10 c0 movl $0xc010d750,(%esp) +c0107598: e8 db 8d ff ff call c0100378 + + for (i=0;i + check_rp[i] = alloc_page();// 分配页面 +c01075a9: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c01075b0: e8 cc db ff ff call c0105181 +c01075b5: 8b 55 ec mov -0x14(%ebp),%edx +c01075b8: 89 04 95 cc 40 1a c0 mov %eax,-0x3fe5bf34(,%edx,4) + assert(check_rp[i] != NULL );// 断言分配页面成功 +c01075bf: 8b 45 ec mov -0x14(%ebp),%eax +c01075c2: 8b 04 85 cc 40 1a c0 mov -0x3fe5bf34(,%eax,4),%eax +c01075c9: 85 c0 test %eax,%eax +c01075cb: 75 24 jne c01075f1 +c01075cd: c7 44 24 0c 74 d7 10 movl $0xc010d774,0xc(%esp) +c01075d4: c0 +c01075d5: c7 44 24 08 7e d5 10 movl $0xc010d57e,0x8(%esp) +c01075dc: c0 +c01075dd: c7 44 24 04 dd 00 00 movl $0xdd,0x4(%esp) +c01075e4: 00 +c01075e5: c7 04 24 18 d5 10 c0 movl $0xc010d518,(%esp) +c01075ec: e8 4a 97 ff ff call c0100d3b <__panic> + assert(!PageProperty(check_rp[i]));// 断言页面属性无效 +c01075f1: 8b 45 ec mov -0x14(%ebp),%eax +c01075f4: 8b 04 85 cc 40 1a c0 mov -0x3fe5bf34(,%eax,4),%eax +c01075fb: 83 c0 04 add $0x4,%eax +c01075fe: c7 45 b4 01 00 00 00 movl $0x1,-0x4c(%ebp) +c0107605: 89 45 b0 mov %eax,-0x50(%ebp) + asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr)); +c0107608: 8b 45 b0 mov -0x50(%ebp),%eax +c010760b: 8b 55 b4 mov -0x4c(%ebp),%edx +c010760e: 0f a3 10 bt %edx,(%eax) +c0107611: 19 c0 sbb %eax,%eax +c0107613: 89 45 ac mov %eax,-0x54(%ebp) + return oldbit != 0; +c0107616: 83 7d ac 00 cmpl $0x0,-0x54(%ebp) +c010761a: 0f 95 c0 setne %al +c010761d: 0f b6 c0 movzbl %al,%eax +c0107620: 85 c0 test %eax,%eax +c0107622: 74 24 je c0107648 +c0107624: c7 44 24 0c 88 d7 10 movl $0xc010d788,0xc(%esp) +c010762b: c0 +c010762c: c7 44 24 08 7e d5 10 movl $0xc010d57e,0x8(%esp) +c0107633: c0 +c0107634: c7 44 24 04 de 00 00 movl $0xde,0x4(%esp) +c010763b: 00 +c010763c: c7 04 24 18 d5 10 c0 movl $0xc010d518,(%esp) +c0107643: e8 f3 96 ff ff call c0100d3b <__panic> + for (i=0;i + } + list_entry_t free_list_store = free_list;// 保存当前空闲列表 +c0107655: a1 84 3f 1a c0 mov 0xc01a3f84,%eax +c010765a: 8b 15 88 3f 1a c0 mov 0xc01a3f88,%edx +c0107660: 89 45 98 mov %eax,-0x68(%ebp) +c0107663: 89 55 9c mov %edx,-0x64(%ebp) +c0107666: c7 45 a4 84 3f 1a c0 movl $0xc01a3f84,-0x5c(%ebp) + elm->prev = elm->next = elm; +c010766d: 8b 45 a4 mov -0x5c(%ebp),%eax +c0107670: 8b 55 a4 mov -0x5c(%ebp),%edx +c0107673: 89 50 04 mov %edx,0x4(%eax) +c0107676: 8b 45 a4 mov -0x5c(%ebp),%eax +c0107679: 8b 50 04 mov 0x4(%eax),%edx +c010767c: 8b 45 a4 mov -0x5c(%ebp),%eax +c010767f: 89 10 mov %edx,(%eax) +} +c0107681: 90 nop +c0107682: c7 45 a8 84 3f 1a c0 movl $0xc01a3f84,-0x58(%ebp) + return list->next == list; +c0107689: 8b 45 a8 mov -0x58(%ebp),%eax +c010768c: 8b 40 04 mov 0x4(%eax),%eax +c010768f: 39 45 a8 cmp %eax,-0x58(%ebp) +c0107692: 0f 94 c0 sete %al +c0107695: 0f b6 c0 movzbl %al,%eax + list_init(&free_list);// 初始化空闲列表 + assert(list_empty(&free_list));// 断言空闲列表为空 +c0107698: 85 c0 test %eax,%eax +c010769a: 75 24 jne c01076c0 +c010769c: c7 44 24 0c a3 d7 10 movl $0xc010d7a3,0xc(%esp) +c01076a3: c0 +c01076a4: c7 44 24 08 7e d5 10 movl $0xc010d57e,0x8(%esp) +c01076ab: c0 +c01076ac: c7 44 24 04 e2 00 00 movl $0xe2,0x4(%esp) +c01076b3: 00 +c01076b4: c7 04 24 18 d5 10 c0 movl $0xc010d518,(%esp) +c01076bb: e8 7b 96 ff ff call c0100d3b <__panic> + + //assert(alloc_page() == NULL); + + unsigned int nr_free_store = nr_free;// 保存当前空闲页面数 +c01076c0: a1 8c 3f 1a c0 mov 0xc01a3f8c,%eax +c01076c5: 89 45 d4 mov %eax,-0x2c(%ebp) + nr_free = 0;// 将空闲页面数设为 0 +c01076c8: c7 05 8c 3f 1a c0 00 movl $0x0,0xc01a3f8c +c01076cf: 00 00 00 + for (i=0;i + free_pages(check_rp[i],1);// 释放页面 +c01076db: 8b 45 ec mov -0x14(%ebp),%eax +c01076de: 8b 04 85 cc 40 1a c0 mov -0x3fe5bf34(,%eax,4),%eax +c01076e5: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c01076ec: 00 +c01076ed: 89 04 24 mov %eax,(%esp) +c01076f0: e8 f9 da ff ff call c01051ee + for (i=0;i + } + assert(nr_free==CHECK_VALID_PHY_PAGE_NUM);// 断言释放的页面数正确 +c01076fe: a1 8c 3f 1a c0 mov 0xc01a3f8c,%eax +c0107703: 83 f8 04 cmp $0x4,%eax +c0107706: 74 24 je c010772c +c0107708: c7 44 24 0c bc d7 10 movl $0xc010d7bc,0xc(%esp) +c010770f: c0 +c0107710: c7 44 24 08 7e d5 10 movl $0xc010d57e,0x8(%esp) +c0107717: c0 +c0107718: c7 44 24 04 eb 00 00 movl $0xeb,0x4(%esp) +c010771f: 00 +c0107720: c7 04 24 18 d5 10 c0 movl $0xc010d518,(%esp) +c0107727: e8 0f 96 ff ff call c0100d3b <__panic> + + cprintf("set up init env for check_swap begin!\n");// 打印设置初始环境开始的信息 +c010772c: c7 04 24 e0 d7 10 c0 movl $0xc010d7e0,(%esp) +c0107733: e8 40 8c ff ff call c0100378 + //setup initial vir_page<->phy_page environment for page relpacement algorithm + // 设置初始虚拟到物理页面环境,用于页面替换算法 + + pgfault_num=0;// 初始化页面故障数 +c0107738: c7 05 10 41 1a c0 00 movl $0x0,0xc01a4110 +c010773f: 00 00 00 + + check_content_set();// 设置检查内容 +c0107742: e8 26 fa ff ff call c010716d + assert( nr_free == 0); // 断言空闲页面数为 0 +c0107747: a1 8c 3f 1a c0 mov 0xc01a3f8c,%eax +c010774c: 85 c0 test %eax,%eax +c010774e: 74 24 je c0107774 +c0107750: c7 44 24 0c 07 d8 10 movl $0xc010d807,0xc(%esp) +c0107757: c0 +c0107758: c7 44 24 08 7e d5 10 movl $0xc010d57e,0x8(%esp) +c010775f: c0 +c0107760: c7 44 24 04 f4 00 00 movl $0xf4,0x4(%esp) +c0107767: 00 +c0107768: c7 04 24 18 d5 10 c0 movl $0xc010d518,(%esp) +c010776f: e8 c7 95 ff ff call c0100d3b <__panic> + for(i = 0; i + swap_out_seq_no[i]=swap_in_seq_no[i]=-1;// 初始化页面替换序列号 +c010777d: 8b 45 ec mov -0x14(%ebp),%eax +c0107780: c7 04 85 60 40 1a c0 movl $0xffffffff,-0x3fe5bfa0(,%eax,4) +c0107787: ff ff ff ff +c010778b: 8b 45 ec mov -0x14(%ebp),%eax +c010778e: 8b 14 85 60 40 1a c0 mov -0x3fe5bfa0(,%eax,4),%edx +c0107795: 8b 45 ec mov -0x14(%ebp),%eax +c0107798: 89 14 85 a0 40 1a c0 mov %edx,-0x3fe5bf60(,%eax,4) + for(i = 0; i + + for (i= 0;i + check_ptep[i]=0; +c01077b4: 8b 45 ec mov -0x14(%ebp),%eax +c01077b7: c7 04 85 dc 40 1a c0 movl $0x0,-0x3fe5bf24(,%eax,4) +c01077be: 00 00 00 00 + check_ptep[i] = get_pte(pgdir, (i+1)*0x1000, 0);// 获取页表项 +c01077c2: 8b 45 ec mov -0x14(%ebp),%eax +c01077c5: 40 inc %eax +c01077c6: c1 e0 0c shl $0xc,%eax +c01077c9: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) +c01077d0: 00 +c01077d1: 89 44 24 04 mov %eax,0x4(%esp) +c01077d5: 8b 45 e0 mov -0x20(%ebp),%eax +c01077d8: 89 04 24 mov %eax,(%esp) +c01077db: e8 5c e0 ff ff call c010583c +c01077e0: 8b 55 ec mov -0x14(%ebp),%edx +c01077e3: 89 04 95 dc 40 1a c0 mov %eax,-0x3fe5bf24(,%edx,4) + //cprintf("i %d, check_ptep addr %x, value %x\n", i, check_ptep[i], *check_ptep[i]); + assert(check_ptep[i] != NULL);// 断言获取页表项成功 +c01077ea: 8b 45 ec mov -0x14(%ebp),%eax +c01077ed: 8b 04 85 dc 40 1a c0 mov -0x3fe5bf24(,%eax,4),%eax +c01077f4: 85 c0 test %eax,%eax +c01077f6: 75 24 jne c010781c +c01077f8: c7 44 24 0c 14 d8 10 movl $0xc010d814,0xc(%esp) +c01077ff: c0 +c0107800: c7 44 24 08 7e d5 10 movl $0xc010d57e,0x8(%esp) +c0107807: c0 +c0107808: c7 44 24 04 fc 00 00 movl $0xfc,0x4(%esp) +c010780f: 00 +c0107810: c7 04 24 18 d5 10 c0 movl $0xc010d518,(%esp) +c0107817: e8 1f 95 ff ff call c0100d3b <__panic> + assert(pte2page(*check_ptep[i]) == check_rp[i]); // 断言页表项对应的页面正确 +c010781c: 8b 45 ec mov -0x14(%ebp),%eax +c010781f: 8b 04 85 dc 40 1a c0 mov -0x3fe5bf24(,%eax,4),%eax +c0107826: 8b 00 mov (%eax),%eax +c0107828: 89 04 24 mov %eax,(%esp) +c010782b: e8 7d f5 ff ff call c0106dad +c0107830: 8b 55 ec mov -0x14(%ebp),%edx +c0107833: 8b 14 95 cc 40 1a c0 mov -0x3fe5bf34(,%edx,4),%edx +c010783a: 39 d0 cmp %edx,%eax +c010783c: 74 24 je c0107862 +c010783e: c7 44 24 0c 2c d8 10 movl $0xc010d82c,0xc(%esp) +c0107845: c0 +c0107846: c7 44 24 08 7e d5 10 movl $0xc010d57e,0x8(%esp) +c010784d: c0 +c010784e: c7 44 24 04 fd 00 00 movl $0xfd,0x4(%esp) +c0107855: 00 +c0107856: c7 04 24 18 d5 10 c0 movl $0xc010d518,(%esp) +c010785d: e8 d9 94 ff ff call c0100d3b <__panic> + assert((*check_ptep[i] & PTE_P)); // 断言页表项有效 +c0107862: 8b 45 ec mov -0x14(%ebp),%eax +c0107865: 8b 04 85 dc 40 1a c0 mov -0x3fe5bf24(,%eax,4),%eax +c010786c: 8b 00 mov (%eax),%eax +c010786e: 83 e0 01 and $0x1,%eax +c0107871: 85 c0 test %eax,%eax +c0107873: 75 24 jne c0107899 +c0107875: c7 44 24 0c 54 d8 10 movl $0xc010d854,0xc(%esp) +c010787c: c0 +c010787d: c7 44 24 08 7e d5 10 movl $0xc010d57e,0x8(%esp) +c0107884: c0 +c0107885: c7 44 24 04 fe 00 00 movl $0xfe,0x4(%esp) +c010788c: 00 +c010788d: c7 04 24 18 d5 10 c0 movl $0xc010d518,(%esp) +c0107894: e8 a2 94 ff ff call c0100d3b <__panic> + for (i= 0;i + } + cprintf("set up init env for check_swap over!\n");// 打印设置初始环境完成的信息 +c01078a6: c7 04 24 70 d8 10 c0 movl $0xc010d870,(%esp) +c01078ad: e8 c6 8a ff ff call c0100378 + // now access the virt pages to test page relpacement algorithm + ret=check_content_access(); +c01078b2: e8 71 fa ff ff call c0107328 +c01078b7: 89 45 d0 mov %eax,-0x30(%ebp) + assert(ret==0); // 断言访问检查成功 +c01078ba: 83 7d d0 00 cmpl $0x0,-0x30(%ebp) +c01078be: 74 24 je c01078e4 +c01078c0: c7 44 24 0c 96 d8 10 movl $0xc010d896,0xc(%esp) +c01078c7: c0 +c01078c8: c7 44 24 08 7e d5 10 movl $0xc010d57e,0x8(%esp) +c01078cf: c0 +c01078d0: c7 44 24 04 03 01 00 movl $0x103,0x4(%esp) +c01078d7: 00 +c01078d8: c7 04 24 18 d5 10 c0 movl $0xc010d518,(%esp) +c01078df: e8 57 94 ff ff call c0100d3b <__panic> + + //restore kernel mem env + for (i=0;i + free_pages(check_rp[i],1); +c01078ed: 8b 45 ec mov -0x14(%ebp),%eax +c01078f0: 8b 04 85 cc 40 1a c0 mov -0x3fe5bf34(,%eax,4),%eax +c01078f7: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c01078fe: 00 +c01078ff: 89 04 24 mov %eax,(%esp) +c0107902: e8 e7 d8 ff ff call c01051ee + for (i=0;i + } + + //free_page(pte2page(*temp_ptep)); + free_page(pde2page(pgdir[0])); +c0107910: 8b 45 e0 mov -0x20(%ebp),%eax +c0107913: 8b 00 mov (%eax),%eax +c0107915: 89 04 24 mov %eax,(%esp) +c0107918: e8 d0 f4 ff ff call c0106ded +c010791d: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c0107924: 00 +c0107925: 89 04 24 mov %eax,(%esp) +c0107928: e8 c1 d8 ff ff call c01051ee + pgdir[0] = 0; +c010792d: 8b 45 e0 mov -0x20(%ebp),%eax +c0107930: c7 00 00 00 00 00 movl $0x0,(%eax) + mm->pgdir = NULL; +c0107936: 8b 45 e4 mov -0x1c(%ebp),%eax +c0107939: c7 40 0c 00 00 00 00 movl $0x0,0xc(%eax) + mm_destroy(mm);// 销毁内存管理结构 +c0107940: 8b 45 e4 mov -0x1c(%ebp),%eax +c0107943: 89 04 24 mov %eax,(%esp) +c0107946: e8 d3 09 00 00 call c010831e + check_mm_struct = NULL; +c010794b: c7 05 0c 41 1a c0 00 movl $0x0,0xc01a410c +c0107952: 00 00 00 + + nr_free = nr_free_store;// 恢复空闲页面数 +c0107955: 8b 45 d4 mov -0x2c(%ebp),%eax +c0107958: a3 8c 3f 1a c0 mov %eax,0xc01a3f8c + free_list = free_list_store;// 恢复空闲列表 +c010795d: 8b 45 98 mov -0x68(%ebp),%eax +c0107960: 8b 55 9c mov -0x64(%ebp),%edx +c0107963: a3 84 3f 1a c0 mov %eax,0xc01a3f84 +c0107968: 89 15 88 3f 1a c0 mov %edx,0xc01a3f88 + + + le = &free_list; +c010796e: c7 45 e8 84 3f 1a c0 movl $0xc01a3f84,-0x18(%ebp) + while ((le = list_next(le)) != &free_list) { +c0107975: eb 1c jmp c0107993 + struct Page *p = le2page(le, page_link);// 将链表条目转换为页面结构 +c0107977: 8b 45 e8 mov -0x18(%ebp),%eax +c010797a: 83 e8 0c sub $0xc,%eax +c010797d: 89 45 cc mov %eax,-0x34(%ebp) + count --, total -= p->property;// 更新页面数量和属性总和 +c0107980: ff 4d f4 decl -0xc(%ebp) +c0107983: 8b 55 f0 mov -0x10(%ebp),%edx +c0107986: 8b 45 cc mov -0x34(%ebp),%eax +c0107989: 8b 48 08 mov 0x8(%eax),%ecx +c010798c: 89 d0 mov %edx,%eax +c010798e: 29 c8 sub %ecx,%eax +c0107990: 89 45 f0 mov %eax,-0x10(%ebp) +c0107993: 8b 45 e8 mov -0x18(%ebp),%eax +c0107996: 89 45 a0 mov %eax,-0x60(%ebp) + return listelm->next; +c0107999: 8b 45 a0 mov -0x60(%ebp),%eax +c010799c: 8b 40 04 mov 0x4(%eax),%eax + while ((le = list_next(le)) != &free_list) { +c010799f: 89 45 e8 mov %eax,-0x18(%ebp) +c01079a2: 81 7d e8 84 3f 1a c0 cmpl $0xc01a3f84,-0x18(%ebp) +c01079a9: 75 cc jne c0107977 + } + cprintf("count is %d, total is %d\n",count,total);// 打印恢复后的状态 +c01079ab: 8b 45 f0 mov -0x10(%ebp),%eax +c01079ae: 89 44 24 08 mov %eax,0x8(%esp) +c01079b2: 8b 45 f4 mov -0xc(%ebp),%eax +c01079b5: 89 44 24 04 mov %eax,0x4(%esp) +c01079b9: c7 04 24 9d d8 10 c0 movl $0xc010d89d,(%esp) +c01079c0: e8 b3 89 ff ff call c0100378 + //assert(count == 0); + + cprintf("check_swap() succeeded!\n");// 打印检查成功的信息 +c01079c5: c7 04 24 b7 d8 10 c0 movl $0xc010d8b7,(%esp) +c01079cc: e8 a7 89 ff ff call c0100378 +} +c01079d1: 90 nop +c01079d2: 89 ec mov %ebp,%esp +c01079d4: 5d pop %ebp +c01079d5: c3 ret + +c01079d6 <_fifo_init_mm>: + * (2) _fifo_init_mm: init pra_list_head and let mm->sm_priv point to the addr of pra_list_head. + * Now, From the memory control struct mm_struct, we can access FIFO PRA + */ +static int +_fifo_init_mm(struct mm_struct *mm) +{ +c01079d6: 55 push %ebp +c01079d7: 89 e5 mov %esp,%ebp +c01079d9: 83 ec 10 sub $0x10,%esp +c01079dc: c7 45 fc 04 41 1a c0 movl $0xc01a4104,-0x4(%ebp) + elm->prev = elm->next = elm; +c01079e3: 8b 45 fc mov -0x4(%ebp),%eax +c01079e6: 8b 55 fc mov -0x4(%ebp),%edx +c01079e9: 89 50 04 mov %edx,0x4(%eax) +c01079ec: 8b 45 fc mov -0x4(%ebp),%eax +c01079ef: 8b 50 04 mov 0x4(%eax),%edx +c01079f2: 8b 45 fc mov -0x4(%ebp),%eax +c01079f5: 89 10 mov %edx,(%eax) +} +c01079f7: 90 nop + //初始化一个链表头 pra_list_head + list_init(&pra_list_head); + //将 mm 结构中的 sm_priv 字段指向这个链表头 + mm->sm_priv = &pra_list_head; +c01079f8: 8b 45 08 mov 0x8(%ebp),%eax +c01079fb: c7 40 14 04 41 1a c0 movl $0xc01a4104,0x14(%eax) + //cprintf(" mm->sm_priv %x in fifo_init_mm\n",mm->sm_priv); + //返回 0 表示成功 + return 0; +c0107a02: b8 00 00 00 00 mov $0x0,%eax +} +c0107a07: 89 ec mov %ebp,%esp +c0107a09: 5d pop %ebp +c0107a0a: c3 ret + +c0107a0b <_fifo_map_swappable>: +/* + * (3)_fifo_map_swappable: According FIFO PRA, we should link the most recent arrival page at the back of pra_list_head qeueue + */ +static int +_fifo_map_swappable(struct mm_struct *mm, uintptr_t addr, struct Page *page, int swap_in) +{ +c0107a0b: 55 push %ebp +c0107a0c: 89 e5 mov %esp,%ebp +c0107a0e: 83 ec 48 sub $0x48,%esp + //获取 mm_struct 结构中的 sm_priv 指针, + //并将其转换为 list_entry_t 类型的链表头指针 head + list_entry_t *head=(list_entry_t*) mm->sm_priv; +c0107a11: 8b 45 08 mov 0x8(%ebp),%eax +c0107a14: 8b 40 14 mov 0x14(%eax),%eax +c0107a17: 89 45 f4 mov %eax,-0xc(%ebp) + list_entry_t *entry=&(page->pra_page_link); +c0107a1a: 8b 45 10 mov 0x10(%ebp),%eax +c0107a1d: 83 c0 14 add $0x14,%eax +c0107a20: 89 45 f0 mov %eax,-0x10(%ebp) + + assert(entry != NULL && head != NULL); +c0107a23: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) +c0107a27: 74 06 je c0107a2f <_fifo_map_swappable+0x24> +c0107a29: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c0107a2d: 75 24 jne c0107a53 <_fifo_map_swappable+0x48> +c0107a2f: c7 44 24 0c d0 d8 10 movl $0xc010d8d0,0xc(%esp) +c0107a36: c0 +c0107a37: c7 44 24 08 ee d8 10 movl $0xc010d8ee,0x8(%esp) +c0107a3e: c0 +c0107a3f: c7 44 24 04 37 00 00 movl $0x37,0x4(%esp) +c0107a46: 00 +c0107a47: c7 04 24 03 d9 10 c0 movl $0xc010d903,(%esp) +c0107a4e: e8 e8 92 ff ff call c0100d3b <__panic> +c0107a53: 8b 45 f4 mov -0xc(%ebp),%eax +c0107a56: 89 45 ec mov %eax,-0x14(%ebp) +c0107a59: 8b 45 f0 mov -0x10(%ebp),%eax +c0107a5c: 89 45 e8 mov %eax,-0x18(%ebp) +c0107a5f: 8b 45 ec mov -0x14(%ebp),%eax +c0107a62: 89 45 e4 mov %eax,-0x1c(%ebp) +c0107a65: 8b 45 e8 mov -0x18(%ebp),%eax +c0107a68: 89 45 e0 mov %eax,-0x20(%ebp) + __list_add(elm, listelm, listelm->next); +c0107a6b: 8b 45 e4 mov -0x1c(%ebp),%eax +c0107a6e: 8b 40 04 mov 0x4(%eax),%eax +c0107a71: 8b 55 e0 mov -0x20(%ebp),%edx +c0107a74: 89 55 dc mov %edx,-0x24(%ebp) +c0107a77: 8b 55 e4 mov -0x1c(%ebp),%edx +c0107a7a: 89 55 d8 mov %edx,-0x28(%ebp) +c0107a7d: 89 45 d4 mov %eax,-0x2c(%ebp) + prev->next = next->prev = elm; +c0107a80: 8b 45 d4 mov -0x2c(%ebp),%eax +c0107a83: 8b 55 dc mov -0x24(%ebp),%edx +c0107a86: 89 10 mov %edx,(%eax) +c0107a88: 8b 45 d4 mov -0x2c(%ebp),%eax +c0107a8b: 8b 10 mov (%eax),%edx +c0107a8d: 8b 45 d8 mov -0x28(%ebp),%eax +c0107a90: 89 50 04 mov %edx,0x4(%eax) + elm->next = next; +c0107a93: 8b 45 dc mov -0x24(%ebp),%eax +c0107a96: 8b 55 d4 mov -0x2c(%ebp),%edx +c0107a99: 89 50 04 mov %edx,0x4(%eax) + elm->prev = prev; +c0107a9c: 8b 45 dc mov -0x24(%ebp),%eax +c0107a9f: 8b 55 d8 mov -0x28(%ebp),%edx +c0107aa2: 89 10 mov %edx,(%eax) +} +c0107aa4: 90 nop +} +c0107aa5: 90 nop +} +c0107aa6: 90 nop + //record the page access situlation + /*LAB3 EXERCISE 2: YOUR CODE*/ + //(1)link the most recent arrival page at the back of the pra_list_head qeueue. + //将最近到达的页面链接到 pra_list_head 队列的末尾 + list_add(head, entry); + return 0; +c0107aa7: b8 00 00 00 00 mov $0x0,%eax +} +c0107aac: 89 ec mov %ebp,%esp +c0107aae: 5d pop %ebp +c0107aaf: c3 ret + +c0107ab0 <_fifo_swap_out_victim>: + * + * @return 返回0表示成功,其他值表示失败。 + */ +static int +_fifo_swap_out_victim(struct mm_struct *mm, struct Page ** ptr_page, int in_tick) +{ +c0107ab0: 55 push %ebp +c0107ab1: 89 e5 mov %esp,%ebp +c0107ab3: 83 ec 38 sub $0x38,%esp + list_entry_t *head=(list_entry_t*) mm->sm_priv; +c0107ab6: 8b 45 08 mov 0x8(%ebp),%eax +c0107ab9: 8b 40 14 mov 0x14(%eax),%eax +c0107abc: 89 45 f4 mov %eax,-0xc(%ebp) + assert(head != NULL); +c0107abf: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c0107ac3: 75 24 jne c0107ae9 <_fifo_swap_out_victim+0x39> +c0107ac5: c7 44 24 0c 17 d9 10 movl $0xc010d917,0xc(%esp) +c0107acc: c0 +c0107acd: c7 44 24 08 ee d8 10 movl $0xc010d8ee,0x8(%esp) +c0107ad4: c0 +c0107ad5: c7 44 24 04 50 00 00 movl $0x50,0x4(%esp) +c0107adc: 00 +c0107add: c7 04 24 03 d9 10 c0 movl $0xc010d903,(%esp) +c0107ae4: e8 52 92 ff ff call c0100d3b <__panic> + assert(in_tick==0); +c0107ae9: 83 7d 10 00 cmpl $0x0,0x10(%ebp) +c0107aed: 74 24 je c0107b13 <_fifo_swap_out_victim+0x63> +c0107aef: c7 44 24 0c 24 d9 10 movl $0xc010d924,0xc(%esp) +c0107af6: c0 +c0107af7: c7 44 24 08 ee d8 10 movl $0xc010d8ee,0x8(%esp) +c0107afe: c0 +c0107aff: c7 44 24 04 51 00 00 movl $0x51,0x4(%esp) +c0107b06: 00 +c0107b07: c7 04 24 03 d9 10 c0 movl $0xc010d903,(%esp) +c0107b0e: e8 28 92 ff ff call c0100d3b <__panic> + /* Select the victim */ + /*LAB3 EXERCISE 2: YOUR CODE*/ + //(1) unlink the earliest arrival page in front of pra_list_head qeueue + //(2) assign the value of *ptr_page to the addr of this page + //head->prev 获取链表中最先到达的页面 + list_entry_t *le = head->prev; +c0107b13: 8b 45 f4 mov -0xc(%ebp),%eax +c0107b16: 8b 00 mov (%eax),%eax +c0107b18: 89 45 f0 mov %eax,-0x10(%ebp) + assert(head!=le); +c0107b1b: 8b 45 f4 mov -0xc(%ebp),%eax +c0107b1e: 3b 45 f0 cmp -0x10(%ebp),%eax +c0107b21: 75 24 jne c0107b47 <_fifo_swap_out_victim+0x97> +c0107b23: c7 44 24 0c 2f d9 10 movl $0xc010d92f,0xc(%esp) +c0107b2a: c0 +c0107b2b: c7 44 24 08 ee d8 10 movl $0xc010d8ee,0x8(%esp) +c0107b32: c0 +c0107b33: c7 44 24 04 58 00 00 movl $0x58,0x4(%esp) +c0107b3a: 00 +c0107b3b: c7 04 24 03 d9 10 c0 movl $0xc010d903,(%esp) +c0107b42: e8 f4 91 ff ff call c0100d3b <__panic> + struct Page *p = le2page(le, pra_page_link); +c0107b47: 8b 45 f0 mov -0x10(%ebp),%eax +c0107b4a: 83 e8 14 sub $0x14,%eax +c0107b4d: 89 45 ec mov %eax,-0x14(%ebp) +c0107b50: 8b 45 f0 mov -0x10(%ebp),%eax +c0107b53: 89 45 e8 mov %eax,-0x18(%ebp) + __list_del(listelm->prev, listelm->next); +c0107b56: 8b 45 e8 mov -0x18(%ebp),%eax +c0107b59: 8b 40 04 mov 0x4(%eax),%eax +c0107b5c: 8b 55 e8 mov -0x18(%ebp),%edx +c0107b5f: 8b 12 mov (%edx),%edx +c0107b61: 89 55 e4 mov %edx,-0x1c(%ebp) +c0107b64: 89 45 e0 mov %eax,-0x20(%ebp) + prev->next = next; +c0107b67: 8b 45 e4 mov -0x1c(%ebp),%eax +c0107b6a: 8b 55 e0 mov -0x20(%ebp),%edx +c0107b6d: 89 50 04 mov %edx,0x4(%eax) + next->prev = prev; +c0107b70: 8b 45 e0 mov -0x20(%ebp),%eax +c0107b73: 8b 55 e4 mov -0x1c(%ebp),%edx +c0107b76: 89 10 mov %edx,(%eax) +} +c0107b78: 90 nop +} +c0107b79: 90 nop + //使用 list_del 函数将该页面从链表中移除。 + list_del(le); + assert(p != NULL); +c0107b7a: 83 7d ec 00 cmpl $0x0,-0x14(%ebp) +c0107b7e: 75 24 jne c0107ba4 <_fifo_swap_out_victim+0xf4> +c0107b80: c7 44 24 0c 38 d9 10 movl $0xc010d938,0xc(%esp) +c0107b87: c0 +c0107b88: c7 44 24 08 ee d8 10 movl $0xc010d8ee,0x8(%esp) +c0107b8f: c0 +c0107b90: c7 44 24 04 5c 00 00 movl $0x5c,0x4(%esp) +c0107b97: 00 +c0107b98: c7 04 24 03 d9 10 c0 movl $0xc010d903,(%esp) +c0107b9f: e8 97 91 ff ff call c0100d3b <__panic> + //将移除的页面指针赋值给 *ptr_page + *ptr_page = p; +c0107ba4: 8b 45 0c mov 0xc(%ebp),%eax +c0107ba7: 8b 55 ec mov -0x14(%ebp),%edx +c0107baa: 89 10 mov %edx,(%eax) + + return 0; +c0107bac: b8 00 00 00 00 mov $0x0,%eax +} +c0107bb1: 89 ec mov %ebp,%esp +c0107bb3: 5d pop %ebp +c0107bb4: c3 ret + +c0107bb5 <_fifo_check_swap>: + * + * 返回值: + * - 0: 表示所有检查均通过。 + */ +static int +_fifo_check_swap(void) { +c0107bb5: 55 push %ebp +c0107bb6: 89 e5 mov %esp,%ebp +c0107bb8: 83 ec 18 sub $0x18,%esp + // 写入虚拟页 c 并检查页面故障数 + cprintf("write Virt Page c in fifo_check_swap\n"); +c0107bbb: c7 04 24 44 d9 10 c0 movl $0xc010d944,(%esp) +c0107bc2: e8 b1 87 ff ff call c0100378 + *(unsigned char *)0x3000 = 0x0c; +c0107bc7: b8 00 30 00 00 mov $0x3000,%eax +c0107bcc: c6 00 0c movb $0xc,(%eax) + assert(pgfault_num==4); +c0107bcf: a1 10 41 1a c0 mov 0xc01a4110,%eax +c0107bd4: 83 f8 04 cmp $0x4,%eax +c0107bd7: 74 24 je c0107bfd <_fifo_check_swap+0x48> +c0107bd9: c7 44 24 0c 6a d9 10 movl $0xc010d96a,0xc(%esp) +c0107be0: c0 +c0107be1: c7 44 24 08 ee d8 10 movl $0xc010d8ee,0x8(%esp) +c0107be8: c0 +c0107be9: c7 44 24 04 70 00 00 movl $0x70,0x4(%esp) +c0107bf0: 00 +c0107bf1: c7 04 24 03 d9 10 c0 movl $0xc010d903,(%esp) +c0107bf8: e8 3e 91 ff ff call c0100d3b <__panic> + + // 写入虚拟页 a 并检查页面故障数 + cprintf("write Virt Page a in fifo_check_swap\n"); +c0107bfd: c7 04 24 7c d9 10 c0 movl $0xc010d97c,(%esp) +c0107c04: e8 6f 87 ff ff call c0100378 + *(unsigned char *)0x1000 = 0x0a; +c0107c09: b8 00 10 00 00 mov $0x1000,%eax +c0107c0e: c6 00 0a movb $0xa,(%eax) + assert(pgfault_num==4); +c0107c11: a1 10 41 1a c0 mov 0xc01a4110,%eax +c0107c16: 83 f8 04 cmp $0x4,%eax +c0107c19: 74 24 je c0107c3f <_fifo_check_swap+0x8a> +c0107c1b: c7 44 24 0c 6a d9 10 movl $0xc010d96a,0xc(%esp) +c0107c22: c0 +c0107c23: c7 44 24 08 ee d8 10 movl $0xc010d8ee,0x8(%esp) +c0107c2a: c0 +c0107c2b: c7 44 24 04 75 00 00 movl $0x75,0x4(%esp) +c0107c32: 00 +c0107c33: c7 04 24 03 d9 10 c0 movl $0xc010d903,(%esp) +c0107c3a: e8 fc 90 ff ff call c0100d3b <__panic> + + // 写入虚拟页 d 并检查页面故障数 + cprintf("write Virt Page d in fifo_check_swap\n"); +c0107c3f: c7 04 24 a4 d9 10 c0 movl $0xc010d9a4,(%esp) +c0107c46: e8 2d 87 ff ff call c0100378 + *(unsigned char *)0x4000 = 0x0d; +c0107c4b: b8 00 40 00 00 mov $0x4000,%eax +c0107c50: c6 00 0d movb $0xd,(%eax) + assert(pgfault_num==4); +c0107c53: a1 10 41 1a c0 mov 0xc01a4110,%eax +c0107c58: 83 f8 04 cmp $0x4,%eax +c0107c5b: 74 24 je c0107c81 <_fifo_check_swap+0xcc> +c0107c5d: c7 44 24 0c 6a d9 10 movl $0xc010d96a,0xc(%esp) +c0107c64: c0 +c0107c65: c7 44 24 08 ee d8 10 movl $0xc010d8ee,0x8(%esp) +c0107c6c: c0 +c0107c6d: c7 44 24 04 7a 00 00 movl $0x7a,0x4(%esp) +c0107c74: 00 +c0107c75: c7 04 24 03 d9 10 c0 movl $0xc010d903,(%esp) +c0107c7c: e8 ba 90 ff ff call c0100d3b <__panic> + + // 写入虚拟页 b 并检查页面故障数 + cprintf("write Virt Page b in fifo_check_swap\n"); +c0107c81: c7 04 24 cc d9 10 c0 movl $0xc010d9cc,(%esp) +c0107c88: e8 eb 86 ff ff call c0100378 + *(unsigned char *)0x2000 = 0x0b; +c0107c8d: b8 00 20 00 00 mov $0x2000,%eax +c0107c92: c6 00 0b movb $0xb,(%eax) + assert(pgfault_num==4); +c0107c95: a1 10 41 1a c0 mov 0xc01a4110,%eax +c0107c9a: 83 f8 04 cmp $0x4,%eax +c0107c9d: 74 24 je c0107cc3 <_fifo_check_swap+0x10e> +c0107c9f: c7 44 24 0c 6a d9 10 movl $0xc010d96a,0xc(%esp) +c0107ca6: c0 +c0107ca7: c7 44 24 08 ee d8 10 movl $0xc010d8ee,0x8(%esp) +c0107cae: c0 +c0107caf: c7 44 24 04 7f 00 00 movl $0x7f,0x4(%esp) +c0107cb6: 00 +c0107cb7: c7 04 24 03 d9 10 c0 movl $0xc010d903,(%esp) +c0107cbe: e8 78 90 ff ff call c0100d3b <__panic> + + // 写入虚拟页 e 并检查页面故障数 + cprintf("write Virt Page e in fifo_check_swap\n"); +c0107cc3: c7 04 24 f4 d9 10 c0 movl $0xc010d9f4,(%esp) +c0107cca: e8 a9 86 ff ff call c0100378 + *(unsigned char *)0x5000 = 0x0e; +c0107ccf: b8 00 50 00 00 mov $0x5000,%eax +c0107cd4: c6 00 0e movb $0xe,(%eax) + assert(pgfault_num==5); +c0107cd7: a1 10 41 1a c0 mov 0xc01a4110,%eax +c0107cdc: 83 f8 05 cmp $0x5,%eax +c0107cdf: 74 24 je c0107d05 <_fifo_check_swap+0x150> +c0107ce1: c7 44 24 0c 1a da 10 movl $0xc010da1a,0xc(%esp) +c0107ce8: c0 +c0107ce9: c7 44 24 08 ee d8 10 movl $0xc010d8ee,0x8(%esp) +c0107cf0: c0 +c0107cf1: c7 44 24 04 84 00 00 movl $0x84,0x4(%esp) +c0107cf8: 00 +c0107cf9: c7 04 24 03 d9 10 c0 movl $0xc010d903,(%esp) +c0107d00: e8 36 90 ff ff call c0100d3b <__panic> + + // 再次写入虚拟页 b 并检查页面故障数 + cprintf("write Virt Page b in fifo_check_swap\n"); +c0107d05: c7 04 24 cc d9 10 c0 movl $0xc010d9cc,(%esp) +c0107d0c: e8 67 86 ff ff call c0100378 + *(unsigned char *)0x2000 = 0x0b; +c0107d11: b8 00 20 00 00 mov $0x2000,%eax +c0107d16: c6 00 0b movb $0xb,(%eax) + assert(pgfault_num==5); +c0107d19: a1 10 41 1a c0 mov 0xc01a4110,%eax +c0107d1e: 83 f8 05 cmp $0x5,%eax +c0107d21: 74 24 je c0107d47 <_fifo_check_swap+0x192> +c0107d23: c7 44 24 0c 1a da 10 movl $0xc010da1a,0xc(%esp) +c0107d2a: c0 +c0107d2b: c7 44 24 08 ee d8 10 movl $0xc010d8ee,0x8(%esp) +c0107d32: c0 +c0107d33: c7 44 24 04 89 00 00 movl $0x89,0x4(%esp) +c0107d3a: 00 +c0107d3b: c7 04 24 03 d9 10 c0 movl $0xc010d903,(%esp) +c0107d42: e8 f4 8f ff ff call c0100d3b <__panic> + + // 再次写入虚拟页 a 并检查页面故障数 + cprintf("write Virt Page a in fifo_check_swap\n"); +c0107d47: c7 04 24 7c d9 10 c0 movl $0xc010d97c,(%esp) +c0107d4e: e8 25 86 ff ff call c0100378 + *(unsigned char *)0x1000 = 0x0a; +c0107d53: b8 00 10 00 00 mov $0x1000,%eax +c0107d58: c6 00 0a movb $0xa,(%eax) + assert(pgfault_num==6); +c0107d5b: a1 10 41 1a c0 mov 0xc01a4110,%eax +c0107d60: 83 f8 06 cmp $0x6,%eax +c0107d63: 74 24 je c0107d89 <_fifo_check_swap+0x1d4> +c0107d65: c7 44 24 0c 29 da 10 movl $0xc010da29,0xc(%esp) +c0107d6c: c0 +c0107d6d: c7 44 24 08 ee d8 10 movl $0xc010d8ee,0x8(%esp) +c0107d74: c0 +c0107d75: c7 44 24 04 8e 00 00 movl $0x8e,0x4(%esp) +c0107d7c: 00 +c0107d7d: c7 04 24 03 d9 10 c0 movl $0xc010d903,(%esp) +c0107d84: e8 b2 8f ff ff call c0100d3b <__panic> + + // 再次写入虚拟页 b 并检查页面故障数 + cprintf("write Virt Page b in fifo_check_swap\n"); +c0107d89: c7 04 24 cc d9 10 c0 movl $0xc010d9cc,(%esp) +c0107d90: e8 e3 85 ff ff call c0100378 + *(unsigned char *)0x2000 = 0x0b; +c0107d95: b8 00 20 00 00 mov $0x2000,%eax +c0107d9a: c6 00 0b movb $0xb,(%eax) + assert(pgfault_num==7); +c0107d9d: a1 10 41 1a c0 mov 0xc01a4110,%eax +c0107da2: 83 f8 07 cmp $0x7,%eax +c0107da5: 74 24 je c0107dcb <_fifo_check_swap+0x216> +c0107da7: c7 44 24 0c 38 da 10 movl $0xc010da38,0xc(%esp) +c0107dae: c0 +c0107daf: c7 44 24 08 ee d8 10 movl $0xc010d8ee,0x8(%esp) +c0107db6: c0 +c0107db7: c7 44 24 04 93 00 00 movl $0x93,0x4(%esp) +c0107dbe: 00 +c0107dbf: c7 04 24 03 d9 10 c0 movl $0xc010d903,(%esp) +c0107dc6: e8 70 8f ff ff call c0100d3b <__panic> + + // 再次写入虚拟页 c 并检查页面故障数 + cprintf("write Virt Page c in fifo_check_swap\n"); +c0107dcb: c7 04 24 44 d9 10 c0 movl $0xc010d944,(%esp) +c0107dd2: e8 a1 85 ff ff call c0100378 + *(unsigned char *)0x3000 = 0x0c; +c0107dd7: b8 00 30 00 00 mov $0x3000,%eax +c0107ddc: c6 00 0c movb $0xc,(%eax) + assert(pgfault_num==8); +c0107ddf: a1 10 41 1a c0 mov 0xc01a4110,%eax +c0107de4: 83 f8 08 cmp $0x8,%eax +c0107de7: 74 24 je c0107e0d <_fifo_check_swap+0x258> +c0107de9: c7 44 24 0c 47 da 10 movl $0xc010da47,0xc(%esp) +c0107df0: c0 +c0107df1: c7 44 24 08 ee d8 10 movl $0xc010d8ee,0x8(%esp) +c0107df8: c0 +c0107df9: c7 44 24 04 98 00 00 movl $0x98,0x4(%esp) +c0107e00: 00 +c0107e01: c7 04 24 03 d9 10 c0 movl $0xc010d903,(%esp) +c0107e08: e8 2e 8f ff ff call c0100d3b <__panic> + + // 再次写入虚拟页 d 并检查页面故障数 + cprintf("write Virt Page d in fifo_check_swap\n"); +c0107e0d: c7 04 24 a4 d9 10 c0 movl $0xc010d9a4,(%esp) +c0107e14: e8 5f 85 ff ff call c0100378 + *(unsigned char *)0x4000 = 0x0d; +c0107e19: b8 00 40 00 00 mov $0x4000,%eax +c0107e1e: c6 00 0d movb $0xd,(%eax) + assert(pgfault_num==9); +c0107e21: a1 10 41 1a c0 mov 0xc01a4110,%eax +c0107e26: 83 f8 09 cmp $0x9,%eax +c0107e29: 74 24 je c0107e4f <_fifo_check_swap+0x29a> +c0107e2b: c7 44 24 0c 56 da 10 movl $0xc010da56,0xc(%esp) +c0107e32: c0 +c0107e33: c7 44 24 08 ee d8 10 movl $0xc010d8ee,0x8(%esp) +c0107e3a: c0 +c0107e3b: c7 44 24 04 9d 00 00 movl $0x9d,0x4(%esp) +c0107e42: 00 +c0107e43: c7 04 24 03 d9 10 c0 movl $0xc010d903,(%esp) +c0107e4a: e8 ec 8e ff ff call c0100d3b <__panic> + + // 再次写入虚拟页 e 并检查页面故障数 + cprintf("write Virt Page e in fifo_check_swap\n"); +c0107e4f: c7 04 24 f4 d9 10 c0 movl $0xc010d9f4,(%esp) +c0107e56: e8 1d 85 ff ff call c0100378 + *(unsigned char *)0x5000 = 0x0e; +c0107e5b: b8 00 50 00 00 mov $0x5000,%eax +c0107e60: c6 00 0e movb $0xe,(%eax) + assert(pgfault_num==10); +c0107e63: a1 10 41 1a c0 mov 0xc01a4110,%eax +c0107e68: 83 f8 0a cmp $0xa,%eax +c0107e6b: 74 24 je c0107e91 <_fifo_check_swap+0x2dc> +c0107e6d: c7 44 24 0c 65 da 10 movl $0xc010da65,0xc(%esp) +c0107e74: c0 +c0107e75: c7 44 24 08 ee d8 10 movl $0xc010d8ee,0x8(%esp) +c0107e7c: c0 +c0107e7d: c7 44 24 04 a2 00 00 movl $0xa2,0x4(%esp) +c0107e84: 00 +c0107e85: c7 04 24 03 d9 10 c0 movl $0xc010d903,(%esp) +c0107e8c: e8 aa 8e ff ff call c0100d3b <__panic> + + // 再次写入虚拟页 a 并检查页面故障数 + cprintf("write Virt Page a in fifo_check_swap\n"); +c0107e91: c7 04 24 7c d9 10 c0 movl $0xc010d97c,(%esp) +c0107e98: e8 db 84 ff ff call c0100378 + assert(*(unsigned char *)0x1000 == 0x0a); +c0107e9d: b8 00 10 00 00 mov $0x1000,%eax +c0107ea2: 0f b6 00 movzbl (%eax),%eax +c0107ea5: 3c 0a cmp $0xa,%al +c0107ea7: 74 24 je c0107ecd <_fifo_check_swap+0x318> +c0107ea9: c7 44 24 0c 78 da 10 movl $0xc010da78,0xc(%esp) +c0107eb0: c0 +c0107eb1: c7 44 24 08 ee d8 10 movl $0xc010d8ee,0x8(%esp) +c0107eb8: c0 +c0107eb9: c7 44 24 04 a6 00 00 movl $0xa6,0x4(%esp) +c0107ec0: 00 +c0107ec1: c7 04 24 03 d9 10 c0 movl $0xc010d903,(%esp) +c0107ec8: e8 6e 8e ff ff call c0100d3b <__panic> + *(unsigned char *)0x1000 = 0x0a; +c0107ecd: b8 00 10 00 00 mov $0x1000,%eax +c0107ed2: c6 00 0a movb $0xa,(%eax) + assert(pgfault_num==11); +c0107ed5: a1 10 41 1a c0 mov 0xc01a4110,%eax +c0107eda: 83 f8 0b cmp $0xb,%eax +c0107edd: 74 24 je c0107f03 <_fifo_check_swap+0x34e> +c0107edf: c7 44 24 0c 99 da 10 movl $0xc010da99,0xc(%esp) +c0107ee6: c0 +c0107ee7: c7 44 24 08 ee d8 10 movl $0xc010d8ee,0x8(%esp) +c0107eee: c0 +c0107eef: c7 44 24 04 a8 00 00 movl $0xa8,0x4(%esp) +c0107ef6: 00 +c0107ef7: c7 04 24 03 d9 10 c0 movl $0xc010d903,(%esp) +c0107efe: e8 38 8e ff ff call c0100d3b <__panic> + return 0; +c0107f03: b8 00 00 00 00 mov $0x0,%eax +} +c0107f08: 89 ec mov %ebp,%esp +c0107f0a: 5d pop %ebp +c0107f0b: c3 ret + +c0107f0c <_fifo_init>: + + +static int +_fifo_init(void) +{ +c0107f0c: 55 push %ebp +c0107f0d: 89 e5 mov %esp,%ebp + return 0; +c0107f0f: b8 00 00 00 00 mov $0x0,%eax +} +c0107f14: 5d pop %ebp +c0107f15: c3 ret + +c0107f16 <_fifo_set_unswappable>: + +static int +_fifo_set_unswappable(struct mm_struct *mm, uintptr_t addr) +{ +c0107f16: 55 push %ebp +c0107f17: 89 e5 mov %esp,%ebp + return 0; +c0107f19: b8 00 00 00 00 mov $0x0,%eax +} +c0107f1e: 5d pop %ebp +c0107f1f: c3 ret + +c0107f20 <_fifo_tick_event>: + +static int +_fifo_tick_event(struct mm_struct *mm) +{ return 0; } +c0107f20: 55 push %ebp +c0107f21: 89 e5 mov %esp,%ebp +c0107f23: b8 00 00 00 00 mov $0x0,%eax +c0107f28: 5d pop %ebp +c0107f29: c3 ret + +c0107f2a : +#define local_intr_restore(x) __intr_restore(x); + +typedef volatile bool lock_t; + +static inline void +lock_init(lock_t *lock) { +c0107f2a: 55 push %ebp +c0107f2b: 89 e5 mov %esp,%ebp + *lock = 0; +c0107f2d: 8b 45 08 mov 0x8(%ebp),%eax +c0107f30: c7 00 00 00 00 00 movl $0x0,(%eax) +} +c0107f36: 90 nop +c0107f37: 5d pop %ebp +c0107f38: c3 ret + +c0107f39 : +bool user_mem_check(struct mm_struct *mm, uintptr_t start, size_t len, bool write); +bool copy_from_user(struct mm_struct *mm, void *dst, const void *src, size_t len, bool writable); +bool copy_to_user(struct mm_struct *mm, void *dst, const void *src, size_t len); + +static inline int +mm_count(struct mm_struct *mm) { +c0107f39: 55 push %ebp +c0107f3a: 89 e5 mov %esp,%ebp + return mm->mm_count; +c0107f3c: 8b 45 08 mov 0x8(%ebp),%eax +c0107f3f: 8b 40 18 mov 0x18(%eax),%eax +} +c0107f42: 5d pop %ebp +c0107f43: c3 ret + +c0107f44 : + +static inline void +set_mm_count(struct mm_struct *mm, int val) { +c0107f44: 55 push %ebp +c0107f45: 89 e5 mov %esp,%ebp + mm->mm_count = val; +c0107f47: 8b 45 08 mov 0x8(%ebp),%eax +c0107f4a: 8b 55 0c mov 0xc(%ebp),%edx +c0107f4d: 89 50 18 mov %edx,0x18(%eax) +} +c0107f50: 90 nop +c0107f51: 5d pop %ebp +c0107f52: c3 ret + +c0107f53 : +pa2page(uintptr_t pa) { +c0107f53: 55 push %ebp +c0107f54: 89 e5 mov %esp,%ebp +c0107f56: 83 ec 18 sub $0x18,%esp + if (PPN(pa) >= npage) { +c0107f59: 8b 45 08 mov 0x8(%ebp),%eax +c0107f5c: c1 e8 0c shr $0xc,%eax +c0107f5f: 89 c2 mov %eax,%edx +c0107f61: a1 a4 3f 1a c0 mov 0xc01a3fa4,%eax +c0107f66: 39 c2 cmp %eax,%edx +c0107f68: 72 1c jb c0107f86 + panic("pa2page called with invalid pa"); +c0107f6a: c7 44 24 08 bc da 10 movl $0xc010dabc,0x8(%esp) +c0107f71: c0 +c0107f72: c7 44 24 04 5e 00 00 movl $0x5e,0x4(%esp) +c0107f79: 00 +c0107f7a: c7 04 24 db da 10 c0 movl $0xc010dadb,(%esp) +c0107f81: e8 b5 8d ff ff call c0100d3b <__panic> + return &pages[PPN(pa)]; +c0107f86: 8b 15 a0 3f 1a c0 mov 0xc01a3fa0,%edx +c0107f8c: 8b 45 08 mov 0x8(%ebp),%eax +c0107f8f: c1 e8 0c shr $0xc,%eax +c0107f92: c1 e0 05 shl $0x5,%eax +c0107f95: 01 d0 add %edx,%eax +} +c0107f97: 89 ec mov %ebp,%esp +c0107f99: 5d pop %ebp +c0107f9a: c3 ret + +c0107f9b : +pde2page(pde_t pde) { +c0107f9b: 55 push %ebp +c0107f9c: 89 e5 mov %esp,%ebp +c0107f9e: 83 ec 18 sub $0x18,%esp + return pa2page(PDE_ADDR(pde)); +c0107fa1: 8b 45 08 mov 0x8(%ebp),%eax +c0107fa4: 25 00 f0 ff ff and $0xfffff000,%eax +c0107fa9: 89 04 24 mov %eax,(%esp) +c0107fac: e8 a2 ff ff ff call c0107f53 +} +c0107fb1: 89 ec mov %ebp,%esp +c0107fb3: 5d pop %ebp +c0107fb4: c3 ret + +c0107fb5 : + * 它包括内存映射列表、页目录、映射缓存等重要信息 + * + * @return 分配并初始化后的`mm_struct`结构体指针,如果分配失败则返回NULL + */ +struct mm_struct * +mm_create(void) { +c0107fb5: 55 push %ebp +c0107fb6: 89 e5 mov %esp,%ebp +c0107fb8: 83 ec 28 sub $0x28,%esp + // 分配一个mm_struct结构体的空间 + struct mm_struct *mm = kmalloc(sizeof(struct mm_struct)); +c0107fbb: c7 04 24 20 00 00 00 movl $0x20,(%esp) +c0107fc2: e8 29 cd ff ff call c0104cf0 +c0107fc7: 89 45 f4 mov %eax,-0xc(%ebp) + // 检查是否成功分配了内存 + if (mm != NULL) { +c0107fca: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c0107fce: 74 7a je c010804a + // 初始化内存映射列表 + list_init(&(mm->mmap_list)); +c0107fd0: 8b 45 f4 mov -0xc(%ebp),%eax +c0107fd3: 89 45 f0 mov %eax,-0x10(%ebp) + elm->prev = elm->next = elm; +c0107fd6: 8b 45 f0 mov -0x10(%ebp),%eax +c0107fd9: 8b 55 f0 mov -0x10(%ebp),%edx +c0107fdc: 89 50 04 mov %edx,0x4(%eax) +c0107fdf: 8b 45 f0 mov -0x10(%ebp),%eax +c0107fe2: 8b 50 04 mov 0x4(%eax),%edx +c0107fe5: 8b 45 f0 mov -0x10(%ebp),%eax +c0107fe8: 89 10 mov %edx,(%eax) +} +c0107fea: 90 nop + // 设置映射缓存为NULL,表示尚未缓存任何映射 + mm->mmap_cache = NULL; +c0107feb: 8b 45 f4 mov -0xc(%ebp),%eax +c0107fee: c7 40 08 00 00 00 00 movl $0x0,0x8(%eax) + // 设置页目录为NULL,表示尚未分配页目录 + mm->pgdir = NULL; +c0107ff5: 8b 45 f4 mov -0xc(%ebp),%eax +c0107ff8: c7 40 0c 00 00 00 00 movl $0x0,0xc(%eax) + // 初始化映射计数为0,表示尚未创建任何内存映射 + mm->map_count = 0; +c0107fff: 8b 45 f4 mov -0xc(%ebp),%eax +c0108002: c7 40 10 00 00 00 00 movl $0x0,0x10(%eax) + // 如果交换空间初始化成功,则为当前内存管理结构体进行交换空间初始化 + if (swap_init_ok) swap_init_mm(mm); +c0108009: a1 44 40 1a c0 mov 0xc01a4044,%eax +c010800e: 85 c0 test %eax,%eax +c0108010: 74 0d je c010801f +c0108012: 8b 45 f4 mov -0xc(%ebp),%eax +c0108015: 89 04 24 mov %eax,(%esp) +c0108018: e8 7c ee ff ff call c0106e99 +c010801d: eb 0a jmp c0108029 + else mm->sm_priv = NULL; +c010801f: 8b 45 f4 mov -0xc(%ebp),%eax +c0108022: c7 40 14 00 00 00 00 movl $0x0,0x14(%eax) + //设置引用计数和锁: + set_mm_count(mm, 0); +c0108029: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) +c0108030: 00 +c0108031: 8b 45 f4 mov -0xc(%ebp),%eax +c0108034: 89 04 24 mov %eax,(%esp) +c0108037: e8 08 ff ff ff call c0107f44 + lock_init(&(mm->mm_lock)); +c010803c: 8b 45 f4 mov -0xc(%ebp),%eax +c010803f: 83 c0 1c add $0x1c,%eax +c0108042: 89 04 24 mov %eax,(%esp) +c0108045: e8 e0 fe ff ff call c0107f2a + } + return mm; +c010804a: 8b 45 f4 mov -0xc(%ebp),%eax +} +c010804d: 89 ec mov %ebp,%esp +c010804f: 5d pop %ebp +c0108050: c3 ret + +c0108051 : + * @param vm_flags 虚拟内存区域的标志,表示内存区域的权限和特性。 + * + * @return 返回指向新创建的vma_struct结构体的指针,如果内存分配失败,则返回NULL。 + */ +struct vma_struct * +vma_create(uintptr_t vm_start, uintptr_t vm_end, uint32_t vm_flags) { +c0108051: 55 push %ebp +c0108052: 89 e5 mov %esp,%ebp +c0108054: 83 ec 28 sub $0x28,%esp + // 分配vma_struct结构体所需的内存空间 + struct vma_struct *vma = kmalloc(sizeof(struct vma_struct)); +c0108057: c7 04 24 18 00 00 00 movl $0x18,(%esp) +c010805e: e8 8d cc ff ff call c0104cf0 +c0108063: 89 45 f4 mov %eax,-0xc(%ebp) + // 检查内存是否成功分配 + if (vma != NULL) { +c0108066: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c010806a: 74 1b je c0108087 + // 初始化vma_struct的成员变量 + vma->vm_start = vm_start; +c010806c: 8b 45 f4 mov -0xc(%ebp),%eax +c010806f: 8b 55 08 mov 0x8(%ebp),%edx +c0108072: 89 50 04 mov %edx,0x4(%eax) + vma->vm_end = vm_end; +c0108075: 8b 45 f4 mov -0xc(%ebp),%eax +c0108078: 8b 55 0c mov 0xc(%ebp),%edx +c010807b: 89 50 08 mov %edx,0x8(%eax) + vma->vm_flags = vm_flags; +c010807e: 8b 45 f4 mov -0xc(%ebp),%eax +c0108081: 8b 55 10 mov 0x10(%ebp),%edx +c0108084: 89 50 0c mov %edx,0xc(%eax) + } + // 返回指向新创建的vma_struct结构体的指针,或在内存分配失败时返回NULL + return vma; +c0108087: 8b 45 f4 mov -0xc(%ebp),%eax +} +c010808a: 89 ec mov %ebp,%esp +c010808c: 5d pop %ebp +c010808d: c3 ret + +c010808e : + * 此函数首先检查mmap_cache是否包含所需的VMA,以加速查找过程 + * 如果mmap_cache未命中,则遍历VMA列表,直到找到包含给定地址的VMA或确定不存在这样的VMA + * 如果找到了合适的VMA,它将更新mmap_cache以供后续查找使用 + */ +struct vma_struct * +find_vma(struct mm_struct *mm, uintptr_t addr) { +c010808e: 55 push %ebp +c010808f: 89 e5 mov %esp,%ebp +c0108091: 83 ec 20 sub $0x20,%esp + struct vma_struct *vma = NULL;// 初始化VMA指针为NULL +c0108094: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + if (mm != NULL) {// 检查传入的内存描述符是否有效 +c010809b: 83 7d 08 00 cmpl $0x0,0x8(%ebp) +c010809f: 0f 84 95 00 00 00 je c010813a + // 检查mmap_cache是否包含所需的VMA + vma = mm->mmap_cache; +c01080a5: 8b 45 08 mov 0x8(%ebp),%eax +c01080a8: 8b 40 08 mov 0x8(%eax),%eax +c01080ab: 89 45 fc mov %eax,-0x4(%ebp) + if (!(vma != NULL && vma->vm_start <= addr && vma->vm_end > addr)) { +c01080ae: 83 7d fc 00 cmpl $0x0,-0x4(%ebp) +c01080b2: 74 16 je c01080ca +c01080b4: 8b 45 fc mov -0x4(%ebp),%eax +c01080b7: 8b 40 04 mov 0x4(%eax),%eax +c01080ba: 39 45 0c cmp %eax,0xc(%ebp) +c01080bd: 72 0b jb c01080ca +c01080bf: 8b 45 fc mov -0x4(%ebp),%eax +c01080c2: 8b 40 08 mov 0x8(%eax),%eax +c01080c5: 39 45 0c cmp %eax,0xc(%ebp) +c01080c8: 72 61 jb c010812b + // 如果mmap_cache未命中,则开始遍历VMA列表 + bool found = 0;// 初始化找到标志为0 +c01080ca: c7 45 f8 00 00 00 00 movl $0x0,-0x8(%ebp) + // 获取VMA列表的头指针 + list_entry_t *list = &(mm->mmap_list), *le = list; +c01080d1: 8b 45 08 mov 0x8(%ebp),%eax +c01080d4: 89 45 f0 mov %eax,-0x10(%ebp) +c01080d7: 8b 45 f0 mov -0x10(%ebp),%eax +c01080da: 89 45 f4 mov %eax,-0xc(%ebp) + while ((le = list_next(le)) != list) { // 遍历VMA列表 +c01080dd: eb 28 jmp c0108107 + vma = le2vma(le, list_link);// 将链表项转换为VMA结构 +c01080df: 8b 45 f4 mov -0xc(%ebp),%eax +c01080e2: 83 e8 10 sub $0x10,%eax +c01080e5: 89 45 fc mov %eax,-0x4(%ebp) + // 检查当前VMA是否包含给定地址 + if (vma->vm_start<=addr && addr < vma->vm_end) { +c01080e8: 8b 45 fc mov -0x4(%ebp),%eax +c01080eb: 8b 40 04 mov 0x4(%eax),%eax +c01080ee: 39 45 0c cmp %eax,0xc(%ebp) +c01080f1: 72 14 jb c0108107 +c01080f3: 8b 45 fc mov -0x4(%ebp),%eax +c01080f6: 8b 40 08 mov 0x8(%eax),%eax +c01080f9: 39 45 0c cmp %eax,0xc(%ebp) +c01080fc: 73 09 jae c0108107 + found = 1;// 找到合适的VMA +c01080fe: c7 45 f8 01 00 00 00 movl $0x1,-0x8(%ebp) + break;// 结束循环 +c0108105: eb 17 jmp c010811e +c0108107: 8b 45 f4 mov -0xc(%ebp),%eax +c010810a: 89 45 ec mov %eax,-0x14(%ebp) + return listelm->next; +c010810d: 8b 45 ec mov -0x14(%ebp),%eax +c0108110: 8b 40 04 mov 0x4(%eax),%eax + while ((le = list_next(le)) != list) { // 遍历VMA列表 +c0108113: 89 45 f4 mov %eax,-0xc(%ebp) +c0108116: 8b 45 f4 mov -0xc(%ebp),%eax +c0108119: 3b 45 f0 cmp -0x10(%ebp),%eax +c010811c: 75 c1 jne c01080df + } + } + if (!found) {// 如果未找到合适的VMA +c010811e: 83 7d f8 00 cmpl $0x0,-0x8(%ebp) +c0108122: 75 07 jne c010812b + vma = NULL;// 将VMA指针设置为NULL +c0108124: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + } + } + // 如果找到了合适的VMA,更新mmap_cache + if (vma != NULL) { +c010812b: 83 7d fc 00 cmpl $0x0,-0x4(%ebp) +c010812f: 74 09 je c010813a + mm->mmap_cache = vma;// 更新mmap_cache以加速后续查找 +c0108131: 8b 45 08 mov 0x8(%ebp),%eax +c0108134: 8b 55 fc mov -0x4(%ebp),%edx +c0108137: 89 50 08 mov %edx,0x8(%eax) + } + } + return vma; +c010813a: 8b 45 fc mov -0x4(%ebp),%eax +} +c010813d: 89 ec mov %ebp,%esp +c010813f: 5d pop %ebp +c0108140: c3 ret + +c0108141 : + * + * @param prev 指向前一个虚拟内存区域(VMA)的结构体指针 + * @param next 指向后一个虚拟内存区域(VMA)的结构体指针 + */ +static inline void +check_vma_overlap(struct vma_struct *prev, struct vma_struct *next) { +c0108141: 55 push %ebp +c0108142: 89 e5 mov %esp,%ebp +c0108144: 83 ec 18 sub $0x18,%esp + assert(prev->vm_start < prev->vm_end);// 确保前一个VMA的地址范围是有效的 +c0108147: 8b 45 08 mov 0x8(%ebp),%eax +c010814a: 8b 50 04 mov 0x4(%eax),%edx +c010814d: 8b 45 08 mov 0x8(%ebp),%eax +c0108150: 8b 40 08 mov 0x8(%eax),%eax +c0108153: 39 c2 cmp %eax,%edx +c0108155: 72 24 jb c010817b +c0108157: c7 44 24 0c e9 da 10 movl $0xc010dae9,0xc(%esp) +c010815e: c0 +c010815f: c7 44 24 08 07 db 10 movl $0xc010db07,0x8(%esp) +c0108166: c0 +c0108167: c7 44 24 04 a2 00 00 movl $0xa2,0x4(%esp) +c010816e: 00 +c010816f: c7 04 24 1c db 10 c0 movl $0xc010db1c,(%esp) +c0108176: e8 c0 8b ff ff call c0100d3b <__panic> + assert(prev->vm_end <= next->vm_start);// 确保两个VMA之间没有重叠 +c010817b: 8b 45 08 mov 0x8(%ebp),%eax +c010817e: 8b 50 08 mov 0x8(%eax),%edx +c0108181: 8b 45 0c mov 0xc(%ebp),%eax +c0108184: 8b 40 04 mov 0x4(%eax),%eax +c0108187: 39 c2 cmp %eax,%edx +c0108189: 76 24 jbe c01081af +c010818b: c7 44 24 0c 2c db 10 movl $0xc010db2c,0xc(%esp) +c0108192: c0 +c0108193: c7 44 24 08 07 db 10 movl $0xc010db07,0x8(%esp) +c010819a: c0 +c010819b: c7 44 24 04 a3 00 00 movl $0xa3,0x4(%esp) +c01081a2: 00 +c01081a3: c7 04 24 1c db 10 c0 movl $0xc010db1c,(%esp) +c01081aa: e8 8c 8b ff ff call c0100d3b <__panic> + assert(next->vm_start < next->vm_end);// 确保后一个VMA的地址范围是有效的 +c01081af: 8b 45 0c mov 0xc(%ebp),%eax +c01081b2: 8b 50 04 mov 0x4(%eax),%edx +c01081b5: 8b 45 0c mov 0xc(%ebp),%eax +c01081b8: 8b 40 08 mov 0x8(%eax),%eax +c01081bb: 39 c2 cmp %eax,%edx +c01081bd: 72 24 jb c01081e3 +c01081bf: c7 44 24 0c 4b db 10 movl $0xc010db4b,0xc(%esp) +c01081c6: c0 +c01081c7: c7 44 24 08 07 db 10 movl $0xc010db07,0x8(%esp) +c01081ce: c0 +c01081cf: c7 44 24 04 a4 00 00 movl $0xa4,0x4(%esp) +c01081d6: 00 +c01081d7: c7 04 24 1c db 10 c0 movl $0xc010db1c,(%esp) +c01081de: e8 58 8b ff ff call c0100d3b <__panic> +} +c01081e3: 90 nop +c01081e4: 89 ec mov %ebp,%esp +c01081e6: 5d pop %ebp +c01081e7: c3 ret + +c01081e8 : + * + * @param mm 指向内存描述符结构 `struct mm_struct` 的指针,表示一个进程的内存空间。 + * @param vma 指向要插入的VMA结构 `struct vma_struct` 的指针,描述一个内存区域。 + */ +void +insert_vma_struct(struct mm_struct *mm, struct vma_struct *vma) { +c01081e8: 55 push %ebp +c01081e9: 89 e5 mov %esp,%ebp +c01081eb: 83 ec 48 sub $0x48,%esp + // 断言VMA结构的起始地址小于结束地址,确保VMA结构的有效性。 + assert(vma->vm_start < vma->vm_end); +c01081ee: 8b 45 0c mov 0xc(%ebp),%eax +c01081f1: 8b 50 04 mov 0x4(%eax),%edx +c01081f4: 8b 45 0c mov 0xc(%ebp),%eax +c01081f7: 8b 40 08 mov 0x8(%eax),%eax +c01081fa: 39 c2 cmp %eax,%edx +c01081fc: 72 24 jb c0108222 +c01081fe: c7 44 24 0c 69 db 10 movl $0xc010db69,0xc(%esp) +c0108205: c0 +c0108206: c7 44 24 08 07 db 10 movl $0xc010db07,0x8(%esp) +c010820d: c0 +c010820e: c7 44 24 04 b5 00 00 movl $0xb5,0x4(%esp) +c0108215: 00 +c0108216: c7 04 24 1c db 10 c0 movl $0xc010db1c,(%esp) +c010821d: e8 19 8b ff ff call c0100d3b <__panic> + // 指向内存描述符中的VMA链表。 + list_entry_t *list = &(mm->mmap_list); +c0108222: 8b 45 08 mov 0x8(%ebp),%eax +c0108225: 89 45 ec mov %eax,-0x14(%ebp) + // 遍历链表以找到新VMA结构的正确插入位置。 + list_entry_t *le_prev = list, *le_next; +c0108228: 8b 45 ec mov -0x14(%ebp),%eax +c010822b: 89 45 f4 mov %eax,-0xc(%ebp) + + list_entry_t *le = list; +c010822e: 8b 45 ec mov -0x14(%ebp),%eax +c0108231: 89 45 f0 mov %eax,-0x10(%ebp) + // 遍历链表以找到新VMA结构的正确插入位置 + while ((le = list_next(le)) != list) { +c0108234: eb 1f jmp c0108255 + struct vma_struct *mmap_prev = le2vma(le, list_link); +c0108236: 8b 45 f0 mov -0x10(%ebp),%eax +c0108239: 83 e8 10 sub $0x10,%eax +c010823c: 89 45 e8 mov %eax,-0x18(%ebp) + // 如果当前VMA的起始地址大于新VMA的起始地址,则跳出循环 + if (mmap_prev->vm_start > vma->vm_start) { +c010823f: 8b 45 e8 mov -0x18(%ebp),%eax +c0108242: 8b 50 04 mov 0x4(%eax),%edx +c0108245: 8b 45 0c mov 0xc(%ebp),%eax +c0108248: 8b 40 04 mov 0x4(%eax),%eax +c010824b: 39 c2 cmp %eax,%edx +c010824d: 77 1f ja c010826e + break; + } + le_prev = le; +c010824f: 8b 45 f0 mov -0x10(%ebp),%eax +c0108252: 89 45 f4 mov %eax,-0xc(%ebp) +c0108255: 8b 45 f0 mov -0x10(%ebp),%eax +c0108258: 89 45 e0 mov %eax,-0x20(%ebp) +c010825b: 8b 45 e0 mov -0x20(%ebp),%eax +c010825e: 8b 40 04 mov 0x4(%eax),%eax + while ((le = list_next(le)) != list) { +c0108261: 89 45 f0 mov %eax,-0x10(%ebp) +c0108264: 8b 45 f0 mov -0x10(%ebp),%eax +c0108267: 3b 45 ec cmp -0x14(%ebp),%eax +c010826a: 75 ca jne c0108236 +c010826c: eb 01 jmp c010826f + break; +c010826e: 90 nop +c010826f: 8b 45 f4 mov -0xc(%ebp),%eax +c0108272: 89 45 dc mov %eax,-0x24(%ebp) +c0108275: 8b 45 dc mov -0x24(%ebp),%eax +c0108278: 8b 40 04 mov 0x4(%eax),%eax + } + // 获取下一个链表项 + le_next = list_next(le_prev); +c010827b: 89 45 e4 mov %eax,-0x1c(%ebp) + + /* check overlap */ + // 检查前一个VMA结构是否与新VMA结构重叠 + if (le_prev != list) { +c010827e: 8b 45 f4 mov -0xc(%ebp),%eax +c0108281: 3b 45 ec cmp -0x14(%ebp),%eax +c0108284: 74 15 je c010829b + check_vma_overlap(le2vma(le_prev, list_link), vma); +c0108286: 8b 45 f4 mov -0xc(%ebp),%eax +c0108289: 8d 50 f0 lea -0x10(%eax),%edx +c010828c: 8b 45 0c mov 0xc(%ebp),%eax +c010828f: 89 44 24 04 mov %eax,0x4(%esp) +c0108293: 89 14 24 mov %edx,(%esp) +c0108296: e8 a6 fe ff ff call c0108141 + } + // 检查下一个VMA结构是否与新VMA结构重叠 + if (le_next != list) { +c010829b: 8b 45 e4 mov -0x1c(%ebp),%eax +c010829e: 3b 45 ec cmp -0x14(%ebp),%eax +c01082a1: 74 15 je c01082b8 + check_vma_overlap(vma, le2vma(le_next, list_link)); +c01082a3: 8b 45 e4 mov -0x1c(%ebp),%eax +c01082a6: 83 e8 10 sub $0x10,%eax +c01082a9: 89 44 24 04 mov %eax,0x4(%esp) +c01082ad: 8b 45 0c mov 0xc(%ebp),%eax +c01082b0: 89 04 24 mov %eax,(%esp) +c01082b3: e8 89 fe ff ff call c0108141 + } + // 设置VMA结构所属的内存描述符 + vma->vm_mm = mm; +c01082b8: 8b 45 0c mov 0xc(%ebp),%eax +c01082bb: 8b 55 08 mov 0x8(%ebp),%edx +c01082be: 89 10 mov %edx,(%eax) + // 将新VMA结构插入链表 + list_add_after(le_prev, &(vma->list_link)); +c01082c0: 8b 45 0c mov 0xc(%ebp),%eax +c01082c3: 8d 50 10 lea 0x10(%eax),%edx +c01082c6: 8b 45 f4 mov -0xc(%ebp),%eax +c01082c9: 89 45 d8 mov %eax,-0x28(%ebp) +c01082cc: 89 55 d4 mov %edx,-0x2c(%ebp) + __list_add(elm, listelm, listelm->next); +c01082cf: 8b 45 d8 mov -0x28(%ebp),%eax +c01082d2: 8b 40 04 mov 0x4(%eax),%eax +c01082d5: 8b 55 d4 mov -0x2c(%ebp),%edx +c01082d8: 89 55 d0 mov %edx,-0x30(%ebp) +c01082db: 8b 55 d8 mov -0x28(%ebp),%edx +c01082de: 89 55 cc mov %edx,-0x34(%ebp) +c01082e1: 89 45 c8 mov %eax,-0x38(%ebp) + prev->next = next->prev = elm; +c01082e4: 8b 45 c8 mov -0x38(%ebp),%eax +c01082e7: 8b 55 d0 mov -0x30(%ebp),%edx +c01082ea: 89 10 mov %edx,(%eax) +c01082ec: 8b 45 c8 mov -0x38(%ebp),%eax +c01082ef: 8b 10 mov (%eax),%edx +c01082f1: 8b 45 cc mov -0x34(%ebp),%eax +c01082f4: 89 50 04 mov %edx,0x4(%eax) + elm->next = next; +c01082f7: 8b 45 d0 mov -0x30(%ebp),%eax +c01082fa: 8b 55 c8 mov -0x38(%ebp),%edx +c01082fd: 89 50 04 mov %edx,0x4(%eax) + elm->prev = prev; +c0108300: 8b 45 d0 mov -0x30(%ebp),%eax +c0108303: 8b 55 cc mov -0x34(%ebp),%edx +c0108306: 89 10 mov %edx,(%eax) +} +c0108308: 90 nop +} +c0108309: 90 nop + // 增加内存描述符中的映射计数 + mm->map_count ++; +c010830a: 8b 45 08 mov 0x8(%ebp),%eax +c010830d: 8b 40 10 mov 0x10(%eax),%eax +c0108310: 8d 50 01 lea 0x1(%eax),%edx +c0108313: 8b 45 08 mov 0x8(%ebp),%eax +c0108316: 89 50 10 mov %edx,0x10(%eax) +} +c0108319: 90 nop +c010831a: 89 ec mov %ebp,%esp +c010831c: 5d pop %ebp +c010831d: c3 ret + +c010831e : + * 此函数遍历并销毁与内存管理结构(mm_struct)关联的所有虚拟内存区域(VMA), + * 然后释放内存管理结构本身所占用的内存。这样做是为了确保在销毁内存管理结构之前, + * 所有相关的资源都被正确地释放。 + */ +void +mm_destroy(struct mm_struct *mm) { +c010831e: 55 push %ebp +c010831f: 89 e5 mov %esp,%ebp +c0108321: 83 ec 38 sub $0x38,%esp + // 获取内存映射列表的头指针 + list_entry_t *list = &(mm->mmap_list), *le; +c0108324: 8b 45 08 mov 0x8(%ebp),%eax +c0108327: 89 45 f4 mov %eax,-0xc(%ebp) + // 遍历内存映射列表,直到回到起点 + while ((le = list_next(list)) != list) { +c010832a: eb 38 jmp c0108364 +c010832c: 8b 45 f0 mov -0x10(%ebp),%eax +c010832f: 89 45 ec mov %eax,-0x14(%ebp) + __list_del(listelm->prev, listelm->next); +c0108332: 8b 45 ec mov -0x14(%ebp),%eax +c0108335: 8b 40 04 mov 0x4(%eax),%eax +c0108338: 8b 55 ec mov -0x14(%ebp),%edx +c010833b: 8b 12 mov (%edx),%edx +c010833d: 89 55 e8 mov %edx,-0x18(%ebp) +c0108340: 89 45 e4 mov %eax,-0x1c(%ebp) + prev->next = next; +c0108343: 8b 45 e8 mov -0x18(%ebp),%eax +c0108346: 8b 55 e4 mov -0x1c(%ebp),%edx +c0108349: 89 50 04 mov %edx,0x4(%eax) + next->prev = prev; +c010834c: 8b 45 e4 mov -0x1c(%ebp),%eax +c010834f: 8b 55 e8 mov -0x18(%ebp),%edx +c0108352: 89 10 mov %edx,(%eax) +} +c0108354: 90 nop +} +c0108355: 90 nop + // 从列表中删除当前虚拟内存区域的项 + list_del(le); + // 释放虚拟内存区域结构的内存 + kfree(le2vma(le, list_link)); +c0108356: 8b 45 f0 mov -0x10(%ebp),%eax +c0108359: 83 e8 10 sub $0x10,%eax +c010835c: 89 04 24 mov %eax,(%esp) +c010835f: e8 a9 c9 ff ff call c0104d0d +c0108364: 8b 45 f4 mov -0xc(%ebp),%eax +c0108367: 89 45 e0 mov %eax,-0x20(%ebp) + return listelm->next; +c010836a: 8b 45 e0 mov -0x20(%ebp),%eax +c010836d: 8b 40 04 mov 0x4(%eax),%eax + while ((le = list_next(list)) != list) { +c0108370: 89 45 f0 mov %eax,-0x10(%ebp) +c0108373: 8b 45 f0 mov -0x10(%ebp),%eax +c0108376: 3b 45 f4 cmp -0xc(%ebp),%eax +c0108379: 75 b1 jne c010832c + //kfree(le2vma(le, list_link), sizeof(struct vma_struct)); //kfree vma + } + // 释放内存管理结构本身的内存 + kfree(mm); //kfree mm +c010837b: 8b 45 08 mov 0x8(%ebp),%eax +c010837e: 89 04 24 mov %eax,(%esp) +c0108381: e8 87 c9 ff ff call c0104d0d + //kfree(mm, sizeof(struct mm_struct)); //kfree mm + // 将指针设置为NULL,表示该结构已被销毁 + mm=NULL; +c0108386: c7 45 08 00 00 00 00 movl $0x0,0x8(%ebp) +} +c010838d: 90 nop +c010838e: 89 ec mov %ebp,%esp +c0108390: 5d pop %ebp +c0108391: c3 ret + +c0108392 : + +int +mm_map(struct mm_struct *mm, uintptr_t addr, size_t len, uint32_t vm_flags, + struct vma_struct **vma_store) { +c0108392: 55 push %ebp +c0108393: 89 e5 mov %esp,%ebp +c0108395: 83 ec 38 sub $0x38,%esp + uintptr_t start = ROUNDDOWN(addr, PGSIZE), end = ROUNDUP(addr + len, PGSIZE); +c0108398: 8b 45 0c mov 0xc(%ebp),%eax +c010839b: 89 45 f0 mov %eax,-0x10(%ebp) +c010839e: 8b 45 f0 mov -0x10(%ebp),%eax +c01083a1: 25 00 f0 ff ff and $0xfffff000,%eax +c01083a6: 89 45 ec mov %eax,-0x14(%ebp) +c01083a9: c7 45 e8 00 10 00 00 movl $0x1000,-0x18(%ebp) +c01083b0: 8b 55 0c mov 0xc(%ebp),%edx +c01083b3: 8b 45 10 mov 0x10(%ebp),%eax +c01083b6: 01 c2 add %eax,%edx +c01083b8: 8b 45 e8 mov -0x18(%ebp),%eax +c01083bb: 01 d0 add %edx,%eax +c01083bd: 48 dec %eax +c01083be: 89 45 e4 mov %eax,-0x1c(%ebp) +c01083c1: 8b 45 e4 mov -0x1c(%ebp),%eax +c01083c4: ba 00 00 00 00 mov $0x0,%edx +c01083c9: f7 75 e8 divl -0x18(%ebp) +c01083cc: 8b 45 e4 mov -0x1c(%ebp),%eax +c01083cf: 29 d0 sub %edx,%eax +c01083d1: 89 45 e0 mov %eax,-0x20(%ebp) + if (!USER_ACCESS(start, end)) { +c01083d4: 81 7d ec ff ff 1f 00 cmpl $0x1fffff,-0x14(%ebp) +c01083db: 76 11 jbe c01083ee +c01083dd: 8b 45 ec mov -0x14(%ebp),%eax +c01083e0: 3b 45 e0 cmp -0x20(%ebp),%eax +c01083e3: 73 09 jae c01083ee +c01083e5: 81 7d e0 00 00 00 b0 cmpl $0xb0000000,-0x20(%ebp) +c01083ec: 76 0a jbe c01083f8 + return -E_INVAL; +c01083ee: b8 fd ff ff ff mov $0xfffffffd,%eax +c01083f3: e9 b0 00 00 00 jmp c01084a8 + } + + assert(mm != NULL); +c01083f8: 83 7d 08 00 cmpl $0x0,0x8(%ebp) +c01083fc: 75 24 jne c0108422 +c01083fe: c7 44 24 0c 85 db 10 movl $0xc010db85,0xc(%esp) +c0108405: c0 +c0108406: c7 44 24 08 07 db 10 movl $0xc010db07,0x8(%esp) +c010840d: c0 +c010840e: c7 44 24 04 fd 00 00 movl $0xfd,0x4(%esp) +c0108415: 00 +c0108416: c7 04 24 1c db 10 c0 movl $0xc010db1c,(%esp) +c010841d: e8 19 89 ff ff call c0100d3b <__panic> + + int ret = -E_INVAL; +c0108422: c7 45 f4 fd ff ff ff movl $0xfffffffd,-0xc(%ebp) + + struct vma_struct *vma; + if ((vma = find_vma(mm, start)) != NULL && end > vma->vm_start) { +c0108429: 8b 45 ec mov -0x14(%ebp),%eax +c010842c: 89 44 24 04 mov %eax,0x4(%esp) +c0108430: 8b 45 08 mov 0x8(%ebp),%eax +c0108433: 89 04 24 mov %eax,(%esp) +c0108436: e8 53 fc ff ff call c010808e +c010843b: 89 45 dc mov %eax,-0x24(%ebp) +c010843e: 83 7d dc 00 cmpl $0x0,-0x24(%ebp) +c0108442: 74 0b je c010844f +c0108444: 8b 45 dc mov -0x24(%ebp),%eax +c0108447: 8b 40 04 mov 0x4(%eax),%eax +c010844a: 39 45 e0 cmp %eax,-0x20(%ebp) +c010844d: 77 52 ja c01084a1 + goto out; + } + ret = -E_NO_MEM; +c010844f: c7 45 f4 fc ff ff ff movl $0xfffffffc,-0xc(%ebp) + + if ((vma = vma_create(start, end, vm_flags)) == NULL) { +c0108456: 8b 45 14 mov 0x14(%ebp),%eax +c0108459: 89 44 24 08 mov %eax,0x8(%esp) +c010845d: 8b 45 e0 mov -0x20(%ebp),%eax +c0108460: 89 44 24 04 mov %eax,0x4(%esp) +c0108464: 8b 45 ec mov -0x14(%ebp),%eax +c0108467: 89 04 24 mov %eax,(%esp) +c010846a: e8 e2 fb ff ff call c0108051 +c010846f: 89 45 dc mov %eax,-0x24(%ebp) +c0108472: 83 7d dc 00 cmpl $0x0,-0x24(%ebp) +c0108476: 74 2c je c01084a4 + goto out; + } + insert_vma_struct(mm, vma); +c0108478: 8b 45 dc mov -0x24(%ebp),%eax +c010847b: 89 44 24 04 mov %eax,0x4(%esp) +c010847f: 8b 45 08 mov 0x8(%ebp),%eax +c0108482: 89 04 24 mov %eax,(%esp) +c0108485: e8 5e fd ff ff call c01081e8 + if (vma_store != NULL) { +c010848a: 83 7d 18 00 cmpl $0x0,0x18(%ebp) +c010848e: 74 08 je c0108498 + *vma_store = vma; +c0108490: 8b 45 18 mov 0x18(%ebp),%eax +c0108493: 8b 55 dc mov -0x24(%ebp),%edx +c0108496: 89 10 mov %edx,(%eax) + } + ret = 0; +c0108498: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) +c010849f: eb 04 jmp c01084a5 + goto out; +c01084a1: 90 nop +c01084a2: eb 01 jmp c01084a5 + goto out; +c01084a4: 90 nop + +out: + return ret; +c01084a5: 8b 45 f4 mov -0xc(%ebp),%eax +} +c01084a8: 89 ec mov %ebp,%esp +c01084aa: 5d pop %ebp +c01084ab: c3 ret + +c01084ac : + +int +dup_mmap(struct mm_struct *to, struct mm_struct *from) { +c01084ac: 55 push %ebp +c01084ad: 89 e5 mov %esp,%ebp +c01084af: 56 push %esi +c01084b0: 53 push %ebx +c01084b1: 83 ec 40 sub $0x40,%esp + assert(to != NULL && from != NULL); +c01084b4: 83 7d 08 00 cmpl $0x0,0x8(%ebp) +c01084b8: 74 06 je c01084c0 +c01084ba: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) +c01084be: 75 24 jne c01084e4 +c01084c0: c7 44 24 0c 90 db 10 movl $0xc010db90,0xc(%esp) +c01084c7: c0 +c01084c8: c7 44 24 08 07 db 10 movl $0xc010db07,0x8(%esp) +c01084cf: c0 +c01084d0: c7 44 24 04 16 01 00 movl $0x116,0x4(%esp) +c01084d7: 00 +c01084d8: c7 04 24 1c db 10 c0 movl $0xc010db1c,(%esp) +c01084df: e8 57 88 ff ff call c0100d3b <__panic> + list_entry_t *list = &(from->mmap_list), *le = list; +c01084e4: 8b 45 0c mov 0xc(%ebp),%eax +c01084e7: 89 45 f0 mov %eax,-0x10(%ebp) +c01084ea: 8b 45 f0 mov -0x10(%ebp),%eax +c01084ed: 89 45 f4 mov %eax,-0xc(%ebp) + while ((le = list_prev(le)) != list) { +c01084f0: e9 92 00 00 00 jmp c0108587 + struct vma_struct *vma, *nvma; + vma = le2vma(le, list_link); +c01084f5: 8b 45 f4 mov -0xc(%ebp),%eax +c01084f8: 83 e8 10 sub $0x10,%eax +c01084fb: 89 45 ec mov %eax,-0x14(%ebp) + nvma = vma_create(vma->vm_start, vma->vm_end, vma->vm_flags); +c01084fe: 8b 45 ec mov -0x14(%ebp),%eax +c0108501: 8b 48 0c mov 0xc(%eax),%ecx +c0108504: 8b 45 ec mov -0x14(%ebp),%eax +c0108507: 8b 50 08 mov 0x8(%eax),%edx +c010850a: 8b 45 ec mov -0x14(%ebp),%eax +c010850d: 8b 40 04 mov 0x4(%eax),%eax +c0108510: 89 4c 24 08 mov %ecx,0x8(%esp) +c0108514: 89 54 24 04 mov %edx,0x4(%esp) +c0108518: 89 04 24 mov %eax,(%esp) +c010851b: e8 31 fb ff ff call c0108051 +c0108520: 89 45 e8 mov %eax,-0x18(%ebp) + if (nvma == NULL) { +c0108523: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) +c0108527: 75 07 jne c0108530 + return -E_NO_MEM; +c0108529: b8 fc ff ff ff mov $0xfffffffc,%eax +c010852e: eb 76 jmp c01085a6 + } + + insert_vma_struct(to, nvma); +c0108530: 8b 45 e8 mov -0x18(%ebp),%eax +c0108533: 89 44 24 04 mov %eax,0x4(%esp) +c0108537: 8b 45 08 mov 0x8(%ebp),%eax +c010853a: 89 04 24 mov %eax,(%esp) +c010853d: e8 a6 fc ff ff call c01081e8 + + bool share = 0; +c0108542: c7 45 e4 00 00 00 00 movl $0x0,-0x1c(%ebp) + if (copy_range(to->pgdir, from->pgdir, vma->vm_start, vma->vm_end, share) != 0) { +c0108549: 8b 45 ec mov -0x14(%ebp),%eax +c010854c: 8b 58 08 mov 0x8(%eax),%ebx +c010854f: 8b 45 ec mov -0x14(%ebp),%eax +c0108552: 8b 48 04 mov 0x4(%eax),%ecx +c0108555: 8b 45 0c mov 0xc(%ebp),%eax +c0108558: 8b 50 0c mov 0xc(%eax),%edx +c010855b: 8b 45 08 mov 0x8(%ebp),%eax +c010855e: 8b 40 0c mov 0xc(%eax),%eax +c0108561: 8b 75 e4 mov -0x1c(%ebp),%esi +c0108564: 89 74 24 10 mov %esi,0x10(%esp) +c0108568: 89 5c 24 0c mov %ebx,0xc(%esp) +c010856c: 89 4c 24 08 mov %ecx,0x8(%esp) +c0108570: 89 54 24 04 mov %edx,0x4(%esp) +c0108574: 89 04 24 mov %eax,(%esp) +c0108577: e8 bb d6 ff ff call c0105c37 +c010857c: 85 c0 test %eax,%eax +c010857e: 74 07 je c0108587 + return -E_NO_MEM; +c0108580: b8 fc ff ff ff mov $0xfffffffc,%eax +c0108585: eb 1f jmp c01085a6 +c0108587: 8b 45 f4 mov -0xc(%ebp),%eax +c010858a: 89 45 e0 mov %eax,-0x20(%ebp) + return listelm->prev; +c010858d: 8b 45 e0 mov -0x20(%ebp),%eax +c0108590: 8b 00 mov (%eax),%eax + while ((le = list_prev(le)) != list) { +c0108592: 89 45 f4 mov %eax,-0xc(%ebp) +c0108595: 8b 45 f4 mov -0xc(%ebp),%eax +c0108598: 3b 45 f0 cmp -0x10(%ebp),%eax +c010859b: 0f 85 54 ff ff ff jne c01084f5 + } + } + return 0; +c01085a1: b8 00 00 00 00 mov $0x0,%eax +} +c01085a6: 83 c4 40 add $0x40,%esp +c01085a9: 5b pop %ebx +c01085aa: 5e pop %esi +c01085ab: 5d pop %ebp +c01085ac: c3 ret + +c01085ad : + +void +exit_mmap(struct mm_struct *mm) { +c01085ad: 55 push %ebp +c01085ae: 89 e5 mov %esp,%ebp +c01085b0: 83 ec 38 sub $0x38,%esp + assert(mm != NULL && mm_count(mm) == 0); +c01085b3: 83 7d 08 00 cmpl $0x0,0x8(%ebp) +c01085b7: 74 0f je c01085c8 +c01085b9: 8b 45 08 mov 0x8(%ebp),%eax +c01085bc: 89 04 24 mov %eax,(%esp) +c01085bf: e8 75 f9 ff ff call c0107f39 +c01085c4: 85 c0 test %eax,%eax +c01085c6: 74 24 je c01085ec +c01085c8: c7 44 24 0c ac db 10 movl $0xc010dbac,0xc(%esp) +c01085cf: c0 +c01085d0: c7 44 24 08 07 db 10 movl $0xc010db07,0x8(%esp) +c01085d7: c0 +c01085d8: c7 44 24 04 2c 01 00 movl $0x12c,0x4(%esp) +c01085df: 00 +c01085e0: c7 04 24 1c db 10 c0 movl $0xc010db1c,(%esp) +c01085e7: e8 4f 87 ff ff call c0100d3b <__panic> + pde_t *pgdir = mm->pgdir; +c01085ec: 8b 45 08 mov 0x8(%ebp),%eax +c01085ef: 8b 40 0c mov 0xc(%eax),%eax +c01085f2: 89 45 f0 mov %eax,-0x10(%ebp) + list_entry_t *list = &(mm->mmap_list), *le = list; +c01085f5: 8b 45 08 mov 0x8(%ebp),%eax +c01085f8: 89 45 ec mov %eax,-0x14(%ebp) +c01085fb: 8b 45 ec mov -0x14(%ebp),%eax +c01085fe: 89 45 f4 mov %eax,-0xc(%ebp) + while ((le = list_next(le)) != list) { +c0108601: eb 28 jmp c010862b + struct vma_struct *vma = le2vma(le, list_link); +c0108603: 8b 45 f4 mov -0xc(%ebp),%eax +c0108606: 83 e8 10 sub $0x10,%eax +c0108609: 89 45 e4 mov %eax,-0x1c(%ebp) + unmap_range(pgdir, vma->vm_start, vma->vm_end); +c010860c: 8b 45 e4 mov -0x1c(%ebp),%eax +c010860f: 8b 50 08 mov 0x8(%eax),%edx +c0108612: 8b 45 e4 mov -0x1c(%ebp),%eax +c0108615: 8b 40 04 mov 0x4(%eax),%eax +c0108618: 89 54 24 08 mov %edx,0x8(%esp) +c010861c: 89 44 24 04 mov %eax,0x4(%esp) +c0108620: 8b 45 f0 mov -0x10(%ebp),%eax +c0108623: 89 04 24 mov %eax,(%esp) +c0108626: e8 0b d4 ff ff call c0105a36 +c010862b: 8b 45 f4 mov -0xc(%ebp),%eax +c010862e: 89 45 e0 mov %eax,-0x20(%ebp) + return listelm->next; +c0108631: 8b 45 e0 mov -0x20(%ebp),%eax +c0108634: 8b 40 04 mov 0x4(%eax),%eax + while ((le = list_next(le)) != list) { +c0108637: 89 45 f4 mov %eax,-0xc(%ebp) +c010863a: 8b 45 f4 mov -0xc(%ebp),%eax +c010863d: 3b 45 ec cmp -0x14(%ebp),%eax +c0108640: 75 c1 jne c0108603 + } + while ((le = list_next(le)) != list) { +c0108642: eb 28 jmp c010866c + struct vma_struct *vma = le2vma(le, list_link); +c0108644: 8b 45 f4 mov -0xc(%ebp),%eax +c0108647: 83 e8 10 sub $0x10,%eax +c010864a: 89 45 e8 mov %eax,-0x18(%ebp) + exit_range(pgdir, vma->vm_start, vma->vm_end); +c010864d: 8b 45 e8 mov -0x18(%ebp),%eax +c0108650: 8b 50 08 mov 0x8(%eax),%edx +c0108653: 8b 45 e8 mov -0x18(%ebp),%eax +c0108656: 8b 40 04 mov 0x4(%eax),%eax +c0108659: 89 54 24 08 mov %edx,0x8(%esp) +c010865d: 89 44 24 04 mov %eax,0x4(%esp) +c0108661: 8b 45 f0 mov -0x10(%ebp),%eax +c0108664: 89 04 24 mov %eax,(%esp) +c0108667: e8 c1 d4 ff ff call c0105b2d +c010866c: 8b 45 f4 mov -0xc(%ebp),%eax +c010866f: 89 45 dc mov %eax,-0x24(%ebp) +c0108672: 8b 45 dc mov -0x24(%ebp),%eax +c0108675: 8b 40 04 mov 0x4(%eax),%eax + while ((le = list_next(le)) != list) { +c0108678: 89 45 f4 mov %eax,-0xc(%ebp) +c010867b: 8b 45 f4 mov -0xc(%ebp),%eax +c010867e: 3b 45 ec cmp -0x14(%ebp),%eax +c0108681: 75 c1 jne c0108644 + } +} +c0108683: 90 nop +c0108684: 90 nop +c0108685: 89 ec mov %ebp,%esp +c0108687: 5d pop %ebp +c0108688: c3 ret + +c0108689 : + +bool +copy_from_user(struct mm_struct *mm, void *dst, const void *src, size_t len, bool writable) { +c0108689: 55 push %ebp +c010868a: 89 e5 mov %esp,%ebp +c010868c: 83 ec 18 sub $0x18,%esp + if (!user_mem_check(mm, (uintptr_t)src, len, writable)) { +c010868f: 8b 45 10 mov 0x10(%ebp),%eax +c0108692: 8b 55 18 mov 0x18(%ebp),%edx +c0108695: 89 54 24 0c mov %edx,0xc(%esp) +c0108699: 8b 55 14 mov 0x14(%ebp),%edx +c010869c: 89 54 24 08 mov %edx,0x8(%esp) +c01086a0: 89 44 24 04 mov %eax,0x4(%esp) +c01086a4: 8b 45 08 mov 0x8(%ebp),%eax +c01086a7: 89 04 24 mov %eax,(%esp) +c01086aa: e8 ab 09 00 00 call c010905a +c01086af: 85 c0 test %eax,%eax +c01086b1: 75 07 jne c01086ba + return 0; +c01086b3: b8 00 00 00 00 mov $0x0,%eax +c01086b8: eb 1e jmp c01086d8 + } + memcpy(dst, src, len); +c01086ba: 8b 45 14 mov 0x14(%ebp),%eax +c01086bd: 89 44 24 08 mov %eax,0x8(%esp) +c01086c1: 8b 45 10 mov 0x10(%ebp),%eax +c01086c4: 89 44 24 04 mov %eax,0x4(%esp) +c01086c8: 8b 45 0c mov 0xc(%ebp),%eax +c01086cb: 89 04 24 mov %eax,(%esp) +c01086ce: e8 03 38 00 00 call c010bed6 + return 1; +c01086d3: b8 01 00 00 00 mov $0x1,%eax +} +c01086d8: 89 ec mov %ebp,%esp +c01086da: 5d pop %ebp +c01086db: c3 ret + +c01086dc : + +bool +copy_to_user(struct mm_struct *mm, void *dst, const void *src, size_t len) { +c01086dc: 55 push %ebp +c01086dd: 89 e5 mov %esp,%ebp +c01086df: 83 ec 18 sub $0x18,%esp + if (!user_mem_check(mm, (uintptr_t)dst, len, 1)) { +c01086e2: 8b 45 0c mov 0xc(%ebp),%eax +c01086e5: c7 44 24 0c 01 00 00 movl $0x1,0xc(%esp) +c01086ec: 00 +c01086ed: 8b 55 14 mov 0x14(%ebp),%edx +c01086f0: 89 54 24 08 mov %edx,0x8(%esp) +c01086f4: 89 44 24 04 mov %eax,0x4(%esp) +c01086f8: 8b 45 08 mov 0x8(%ebp),%eax +c01086fb: 89 04 24 mov %eax,(%esp) +c01086fe: e8 57 09 00 00 call c010905a +c0108703: 85 c0 test %eax,%eax +c0108705: 75 07 jne c010870e + return 0; +c0108707: b8 00 00 00 00 mov $0x0,%eax +c010870c: eb 1e jmp c010872c + } + memcpy(dst, src, len); +c010870e: 8b 45 14 mov 0x14(%ebp),%eax +c0108711: 89 44 24 08 mov %eax,0x8(%esp) +c0108715: 8b 45 10 mov 0x10(%ebp),%eax +c0108718: 89 44 24 04 mov %eax,0x4(%esp) +c010871c: 8b 45 0c mov 0xc(%ebp),%eax +c010871f: 89 04 24 mov %eax,(%esp) +c0108722: e8 af 37 00 00 call c010bed6 + return 1; +c0108727: b8 01 00 00 00 mov $0x1,%eax +} +c010872c: 89 ec mov %ebp,%esp +c010872e: 5d pop %ebp +c010872f: c3 ret + +c0108730 : +/** + * 初始化虚拟内存管理(VMM)系统。 + * 此函数通过执行一系列检查来确保VMM系统可以正确初始化和运行。 + */ +void +vmm_init(void) { +c0108730: 55 push %ebp +c0108731: 89 e5 mov %esp,%ebp +c0108733: 83 ec 08 sub $0x8,%esp + // 检查VMM系统的状态和环境,以确保其能够正常工作。 + check_vmm(); +c0108736: e8 05 00 00 00 call c0108740 +} +c010873b: 90 nop +c010873c: 89 ec mov %ebp,%esp +c010873e: 5d pop %ebp +c010873f: c3 ret + +c0108740 : + * 此函数的目的是确保虚拟内存管理系统的正确性通过检查内存区域结构(VMA)、页面故障处理以及免费页面计数的 consistency 来实现 + * 它首先保存当前的免费页面数量,然后执行与 VMA 和页面故障相关的检查,最后确认免费页面数量未发生变化 + * 这是为了确保在检查过程中,内存状态没有因为错误或意外的修改而改变,从而验证内存管理的正确性 + */ +static void +check_vmm(void) { +c0108740: 55 push %ebp +c0108741: 89 e5 mov %esp,%ebp +c0108743: 83 ec 28 sub $0x28,%esp + // 保存当前的免费页面数量,用于后续的 consistency 检查 + size_t nr_free_pages_store = nr_free_pages(); +c0108746: e8 d8 ca ff ff call c0105223 +c010874b: 89 45 f4 mov %eax,-0xc(%ebp) + // 检查虚拟内存区域(VMA)结构的正确性 + check_vma_struct(); +c010874e: e8 16 00 00 00 call c0108769 + // 检查页面故障处理的正确性 + check_pgfault(); +c0108753: e8 a5 04 00 00 call c0108bfd + // 确保在检查过程中免费页面数量未发生变化,表明内存管理操作是正确的 + // assert(nr_free_pages_store == nr_free_pages()); + // 如果所有检查都通过,输出成功信息 + cprintf("check_vmm() succeeded.\n"); +c0108758: c7 04 24 cc db 10 c0 movl $0xc010dbcc,(%esp) +c010875f: e8 14 7c ff ff call c0100378 +} +c0108764: 90 nop +c0108765: 89 ec mov %ebp,%esp +c0108767: 5d pop %ebp +c0108768: c3 ret + +c0108769 : + +//测试虚拟内存区域(VMA)结构的创建、插入和查找功能。 +static void +check_vma_struct(void) { +c0108769: 55 push %ebp +c010876a: 89 e5 mov %esp,%ebp +c010876c: 83 ec 68 sub $0x68,%esp + // 记录当前空闲页面数量 + size_t nr_free_pages_store = nr_free_pages(); +c010876f: e8 af ca ff ff call c0105223 +c0108774: 89 45 ec mov %eax,-0x14(%ebp) + + struct mm_struct *mm = mm_create();// 创建内存管理结构 mm +c0108777: e8 39 f8 ff ff call c0107fb5 +c010877c: 89 45 e8 mov %eax,-0x18(%ebp) + assert(mm != NULL);// 确保 mm 不为 NULL +c010877f: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) +c0108783: 75 24 jne c01087a9 +c0108785: c7 44 24 0c 85 db 10 movl $0xc010db85,0xc(%esp) +c010878c: c0 +c010878d: c7 44 24 08 07 db 10 movl $0xc010db07,0x8(%esp) +c0108794: c0 +c0108795: c7 44 24 04 74 01 00 movl $0x174,0x4(%esp) +c010879c: 00 +c010879d: c7 04 24 1c db 10 c0 movl $0xc010db1c,(%esp) +c01087a4: e8 92 85 ff ff call c0100d3b <__panic> + + int step1 = 10, step2 = step1 * 10;// 定义两个步骤的步数 +c01087a9: c7 45 e4 0a 00 00 00 movl $0xa,-0x1c(%ebp) +c01087b0: 8b 55 e4 mov -0x1c(%ebp),%edx +c01087b3: 89 d0 mov %edx,%eax +c01087b5: c1 e0 02 shl $0x2,%eax +c01087b8: 01 d0 add %edx,%eax +c01087ba: 01 c0 add %eax,%eax +c01087bc: 89 45 e0 mov %eax,-0x20(%ebp) + + int i; + for (i = step1; i >= 1; i --) {// 第一步:创建并插入10个VMA +c01087bf: 8b 45 e4 mov -0x1c(%ebp),%eax +c01087c2: 89 45 f4 mov %eax,-0xc(%ebp) +c01087c5: eb 6f jmp c0108836 + // 创建 VMA 结构 + struct vma_struct *vma = vma_create(i * 5, i * 5 + 2, 0); +c01087c7: 8b 55 f4 mov -0xc(%ebp),%edx +c01087ca: 89 d0 mov %edx,%eax +c01087cc: c1 e0 02 shl $0x2,%eax +c01087cf: 01 d0 add %edx,%eax +c01087d1: 83 c0 02 add $0x2,%eax +c01087d4: 89 c1 mov %eax,%ecx +c01087d6: 8b 55 f4 mov -0xc(%ebp),%edx +c01087d9: 89 d0 mov %edx,%eax +c01087db: c1 e0 02 shl $0x2,%eax +c01087de: 01 d0 add %edx,%eax +c01087e0: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) +c01087e7: 00 +c01087e8: 89 4c 24 04 mov %ecx,0x4(%esp) +c01087ec: 89 04 24 mov %eax,(%esp) +c01087ef: e8 5d f8 ff ff call c0108051 +c01087f4: 89 45 bc mov %eax,-0x44(%ebp) + assert(vma != NULL);// 确保 VMA 不为 NULL +c01087f7: 83 7d bc 00 cmpl $0x0,-0x44(%ebp) +c01087fb: 75 24 jne c0108821 +c01087fd: c7 44 24 0c e4 db 10 movl $0xc010dbe4,0xc(%esp) +c0108804: c0 +c0108805: c7 44 24 08 07 db 10 movl $0xc010db07,0x8(%esp) +c010880c: c0 +c010880d: c7 44 24 04 7c 01 00 movl $0x17c,0x4(%esp) +c0108814: 00 +c0108815: c7 04 24 1c db 10 c0 movl $0xc010db1c,(%esp) +c010881c: e8 1a 85 ff ff call c0100d3b <__panic> + insert_vma_struct(mm, vma); //将 VMA 插入到 mm 中 +c0108821: 8b 45 bc mov -0x44(%ebp),%eax +c0108824: 89 44 24 04 mov %eax,0x4(%esp) +c0108828: 8b 45 e8 mov -0x18(%ebp),%eax +c010882b: 89 04 24 mov %eax,(%esp) +c010882e: e8 b5 f9 ff ff call c01081e8 + for (i = step1; i >= 1; i --) {// 第一步:创建并插入10个VMA +c0108833: ff 4d f4 decl -0xc(%ebp) +c0108836: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c010883a: 7f 8b jg c01087c7 + } + + for (i = step1 + 1; i <= step2; i ++) {// 第二步:创建并插入90个VMA +c010883c: 8b 45 e4 mov -0x1c(%ebp),%eax +c010883f: 40 inc %eax +c0108840: 89 45 f4 mov %eax,-0xc(%ebp) +c0108843: eb 6f jmp c01088b4 + // 创建 VMA 结构 + struct vma_struct *vma = vma_create(i * 5, i * 5 + 2, 0); +c0108845: 8b 55 f4 mov -0xc(%ebp),%edx +c0108848: 89 d0 mov %edx,%eax +c010884a: c1 e0 02 shl $0x2,%eax +c010884d: 01 d0 add %edx,%eax +c010884f: 83 c0 02 add $0x2,%eax +c0108852: 89 c1 mov %eax,%ecx +c0108854: 8b 55 f4 mov -0xc(%ebp),%edx +c0108857: 89 d0 mov %edx,%eax +c0108859: c1 e0 02 shl $0x2,%eax +c010885c: 01 d0 add %edx,%eax +c010885e: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) +c0108865: 00 +c0108866: 89 4c 24 04 mov %ecx,0x4(%esp) +c010886a: 89 04 24 mov %eax,(%esp) +c010886d: e8 df f7 ff ff call c0108051 +c0108872: 89 45 c0 mov %eax,-0x40(%ebp) + assert(vma != NULL);// 确保 VMA 不为 NULL +c0108875: 83 7d c0 00 cmpl $0x0,-0x40(%ebp) +c0108879: 75 24 jne c010889f +c010887b: c7 44 24 0c e4 db 10 movl $0xc010dbe4,0xc(%esp) +c0108882: c0 +c0108883: c7 44 24 08 07 db 10 movl $0xc010db07,0x8(%esp) +c010888a: c0 +c010888b: c7 44 24 04 83 01 00 movl $0x183,0x4(%esp) +c0108892: 00 +c0108893: c7 04 24 1c db 10 c0 movl $0xc010db1c,(%esp) +c010889a: e8 9c 84 ff ff call c0100d3b <__panic> + insert_vma_struct(mm, vma);// 将 VMA 插入到 mm 中 +c010889f: 8b 45 c0 mov -0x40(%ebp),%eax +c01088a2: 89 44 24 04 mov %eax,0x4(%esp) +c01088a6: 8b 45 e8 mov -0x18(%ebp),%eax +c01088a9: 89 04 24 mov %eax,(%esp) +c01088ac: e8 37 f9 ff ff call c01081e8 + for (i = step1 + 1; i <= step2; i ++) {// 第二步:创建并插入90个VMA +c01088b1: ff 45 f4 incl -0xc(%ebp) +c01088b4: 8b 45 f4 mov -0xc(%ebp),%eax +c01088b7: 3b 45 e0 cmp -0x20(%ebp),%eax +c01088ba: 7e 89 jle c0108845 + } + // 获取 VMA 链表的第一个节点 + list_entry_t *le = list_next(&(mm->mmap_list)); +c01088bc: 8b 45 e8 mov -0x18(%ebp),%eax +c01088bf: 89 45 b8 mov %eax,-0x48(%ebp) +c01088c2: 8b 45 b8 mov -0x48(%ebp),%eax +c01088c5: 8b 40 04 mov 0x4(%eax),%eax +c01088c8: 89 45 f0 mov %eax,-0x10(%ebp) + + for (i = 1; i <= step2; i ++) {// 验证插入顺序 +c01088cb: c7 45 f4 01 00 00 00 movl $0x1,-0xc(%ebp) +c01088d2: e9 96 00 00 00 jmp c010896d + assert(le != &(mm->mmap_list));// 确保节点不为空 +c01088d7: 8b 45 e8 mov -0x18(%ebp),%eax +c01088da: 39 45 f0 cmp %eax,-0x10(%ebp) +c01088dd: 75 24 jne c0108903 +c01088df: c7 44 24 0c f0 db 10 movl $0xc010dbf0,0xc(%esp) +c01088e6: c0 +c01088e7: c7 44 24 08 07 db 10 movl $0xc010db07,0x8(%esp) +c01088ee: c0 +c01088ef: c7 44 24 04 8a 01 00 movl $0x18a,0x4(%esp) +c01088f6: 00 +c01088f7: c7 04 24 1c db 10 c0 movl $0xc010db1c,(%esp) +c01088fe: e8 38 84 ff ff call c0100d3b <__panic> + struct vma_struct *mmap = le2vma(le, list_link);// 将链表节点转换为 VMA 结构 +c0108903: 8b 45 f0 mov -0x10(%ebp),%eax +c0108906: 83 e8 10 sub $0x10,%eax +c0108909: 89 45 c4 mov %eax,-0x3c(%ebp) + // 确认 VMA 的起始和结束地址 + assert(mmap->vm_start == i * 5 && mmap->vm_end == i * 5 + 2); +c010890c: 8b 45 c4 mov -0x3c(%ebp),%eax +c010890f: 8b 48 04 mov 0x4(%eax),%ecx +c0108912: 8b 55 f4 mov -0xc(%ebp),%edx +c0108915: 89 d0 mov %edx,%eax +c0108917: c1 e0 02 shl $0x2,%eax +c010891a: 01 d0 add %edx,%eax +c010891c: 39 c1 cmp %eax,%ecx +c010891e: 75 17 jne c0108937 +c0108920: 8b 45 c4 mov -0x3c(%ebp),%eax +c0108923: 8b 48 08 mov 0x8(%eax),%ecx +c0108926: 8b 55 f4 mov -0xc(%ebp),%edx +c0108929: 89 d0 mov %edx,%eax +c010892b: c1 e0 02 shl $0x2,%eax +c010892e: 01 d0 add %edx,%eax +c0108930: 83 c0 02 add $0x2,%eax +c0108933: 39 c1 cmp %eax,%ecx +c0108935: 74 24 je c010895b +c0108937: c7 44 24 0c 08 dc 10 movl $0xc010dc08,0xc(%esp) +c010893e: c0 +c010893f: c7 44 24 08 07 db 10 movl $0xc010db07,0x8(%esp) +c0108946: c0 +c0108947: c7 44 24 04 8d 01 00 movl $0x18d,0x4(%esp) +c010894e: 00 +c010894f: c7 04 24 1c db 10 c0 movl $0xc010db1c,(%esp) +c0108956: e8 e0 83 ff ff call c0100d3b <__panic> +c010895b: 8b 45 f0 mov -0x10(%ebp),%eax +c010895e: 89 45 b4 mov %eax,-0x4c(%ebp) +c0108961: 8b 45 b4 mov -0x4c(%ebp),%eax +c0108964: 8b 40 04 mov 0x4(%eax),%eax + le = list_next(le);// 移动到下一个节点 +c0108967: 89 45 f0 mov %eax,-0x10(%ebp) + for (i = 1; i <= step2; i ++) {// 验证插入顺序 +c010896a: ff 45 f4 incl -0xc(%ebp) +c010896d: 8b 45 f4 mov -0xc(%ebp),%eax +c0108970: 3b 45 e0 cmp -0x20(%ebp),%eax +c0108973: 0f 8e 5e ff ff ff jle c01088d7 + } + + for (i = 5; i <= 5 * step2; i +=5) {// 查找特定地址范围内的 VMA +c0108979: c7 45 f4 05 00 00 00 movl $0x5,-0xc(%ebp) +c0108980: e9 cb 01 00 00 jmp c0108b50 + struct vma_struct *vma1 = find_vma(mm, i);// 查找地址 i 处的 VMA +c0108985: 8b 45 f4 mov -0xc(%ebp),%eax +c0108988: 89 44 24 04 mov %eax,0x4(%esp) +c010898c: 8b 45 e8 mov -0x18(%ebp),%eax +c010898f: 89 04 24 mov %eax,(%esp) +c0108992: e8 f7 f6 ff ff call c010808e +c0108997: 89 45 d8 mov %eax,-0x28(%ebp) + assert(vma1 != NULL);// 确保找到 VMA +c010899a: 83 7d d8 00 cmpl $0x0,-0x28(%ebp) +c010899e: 75 24 jne c01089c4 +c01089a0: c7 44 24 0c 3d dc 10 movl $0xc010dc3d,0xc(%esp) +c01089a7: c0 +c01089a8: c7 44 24 08 07 db 10 movl $0xc010db07,0x8(%esp) +c01089af: c0 +c01089b0: c7 44 24 04 93 01 00 movl $0x193,0x4(%esp) +c01089b7: 00 +c01089b8: c7 04 24 1c db 10 c0 movl $0xc010db1c,(%esp) +c01089bf: e8 77 83 ff ff call c0100d3b <__panic> + // 查找地址 i + 1 处的 VMA + struct vma_struct *vma2 = find_vma(mm, i+1); +c01089c4: 8b 45 f4 mov -0xc(%ebp),%eax +c01089c7: 40 inc %eax +c01089c8: 89 44 24 04 mov %eax,0x4(%esp) +c01089cc: 8b 45 e8 mov -0x18(%ebp),%eax +c01089cf: 89 04 24 mov %eax,(%esp) +c01089d2: e8 b7 f6 ff ff call c010808e +c01089d7: 89 45 d4 mov %eax,-0x2c(%ebp) + assert(vma2 != NULL);// 确保找到 VMA +c01089da: 83 7d d4 00 cmpl $0x0,-0x2c(%ebp) +c01089de: 75 24 jne c0108a04 +c01089e0: c7 44 24 0c 4a dc 10 movl $0xc010dc4a,0xc(%esp) +c01089e7: c0 +c01089e8: c7 44 24 08 07 db 10 movl $0xc010db07,0x8(%esp) +c01089ef: c0 +c01089f0: c7 44 24 04 96 01 00 movl $0x196,0x4(%esp) +c01089f7: 00 +c01089f8: c7 04 24 1c db 10 c0 movl $0xc010db1c,(%esp) +c01089ff: e8 37 83 ff ff call c0100d3b <__panic> + // 查找地址 i + 2 处的 VMA + struct vma_struct *vma3 = find_vma(mm, i+2); +c0108a04: 8b 45 f4 mov -0xc(%ebp),%eax +c0108a07: 83 c0 02 add $0x2,%eax +c0108a0a: 89 44 24 04 mov %eax,0x4(%esp) +c0108a0e: 8b 45 e8 mov -0x18(%ebp),%eax +c0108a11: 89 04 24 mov %eax,(%esp) +c0108a14: e8 75 f6 ff ff call c010808e +c0108a19: 89 45 d0 mov %eax,-0x30(%ebp) + assert(vma3 == NULL);// 确保未找到 VMA +c0108a1c: 83 7d d0 00 cmpl $0x0,-0x30(%ebp) +c0108a20: 74 24 je c0108a46 +c0108a22: c7 44 24 0c 57 dc 10 movl $0xc010dc57,0xc(%esp) +c0108a29: c0 +c0108a2a: c7 44 24 08 07 db 10 movl $0xc010db07,0x8(%esp) +c0108a31: c0 +c0108a32: c7 44 24 04 99 01 00 movl $0x199,0x4(%esp) +c0108a39: 00 +c0108a3a: c7 04 24 1c db 10 c0 movl $0xc010db1c,(%esp) +c0108a41: e8 f5 82 ff ff call c0100d3b <__panic> + // 查找地址 i + 3 处的 VMA + struct vma_struct *vma4 = find_vma(mm, i+3); +c0108a46: 8b 45 f4 mov -0xc(%ebp),%eax +c0108a49: 83 c0 03 add $0x3,%eax +c0108a4c: 89 44 24 04 mov %eax,0x4(%esp) +c0108a50: 8b 45 e8 mov -0x18(%ebp),%eax +c0108a53: 89 04 24 mov %eax,(%esp) +c0108a56: e8 33 f6 ff ff call c010808e +c0108a5b: 89 45 cc mov %eax,-0x34(%ebp) + assert(vma4 == NULL);// 确保未找到 VMA +c0108a5e: 83 7d cc 00 cmpl $0x0,-0x34(%ebp) +c0108a62: 74 24 je c0108a88 +c0108a64: c7 44 24 0c 64 dc 10 movl $0xc010dc64,0xc(%esp) +c0108a6b: c0 +c0108a6c: c7 44 24 08 07 db 10 movl $0xc010db07,0x8(%esp) +c0108a73: c0 +c0108a74: c7 44 24 04 9c 01 00 movl $0x19c,0x4(%esp) +c0108a7b: 00 +c0108a7c: c7 04 24 1c db 10 c0 movl $0xc010db1c,(%esp) +c0108a83: e8 b3 82 ff ff call c0100d3b <__panic> + // 查找地址 i + 4 处的 VMA + struct vma_struct *vma5 = find_vma(mm, i+4); +c0108a88: 8b 45 f4 mov -0xc(%ebp),%eax +c0108a8b: 83 c0 04 add $0x4,%eax +c0108a8e: 89 44 24 04 mov %eax,0x4(%esp) +c0108a92: 8b 45 e8 mov -0x18(%ebp),%eax +c0108a95: 89 04 24 mov %eax,(%esp) +c0108a98: e8 f1 f5 ff ff call c010808e +c0108a9d: 89 45 c8 mov %eax,-0x38(%ebp) + assert(vma5 == NULL);// 确保未找到 VMA +c0108aa0: 83 7d c8 00 cmpl $0x0,-0x38(%ebp) +c0108aa4: 74 24 je c0108aca +c0108aa6: c7 44 24 0c 71 dc 10 movl $0xc010dc71,0xc(%esp) +c0108aad: c0 +c0108aae: c7 44 24 08 07 db 10 movl $0xc010db07,0x8(%esp) +c0108ab5: c0 +c0108ab6: c7 44 24 04 9f 01 00 movl $0x19f,0x4(%esp) +c0108abd: 00 +c0108abe: c7 04 24 1c db 10 c0 movl $0xc010db1c,(%esp) +c0108ac5: e8 71 82 ff ff call c0100d3b <__panic> + // 确认 VMA1 的起始和结束地址 + assert(vma1->vm_start == i && vma1->vm_end == i + 2); +c0108aca: 8b 45 d8 mov -0x28(%ebp),%eax +c0108acd: 8b 50 04 mov 0x4(%eax),%edx +c0108ad0: 8b 45 f4 mov -0xc(%ebp),%eax +c0108ad3: 39 c2 cmp %eax,%edx +c0108ad5: 75 10 jne c0108ae7 +c0108ad7: 8b 45 d8 mov -0x28(%ebp),%eax +c0108ada: 8b 40 08 mov 0x8(%eax),%eax +c0108add: 8b 55 f4 mov -0xc(%ebp),%edx +c0108ae0: 83 c2 02 add $0x2,%edx +c0108ae3: 39 d0 cmp %edx,%eax +c0108ae5: 74 24 je c0108b0b +c0108ae7: c7 44 24 0c 80 dc 10 movl $0xc010dc80,0xc(%esp) +c0108aee: c0 +c0108aef: c7 44 24 08 07 db 10 movl $0xc010db07,0x8(%esp) +c0108af6: c0 +c0108af7: c7 44 24 04 a1 01 00 movl $0x1a1,0x4(%esp) +c0108afe: 00 +c0108aff: c7 04 24 1c db 10 c0 movl $0xc010db1c,(%esp) +c0108b06: e8 30 82 ff ff call c0100d3b <__panic> + // 确认 VMA2 的起始和结束地址 + assert(vma2->vm_start == i && vma2->vm_end == i + 2); +c0108b0b: 8b 45 d4 mov -0x2c(%ebp),%eax +c0108b0e: 8b 50 04 mov 0x4(%eax),%edx +c0108b11: 8b 45 f4 mov -0xc(%ebp),%eax +c0108b14: 39 c2 cmp %eax,%edx +c0108b16: 75 10 jne c0108b28 +c0108b18: 8b 45 d4 mov -0x2c(%ebp),%eax +c0108b1b: 8b 40 08 mov 0x8(%eax),%eax +c0108b1e: 8b 55 f4 mov -0xc(%ebp),%edx +c0108b21: 83 c2 02 add $0x2,%edx +c0108b24: 39 d0 cmp %edx,%eax +c0108b26: 74 24 je c0108b4c +c0108b28: c7 44 24 0c b0 dc 10 movl $0xc010dcb0,0xc(%esp) +c0108b2f: c0 +c0108b30: c7 44 24 08 07 db 10 movl $0xc010db07,0x8(%esp) +c0108b37: c0 +c0108b38: c7 44 24 04 a3 01 00 movl $0x1a3,0x4(%esp) +c0108b3f: 00 +c0108b40: c7 04 24 1c db 10 c0 movl $0xc010db1c,(%esp) +c0108b47: e8 ef 81 ff ff call c0100d3b <__panic> + for (i = 5; i <= 5 * step2; i +=5) {// 查找特定地址范围内的 VMA +c0108b4c: 83 45 f4 05 addl $0x5,-0xc(%ebp) +c0108b50: 8b 55 e0 mov -0x20(%ebp),%edx +c0108b53: 89 d0 mov %edx,%eax +c0108b55: c1 e0 02 shl $0x2,%eax +c0108b58: 01 d0 add %edx,%eax +c0108b5a: 39 45 f4 cmp %eax,-0xc(%ebp) +c0108b5d: 0f 8e 22 fe ff ff jle c0108985 + } + // 检查小于5的地址范围内是否存在 VMA + for (i =4; i>=0; i--) { +c0108b63: c7 45 f4 04 00 00 00 movl $0x4,-0xc(%ebp) +c0108b6a: eb 6f jmp c0108bdb + // 查找地址 i 处的 VMA + struct vma_struct *vma_below_5= find_vma(mm,i); +c0108b6c: 8b 45 f4 mov -0xc(%ebp),%eax +c0108b6f: 89 44 24 04 mov %eax,0x4(%esp) +c0108b73: 8b 45 e8 mov -0x18(%ebp),%eax +c0108b76: 89 04 24 mov %eax,(%esp) +c0108b79: e8 10 f5 ff ff call c010808e +c0108b7e: 89 45 dc mov %eax,-0x24(%ebp) + if (vma_below_5 != NULL ) {// 如果找到 VMA +c0108b81: 83 7d dc 00 cmpl $0x0,-0x24(%ebp) +c0108b85: 74 27 je c0108bae + cprintf("vma_below_5: i %x, start %x, end %x\n",i, vma_below_5->vm_start, vma_below_5->vm_end); +c0108b87: 8b 45 dc mov -0x24(%ebp),%eax +c0108b8a: 8b 50 08 mov 0x8(%eax),%edx +c0108b8d: 8b 45 dc mov -0x24(%ebp),%eax +c0108b90: 8b 40 04 mov 0x4(%eax),%eax +c0108b93: 89 54 24 0c mov %edx,0xc(%esp) +c0108b97: 89 44 24 08 mov %eax,0x8(%esp) +c0108b9b: 8b 45 f4 mov -0xc(%ebp),%eax +c0108b9e: 89 44 24 04 mov %eax,0x4(%esp) +c0108ba2: c7 04 24 e0 dc 10 c0 movl $0xc010dce0,(%esp) +c0108ba9: e8 ca 77 ff ff call c0100378 + } + assert(vma_below_5 == NULL);// 确保未找到 VMA +c0108bae: 83 7d dc 00 cmpl $0x0,-0x24(%ebp) +c0108bb2: 74 24 je c0108bd8 +c0108bb4: c7 44 24 0c 05 dd 10 movl $0xc010dd05,0xc(%esp) +c0108bbb: c0 +c0108bbc: c7 44 24 08 07 db 10 movl $0xc010db07,0x8(%esp) +c0108bc3: c0 +c0108bc4: c7 44 24 04 ac 01 00 movl $0x1ac,0x4(%esp) +c0108bcb: 00 +c0108bcc: c7 04 24 1c db 10 c0 movl $0xc010db1c,(%esp) +c0108bd3: e8 63 81 ff ff call c0100d3b <__panic> + for (i =4; i>=0; i--) { +c0108bd8: ff 4d f4 decl -0xc(%ebp) +c0108bdb: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c0108bdf: 79 8b jns c0108b6c + } + + mm_destroy(mm);// 销毁 mm 结构 +c0108be1: 8b 45 e8 mov -0x18(%ebp),%eax +c0108be4: 89 04 24 mov %eax,(%esp) +c0108be7: e8 32 f7 ff ff call c010831e + + // 确保释放的页面数量与初始记录一致 + // assert(nr_free_pages_store == nr_free_pages()); + // 输出成功信息 + cprintf("check_vma_struct() succeeded!\n"); +c0108bec: c7 04 24 1c dd 10 c0 movl $0xc010dd1c,(%esp) +c0108bf3: e8 80 77 ff ff call c0100378 +} +c0108bf8: 90 nop +c0108bf9: 89 ec mov %ebp,%esp +c0108bfb: 5d pop %ebp +c0108bfc: c3 ret + +c0108bfd : +struct mm_struct *check_mm_struct; + +// check_pgfault - check correctness of pgfault handler +// 检查页故障处理的正确性 +static void +check_pgfault(void) { +c0108bfd: 55 push %ebp +c0108bfe: 89 e5 mov %esp,%ebp +c0108c00: 83 ec 38 sub $0x38,%esp + // 保存当前空闲页面的数量,用于后续检查 + size_t nr_free_pages_store = nr_free_pages(); +c0108c03: e8 1b c6 ff ff call c0105223 +c0108c08: 89 45 ec mov %eax,-0x14(%ebp) + // 创建内存管理结构体 + check_mm_struct = mm_create(); +c0108c0b: e8 a5 f3 ff ff call c0107fb5 +c0108c10: a3 0c 41 1a c0 mov %eax,0xc01a410c + // 确保内存管理结构体创建成功 + assert(check_mm_struct != NULL); +c0108c15: a1 0c 41 1a c0 mov 0xc01a410c,%eax +c0108c1a: 85 c0 test %eax,%eax +c0108c1c: 75 24 jne c0108c42 +c0108c1e: c7 44 24 0c 3b dd 10 movl $0xc010dd3b,0xc(%esp) +c0108c25: c0 +c0108c26: c7 44 24 08 07 db 10 movl $0xc010db07,0x8(%esp) +c0108c2d: c0 +c0108c2e: c7 44 24 04 c2 01 00 movl $0x1c2,0x4(%esp) +c0108c35: 00 +c0108c36: c7 04 24 1c db 10 c0 movl $0xc010db1c,(%esp) +c0108c3d: e8 f9 80 ff ff call c0100d3b <__panic> + // 将新创建的内存管理结构体赋值给局部变量mm + struct mm_struct *mm = check_mm_struct; +c0108c42: a1 0c 41 1a c0 mov 0xc01a410c,%eax +c0108c47: 89 45 e8 mov %eax,-0x18(%ebp) + // 将引导程序的页目录复制到新创建的内存管理结构体中 + pde_t *pgdir = mm->pgdir = boot_pgdir; +c0108c4a: 8b 15 00 fa 12 c0 mov 0xc012fa00,%edx +c0108c50: 8b 45 e8 mov -0x18(%ebp),%eax +c0108c53: 89 50 0c mov %edx,0xc(%eax) +c0108c56: 8b 45 e8 mov -0x18(%ebp),%eax +c0108c59: 8b 40 0c mov 0xc(%eax),%eax +c0108c5c: 89 45 e4 mov %eax,-0x1c(%ebp) + // 确保页目录的第0项是空的 + assert(pgdir[0] == 0); +c0108c5f: 8b 45 e4 mov -0x1c(%ebp),%eax +c0108c62: 8b 00 mov (%eax),%eax +c0108c64: 85 c0 test %eax,%eax +c0108c66: 74 24 je c0108c8c +c0108c68: c7 44 24 0c 53 dd 10 movl $0xc010dd53,0xc(%esp) +c0108c6f: c0 +c0108c70: c7 44 24 08 07 db 10 movl $0xc010db07,0x8(%esp) +c0108c77: c0 +c0108c78: c7 44 24 04 c8 01 00 movl $0x1c8,0x4(%esp) +c0108c7f: 00 +c0108c80: c7 04 24 1c db 10 c0 movl $0xc010db1c,(%esp) +c0108c87: e8 af 80 ff ff call c0100d3b <__panic> + // 创建一个虚拟内存区域结构体,具有写权限 + struct vma_struct *vma = vma_create(0, PTSIZE, VM_WRITE); +c0108c8c: c7 44 24 08 02 00 00 movl $0x2,0x8(%esp) +c0108c93: 00 +c0108c94: c7 44 24 04 00 00 40 movl $0x400000,0x4(%esp) +c0108c9b: 00 +c0108c9c: c7 04 24 00 00 00 00 movl $0x0,(%esp) +c0108ca3: e8 a9 f3 ff ff call c0108051 +c0108ca8: 89 45 e0 mov %eax,-0x20(%ebp) + // 确保虚拟内存区域结构体创建成功 + assert(vma != NULL); +c0108cab: 83 7d e0 00 cmpl $0x0,-0x20(%ebp) +c0108caf: 75 24 jne c0108cd5 +c0108cb1: c7 44 24 0c e4 db 10 movl $0xc010dbe4,0xc(%esp) +c0108cb8: c0 +c0108cb9: c7 44 24 08 07 db 10 movl $0xc010db07,0x8(%esp) +c0108cc0: c0 +c0108cc1: c7 44 24 04 cc 01 00 movl $0x1cc,0x4(%esp) +c0108cc8: 00 +c0108cc9: c7 04 24 1c db 10 c0 movl $0xc010db1c,(%esp) +c0108cd0: e8 66 80 ff ff call c0100d3b <__panic> + // 将虚拟内存区域结构体插入到内存管理结构体中 + insert_vma_struct(mm, vma); +c0108cd5: 8b 45 e0 mov -0x20(%ebp),%eax +c0108cd8: 89 44 24 04 mov %eax,0x4(%esp) +c0108cdc: 8b 45 e8 mov -0x18(%ebp),%eax +c0108cdf: 89 04 24 mov %eax,(%esp) +c0108ce2: e8 01 f5 ff ff call c01081e8 + // 定义一个地址,用于访问虚拟内存 + uintptr_t addr = 0x100; +c0108ce7: c7 45 dc 00 01 00 00 movl $0x100,-0x24(%ebp) + // 确保通过该地址可以找到之前插入的虚拟内存区域 + assert(find_vma(mm, addr) == vma); +c0108cee: 8b 45 dc mov -0x24(%ebp),%eax +c0108cf1: 89 44 24 04 mov %eax,0x4(%esp) +c0108cf5: 8b 45 e8 mov -0x18(%ebp),%eax +c0108cf8: 89 04 24 mov %eax,(%esp) +c0108cfb: e8 8e f3 ff ff call c010808e +c0108d00: 39 45 e0 cmp %eax,-0x20(%ebp) +c0108d03: 74 24 je c0108d29 +c0108d05: c7 44 24 0c 61 dd 10 movl $0xc010dd61,0xc(%esp) +c0108d0c: c0 +c0108d0d: c7 44 24 08 07 db 10 movl $0xc010db07,0x8(%esp) +c0108d14: c0 +c0108d15: c7 44 24 04 d2 01 00 movl $0x1d2,0x4(%esp) +c0108d1c: 00 +c0108d1d: c7 04 24 1c db 10 c0 movl $0xc010db1c,(%esp) +c0108d24: e8 12 80 ff ff call c0100d3b <__panic> + // 初始化一个累加器,用于校验写入的数据 + int i, sum = 0; +c0108d29: c7 45 f0 00 00 00 00 movl $0x0,-0x10(%ebp) + // 写入数据到虚拟内存,并累加 + for (i = 0; i < 100; i ++) { +c0108d30: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) +c0108d37: eb 16 jmp c0108d4f + *(char *)(addr + i) = i; +c0108d39: 8b 55 f4 mov -0xc(%ebp),%edx +c0108d3c: 8b 45 dc mov -0x24(%ebp),%eax +c0108d3f: 01 d0 add %edx,%eax +c0108d41: 8b 55 f4 mov -0xc(%ebp),%edx +c0108d44: 88 10 mov %dl,(%eax) + sum += i; +c0108d46: 8b 45 f4 mov -0xc(%ebp),%eax +c0108d49: 01 45 f0 add %eax,-0x10(%ebp) + for (i = 0; i < 100; i ++) { +c0108d4c: ff 45 f4 incl -0xc(%ebp) +c0108d4f: 83 7d f4 63 cmpl $0x63,-0xc(%ebp) +c0108d53: 7e e4 jle c0108d39 + } + // 读取虚拟内存中的数据,并减去,最终结果应为0 + for (i = 0; i < 100; i ++) { +c0108d55: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) +c0108d5c: eb 14 jmp c0108d72 + sum -= *(char *)(addr + i); +c0108d5e: 8b 55 f4 mov -0xc(%ebp),%edx +c0108d61: 8b 45 dc mov -0x24(%ebp),%eax +c0108d64: 01 d0 add %edx,%eax +c0108d66: 0f b6 00 movzbl (%eax),%eax +c0108d69: 0f be c0 movsbl %al,%eax +c0108d6c: 29 45 f0 sub %eax,-0x10(%ebp) + for (i = 0; i < 100; i ++) { +c0108d6f: ff 45 f4 incl -0xc(%ebp) +c0108d72: 83 7d f4 63 cmpl $0x63,-0xc(%ebp) +c0108d76: 7e e6 jle c0108d5e + } + // 确保累加器的值为0,证明数据读写正确 + assert(sum == 0); +c0108d78: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) +c0108d7c: 74 24 je c0108da2 +c0108d7e: c7 44 24 0c 7b dd 10 movl $0xc010dd7b,0xc(%esp) +c0108d85: c0 +c0108d86: c7 44 24 08 07 db 10 movl $0xc010db07,0x8(%esp) +c0108d8d: c0 +c0108d8e: c7 44 24 04 df 01 00 movl $0x1df,0x4(%esp) +c0108d95: 00 +c0108d96: c7 04 24 1c db 10 c0 movl $0xc010db1c,(%esp) +c0108d9d: e8 99 7f ff ff call c0100d3b <__panic> + // 移除页目录中的相应页面 + page_remove(pgdir, ROUNDDOWN(addr, PGSIZE)); +c0108da2: 8b 45 dc mov -0x24(%ebp),%eax +c0108da5: 89 45 d8 mov %eax,-0x28(%ebp) +c0108da8: 8b 45 d8 mov -0x28(%ebp),%eax +c0108dab: 25 00 f0 ff ff and $0xfffff000,%eax +c0108db0: 89 44 24 04 mov %eax,0x4(%esp) +c0108db4: 8b 45 e4 mov -0x1c(%ebp),%eax +c0108db7: 89 04 24 mov %eax,(%esp) +c0108dba: e8 9d d0 ff ff call c0105e5c + // 释放第0项页目录对应的页面 + free_page(pde2page(pgdir[0])); +c0108dbf: 8b 45 e4 mov -0x1c(%ebp),%eax +c0108dc2: 8b 00 mov (%eax),%eax +c0108dc4: 89 04 24 mov %eax,(%esp) +c0108dc7: e8 cf f1 ff ff call c0107f9b +c0108dcc: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c0108dd3: 00 +c0108dd4: 89 04 24 mov %eax,(%esp) +c0108dd7: e8 12 c4 ff ff call c01051ee + // 将页目录的第0项设置为空 + pgdir[0] = 0; +c0108ddc: 8b 45 e4 mov -0x1c(%ebp),%eax +c0108ddf: c7 00 00 00 00 00 movl $0x0,(%eax) + // 将内存管理结构体中的页目录设置为空 + mm->pgdir = NULL; +c0108de5: 8b 45 e8 mov -0x18(%ebp),%eax +c0108de8: c7 40 0c 00 00 00 00 movl $0x0,0xc(%eax) + // 销毁内存管理结构体 + mm_destroy(mm); +c0108def: 8b 45 e8 mov -0x18(%ebp),%eax +c0108df2: 89 04 24 mov %eax,(%esp) +c0108df5: e8 24 f5 ff ff call c010831e + // 将检查用的内存管理结构体设置为空 + check_mm_struct = NULL; +c0108dfa: c7 05 0c 41 1a c0 00 movl $0x0,0xc01a410c +c0108e01: 00 00 00 + // 确保空闲页面的数量没有变化,证明内存管理正确 + assert(nr_free_pages_store == nr_free_pages()); +c0108e04: e8 1a c4 ff ff call c0105223 +c0108e09: 39 45 ec cmp %eax,-0x14(%ebp) +c0108e0c: 74 24 je c0108e32 +c0108e0e: c7 44 24 0c 84 dd 10 movl $0xc010dd84,0xc(%esp) +c0108e15: c0 +c0108e16: c7 44 24 08 07 db 10 movl $0xc010db07,0x8(%esp) +c0108e1d: c0 +c0108e1e: c7 44 24 04 ed 01 00 movl $0x1ed,0x4(%esp) +c0108e25: 00 +c0108e26: c7 04 24 1c db 10 c0 movl $0xc010db1c,(%esp) +c0108e2d: e8 09 7f ff ff call c0100d3b <__panic> + // 打印成功信息 + cprintf("check_pgfault() succeeded!\n"); +c0108e32: c7 04 24 ab dd 10 c0 movl $0xc010ddab,(%esp) +c0108e39: e8 3a 75 ff ff call c0100378 +} +c0108e3e: 90 nop +c0108e3f: 89 ec mov %ebp,%esp +c0108e41: 5d pop %ebp +c0108e42: c3 ret + +c0108e43 : + * @param addr 引发页面错误的线性地址。 + * + * @return 成功返回0,失败返回负错误码。 + */ +int +do_pgfault(struct mm_struct *mm, uint32_t error_code, uintptr_t addr) { +c0108e43: 55 push %ebp +c0108e44: 89 e5 mov %esp,%ebp +c0108e46: 83 ec 38 sub $0x38,%esp + int ret = -E_INVAL;// 初始化返回值为无效错误 +c0108e49: c7 45 f4 fd ff ff ff movl $0xfffffffd,-0xc(%ebp) + //try to find a vma which include addr + // 尝试找到包含 addr 的 vma + struct vma_struct *vma = find_vma(mm, addr); +c0108e50: 8b 45 10 mov 0x10(%ebp),%eax +c0108e53: 89 44 24 04 mov %eax,0x4(%esp) +c0108e57: 8b 45 08 mov 0x8(%ebp),%eax +c0108e5a: 89 04 24 mov %eax,(%esp) +c0108e5d: e8 2c f2 ff ff call c010808e +c0108e62: 89 45 ec mov %eax,-0x14(%ebp) + + pgfault_num++;// 增加页面错误计数 +c0108e65: a1 10 41 1a c0 mov 0xc01a4110,%eax +c0108e6a: 40 inc %eax +c0108e6b: a3 10 41 1a c0 mov %eax,0xc01a4110 + // 检查 addr 是否在 mm 的 vma 范围内 + //If the addr is in the range of a mm's vma? + if (vma == NULL || vma->vm_start > addr) { +c0108e70: 83 7d ec 00 cmpl $0x0,-0x14(%ebp) +c0108e74: 74 0b je c0108e81 +c0108e76: 8b 45 ec mov -0x14(%ebp),%eax +c0108e79: 8b 40 04 mov 0x4(%eax),%eax +c0108e7c: 39 45 10 cmp %eax,0x10(%ebp) +c0108e7f: 73 18 jae c0108e99 + cprintf("not valid addr %x, and can not find it in vma\n", addr); +c0108e81: 8b 45 10 mov 0x10(%ebp),%eax +c0108e84: 89 44 24 04 mov %eax,0x4(%esp) +c0108e88: c7 04 24 c8 dd 10 c0 movl $0xc010ddc8,(%esp) +c0108e8f: e8 e4 74 ff ff call c0100378 + goto failed;// 跳转到错误处理部分 +c0108e94: e9 ba 01 00 00 jmp c0109053 + } + //check the error_code + // 检查错误代码 + switch (error_code & 3) { +c0108e99: 8b 45 0c mov 0xc(%ebp),%eax +c0108e9c: 83 e0 03 and $0x3,%eax +c0108e9f: 85 c0 test %eax,%eax +c0108ea1: 74 34 je c0108ed7 +c0108ea3: 83 f8 01 cmp $0x1,%eax +c0108ea6: 74 1e je c0108ec6 + default: + /* 默认错误代码标志:3 (W/R=1, P=1): 写操作,存在 */ + /* error code flag : default is 3 ( W/R=1, P=1): write, present */ + case 2: /* error code flag : (W/R=1, P=0): write, not present */ + /* 错误代码标志:(W/R=1, P=0): 写操作,不存在 */ + if (!(vma->vm_flags & VM_WRITE)) { +c0108ea8: 8b 45 ec mov -0x14(%ebp),%eax +c0108eab: 8b 40 0c mov 0xc(%eax),%eax +c0108eae: 83 e0 02 and $0x2,%eax +c0108eb1: 85 c0 test %eax,%eax +c0108eb3: 75 40 jne c0108ef5 + cprintf("do_pgfault failed: error code flag = write AND not present, but the addr's vma cannot write\n"); +c0108eb5: c7 04 24 f8 dd 10 c0 movl $0xc010ddf8,(%esp) +c0108ebc: e8 b7 74 ff ff call c0100378 + goto failed;// 跳转到错误处理部分 +c0108ec1: e9 8d 01 00 00 jmp c0109053 + } + break; + case 1: /* error code flag : (W/R=0, P=1): read, present */ + /* 错误代码标志:(W/R=0, P=1): 读操作,存在 */ + cprintf("do_pgfault failed: error code flag = read AND present\n"); +c0108ec6: c7 04 24 58 de 10 c0 movl $0xc010de58,(%esp) +c0108ecd: e8 a6 74 ff ff call c0100378 + goto failed;// 跳转到错误处理部分 +c0108ed2: e9 7c 01 00 00 jmp c0109053 + case 0: /* error code flag : (W/R=0, P=0): read, not present */ + /* 错误代码标志:(W/R=0, P=0): 读操作,不存在 */ + if (!(vma->vm_flags & (VM_READ | VM_EXEC))) { +c0108ed7: 8b 45 ec mov -0x14(%ebp),%eax +c0108eda: 8b 40 0c mov 0xc(%eax),%eax +c0108edd: 83 e0 05 and $0x5,%eax +c0108ee0: 85 c0 test %eax,%eax +c0108ee2: 75 12 jne c0108ef6 + cprintf("do_pgfault failed: error code flag = read AND not present, but the addr's vma cannot read or exec\n"); +c0108ee4: c7 04 24 90 de 10 c0 movl $0xc010de90,(%esp) +c0108eeb: e8 88 74 ff ff call c0100378 + goto failed;// 跳转到错误处理部分 +c0108ef0: e9 5e 01 00 00 jmp c0109053 + break; +c0108ef5: 90 nop + /* 如果 (写入已存在的地址) 或 + * (写入不存在的地址且地址可写) 或 + * (读取不存在的地址且地址可读) + * 则继续处理 + */ + uint32_t perm = PTE_U;// 初始化权限标志为用户可访问 +c0108ef6: c7 45 f0 04 00 00 00 movl $0x4,-0x10(%ebp) + if (vma->vm_flags & VM_WRITE) { +c0108efd: 8b 45 ec mov -0x14(%ebp),%eax +c0108f00: 8b 40 0c mov 0xc(%eax),%eax +c0108f03: 83 e0 02 and $0x2,%eax +c0108f06: 85 c0 test %eax,%eax +c0108f08: 74 04 je c0108f0e + perm |= PTE_W;// 如果 vma 可写,则设置写权限 +c0108f0a: 83 4d f0 02 orl $0x2,-0x10(%ebp) + } + addr = ROUNDDOWN(addr, PGSIZE);// 将地址对齐到页边界 +c0108f0e: 8b 45 10 mov 0x10(%ebp),%eax +c0108f11: 89 45 e8 mov %eax,-0x18(%ebp) +c0108f14: 8b 45 e8 mov -0x18(%ebp),%eax +c0108f17: 25 00 f0 ff ff and $0xfffff000,%eax +c0108f1c: 89 45 10 mov %eax,0x10(%ebp) + + ret = -E_NO_MEM;// 初始化返回值为内存不足错误 +c0108f1f: c7 45 f4 fc ff ff ff movl $0xfffffffc,-0xc(%ebp) + + pte_t *ptep=NULL; +c0108f26: c7 45 e4 00 00 00 00 movl $0x0,-0x1c(%ebp) +#endif + // try to find a pte, if pte's PT(Page Table) isn't existed, then create a PT. + // (notice the 3th parameter '1') + // 尝试找到一个页表项 pte,如果包含该 pte 的页表不存在,则创建一个页表。 + // 注意第三个参数 '1' 表示如果需要,可以创建新的页表。 + if ((ptep = get_pte(mm->pgdir, addr, 1)) == NULL) { +c0108f2d: 8b 45 08 mov 0x8(%ebp),%eax +c0108f30: 8b 40 0c mov 0xc(%eax),%eax +c0108f33: c7 44 24 08 01 00 00 movl $0x1,0x8(%esp) +c0108f3a: 00 +c0108f3b: 8b 55 10 mov 0x10(%ebp),%edx +c0108f3e: 89 54 24 04 mov %edx,0x4(%esp) +c0108f42: 89 04 24 mov %eax,(%esp) +c0108f45: e8 f2 c8 ff ff call c010583c +c0108f4a: 89 45 e4 mov %eax,-0x1c(%ebp) +c0108f4d: 83 7d e4 00 cmpl $0x0,-0x1c(%ebp) +c0108f51: 75 11 jne c0108f64 + cprintf("get_pte in do_pgfault failed\n");// 输出错误信息 +c0108f53: c7 04 24 f3 de 10 c0 movl $0xc010def3,(%esp) +c0108f5a: e8 19 74 ff ff call c0100378 + goto failed;// 跳转到错误处理部分 +c0108f5f: e9 ef 00 00 00 jmp c0109053 + } + // 如果页表项 pte 的物理地址不存在,则分配一页内存并映射物理地址与逻辑地址 + if (*ptep == 0) { // if the phy addr isn't exist, then alloc a page & map the phy addr with logical addr +c0108f64: 8b 45 e4 mov -0x1c(%ebp),%eax +c0108f67: 8b 00 mov (%eax),%eax +c0108f69: 85 c0 test %eax,%eax +c0108f6b: 75 35 jne c0108fa2 + if (pgdir_alloc_page(mm->pgdir, addr, perm) == NULL) { +c0108f6d: 8b 45 08 mov 0x8(%ebp),%eax +c0108f70: 8b 40 0c mov 0xc(%eax),%eax +c0108f73: 8b 55 f0 mov -0x10(%ebp),%edx +c0108f76: 89 54 24 08 mov %edx,0x8(%esp) +c0108f7a: 8b 55 10 mov 0x10(%ebp),%edx +c0108f7d: 89 54 24 04 mov %edx,0x4(%esp) +c0108f81: 89 04 24 mov %eax,(%esp) +c0108f84: e8 34 d0 ff ff call c0105fbd +c0108f89: 85 c0 test %eax,%eax +c0108f8b: 0f 85 bb 00 00 00 jne c010904c + cprintf("pgdir_alloc_page in do_pgfault failed\n");// 输出错误信息 +c0108f91: c7 04 24 14 df 10 c0 movl $0xc010df14,(%esp) +c0108f98: e8 db 73 ff ff call c0100378 + goto failed;// 跳转到错误处理部分 +c0108f9d: e9 b1 00 00 00 jmp c0109053 + } + else { // if this pte is a swap entry, then load data from disk to a page with phy addr + // and call page_insert to map the phy addr with logical addr + // 如果页表项 pte 是一个交换项,则从磁盘加载数据到 + //一个具有物理地址的页面,并映射物理地址与逻辑地址 + if(swap_init_ok) {// 检查交换初始化是否成功 +c0108fa2: a1 44 40 1a c0 mov 0xc01a4044,%eax +c0108fa7: 85 c0 test %eax,%eax +c0108fa9: 0f 84 86 00 00 00 je c0109035 + struct Page *page=NULL;// 声明一个页面指针 +c0108faf: c7 45 e0 00 00 00 00 movl $0x0,-0x20(%ebp) + if ((ret = swap_in(mm, addr, &page)) != 0) { +c0108fb6: 8d 45 e0 lea -0x20(%ebp),%eax +c0108fb9: 89 44 24 08 mov %eax,0x8(%esp) +c0108fbd: 8b 45 10 mov 0x10(%ebp),%eax +c0108fc0: 89 44 24 04 mov %eax,0x4(%esp) +c0108fc4: 8b 45 08 mov 0x8(%ebp),%eax +c0108fc7: 89 04 24 mov %eax,(%esp) +c0108fca: e8 c6 e0 ff ff call c0107095 +c0108fcf: 89 45 f4 mov %eax,-0xc(%ebp) +c0108fd2: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c0108fd6: 74 0e je c0108fe6 + cprintf("swap_in in do_pgfault failed\n"); +c0108fd8: c7 04 24 3b df 10 c0 movl $0xc010df3b,(%esp) +c0108fdf: e8 94 73 ff ff call c0100378 +c0108fe4: eb 6d jmp c0109053 + goto failed; + } + page_insert(mm->pgdir, page, addr, perm);// 设置物理地址与逻辑地址的映射 +c0108fe6: 8b 55 e0 mov -0x20(%ebp),%edx +c0108fe9: 8b 45 08 mov 0x8(%ebp),%eax +c0108fec: 8b 40 0c mov 0xc(%eax),%eax +c0108fef: 8b 4d f0 mov -0x10(%ebp),%ecx +c0108ff2: 89 4c 24 0c mov %ecx,0xc(%esp) +c0108ff6: 8b 4d 10 mov 0x10(%ebp),%ecx +c0108ff9: 89 4c 24 08 mov %ecx,0x8(%esp) +c0108ffd: 89 54 24 04 mov %edx,0x4(%esp) +c0109001: 89 04 24 mov %eax,(%esp) +c0109004: e8 9a ce ff ff call c0105ea3 + swap_map_swappable(mm, addr, page, 1);// 设置页面可交换 +c0109009: 8b 45 e0 mov -0x20(%ebp),%eax +c010900c: c7 44 24 0c 01 00 00 movl $0x1,0xc(%esp) +c0109013: 00 +c0109014: 89 44 24 08 mov %eax,0x8(%esp) +c0109018: 8b 45 10 mov 0x10(%ebp),%eax +c010901b: 89 44 24 04 mov %eax,0x4(%esp) +c010901f: 8b 45 08 mov 0x8(%ebp),%eax +c0109022: 89 04 24 mov %eax,(%esp) +c0109025: e8 a3 de ff ff call c0106ecd + page->pra_vaddr = addr;// 记录页面的虚拟地址 +c010902a: 8b 45 e0 mov -0x20(%ebp),%eax +c010902d: 8b 55 10 mov 0x10(%ebp),%edx +c0109030: 89 50 1c mov %edx,0x1c(%eax) +c0109033: eb 17 jmp c010904c + } + else { + cprintf("no swap_init_ok but ptep is %x, failed\n",*ptep); +c0109035: 8b 45 e4 mov -0x1c(%ebp),%eax +c0109038: 8b 00 mov (%eax),%eax +c010903a: 89 44 24 04 mov %eax,0x4(%esp) +c010903e: c7 04 24 5c df 10 c0 movl $0xc010df5c,(%esp) +c0109045: e8 2e 73 ff ff call c0100378 + goto failed;// 跳转到错误处理部分 +c010904a: eb 07 jmp c0109053 + } + } + ret = 0; +c010904c: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) +failed: + return ret; +c0109053: 8b 45 f4 mov -0xc(%ebp),%eax +} +c0109056: 89 ec mov %ebp,%esp +c0109058: 5d pop %ebp +c0109059: c3 ret + +c010905a : + +bool +user_mem_check(struct mm_struct *mm, uintptr_t addr, size_t len, bool write) { +c010905a: 55 push %ebp +c010905b: 89 e5 mov %esp,%ebp +c010905d: 83 ec 18 sub $0x18,%esp + if (mm != NULL) { +c0109060: 83 7d 08 00 cmpl $0x0,0x8(%ebp) +c0109064: 0f 84 e0 00 00 00 je c010914a + if (!USER_ACCESS(addr, addr + len)) { +c010906a: 81 7d 0c ff ff 1f 00 cmpl $0x1fffff,0xc(%ebp) +c0109071: 76 1c jbe c010908f +c0109073: 8b 55 0c mov 0xc(%ebp),%edx +c0109076: 8b 45 10 mov 0x10(%ebp),%eax +c0109079: 01 d0 add %edx,%eax +c010907b: 39 45 0c cmp %eax,0xc(%ebp) +c010907e: 73 0f jae c010908f +c0109080: 8b 55 0c mov 0xc(%ebp),%edx +c0109083: 8b 45 10 mov 0x10(%ebp),%eax +c0109086: 01 d0 add %edx,%eax +c0109088: 3d 00 00 00 b0 cmp $0xb0000000,%eax +c010908d: 76 0a jbe c0109099 + return 0; +c010908f: b8 00 00 00 00 mov $0x0,%eax +c0109094: e9 e2 00 00 00 jmp c010917b + } + struct vma_struct *vma; + uintptr_t start = addr, end = addr + len; +c0109099: 8b 45 0c mov 0xc(%ebp),%eax +c010909c: 89 45 fc mov %eax,-0x4(%ebp) +c010909f: 8b 55 0c mov 0xc(%ebp),%edx +c01090a2: 8b 45 10 mov 0x10(%ebp),%eax +c01090a5: 01 d0 add %edx,%eax +c01090a7: 89 45 f8 mov %eax,-0x8(%ebp) + while (start < end) { +c01090aa: e9 88 00 00 00 jmp c0109137 + if ((vma = find_vma(mm, start)) == NULL || start < vma->vm_start) { +c01090af: 8b 45 fc mov -0x4(%ebp),%eax +c01090b2: 89 44 24 04 mov %eax,0x4(%esp) +c01090b6: 8b 45 08 mov 0x8(%ebp),%eax +c01090b9: 89 04 24 mov %eax,(%esp) +c01090bc: e8 cd ef ff ff call c010808e +c01090c1: 89 45 f4 mov %eax,-0xc(%ebp) +c01090c4: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c01090c8: 74 0b je c01090d5 +c01090ca: 8b 45 f4 mov -0xc(%ebp),%eax +c01090cd: 8b 40 04 mov 0x4(%eax),%eax +c01090d0: 39 45 fc cmp %eax,-0x4(%ebp) +c01090d3: 73 0a jae c01090df + return 0; +c01090d5: b8 00 00 00 00 mov $0x0,%eax +c01090da: e9 9c 00 00 00 jmp c010917b + } + if (!(vma->vm_flags & ((write) ? VM_WRITE : VM_READ))) { +c01090df: 8b 45 f4 mov -0xc(%ebp),%eax +c01090e2: 8b 40 0c mov 0xc(%eax),%eax +c01090e5: 83 7d 14 00 cmpl $0x0,0x14(%ebp) +c01090e9: 74 07 je c01090f2 +c01090eb: ba 02 00 00 00 mov $0x2,%edx +c01090f0: eb 05 jmp c01090f7 +c01090f2: ba 01 00 00 00 mov $0x1,%edx +c01090f7: 21 d0 and %edx,%eax +c01090f9: 85 c0 test %eax,%eax +c01090fb: 75 07 jne c0109104 + return 0; +c01090fd: b8 00 00 00 00 mov $0x0,%eax +c0109102: eb 77 jmp c010917b + } + if (write && (vma->vm_flags & VM_STACK)) { +c0109104: 83 7d 14 00 cmpl $0x0,0x14(%ebp) +c0109108: 74 24 je c010912e +c010910a: 8b 45 f4 mov -0xc(%ebp),%eax +c010910d: 8b 40 0c mov 0xc(%eax),%eax +c0109110: 83 e0 08 and $0x8,%eax +c0109113: 85 c0 test %eax,%eax +c0109115: 74 17 je c010912e + if (start < vma->vm_start + PGSIZE) { //check stack start & size +c0109117: 8b 45 f4 mov -0xc(%ebp),%eax +c010911a: 8b 40 04 mov 0x4(%eax),%eax +c010911d: 05 00 10 00 00 add $0x1000,%eax +c0109122: 39 45 fc cmp %eax,-0x4(%ebp) +c0109125: 73 07 jae c010912e + return 0; +c0109127: b8 00 00 00 00 mov $0x0,%eax +c010912c: eb 4d jmp c010917b + } + } + start = vma->vm_end; +c010912e: 8b 45 f4 mov -0xc(%ebp),%eax +c0109131: 8b 40 08 mov 0x8(%eax),%eax +c0109134: 89 45 fc mov %eax,-0x4(%ebp) + while (start < end) { +c0109137: 8b 45 fc mov -0x4(%ebp),%eax +c010913a: 3b 45 f8 cmp -0x8(%ebp),%eax +c010913d: 0f 82 6c ff ff ff jb c01090af + } + return 1; +c0109143: b8 01 00 00 00 mov $0x1,%eax +c0109148: eb 31 jmp c010917b + } + return KERN_ACCESS(addr, addr + len); +c010914a: 81 7d 0c ff ff ff bf cmpl $0xbfffffff,0xc(%ebp) +c0109151: 76 23 jbe c0109176 +c0109153: 8b 55 0c mov 0xc(%ebp),%edx +c0109156: 8b 45 10 mov 0x10(%ebp),%eax +c0109159: 01 d0 add %edx,%eax +c010915b: 39 45 0c cmp %eax,0xc(%ebp) +c010915e: 73 16 jae c0109176 +c0109160: 8b 55 0c mov 0xc(%ebp),%edx +c0109163: 8b 45 10 mov 0x10(%ebp),%eax +c0109166: 01 d0 add %edx,%eax +c0109168: 3d 00 00 00 f8 cmp $0xf8000000,%eax +c010916d: 77 07 ja c0109176 +c010916f: b8 01 00 00 00 mov $0x1,%eax +c0109174: eb 05 jmp c010917b +c0109176: b8 00 00 00 00 mov $0x0,%eax +} +c010917b: 89 ec mov %ebp,%esp +c010917d: 5d pop %ebp +c010917e: c3 ret + +c010917f : +page2ppn(struct Page *page) { +c010917f: 55 push %ebp +c0109180: 89 e5 mov %esp,%ebp + return page - pages; +c0109182: 8b 15 a0 3f 1a c0 mov 0xc01a3fa0,%edx +c0109188: 8b 45 08 mov 0x8(%ebp),%eax +c010918b: 29 d0 sub %edx,%eax +c010918d: c1 f8 05 sar $0x5,%eax +} +c0109190: 5d pop %ebp +c0109191: c3 ret + +c0109192 : +page2pa(struct Page *page) { +c0109192: 55 push %ebp +c0109193: 89 e5 mov %esp,%ebp +c0109195: 83 ec 04 sub $0x4,%esp + return page2ppn(page) << PGSHIFT; +c0109198: 8b 45 08 mov 0x8(%ebp),%eax +c010919b: 89 04 24 mov %eax,(%esp) +c010919e: e8 dc ff ff ff call c010917f +c01091a3: c1 e0 0c shl $0xc,%eax +} +c01091a6: 89 ec mov %ebp,%esp +c01091a8: 5d pop %ebp +c01091a9: c3 ret + +c01091aa : +page2kva(struct Page *page) { +c01091aa: 55 push %ebp +c01091ab: 89 e5 mov %esp,%ebp +c01091ad: 83 ec 28 sub $0x28,%esp + return KADDR(page2pa(page)); +c01091b0: 8b 45 08 mov 0x8(%ebp),%eax +c01091b3: 89 04 24 mov %eax,(%esp) +c01091b6: e8 d7 ff ff ff call c0109192 +c01091bb: 89 45 f4 mov %eax,-0xc(%ebp) +c01091be: 8b 45 f4 mov -0xc(%ebp),%eax +c01091c1: c1 e8 0c shr $0xc,%eax +c01091c4: 89 45 f0 mov %eax,-0x10(%ebp) +c01091c7: a1 a4 3f 1a c0 mov 0xc01a3fa4,%eax +c01091cc: 39 45 f0 cmp %eax,-0x10(%ebp) +c01091cf: 72 23 jb c01091f4 +c01091d1: 8b 45 f4 mov -0xc(%ebp),%eax +c01091d4: 89 44 24 0c mov %eax,0xc(%esp) +c01091d8: c7 44 24 08 84 df 10 movl $0xc010df84,0x8(%esp) +c01091df: c0 +c01091e0: c7 44 24 04 65 00 00 movl $0x65,0x4(%esp) +c01091e7: 00 +c01091e8: c7 04 24 a7 df 10 c0 movl $0xc010dfa7,(%esp) +c01091ef: e8 47 7b ff ff call c0100d3b <__panic> +c01091f4: 8b 45 f4 mov -0xc(%ebp),%eax +c01091f7: 2d 00 00 00 40 sub $0x40000000,%eax +} +c01091fc: 89 ec mov %ebp,%esp +c01091fe: 5d pop %ebp +c01091ff: c3 ret + +c0109200 : +#include +#include +#include + +void +swapfs_init(void) { +c0109200: 55 push %ebp +c0109201: 89 e5 mov %esp,%ebp +c0109203: 83 ec 18 sub $0x18,%esp + static_assert((PGSIZE % SECTSIZE) == 0); + if (!ide_device_valid(SWAP_DEV_NO)) { +c0109206: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c010920d: e8 d8 88 ff ff call c0101aea +c0109212: 85 c0 test %eax,%eax +c0109214: 75 1c jne c0109232 + panic("swap fs isn't available.\n"); +c0109216: c7 44 24 08 b5 df 10 movl $0xc010dfb5,0x8(%esp) +c010921d: c0 +c010921e: c7 44 24 04 0d 00 00 movl $0xd,0x4(%esp) +c0109225: 00 +c0109226: c7 04 24 cf df 10 c0 movl $0xc010dfcf,(%esp) +c010922d: e8 09 7b ff ff call c0100d3b <__panic> + } + max_swap_offset = ide_device_size(SWAP_DEV_NO) / (PGSIZE / SECTSIZE); +c0109232: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c0109239: e8 ec 88 ff ff call c0101b2a +c010923e: c1 e8 03 shr $0x3,%eax +c0109241: a3 40 40 1a c0 mov %eax,0xc01a4040 +} +c0109246: 90 nop +c0109247: 89 ec mov %ebp,%esp +c0109249: 5d pop %ebp +c010924a: c3 ret + +c010924b : + +int +swapfs_read(swap_entry_t entry, struct Page *page) { +c010924b: 55 push %ebp +c010924c: 89 e5 mov %esp,%ebp +c010924e: 83 ec 28 sub $0x28,%esp + return ide_read_secs(SWAP_DEV_NO, swap_offset(entry) * PAGE_NSECT, page2kva(page), PAGE_NSECT); +c0109251: 8b 45 0c mov 0xc(%ebp),%eax +c0109254: 89 04 24 mov %eax,(%esp) +c0109257: e8 4e ff ff ff call c01091aa +c010925c: 8b 55 08 mov 0x8(%ebp),%edx +c010925f: c1 ea 08 shr $0x8,%edx +c0109262: 89 55 f4 mov %edx,-0xc(%ebp) +c0109265: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c0109269: 74 0b je c0109276 +c010926b: 8b 15 40 40 1a c0 mov 0xc01a4040,%edx +c0109271: 39 55 f4 cmp %edx,-0xc(%ebp) +c0109274: 72 23 jb c0109299 +c0109276: 8b 45 08 mov 0x8(%ebp),%eax +c0109279: 89 44 24 0c mov %eax,0xc(%esp) +c010927d: c7 44 24 08 e0 df 10 movl $0xc010dfe0,0x8(%esp) +c0109284: c0 +c0109285: c7 44 24 04 14 00 00 movl $0x14,0x4(%esp) +c010928c: 00 +c010928d: c7 04 24 cf df 10 c0 movl $0xc010dfcf,(%esp) +c0109294: e8 a2 7a ff ff call c0100d3b <__panic> +c0109299: 8b 55 f4 mov -0xc(%ebp),%edx +c010929c: c1 e2 03 shl $0x3,%edx +c010929f: c7 44 24 0c 08 00 00 movl $0x8,0xc(%esp) +c01092a6: 00 +c01092a7: 89 44 24 08 mov %eax,0x8(%esp) +c01092ab: 89 54 24 04 mov %edx,0x4(%esp) +c01092af: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c01092b6: e8 ac 88 ff ff call c0101b67 +} +c01092bb: 89 ec mov %ebp,%esp +c01092bd: 5d pop %ebp +c01092be: c3 ret + +c01092bf : + +int +swapfs_write(swap_entry_t entry, struct Page *page) { +c01092bf: 55 push %ebp +c01092c0: 89 e5 mov %esp,%ebp +c01092c2: 83 ec 28 sub $0x28,%esp + return ide_write_secs(SWAP_DEV_NO, swap_offset(entry) * PAGE_NSECT, page2kva(page), PAGE_NSECT); +c01092c5: 8b 45 0c mov 0xc(%ebp),%eax +c01092c8: 89 04 24 mov %eax,(%esp) +c01092cb: e8 da fe ff ff call c01091aa +c01092d0: 8b 55 08 mov 0x8(%ebp),%edx +c01092d3: c1 ea 08 shr $0x8,%edx +c01092d6: 89 55 f4 mov %edx,-0xc(%ebp) +c01092d9: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c01092dd: 74 0b je c01092ea +c01092df: 8b 15 40 40 1a c0 mov 0xc01a4040,%edx +c01092e5: 39 55 f4 cmp %edx,-0xc(%ebp) +c01092e8: 72 23 jb c010930d +c01092ea: 8b 45 08 mov 0x8(%ebp),%eax +c01092ed: 89 44 24 0c mov %eax,0xc(%esp) +c01092f1: c7 44 24 08 e0 df 10 movl $0xc010dfe0,0x8(%esp) +c01092f8: c0 +c01092f9: c7 44 24 04 19 00 00 movl $0x19,0x4(%esp) +c0109300: 00 +c0109301: c7 04 24 cf df 10 c0 movl $0xc010dfcf,(%esp) +c0109308: e8 2e 7a ff ff call c0100d3b <__panic> +c010930d: 8b 55 f4 mov -0xc(%ebp),%edx +c0109310: c1 e2 03 shl $0x3,%edx +c0109313: c7 44 24 0c 08 00 00 movl $0x8,0xc(%esp) +c010931a: 00 +c010931b: 89 44 24 08 mov %eax,0x8(%esp) +c010931f: 89 54 24 04 mov %edx,0x4(%esp) +c0109323: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c010932a: e8 79 8a ff ff call c0101da8 +} +c010932f: 89 ec mov %ebp,%esp +c0109331: 5d pop %ebp +c0109332: c3 ret + +c0109333 : +.text +.globl kernel_thread_entry +kernel_thread_entry: # void kernel_thread(void) + + pushl %edx # push arg +c0109333: 52 push %edx + call *%ebx # call fn +c0109334: ff d3 call *%ebx + + pushl %eax # save the return value of fn(arg) +c0109336: 50 push %eax + call do_exit # call do_exit to terminate current thread +c0109337: e8 d4 0c 00 00 call c010a010 + +c010933c : + * test_and_set_bit - Atomically set a bit and return its old value + * @nr: the bit to set + * @addr: the address to count from + * */ +static inline bool +test_and_set_bit(int nr, volatile void *addr) { +c010933c: 55 push %ebp +c010933d: 89 e5 mov %esp,%ebp +c010933f: 83 ec 10 sub $0x10,%esp + int oldbit; + asm volatile ("btsl %2, %1; sbbl %0, %0" : "=r" (oldbit), "=m" (*(volatile long *)addr) : "Ir" (nr) : "memory"); +c0109342: 8b 55 0c mov 0xc(%ebp),%edx +c0109345: 8b 45 08 mov 0x8(%ebp),%eax +c0109348: 0f ab 02 bts %eax,(%edx) +c010934b: 19 c0 sbb %eax,%eax +c010934d: 89 45 fc mov %eax,-0x4(%ebp) + return oldbit != 0; +c0109350: 83 7d fc 00 cmpl $0x0,-0x4(%ebp) +c0109354: 0f 95 c0 setne %al +c0109357: 0f b6 c0 movzbl %al,%eax +} +c010935a: 89 ec mov %ebp,%esp +c010935c: 5d pop %ebp +c010935d: c3 ret + +c010935e : + * test_and_clear_bit - Atomically clear a bit and return its old value + * @nr: the bit to clear + * @addr: the address to count from + * */ +static inline bool +test_and_clear_bit(int nr, volatile void *addr) { +c010935e: 55 push %ebp +c010935f: 89 e5 mov %esp,%ebp +c0109361: 83 ec 10 sub $0x10,%esp + int oldbit; + asm volatile ("btrl %2, %1; sbbl %0, %0" : "=r" (oldbit), "=m" (*(volatile long *)addr) : "Ir" (nr) : "memory"); +c0109364: 8b 55 0c mov 0xc(%ebp),%edx +c0109367: 8b 45 08 mov 0x8(%ebp),%eax +c010936a: 0f b3 02 btr %eax,(%edx) +c010936d: 19 c0 sbb %eax,%eax +c010936f: 89 45 fc mov %eax,-0x4(%ebp) + return oldbit != 0; +c0109372: 83 7d fc 00 cmpl $0x0,-0x4(%ebp) +c0109376: 0f 95 c0 setne %al +c0109379: 0f b6 c0 movzbl %al,%eax +} +c010937c: 89 ec mov %ebp,%esp +c010937e: 5d pop %ebp +c010937f: c3 ret + +c0109380 <__intr_save>: +__intr_save(void) { +c0109380: 55 push %ebp +c0109381: 89 e5 mov %esp,%ebp +c0109383: 83 ec 18 sub $0x18,%esp + asm volatile ("pushfl; popl %0" : "=r" (eflags)); +c0109386: 9c pushf +c0109387: 58 pop %eax +c0109388: 89 45 f4 mov %eax,-0xc(%ebp) + return eflags; +c010938b: 8b 45 f4 mov -0xc(%ebp),%eax + if (read_eflags() & FL_IF) { +c010938e: 25 00 02 00 00 and $0x200,%eax +c0109393: 85 c0 test %eax,%eax +c0109395: 74 0c je c01093a3 <__intr_save+0x23> + intr_disable(); +c0109397: e8 55 8c ff ff call c0101ff1 + return 1; +c010939c: b8 01 00 00 00 mov $0x1,%eax +c01093a1: eb 05 jmp c01093a8 <__intr_save+0x28> + return 0; +c01093a3: b8 00 00 00 00 mov $0x0,%eax +} +c01093a8: 89 ec mov %ebp,%esp +c01093aa: 5d pop %ebp +c01093ab: c3 ret + +c01093ac <__intr_restore>: +__intr_restore(bool flag) { +c01093ac: 55 push %ebp +c01093ad: 89 e5 mov %esp,%ebp +c01093af: 83 ec 08 sub $0x8,%esp + if (flag) { +c01093b2: 83 7d 08 00 cmpl $0x0,0x8(%ebp) +c01093b6: 74 05 je c01093bd <__intr_restore+0x11> + intr_enable(); +c01093b8: e8 2c 8c ff ff call c0101fe9 +} +c01093bd: 90 nop +c01093be: 89 ec mov %ebp,%esp +c01093c0: 5d pop %ebp +c01093c1: c3 ret + +c01093c2 : + +static inline bool +try_lock(lock_t *lock) { +c01093c2: 55 push %ebp +c01093c3: 89 e5 mov %esp,%ebp +c01093c5: 83 ec 08 sub $0x8,%esp + return !test_and_set_bit(0, lock); +c01093c8: 8b 45 08 mov 0x8(%ebp),%eax +c01093cb: 89 44 24 04 mov %eax,0x4(%esp) +c01093cf: c7 04 24 00 00 00 00 movl $0x0,(%esp) +c01093d6: e8 61 ff ff ff call c010933c +c01093db: 85 c0 test %eax,%eax +c01093dd: 0f 94 c0 sete %al +c01093e0: 0f b6 c0 movzbl %al,%eax +} +c01093e3: 89 ec mov %ebp,%esp +c01093e5: 5d pop %ebp +c01093e6: c3 ret + +c01093e7 : + +static inline void +lock(lock_t *lock) { +c01093e7: 55 push %ebp +c01093e8: 89 e5 mov %esp,%ebp +c01093ea: 83 ec 18 sub $0x18,%esp + while (!try_lock(lock)) { +c01093ed: eb 05 jmp c01093f4 + schedule(); +c01093ef: e8 88 1c 00 00 call c010b07c + while (!try_lock(lock)) { +c01093f4: 8b 45 08 mov 0x8(%ebp),%eax +c01093f7: 89 04 24 mov %eax,(%esp) +c01093fa: e8 c3 ff ff ff call c01093c2 +c01093ff: 85 c0 test %eax,%eax +c0109401: 74 ec je c01093ef + } +} +c0109403: 90 nop +c0109404: 90 nop +c0109405: 89 ec mov %ebp,%esp +c0109407: 5d pop %ebp +c0109408: c3 ret + +c0109409 : + +static inline void +unlock(lock_t *lock) { +c0109409: 55 push %ebp +c010940a: 89 e5 mov %esp,%ebp +c010940c: 83 ec 18 sub $0x18,%esp + if (!test_and_clear_bit(0, lock)) { +c010940f: 8b 45 08 mov 0x8(%ebp),%eax +c0109412: 89 44 24 04 mov %eax,0x4(%esp) +c0109416: c7 04 24 00 00 00 00 movl $0x0,(%esp) +c010941d: e8 3c ff ff ff call c010935e +c0109422: 85 c0 test %eax,%eax +c0109424: 75 1c jne c0109442 + panic("Unlock failed.\n"); +c0109426: c7 44 24 08 00 e0 10 movl $0xc010e000,0x8(%esp) +c010942d: c0 +c010942e: c7 44 24 04 34 00 00 movl $0x34,0x4(%esp) +c0109435: 00 +c0109436: c7 04 24 10 e0 10 c0 movl $0xc010e010,(%esp) +c010943d: e8 f9 78 ff ff call c0100d3b <__panic> + } +} +c0109442: 90 nop +c0109443: 89 ec mov %ebp,%esp +c0109445: 5d pop %ebp +c0109446: c3 ret + +c0109447 : +page2ppn(struct Page *page) { +c0109447: 55 push %ebp +c0109448: 89 e5 mov %esp,%ebp + return page - pages; +c010944a: 8b 15 a0 3f 1a c0 mov 0xc01a3fa0,%edx +c0109450: 8b 45 08 mov 0x8(%ebp),%eax +c0109453: 29 d0 sub %edx,%eax +c0109455: c1 f8 05 sar $0x5,%eax +} +c0109458: 5d pop %ebp +c0109459: c3 ret + +c010945a : +page2pa(struct Page *page) { +c010945a: 55 push %ebp +c010945b: 89 e5 mov %esp,%ebp +c010945d: 83 ec 04 sub $0x4,%esp + return page2ppn(page) << PGSHIFT; +c0109460: 8b 45 08 mov 0x8(%ebp),%eax +c0109463: 89 04 24 mov %eax,(%esp) +c0109466: e8 dc ff ff ff call c0109447 +c010946b: c1 e0 0c shl $0xc,%eax +} +c010946e: 89 ec mov %ebp,%esp +c0109470: 5d pop %ebp +c0109471: c3 ret + +c0109472 : +pa2page(uintptr_t pa) { +c0109472: 55 push %ebp +c0109473: 89 e5 mov %esp,%ebp +c0109475: 83 ec 18 sub $0x18,%esp + if (PPN(pa) >= npage) { +c0109478: 8b 45 08 mov 0x8(%ebp),%eax +c010947b: c1 e8 0c shr $0xc,%eax +c010947e: 89 c2 mov %eax,%edx +c0109480: a1 a4 3f 1a c0 mov 0xc01a3fa4,%eax +c0109485: 39 c2 cmp %eax,%edx +c0109487: 72 1c jb c01094a5 + panic("pa2page called with invalid pa"); +c0109489: c7 44 24 08 24 e0 10 movl $0xc010e024,0x8(%esp) +c0109490: c0 +c0109491: c7 44 24 04 5e 00 00 movl $0x5e,0x4(%esp) +c0109498: 00 +c0109499: c7 04 24 43 e0 10 c0 movl $0xc010e043,(%esp) +c01094a0: e8 96 78 ff ff call c0100d3b <__panic> + return &pages[PPN(pa)]; +c01094a5: 8b 15 a0 3f 1a c0 mov 0xc01a3fa0,%edx +c01094ab: 8b 45 08 mov 0x8(%ebp),%eax +c01094ae: c1 e8 0c shr $0xc,%eax +c01094b1: c1 e0 05 shl $0x5,%eax +c01094b4: 01 d0 add %edx,%eax +} +c01094b6: 89 ec mov %ebp,%esp +c01094b8: 5d pop %ebp +c01094b9: c3 ret + +c01094ba : +page2kva(struct Page *page) { +c01094ba: 55 push %ebp +c01094bb: 89 e5 mov %esp,%ebp +c01094bd: 83 ec 28 sub $0x28,%esp + return KADDR(page2pa(page)); +c01094c0: 8b 45 08 mov 0x8(%ebp),%eax +c01094c3: 89 04 24 mov %eax,(%esp) +c01094c6: e8 8f ff ff ff call c010945a +c01094cb: 89 45 f4 mov %eax,-0xc(%ebp) +c01094ce: 8b 45 f4 mov -0xc(%ebp),%eax +c01094d1: c1 e8 0c shr $0xc,%eax +c01094d4: 89 45 f0 mov %eax,-0x10(%ebp) +c01094d7: a1 a4 3f 1a c0 mov 0xc01a3fa4,%eax +c01094dc: 39 45 f0 cmp %eax,-0x10(%ebp) +c01094df: 72 23 jb c0109504 +c01094e1: 8b 45 f4 mov -0xc(%ebp),%eax +c01094e4: 89 44 24 0c mov %eax,0xc(%esp) +c01094e8: c7 44 24 08 54 e0 10 movl $0xc010e054,0x8(%esp) +c01094ef: c0 +c01094f0: c7 44 24 04 65 00 00 movl $0x65,0x4(%esp) +c01094f7: 00 +c01094f8: c7 04 24 43 e0 10 c0 movl $0xc010e043,(%esp) +c01094ff: e8 37 78 ff ff call c0100d3b <__panic> +c0109504: 8b 45 f4 mov -0xc(%ebp),%eax +c0109507: 2d 00 00 00 40 sub $0x40000000,%eax +} +c010950c: 89 ec mov %ebp,%esp +c010950e: 5d pop %ebp +c010950f: c3 ret + +c0109510 : +kva2page(void *kva) { +c0109510: 55 push %ebp +c0109511: 89 e5 mov %esp,%ebp +c0109513: 83 ec 28 sub $0x28,%esp + return pa2page(PADDR(kva)); +c0109516: 8b 45 08 mov 0x8(%ebp),%eax +c0109519: 89 45 f4 mov %eax,-0xc(%ebp) +c010951c: 81 7d f4 ff ff ff bf cmpl $0xbfffffff,-0xc(%ebp) +c0109523: 77 23 ja c0109548 +c0109525: 8b 45 f4 mov -0xc(%ebp),%eax +c0109528: 89 44 24 0c mov %eax,0xc(%esp) +c010952c: c7 44 24 08 78 e0 10 movl $0xc010e078,0x8(%esp) +c0109533: c0 +c0109534: c7 44 24 04 6a 00 00 movl $0x6a,0x4(%esp) +c010953b: 00 +c010953c: c7 04 24 43 e0 10 c0 movl $0xc010e043,(%esp) +c0109543: e8 f3 77 ff ff call c0100d3b <__panic> +c0109548: 8b 45 f4 mov -0xc(%ebp),%eax +c010954b: 05 00 00 00 40 add $0x40000000,%eax +c0109550: 89 04 24 mov %eax,(%esp) +c0109553: e8 1a ff ff ff call c0109472 +} +c0109558: 89 ec mov %ebp,%esp +c010955a: 5d pop %ebp +c010955b: c3 ret + +c010955c : + +static inline int +mm_count_inc(struct mm_struct *mm) { +c010955c: 55 push %ebp +c010955d: 89 e5 mov %esp,%ebp + mm->mm_count += 1; +c010955f: 8b 45 08 mov 0x8(%ebp),%eax +c0109562: 8b 40 18 mov 0x18(%eax),%eax +c0109565: 8d 50 01 lea 0x1(%eax),%edx +c0109568: 8b 45 08 mov 0x8(%ebp),%eax +c010956b: 89 50 18 mov %edx,0x18(%eax) + return mm->mm_count; +c010956e: 8b 45 08 mov 0x8(%ebp),%eax +c0109571: 8b 40 18 mov 0x18(%eax),%eax +} +c0109574: 5d pop %ebp +c0109575: c3 ret + +c0109576 : + +static inline int +mm_count_dec(struct mm_struct *mm) { +c0109576: 55 push %ebp +c0109577: 89 e5 mov %esp,%ebp + mm->mm_count -= 1; +c0109579: 8b 45 08 mov 0x8(%ebp),%eax +c010957c: 8b 40 18 mov 0x18(%eax),%eax +c010957f: 8d 50 ff lea -0x1(%eax),%edx +c0109582: 8b 45 08 mov 0x8(%ebp),%eax +c0109585: 89 50 18 mov %edx,0x18(%eax) + return mm->mm_count; +c0109588: 8b 45 08 mov 0x8(%ebp),%eax +c010958b: 8b 40 18 mov 0x18(%eax),%eax +} +c010958e: 5d pop %ebp +c010958f: c3 ret + +c0109590 : + +static inline void +lock_mm(struct mm_struct *mm) { +c0109590: 55 push %ebp +c0109591: 89 e5 mov %esp,%ebp +c0109593: 83 ec 18 sub $0x18,%esp + if (mm != NULL) { +c0109596: 83 7d 08 00 cmpl $0x0,0x8(%ebp) +c010959a: 74 0e je c01095aa + lock(&(mm->mm_lock)); +c010959c: 8b 45 08 mov 0x8(%ebp),%eax +c010959f: 83 c0 1c add $0x1c,%eax +c01095a2: 89 04 24 mov %eax,(%esp) +c01095a5: e8 3d fe ff ff call c01093e7 + } +} +c01095aa: 90 nop +c01095ab: 89 ec mov %ebp,%esp +c01095ad: 5d pop %ebp +c01095ae: c3 ret + +c01095af : + +static inline void +unlock_mm(struct mm_struct *mm) { +c01095af: 55 push %ebp +c01095b0: 89 e5 mov %esp,%ebp +c01095b2: 83 ec 18 sub $0x18,%esp + if (mm != NULL) { +c01095b5: 83 7d 08 00 cmpl $0x0,0x8(%ebp) +c01095b9: 74 0e je c01095c9 + unlock(&(mm->mm_lock)); +c01095bb: 8b 45 08 mov 0x8(%ebp),%eax +c01095be: 83 c0 1c add $0x1c,%eax +c01095c1: 89 04 24 mov %eax,(%esp) +c01095c4: e8 40 fe ff ff call c0109409 + } +} +c01095c9: 90 nop +c01095ca: 89 ec mov %ebp,%esp +c01095cc: 5d pop %ebp +c01095cd: c3 ret + +c01095ce : +void forkrets(struct trapframe *tf); +void switch_to(struct context *from, struct context *to); + +// alloc_proc - alloc a proc_struct and init all fields of proc_struct +static struct proc_struct * +alloc_proc(void) { +c01095ce: 55 push %ebp +c01095cf: 89 e5 mov %esp,%ebp +c01095d1: 83 ec 28 sub $0x28,%esp + struct proc_struct *proc = kmalloc(sizeof(struct proc_struct)); +c01095d4: c7 04 24 7c 00 00 00 movl $0x7c,(%esp) +c01095db: e8 10 b7 ff ff call c0104cf0 +c01095e0: 89 45 f4 mov %eax,-0xc(%ebp) + if (proc != NULL) { +c01095e3: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c01095e7: 0f 84 cd 00 00 00 je c01096ba + /* + * below fields(add in LAB5) in proc_struct need to be initialized + * uint32_t wait_state; // waiting state + * struct proc_struct *cptr, *yptr, *optr; // relations between processes + */ + proc->state = PROC_UNINIT; // 初始状态为未初始化 +c01095ed: 8b 45 f4 mov -0xc(%ebp),%eax +c01095f0: c7 00 00 00 00 00 movl $0x0,(%eax) + proc->pid = -1; // 初始进程ID为-1 +c01095f6: 8b 45 f4 mov -0xc(%ebp),%eax +c01095f9: c7 40 04 ff ff ff ff movl $0xffffffff,0x4(%eax) + proc->runs = 0; // 初始运行次数为0 +c0109600: 8b 45 f4 mov -0xc(%ebp),%eax +c0109603: c7 40 08 00 00 00 00 movl $0x0,0x8(%eax) + proc->kstack = 0; // 初始内核栈指针为0 +c010960a: 8b 45 f4 mov -0xc(%ebp),%eax +c010960d: c7 40 0c 00 00 00 00 movl $0x0,0xc(%eax) + proc->need_resched = 0; // 初始不需要重新调度 +c0109614: 8b 45 f4 mov -0xc(%ebp),%eax +c0109617: c7 40 10 00 00 00 00 movl $0x0,0x10(%eax) + proc->parent = NULL; // 初始父进程指针为NULL +c010961e: 8b 45 f4 mov -0xc(%ebp),%eax +c0109621: c7 40 14 00 00 00 00 movl $0x0,0x14(%eax) + proc->mm = NULL; // 初始内存管理结构指针为NULL +c0109628: 8b 45 f4 mov -0xc(%ebp),%eax +c010962b: c7 40 18 00 00 00 00 movl $0x0,0x18(%eax) + memset(&proc->context, 0, sizeof(struct context)); // 初始化上下文切换信息 +c0109632: 8b 45 f4 mov -0xc(%ebp),%eax +c0109635: 83 c0 1c add $0x1c,%eax +c0109638: c7 44 24 08 20 00 00 movl $0x20,0x8(%esp) +c010963f: 00 +c0109640: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) +c0109647: 00 +c0109648: 89 04 24 mov %eax,(%esp) +c010964b: e8 a1 27 00 00 call c010bdf1 + proc->tf = NULL; // 初始中断陷阱帧指针为NULL +c0109650: 8b 45 f4 mov -0xc(%ebp),%eax +c0109653: c7 40 3c 00 00 00 00 movl $0x0,0x3c(%eax) + proc->cr3 = boot_cr3; // 初始CR3寄存器值为0 +c010965a: 8b 15 a8 3f 1a c0 mov 0xc01a3fa8,%edx +c0109660: 8b 45 f4 mov -0xc(%ebp),%eax +c0109663: 89 50 40 mov %edx,0x40(%eax) + proc->flags = 0; // 初始进程标志为0 +c0109666: 8b 45 f4 mov -0xc(%ebp),%eax +c0109669: c7 40 44 00 00 00 00 movl $0x0,0x44(%eax) + memset(proc->name, 0, PROC_NAME_LEN); // 初始进程名称为空字符串 +c0109670: 8b 45 f4 mov -0xc(%ebp),%eax +c0109673: 83 c0 48 add $0x48,%eax +c0109676: c7 44 24 08 0f 00 00 movl $0xf,0x8(%esp) +c010967d: 00 +c010967e: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) +c0109685: 00 +c0109686: 89 04 24 mov %eax,(%esp) +c0109689: e8 63 27 00 00 call c010bdf1 + proc->wait_state = 0; +c010968e: 8b 45 f4 mov -0xc(%ebp),%eax +c0109691: c7 40 6c 00 00 00 00 movl $0x0,0x6c(%eax) + proc->cptr = proc->optr = proc->yptr = NULL; +c0109698: 8b 45 f4 mov -0xc(%ebp),%eax +c010969b: c7 40 74 00 00 00 00 movl $0x0,0x74(%eax) +c01096a2: 8b 45 f4 mov -0xc(%ebp),%eax +c01096a5: 8b 50 74 mov 0x74(%eax),%edx +c01096a8: 8b 45 f4 mov -0xc(%ebp),%eax +c01096ab: 89 50 78 mov %edx,0x78(%eax) +c01096ae: 8b 45 f4 mov -0xc(%ebp),%eax +c01096b1: 8b 50 78 mov 0x78(%eax),%edx +c01096b4: 8b 45 f4 mov -0xc(%ebp),%eax +c01096b7: 89 50 70 mov %edx,0x70(%eax) + } + return proc; +c01096ba: 8b 45 f4 mov -0xc(%ebp),%eax +} +c01096bd: 89 ec mov %ebp,%esp +c01096bf: 5d pop %ebp +c01096c0: c3 ret + +c01096c1 : + * @return 返回指向进程名称的指针,这是在内存中直接修改后的结果 + * + * 注意:此函数直接操作传入的进程结构体,对名称字段进行先清空后赋值的操作 + */ +char * +set_proc_name(struct proc_struct *proc, const char *name) { +c01096c1: 55 push %ebp +c01096c2: 89 e5 mov %esp,%ebp +c01096c4: 83 ec 18 sub $0x18,%esp + + // 清空进程名称字段中的现有内容,以准备存储新的名称 + memset(proc->name, 0, sizeof(proc->name)); +c01096c7: 8b 45 08 mov 0x8(%ebp),%eax +c01096ca: 83 c0 48 add $0x48,%eax +c01096cd: c7 44 24 08 10 00 00 movl $0x10,0x8(%esp) +c01096d4: 00 +c01096d5: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) +c01096dc: 00 +c01096dd: 89 04 24 mov %eax,(%esp) +c01096e0: e8 0c 27 00 00 call c010bdf1 + // 将新的名称复制到进程名称字段中 + return memcpy(proc->name, name, PROC_NAME_LEN); +c01096e5: 8b 45 08 mov 0x8(%ebp),%eax +c01096e8: 8d 50 48 lea 0x48(%eax),%edx +c01096eb: c7 44 24 08 0f 00 00 movl $0xf,0x8(%esp) +c01096f2: 00 +c01096f3: 8b 45 0c mov 0xc(%ebp),%eax +c01096f6: 89 44 24 04 mov %eax,0x4(%esp) +c01096fa: 89 14 24 mov %edx,(%esp) +c01096fd: e8 d4 27 00 00 call c010bed6 +} +c0109702: 89 ec mov %ebp,%esp +c0109704: 5d pop %ebp +c0109705: c3 ret + +c0109706 : + +// get_proc_name - get the name of proc +char * +get_proc_name(struct proc_struct *proc) { +c0109706: 55 push %ebp +c0109707: 89 e5 mov %esp,%ebp +c0109709: 83 ec 18 sub $0x18,%esp + static char name[PROC_NAME_LEN + 1]; + memset(name, 0, sizeof(name)); +c010970c: c7 44 24 08 10 00 00 movl $0x10,0x8(%esp) +c0109713: 00 +c0109714: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) +c010971b: 00 +c010971c: c7 04 24 44 61 1a c0 movl $0xc01a6144,(%esp) +c0109723: e8 c9 26 00 00 call c010bdf1 + return memcpy(name, proc->name, PROC_NAME_LEN); +c0109728: 8b 45 08 mov 0x8(%ebp),%eax +c010972b: 83 c0 48 add $0x48,%eax +c010972e: c7 44 24 08 0f 00 00 movl $0xf,0x8(%esp) +c0109735: 00 +c0109736: 89 44 24 04 mov %eax,0x4(%esp) +c010973a: c7 04 24 44 61 1a c0 movl $0xc01a6144,(%esp) +c0109741: e8 90 27 00 00 call c010bed6 +} +c0109746: 89 ec mov %ebp,%esp +c0109748: 5d pop %ebp +c0109749: c3 ret + +c010974a : + +// set_links - set the relation links of process +static void +set_links(struct proc_struct *proc) { +c010974a: 55 push %ebp +c010974b: 89 e5 mov %esp,%ebp +c010974d: 83 ec 20 sub $0x20,%esp + list_add(&proc_list, &(proc->list_link)); +c0109750: 8b 45 08 mov 0x8(%ebp),%eax +c0109753: 83 c0 58 add $0x58,%eax +c0109756: c7 45 fc 20 41 1a c0 movl $0xc01a4120,-0x4(%ebp) +c010975d: 89 45 f8 mov %eax,-0x8(%ebp) +c0109760: 8b 45 fc mov -0x4(%ebp),%eax +c0109763: 89 45 f4 mov %eax,-0xc(%ebp) +c0109766: 8b 45 f8 mov -0x8(%ebp),%eax +c0109769: 89 45 f0 mov %eax,-0x10(%ebp) + __list_add(elm, listelm, listelm->next); +c010976c: 8b 45 f4 mov -0xc(%ebp),%eax +c010976f: 8b 40 04 mov 0x4(%eax),%eax +c0109772: 8b 55 f0 mov -0x10(%ebp),%edx +c0109775: 89 55 ec mov %edx,-0x14(%ebp) +c0109778: 8b 55 f4 mov -0xc(%ebp),%edx +c010977b: 89 55 e8 mov %edx,-0x18(%ebp) +c010977e: 89 45 e4 mov %eax,-0x1c(%ebp) + prev->next = next->prev = elm; +c0109781: 8b 45 e4 mov -0x1c(%ebp),%eax +c0109784: 8b 55 ec mov -0x14(%ebp),%edx +c0109787: 89 10 mov %edx,(%eax) +c0109789: 8b 45 e4 mov -0x1c(%ebp),%eax +c010978c: 8b 10 mov (%eax),%edx +c010978e: 8b 45 e8 mov -0x18(%ebp),%eax +c0109791: 89 50 04 mov %edx,0x4(%eax) + elm->next = next; +c0109794: 8b 45 ec mov -0x14(%ebp),%eax +c0109797: 8b 55 e4 mov -0x1c(%ebp),%edx +c010979a: 89 50 04 mov %edx,0x4(%eax) + elm->prev = prev; +c010979d: 8b 45 ec mov -0x14(%ebp),%eax +c01097a0: 8b 55 e8 mov -0x18(%ebp),%edx +c01097a3: 89 10 mov %edx,(%eax) +} +c01097a5: 90 nop +} +c01097a6: 90 nop +} +c01097a7: 90 nop + proc->yptr = NULL; +c01097a8: 8b 45 08 mov 0x8(%ebp),%eax +c01097ab: c7 40 74 00 00 00 00 movl $0x0,0x74(%eax) + if ((proc->optr = proc->parent->cptr) != NULL) { +c01097b2: 8b 45 08 mov 0x8(%ebp),%eax +c01097b5: 8b 40 14 mov 0x14(%eax),%eax +c01097b8: 8b 50 70 mov 0x70(%eax),%edx +c01097bb: 8b 45 08 mov 0x8(%ebp),%eax +c01097be: 89 50 78 mov %edx,0x78(%eax) +c01097c1: 8b 45 08 mov 0x8(%ebp),%eax +c01097c4: 8b 40 78 mov 0x78(%eax),%eax +c01097c7: 85 c0 test %eax,%eax +c01097c9: 74 0c je c01097d7 + proc->optr->yptr = proc; +c01097cb: 8b 45 08 mov 0x8(%ebp),%eax +c01097ce: 8b 40 78 mov 0x78(%eax),%eax +c01097d1: 8b 55 08 mov 0x8(%ebp),%edx +c01097d4: 89 50 74 mov %edx,0x74(%eax) + } + proc->parent->cptr = proc; +c01097d7: 8b 45 08 mov 0x8(%ebp),%eax +c01097da: 8b 40 14 mov 0x14(%eax),%eax +c01097dd: 8b 55 08 mov 0x8(%ebp),%edx +c01097e0: 89 50 70 mov %edx,0x70(%eax) + nr_process ++; +c01097e3: a1 40 61 1a c0 mov 0xc01a6140,%eax +c01097e8: 40 inc %eax +c01097e9: a3 40 61 1a c0 mov %eax,0xc01a6140 +} +c01097ee: 90 nop +c01097ef: 89 ec mov %ebp,%esp +c01097f1: 5d pop %ebp +c01097f2: c3 ret + +c01097f3 : + +// remove_links - clean the relation links of process +static void +remove_links(struct proc_struct *proc) { +c01097f3: 55 push %ebp +c01097f4: 89 e5 mov %esp,%ebp +c01097f6: 83 ec 10 sub $0x10,%esp + list_del(&(proc->list_link)); +c01097f9: 8b 45 08 mov 0x8(%ebp),%eax +c01097fc: 83 c0 58 add $0x58,%eax +c01097ff: 89 45 fc mov %eax,-0x4(%ebp) + __list_del(listelm->prev, listelm->next); +c0109802: 8b 45 fc mov -0x4(%ebp),%eax +c0109805: 8b 40 04 mov 0x4(%eax),%eax +c0109808: 8b 55 fc mov -0x4(%ebp),%edx +c010980b: 8b 12 mov (%edx),%edx +c010980d: 89 55 f8 mov %edx,-0x8(%ebp) +c0109810: 89 45 f4 mov %eax,-0xc(%ebp) + prev->next = next; +c0109813: 8b 45 f8 mov -0x8(%ebp),%eax +c0109816: 8b 55 f4 mov -0xc(%ebp),%edx +c0109819: 89 50 04 mov %edx,0x4(%eax) + next->prev = prev; +c010981c: 8b 45 f4 mov -0xc(%ebp),%eax +c010981f: 8b 55 f8 mov -0x8(%ebp),%edx +c0109822: 89 10 mov %edx,(%eax) +} +c0109824: 90 nop +} +c0109825: 90 nop + if (proc->optr != NULL) { +c0109826: 8b 45 08 mov 0x8(%ebp),%eax +c0109829: 8b 40 78 mov 0x78(%eax),%eax +c010982c: 85 c0 test %eax,%eax +c010982e: 74 0f je c010983f + proc->optr->yptr = proc->yptr; +c0109830: 8b 45 08 mov 0x8(%ebp),%eax +c0109833: 8b 40 78 mov 0x78(%eax),%eax +c0109836: 8b 55 08 mov 0x8(%ebp),%edx +c0109839: 8b 52 74 mov 0x74(%edx),%edx +c010983c: 89 50 74 mov %edx,0x74(%eax) + } + if (proc->yptr != NULL) { +c010983f: 8b 45 08 mov 0x8(%ebp),%eax +c0109842: 8b 40 74 mov 0x74(%eax),%eax +c0109845: 85 c0 test %eax,%eax +c0109847: 74 11 je c010985a + proc->yptr->optr = proc->optr; +c0109849: 8b 45 08 mov 0x8(%ebp),%eax +c010984c: 8b 40 74 mov 0x74(%eax),%eax +c010984f: 8b 55 08 mov 0x8(%ebp),%edx +c0109852: 8b 52 78 mov 0x78(%edx),%edx +c0109855: 89 50 78 mov %edx,0x78(%eax) +c0109858: eb 0f jmp c0109869 + } + else { + proc->parent->cptr = proc->optr; +c010985a: 8b 45 08 mov 0x8(%ebp),%eax +c010985d: 8b 40 14 mov 0x14(%eax),%eax +c0109860: 8b 55 08 mov 0x8(%ebp),%edx +c0109863: 8b 52 78 mov 0x78(%edx),%edx +c0109866: 89 50 70 mov %edx,0x70(%eax) + } + nr_process --; +c0109869: a1 40 61 1a c0 mov 0xc01a6140,%eax +c010986e: 48 dec %eax +c010986f: a3 40 61 1a c0 mov %eax,0xc01a6140 +} +c0109874: 90 nop +c0109875: 89 ec mov %ebp,%esp +c0109877: 5d pop %ebp +c0109878: c3 ret + +c0109879 : + * 它使用静态变量来跟踪最后一个分配的PID和下一个安全PID,以提高效率并避免PID冲突。 + * + * @return 返回一个未被使用的进程ID。 + */ +static int +get_pid(void) { +c0109879: 55 push %ebp +c010987a: 89 e5 mov %esp,%ebp +c010987c: 83 ec 10 sub $0x10,%esp + static_assert(MAX_PID > MAX_PROCESS); + + // 定义一个指向进程结构的指针,用于遍历进程列表。 + struct proc_struct *proc; + // 初始化列表指针,从进程列表的头部开始。 + list_entry_t *list = &proc_list, *le; +c010987f: c7 45 f8 20 41 1a c0 movl $0xc01a4120,-0x8(%ebp) + // 定义静态变量,next_safe用于记录下一个安全的PID值,last_pid用于记录上一个分配的PID。 + static int next_safe = MAX_PID, last_pid = MAX_PID; + + // 尝试递增last_pid以查找下一个可用的PID,如果超过最大值则重置为1。 + if (++ last_pid >= MAX_PID) { +c0109886: a1 80 fa 12 c0 mov 0xc012fa80,%eax +c010988b: 40 inc %eax +c010988c: a3 80 fa 12 c0 mov %eax,0xc012fa80 +c0109891: a1 80 fa 12 c0 mov 0xc012fa80,%eax +c0109896: 3d ff 1f 00 00 cmp $0x1fff,%eax +c010989b: 7e 0c jle c01098a9 + last_pid = 1; +c010989d: c7 05 80 fa 12 c0 01 movl $0x1,0xc012fa80 +c01098a4: 00 00 00 + goto inside; +c01098a7: eb 14 jmp c01098bd + } + + // 如果当前的last_pid大于等于next_safe,表示需要重新计算下一个安全的PID。 + if (last_pid >= next_safe) { +c01098a9: 8b 15 80 fa 12 c0 mov 0xc012fa80,%edx +c01098af: a1 84 fa 12 c0 mov 0xc012fa84,%eax +c01098b4: 39 c2 cmp %eax,%edx +c01098b6: 0f 8c ab 00 00 00 jl c0109967 + inside: +c01098bc: 90 nop + next_safe = MAX_PID; +c01098bd: c7 05 84 fa 12 c0 00 movl $0x2000,0xc012fa84 +c01098c4: 20 00 00 + repeat: + // 从进程列表的头部开始遍历。 + le = list; +c01098c7: 8b 45 f8 mov -0x8(%ebp),%eax +c01098ca: 89 45 fc mov %eax,-0x4(%ebp) + while ((le = list_next(le)) != list) { +c01098cd: eb 7d jmp c010994c + + // 将列表项转换为进程结构。 + proc = le2proc(le, list_link); +c01098cf: 8b 45 fc mov -0x4(%ebp),%eax +c01098d2: 83 e8 58 sub $0x58,%eax +c01098d5: 89 45 f4 mov %eax,-0xc(%ebp) + + // 如果找到相同PID的进程,表示当前last_pid已被使用,需要继续寻找下一个可用的PID。 + if (proc->pid == last_pid) { +c01098d8: 8b 45 f4 mov -0xc(%ebp),%eax +c01098db: 8b 50 04 mov 0x4(%eax),%edx +c01098de: a1 80 fa 12 c0 mov 0xc012fa80,%eax +c01098e3: 39 c2 cmp %eax,%edx +c01098e5: 75 3c jne c0109923 + if (++ last_pid >= next_safe) { +c01098e7: a1 80 fa 12 c0 mov 0xc012fa80,%eax +c01098ec: 40 inc %eax +c01098ed: a3 80 fa 12 c0 mov %eax,0xc012fa80 +c01098f2: 8b 15 80 fa 12 c0 mov 0xc012fa80,%edx +c01098f8: a1 84 fa 12 c0 mov 0xc012fa84,%eax +c01098fd: 39 c2 cmp %eax,%edx +c01098ff: 7c 4b jl c010994c + if (last_pid >= MAX_PID) { +c0109901: a1 80 fa 12 c0 mov 0xc012fa80,%eax +c0109906: 3d ff 1f 00 00 cmp $0x1fff,%eax +c010990b: 7e 0a jle c0109917 + last_pid = 1; +c010990d: c7 05 80 fa 12 c0 01 movl $0x1,0xc012fa80 +c0109914: 00 00 00 + } + next_safe = MAX_PID; +c0109917: c7 05 84 fa 12 c0 00 movl $0x2000,0xc012fa84 +c010991e: 20 00 00 + goto repeat; +c0109921: eb a4 jmp c01098c7 + } + } + + // 如果找到一个更大的PID,更新next_safe为当前进程的PID,以确保找到的PID是安全的。 + else if (proc->pid > last_pid && next_safe > proc->pid) { +c0109923: 8b 45 f4 mov -0xc(%ebp),%eax +c0109926: 8b 50 04 mov 0x4(%eax),%edx +c0109929: a1 80 fa 12 c0 mov 0xc012fa80,%eax +c010992e: 39 c2 cmp %eax,%edx +c0109930: 7e 1a jle c010994c +c0109932: 8b 45 f4 mov -0xc(%ebp),%eax +c0109935: 8b 50 04 mov 0x4(%eax),%edx +c0109938: a1 84 fa 12 c0 mov 0xc012fa84,%eax +c010993d: 39 c2 cmp %eax,%edx +c010993f: 7d 0b jge c010994c + next_safe = proc->pid; +c0109941: 8b 45 f4 mov -0xc(%ebp),%eax +c0109944: 8b 40 04 mov 0x4(%eax),%eax +c0109947: a3 84 fa 12 c0 mov %eax,0xc012fa84 +c010994c: 8b 45 fc mov -0x4(%ebp),%eax +c010994f: 89 45 f0 mov %eax,-0x10(%ebp) + return listelm->next; +c0109952: 8b 45 f0 mov -0x10(%ebp),%eax +c0109955: 8b 40 04 mov 0x4(%eax),%eax + while ((le = list_next(le)) != list) { +c0109958: 89 45 fc mov %eax,-0x4(%ebp) +c010995b: 8b 45 fc mov -0x4(%ebp),%eax +c010995e: 3b 45 f8 cmp -0x8(%ebp),%eax +c0109961: 0f 85 68 ff ff ff jne c01098cf + } + } + } + // 返回找到的可用PID。 + return last_pid; +c0109967: a1 80 fa 12 c0 mov 0xc012fa80,%eax +} +c010996c: 89 ec mov %ebp,%esp +c010996e: 5d pop %ebp +c010996f: c3 ret + +c0109970 : + +// proc_run - make process "proc" running on cpu +// NOTE: before call switch_to, should load base addr of "proc"'s new PDT +//切换当前运行的进程 +void +proc_run(struct proc_struct *proc) { +c0109970: 55 push %ebp +c0109971: 89 e5 mov %esp,%ebp +c0109973: 83 ec 28 sub $0x28,%esp + if (proc != current) { +c0109976: a1 30 41 1a c0 mov 0xc01a4130,%eax +c010997b: 39 45 08 cmp %eax,0x8(%ebp) +c010997e: 74 64 je c01099e4 + bool intr_flag; + struct proc_struct *prev = current, *next = proc; +c0109980: a1 30 41 1a c0 mov 0xc01a4130,%eax +c0109985: 89 45 f4 mov %eax,-0xc(%ebp) +c0109988: 8b 45 08 mov 0x8(%ebp),%eax +c010998b: 89 45 f0 mov %eax,-0x10(%ebp) + local_intr_save(intr_flag); +c010998e: e8 ed f9 ff ff call c0109380 <__intr_save> +c0109993: 89 45 ec mov %eax,-0x14(%ebp) + { + current = proc; +c0109996: 8b 45 08 mov 0x8(%ebp),%eax +c0109999: a3 30 41 1a c0 mov %eax,0xc01a4130 + load_esp0(next->kstack + KSTACKSIZE); +c010999e: 8b 45 f0 mov -0x10(%ebp),%eax +c01099a1: 8b 40 0c mov 0xc(%eax),%eax +c01099a4: 05 00 20 00 00 add $0x2000,%eax +c01099a9: 89 04 24 mov %eax,(%esp) +c01099ac: e8 7e b6 ff ff call c010502f + lcr3(next->cr3); +c01099b1: 8b 45 f0 mov -0x10(%ebp),%eax +c01099b4: 8b 40 40 mov 0x40(%eax),%eax +c01099b7: 89 45 e8 mov %eax,-0x18(%ebp) + asm volatile ("mov %0, %%cr3" :: "r" (cr3) : "memory"); +c01099ba: 8b 45 e8 mov -0x18(%ebp),%eax +c01099bd: 0f 22 d8 mov %eax,%cr3 +} +c01099c0: 90 nop + switch_to(&(prev->context), &(next->context)); +c01099c1: 8b 45 f0 mov -0x10(%ebp),%eax +c01099c4: 8d 50 1c lea 0x1c(%eax),%edx +c01099c7: 8b 45 f4 mov -0xc(%ebp),%eax +c01099ca: 83 c0 1c add $0x1c,%eax +c01099cd: 89 54 24 04 mov %edx,0x4(%esp) +c01099d1: 89 04 24 mov %eax,(%esp) +c01099d4: e8 a3 15 00 00 call c010af7c + } + local_intr_restore(intr_flag); +c01099d9: 8b 45 ec mov -0x14(%ebp),%eax +c01099dc: 89 04 24 mov %eax,(%esp) +c01099df: e8 c8 f9 ff ff call c01093ac <__intr_restore> + } +} +c01099e4: 90 nop +c01099e5: 89 ec mov %ebp,%esp +c01099e7: 5d pop %ebp +c01099e8: c3 ret + +c01099e9 : +// forkret -- the first kernel entry point of a new thread/process +// NOTE: the addr of forkret is setted in copy_thread function +// after switch_to, the current proc will execute here. +// 函数在调用时会传递当前进程的线程上下文(通过 current->tf 获取)给 forkrets 函数。 +static void +forkret(void) { +c01099e9: 55 push %ebp +c01099ea: 89 e5 mov %esp,%ebp +c01099ec: 83 ec 18 sub $0x18,%esp + forkrets(current->tf); +c01099ef: a1 30 41 1a c0 mov 0xc01a4130,%eax +c01099f4: 8b 40 3c mov 0x3c(%eax),%eax +c01099f7: 89 04 24 mov %eax,(%esp) +c01099fa: e8 67 90 ff ff call c0102a66 +} +c01099ff: 90 nop +c0109a00: 89 ec mov %ebp,%esp +c0109a02: 5d pop %ebp +c0109a03: c3 ret + +c0109a04 : + * 这有助于在需要时快速查找进程 + * + * @param proc 指向进程结构体的指针,表示要添加到哈希表的进程 + */ +static void +hash_proc(struct proc_struct *proc) { +c0109a04: 55 push %ebp +c0109a05: 89 e5 mov %esp,%ebp +c0109a07: 83 ec 38 sub $0x38,%esp +c0109a0a: 89 5d fc mov %ebx,-0x4(%ebp) + // 根据进程的PID计算哈希值,并将进程添加到相应哈希链表的末尾 + list_add(hash_list + pid_hashfn(proc->pid), &(proc->hash_link)); +c0109a0d: 8b 45 08 mov 0x8(%ebp),%eax +c0109a10: 8d 58 60 lea 0x60(%eax),%ebx +c0109a13: 8b 45 08 mov 0x8(%ebp),%eax +c0109a16: 8b 40 04 mov 0x4(%eax),%eax +c0109a19: c7 44 24 04 0a 00 00 movl $0xa,0x4(%esp) +c0109a20: 00 +c0109a21: 89 04 24 mov %eax,(%esp) +c0109a24: e8 2b 19 00 00 call c010b354 +c0109a29: c1 e0 03 shl $0x3,%eax +c0109a2c: 05 40 41 1a c0 add $0xc01a4140,%eax +c0109a31: 89 45 f4 mov %eax,-0xc(%ebp) +c0109a34: 89 5d f0 mov %ebx,-0x10(%ebp) +c0109a37: 8b 45 f4 mov -0xc(%ebp),%eax +c0109a3a: 89 45 ec mov %eax,-0x14(%ebp) +c0109a3d: 8b 45 f0 mov -0x10(%ebp),%eax +c0109a40: 89 45 e8 mov %eax,-0x18(%ebp) + __list_add(elm, listelm, listelm->next); +c0109a43: 8b 45 ec mov -0x14(%ebp),%eax +c0109a46: 8b 40 04 mov 0x4(%eax),%eax +c0109a49: 8b 55 e8 mov -0x18(%ebp),%edx +c0109a4c: 89 55 e4 mov %edx,-0x1c(%ebp) +c0109a4f: 8b 55 ec mov -0x14(%ebp),%edx +c0109a52: 89 55 e0 mov %edx,-0x20(%ebp) +c0109a55: 89 45 dc mov %eax,-0x24(%ebp) + prev->next = next->prev = elm; +c0109a58: 8b 45 dc mov -0x24(%ebp),%eax +c0109a5b: 8b 55 e4 mov -0x1c(%ebp),%edx +c0109a5e: 89 10 mov %edx,(%eax) +c0109a60: 8b 45 dc mov -0x24(%ebp),%eax +c0109a63: 8b 10 mov (%eax),%edx +c0109a65: 8b 45 e0 mov -0x20(%ebp),%eax +c0109a68: 89 50 04 mov %edx,0x4(%eax) + elm->next = next; +c0109a6b: 8b 45 e4 mov -0x1c(%ebp),%eax +c0109a6e: 8b 55 dc mov -0x24(%ebp),%edx +c0109a71: 89 50 04 mov %edx,0x4(%eax) + elm->prev = prev; +c0109a74: 8b 45 e4 mov -0x1c(%ebp),%eax +c0109a77: 8b 55 e0 mov -0x20(%ebp),%edx +c0109a7a: 89 10 mov %edx,(%eax) +} +c0109a7c: 90 nop +} +c0109a7d: 90 nop +} +c0109a7e: 90 nop +} +c0109a7f: 90 nop +c0109a80: 8b 5d fc mov -0x4(%ebp),%ebx +c0109a83: 89 ec mov %ebp,%esp +c0109a85: 5d pop %ebp +c0109a86: c3 ret + +c0109a87 : + +// unhash_proc - delete proc from proc hash_list +static void +unhash_proc(struct proc_struct *proc) { +c0109a87: 55 push %ebp +c0109a88: 89 e5 mov %esp,%ebp +c0109a8a: 83 ec 10 sub $0x10,%esp + list_del(&(proc->hash_link)); +c0109a8d: 8b 45 08 mov 0x8(%ebp),%eax +c0109a90: 83 c0 60 add $0x60,%eax +c0109a93: 89 45 fc mov %eax,-0x4(%ebp) + __list_del(listelm->prev, listelm->next); +c0109a96: 8b 45 fc mov -0x4(%ebp),%eax +c0109a99: 8b 40 04 mov 0x4(%eax),%eax +c0109a9c: 8b 55 fc mov -0x4(%ebp),%edx +c0109a9f: 8b 12 mov (%edx),%edx +c0109aa1: 89 55 f8 mov %edx,-0x8(%ebp) +c0109aa4: 89 45 f4 mov %eax,-0xc(%ebp) + prev->next = next; +c0109aa7: 8b 45 f8 mov -0x8(%ebp),%eax +c0109aaa: 8b 55 f4 mov -0xc(%ebp),%edx +c0109aad: 89 50 04 mov %edx,0x4(%eax) + next->prev = prev; +c0109ab0: 8b 45 f4 mov -0xc(%ebp),%eax +c0109ab3: 8b 55 f8 mov -0x8(%ebp),%edx +c0109ab6: 89 10 mov %edx,(%eax) +} +c0109ab8: 90 nop +} +c0109ab9: 90 nop +} +c0109aba: 90 nop +c0109abb: 89 ec mov %ebp,%esp +c0109abd: 5d pop %ebp +c0109abe: c3 ret + +c0109abf : + +// find_proc - find proc frome proc hash_list according to pid +struct proc_struct * +find_proc(int pid) { +c0109abf: 55 push %ebp +c0109ac0: 89 e5 mov %esp,%ebp +c0109ac2: 83 ec 28 sub $0x28,%esp + if (0 < pid && pid < MAX_PID) { +c0109ac5: 83 7d 08 00 cmpl $0x0,0x8(%ebp) +c0109ac9: 7e 5f jle c0109b2a +c0109acb: 81 7d 08 ff 1f 00 00 cmpl $0x1fff,0x8(%ebp) +c0109ad2: 7f 56 jg c0109b2a + list_entry_t *list = hash_list + pid_hashfn(pid), *le = list; +c0109ad4: 8b 45 08 mov 0x8(%ebp),%eax +c0109ad7: c7 44 24 04 0a 00 00 movl $0xa,0x4(%esp) +c0109ade: 00 +c0109adf: 89 04 24 mov %eax,(%esp) +c0109ae2: e8 6d 18 00 00 call c010b354 +c0109ae7: c1 e0 03 shl $0x3,%eax +c0109aea: 05 40 41 1a c0 add $0xc01a4140,%eax +c0109aef: 89 45 f0 mov %eax,-0x10(%ebp) +c0109af2: 8b 45 f0 mov -0x10(%ebp),%eax +c0109af5: 89 45 f4 mov %eax,-0xc(%ebp) + while ((le = list_next(le)) != list) { +c0109af8: eb 19 jmp c0109b13 + struct proc_struct *proc = le2proc(le, hash_link); +c0109afa: 8b 45 f4 mov -0xc(%ebp),%eax +c0109afd: 83 e8 60 sub $0x60,%eax +c0109b00: 89 45 ec mov %eax,-0x14(%ebp) + if (proc->pid == pid) { +c0109b03: 8b 45 ec mov -0x14(%ebp),%eax +c0109b06: 8b 40 04 mov 0x4(%eax),%eax +c0109b09: 39 45 08 cmp %eax,0x8(%ebp) +c0109b0c: 75 05 jne c0109b13 + return proc; +c0109b0e: 8b 45 ec mov -0x14(%ebp),%eax +c0109b11: eb 1c jmp c0109b2f +c0109b13: 8b 45 f4 mov -0xc(%ebp),%eax +c0109b16: 89 45 e8 mov %eax,-0x18(%ebp) + return listelm->next; +c0109b19: 8b 45 e8 mov -0x18(%ebp),%eax +c0109b1c: 8b 40 04 mov 0x4(%eax),%eax + while ((le = list_next(le)) != list) { +c0109b1f: 89 45 f4 mov %eax,-0xc(%ebp) +c0109b22: 8b 45 f4 mov -0xc(%ebp),%eax +c0109b25: 3b 45 f0 cmp -0x10(%ebp),%eax +c0109b28: 75 d0 jne c0109afa + } + } + } + return NULL; +c0109b2a: b8 00 00 00 00 mov $0x0,%eax +} +c0109b2f: 89 ec mov %ebp,%esp +c0109b31: 5d pop %ebp +c0109b32: c3 ret + +c0109b33 : + * + * 该函数通过设置trapframe来创建一个内核线程,并安排其执行指定的函数fn + * 使用do_fork函数来进行实际的线程创建操作,创建的线程将共享父线程的虚拟内存 + */ +int +kernel_thread(int (*fn)(void *), void *arg, uint32_t clone_flags) { +c0109b33: 55 push %ebp +c0109b34: 89 e5 mov %esp,%ebp +c0109b36: 83 ec 68 sub $0x68,%esp + // 初始化trapframe结构体,用于描述线程的初始状态 + struct trapframe tf; + memset(&tf, 0, sizeof(struct trapframe)); +c0109b39: c7 44 24 08 4c 00 00 movl $0x4c,0x8(%esp) +c0109b40: 00 +c0109b41: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) +c0109b48: 00 +c0109b49: 8d 45 ac lea -0x54(%ebp),%eax +c0109b4c: 89 04 24 mov %eax,(%esp) +c0109b4f: e8 9d 22 00 00 call c010bdf1 + + // 设置代码段和数据段寄存器的值,使线程运行在内核态 + tf.tf_cs = KERNEL_CS; +c0109b54: 66 c7 45 e8 08 00 movw $0x8,-0x18(%ebp) + tf.tf_ds = tf.tf_es = tf.tf_ss = KERNEL_DS; +c0109b5a: 66 c7 45 f4 10 00 movw $0x10,-0xc(%ebp) +c0109b60: 0f b7 45 f4 movzwl -0xc(%ebp),%eax +c0109b64: 66 89 45 d4 mov %ax,-0x2c(%ebp) +c0109b68: 0f b7 45 d4 movzwl -0x2c(%ebp),%eax +c0109b6c: 66 89 45 d8 mov %ax,-0x28(%ebp) + + // 将要执行的函数fn的地址和参数arg的地址分别放入ebx和edx寄存器 + tf.tf_regs.reg_ebx = (uint32_t)fn; +c0109b70: 8b 45 08 mov 0x8(%ebp),%eax +c0109b73: 89 45 bc mov %eax,-0x44(%ebp) + tf.tf_regs.reg_edx = (uint32_t)arg; +c0109b76: 8b 45 0c mov 0xc(%ebp),%eax +c0109b79: 89 45 c0 mov %eax,-0x40(%ebp) + + // 设置指令指针寄存器eip,使其指向内核线程入口函数kernel_thread_entry + tf.tf_eip = (uint32_t)kernel_thread_entry; +c0109b7c: b8 33 93 10 c0 mov $0xc0109333,%eax +c0109b81: 89 45 e4 mov %eax,-0x1c(%ebp) + + // 调用do_fork函数创建新线程,新线程将共享父线程的虚拟内存 + // 并将新线程的初始状态设置为之前准备的trapframe + return do_fork(clone_flags | CLONE_VM, 0, &tf); +c0109b84: 8b 45 10 mov 0x10(%ebp),%eax +c0109b87: 0d 00 01 00 00 or $0x100,%eax +c0109b8c: 89 c2 mov %eax,%edx +c0109b8e: 8d 45 ac lea -0x54(%ebp),%eax +c0109b91: 89 44 24 08 mov %eax,0x8(%esp) +c0109b95: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) +c0109b9c: 00 +c0109b9d: 89 14 24 mov %edx,(%esp) +c0109ba0: e8 44 03 00 00 call c0109ee9 +} +c0109ba5: 89 ec mov %ebp,%esp +c0109ba7: 5d pop %ebp +c0109ba8: c3 ret + +c0109ba9 : + * + * 此函数通过分配一页内存用作进程的内核栈,并将该内存页的虚拟地址设置为进程的内核栈地址 + * 如果内存分配成功,则返回0;如果内存分配失败,则返回-E_NO_MEM + */ +static int +setup_kstack(struct proc_struct *proc) { +c0109ba9: 55 push %ebp +c0109baa: 89 e5 mov %esp,%ebp +c0109bac: 83 ec 28 sub $0x28,%esp + // 分配KSTACKPAGE页内存用作内核栈 + struct Page *page = alloc_pages(KSTACKPAGE); +c0109baf: c7 04 24 02 00 00 00 movl $0x2,(%esp) +c0109bb6: e8 c6 b5 ff ff call c0105181 +c0109bbb: 89 45 f4 mov %eax,-0xc(%ebp) + if (page != NULL) { +c0109bbe: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c0109bc2: 74 1a je c0109bde + // 如果内存分配成功,将内存页的虚拟地址设置为进程的内核栈地址 + proc->kstack = (uintptr_t)page2kva(page); +c0109bc4: 8b 45 f4 mov -0xc(%ebp),%eax +c0109bc7: 89 04 24 mov %eax,(%esp) +c0109bca: e8 eb f8 ff ff call c01094ba +c0109bcf: 89 c2 mov %eax,%edx +c0109bd1: 8b 45 08 mov 0x8(%ebp),%eax +c0109bd4: 89 50 0c mov %edx,0xc(%eax) + return 0; +c0109bd7: b8 00 00 00 00 mov $0x0,%eax +c0109bdc: eb 05 jmp c0109be3 + } + // 如果内存分配失败,返回错误码 + return -E_NO_MEM; +c0109bde: b8 fc ff ff ff mov $0xfffffffc,%eax +} +c0109be3: 89 ec mov %ebp,%esp +c0109be5: 5d pop %ebp +c0109be6: c3 ret + +c0109be7 : + +// put_kstack - free the memory space of process kernel stack +static void +put_kstack(struct proc_struct *proc) { +c0109be7: 55 push %ebp +c0109be8: 89 e5 mov %esp,%ebp +c0109bea: 83 ec 18 sub $0x18,%esp + free_pages(kva2page((void *)(proc->kstack)), KSTACKPAGE); +c0109bed: 8b 45 08 mov 0x8(%ebp),%eax +c0109bf0: 8b 40 0c mov 0xc(%eax),%eax +c0109bf3: 89 04 24 mov %eax,(%esp) +c0109bf6: e8 15 f9 ff ff call c0109510 +c0109bfb: c7 44 24 04 02 00 00 movl $0x2,0x4(%esp) +c0109c02: 00 +c0109c03: 89 04 24 mov %eax,(%esp) +c0109c06: e8 e3 b5 ff ff call c01051ee +} +c0109c0b: 90 nop +c0109c0c: 89 ec mov %ebp,%esp +c0109c0e: 5d pop %ebp +c0109c0f: c3 ret + +c0109c10 : + +// setup_pgdir - alloc one page as PDT +static int +setup_pgdir(struct mm_struct *mm) { +c0109c10: 55 push %ebp +c0109c11: 89 e5 mov %esp,%ebp +c0109c13: 83 ec 28 sub $0x28,%esp + struct Page *page; + if ((page = alloc_page()) == NULL) { +c0109c16: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c0109c1d: e8 5f b5 ff ff call c0105181 +c0109c22: 89 45 f4 mov %eax,-0xc(%ebp) +c0109c25: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c0109c29: 75 0a jne c0109c35 + return -E_NO_MEM; +c0109c2b: b8 fc ff ff ff mov $0xfffffffc,%eax +c0109c30: e9 80 00 00 00 jmp c0109cb5 + } + pde_t *pgdir = page2kva(page); +c0109c35: 8b 45 f4 mov -0xc(%ebp),%eax +c0109c38: 89 04 24 mov %eax,(%esp) +c0109c3b: e8 7a f8 ff ff call c01094ba +c0109c40: 89 45 f0 mov %eax,-0x10(%ebp) + memcpy(pgdir, boot_pgdir, PGSIZE); +c0109c43: a1 00 fa 12 c0 mov 0xc012fa00,%eax +c0109c48: c7 44 24 08 00 10 00 movl $0x1000,0x8(%esp) +c0109c4f: 00 +c0109c50: 89 44 24 04 mov %eax,0x4(%esp) +c0109c54: 8b 45 f0 mov -0x10(%ebp),%eax +c0109c57: 89 04 24 mov %eax,(%esp) +c0109c5a: e8 77 22 00 00 call c010bed6 + pgdir[PDX(VPT)] = PADDR(pgdir) | PTE_P | PTE_W; +c0109c5f: 8b 45 f0 mov -0x10(%ebp),%eax +c0109c62: 89 45 ec mov %eax,-0x14(%ebp) +c0109c65: 81 7d ec ff ff ff bf cmpl $0xbfffffff,-0x14(%ebp) +c0109c6c: 77 23 ja c0109c91 +c0109c6e: 8b 45 ec mov -0x14(%ebp),%eax +c0109c71: 89 44 24 0c mov %eax,0xc(%esp) +c0109c75: c7 44 24 08 78 e0 10 movl $0xc010e078,0x8(%esp) +c0109c7c: c0 +c0109c7d: c7 44 24 04 84 01 00 movl $0x184,0x4(%esp) +c0109c84: 00 +c0109c85: c7 04 24 9c e0 10 c0 movl $0xc010e09c,(%esp) +c0109c8c: e8 aa 70 ff ff call c0100d3b <__panic> +c0109c91: 8b 45 ec mov -0x14(%ebp),%eax +c0109c94: 8d 90 00 00 00 40 lea 0x40000000(%eax),%edx +c0109c9a: 8b 45 f0 mov -0x10(%ebp),%eax +c0109c9d: 05 ac 0f 00 00 add $0xfac,%eax +c0109ca2: 83 ca 03 or $0x3,%edx +c0109ca5: 89 10 mov %edx,(%eax) + mm->pgdir = pgdir; +c0109ca7: 8b 45 08 mov 0x8(%ebp),%eax +c0109caa: 8b 55 f0 mov -0x10(%ebp),%edx +c0109cad: 89 50 0c mov %edx,0xc(%eax) + return 0; +c0109cb0: b8 00 00 00 00 mov $0x0,%eax +} +c0109cb5: 89 ec mov %ebp,%esp +c0109cb7: 5d pop %ebp +c0109cb8: c3 ret + +c0109cb9 : + +// put_pgdir - free the memory space of PDT +static void +put_pgdir(struct mm_struct *mm) { +c0109cb9: 55 push %ebp +c0109cba: 89 e5 mov %esp,%ebp +c0109cbc: 83 ec 18 sub $0x18,%esp + free_page(kva2page(mm->pgdir)); +c0109cbf: 8b 45 08 mov 0x8(%ebp),%eax +c0109cc2: 8b 40 0c mov 0xc(%eax),%eax +c0109cc5: 89 04 24 mov %eax,(%esp) +c0109cc8: e8 43 f8 ff ff call c0109510 +c0109ccd: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c0109cd4: 00 +c0109cd5: 89 04 24 mov %eax,(%esp) +c0109cd8: e8 11 b5 ff ff call c01051ee +} +c0109cdd: 90 nop +c0109cde: 89 ec mov %ebp,%esp +c0109ce0: 5d pop %ebp +c0109ce1: c3 ret + +c0109ce2 : + +// copy_mm - process "proc" duplicate OR share process "current"'s mm according clone_flags +// - if clone_flags & CLONE_VM, then "share" ; else "duplicate" +static int +copy_mm(uint32_t clone_flags, struct proc_struct *proc) { +c0109ce2: 55 push %ebp +c0109ce3: 89 e5 mov %esp,%ebp +c0109ce5: 83 ec 28 sub $0x28,%esp + struct mm_struct *mm, *oldmm = current->mm; +c0109ce8: a1 30 41 1a c0 mov 0xc01a4130,%eax +c0109ced: 8b 40 18 mov 0x18(%eax),%eax +c0109cf0: 89 45 ec mov %eax,-0x14(%ebp) + + /* current is a kernel thread */ + if (oldmm == NULL) { +c0109cf3: 83 7d ec 00 cmpl $0x0,-0x14(%ebp) +c0109cf7: 75 0a jne c0109d03 + return 0; +c0109cf9: b8 00 00 00 00 mov $0x0,%eax +c0109cfe: e9 fc 00 00 00 jmp c0109dff + } + if (clone_flags & CLONE_VM) { +c0109d03: 8b 45 08 mov 0x8(%ebp),%eax +c0109d06: 25 00 01 00 00 and $0x100,%eax +c0109d0b: 85 c0 test %eax,%eax +c0109d0d: 74 08 je c0109d17 + mm = oldmm; +c0109d0f: 8b 45 ec mov -0x14(%ebp),%eax +c0109d12: 89 45 f4 mov %eax,-0xc(%ebp) + goto good_mm; +c0109d15: eb 5e jmp c0109d75 + } + + int ret = -E_NO_MEM; +c0109d17: c7 45 f0 fc ff ff ff movl $0xfffffffc,-0x10(%ebp) + if ((mm = mm_create()) == NULL) { +c0109d1e: e8 92 e2 ff ff call c0107fb5 +c0109d23: 89 45 f4 mov %eax,-0xc(%ebp) +c0109d26: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c0109d2a: 0f 84 cb 00 00 00 je c0109dfb + goto bad_mm; + } + if (setup_pgdir(mm) != 0) { +c0109d30: 8b 45 f4 mov -0xc(%ebp),%eax +c0109d33: 89 04 24 mov %eax,(%esp) +c0109d36: e8 d5 fe ff ff call c0109c10 +c0109d3b: 85 c0 test %eax,%eax +c0109d3d: 0f 85 aa 00 00 00 jne c0109ded + goto bad_pgdir_cleanup_mm; + } + + lock_mm(oldmm); +c0109d43: 8b 45 ec mov -0x14(%ebp),%eax +c0109d46: 89 04 24 mov %eax,(%esp) +c0109d49: e8 42 f8 ff ff call c0109590 + { + ret = dup_mmap(mm, oldmm); +c0109d4e: 8b 45 ec mov -0x14(%ebp),%eax +c0109d51: 89 44 24 04 mov %eax,0x4(%esp) +c0109d55: 8b 45 f4 mov -0xc(%ebp),%eax +c0109d58: 89 04 24 mov %eax,(%esp) +c0109d5b: e8 4c e7 ff ff call c01084ac +c0109d60: 89 45 f0 mov %eax,-0x10(%ebp) + } + unlock_mm(oldmm); +c0109d63: 8b 45 ec mov -0x14(%ebp),%eax +c0109d66: 89 04 24 mov %eax,(%esp) +c0109d69: e8 41 f8 ff ff call c01095af + + if (ret != 0) { +c0109d6e: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) +c0109d72: 75 60 jne c0109dd4 + goto bad_dup_cleanup_mmap; + } + +good_mm: +c0109d74: 90 nop + mm_count_inc(mm); +c0109d75: 8b 45 f4 mov -0xc(%ebp),%eax +c0109d78: 89 04 24 mov %eax,(%esp) +c0109d7b: e8 dc f7 ff ff call c010955c + proc->mm = mm; +c0109d80: 8b 45 0c mov 0xc(%ebp),%eax +c0109d83: 8b 55 f4 mov -0xc(%ebp),%edx +c0109d86: 89 50 18 mov %edx,0x18(%eax) + proc->cr3 = PADDR(mm->pgdir); +c0109d89: 8b 45 f4 mov -0xc(%ebp),%eax +c0109d8c: 8b 40 0c mov 0xc(%eax),%eax +c0109d8f: 89 45 e8 mov %eax,-0x18(%ebp) +c0109d92: 81 7d e8 ff ff ff bf cmpl $0xbfffffff,-0x18(%ebp) +c0109d99: 77 23 ja c0109dbe +c0109d9b: 8b 45 e8 mov -0x18(%ebp),%eax +c0109d9e: 89 44 24 0c mov %eax,0xc(%esp) +c0109da2: c7 44 24 08 78 e0 10 movl $0xc010e078,0x8(%esp) +c0109da9: c0 +c0109daa: c7 44 24 04 b3 01 00 movl $0x1b3,0x4(%esp) +c0109db1: 00 +c0109db2: c7 04 24 9c e0 10 c0 movl $0xc010e09c,(%esp) +c0109db9: e8 7d 6f ff ff call c0100d3b <__panic> +c0109dbe: 8b 45 e8 mov -0x18(%ebp),%eax +c0109dc1: 8d 90 00 00 00 40 lea 0x40000000(%eax),%edx +c0109dc7: 8b 45 0c mov 0xc(%ebp),%eax +c0109dca: 89 50 40 mov %edx,0x40(%eax) + return 0; +c0109dcd: b8 00 00 00 00 mov $0x0,%eax +c0109dd2: eb 2b jmp c0109dff + goto bad_dup_cleanup_mmap; +c0109dd4: 90 nop +bad_dup_cleanup_mmap: + exit_mmap(mm); +c0109dd5: 8b 45 f4 mov -0xc(%ebp),%eax +c0109dd8: 89 04 24 mov %eax,(%esp) +c0109ddb: e8 cd e7 ff ff call c01085ad + put_pgdir(mm); +c0109de0: 8b 45 f4 mov -0xc(%ebp),%eax +c0109de3: 89 04 24 mov %eax,(%esp) +c0109de6: e8 ce fe ff ff call c0109cb9 +c0109deb: eb 01 jmp c0109dee + goto bad_pgdir_cleanup_mm; +c0109ded: 90 nop +bad_pgdir_cleanup_mm: + mm_destroy(mm); +c0109dee: 8b 45 f4 mov -0xc(%ebp),%eax +c0109df1: 89 04 24 mov %eax,(%esp) +c0109df4: e8 25 e5 ff ff call c010831e +c0109df9: eb 01 jmp c0109dfc + goto bad_mm; +c0109dfb: 90 nop +bad_mm: + return ret; +c0109dfc: 8b 45 f0 mov -0x10(%ebp),%eax +} +c0109dff: 89 ec mov %ebp,%esp +c0109e01: 5d pop %ebp +c0109e02: c3 ret + +c0109e03 : + * @param proc 指向新进程的进程结构体,用于存储初始化后的陷阱帧和上下文信息。 + * @param esp 新进程的栈指针,表示新进程栈的初始位置。 + * @param tf 指向当前线程的陷阱帧结构体,用于将当前线程的执行状态复制到新进程中。 + */ +static void +copy_thread(struct proc_struct *proc, uintptr_t esp, struct trapframe *tf) { +c0109e03: 55 push %ebp +c0109e04: 89 e5 mov %esp,%ebp +c0109e06: 57 push %edi +c0109e07: 56 push %esi +c0109e08: 53 push %ebx + // 初始化新进程的陷阱帧,位于其内核栈的顶部 + proc->tf = (struct trapframe *)(proc->kstack + KSTACKSIZE) - 1; +c0109e09: 8b 45 08 mov 0x8(%ebp),%eax +c0109e0c: 8b 40 0c mov 0xc(%eax),%eax +c0109e0f: 05 b4 1f 00 00 add $0x1fb4,%eax +c0109e14: 89 c2 mov %eax,%edx +c0109e16: 8b 45 08 mov 0x8(%ebp),%eax +c0109e19: 89 50 3c mov %edx,0x3c(%eax) + + // 将当前线程的陷阱帧内容复制到新进程的陷阱帧 + *(proc->tf) = *tf; +c0109e1c: 8b 45 08 mov 0x8(%ebp),%eax +c0109e1f: 8b 40 3c mov 0x3c(%eax),%eax +c0109e22: 8b 55 10 mov 0x10(%ebp),%edx +c0109e25: b9 4c 00 00 00 mov $0x4c,%ecx +c0109e2a: 89 c3 mov %eax,%ebx +c0109e2c: 83 e3 01 and $0x1,%ebx +c0109e2f: 85 db test %ebx,%ebx +c0109e31: 74 0c je c0109e3f +c0109e33: 0f b6 1a movzbl (%edx),%ebx +c0109e36: 88 18 mov %bl,(%eax) +c0109e38: 8d 40 01 lea 0x1(%eax),%eax +c0109e3b: 8d 52 01 lea 0x1(%edx),%edx +c0109e3e: 49 dec %ecx +c0109e3f: 89 c3 mov %eax,%ebx +c0109e41: 83 e3 02 and $0x2,%ebx +c0109e44: 85 db test %ebx,%ebx +c0109e46: 74 0f je c0109e57 +c0109e48: 0f b7 1a movzwl (%edx),%ebx +c0109e4b: 66 89 18 mov %bx,(%eax) +c0109e4e: 8d 40 02 lea 0x2(%eax),%eax +c0109e51: 8d 52 02 lea 0x2(%edx),%edx +c0109e54: 83 e9 02 sub $0x2,%ecx +c0109e57: 89 cf mov %ecx,%edi +c0109e59: 83 e7 fc and $0xfffffffc,%edi +c0109e5c: bb 00 00 00 00 mov $0x0,%ebx +c0109e61: 8b 34 1a mov (%edx,%ebx,1),%esi +c0109e64: 89 34 18 mov %esi,(%eax,%ebx,1) +c0109e67: 83 c3 04 add $0x4,%ebx +c0109e6a: 39 fb cmp %edi,%ebx +c0109e6c: 72 f3 jb c0109e61 +c0109e6e: 01 d8 add %ebx,%eax +c0109e70: 01 da add %ebx,%edx +c0109e72: bb 00 00 00 00 mov $0x0,%ebx +c0109e77: 89 ce mov %ecx,%esi +c0109e79: 83 e6 02 and $0x2,%esi +c0109e7c: 85 f6 test %esi,%esi +c0109e7e: 74 0b je c0109e8b +c0109e80: 0f b7 34 1a movzwl (%edx,%ebx,1),%esi +c0109e84: 66 89 34 18 mov %si,(%eax,%ebx,1) +c0109e88: 83 c3 02 add $0x2,%ebx +c0109e8b: 83 e1 01 and $0x1,%ecx +c0109e8e: 85 c9 test %ecx,%ecx +c0109e90: 74 07 je c0109e99 +c0109e92: 0f b6 14 1a movzbl (%edx,%ebx,1),%edx +c0109e96: 88 14 18 mov %dl,(%eax,%ebx,1) + + // 设置子进程的返回值为0,表示fork成功 + proc->tf->tf_regs.reg_eax = 0; +c0109e99: 8b 45 08 mov 0x8(%ebp),%eax +c0109e9c: 8b 40 3c mov 0x3c(%eax),%eax +c0109e9f: c7 40 1c 00 00 00 00 movl $0x0,0x1c(%eax) + // 设置子进程的栈指针为指定的esp位置 + proc->tf->tf_esp = esp; +c0109ea6: 8b 45 08 mov 0x8(%ebp),%eax +c0109ea9: 8b 40 3c mov 0x3c(%eax),%eax +c0109eac: 8b 55 0c mov 0xc(%ebp),%edx +c0109eaf: 89 50 44 mov %edx,0x44(%eax) + // 启用子进程的中断标志 + proc->tf->tf_eflags |= FL_IF; +c0109eb2: 8b 45 08 mov 0x8(%ebp),%eax +c0109eb5: 8b 40 3c mov 0x3c(%eax),%eax +c0109eb8: 8b 50 40 mov 0x40(%eax),%edx +c0109ebb: 8b 45 08 mov 0x8(%ebp),%eax +c0109ebe: 8b 40 3c mov 0x3c(%eax),%eax +c0109ec1: 81 ca 00 02 00 00 or $0x200,%edx +c0109ec7: 89 50 40 mov %edx,0x40(%eax) + + // 设置子进程的初始指令指针为forkret函数的地址 + proc->context.eip = (uintptr_t)forkret; +c0109eca: ba e9 99 10 c0 mov $0xc01099e9,%edx +c0109ecf: 8b 45 08 mov 0x8(%ebp),%eax +c0109ed2: 89 50 1c mov %edx,0x1c(%eax) + // 设置子进程的栈指针为其陷阱帧的地址 + proc->context.esp = (uintptr_t)(proc->tf); +c0109ed5: 8b 45 08 mov 0x8(%ebp),%eax +c0109ed8: 8b 40 3c mov 0x3c(%eax),%eax +c0109edb: 89 c2 mov %eax,%edx +c0109edd: 8b 45 08 mov 0x8(%ebp),%eax +c0109ee0: 89 50 20 mov %edx,0x20(%eax) +} +c0109ee3: 90 nop +c0109ee4: 5b pop %ebx +c0109ee5: 5e pop %esi +c0109ee6: 5f pop %edi +c0109ee7: 5d pop %ebp +c0109ee8: c3 ret + +c0109ee9 : + * + * 此函数负责分配proc_struct、设置内核栈、复制或共享内存管理结构, + * 复制线程上下文,将新进程插入到进程列表中,并将其设置为可运行状态 + */ +int +do_fork(uint32_t clone_flags, uintptr_t stack, struct trapframe *tf) { +c0109ee9: 55 push %ebp +c0109eea: 89 e5 mov %esp,%ebp +c0109eec: 83 ec 28 sub $0x28,%esp + int ret = -E_NO_FREE_PROC; +c0109eef: c7 45 f4 fb ff ff ff movl $0xfffffffb,-0xc(%ebp) + struct proc_struct *proc; + // 检查系统中是否有足够的资源创建新进程 + if (nr_process >= MAX_PROCESS) { +c0109ef6: a1 40 61 1a c0 mov 0xc01a6140,%eax +c0109efb: 3d ff 0f 00 00 cmp $0xfff,%eax +c0109f00: 0f 8f e1 00 00 00 jg c0109fe7 + goto fork_out; + } + ret = -E_NO_MEM; +c0109f06: c7 45 f4 fc ff ff ff movl $0xfffffffc,-0xc(%ebp) + // 4. call copy_thread to setup tf & context in proc_struct + // 5. insert proc_struct into hash_list && proc_list + // 6. call wakeup_proc to make the new child process RUNNABLE + // 7. set ret vaule using child proc's pid + //调用alloc_proc,首先获得一块用户信息块 + if((proc = alloc_proc()) == NULL){ +c0109f0d: e8 bc f6 ff ff call c01095ce +c0109f12: 89 45 f0 mov %eax,-0x10(%ebp) +c0109f15: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) +c0109f19: 0f 84 cb 00 00 00 je c0109fea + goto fork_out; + } + + // 设置新进程的父进程为当前进程,并确保当前进程的wait_state为0 + proc->parent = current; +c0109f1f: 8b 15 30 41 1a c0 mov 0xc01a4130,%edx +c0109f25: 8b 45 f0 mov -0x10(%ebp),%eax +c0109f28: 89 50 14 mov %edx,0x14(%eax) + assert(current->wait_state == 0); +c0109f2b: a1 30 41 1a c0 mov 0xc01a4130,%eax +c0109f30: 8b 40 6c mov 0x6c(%eax),%eax +c0109f33: 85 c0 test %eax,%eax +c0109f35: 74 24 je c0109f5b +c0109f37: c7 44 24 0c b0 e0 10 movl $0xc010e0b0,0xc(%esp) +c0109f3e: c0 +c0109f3f: c7 44 24 08 c9 e0 10 movl $0xc010e0c9,0x8(%esp) +c0109f46: c0 +c0109f47: c7 44 24 04 17 02 00 movl $0x217,0x4(%esp) +c0109f4e: 00 +c0109f4f: c7 04 24 9c e0 10 c0 movl $0xc010e09c,(%esp) +c0109f56: e8 e0 6d ff ff call c0100d3b <__panic> + + // 为新进程分配内核栈 + if (setup_kstack(proc) != 0) { +c0109f5b: 8b 45 f0 mov -0x10(%ebp),%eax +c0109f5e: 89 04 24 mov %eax,(%esp) +c0109f61: e8 43 fc ff ff call c0109ba9 +c0109f66: 85 c0 test %eax,%eax +c0109f68: 0f 85 90 00 00 00 jne c0109ffe + goto bad_fork_cleanup_proc; + } + // 根据clone_flags复制或共享内存管理结构 + if (copy_mm(clone_flags, proc) != 0) { +c0109f6e: 8b 45 f0 mov -0x10(%ebp),%eax +c0109f71: 89 44 24 04 mov %eax,0x4(%esp) +c0109f75: 8b 45 08 mov 0x8(%ebp),%eax +c0109f78: 89 04 24 mov %eax,(%esp) +c0109f7b: e8 62 fd ff ff call c0109ce2 +c0109f80: 85 c0 test %eax,%eax +c0109f82: 75 6c jne c0109ff0 + goto bad_fork_cleanup_kstack; + } + + // 复制线程上下文到新进程 + copy_thread(proc, stack, tf); +c0109f84: 8b 45 10 mov 0x10(%ebp),%eax +c0109f87: 89 44 24 08 mov %eax,0x8(%esp) +c0109f8b: 8b 45 0c mov 0xc(%ebp),%eax +c0109f8e: 89 44 24 04 mov %eax,0x4(%esp) +c0109f92: 8b 45 f0 mov -0x10(%ebp),%eax +c0109f95: 89 04 24 mov %eax,(%esp) +c0109f98: e8 66 fe ff ff call c0109e03 + + bool intr_flag; + local_intr_save(intr_flag); +c0109f9d: e8 de f3 ff ff call c0109380 <__intr_save> +c0109fa2: 89 45 ec mov %eax,-0x14(%ebp) + { + // 为新进程分配唯一的pid,并将其插入到进程哈希列表和进程列表中 + proc->pid = get_pid(); +c0109fa5: e8 cf f8 ff ff call c0109879 +c0109faa: 8b 55 f0 mov -0x10(%ebp),%edx +c0109fad: 89 42 04 mov %eax,0x4(%edx) + hash_proc(proc); +c0109fb0: 8b 45 f0 mov -0x10(%ebp),%eax +c0109fb3: 89 04 24 mov %eax,(%esp) +c0109fb6: e8 49 fa ff ff call c0109a04 + set_links(proc); +c0109fbb: 8b 45 f0 mov -0x10(%ebp),%eax +c0109fbe: 89 04 24 mov %eax,(%esp) +c0109fc1: e8 84 f7 ff ff call c010974a + + } + local_intr_restore(intr_flag); +c0109fc6: 8b 45 ec mov -0x14(%ebp),%eax +c0109fc9: 89 04 24 mov %eax,(%esp) +c0109fcc: e8 db f3 ff ff call c01093ac <__intr_restore> + + // 将新进程设置为可运行状态 + wakeup_proc(proc); +c0109fd1: 8b 45 f0 mov -0x10(%ebp),%eax +c0109fd4: 89 04 24 mov %eax,(%esp) +c0109fd7: e8 19 10 00 00 call c010aff5 + + // 设置返回值为新进程的pid + ret = proc->pid; +c0109fdc: 8b 45 f0 mov -0x10(%ebp),%eax +c0109fdf: 8b 40 04 mov 0x4(%eax),%eax +c0109fe2: 89 45 f4 mov %eax,-0xc(%ebp) +c0109fe5: eb 04 jmp c0109feb + goto fork_out; +c0109fe7: 90 nop +c0109fe8: eb 01 jmp c0109feb + goto fork_out; +c0109fea: 90 nop + * update step 5: insert proc_struct into hash_list && proc_list, set the relation links of process + */ + + +fork_out: + return ret; +c0109feb: 8b 45 f4 mov -0xc(%ebp),%eax +c0109fee: eb 1c jmp c010a00c + goto bad_fork_cleanup_kstack; +c0109ff0: 90 nop + +bad_fork_cleanup_kstack: + // 如果资源分配失败,释放已分配的内核栈 + put_kstack(proc); +c0109ff1: 8b 45 f0 mov -0x10(%ebp),%eax +c0109ff4: 89 04 24 mov %eax,(%esp) +c0109ff7: e8 eb fb ff ff call c0109be7 +c0109ffc: eb 01 jmp c0109fff + goto bad_fork_cleanup_proc; +c0109ffe: 90 nop +bad_fork_cleanup_proc: +// 释放proc_struct结构体 + kfree(proc); +c0109fff: 8b 45 f0 mov -0x10(%ebp),%eax +c010a002: 89 04 24 mov %eax,(%esp) +c010a005: e8 03 ad ff ff call c0104d0d + goto fork_out; +c010a00a: eb df jmp c0109feb +} +c010a00c: 89 ec mov %ebp,%esp +c010a00e: 5d pop %ebp +c010a00f: c3 ret + +c010a010 : + * @param error_code 进程退出码,表示进程退出的状态。 + * + * @return 该函数不会返回。 + */ +int +do_exit(int error_code) { +c010a010: 55 push %ebp +c010a011: 89 e5 mov %esp,%ebp +c010a013: 83 ec 28 sub $0x28,%esp + // 检查当前进程是否为idle进程,如果是,则引发panic。 + if (current == idleproc) { +c010a016: 8b 15 30 41 1a c0 mov 0xc01a4130,%edx +c010a01c: a1 28 41 1a c0 mov 0xc01a4128,%eax +c010a021: 39 c2 cmp %eax,%edx +c010a023: 75 1c jne c010a041 + panic("idleproc exit.\n"); +c010a025: c7 44 24 08 de e0 10 movl $0xc010e0de,0x8(%esp) +c010a02c: c0 +c010a02d: c7 44 24 04 59 02 00 movl $0x259,0x4(%esp) +c010a034: 00 +c010a035: c7 04 24 9c e0 10 c0 movl $0xc010e09c,(%esp) +c010a03c: e8 fa 6c ff ff call c0100d3b <__panic> + } + // 检查当前进程是否为init进程,如果是,则引发panic。 + if (current == initproc) { +c010a041: 8b 15 30 41 1a c0 mov 0xc01a4130,%edx +c010a047: a1 2c 41 1a c0 mov 0xc01a412c,%eax +c010a04c: 39 c2 cmp %eax,%edx +c010a04e: 75 1c jne c010a06c + panic("initproc exit.\n"); +c010a050: c7 44 24 08 ee e0 10 movl $0xc010e0ee,0x8(%esp) +c010a057: c0 +c010a058: c7 44 24 04 5d 02 00 movl $0x25d,0x4(%esp) +c010a05f: 00 +c010a060: c7 04 24 9c e0 10 c0 movl $0xc010e09c,(%esp) +c010a067: e8 cf 6c ff ff call c0100d3b <__panic> + } + + // 获取当前进程的内存管理结构。 + struct mm_struct *mm = current->mm; +c010a06c: a1 30 41 1a c0 mov 0xc01a4130,%eax +c010a071: 8b 40 18 mov 0x18(%eax),%eax +c010a074: 89 45 f4 mov %eax,-0xc(%ebp) + // 如果当前进程有内存管理结构,则进行清理。 + if (mm != NULL) { +c010a077: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c010a07b: 74 4b je c010a0c8 + // 加载引导页表,准备清理当前进程的页表。 + lcr3(boot_cr3); +c010a07d: a1 a8 3f 1a c0 mov 0xc01a3fa8,%eax +c010a082: 89 45 e8 mov %eax,-0x18(%ebp) + asm volatile ("mov %0, %%cr3" :: "r" (cr3) : "memory"); +c010a085: 8b 45 e8 mov -0x18(%ebp),%eax +c010a088: 0f 22 d8 mov %eax,%cr3 +} +c010a08b: 90 nop + // 如果内存管理结构的引用计数减到0,则释放相关资源。 + if (mm_count_dec(mm) == 0) { +c010a08c: 8b 45 f4 mov -0xc(%ebp),%eax +c010a08f: 89 04 24 mov %eax,(%esp) +c010a092: e8 df f4 ff ff call c0109576 +c010a097: 85 c0 test %eax,%eax +c010a099: 75 21 jne c010a0bc + exit_mmap(mm); +c010a09b: 8b 45 f4 mov -0xc(%ebp),%eax +c010a09e: 89 04 24 mov %eax,(%esp) +c010a0a1: e8 07 e5 ff ff call c01085ad + put_pgdir(mm); +c010a0a6: 8b 45 f4 mov -0xc(%ebp),%eax +c010a0a9: 89 04 24 mov %eax,(%esp) +c010a0ac: e8 08 fc ff ff call c0109cb9 + mm_destroy(mm); +c010a0b1: 8b 45 f4 mov -0xc(%ebp),%eax +c010a0b4: 89 04 24 mov %eax,(%esp) +c010a0b7: e8 62 e2 ff ff call c010831e + } + // 将当前进程的内存管理结构设置为NULL。 + current->mm = NULL; +c010a0bc: a1 30 41 1a c0 mov 0xc01a4130,%eax +c010a0c1: c7 40 18 00 00 00 00 movl $0x0,0x18(%eax) + } + // 将当前进程的状态设置为僵尸状态,并保存退出码。 + current->state = PROC_ZOMBIE; +c010a0c8: a1 30 41 1a c0 mov 0xc01a4130,%eax +c010a0cd: c7 00 03 00 00 00 movl $0x3,(%eax) + current->exit_code = error_code; +c010a0d3: a1 30 41 1a c0 mov 0xc01a4130,%eax +c010a0d8: 8b 55 08 mov 0x8(%ebp),%edx +c010a0db: 89 50 68 mov %edx,0x68(%eax) + + // 保存中断状态,并获取当前进程的父进程。 + bool intr_flag; + struct proc_struct *proc; + local_intr_save(intr_flag); +c010a0de: e8 9d f2 ff ff call c0109380 <__intr_save> +c010a0e3: 89 45 f0 mov %eax,-0x10(%ebp) + { + proc = current->parent; +c010a0e6: a1 30 41 1a c0 mov 0xc01a4130,%eax +c010a0eb: 8b 40 14 mov 0x14(%eax),%eax +c010a0ee: 89 45 ec mov %eax,-0x14(%ebp) + // 如果父进程在等待子进程,则唤醒父进程。 + if (proc->wait_state == WT_CHILD) { +c010a0f1: 8b 45 ec mov -0x14(%ebp),%eax +c010a0f4: 8b 40 6c mov 0x6c(%eax),%eax +c010a0f7: 3d 01 00 00 80 cmp $0x80000001,%eax +c010a0fc: 0f 85 96 00 00 00 jne c010a198 + wakeup_proc(proc); +c010a102: 8b 45 ec mov -0x14(%ebp),%eax +c010a105: 89 04 24 mov %eax,(%esp) +c010a108: e8 e8 0e 00 00 call c010aff5 + } + // 遍历当前进程的所有子进程,并将它们的父进程设置为init进程。 + while (current->cptr != NULL) { +c010a10d: e9 86 00 00 00 jmp c010a198 + proc = current->cptr; +c010a112: a1 30 41 1a c0 mov 0xc01a4130,%eax +c010a117: 8b 40 70 mov 0x70(%eax),%eax +c010a11a: 89 45 ec mov %eax,-0x14(%ebp) + current->cptr = proc->optr; +c010a11d: a1 30 41 1a c0 mov 0xc01a4130,%eax +c010a122: 8b 55 ec mov -0x14(%ebp),%edx +c010a125: 8b 52 78 mov 0x78(%edx),%edx +c010a128: 89 50 70 mov %edx,0x70(%eax) + + proc->yptr = NULL; +c010a12b: 8b 45 ec mov -0x14(%ebp),%eax +c010a12e: c7 40 74 00 00 00 00 movl $0x0,0x74(%eax) + if ((proc->optr = initproc->cptr) != NULL) { +c010a135: a1 2c 41 1a c0 mov 0xc01a412c,%eax +c010a13a: 8b 50 70 mov 0x70(%eax),%edx +c010a13d: 8b 45 ec mov -0x14(%ebp),%eax +c010a140: 89 50 78 mov %edx,0x78(%eax) +c010a143: 8b 45 ec mov -0x14(%ebp),%eax +c010a146: 8b 40 78 mov 0x78(%eax),%eax +c010a149: 85 c0 test %eax,%eax +c010a14b: 74 0e je c010a15b + initproc->cptr->yptr = proc; +c010a14d: a1 2c 41 1a c0 mov 0xc01a412c,%eax +c010a152: 8b 40 70 mov 0x70(%eax),%eax +c010a155: 8b 55 ec mov -0x14(%ebp),%edx +c010a158: 89 50 74 mov %edx,0x74(%eax) + } + proc->parent = initproc; +c010a15b: 8b 15 2c 41 1a c0 mov 0xc01a412c,%edx +c010a161: 8b 45 ec mov -0x14(%ebp),%eax +c010a164: 89 50 14 mov %edx,0x14(%eax) + initproc->cptr = proc; +c010a167: a1 2c 41 1a c0 mov 0xc01a412c,%eax +c010a16c: 8b 55 ec mov -0x14(%ebp),%edx +c010a16f: 89 50 70 mov %edx,0x70(%eax) + // 如果子进程处于僵尸状态,并且init进程在等待子进程,则唤醒init进程。 + if (proc->state == PROC_ZOMBIE) { +c010a172: 8b 45 ec mov -0x14(%ebp),%eax +c010a175: 8b 00 mov (%eax),%eax +c010a177: 83 f8 03 cmp $0x3,%eax +c010a17a: 75 1c jne c010a198 + if (initproc->wait_state == WT_CHILD) { +c010a17c: a1 2c 41 1a c0 mov 0xc01a412c,%eax +c010a181: 8b 40 6c mov 0x6c(%eax),%eax +c010a184: 3d 01 00 00 80 cmp $0x80000001,%eax +c010a189: 75 0d jne c010a198 + wakeup_proc(initproc); +c010a18b: a1 2c 41 1a c0 mov 0xc01a412c,%eax +c010a190: 89 04 24 mov %eax,(%esp) +c010a193: e8 5d 0e 00 00 call c010aff5 + while (current->cptr != NULL) { +c010a198: a1 30 41 1a c0 mov 0xc01a4130,%eax +c010a19d: 8b 40 70 mov 0x70(%eax),%eax +c010a1a0: 85 c0 test %eax,%eax +c010a1a2: 0f 85 6a ff ff ff jne c010a112 + } + } + } + } + // 恢复中断状态。 + local_intr_restore(intr_flag); +c010a1a8: 8b 45 f0 mov -0x10(%ebp),%eax +c010a1ab: 89 04 24 mov %eax,(%esp) +c010a1ae: e8 f9 f1 ff ff call c01093ac <__intr_restore> + // 调度新的进程运行。 + schedule(); +c010a1b3: e8 c4 0e 00 00 call c010b07c + // 如果调度失败,引发panic。 + panic("do_exit will not return!! %d.\n", current->pid); +c010a1b8: a1 30 41 1a c0 mov 0xc01a4130,%eax +c010a1bd: 8b 40 04 mov 0x4(%eax),%eax +c010a1c0: 89 44 24 0c mov %eax,0xc(%esp) +c010a1c4: c7 44 24 08 00 e1 10 movl $0xc010e100,0x8(%esp) +c010a1cb: c0 +c010a1cc: c7 44 24 04 95 02 00 movl $0x295,0x4(%esp) +c010a1d3: 00 +c010a1d4: c7 04 24 9c e0 10 c0 movl $0xc010e09c,(%esp) +c010a1db: e8 5b 6b ff ff call c0100d3b <__panic> + +c010a1e0 : + * @param binary 二进制程序的指针 + * @param size 二进制程序的大小 + * @return 成功返回 0,失败返回负的错误码 + */ +static int +load_icode(unsigned char *binary, size_t size) { +c010a1e0: 55 push %ebp +c010a1e1: 89 e5 mov %esp,%ebp +c010a1e3: 83 ec 78 sub $0x78,%esp + // 检查当前进程是否已经有内存描述符,如果有则触发 panic + if (current->mm != NULL) { +c010a1e6: a1 30 41 1a c0 mov 0xc01a4130,%eax +c010a1eb: 8b 40 18 mov 0x18(%eax),%eax +c010a1ee: 85 c0 test %eax,%eax +c010a1f0: 74 1c je c010a20e + panic("load_icode: current->mm must be empty.\n"); +c010a1f2: c7 44 24 08 20 e1 10 movl $0xc010e120,0x8(%esp) +c010a1f9: c0 +c010a1fa: c7 44 24 04 ae 02 00 movl $0x2ae,0x4(%esp) +c010a201: 00 +c010a202: c7 04 24 9c e0 10 c0 movl $0xc010e09c,(%esp) +c010a209: e8 2d 6b ff ff call c0100d3b <__panic> + } + + // 初始化返回值为 -E_NO_MEM + int ret = -E_NO_MEM; +c010a20e: c7 45 f4 fc ff ff ff movl $0xfffffffc,-0xc(%ebp) + struct mm_struct *mm; + //(1) create a new mm for current process + //(1) 为当前进程创建一个新的内存描述符 (mm_struct) + if ((mm = mm_create()) == NULL) { +c010a215: e8 9b dd ff ff call c0107fb5 +c010a21a: 89 45 d0 mov %eax,-0x30(%ebp) +c010a21d: 83 7d d0 00 cmpl $0x0,-0x30(%ebp) +c010a221: 0f 84 0e 06 00 00 je c010a835 + goto bad_mm; + } + //(2) create a new PDT, and mm->pgdir= kernel virtual addr of PDT + // (2) 创建一个新的页目录表 (PDT),并将 mm->pgdir 设置为内核虚拟地址的 PDT + if (setup_pgdir(mm) != 0) { +c010a227: 8b 45 d0 mov -0x30(%ebp),%eax +c010a22a: 89 04 24 mov %eax,(%esp) +c010a22d: e8 de f9 ff ff call c0109c10 +c010a232: 85 c0 test %eax,%eax +c010a234: 0f 85 ed 05 00 00 jne c010a827 + //(3) copy TEXT/DATA section, build BSS parts in binary to memory space of process + // (3) 将二进制程序的 TEXT/DATA 段复制到进程的内存空间,并构建 BSS 部分 + struct Page *page; + //(3.1) get the file header of the bianry program (ELF format) + // (3.1) 获取二进制程序的文件头 (ELF 格式) + struct elfhdr *elf = (struct elfhdr *)binary; +c010a23a: 8b 45 08 mov 0x8(%ebp),%eax +c010a23d: 89 45 cc mov %eax,-0x34(%ebp) + //(3.2) get the entry of the program section headers of the bianry program (ELF format) + // (3.2) 获取二进制程序的程序段头表入口 (ELF 格式) + struct proghdr *ph = (struct proghdr *)(binary + elf->e_phoff); +c010a240: 8b 45 cc mov -0x34(%ebp),%eax +c010a243: 8b 50 1c mov 0x1c(%eax),%edx +c010a246: 8b 45 08 mov 0x8(%ebp),%eax +c010a249: 01 d0 add %edx,%eax +c010a24b: 89 45 ec mov %eax,-0x14(%ebp) + //(3.3) This program is valid? + // (3.3) 检查程序是否有效 + if (elf->e_magic != ELF_MAGIC) { +c010a24e: 8b 45 cc mov -0x34(%ebp),%eax +c010a251: 8b 00 mov (%eax),%eax +c010a253: 3d 7f 45 4c 46 cmp $0x464c457f,%eax +c010a258: 74 0c je c010a266 + ret = -E_INVAL_ELF; +c010a25a: c7 45 f4 f8 ff ff ff movl $0xfffffff8,-0xc(%ebp) + goto bad_elf_cleanup_pgdir; +c010a261: e9 b4 05 00 00 jmp c010a81a + } + + uint32_t vm_flags, perm; + struct proghdr *ph_end = ph + elf->e_phnum; +c010a266: 8b 45 cc mov -0x34(%ebp),%eax +c010a269: 0f b7 40 2c movzwl 0x2c(%eax),%eax +c010a26d: c1 e0 05 shl $0x5,%eax +c010a270: 89 c2 mov %eax,%edx +c010a272: 8b 45 ec mov -0x14(%ebp),%eax +c010a275: 01 d0 add %edx,%eax +c010a277: 89 45 c8 mov %eax,-0x38(%ebp) + for (; ph < ph_end; ph ++) { +c010a27a: e9 01 03 00 00 jmp c010a580 + //(3.4) find every program section headers + // (3.4) 查找每一个程序段头 + if (ph->p_type != ELF_PT_LOAD) { +c010a27f: 8b 45 ec mov -0x14(%ebp),%eax +c010a282: 8b 00 mov (%eax),%eax +c010a284: 83 f8 01 cmp $0x1,%eax +c010a287: 0f 85 e8 02 00 00 jne c010a575 + continue ; + } + if (ph->p_filesz > ph->p_memsz) { +c010a28d: 8b 45 ec mov -0x14(%ebp),%eax +c010a290: 8b 50 10 mov 0x10(%eax),%edx +c010a293: 8b 45 ec mov -0x14(%ebp),%eax +c010a296: 8b 40 14 mov 0x14(%eax),%eax +c010a299: 39 c2 cmp %eax,%edx +c010a29b: 76 0c jbe c010a2a9 + ret = -E_INVAL_ELF; +c010a29d: c7 45 f4 f8 ff ff ff movl $0xfffffff8,-0xc(%ebp) + goto bad_cleanup_mmap; +c010a2a4: e9 66 05 00 00 jmp c010a80f + } + if (ph->p_filesz == 0) { +c010a2a9: 8b 45 ec mov -0x14(%ebp),%eax +c010a2ac: 8b 40 10 mov 0x10(%eax),%eax +c010a2af: 85 c0 test %eax,%eax +c010a2b1: 0f 84 c1 02 00 00 je c010a578 + continue ; + } + //(3.5) call mm_map fun to setup the new vma ( ph->p_va, ph->p_memsz) + // (3.5) 调用 mm_map 函数设置新的 VMA (ph->p_va, ph->p_memsz) + vm_flags = 0, perm = PTE_U; +c010a2b7: c7 45 e8 00 00 00 00 movl $0x0,-0x18(%ebp) +c010a2be: c7 45 e4 04 00 00 00 movl $0x4,-0x1c(%ebp) + if (ph->p_flags & ELF_PF_X) vm_flags |= VM_EXEC; +c010a2c5: 8b 45 ec mov -0x14(%ebp),%eax +c010a2c8: 8b 40 18 mov 0x18(%eax),%eax +c010a2cb: 83 e0 01 and $0x1,%eax +c010a2ce: 85 c0 test %eax,%eax +c010a2d0: 74 04 je c010a2d6 +c010a2d2: 83 4d e8 04 orl $0x4,-0x18(%ebp) + if (ph->p_flags & ELF_PF_W) vm_flags |= VM_WRITE; +c010a2d6: 8b 45 ec mov -0x14(%ebp),%eax +c010a2d9: 8b 40 18 mov 0x18(%eax),%eax +c010a2dc: 83 e0 02 and $0x2,%eax +c010a2df: 85 c0 test %eax,%eax +c010a2e1: 74 04 je c010a2e7 +c010a2e3: 83 4d e8 02 orl $0x2,-0x18(%ebp) + if (ph->p_flags & ELF_PF_R) vm_flags |= VM_READ; +c010a2e7: 8b 45 ec mov -0x14(%ebp),%eax +c010a2ea: 8b 40 18 mov 0x18(%eax),%eax +c010a2ed: 83 e0 04 and $0x4,%eax +c010a2f0: 85 c0 test %eax,%eax +c010a2f2: 74 04 je c010a2f8 +c010a2f4: 83 4d e8 01 orl $0x1,-0x18(%ebp) + if (vm_flags & VM_WRITE) perm |= PTE_W; +c010a2f8: 8b 45 e8 mov -0x18(%ebp),%eax +c010a2fb: 83 e0 02 and $0x2,%eax +c010a2fe: 85 c0 test %eax,%eax +c010a300: 74 04 je c010a306 +c010a302: 83 4d e4 02 orl $0x2,-0x1c(%ebp) + if ((ret = mm_map(mm, ph->p_va, ph->p_memsz, vm_flags, NULL)) != 0) { +c010a306: 8b 45 ec mov -0x14(%ebp),%eax +c010a309: 8b 50 14 mov 0x14(%eax),%edx +c010a30c: 8b 45 ec mov -0x14(%ebp),%eax +c010a30f: 8b 40 08 mov 0x8(%eax),%eax +c010a312: c7 44 24 10 00 00 00 movl $0x0,0x10(%esp) +c010a319: 00 +c010a31a: 8b 4d e8 mov -0x18(%ebp),%ecx +c010a31d: 89 4c 24 0c mov %ecx,0xc(%esp) +c010a321: 89 54 24 08 mov %edx,0x8(%esp) +c010a325: 89 44 24 04 mov %eax,0x4(%esp) +c010a329: 8b 45 d0 mov -0x30(%ebp),%eax +c010a32c: 89 04 24 mov %eax,(%esp) +c010a32f: e8 5e e0 ff ff call c0108392 +c010a334: 89 45 f4 mov %eax,-0xc(%ebp) +c010a337: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c010a33b: 0f 85 c4 04 00 00 jne c010a805 + goto bad_cleanup_mmap; + } + unsigned char *from = binary + ph->p_offset; +c010a341: 8b 45 ec mov -0x14(%ebp),%eax +c010a344: 8b 50 04 mov 0x4(%eax),%edx +c010a347: 8b 45 08 mov 0x8(%ebp),%eax +c010a34a: 01 d0 add %edx,%eax +c010a34c: 89 45 e0 mov %eax,-0x20(%ebp) + size_t off, size; + uintptr_t start = ph->p_va, end, la = ROUNDDOWN(start, PGSIZE); +c010a34f: 8b 45 ec mov -0x14(%ebp),%eax +c010a352: 8b 40 08 mov 0x8(%eax),%eax +c010a355: 89 45 d8 mov %eax,-0x28(%ebp) +c010a358: 8b 45 d8 mov -0x28(%ebp),%eax +c010a35b: 89 45 b8 mov %eax,-0x48(%ebp) +c010a35e: 8b 45 b8 mov -0x48(%ebp),%eax +c010a361: 25 00 f0 ff ff and $0xfffff000,%eax +c010a366: 89 45 d4 mov %eax,-0x2c(%ebp) + + ret = -E_NO_MEM; +c010a369: c7 45 f4 fc ff ff ff movl $0xfffffffc,-0xc(%ebp) + + //(3.6) alloc memory, and copy the contents of every program section (from, from+end) to process's memory (la, la+end) + // (3.6) 分配内存,并将每个程序段的内容 (from, from+end) 复制到进程的内存 (la, la+end) + end = ph->p_va + ph->p_filesz; +c010a370: 8b 45 ec mov -0x14(%ebp),%eax +c010a373: 8b 50 08 mov 0x8(%eax),%edx +c010a376: 8b 45 ec mov -0x14(%ebp),%eax +c010a379: 8b 40 10 mov 0x10(%eax),%eax +c010a37c: 01 d0 add %edx,%eax +c010a37e: 89 45 b4 mov %eax,-0x4c(%ebp) + //(3.6.1) copy TEXT/DATA section of bianry program + // (3.6.1) 复制二进制程序的 TEXT/DATA 段 + while (start < end) { +c010a381: e9 87 00 00 00 jmp c010a40d + if ((page = pgdir_alloc_page(mm->pgdir, la, perm)) == NULL) { +c010a386: 8b 45 d0 mov -0x30(%ebp),%eax +c010a389: 8b 40 0c mov 0xc(%eax),%eax +c010a38c: 8b 55 e4 mov -0x1c(%ebp),%edx +c010a38f: 89 54 24 08 mov %edx,0x8(%esp) +c010a393: 8b 55 d4 mov -0x2c(%ebp),%edx +c010a396: 89 54 24 04 mov %edx,0x4(%esp) +c010a39a: 89 04 24 mov %eax,(%esp) +c010a39d: e8 1b bc ff ff call c0105fbd +c010a3a2: 89 45 f0 mov %eax,-0x10(%ebp) +c010a3a5: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) +c010a3a9: 0f 84 59 04 00 00 je c010a808 + goto bad_cleanup_mmap; + } + off = start - la, size = PGSIZE - off, la += PGSIZE; +c010a3af: 8b 45 d8 mov -0x28(%ebp),%eax +c010a3b2: 2b 45 d4 sub -0x2c(%ebp),%eax +c010a3b5: 89 45 b0 mov %eax,-0x50(%ebp) +c010a3b8: b8 00 10 00 00 mov $0x1000,%eax +c010a3bd: 2b 45 b0 sub -0x50(%ebp),%eax +c010a3c0: 89 45 dc mov %eax,-0x24(%ebp) +c010a3c3: 81 45 d4 00 10 00 00 addl $0x1000,-0x2c(%ebp) + if (end < la) { +c010a3ca: 8b 45 b4 mov -0x4c(%ebp),%eax +c010a3cd: 3b 45 d4 cmp -0x2c(%ebp),%eax +c010a3d0: 73 09 jae c010a3db + size -= la - end; +c010a3d2: 8b 45 b4 mov -0x4c(%ebp),%eax +c010a3d5: 2b 45 d4 sub -0x2c(%ebp),%eax +c010a3d8: 01 45 dc add %eax,-0x24(%ebp) + } + memcpy(page2kva(page) + off, from, size); +c010a3db: 8b 45 f0 mov -0x10(%ebp),%eax +c010a3de: 89 04 24 mov %eax,(%esp) +c010a3e1: e8 d4 f0 ff ff call c01094ba +c010a3e6: 8b 55 b0 mov -0x50(%ebp),%edx +c010a3e9: 01 c2 add %eax,%edx +c010a3eb: 8b 45 dc mov -0x24(%ebp),%eax +c010a3ee: 89 44 24 08 mov %eax,0x8(%esp) +c010a3f2: 8b 45 e0 mov -0x20(%ebp),%eax +c010a3f5: 89 44 24 04 mov %eax,0x4(%esp) +c010a3f9: 89 14 24 mov %edx,(%esp) +c010a3fc: e8 d5 1a 00 00 call c010bed6 + start += size, from += size; +c010a401: 8b 45 dc mov -0x24(%ebp),%eax +c010a404: 01 45 d8 add %eax,-0x28(%ebp) +c010a407: 8b 45 dc mov -0x24(%ebp),%eax +c010a40a: 01 45 e0 add %eax,-0x20(%ebp) + while (start < end) { +c010a40d: 8b 45 d8 mov -0x28(%ebp),%eax +c010a410: 3b 45 b4 cmp -0x4c(%ebp),%eax +c010a413: 0f 82 6d ff ff ff jb c010a386 + } + + //(3.6.2) build BSS section of binary program + // (3.6.2) 构建二进制程序的 BSS 段 + end = ph->p_va + ph->p_memsz; +c010a419: 8b 45 ec mov -0x14(%ebp),%eax +c010a41c: 8b 50 08 mov 0x8(%eax),%edx +c010a41f: 8b 45 ec mov -0x14(%ebp),%eax +c010a422: 8b 40 14 mov 0x14(%eax),%eax +c010a425: 01 d0 add %edx,%eax +c010a427: 89 45 b4 mov %eax,-0x4c(%ebp) + if (start < la) { +c010a42a: 8b 45 d8 mov -0x28(%ebp),%eax +c010a42d: 3b 45 d4 cmp -0x2c(%ebp),%eax +c010a430: 0f 83 31 01 00 00 jae c010a567 + /* ph->p_memsz == ph->p_filesz */ + if (start == end) { +c010a436: 8b 45 d8 mov -0x28(%ebp),%eax +c010a439: 3b 45 b4 cmp -0x4c(%ebp),%eax +c010a43c: 0f 84 39 01 00 00 je c010a57b + continue ; + } + off = start + PGSIZE - la, size = PGSIZE - off; +c010a442: 8b 45 d8 mov -0x28(%ebp),%eax +c010a445: 2b 45 d4 sub -0x2c(%ebp),%eax +c010a448: 05 00 10 00 00 add $0x1000,%eax +c010a44d: 89 45 b0 mov %eax,-0x50(%ebp) +c010a450: b8 00 10 00 00 mov $0x1000,%eax +c010a455: 2b 45 b0 sub -0x50(%ebp),%eax +c010a458: 89 45 dc mov %eax,-0x24(%ebp) + if (end < la) { +c010a45b: 8b 45 b4 mov -0x4c(%ebp),%eax +c010a45e: 3b 45 d4 cmp -0x2c(%ebp),%eax +c010a461: 73 09 jae c010a46c + size -= la - end; +c010a463: 8b 45 b4 mov -0x4c(%ebp),%eax +c010a466: 2b 45 d4 sub -0x2c(%ebp),%eax +c010a469: 01 45 dc add %eax,-0x24(%ebp) + } + memset(page2kva(page) + off, 0, size); +c010a46c: 8b 45 f0 mov -0x10(%ebp),%eax +c010a46f: 89 04 24 mov %eax,(%esp) +c010a472: e8 43 f0 ff ff call c01094ba +c010a477: 8b 55 b0 mov -0x50(%ebp),%edx +c010a47a: 01 c2 add %eax,%edx +c010a47c: 8b 45 dc mov -0x24(%ebp),%eax +c010a47f: 89 44 24 08 mov %eax,0x8(%esp) +c010a483: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) +c010a48a: 00 +c010a48b: 89 14 24 mov %edx,(%esp) +c010a48e: e8 5e 19 00 00 call c010bdf1 + start += size; +c010a493: 8b 45 dc mov -0x24(%ebp),%eax +c010a496: 01 45 d8 add %eax,-0x28(%ebp) + assert((end < la && start == end) || (end >= la && start == la)); +c010a499: 8b 45 b4 mov -0x4c(%ebp),%eax +c010a49c: 3b 45 d4 cmp -0x2c(%ebp),%eax +c010a49f: 73 0c jae c010a4ad +c010a4a1: 8b 45 d8 mov -0x28(%ebp),%eax +c010a4a4: 3b 45 b4 cmp -0x4c(%ebp),%eax +c010a4a7: 0f 84 ba 00 00 00 je c010a567 +c010a4ad: 8b 45 b4 mov -0x4c(%ebp),%eax +c010a4b0: 3b 45 d4 cmp -0x2c(%ebp),%eax +c010a4b3: 72 0c jb c010a4c1 +c010a4b5: 8b 45 d8 mov -0x28(%ebp),%eax +c010a4b8: 3b 45 d4 cmp -0x2c(%ebp),%eax +c010a4bb: 0f 84 a6 00 00 00 je c010a567 +c010a4c1: c7 44 24 0c 48 e1 10 movl $0xc010e148,0xc(%esp) +c010a4c8: c0 +c010a4c9: c7 44 24 08 c9 e0 10 movl $0xc010e0c9,0x8(%esp) +c010a4d0: c0 +c010a4d1: c7 44 24 04 0c 03 00 movl $0x30c,0x4(%esp) +c010a4d8: 00 +c010a4d9: c7 04 24 9c e0 10 c0 movl $0xc010e09c,(%esp) +c010a4e0: e8 56 68 ff ff call c0100d3b <__panic> + } + while (start < end) { + if ((page = pgdir_alloc_page(mm->pgdir, la, perm)) == NULL) { +c010a4e5: 8b 45 d0 mov -0x30(%ebp),%eax +c010a4e8: 8b 40 0c mov 0xc(%eax),%eax +c010a4eb: 8b 55 e4 mov -0x1c(%ebp),%edx +c010a4ee: 89 54 24 08 mov %edx,0x8(%esp) +c010a4f2: 8b 55 d4 mov -0x2c(%ebp),%edx +c010a4f5: 89 54 24 04 mov %edx,0x4(%esp) +c010a4f9: 89 04 24 mov %eax,(%esp) +c010a4fc: e8 bc ba ff ff call c0105fbd +c010a501: 89 45 f0 mov %eax,-0x10(%ebp) +c010a504: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) +c010a508: 0f 84 fd 02 00 00 je c010a80b + goto bad_cleanup_mmap; + } + off = start - la, size = PGSIZE - off, la += PGSIZE; +c010a50e: 8b 45 d8 mov -0x28(%ebp),%eax +c010a511: 2b 45 d4 sub -0x2c(%ebp),%eax +c010a514: 89 45 b0 mov %eax,-0x50(%ebp) +c010a517: b8 00 10 00 00 mov $0x1000,%eax +c010a51c: 2b 45 b0 sub -0x50(%ebp),%eax +c010a51f: 89 45 dc mov %eax,-0x24(%ebp) +c010a522: 81 45 d4 00 10 00 00 addl $0x1000,-0x2c(%ebp) + if (end < la) { +c010a529: 8b 45 b4 mov -0x4c(%ebp),%eax +c010a52c: 3b 45 d4 cmp -0x2c(%ebp),%eax +c010a52f: 73 09 jae c010a53a + size -= la - end; +c010a531: 8b 45 b4 mov -0x4c(%ebp),%eax +c010a534: 2b 45 d4 sub -0x2c(%ebp),%eax +c010a537: 01 45 dc add %eax,-0x24(%ebp) + } + memset(page2kva(page) + off, 0, size); +c010a53a: 8b 45 f0 mov -0x10(%ebp),%eax +c010a53d: 89 04 24 mov %eax,(%esp) +c010a540: e8 75 ef ff ff call c01094ba +c010a545: 8b 55 b0 mov -0x50(%ebp),%edx +c010a548: 01 c2 add %eax,%edx +c010a54a: 8b 45 dc mov -0x24(%ebp),%eax +c010a54d: 89 44 24 08 mov %eax,0x8(%esp) +c010a551: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) +c010a558: 00 +c010a559: 89 14 24 mov %edx,(%esp) +c010a55c: e8 90 18 00 00 call c010bdf1 + start += size; +c010a561: 8b 45 dc mov -0x24(%ebp),%eax +c010a564: 01 45 d8 add %eax,-0x28(%ebp) + while (start < end) { +c010a567: 8b 45 d8 mov -0x28(%ebp),%eax +c010a56a: 3b 45 b4 cmp -0x4c(%ebp),%eax +c010a56d: 0f 82 72 ff ff ff jb c010a4e5 +c010a573: eb 07 jmp c010a57c + continue ; +c010a575: 90 nop +c010a576: eb 04 jmp c010a57c + continue ; +c010a578: 90 nop +c010a579: eb 01 jmp c010a57c + continue ; +c010a57b: 90 nop + for (; ph < ph_end; ph ++) { +c010a57c: 83 45 ec 20 addl $0x20,-0x14(%ebp) +c010a580: 8b 45 ec mov -0x14(%ebp),%eax +c010a583: 3b 45 c8 cmp -0x38(%ebp),%eax +c010a586: 0f 82 f3 fc ff ff jb c010a27f + } + } + //(4) build user stack memory + // (4) 构建用户栈内存 + vm_flags = VM_READ | VM_WRITE | VM_STACK; +c010a58c: c7 45 e8 0b 00 00 00 movl $0xb,-0x18(%ebp) + if ((ret = mm_map(mm, USTACKTOP - USTACKSIZE, USTACKSIZE, vm_flags, NULL)) != 0) { +c010a593: c7 44 24 10 00 00 00 movl $0x0,0x10(%esp) +c010a59a: 00 +c010a59b: 8b 45 e8 mov -0x18(%ebp),%eax +c010a59e: 89 44 24 0c mov %eax,0xc(%esp) +c010a5a2: c7 44 24 08 00 00 10 movl $0x100000,0x8(%esp) +c010a5a9: 00 +c010a5aa: c7 44 24 04 00 00 f0 movl $0xaff00000,0x4(%esp) +c010a5b1: af +c010a5b2: 8b 45 d0 mov -0x30(%ebp),%eax +c010a5b5: 89 04 24 mov %eax,(%esp) +c010a5b8: e8 d5 dd ff ff call c0108392 +c010a5bd: 89 45 f4 mov %eax,-0xc(%ebp) +c010a5c0: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c010a5c4: 0f 85 44 02 00 00 jne c010a80e + goto bad_cleanup_mmap; + } + assert(pgdir_alloc_page(mm->pgdir, USTACKTOP-PGSIZE , PTE_USER) != NULL); +c010a5ca: 8b 45 d0 mov -0x30(%ebp),%eax +c010a5cd: 8b 40 0c mov 0xc(%eax),%eax +c010a5d0: c7 44 24 08 07 00 00 movl $0x7,0x8(%esp) +c010a5d7: 00 +c010a5d8: c7 44 24 04 00 f0 ff movl $0xaffff000,0x4(%esp) +c010a5df: af +c010a5e0: 89 04 24 mov %eax,(%esp) +c010a5e3: e8 d5 b9 ff ff call c0105fbd +c010a5e8: 85 c0 test %eax,%eax +c010a5ea: 75 24 jne c010a610 +c010a5ec: c7 44 24 0c 84 e1 10 movl $0xc010e184,0xc(%esp) +c010a5f3: c0 +c010a5f4: c7 44 24 08 c9 e0 10 movl $0xc010e0c9,0x8(%esp) +c010a5fb: c0 +c010a5fc: c7 44 24 04 20 03 00 movl $0x320,0x4(%esp) +c010a603: 00 +c010a604: c7 04 24 9c e0 10 c0 movl $0xc010e09c,(%esp) +c010a60b: e8 2b 67 ff ff call c0100d3b <__panic> + assert(pgdir_alloc_page(mm->pgdir, USTACKTOP-2*PGSIZE , PTE_USER) != NULL); +c010a610: 8b 45 d0 mov -0x30(%ebp),%eax +c010a613: 8b 40 0c mov 0xc(%eax),%eax +c010a616: c7 44 24 08 07 00 00 movl $0x7,0x8(%esp) +c010a61d: 00 +c010a61e: c7 44 24 04 00 e0 ff movl $0xafffe000,0x4(%esp) +c010a625: af +c010a626: 89 04 24 mov %eax,(%esp) +c010a629: e8 8f b9 ff ff call c0105fbd +c010a62e: 85 c0 test %eax,%eax +c010a630: 75 24 jne c010a656 +c010a632: c7 44 24 0c c8 e1 10 movl $0xc010e1c8,0xc(%esp) +c010a639: c0 +c010a63a: c7 44 24 08 c9 e0 10 movl $0xc010e0c9,0x8(%esp) +c010a641: c0 +c010a642: c7 44 24 04 21 03 00 movl $0x321,0x4(%esp) +c010a649: 00 +c010a64a: c7 04 24 9c e0 10 c0 movl $0xc010e09c,(%esp) +c010a651: e8 e5 66 ff ff call c0100d3b <__panic> + assert(pgdir_alloc_page(mm->pgdir, USTACKTOP-3*PGSIZE , PTE_USER) != NULL); +c010a656: 8b 45 d0 mov -0x30(%ebp),%eax +c010a659: 8b 40 0c mov 0xc(%eax),%eax +c010a65c: c7 44 24 08 07 00 00 movl $0x7,0x8(%esp) +c010a663: 00 +c010a664: c7 44 24 04 00 d0 ff movl $0xafffd000,0x4(%esp) +c010a66b: af +c010a66c: 89 04 24 mov %eax,(%esp) +c010a66f: e8 49 b9 ff ff call c0105fbd +c010a674: 85 c0 test %eax,%eax +c010a676: 75 24 jne c010a69c +c010a678: c7 44 24 0c 0c e2 10 movl $0xc010e20c,0xc(%esp) +c010a67f: c0 +c010a680: c7 44 24 08 c9 e0 10 movl $0xc010e0c9,0x8(%esp) +c010a687: c0 +c010a688: c7 44 24 04 22 03 00 movl $0x322,0x4(%esp) +c010a68f: 00 +c010a690: c7 04 24 9c e0 10 c0 movl $0xc010e09c,(%esp) +c010a697: e8 9f 66 ff ff call c0100d3b <__panic> + assert(pgdir_alloc_page(mm->pgdir, USTACKTOP-4*PGSIZE , PTE_USER) != NULL); +c010a69c: 8b 45 d0 mov -0x30(%ebp),%eax +c010a69f: 8b 40 0c mov 0xc(%eax),%eax +c010a6a2: c7 44 24 08 07 00 00 movl $0x7,0x8(%esp) +c010a6a9: 00 +c010a6aa: c7 44 24 04 00 c0 ff movl $0xafffc000,0x4(%esp) +c010a6b1: af +c010a6b2: 89 04 24 mov %eax,(%esp) +c010a6b5: e8 03 b9 ff ff call c0105fbd +c010a6ba: 85 c0 test %eax,%eax +c010a6bc: 75 24 jne c010a6e2 +c010a6be: c7 44 24 0c 50 e2 10 movl $0xc010e250,0xc(%esp) +c010a6c5: c0 +c010a6c6: c7 44 24 08 c9 e0 10 movl $0xc010e0c9,0x8(%esp) +c010a6cd: c0 +c010a6ce: c7 44 24 04 23 03 00 movl $0x323,0x4(%esp) +c010a6d5: 00 +c010a6d6: c7 04 24 9c e0 10 c0 movl $0xc010e09c,(%esp) +c010a6dd: e8 59 66 ff ff call c0100d3b <__panic> + + //(5) set current process's mm, sr3, and set CR3 reg = physical addr of Page Directory + // (5) 设置当前进程的 mm、sr3,并将 CR3 寄存器设置为页目录的物理地址 + mm_count_inc(mm); +c010a6e2: 8b 45 d0 mov -0x30(%ebp),%eax +c010a6e5: 89 04 24 mov %eax,(%esp) +c010a6e8: e8 6f ee ff ff call c010955c + current->mm = mm; +c010a6ed: a1 30 41 1a c0 mov 0xc01a4130,%eax +c010a6f2: 8b 55 d0 mov -0x30(%ebp),%edx +c010a6f5: 89 50 18 mov %edx,0x18(%eax) + current->cr3 = PADDR(mm->pgdir); +c010a6f8: 8b 45 d0 mov -0x30(%ebp),%eax +c010a6fb: 8b 40 0c mov 0xc(%eax),%eax +c010a6fe: 89 45 c4 mov %eax,-0x3c(%ebp) +c010a701: 81 7d c4 ff ff ff bf cmpl $0xbfffffff,-0x3c(%ebp) +c010a708: 77 23 ja c010a72d +c010a70a: 8b 45 c4 mov -0x3c(%ebp),%eax +c010a70d: 89 44 24 0c mov %eax,0xc(%esp) +c010a711: c7 44 24 08 78 e0 10 movl $0xc010e078,0x8(%esp) +c010a718: c0 +c010a719: c7 44 24 04 29 03 00 movl $0x329,0x4(%esp) +c010a720: 00 +c010a721: c7 04 24 9c e0 10 c0 movl $0xc010e09c,(%esp) +c010a728: e8 0e 66 ff ff call c0100d3b <__panic> +c010a72d: 8b 45 c4 mov -0x3c(%ebp),%eax +c010a730: 8d 90 00 00 00 40 lea 0x40000000(%eax),%edx +c010a736: a1 30 41 1a c0 mov 0xc01a4130,%eax +c010a73b: 89 50 40 mov %edx,0x40(%eax) + lcr3(PADDR(mm->pgdir)); +c010a73e: 8b 45 d0 mov -0x30(%ebp),%eax +c010a741: 8b 40 0c mov 0xc(%eax),%eax +c010a744: 89 45 c0 mov %eax,-0x40(%ebp) +c010a747: 81 7d c0 ff ff ff bf cmpl $0xbfffffff,-0x40(%ebp) +c010a74e: 77 23 ja c010a773 +c010a750: 8b 45 c0 mov -0x40(%ebp),%eax +c010a753: 89 44 24 0c mov %eax,0xc(%esp) +c010a757: c7 44 24 08 78 e0 10 movl $0xc010e078,0x8(%esp) +c010a75e: c0 +c010a75f: c7 44 24 04 2a 03 00 movl $0x32a,0x4(%esp) +c010a766: 00 +c010a767: c7 04 24 9c e0 10 c0 movl $0xc010e09c,(%esp) +c010a76e: e8 c8 65 ff ff call c0100d3b <__panic> +c010a773: 8b 45 c0 mov -0x40(%ebp),%eax +c010a776: 05 00 00 00 40 add $0x40000000,%eax +c010a77b: 89 45 ac mov %eax,-0x54(%ebp) + asm volatile ("mov %0, %%cr3" :: "r" (cr3) : "memory"); +c010a77e: 8b 45 ac mov -0x54(%ebp),%eax +c010a781: 0f 22 d8 mov %eax,%cr3 +} +c010a784: 90 nop + + //(6) setup trapframe for user environment + // (6) 为用户环境设置陷阱帧 (trapframe) + struct trapframe *tf = current->tf; +c010a785: a1 30 41 1a c0 mov 0xc01a4130,%eax +c010a78a: 8b 40 3c mov 0x3c(%eax),%eax +c010a78d: 89 45 bc mov %eax,-0x44(%ebp) + memset(tf, 0, sizeof(struct trapframe)); +c010a790: c7 44 24 08 4c 00 00 movl $0x4c,0x8(%esp) +c010a797: 00 +c010a798: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) +c010a79f: 00 +c010a7a0: 8b 45 bc mov -0x44(%ebp),%eax +c010a7a3: 89 04 24 mov %eax,(%esp) +c010a7a6: e8 46 16 00 00 call c010bdf1 + * tf_ds=tf_es=tf_ss should be USER_DS segment + * tf_esp should be the top addr of user stack (USTACKTOP) + * tf_eip should be the entry point of this binary program (elf->e_entry) + * tf_eflags should be set to enable computer to produce Interrupt + */ + tf->tf_cs = USER_CS; +c010a7ab: 8b 45 bc mov -0x44(%ebp),%eax +c010a7ae: 66 c7 40 3c 1b 00 movw $0x1b,0x3c(%eax) + tf->tf_ds = tf->tf_es = tf->tf_ss = USER_DS; +c010a7b4: 8b 45 bc mov -0x44(%ebp),%eax +c010a7b7: 66 c7 40 48 23 00 movw $0x23,0x48(%eax) +c010a7bd: 8b 45 bc mov -0x44(%ebp),%eax +c010a7c0: 0f b7 50 48 movzwl 0x48(%eax),%edx +c010a7c4: 8b 45 bc mov -0x44(%ebp),%eax +c010a7c7: 66 89 50 28 mov %dx,0x28(%eax) +c010a7cb: 8b 45 bc mov -0x44(%ebp),%eax +c010a7ce: 0f b7 50 28 movzwl 0x28(%eax),%edx +c010a7d2: 8b 45 bc mov -0x44(%ebp),%eax +c010a7d5: 66 89 50 2c mov %dx,0x2c(%eax) + tf->tf_esp = USTACKTOP; +c010a7d9: 8b 45 bc mov -0x44(%ebp),%eax +c010a7dc: c7 40 44 00 00 00 b0 movl $0xb0000000,0x44(%eax) + tf->tf_eip = elf->e_entry; +c010a7e3: 8b 45 cc mov -0x34(%ebp),%eax +c010a7e6: 8b 50 18 mov 0x18(%eax),%edx +c010a7e9: 8b 45 bc mov -0x44(%ebp),%eax +c010a7ec: 89 50 38 mov %edx,0x38(%eax) + tf->tf_eflags = FL_IF; +c010a7ef: 8b 45 bc mov -0x44(%ebp),%eax +c010a7f2: c7 40 40 00 02 00 00 movl $0x200,0x40(%eax) + ret = 0; +c010a7f9: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) +out: + return ret; +c010a800: 8b 45 f4 mov -0xc(%ebp),%eax +c010a803: eb 33 jmp c010a838 + goto bad_cleanup_mmap; +c010a805: 90 nop +c010a806: eb 07 jmp c010a80f + goto bad_cleanup_mmap; +c010a808: 90 nop +c010a809: eb 04 jmp c010a80f + goto bad_cleanup_mmap; +c010a80b: 90 nop +c010a80c: eb 01 jmp c010a80f + goto bad_cleanup_mmap; +c010a80e: 90 nop +bad_cleanup_mmap: + exit_mmap(mm); +c010a80f: 8b 45 d0 mov -0x30(%ebp),%eax +c010a812: 89 04 24 mov %eax,(%esp) +c010a815: e8 93 dd ff ff call c01085ad +bad_elf_cleanup_pgdir: + put_pgdir(mm); +c010a81a: 8b 45 d0 mov -0x30(%ebp),%eax +c010a81d: 89 04 24 mov %eax,(%esp) +c010a820: e8 94 f4 ff ff call c0109cb9 +c010a825: eb 01 jmp c010a828 + goto bad_pgdir_cleanup_mm; +c010a827: 90 nop +bad_pgdir_cleanup_mm: + mm_destroy(mm); +c010a828: 8b 45 d0 mov -0x30(%ebp),%eax +c010a82b: 89 04 24 mov %eax,(%esp) +c010a82e: e8 eb da ff ff call c010831e +bad_mm: + goto out; +c010a833: eb cb jmp c010a800 + goto bad_mm; +c010a835: 90 nop + goto out; +c010a836: eb c8 jmp c010a800 +} +c010a838: 89 ec mov %ebp,%esp +c010a83a: 5d pop %ebp +c010a83b: c3 ret + +c010a83c : + * 如果加载过程中发生错误,函数将终止当前进程 + * + * @return 成功时返回0,失败时返回错误码 + */ +int +do_execve(const char *name, size_t len, unsigned char *binary, size_t size) { +c010a83c: 55 push %ebp +c010a83d: 89 e5 mov %esp,%ebp +c010a83f: 83 ec 38 sub $0x38,%esp + // 获取当前进程的内存管理结构 + struct mm_struct *mm = current->mm; +c010a842: a1 30 41 1a c0 mov 0xc01a4130,%eax +c010a847: 8b 40 18 mov 0x18(%eax),%eax +c010a84a: 89 45 f4 mov %eax,-0xc(%ebp) + + // 检查程序名称是否在用户空间中有效 + if (!user_mem_check(mm, (uintptr_t)name, len, 0)) { +c010a84d: 8b 45 08 mov 0x8(%ebp),%eax +c010a850: c7 44 24 0c 00 00 00 movl $0x0,0xc(%esp) +c010a857: 00 +c010a858: 8b 55 0c mov 0xc(%ebp),%edx +c010a85b: 89 54 24 08 mov %edx,0x8(%esp) +c010a85f: 89 44 24 04 mov %eax,0x4(%esp) +c010a863: 8b 45 f4 mov -0xc(%ebp),%eax +c010a866: 89 04 24 mov %eax,(%esp) +c010a869: e8 ec e7 ff ff call c010905a +c010a86e: 85 c0 test %eax,%eax +c010a870: 75 0a jne c010a87c + return -E_INVAL; +c010a872: b8 fd ff ff ff mov $0xfffffffd,%eax +c010a877: e9 f7 00 00 00 jmp c010a973 + } + + // 如果程序名称过长,截断到最大长度 + if (len > PROC_NAME_LEN) { +c010a87c: 83 7d 0c 0f cmpl $0xf,0xc(%ebp) +c010a880: 76 07 jbe c010a889 + len = PROC_NAME_LEN; +c010a882: c7 45 0c 0f 00 00 00 movl $0xf,0xc(%ebp) + } + + // 准备一个本地缓冲区,用于存储程序名称 + char local_name[PROC_NAME_LEN + 1]; + memset(local_name, 0, sizeof(local_name)); +c010a889: c7 44 24 08 10 00 00 movl $0x10,0x8(%esp) +c010a890: 00 +c010a891: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) +c010a898: 00 +c010a899: 8d 45 dc lea -0x24(%ebp),%eax +c010a89c: 89 04 24 mov %eax,(%esp) +c010a89f: e8 4d 15 00 00 call c010bdf1 + memcpy(local_name, name, len); +c010a8a4: 8b 45 0c mov 0xc(%ebp),%eax +c010a8a7: 89 44 24 08 mov %eax,0x8(%esp) +c010a8ab: 8b 45 08 mov 0x8(%ebp),%eax +c010a8ae: 89 44 24 04 mov %eax,0x4(%esp) +c010a8b2: 8d 45 dc lea -0x24(%ebp),%eax +c010a8b5: 89 04 24 mov %eax,(%esp) +c010a8b8: e8 19 16 00 00 call c010bed6 + + // 如果当前进程已有内存管理结构,进行清理 + if (mm != NULL) { +c010a8bd: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c010a8c1: 74 4b je c010a90e + // 切换到引导页表,准备清理当前进程的地址空间 + lcr3(boot_cr3); +c010a8c3: a1 a8 3f 1a c0 mov 0xc01a3fa8,%eax +c010a8c8: 89 45 ec mov %eax,-0x14(%ebp) + asm volatile ("mov %0, %%cr3" :: "r" (cr3) : "memory"); +c010a8cb: 8b 45 ec mov -0x14(%ebp),%eax +c010a8ce: 0f 22 d8 mov %eax,%cr3 +} +c010a8d1: 90 nop + + // 减少内存管理结构的引用计数,如果为0则进行清理 + if (mm_count_dec(mm) == 0) { +c010a8d2: 8b 45 f4 mov -0xc(%ebp),%eax +c010a8d5: 89 04 24 mov %eax,(%esp) +c010a8d8: e8 99 ec ff ff call c0109576 +c010a8dd: 85 c0 test %eax,%eax +c010a8df: 75 21 jne c010a902 + exit_mmap(mm); +c010a8e1: 8b 45 f4 mov -0xc(%ebp),%eax +c010a8e4: 89 04 24 mov %eax,(%esp) +c010a8e7: e8 c1 dc ff ff call c01085ad + put_pgdir(mm); +c010a8ec: 8b 45 f4 mov -0xc(%ebp),%eax +c010a8ef: 89 04 24 mov %eax,(%esp) +c010a8f2: e8 c2 f3 ff ff call c0109cb9 + mm_destroy(mm); +c010a8f7: 8b 45 f4 mov -0xc(%ebp),%eax +c010a8fa: 89 04 24 mov %eax,(%esp) +c010a8fd: e8 1c da ff ff call c010831e + } + // 当前进程不再有内存管理结构 + current->mm = NULL; +c010a902: a1 30 41 1a c0 mov 0xc01a4130,%eax +c010a907: c7 40 18 00 00 00 00 movl $0x0,0x18(%eax) + } + // 加载新的程序代码 + int ret; + if ((ret = load_icode(binary, size)) != 0) { +c010a90e: 8b 45 14 mov 0x14(%ebp),%eax +c010a911: 89 44 24 04 mov %eax,0x4(%esp) +c010a915: 8b 45 10 mov 0x10(%ebp),%eax +c010a918: 89 04 24 mov %eax,(%esp) +c010a91b: e8 c0 f8 ff ff call c010a1e0 +c010a920: 89 45 f0 mov %eax,-0x10(%ebp) +c010a923: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) +c010a927: 75 1b jne c010a944 + // 如果加载失败,终止当前进程 + goto execve_exit; + } + // 设置当前进程的名称为新的程序名称 + set_proc_name(current, local_name); +c010a929: a1 30 41 1a c0 mov 0xc01a4130,%eax +c010a92e: 8d 55 dc lea -0x24(%ebp),%edx +c010a931: 89 54 24 04 mov %edx,0x4(%esp) +c010a935: 89 04 24 mov %eax,(%esp) +c010a938: e8 84 ed ff ff call c01096c1 + return 0; +c010a93d: b8 00 00 00 00 mov $0x0,%eax +c010a942: eb 2f jmp c010a973 + goto execve_exit; +c010a944: 90 nop + +execve_exit: +// 加载失败时的清理工作 + do_exit(ret); +c010a945: 8b 45 f0 mov -0x10(%ebp),%eax +c010a948: 89 04 24 mov %eax,(%esp) +c010a94b: e8 c0 f6 ff ff call c010a010 + panic("already exit: %e.\n", ret); +c010a950: 8b 45 f0 mov -0x10(%ebp),%eax +c010a953: 89 44 24 0c mov %eax,0xc(%esp) +c010a957: c7 44 24 08 93 e2 10 movl $0xc010e293,0x8(%esp) +c010a95e: c0 +c010a95f: c7 44 24 04 8a 03 00 movl $0x38a,0x4(%esp) +c010a966: 00 +c010a967: c7 04 24 9c e0 10 c0 movl $0xc010e09c,(%esp) +c010a96e: e8 c8 63 ff ff call c0100d3b <__panic> +} +c010a973: 89 ec mov %ebp,%esp +c010a975: 5d pop %ebp +c010a976: c3 ret + +c010a977 : + +// do_yield - ask the scheduler to reschedule +int +do_yield(void) { +c010a977: 55 push %ebp +c010a978: 89 e5 mov %esp,%ebp + current->need_resched = 1; +c010a97a: a1 30 41 1a c0 mov 0xc01a4130,%eax +c010a97f: c7 40 10 01 00 00 00 movl $0x1,0x10(%eax) + return 0; +c010a986: b8 00 00 00 00 mov $0x0,%eax +} +c010a98b: 5d pop %ebp +c010a98c: c3 ret + +c010a98d : + * 它首先检查参数的有效性,然后寻找指定的子进程如果找到已终止的子进程, + * 则回收其资源并返回子进程的退出状态码如果没有找到已终止的子进程,则当前进程进入睡眠状态, + * 直到有子进程终止或者没有子进程可等待时返回错误代码 + */ +int +do_wait(int pid, int *code_store) { +c010a98d: 55 push %ebp +c010a98e: 89 e5 mov %esp,%ebp +c010a990: 83 ec 28 sub $0x28,%esp + // 获取当前进程的内存描述符 + struct mm_struct *mm = current->mm; +c010a993: a1 30 41 1a c0 mov 0xc01a4130,%eax +c010a998: 8b 40 18 mov 0x18(%eax),%eax +c010a99b: 89 45 ec mov %eax,-0x14(%ebp) + // 如果code_store不为NULL,检查其指向的用户内存区域是否有效 + if (code_store != NULL) { +c010a99e: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) +c010a9a2: 74 30 je c010a9d4 + if (!user_mem_check(mm, (uintptr_t)code_store, sizeof(int), 1)) { +c010a9a4: 8b 45 0c mov 0xc(%ebp),%eax +c010a9a7: c7 44 24 0c 01 00 00 movl $0x1,0xc(%esp) +c010a9ae: 00 +c010a9af: c7 44 24 08 04 00 00 movl $0x4,0x8(%esp) +c010a9b6: 00 +c010a9b7: 89 44 24 04 mov %eax,0x4(%esp) +c010a9bb: 8b 45 ec mov -0x14(%ebp),%eax +c010a9be: 89 04 24 mov %eax,(%esp) +c010a9c1: e8 94 e6 ff ff call c010905a +c010a9c6: 85 c0 test %eax,%eax +c010a9c8: 75 0a jne c010a9d4 + return -E_INVAL; +c010a9ca: b8 fd ff ff ff mov $0xfffffffd,%eax +c010a9cf: e9 47 01 00 00 jmp c010ab1b + } + } + // 定义指向进程结构的指针以及布尔变量用于控制流程 + struct proc_struct *proc; + bool intr_flag, haskid; +repeat: +c010a9d4: 90 nop +// 初始化haskid为0,表示尚未找到可等待的子进程 + haskid = 0; +c010a9d5: c7 45 f0 00 00 00 00 movl $0x0,-0x10(%ebp) + + // 如果pid不为0,寻找指定的子进程 + if (pid != 0) { +c010a9dc: 83 7d 08 00 cmpl $0x0,0x8(%ebp) +c010a9e0: 74 36 je c010aa18 + proc = find_proc(pid); +c010a9e2: 8b 45 08 mov 0x8(%ebp),%eax +c010a9e5: 89 04 24 mov %eax,(%esp) +c010a9e8: e8 d2 f0 ff ff call c0109abf +c010a9ed: 89 45 f4 mov %eax,-0xc(%ebp) + if (proc != NULL && proc->parent == current) { +c010a9f0: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c010a9f4: 74 4f je c010aa45 +c010a9f6: 8b 45 f4 mov -0xc(%ebp),%eax +c010a9f9: 8b 50 14 mov 0x14(%eax),%edx +c010a9fc: a1 30 41 1a c0 mov 0xc01a4130,%eax +c010aa01: 39 c2 cmp %eax,%edx +c010aa03: 75 40 jne c010aa45 + haskid = 1; +c010aa05: c7 45 f0 01 00 00 00 movl $0x1,-0x10(%ebp) + if (proc->state == PROC_ZOMBIE) { +c010aa0c: 8b 45 f4 mov -0xc(%ebp),%eax +c010aa0f: 8b 00 mov (%eax),%eax +c010aa11: 83 f8 03 cmp $0x3,%eax +c010aa14: 75 2f jne c010aa45 + goto found; +c010aa16: eb 7e jmp c010aa96 + } + } + } + // 如果pid为0,遍历所有子进程寻找已终止的子进程 + else { + proc = current->cptr; +c010aa18: a1 30 41 1a c0 mov 0xc01a4130,%eax +c010aa1d: 8b 40 70 mov 0x70(%eax),%eax +c010aa20: 89 45 f4 mov %eax,-0xc(%ebp) + for (; proc != NULL; proc = proc->optr) { +c010aa23: eb 1a jmp c010aa3f + haskid = 1; +c010aa25: c7 45 f0 01 00 00 00 movl $0x1,-0x10(%ebp) + if (proc->state == PROC_ZOMBIE) { +c010aa2c: 8b 45 f4 mov -0xc(%ebp),%eax +c010aa2f: 8b 00 mov (%eax),%eax +c010aa31: 83 f8 03 cmp $0x3,%eax +c010aa34: 74 5f je c010aa95 + for (; proc != NULL; proc = proc->optr) { +c010aa36: 8b 45 f4 mov -0xc(%ebp),%eax +c010aa39: 8b 40 78 mov 0x78(%eax),%eax +c010aa3c: 89 45 f4 mov %eax,-0xc(%ebp) +c010aa3f: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c010aa43: 75 e0 jne c010aa25 + goto found; + } + } + } + // 如果有子进程但都不是已终止状态,当前进程进入睡眠状态等待 + if (haskid) { +c010aa45: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) +c010aa49: 74 40 je c010aa8b + current->state = PROC_SLEEPING; +c010aa4b: a1 30 41 1a c0 mov 0xc01a4130,%eax +c010aa50: c7 00 01 00 00 00 movl $0x1,(%eax) + current->wait_state = WT_CHILD; +c010aa56: a1 30 41 1a c0 mov 0xc01a4130,%eax +c010aa5b: c7 40 6c 01 00 00 80 movl $0x80000001,0x6c(%eax) + schedule(); +c010aa62: e8 15 06 00 00 call c010b07c + if (current->flags & PF_EXITING) { +c010aa67: a1 30 41 1a c0 mov 0xc01a4130,%eax +c010aa6c: 8b 40 44 mov 0x44(%eax),%eax +c010aa6f: 83 e0 01 and $0x1,%eax +c010aa72: 85 c0 test %eax,%eax +c010aa74: 0f 84 5b ff ff ff je c010a9d5 + do_exit(-E_KILLED); +c010aa7a: c7 04 24 f7 ff ff ff movl $0xfffffff7,(%esp) +c010aa81: e8 8a f5 ff ff call c010a010 + } + goto repeat; +c010aa86: e9 4a ff ff ff jmp c010a9d5 + } + // 如果没有子进程可等待,返回错误代码 + return -E_BAD_PROC; +c010aa8b: b8 fe ff ff ff mov $0xfffffffe,%eax +c010aa90: e9 86 00 00 00 jmp c010ab1b + goto found; +c010aa95: 90 nop + +found: +// 确保找到的进程不是idleproc或initproc,因为它们不应该被等待 + if (proc == idleproc || proc == initproc) { +c010aa96: a1 28 41 1a c0 mov 0xc01a4128,%eax +c010aa9b: 39 45 f4 cmp %eax,-0xc(%ebp) +c010aa9e: 74 0a je c010aaaa +c010aaa0: a1 2c 41 1a c0 mov 0xc01a412c,%eax +c010aaa5: 39 45 f4 cmp %eax,-0xc(%ebp) +c010aaa8: 75 1c jne c010aac6 + panic("wait idleproc or initproc.\n"); +c010aaaa: c7 44 24 08 a6 e2 10 movl $0xc010e2a6,0x8(%esp) +c010aab1: c0 +c010aab2: c7 44 24 04 d8 03 00 movl $0x3d8,0x4(%esp) +c010aab9: 00 +c010aaba: c7 04 24 9c e0 10 c0 movl $0xc010e09c,(%esp) +c010aac1: e8 75 62 ff ff call c0100d3b <__panic> + } + // 如果需要,存储子进程的退出状态码到code_store指向的内存位置 + if (code_store != NULL) { +c010aac6: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) +c010aaca: 74 0b je c010aad7 + *code_store = proc->exit_code; +c010aacc: 8b 45 f4 mov -0xc(%ebp),%eax +c010aacf: 8b 50 68 mov 0x68(%eax),%edx +c010aad2: 8b 45 0c mov 0xc(%ebp),%eax +c010aad5: 89 10 mov %edx,(%eax) + } + // 保存中断标志并临时禁用中断,以确保操作的原子性 + local_intr_save(intr_flag); +c010aad7: e8 a4 e8 ff ff call c0109380 <__intr_save> +c010aadc: 89 45 e8 mov %eax,-0x18(%ebp) + { + // 从进程哈希表中移除进程,并移除其与其他进程的链接 + unhash_proc(proc); +c010aadf: 8b 45 f4 mov -0xc(%ebp),%eax +c010aae2: 89 04 24 mov %eax,(%esp) +c010aae5: e8 9d ef ff ff call c0109a87 + remove_links(proc); +c010aaea: 8b 45 f4 mov -0xc(%ebp),%eax +c010aaed: 89 04 24 mov %eax,(%esp) +c010aaf0: e8 fe ec ff ff call c01097f3 + } + // 恢复中断状态 + local_intr_restore(intr_flag); +c010aaf5: 8b 45 e8 mov -0x18(%ebp),%eax +c010aaf8: 89 04 24 mov %eax,(%esp) +c010aafb: e8 ac e8 ff ff call c01093ac <__intr_restore> + // 释放进程的内核栈和内存资源 + put_kstack(proc); +c010ab00: 8b 45 f4 mov -0xc(%ebp),%eax +c010ab03: 89 04 24 mov %eax,(%esp) +c010ab06: e8 dc f0 ff ff call c0109be7 + kfree(proc); +c010ab0b: 8b 45 f4 mov -0xc(%ebp),%eax +c010ab0e: 89 04 24 mov %eax,(%esp) +c010ab11: e8 f7 a1 ff ff call c0104d0d + // 成功完成等待操作,返回0 + return 0; +c010ab16: b8 00 00 00 00 mov $0x0,%eax +} +c010ab1b: 89 ec mov %ebp,%esp +c010ab1d: 5d pop %ebp +c010ab1e: c3 ret + +c010ab1f : + +// do_kill - kill process with pid by set this process's flags with PF_EXITING +int +do_kill(int pid) { +c010ab1f: 55 push %ebp +c010ab20: 89 e5 mov %esp,%ebp +c010ab22: 83 ec 28 sub $0x28,%esp + struct proc_struct *proc; + if ((proc = find_proc(pid)) != NULL) { +c010ab25: 8b 45 08 mov 0x8(%ebp),%eax +c010ab28: 89 04 24 mov %eax,(%esp) +c010ab2b: e8 8f ef ff ff call c0109abf +c010ab30: 89 45 f4 mov %eax,-0xc(%ebp) +c010ab33: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c010ab37: 74 41 je c010ab7a + if (!(proc->flags & PF_EXITING)) { +c010ab39: 8b 45 f4 mov -0xc(%ebp),%eax +c010ab3c: 8b 40 44 mov 0x44(%eax),%eax +c010ab3f: 83 e0 01 and $0x1,%eax +c010ab42: 85 c0 test %eax,%eax +c010ab44: 75 2d jne c010ab73 + proc->flags |= PF_EXITING; +c010ab46: 8b 45 f4 mov -0xc(%ebp),%eax +c010ab49: 8b 40 44 mov 0x44(%eax),%eax +c010ab4c: 83 c8 01 or $0x1,%eax +c010ab4f: 89 c2 mov %eax,%edx +c010ab51: 8b 45 f4 mov -0xc(%ebp),%eax +c010ab54: 89 50 44 mov %edx,0x44(%eax) + if (proc->wait_state & WT_INTERRUPTED) { +c010ab57: 8b 45 f4 mov -0xc(%ebp),%eax +c010ab5a: 8b 40 6c mov 0x6c(%eax),%eax +c010ab5d: 85 c0 test %eax,%eax +c010ab5f: 79 0b jns c010ab6c + wakeup_proc(proc); +c010ab61: 8b 45 f4 mov -0xc(%ebp),%eax +c010ab64: 89 04 24 mov %eax,(%esp) +c010ab67: e8 89 04 00 00 call c010aff5 + } + return 0; +c010ab6c: b8 00 00 00 00 mov $0x0,%eax +c010ab71: eb 0c jmp c010ab7f + } + return -E_KILLED; +c010ab73: b8 f7 ff ff ff mov $0xfffffff7,%eax +c010ab78: eb 05 jmp c010ab7f + } + return -E_INVAL; +c010ab7a: b8 fd ff ff ff mov $0xfffffffd,%eax +} +c010ab7f: 89 ec mov %ebp,%esp +c010ab81: 5d pop %ebp +c010ab82: c3 ret + +c010ab83 : + * @return 返回系统调用的结果如果成功,通常返回0;如果失败,返回错误码 + * + * 注意:该函数使用内联汇编来触发系统调用,这是一种低级操作,需要对系统调用和汇编语言有深入的了解 + */ +static int +kernel_execve(const char *name, unsigned char *binary, size_t size) { +c010ab83: 55 push %ebp +c010ab84: 89 e5 mov %esp,%ebp +c010ab86: 57 push %edi +c010ab87: 56 push %esi +c010ab88: 53 push %ebx +c010ab89: 83 ec 2c sub $0x2c,%esp + int ret, len = strlen(name); +c010ab8c: 8b 45 08 mov 0x8(%ebp),%eax +c010ab8f: 89 04 24 mov %eax,(%esp) +c010ab92: e8 30 0f 00 00 call c010bac7 +c010ab97: 89 45 e4 mov %eax,-0x1c(%ebp) + asm volatile ( +c010ab9a: b8 04 00 00 00 mov $0x4,%eax +c010ab9f: 8b 55 08 mov 0x8(%ebp),%edx +c010aba2: 8b 4d e4 mov -0x1c(%ebp),%ecx +c010aba5: 8b 5d 0c mov 0xc(%ebp),%ebx +c010aba8: 8b 75 10 mov 0x10(%ebp),%esi +c010abab: 89 f7 mov %esi,%edi +c010abad: cd 80 int $0x80 +c010abaf: 89 45 e0 mov %eax,-0x20(%ebp) + "int %1;" + : "=a" (ret) + : "i" (T_SYSCALL), "0" (SYS_exec), "d" (name), "c" (len), "b" (binary), "D" (size) + : "memory"); + return ret; +c010abb2: 8b 45 e0 mov -0x20(%ebp),%eax +} +c010abb5: 83 c4 2c add $0x2c,%esp +c010abb8: 5b pop %ebx +c010abb9: 5e pop %esi +c010abba: 5f pop %edi +c010abbb: 5d pop %ebp +c010abbc: c3 ret + +c010abbd : + +#define KERNEL_EXECVE2(x, xstart, xsize) __KERNEL_EXECVE2(x, xstart, xsize) + +// user_main - kernel thread used to exec a user program +static int +user_main(void *arg) { +c010abbd: 55 push %ebp +c010abbe: 89 e5 mov %esp,%ebp +c010abc0: 83 ec 18 sub $0x18,%esp +#ifdef TEST + KERNEL_EXECVE2(TEST, TESTSTART, TESTSIZE); +#else + KERNEL_EXECVE(hello); +c010abc3: a1 30 41 1a c0 mov 0xc01a4130,%eax +c010abc8: 8b 40 04 mov 0x4(%eax),%eax +c010abcb: c7 44 24 08 c2 e2 10 movl $0xc010e2c2,0x8(%esp) +c010abd2: c0 +c010abd3: 89 44 24 04 mov %eax,0x4(%esp) +c010abd7: c7 04 24 c8 e2 10 c0 movl $0xc010e2c8,(%esp) +c010abde: e8 95 57 ff ff call c0100378 +c010abe3: b8 f4 77 00 00 mov $0x77f4,%eax +c010abe8: 89 44 24 08 mov %eax,0x8(%esp) +c010abec: c7 44 24 04 9c bb 16 movl $0xc016bb9c,0x4(%esp) +c010abf3: c0 +c010abf4: c7 04 24 c2 e2 10 c0 movl $0xc010e2c2,(%esp) +c010abfb: e8 83 ff ff ff call c010ab83 +#endif + panic("user_main execve failed.\n"); +c010ac00: c7 44 24 08 ef e2 10 movl $0xc010e2ef,0x8(%esp) +c010ac07: c0 +c010ac08: c7 44 24 04 35 04 00 movl $0x435,0x4(%esp) +c010ac0f: 00 +c010ac10: c7 04 24 9c e0 10 c0 movl $0xc010e09c,(%esp) +c010ac17: e8 1f 61 ff ff call c0100d3b <__panic> + +c010ac1c : + * + * @param arg 传递给函数的参数,在此函数中未使用 + * @return 返回0表示成功执行 + */ +static int +init_main(void *arg) { +c010ac1c: 55 push %ebp +c010ac1d: 89 e5 mov %esp,%ebp +c010ac1f: 83 ec 38 sub $0x38,%esp + // 保存当前空闲页面数量和内核已分配内存大小,用于后续检查 + size_t nr_free_pages_store = nr_free_pages(); +c010ac22: e8 fc a5 ff ff call c0105223 +c010ac27: 89 45 f4 mov %eax,-0xc(%ebp) + size_t kernel_allocated_store = kallocated(); +c010ac2a: e8 9e 9f ff ff call c0104bcd +c010ac2f: 89 45 f0 mov %eax,-0x10(%ebp) + + // 创建内核线程来执行用户主函数,如果创建失败,则系统陷入恐慌 + int pid = kernel_thread(user_main, NULL, 0); +c010ac32: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) +c010ac39: 00 +c010ac3a: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) +c010ac41: 00 +c010ac42: c7 04 24 bd ab 10 c0 movl $0xc010abbd,(%esp) +c010ac49: e8 e5 ee ff ff call c0109b33 +c010ac4e: 89 45 ec mov %eax,-0x14(%ebp) + if (pid <= 0) { +c010ac51: 83 7d ec 00 cmpl $0x0,-0x14(%ebp) +c010ac55: 7f 21 jg c010ac78 + panic("create user_main failed.\n"); +c010ac57: c7 44 24 08 09 e3 10 movl $0xc010e309,0x8(%esp) +c010ac5e: c0 +c010ac5f: c7 44 24 04 55 04 00 movl $0x455,0x4(%esp) +c010ac66: 00 +c010ac67: c7 04 24 9c e0 10 c0 movl $0xc010e09c,(%esp) +c010ac6e: e8 c8 60 ff ff call c0100d3b <__panic> + } + + // 循环等待和调度,直到所有用户模式进程结束 + while (do_wait(0, NULL) == 0) { + schedule(); +c010ac73: e8 04 04 00 00 call c010b07c + while (do_wait(0, NULL) == 0) { +c010ac78: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) +c010ac7f: 00 +c010ac80: c7 04 24 00 00 00 00 movl $0x0,(%esp) +c010ac87: e8 01 fd ff ff call c010a98d +c010ac8c: 85 c0 test %eax,%eax +c010ac8e: 74 e3 je c010ac73 + } + + // 所有用户模式进程结束后,打印消息 + cprintf("all user-mode processes have quit.\n"); +c010ac90: c7 04 24 24 e3 10 c0 movl $0xc010e324,(%esp) +c010ac97: e8 dc 56 ff ff call c0100378 + + // 断言系统状态符合预期 + assert(initproc->cptr == NULL && initproc->yptr == NULL && initproc->optr == NULL); +c010ac9c: a1 2c 41 1a c0 mov 0xc01a412c,%eax +c010aca1: 8b 40 70 mov 0x70(%eax),%eax +c010aca4: 85 c0 test %eax,%eax +c010aca6: 75 18 jne c010acc0 +c010aca8: a1 2c 41 1a c0 mov 0xc01a412c,%eax +c010acad: 8b 40 74 mov 0x74(%eax),%eax +c010acb0: 85 c0 test %eax,%eax +c010acb2: 75 0c jne c010acc0 +c010acb4: a1 2c 41 1a c0 mov 0xc01a412c,%eax +c010acb9: 8b 40 78 mov 0x78(%eax),%eax +c010acbc: 85 c0 test %eax,%eax +c010acbe: 74 24 je c010ace4 +c010acc0: c7 44 24 0c 48 e3 10 movl $0xc010e348,0xc(%esp) +c010acc7: c0 +c010acc8: c7 44 24 08 c9 e0 10 movl $0xc010e0c9,0x8(%esp) +c010accf: c0 +c010acd0: c7 44 24 04 61 04 00 movl $0x461,0x4(%esp) +c010acd7: 00 +c010acd8: c7 04 24 9c e0 10 c0 movl $0xc010e09c,(%esp) +c010acdf: e8 57 60 ff ff call c0100d3b <__panic> + assert(nr_process == 2); +c010ace4: a1 40 61 1a c0 mov 0xc01a6140,%eax +c010ace9: 83 f8 02 cmp $0x2,%eax +c010acec: 74 24 je c010ad12 +c010acee: c7 44 24 0c 93 e3 10 movl $0xc010e393,0xc(%esp) +c010acf5: c0 +c010acf6: c7 44 24 08 c9 e0 10 movl $0xc010e0c9,0x8(%esp) +c010acfd: c0 +c010acfe: c7 44 24 04 62 04 00 movl $0x462,0x4(%esp) +c010ad05: 00 +c010ad06: c7 04 24 9c e0 10 c0 movl $0xc010e09c,(%esp) +c010ad0d: e8 29 60 ff ff call c0100d3b <__panic> +c010ad12: c7 45 e8 20 41 1a c0 movl $0xc01a4120,-0x18(%ebp) +c010ad19: 8b 45 e8 mov -0x18(%ebp),%eax +c010ad1c: 8b 40 04 mov 0x4(%eax),%eax + assert(list_next(&proc_list) == &(initproc->list_link)); +c010ad1f: 8b 15 2c 41 1a c0 mov 0xc01a412c,%edx +c010ad25: 83 c2 58 add $0x58,%edx +c010ad28: 39 d0 cmp %edx,%eax +c010ad2a: 74 24 je c010ad50 +c010ad2c: c7 44 24 0c a4 e3 10 movl $0xc010e3a4,0xc(%esp) +c010ad33: c0 +c010ad34: c7 44 24 08 c9 e0 10 movl $0xc010e0c9,0x8(%esp) +c010ad3b: c0 +c010ad3c: c7 44 24 04 63 04 00 movl $0x463,0x4(%esp) +c010ad43: 00 +c010ad44: c7 04 24 9c e0 10 c0 movl $0xc010e09c,(%esp) +c010ad4b: e8 eb 5f ff ff call c0100d3b <__panic> +c010ad50: c7 45 e4 20 41 1a c0 movl $0xc01a4120,-0x1c(%ebp) + return listelm->prev; +c010ad57: 8b 45 e4 mov -0x1c(%ebp),%eax +c010ad5a: 8b 00 mov (%eax),%eax + assert(list_prev(&proc_list) == &(initproc->list_link)); +c010ad5c: 8b 15 2c 41 1a c0 mov 0xc01a412c,%edx +c010ad62: 83 c2 58 add $0x58,%edx +c010ad65: 39 d0 cmp %edx,%eax +c010ad67: 74 24 je c010ad8d +c010ad69: c7 44 24 0c d4 e3 10 movl $0xc010e3d4,0xc(%esp) +c010ad70: c0 +c010ad71: c7 44 24 08 c9 e0 10 movl $0xc010e0c9,0x8(%esp) +c010ad78: c0 +c010ad79: c7 44 24 04 64 04 00 movl $0x464,0x4(%esp) +c010ad80: 00 +c010ad81: c7 04 24 9c e0 10 c0 movl $0xc010e09c,(%esp) +c010ad88: e8 ae 5f ff ff call c0100d3b <__panic> + + // 如果所有检查通过,打印内存检查通过的消息 + cprintf("init check memory pass.\n"); +c010ad8d: c7 04 24 04 e4 10 c0 movl $0xc010e404,(%esp) +c010ad94: e8 df 55 ff ff call c0100378 + return 0; +c010ad99: b8 00 00 00 00 mov $0x0,%eax +} +c010ad9e: 89 ec mov %ebp,%esp +c010ada0: 5d pop %ebp +c010ada1: c3 ret + +c010ada2 : + +// proc_init - set up the first kernel thread idleproc "idle" by itself and +// - create the second kernel thread init_main +void +proc_init(void) { +c010ada2: 55 push %ebp +c010ada3: 89 e5 mov %esp,%ebp +c010ada5: 83 ec 28 sub $0x28,%esp +c010ada8: c7 45 ec 20 41 1a c0 movl $0xc01a4120,-0x14(%ebp) + elm->prev = elm->next = elm; +c010adaf: 8b 45 ec mov -0x14(%ebp),%eax +c010adb2: 8b 55 ec mov -0x14(%ebp),%edx +c010adb5: 89 50 04 mov %edx,0x4(%eax) +c010adb8: 8b 45 ec mov -0x14(%ebp),%eax +c010adbb: 8b 50 04 mov 0x4(%eax),%edx +c010adbe: 8b 45 ec mov -0x14(%ebp),%eax +c010adc1: 89 10 mov %edx,(%eax) +} +c010adc3: 90 nop + + // 初始化全局进程列表 + list_init(&proc_list); + + // 初始化哈希列表,用于快速查找进程 + for (i = 0; i < HASH_LIST_SIZE; i ++) { +c010adc4: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) +c010adcb: eb 26 jmp c010adf3 + list_init(hash_list + i); +c010adcd: 8b 45 f4 mov -0xc(%ebp),%eax +c010add0: c1 e0 03 shl $0x3,%eax +c010add3: 05 40 41 1a c0 add $0xc01a4140,%eax +c010add8: 89 45 e8 mov %eax,-0x18(%ebp) + elm->prev = elm->next = elm; +c010addb: 8b 45 e8 mov -0x18(%ebp),%eax +c010adde: 8b 55 e8 mov -0x18(%ebp),%edx +c010ade1: 89 50 04 mov %edx,0x4(%eax) +c010ade4: 8b 45 e8 mov -0x18(%ebp),%eax +c010ade7: 8b 50 04 mov 0x4(%eax),%edx +c010adea: 8b 45 e8 mov -0x18(%ebp),%eax +c010aded: 89 10 mov %edx,(%eax) +} +c010adef: 90 nop + for (i = 0; i < HASH_LIST_SIZE; i ++) { +c010adf0: ff 45 f4 incl -0xc(%ebp) +c010adf3: 81 7d f4 ff 03 00 00 cmpl $0x3ff,-0xc(%ebp) +c010adfa: 7e d1 jle c010adcd + } + + // 分配空闲进程idleproc,这是系统中的第一个进程 + if ((idleproc = alloc_proc()) == NULL) { +c010adfc: e8 cd e7 ff ff call c01095ce +c010ae01: a3 28 41 1a c0 mov %eax,0xc01a4128 +c010ae06: a1 28 41 1a c0 mov 0xc01a4128,%eax +c010ae0b: 85 c0 test %eax,%eax +c010ae0d: 75 1c jne c010ae2b + panic("cannot alloc idleproc.\n"); +c010ae0f: c7 44 24 08 1d e4 10 movl $0xc010e41d,0x8(%esp) +c010ae16: c0 +c010ae17: c7 44 24 04 7b 04 00 movl $0x47b,0x4(%esp) +c010ae1e: 00 +c010ae1f: c7 04 24 9c e0 10 c0 movl $0xc010e09c,(%esp) +c010ae26: e8 10 5f ff ff call c0100d3b <__panic> + } + + // 设置idleproc的基本信息 + idleproc->pid = 0; +c010ae2b: a1 28 41 1a c0 mov 0xc01a4128,%eax +c010ae30: c7 40 04 00 00 00 00 movl $0x0,0x4(%eax) + idleproc->state = PROC_RUNNABLE; +c010ae37: a1 28 41 1a c0 mov 0xc01a4128,%eax +c010ae3c: c7 00 02 00 00 00 movl $0x2,(%eax) + idleproc->kstack = (uintptr_t)bootstack; +c010ae42: a1 28 41 1a c0 mov 0xc01a4128,%eax +c010ae47: ba 00 d0 12 c0 mov $0xc012d000,%edx +c010ae4c: 89 50 0c mov %edx,0xc(%eax) + idleproc->need_resched = 1; +c010ae4f: a1 28 41 1a c0 mov 0xc01a4128,%eax +c010ae54: c7 40 10 01 00 00 00 movl $0x1,0x10(%eax) + set_proc_name(idleproc, "idle"); +c010ae5b: a1 28 41 1a c0 mov 0xc01a4128,%eax +c010ae60: c7 44 24 04 35 e4 10 movl $0xc010e435,0x4(%esp) +c010ae67: c0 +c010ae68: 89 04 24 mov %eax,(%esp) +c010ae6b: e8 51 e8 ff ff call c01096c1 + nr_process ++; +c010ae70: a1 40 61 1a c0 mov 0xc01a6140,%eax +c010ae75: 40 inc %eax +c010ae76: a3 40 61 1a c0 mov %eax,0xc01a6140 + + // 将当前进程设置为idleproc + current = idleproc; +c010ae7b: a1 28 41 1a c0 mov 0xc01a4128,%eax +c010ae80: a3 30 41 1a c0 mov %eax,0xc01a4130 + + // 创建初始化进程init_main,这是系统中的第二个进程 + int pid = kernel_thread(init_main, NULL, 0); +c010ae85: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) +c010ae8c: 00 +c010ae8d: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) +c010ae94: 00 +c010ae95: c7 04 24 1c ac 10 c0 movl $0xc010ac1c,(%esp) +c010ae9c: e8 92 ec ff ff call c0109b33 +c010aea1: 89 45 f0 mov %eax,-0x10(%ebp) + if (pid <= 0) { +c010aea4: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) +c010aea8: 7f 1c jg c010aec6 + panic("create init_main failed.\n"); +c010aeaa: c7 44 24 08 3a e4 10 movl $0xc010e43a,0x8(%esp) +c010aeb1: c0 +c010aeb2: c7 44 24 04 8c 04 00 movl $0x48c,0x4(%esp) +c010aeb9: 00 +c010aeba: c7 04 24 9c e0 10 c0 movl $0xc010e09c,(%esp) +c010aec1: e8 75 5e ff ff call c0100d3b <__panic> + } + + // 查找并设置初始化进程initproc + initproc = find_proc(pid); +c010aec6: 8b 45 f0 mov -0x10(%ebp),%eax +c010aec9: 89 04 24 mov %eax,(%esp) +c010aecc: e8 ee eb ff ff call c0109abf +c010aed1: a3 2c 41 1a c0 mov %eax,0xc01a412c + set_proc_name(initproc, "init"); +c010aed6: a1 2c 41 1a c0 mov 0xc01a412c,%eax +c010aedb: c7 44 24 04 54 e4 10 movl $0xc010e454,0x4(%esp) +c010aee2: c0 +c010aee3: 89 04 24 mov %eax,(%esp) +c010aee6: e8 d6 e7 ff ff call c01096c1 + + // 断言确保idleproc和initproc正确初始化 + assert(idleproc != NULL && idleproc->pid == 0); +c010aeeb: a1 28 41 1a c0 mov 0xc01a4128,%eax +c010aef0: 85 c0 test %eax,%eax +c010aef2: 74 0c je c010af00 +c010aef4: a1 28 41 1a c0 mov 0xc01a4128,%eax +c010aef9: 8b 40 04 mov 0x4(%eax),%eax +c010aefc: 85 c0 test %eax,%eax +c010aefe: 74 24 je c010af24 +c010af00: c7 44 24 0c 5c e4 10 movl $0xc010e45c,0xc(%esp) +c010af07: c0 +c010af08: c7 44 24 08 c9 e0 10 movl $0xc010e0c9,0x8(%esp) +c010af0f: c0 +c010af10: c7 44 24 04 94 04 00 movl $0x494,0x4(%esp) +c010af17: 00 +c010af18: c7 04 24 9c e0 10 c0 movl $0xc010e09c,(%esp) +c010af1f: e8 17 5e ff ff call c0100d3b <__panic> + assert(initproc != NULL && initproc->pid == 1); +c010af24: a1 2c 41 1a c0 mov 0xc01a412c,%eax +c010af29: 85 c0 test %eax,%eax +c010af2b: 74 0d je c010af3a +c010af2d: a1 2c 41 1a c0 mov 0xc01a412c,%eax +c010af32: 8b 40 04 mov 0x4(%eax),%eax +c010af35: 83 f8 01 cmp $0x1,%eax +c010af38: 74 24 je c010af5e +c010af3a: c7 44 24 0c 84 e4 10 movl $0xc010e484,0xc(%esp) +c010af41: c0 +c010af42: c7 44 24 08 c9 e0 10 movl $0xc010e0c9,0x8(%esp) +c010af49: c0 +c010af4a: c7 44 24 04 95 04 00 movl $0x495,0x4(%esp) +c010af51: 00 +c010af52: c7 04 24 9c e0 10 c0 movl $0xc010e09c,(%esp) +c010af59: e8 dd 5d ff ff call c0100d3b <__panic> +} +c010af5e: 90 nop +c010af5f: 89 ec mov %ebp,%esp +c010af61: 5d pop %ebp +c010af62: c3 ret + +c010af63 : + +// cpu_idle - at the end of kern_init, the first kernel thread idleproc will do below works +void +cpu_idle(void) { +c010af63: 55 push %ebp +c010af64: 89 e5 mov %esp,%ebp +c010af66: 83 ec 08 sub $0x8,%esp + while (1) { + //检查当前进程是否需要重新调度 + if (current->need_resched) { +c010af69: a1 30 41 1a c0 mov 0xc01a4130,%eax +c010af6e: 8b 40 10 mov 0x10(%eax),%eax +c010af71: 85 c0 test %eax,%eax +c010af73: 74 f4 je c010af69 + schedule(); +c010af75: e8 02 01 00 00 call c010b07c + if (current->need_resched) { +c010af7a: eb ed jmp c010af69 + +c010af7c : +.text +.globl switch_to +switch_to: # switch_to(from, to) + + # save from's registers + movl 4(%esp), %eax # eax points to from +c010af7c: 8b 44 24 04 mov 0x4(%esp),%eax + popl 0(%eax) # save eip !popl +c010af80: 8f 00 pop (%eax) + movl %esp, 4(%eax) +c010af82: 89 60 04 mov %esp,0x4(%eax) + movl %ebx, 8(%eax) +c010af85: 89 58 08 mov %ebx,0x8(%eax) + movl %ecx, 12(%eax) +c010af88: 89 48 0c mov %ecx,0xc(%eax) + movl %edx, 16(%eax) +c010af8b: 89 50 10 mov %edx,0x10(%eax) + movl %esi, 20(%eax) +c010af8e: 89 70 14 mov %esi,0x14(%eax) + movl %edi, 24(%eax) +c010af91: 89 78 18 mov %edi,0x18(%eax) + movl %ebp, 28(%eax) +c010af94: 89 68 1c mov %ebp,0x1c(%eax) + + # restore to's registers + movl 4(%esp), %eax # not 8(%esp): popped return address already +c010af97: 8b 44 24 04 mov 0x4(%esp),%eax + # eax now points to to + movl 28(%eax), %ebp +c010af9b: 8b 68 1c mov 0x1c(%eax),%ebp + movl 24(%eax), %edi +c010af9e: 8b 78 18 mov 0x18(%eax),%edi + movl 20(%eax), %esi +c010afa1: 8b 70 14 mov 0x14(%eax),%esi + movl 16(%eax), %edx +c010afa4: 8b 50 10 mov 0x10(%eax),%edx + movl 12(%eax), %ecx +c010afa7: 8b 48 0c mov 0xc(%eax),%ecx + movl 8(%eax), %ebx +c010afaa: 8b 58 08 mov 0x8(%eax),%ebx + movl 4(%eax), %esp +c010afad: 8b 60 04 mov 0x4(%eax),%esp + + pushl 0(%eax) # push eip +c010afb0: ff 30 push (%eax) + + ret +c010afb2: c3 ret + +c010afb3 <__intr_save>: +__intr_save(void) { +c010afb3: 55 push %ebp +c010afb4: 89 e5 mov %esp,%ebp +c010afb6: 83 ec 18 sub $0x18,%esp + asm volatile ("pushfl; popl %0" : "=r" (eflags)); +c010afb9: 9c pushf +c010afba: 58 pop %eax +c010afbb: 89 45 f4 mov %eax,-0xc(%ebp) + return eflags; +c010afbe: 8b 45 f4 mov -0xc(%ebp),%eax + if (read_eflags() & FL_IF) { +c010afc1: 25 00 02 00 00 and $0x200,%eax +c010afc6: 85 c0 test %eax,%eax +c010afc8: 74 0c je c010afd6 <__intr_save+0x23> + intr_disable(); +c010afca: e8 22 70 ff ff call c0101ff1 + return 1; +c010afcf: b8 01 00 00 00 mov $0x1,%eax +c010afd4: eb 05 jmp c010afdb <__intr_save+0x28> + return 0; +c010afd6: b8 00 00 00 00 mov $0x0,%eax +} +c010afdb: 89 ec mov %ebp,%esp +c010afdd: 5d pop %ebp +c010afde: c3 ret + +c010afdf <__intr_restore>: +__intr_restore(bool flag) { +c010afdf: 55 push %ebp +c010afe0: 89 e5 mov %esp,%ebp +c010afe2: 83 ec 08 sub $0x8,%esp + if (flag) { +c010afe5: 83 7d 08 00 cmpl $0x0,0x8(%ebp) +c010afe9: 74 05 je c010aff0 <__intr_restore+0x11> + intr_enable(); +c010afeb: e8 f9 6f ff ff call c0101fe9 +} +c010aff0: 90 nop +c010aff1: 89 ec mov %ebp,%esp +c010aff3: 5d pop %ebp +c010aff4: c3 ret + +c010aff5 : +#include +#include +#include + +void +wakeup_proc(struct proc_struct *proc) { +c010aff5: 55 push %ebp +c010aff6: 89 e5 mov %esp,%ebp +c010aff8: 83 ec 28 sub $0x28,%esp + assert(proc->state != PROC_ZOMBIE); +c010affb: 8b 45 08 mov 0x8(%ebp),%eax +c010affe: 8b 00 mov (%eax),%eax +c010b000: 83 f8 03 cmp $0x3,%eax +c010b003: 75 24 jne c010b029 +c010b005: c7 44 24 0c ab e4 10 movl $0xc010e4ab,0xc(%esp) +c010b00c: c0 +c010b00d: c7 44 24 08 c6 e4 10 movl $0xc010e4c6,0x8(%esp) +c010b014: c0 +c010b015: c7 44 24 04 09 00 00 movl $0x9,0x4(%esp) +c010b01c: 00 +c010b01d: c7 04 24 db e4 10 c0 movl $0xc010e4db,(%esp) +c010b024: e8 12 5d ff ff call c0100d3b <__panic> + bool intr_flag; + local_intr_save(intr_flag); +c010b029: e8 85 ff ff ff call c010afb3 <__intr_save> +c010b02e: 89 45 f4 mov %eax,-0xc(%ebp) + { + if (proc->state != PROC_RUNNABLE) { +c010b031: 8b 45 08 mov 0x8(%ebp),%eax +c010b034: 8b 00 mov (%eax),%eax +c010b036: 83 f8 02 cmp $0x2,%eax +c010b039: 74 15 je c010b050 + proc->state = PROC_RUNNABLE; +c010b03b: 8b 45 08 mov 0x8(%ebp),%eax +c010b03e: c7 00 02 00 00 00 movl $0x2,(%eax) + proc->wait_state = 0; +c010b044: 8b 45 08 mov 0x8(%ebp),%eax +c010b047: c7 40 6c 00 00 00 00 movl $0x0,0x6c(%eax) +c010b04e: eb 1c jmp c010b06c + } + else { + warn("wakeup runnable process.\n"); +c010b050: c7 44 24 08 f1 e4 10 movl $0xc010e4f1,0x8(%esp) +c010b057: c0 +c010b058: c7 44 24 04 12 00 00 movl $0x12,0x4(%esp) +c010b05f: 00 +c010b060: c7 04 24 db e4 10 c0 movl $0xc010e4db,(%esp) +c010b067: e8 4d 5d ff ff call c0100db9 <__warn> + } + } + local_intr_restore(intr_flag); +c010b06c: 8b 45 f4 mov -0xc(%ebp),%eax +c010b06f: 89 04 24 mov %eax,(%esp) +c010b072: e8 68 ff ff ff call c010afdf <__intr_restore> +} +c010b077: 90 nop +c010b078: 89 ec mov %ebp,%esp +c010b07a: 5d pop %ebp +c010b07b: c3 ret + +c010b07c : + * 如果找到可运行的进程,则选择该进程作为下一个要执行的进程,并进行上下文切换。 + * 如果没有找到可运行的进程,则选择空闲进程作为下一个要执行的进程。 + * 最后,恢复中断状态并退出调度函数。 + */ +void +schedule(void) { +c010b07c: 55 push %ebp +c010b07d: 89 e5 mov %esp,%ebp +c010b07f: 83 ec 38 sub $0x38,%esp + // 保存中断状态标志 + bool intr_flag; + // 定义指向进程列表项的指针 + list_entry_t *le, *last; + // 定义下一个要执行的进程指针,并初始化为NULL + struct proc_struct *next = NULL; +c010b082: c7 45 f0 00 00 00 00 movl $0x0,-0x10(%ebp) + // 保存当前中断状态,并禁止中断 + local_intr_save(intr_flag); +c010b089: e8 25 ff ff ff call c010afb3 <__intr_save> +c010b08e: 89 45 ec mov %eax,-0x14(%ebp) + { + // 标记当前进程不需要重新调度 + current->need_resched = 0; +c010b091: a1 30 41 1a c0 mov 0xc01a4130,%eax +c010b096: c7 40 10 00 00 00 00 movl $0x0,0x10(%eax) + // 确定进程列表的最后一个元素 + last = (current == idleproc) ? &proc_list : &(current->list_link); +c010b09d: 8b 15 30 41 1a c0 mov 0xc01a4130,%edx +c010b0a3: a1 28 41 1a c0 mov 0xc01a4128,%eax +c010b0a8: 39 c2 cmp %eax,%edx +c010b0aa: 74 0a je c010b0b6 +c010b0ac: a1 30 41 1a c0 mov 0xc01a4130,%eax +c010b0b1: 83 c0 58 add $0x58,%eax +c010b0b4: eb 05 jmp c010b0bb +c010b0b6: b8 20 41 1a c0 mov $0xc01a4120,%eax +c010b0bb: 89 45 e8 mov %eax,-0x18(%ebp) + // 从最后一个元素开始遍历进程列表 + le = last; +c010b0be: 8b 45 e8 mov -0x18(%ebp),%eax +c010b0c1: 89 45 f4 mov %eax,-0xc(%ebp) +c010b0c4: 8b 45 f4 mov -0xc(%ebp),%eax +c010b0c7: 89 45 e4 mov %eax,-0x1c(%ebp) + return listelm->next; +c010b0ca: 8b 45 e4 mov -0x1c(%ebp),%eax +c010b0cd: 8b 40 04 mov 0x4(%eax),%eax + do { + // 如果不是进程列表的末尾,则继续查找下一个可运行的进程 + if ((le = list_next(le)) != &proc_list) { +c010b0d0: 89 45 f4 mov %eax,-0xc(%ebp) +c010b0d3: 81 7d f4 20 41 1a c0 cmpl $0xc01a4120,-0xc(%ebp) +c010b0da: 74 13 je c010b0ef + // 获取当前列表项对应的进程结构体 + next = le2proc(le, list_link); +c010b0dc: 8b 45 f4 mov -0xc(%ebp),%eax +c010b0df: 83 e8 58 sub $0x58,%eax +c010b0e2: 89 45 f0 mov %eax,-0x10(%ebp) + // 如果进程处于可运行状态,则停止查找 + if (next->state == PROC_RUNNABLE) { +c010b0e5: 8b 45 f0 mov -0x10(%ebp),%eax +c010b0e8: 8b 00 mov (%eax),%eax +c010b0ea: 83 f8 02 cmp $0x2,%eax +c010b0ed: 74 0a je c010b0f9 + break; + } + } + } while (le != last); +c010b0ef: 8b 45 f4 mov -0xc(%ebp),%eax +c010b0f2: 3b 45 e8 cmp -0x18(%ebp),%eax +c010b0f5: 75 cd jne c010b0c4 +c010b0f7: eb 01 jmp c010b0fa + break; +c010b0f9: 90 nop + // 如果没有找到可运行的进程,则选择空闲进程作为下一个要执行的进程 + if (next == NULL || next->state != PROC_RUNNABLE) { +c010b0fa: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) +c010b0fe: 74 0a je c010b10a +c010b100: 8b 45 f0 mov -0x10(%ebp),%eax +c010b103: 8b 00 mov (%eax),%eax +c010b105: 83 f8 02 cmp $0x2,%eax +c010b108: 74 08 je c010b112 + next = idleproc; +c010b10a: a1 28 41 1a c0 mov 0xc01a4128,%eax +c010b10f: 89 45 f0 mov %eax,-0x10(%ebp) + } + // 增加下一个要执行的进程的运行次数 + next->runs ++; +c010b112: 8b 45 f0 mov -0x10(%ebp),%eax +c010b115: 8b 40 08 mov 0x8(%eax),%eax +c010b118: 8d 50 01 lea 0x1(%eax),%edx +c010b11b: 8b 45 f0 mov -0x10(%ebp),%eax +c010b11e: 89 50 08 mov %edx,0x8(%eax) + // 如果下一个要执行的进程不是当前进程,则进行上下文切换 + if (next != current) { +c010b121: a1 30 41 1a c0 mov 0xc01a4130,%eax +c010b126: 39 45 f0 cmp %eax,-0x10(%ebp) +c010b129: 74 0b je c010b136 + proc_run(next); +c010b12b: 8b 45 f0 mov -0x10(%ebp),%eax +c010b12e: 89 04 24 mov %eax,(%esp) +c010b131: e8 3a e8 ff ff call c0109970 + } + } + // 恢复中断状态 + local_intr_restore(intr_flag); +c010b136: 8b 45 ec mov -0x14(%ebp),%eax +c010b139: 89 04 24 mov %eax,(%esp) +c010b13c: e8 9e fe ff ff call c010afdf <__intr_restore> +} +c010b141: 90 nop +c010b142: 89 ec mov %ebp,%esp +c010b144: 5d pop %ebp +c010b145: c3 ret + +c010b146 : +#include +#include +#include + +static int +sys_exit(uint32_t arg[]) { +c010b146: 55 push %ebp +c010b147: 89 e5 mov %esp,%ebp +c010b149: 83 ec 28 sub $0x28,%esp + int error_code = (int)arg[0]; +c010b14c: 8b 45 08 mov 0x8(%ebp),%eax +c010b14f: 8b 00 mov (%eax),%eax +c010b151: 89 45 f4 mov %eax,-0xc(%ebp) + return do_exit(error_code); +c010b154: 8b 45 f4 mov -0xc(%ebp),%eax +c010b157: 89 04 24 mov %eax,(%esp) +c010b15a: e8 b1 ee ff ff call c010a010 +} +c010b15f: 89 ec mov %ebp,%esp +c010b161: 5d pop %ebp +c010b162: c3 ret + +c010b163 : + +//实现进程的创建 +static int +sys_fork(uint32_t arg[]) { +c010b163: 55 push %ebp +c010b164: 89 e5 mov %esp,%ebp +c010b166: 83 ec 28 sub $0x28,%esp + struct trapframe *tf = current->tf; +c010b169: a1 30 41 1a c0 mov 0xc01a4130,%eax +c010b16e: 8b 40 3c mov 0x3c(%eax),%eax +c010b171: 89 45 f4 mov %eax,-0xc(%ebp) + uintptr_t stack = tf->tf_esp; +c010b174: 8b 45 f4 mov -0xc(%ebp),%eax +c010b177: 8b 40 44 mov 0x44(%eax),%eax +c010b17a: 89 45 f0 mov %eax,-0x10(%ebp) + return do_fork(0, stack, tf); +c010b17d: 8b 45 f4 mov -0xc(%ebp),%eax +c010b180: 89 44 24 08 mov %eax,0x8(%esp) +c010b184: 8b 45 f0 mov -0x10(%ebp),%eax +c010b187: 89 44 24 04 mov %eax,0x4(%esp) +c010b18b: c7 04 24 00 00 00 00 movl $0x0,(%esp) +c010b192: e8 52 ed ff ff call c0109ee9 +} +c010b197: 89 ec mov %ebp,%esp +c010b199: 5d pop %ebp +c010b19a: c3 ret + +c010b19b : + +static int +sys_wait(uint32_t arg[]) { +c010b19b: 55 push %ebp +c010b19c: 89 e5 mov %esp,%ebp +c010b19e: 83 ec 28 sub $0x28,%esp + int pid = (int)arg[0]; +c010b1a1: 8b 45 08 mov 0x8(%ebp),%eax +c010b1a4: 8b 00 mov (%eax),%eax +c010b1a6: 89 45 f4 mov %eax,-0xc(%ebp) + int *store = (int *)arg[1]; +c010b1a9: 8b 45 08 mov 0x8(%ebp),%eax +c010b1ac: 83 c0 04 add $0x4,%eax +c010b1af: 8b 00 mov (%eax),%eax +c010b1b1: 89 45 f0 mov %eax,-0x10(%ebp) + return do_wait(pid, store); +c010b1b4: 8b 45 f0 mov -0x10(%ebp),%eax +c010b1b7: 89 44 24 04 mov %eax,0x4(%esp) +c010b1bb: 8b 45 f4 mov -0xc(%ebp),%eax +c010b1be: 89 04 24 mov %eax,(%esp) +c010b1c1: e8 c7 f7 ff ff call c010a98d +} +c010b1c6: 89 ec mov %ebp,%esp +c010b1c8: 5d pop %ebp +c010b1c9: c3 ret + +c010b1ca : + +static int +sys_exec(uint32_t arg[]) { +c010b1ca: 55 push %ebp +c010b1cb: 89 e5 mov %esp,%ebp +c010b1cd: 83 ec 28 sub $0x28,%esp + const char *name = (const char *)arg[0]; +c010b1d0: 8b 45 08 mov 0x8(%ebp),%eax +c010b1d3: 8b 00 mov (%eax),%eax +c010b1d5: 89 45 f4 mov %eax,-0xc(%ebp) + size_t len = (size_t)arg[1]; +c010b1d8: 8b 45 08 mov 0x8(%ebp),%eax +c010b1db: 83 c0 04 add $0x4,%eax +c010b1de: 8b 00 mov (%eax),%eax +c010b1e0: 89 45 f0 mov %eax,-0x10(%ebp) + unsigned char *binary = (unsigned char *)arg[2]; +c010b1e3: 8b 45 08 mov 0x8(%ebp),%eax +c010b1e6: 83 c0 08 add $0x8,%eax +c010b1e9: 8b 00 mov (%eax),%eax +c010b1eb: 89 45 ec mov %eax,-0x14(%ebp) + size_t size = (size_t)arg[3]; +c010b1ee: 8b 45 08 mov 0x8(%ebp),%eax +c010b1f1: 83 c0 0c add $0xc,%eax +c010b1f4: 8b 00 mov (%eax),%eax +c010b1f6: 89 45 e8 mov %eax,-0x18(%ebp) + return do_execve(name, len, binary, size); +c010b1f9: 8b 45 e8 mov -0x18(%ebp),%eax +c010b1fc: 89 44 24 0c mov %eax,0xc(%esp) +c010b200: 8b 45 ec mov -0x14(%ebp),%eax +c010b203: 89 44 24 08 mov %eax,0x8(%esp) +c010b207: 8b 45 f0 mov -0x10(%ebp),%eax +c010b20a: 89 44 24 04 mov %eax,0x4(%esp) +c010b20e: 8b 45 f4 mov -0xc(%ebp),%eax +c010b211: 89 04 24 mov %eax,(%esp) +c010b214: e8 23 f6 ff ff call c010a83c +} +c010b219: 89 ec mov %ebp,%esp +c010b21b: 5d pop %ebp +c010b21c: c3 ret + +c010b21d : + +static int +sys_yield(uint32_t arg[]) { +c010b21d: 55 push %ebp +c010b21e: 89 e5 mov %esp,%ebp +c010b220: 83 ec 08 sub $0x8,%esp + return do_yield(); +c010b223: e8 4f f7 ff ff call c010a977 +} +c010b228: 89 ec mov %ebp,%esp +c010b22a: 5d pop %ebp +c010b22b: c3 ret + +c010b22c : + +static int +sys_kill(uint32_t arg[]) { +c010b22c: 55 push %ebp +c010b22d: 89 e5 mov %esp,%ebp +c010b22f: 83 ec 28 sub $0x28,%esp + int pid = (int)arg[0]; +c010b232: 8b 45 08 mov 0x8(%ebp),%eax +c010b235: 8b 00 mov (%eax),%eax +c010b237: 89 45 f4 mov %eax,-0xc(%ebp) + return do_kill(pid); +c010b23a: 8b 45 f4 mov -0xc(%ebp),%eax +c010b23d: 89 04 24 mov %eax,(%esp) +c010b240: e8 da f8 ff ff call c010ab1f +} +c010b245: 89 ec mov %ebp,%esp +c010b247: 5d pop %ebp +c010b248: c3 ret + +c010b249 : + +//获取当前进程的进程ID(PID) +static int +sys_getpid(uint32_t arg[]) { +c010b249: 55 push %ebp +c010b24a: 89 e5 mov %esp,%ebp + return current->pid; +c010b24c: a1 30 41 1a c0 mov 0xc01a4130,%eax +c010b251: 8b 40 04 mov 0x4(%eax),%eax +} +c010b254: 5d pop %ebp +c010b255: c3 ret + +c010b256 : + +static int +sys_putc(uint32_t arg[]) { +c010b256: 55 push %ebp +c010b257: 89 e5 mov %esp,%ebp +c010b259: 83 ec 28 sub $0x28,%esp + int c = (int)arg[0]; +c010b25c: 8b 45 08 mov 0x8(%ebp),%eax +c010b25f: 8b 00 mov (%eax),%eax +c010b261: 89 45 f4 mov %eax,-0xc(%ebp) + cputchar(c);//将字符 c 输出到控制台 +c010b264: 8b 45 f4 mov -0xc(%ebp),%eax +c010b267: 89 04 24 mov %eax,(%esp) +c010b26a: e8 31 51 ff ff call c01003a0 + return 0; +c010b26f: b8 00 00 00 00 mov $0x0,%eax +} +c010b274: 89 ec mov %ebp,%esp +c010b276: 5d pop %ebp +c010b277: c3 ret + +c010b278 : + +static int +sys_pgdir(uint32_t arg[]) { +c010b278: 55 push %ebp +c010b279: 89 e5 mov %esp,%ebp +c010b27b: 83 ec 08 sub $0x8,%esp + print_pgdir();//打印页目录信息 +c010b27e: e8 7b b9 ff ff call c0106bfe + return 0; +c010b283: b8 00 00 00 00 mov $0x0,%eax +} +c010b288: 89 ec mov %ebp,%esp +c010b28a: 5d pop %ebp +c010b28b: c3 ret + +c010b28c : +}; + +#define NUM_SYSCALLS ((sizeof(syscalls)) / (sizeof(syscalls[0]))) + +void +syscall(void) { +c010b28c: 55 push %ebp +c010b28d: 89 e5 mov %esp,%ebp +c010b28f: 83 ec 48 sub $0x48,%esp + //获取当前线程的陷阱帧 + struct trapframe *tf = current->tf; +c010b292: a1 30 41 1a c0 mov 0xc01a4130,%eax +c010b297: 8b 40 3c mov 0x3c(%eax),%eax +c010b29a: 89 45 f4 mov %eax,-0xc(%ebp) + uint32_t arg[5]; + //提取系统调用号 + int num = tf->tf_regs.reg_eax; +c010b29d: 8b 45 f4 mov -0xc(%ebp),%eax +c010b2a0: 8b 40 1c mov 0x1c(%eax),%eax +c010b2a3: 89 45 f0 mov %eax,-0x10(%ebp) + //检查系统调用号的有效性 + if (num >= 0 && num < NUM_SYSCALLS) { +c010b2a6: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) +c010b2aa: 78 5e js c010b30a +c010b2ac: 8b 45 f0 mov -0x10(%ebp),%eax +c010b2af: 83 f8 1f cmp $0x1f,%eax +c010b2b2: 77 56 ja c010b30a + //调用相应的系统调用处理函数 + if (syscalls[num] != NULL) { +c010b2b4: 8b 45 f0 mov -0x10(%ebp),%eax +c010b2b7: 8b 04 85 a0 fa 12 c0 mov -0x3fed0560(,%eax,4),%eax +c010b2be: 85 c0 test %eax,%eax +c010b2c0: 74 48 je c010b30a + arg[0] = tf->tf_regs.reg_edx; +c010b2c2: 8b 45 f4 mov -0xc(%ebp),%eax +c010b2c5: 8b 40 14 mov 0x14(%eax),%eax +c010b2c8: 89 45 dc mov %eax,-0x24(%ebp) + arg[1] = tf->tf_regs.reg_ecx; +c010b2cb: 8b 45 f4 mov -0xc(%ebp),%eax +c010b2ce: 8b 40 18 mov 0x18(%eax),%eax +c010b2d1: 89 45 e0 mov %eax,-0x20(%ebp) + arg[2] = tf->tf_regs.reg_ebx; +c010b2d4: 8b 45 f4 mov -0xc(%ebp),%eax +c010b2d7: 8b 40 10 mov 0x10(%eax),%eax +c010b2da: 89 45 e4 mov %eax,-0x1c(%ebp) + arg[3] = tf->tf_regs.reg_edi; +c010b2dd: 8b 45 f4 mov -0xc(%ebp),%eax +c010b2e0: 8b 00 mov (%eax),%eax +c010b2e2: 89 45 e8 mov %eax,-0x18(%ebp) + arg[4] = tf->tf_regs.reg_esi; +c010b2e5: 8b 45 f4 mov -0xc(%ebp),%eax +c010b2e8: 8b 40 04 mov 0x4(%eax),%eax +c010b2eb: 89 45 ec mov %eax,-0x14(%ebp) + tf->tf_regs.reg_eax = syscalls[num](arg); +c010b2ee: 8b 45 f0 mov -0x10(%ebp),%eax +c010b2f1: 8b 04 85 a0 fa 12 c0 mov -0x3fed0560(,%eax,4),%eax +c010b2f8: 8d 55 dc lea -0x24(%ebp),%edx +c010b2fb: 89 14 24 mov %edx,(%esp) +c010b2fe: ff d0 call *%eax +c010b300: 89 c2 mov %eax,%edx +c010b302: 8b 45 f4 mov -0xc(%ebp),%eax +c010b305: 89 50 1c mov %edx,0x1c(%eax) + return ; +c010b308: eb 46 jmp c010b350 + } + } + print_trapframe(tf); +c010b30a: 8b 45 f4 mov -0xc(%ebp),%eax +c010b30d: 89 04 24 mov %eax,(%esp) +c010b310: e8 98 70 ff ff call c01023ad + //处理无效系统调用 + panic("undefined syscall %d, pid = %d, name = %s.\n", +c010b315: a1 30 41 1a c0 mov 0xc01a4130,%eax +c010b31a: 8d 50 48 lea 0x48(%eax),%edx +c010b31d: a1 30 41 1a c0 mov 0xc01a4130,%eax +c010b322: 8b 40 04 mov 0x4(%eax),%eax +c010b325: 89 54 24 14 mov %edx,0x14(%esp) +c010b329: 89 44 24 10 mov %eax,0x10(%esp) +c010b32d: 8b 45 f0 mov -0x10(%ebp),%eax +c010b330: 89 44 24 0c mov %eax,0xc(%esp) +c010b334: c7 44 24 08 0c e5 10 movl $0xc010e50c,0x8(%esp) +c010b33b: c0 +c010b33c: c7 44 24 04 69 00 00 movl $0x69,0x4(%esp) +c010b343: 00 +c010b344: c7 04 24 38 e5 10 c0 movl $0xc010e538,(%esp) +c010b34b: e8 eb 59 ff ff call c0100d3b <__panic> + num, current->pid, current->name); +} +c010b350: 89 ec mov %ebp,%esp +c010b352: 5d pop %ebp +c010b353: c3 ret + +c010b354 : + * @bits: the number of bits in a return value + * + * High bits are more random, so we use them. + * */ +uint32_t +hash32(uint32_t val, unsigned int bits) { +c010b354: 55 push %ebp +c010b355: 89 e5 mov %esp,%ebp +c010b357: 83 ec 10 sub $0x10,%esp + uint32_t hash = val * GOLDEN_RATIO_PRIME_32; +c010b35a: 8b 45 08 mov 0x8(%ebp),%eax +c010b35d: 69 c0 01 00 37 9e imul $0x9e370001,%eax,%eax +c010b363: 89 45 fc mov %eax,-0x4(%ebp) + return (hash >> (32 - bits)); +c010b366: b8 20 00 00 00 mov $0x20,%eax +c010b36b: 2b 45 0c sub 0xc(%ebp),%eax +c010b36e: 8b 55 fc mov -0x4(%ebp),%edx +c010b371: 88 c1 mov %al,%cl +c010b373: d3 ea shr %cl,%edx +c010b375: 89 d0 mov %edx,%eax +} +c010b377: 89 ec mov %ebp,%esp +c010b379: 5d pop %ebp +c010b37a: c3 ret + +c010b37b : + * @width: maximum number of digits, if the actual width is less than @width, use @padc instead + * @padc: character that padded on the left if the actual width is less than @width + * */ +static void +printnum(void (*putch)(int, void*), void *putdat, + unsigned long long num, unsigned base, int width, int padc) { +c010b37b: 55 push %ebp +c010b37c: 89 e5 mov %esp,%ebp +c010b37e: 83 ec 58 sub $0x58,%esp +c010b381: 8b 45 10 mov 0x10(%ebp),%eax +c010b384: 89 45 d0 mov %eax,-0x30(%ebp) +c010b387: 8b 45 14 mov 0x14(%ebp),%eax +c010b38a: 89 45 d4 mov %eax,-0x2c(%ebp) + unsigned long long result = num; +c010b38d: 8b 45 d0 mov -0x30(%ebp),%eax +c010b390: 8b 55 d4 mov -0x2c(%ebp),%edx +c010b393: 89 45 e8 mov %eax,-0x18(%ebp) +c010b396: 89 55 ec mov %edx,-0x14(%ebp) + unsigned mod = do_div(result, base); +c010b399: 8b 45 18 mov 0x18(%ebp),%eax +c010b39c: 89 45 e4 mov %eax,-0x1c(%ebp) +c010b39f: 8b 45 e8 mov -0x18(%ebp),%eax +c010b3a2: 8b 55 ec mov -0x14(%ebp),%edx +c010b3a5: 89 45 e0 mov %eax,-0x20(%ebp) +c010b3a8: 89 55 f0 mov %edx,-0x10(%ebp) +c010b3ab: 8b 45 f0 mov -0x10(%ebp),%eax +c010b3ae: 89 45 f4 mov %eax,-0xc(%ebp) +c010b3b1: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) +c010b3b5: 74 1c je c010b3d3 +c010b3b7: 8b 45 f0 mov -0x10(%ebp),%eax +c010b3ba: ba 00 00 00 00 mov $0x0,%edx +c010b3bf: f7 75 e4 divl -0x1c(%ebp) +c010b3c2: 89 55 f4 mov %edx,-0xc(%ebp) +c010b3c5: 8b 45 f0 mov -0x10(%ebp),%eax +c010b3c8: ba 00 00 00 00 mov $0x0,%edx +c010b3cd: f7 75 e4 divl -0x1c(%ebp) +c010b3d0: 89 45 f0 mov %eax,-0x10(%ebp) +c010b3d3: 8b 45 e0 mov -0x20(%ebp),%eax +c010b3d6: 8b 55 f4 mov -0xc(%ebp),%edx +c010b3d9: f7 75 e4 divl -0x1c(%ebp) +c010b3dc: 89 45 e0 mov %eax,-0x20(%ebp) +c010b3df: 89 55 dc mov %edx,-0x24(%ebp) +c010b3e2: 8b 45 e0 mov -0x20(%ebp),%eax +c010b3e5: 8b 55 f0 mov -0x10(%ebp),%edx +c010b3e8: 89 45 e8 mov %eax,-0x18(%ebp) +c010b3eb: 89 55 ec mov %edx,-0x14(%ebp) +c010b3ee: 8b 45 dc mov -0x24(%ebp),%eax +c010b3f1: 89 45 d8 mov %eax,-0x28(%ebp) + + // first recursively print all preceding (more significant) digits + if (num >= base) { +c010b3f4: 8b 45 18 mov 0x18(%ebp),%eax +c010b3f7: ba 00 00 00 00 mov $0x0,%edx +c010b3fc: 8b 4d d4 mov -0x2c(%ebp),%ecx +c010b3ff: 39 45 d0 cmp %eax,-0x30(%ebp) +c010b402: 19 d1 sbb %edx,%ecx +c010b404: 72 4c jb c010b452 + printnum(putch, putdat, result, base, width - 1, padc); +c010b406: 8b 45 1c mov 0x1c(%ebp),%eax +c010b409: 8d 50 ff lea -0x1(%eax),%edx +c010b40c: 8b 45 20 mov 0x20(%ebp),%eax +c010b40f: 89 44 24 18 mov %eax,0x18(%esp) +c010b413: 89 54 24 14 mov %edx,0x14(%esp) +c010b417: 8b 45 18 mov 0x18(%ebp),%eax +c010b41a: 89 44 24 10 mov %eax,0x10(%esp) +c010b41e: 8b 45 e8 mov -0x18(%ebp),%eax +c010b421: 8b 55 ec mov -0x14(%ebp),%edx +c010b424: 89 44 24 08 mov %eax,0x8(%esp) +c010b428: 89 54 24 0c mov %edx,0xc(%esp) +c010b42c: 8b 45 0c mov 0xc(%ebp),%eax +c010b42f: 89 44 24 04 mov %eax,0x4(%esp) +c010b433: 8b 45 08 mov 0x8(%ebp),%eax +c010b436: 89 04 24 mov %eax,(%esp) +c010b439: e8 3d ff ff ff call c010b37b +c010b43e: eb 1b jmp c010b45b + } else { + // print any needed pad characters before first digit + while (-- width > 0) + putch(padc, putdat); +c010b440: 8b 45 0c mov 0xc(%ebp),%eax +c010b443: 89 44 24 04 mov %eax,0x4(%esp) +c010b447: 8b 45 20 mov 0x20(%ebp),%eax +c010b44a: 89 04 24 mov %eax,(%esp) +c010b44d: 8b 45 08 mov 0x8(%ebp),%eax +c010b450: ff d0 call *%eax + while (-- width > 0) +c010b452: ff 4d 1c decl 0x1c(%ebp) +c010b455: 83 7d 1c 00 cmpl $0x0,0x1c(%ebp) +c010b459: 7f e5 jg c010b440 + } + // then print this (the least significant) digit + putch("0123456789abcdef"[mod], putdat); +c010b45b: 8b 45 d8 mov -0x28(%ebp),%eax +c010b45e: 05 64 e6 10 c0 add $0xc010e664,%eax +c010b463: 0f b6 00 movzbl (%eax),%eax +c010b466: 0f be c0 movsbl %al,%eax +c010b469: 8b 55 0c mov 0xc(%ebp),%edx +c010b46c: 89 54 24 04 mov %edx,0x4(%esp) +c010b470: 89 04 24 mov %eax,(%esp) +c010b473: 8b 45 08 mov 0x8(%ebp),%eax +c010b476: ff d0 call *%eax +} +c010b478: 90 nop +c010b479: 89 ec mov %ebp,%esp +c010b47b: 5d pop %ebp +c010b47c: c3 ret + +c010b47d : + * getuint - get an unsigned int of various possible sizes from a varargs list + * @ap: a varargs list pointer + * @lflag: determines the size of the vararg that @ap points to + * */ +static unsigned long long +getuint(va_list *ap, int lflag) { +c010b47d: 55 push %ebp +c010b47e: 89 e5 mov %esp,%ebp + if (lflag >= 2) { +c010b480: 83 7d 0c 01 cmpl $0x1,0xc(%ebp) +c010b484: 7e 14 jle c010b49a + return va_arg(*ap, unsigned long long); +c010b486: 8b 45 08 mov 0x8(%ebp),%eax +c010b489: 8b 00 mov (%eax),%eax +c010b48b: 8d 48 08 lea 0x8(%eax),%ecx +c010b48e: 8b 55 08 mov 0x8(%ebp),%edx +c010b491: 89 0a mov %ecx,(%edx) +c010b493: 8b 50 04 mov 0x4(%eax),%edx +c010b496: 8b 00 mov (%eax),%eax +c010b498: eb 30 jmp c010b4ca + } + else if (lflag) { +c010b49a: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) +c010b49e: 74 16 je c010b4b6 + return va_arg(*ap, unsigned long); +c010b4a0: 8b 45 08 mov 0x8(%ebp),%eax +c010b4a3: 8b 00 mov (%eax),%eax +c010b4a5: 8d 48 04 lea 0x4(%eax),%ecx +c010b4a8: 8b 55 08 mov 0x8(%ebp),%edx +c010b4ab: 89 0a mov %ecx,(%edx) +c010b4ad: 8b 00 mov (%eax),%eax +c010b4af: ba 00 00 00 00 mov $0x0,%edx +c010b4b4: eb 14 jmp c010b4ca + } + else { + return va_arg(*ap, unsigned int); +c010b4b6: 8b 45 08 mov 0x8(%ebp),%eax +c010b4b9: 8b 00 mov (%eax),%eax +c010b4bb: 8d 48 04 lea 0x4(%eax),%ecx +c010b4be: 8b 55 08 mov 0x8(%ebp),%edx +c010b4c1: 89 0a mov %ecx,(%edx) +c010b4c3: 8b 00 mov (%eax),%eax +c010b4c5: ba 00 00 00 00 mov $0x0,%edx + } +} +c010b4ca: 5d pop %ebp +c010b4cb: c3 ret + +c010b4cc : + * getint - same as getuint but signed, we can't use getuint because of sign extension + * @ap: a varargs list pointer + * @lflag: determines the size of the vararg that @ap points to + * */ +static long long +getint(va_list *ap, int lflag) { +c010b4cc: 55 push %ebp +c010b4cd: 89 e5 mov %esp,%ebp + if (lflag >= 2) { +c010b4cf: 83 7d 0c 01 cmpl $0x1,0xc(%ebp) +c010b4d3: 7e 14 jle c010b4e9 + return va_arg(*ap, long long); +c010b4d5: 8b 45 08 mov 0x8(%ebp),%eax +c010b4d8: 8b 00 mov (%eax),%eax +c010b4da: 8d 48 08 lea 0x8(%eax),%ecx +c010b4dd: 8b 55 08 mov 0x8(%ebp),%edx +c010b4e0: 89 0a mov %ecx,(%edx) +c010b4e2: 8b 50 04 mov 0x4(%eax),%edx +c010b4e5: 8b 00 mov (%eax),%eax +c010b4e7: eb 28 jmp c010b511 + } + else if (lflag) { +c010b4e9: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) +c010b4ed: 74 12 je c010b501 + return va_arg(*ap, long); +c010b4ef: 8b 45 08 mov 0x8(%ebp),%eax +c010b4f2: 8b 00 mov (%eax),%eax +c010b4f4: 8d 48 04 lea 0x4(%eax),%ecx +c010b4f7: 8b 55 08 mov 0x8(%ebp),%edx +c010b4fa: 89 0a mov %ecx,(%edx) +c010b4fc: 8b 00 mov (%eax),%eax +c010b4fe: 99 cltd +c010b4ff: eb 10 jmp c010b511 + } + else { + return va_arg(*ap, int); +c010b501: 8b 45 08 mov 0x8(%ebp),%eax +c010b504: 8b 00 mov (%eax),%eax +c010b506: 8d 48 04 lea 0x4(%eax),%ecx +c010b509: 8b 55 08 mov 0x8(%ebp),%edx +c010b50c: 89 0a mov %ecx,(%edx) +c010b50e: 8b 00 mov (%eax),%eax +c010b510: 99 cltd + } +} +c010b511: 5d pop %ebp +c010b512: c3 ret + +c010b513 : + * @putch: specified putch function, print a single character + * @putdat: used by @putch function + * @fmt: the format string to use + * */ +void +printfmt(void (*putch)(int, void*), void *putdat, const char *fmt, ...) { +c010b513: 55 push %ebp +c010b514: 89 e5 mov %esp,%ebp +c010b516: 83 ec 28 sub $0x28,%esp + va_list ap; + + va_start(ap, fmt); +c010b519: 8d 45 14 lea 0x14(%ebp),%eax +c010b51c: 89 45 f4 mov %eax,-0xc(%ebp) + vprintfmt(putch, putdat, fmt, ap); +c010b51f: 8b 45 f4 mov -0xc(%ebp),%eax +c010b522: 89 44 24 0c mov %eax,0xc(%esp) +c010b526: 8b 45 10 mov 0x10(%ebp),%eax +c010b529: 89 44 24 08 mov %eax,0x8(%esp) +c010b52d: 8b 45 0c mov 0xc(%ebp),%eax +c010b530: 89 44 24 04 mov %eax,0x4(%esp) +c010b534: 8b 45 08 mov 0x8(%ebp),%eax +c010b537: 89 04 24 mov %eax,(%esp) +c010b53a: e8 05 00 00 00 call c010b544 + va_end(ap); +} +c010b53f: 90 nop +c010b540: 89 ec mov %ebp,%esp +c010b542: 5d pop %ebp +c010b543: c3 ret + +c010b544 : + * + * Call this function if you are already dealing with a va_list. + * Or you probably want printfmt() instead. + * */ +void +vprintfmt(void (*putch)(int, void*), void *putdat, const char *fmt, va_list ap) { +c010b544: 55 push %ebp +c010b545: 89 e5 mov %esp,%ebp +c010b547: 56 push %esi +c010b548: 53 push %ebx +c010b549: 83 ec 40 sub $0x40,%esp + register int ch, err; + unsigned long long num; + int base, width, precision, lflag, altflag; + + while (1) { + while ((ch = *(unsigned char *)fmt ++) != '%') { +c010b54c: eb 17 jmp c010b565 + if (ch == '\0') { +c010b54e: 85 db test %ebx,%ebx +c010b550: 0f 84 bf 03 00 00 je c010b915 + return; + } + putch(ch, putdat); +c010b556: 8b 45 0c mov 0xc(%ebp),%eax +c010b559: 89 44 24 04 mov %eax,0x4(%esp) +c010b55d: 89 1c 24 mov %ebx,(%esp) +c010b560: 8b 45 08 mov 0x8(%ebp),%eax +c010b563: ff d0 call *%eax + while ((ch = *(unsigned char *)fmt ++) != '%') { +c010b565: 8b 45 10 mov 0x10(%ebp),%eax +c010b568: 8d 50 01 lea 0x1(%eax),%edx +c010b56b: 89 55 10 mov %edx,0x10(%ebp) +c010b56e: 0f b6 00 movzbl (%eax),%eax +c010b571: 0f b6 d8 movzbl %al,%ebx +c010b574: 83 fb 25 cmp $0x25,%ebx +c010b577: 75 d5 jne c010b54e + } + + // Process a %-escape sequence + char padc = ' '; +c010b579: c6 45 db 20 movb $0x20,-0x25(%ebp) + width = precision = -1; +c010b57d: c7 45 e4 ff ff ff ff movl $0xffffffff,-0x1c(%ebp) +c010b584: 8b 45 e4 mov -0x1c(%ebp),%eax +c010b587: 89 45 e8 mov %eax,-0x18(%ebp) + lflag = altflag = 0; +c010b58a: c7 45 dc 00 00 00 00 movl $0x0,-0x24(%ebp) +c010b591: 8b 45 dc mov -0x24(%ebp),%eax +c010b594: 89 45 e0 mov %eax,-0x20(%ebp) + + reswitch: + switch (ch = *(unsigned char *)fmt ++) { +c010b597: 8b 45 10 mov 0x10(%ebp),%eax +c010b59a: 8d 50 01 lea 0x1(%eax),%edx +c010b59d: 89 55 10 mov %edx,0x10(%ebp) +c010b5a0: 0f b6 00 movzbl (%eax),%eax +c010b5a3: 0f b6 d8 movzbl %al,%ebx +c010b5a6: 8d 43 dd lea -0x23(%ebx),%eax +c010b5a9: 83 f8 55 cmp $0x55,%eax +c010b5ac: 0f 87 37 03 00 00 ja c010b8e9 +c010b5b2: 8b 04 85 88 e6 10 c0 mov -0x3fef1978(,%eax,4),%eax +c010b5b9: ff e0 jmp *%eax + + // flag to pad on the right + case '-': + padc = '-'; +c010b5bb: c6 45 db 2d movb $0x2d,-0x25(%ebp) + goto reswitch; +c010b5bf: eb d6 jmp c010b597 + + // flag to pad with 0's instead of spaces + case '0': + padc = '0'; +c010b5c1: c6 45 db 30 movb $0x30,-0x25(%ebp) + goto reswitch; +c010b5c5: eb d0 jmp c010b597 + + // width field + case '1' ... '9': + for (precision = 0; ; ++ fmt) { +c010b5c7: c7 45 e4 00 00 00 00 movl $0x0,-0x1c(%ebp) + precision = precision * 10 + ch - '0'; +c010b5ce: 8b 55 e4 mov -0x1c(%ebp),%edx +c010b5d1: 89 d0 mov %edx,%eax +c010b5d3: c1 e0 02 shl $0x2,%eax +c010b5d6: 01 d0 add %edx,%eax +c010b5d8: 01 c0 add %eax,%eax +c010b5da: 01 d8 add %ebx,%eax +c010b5dc: 83 e8 30 sub $0x30,%eax +c010b5df: 89 45 e4 mov %eax,-0x1c(%ebp) + ch = *fmt; +c010b5e2: 8b 45 10 mov 0x10(%ebp),%eax +c010b5e5: 0f b6 00 movzbl (%eax),%eax +c010b5e8: 0f be d8 movsbl %al,%ebx + if (ch < '0' || ch > '9') { +c010b5eb: 83 fb 2f cmp $0x2f,%ebx +c010b5ee: 7e 38 jle c010b628 +c010b5f0: 83 fb 39 cmp $0x39,%ebx +c010b5f3: 7f 33 jg c010b628 + for (precision = 0; ; ++ fmt) { +c010b5f5: ff 45 10 incl 0x10(%ebp) + precision = precision * 10 + ch - '0'; +c010b5f8: eb d4 jmp c010b5ce + } + } + goto process_precision; + + case '*': + precision = va_arg(ap, int); +c010b5fa: 8b 45 14 mov 0x14(%ebp),%eax +c010b5fd: 8d 50 04 lea 0x4(%eax),%edx +c010b600: 89 55 14 mov %edx,0x14(%ebp) +c010b603: 8b 00 mov (%eax),%eax +c010b605: 89 45 e4 mov %eax,-0x1c(%ebp) + goto process_precision; +c010b608: eb 1f jmp c010b629 + + case '.': + if (width < 0) +c010b60a: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) +c010b60e: 79 87 jns c010b597 + width = 0; +c010b610: c7 45 e8 00 00 00 00 movl $0x0,-0x18(%ebp) + goto reswitch; +c010b617: e9 7b ff ff ff jmp c010b597 + + case '#': + altflag = 1; +c010b61c: c7 45 dc 01 00 00 00 movl $0x1,-0x24(%ebp) + goto reswitch; +c010b623: e9 6f ff ff ff jmp c010b597 + goto process_precision; +c010b628: 90 nop + + process_precision: + if (width < 0) +c010b629: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) +c010b62d: 0f 89 64 ff ff ff jns c010b597 + width = precision, precision = -1; +c010b633: 8b 45 e4 mov -0x1c(%ebp),%eax +c010b636: 89 45 e8 mov %eax,-0x18(%ebp) +c010b639: c7 45 e4 ff ff ff ff movl $0xffffffff,-0x1c(%ebp) + goto reswitch; +c010b640: e9 52 ff ff ff jmp c010b597 + + // long flag (doubled for long long) + case 'l': + lflag ++; +c010b645: ff 45 e0 incl -0x20(%ebp) + goto reswitch; +c010b648: e9 4a ff ff ff jmp c010b597 + + // character + case 'c': + putch(va_arg(ap, int), putdat); +c010b64d: 8b 45 14 mov 0x14(%ebp),%eax +c010b650: 8d 50 04 lea 0x4(%eax),%edx +c010b653: 89 55 14 mov %edx,0x14(%ebp) +c010b656: 8b 00 mov (%eax),%eax +c010b658: 8b 55 0c mov 0xc(%ebp),%edx +c010b65b: 89 54 24 04 mov %edx,0x4(%esp) +c010b65f: 89 04 24 mov %eax,(%esp) +c010b662: 8b 45 08 mov 0x8(%ebp),%eax +c010b665: ff d0 call *%eax + break; +c010b667: e9 a4 02 00 00 jmp c010b910 + + // error message + case 'e': + err = va_arg(ap, int); +c010b66c: 8b 45 14 mov 0x14(%ebp),%eax +c010b66f: 8d 50 04 lea 0x4(%eax),%edx +c010b672: 89 55 14 mov %edx,0x14(%ebp) +c010b675: 8b 18 mov (%eax),%ebx + if (err < 0) { +c010b677: 85 db test %ebx,%ebx +c010b679: 79 02 jns c010b67d + err = -err; +c010b67b: f7 db neg %ebx + } + if (err > MAXERROR || (p = error_string[err]) == NULL) { +c010b67d: 83 fb 18 cmp $0x18,%ebx +c010b680: 7f 0b jg c010b68d +c010b682: 8b 34 9d 00 e6 10 c0 mov -0x3fef1a00(,%ebx,4),%esi +c010b689: 85 f6 test %esi,%esi +c010b68b: 75 23 jne c010b6b0 + printfmt(putch, putdat, "error %d", err); +c010b68d: 89 5c 24 0c mov %ebx,0xc(%esp) +c010b691: c7 44 24 08 75 e6 10 movl $0xc010e675,0x8(%esp) +c010b698: c0 +c010b699: 8b 45 0c mov 0xc(%ebp),%eax +c010b69c: 89 44 24 04 mov %eax,0x4(%esp) +c010b6a0: 8b 45 08 mov 0x8(%ebp),%eax +c010b6a3: 89 04 24 mov %eax,(%esp) +c010b6a6: e8 68 fe ff ff call c010b513 + } + else { + printfmt(putch, putdat, "%s", p); + } + break; +c010b6ab: e9 60 02 00 00 jmp c010b910 + printfmt(putch, putdat, "%s", p); +c010b6b0: 89 74 24 0c mov %esi,0xc(%esp) +c010b6b4: c7 44 24 08 7e e6 10 movl $0xc010e67e,0x8(%esp) +c010b6bb: c0 +c010b6bc: 8b 45 0c mov 0xc(%ebp),%eax +c010b6bf: 89 44 24 04 mov %eax,0x4(%esp) +c010b6c3: 8b 45 08 mov 0x8(%ebp),%eax +c010b6c6: 89 04 24 mov %eax,(%esp) +c010b6c9: e8 45 fe ff ff call c010b513 + break; +c010b6ce: e9 3d 02 00 00 jmp c010b910 + + // string + case 's': + if ((p = va_arg(ap, char *)) == NULL) { +c010b6d3: 8b 45 14 mov 0x14(%ebp),%eax +c010b6d6: 8d 50 04 lea 0x4(%eax),%edx +c010b6d9: 89 55 14 mov %edx,0x14(%ebp) +c010b6dc: 8b 30 mov (%eax),%esi +c010b6de: 85 f6 test %esi,%esi +c010b6e0: 75 05 jne c010b6e7 + p = "(null)"; +c010b6e2: be 81 e6 10 c0 mov $0xc010e681,%esi + } + if (width > 0 && padc != '-') { +c010b6e7: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) +c010b6eb: 7e 76 jle c010b763 +c010b6ed: 80 7d db 2d cmpb $0x2d,-0x25(%ebp) +c010b6f1: 74 70 je c010b763 + for (width -= strnlen(p, precision); width > 0; width --) { +c010b6f3: 8b 45 e4 mov -0x1c(%ebp),%eax +c010b6f6: 89 44 24 04 mov %eax,0x4(%esp) +c010b6fa: 89 34 24 mov %esi,(%esp) +c010b6fd: e8 ee 03 00 00 call c010baf0 +c010b702: 89 c2 mov %eax,%edx +c010b704: 8b 45 e8 mov -0x18(%ebp),%eax +c010b707: 29 d0 sub %edx,%eax +c010b709: 89 45 e8 mov %eax,-0x18(%ebp) +c010b70c: eb 16 jmp c010b724 + putch(padc, putdat); +c010b70e: 0f be 45 db movsbl -0x25(%ebp),%eax +c010b712: 8b 55 0c mov 0xc(%ebp),%edx +c010b715: 89 54 24 04 mov %edx,0x4(%esp) +c010b719: 89 04 24 mov %eax,(%esp) +c010b71c: 8b 45 08 mov 0x8(%ebp),%eax +c010b71f: ff d0 call *%eax + for (width -= strnlen(p, precision); width > 0; width --) { +c010b721: ff 4d e8 decl -0x18(%ebp) +c010b724: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) +c010b728: 7f e4 jg c010b70e + } + } + for (; (ch = *p ++) != '\0' && (precision < 0 || -- precision >= 0); width --) { +c010b72a: eb 37 jmp c010b763 + if (altflag && (ch < ' ' || ch > '~')) { +c010b72c: 83 7d dc 00 cmpl $0x0,-0x24(%ebp) +c010b730: 74 1f je c010b751 +c010b732: 83 fb 1f cmp $0x1f,%ebx +c010b735: 7e 05 jle c010b73c +c010b737: 83 fb 7e cmp $0x7e,%ebx +c010b73a: 7e 15 jle c010b751 + putch('?', putdat); +c010b73c: 8b 45 0c mov 0xc(%ebp),%eax +c010b73f: 89 44 24 04 mov %eax,0x4(%esp) +c010b743: c7 04 24 3f 00 00 00 movl $0x3f,(%esp) +c010b74a: 8b 45 08 mov 0x8(%ebp),%eax +c010b74d: ff d0 call *%eax +c010b74f: eb 0f jmp c010b760 + } + else { + putch(ch, putdat); +c010b751: 8b 45 0c mov 0xc(%ebp),%eax +c010b754: 89 44 24 04 mov %eax,0x4(%esp) +c010b758: 89 1c 24 mov %ebx,(%esp) +c010b75b: 8b 45 08 mov 0x8(%ebp),%eax +c010b75e: ff d0 call *%eax + for (; (ch = *p ++) != '\0' && (precision < 0 || -- precision >= 0); width --) { +c010b760: ff 4d e8 decl -0x18(%ebp) +c010b763: 89 f0 mov %esi,%eax +c010b765: 8d 70 01 lea 0x1(%eax),%esi +c010b768: 0f b6 00 movzbl (%eax),%eax +c010b76b: 0f be d8 movsbl %al,%ebx +c010b76e: 85 db test %ebx,%ebx +c010b770: 74 27 je c010b799 +c010b772: 83 7d e4 00 cmpl $0x0,-0x1c(%ebp) +c010b776: 78 b4 js c010b72c +c010b778: ff 4d e4 decl -0x1c(%ebp) +c010b77b: 83 7d e4 00 cmpl $0x0,-0x1c(%ebp) +c010b77f: 79 ab jns c010b72c + } + } + for (; width > 0; width --) { +c010b781: eb 16 jmp c010b799 + putch(' ', putdat); +c010b783: 8b 45 0c mov 0xc(%ebp),%eax +c010b786: 89 44 24 04 mov %eax,0x4(%esp) +c010b78a: c7 04 24 20 00 00 00 movl $0x20,(%esp) +c010b791: 8b 45 08 mov 0x8(%ebp),%eax +c010b794: ff d0 call *%eax + for (; width > 0; width --) { +c010b796: ff 4d e8 decl -0x18(%ebp) +c010b799: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) +c010b79d: 7f e4 jg c010b783 + } + break; +c010b79f: e9 6c 01 00 00 jmp c010b910 + + // (signed) decimal + case 'd': + num = getint(&ap, lflag); +c010b7a4: 8b 45 e0 mov -0x20(%ebp),%eax +c010b7a7: 89 44 24 04 mov %eax,0x4(%esp) +c010b7ab: 8d 45 14 lea 0x14(%ebp),%eax +c010b7ae: 89 04 24 mov %eax,(%esp) +c010b7b1: e8 16 fd ff ff call c010b4cc +c010b7b6: 89 45 f0 mov %eax,-0x10(%ebp) +c010b7b9: 89 55 f4 mov %edx,-0xc(%ebp) + if ((long long)num < 0) { +c010b7bc: 8b 45 f0 mov -0x10(%ebp),%eax +c010b7bf: 8b 55 f4 mov -0xc(%ebp),%edx +c010b7c2: 85 d2 test %edx,%edx +c010b7c4: 79 26 jns c010b7ec + putch('-', putdat); +c010b7c6: 8b 45 0c mov 0xc(%ebp),%eax +c010b7c9: 89 44 24 04 mov %eax,0x4(%esp) +c010b7cd: c7 04 24 2d 00 00 00 movl $0x2d,(%esp) +c010b7d4: 8b 45 08 mov 0x8(%ebp),%eax +c010b7d7: ff d0 call *%eax + num = -(long long)num; +c010b7d9: 8b 45 f0 mov -0x10(%ebp),%eax +c010b7dc: 8b 55 f4 mov -0xc(%ebp),%edx +c010b7df: f7 d8 neg %eax +c010b7e1: 83 d2 00 adc $0x0,%edx +c010b7e4: f7 da neg %edx +c010b7e6: 89 45 f0 mov %eax,-0x10(%ebp) +c010b7e9: 89 55 f4 mov %edx,-0xc(%ebp) + } + base = 10; +c010b7ec: c7 45 ec 0a 00 00 00 movl $0xa,-0x14(%ebp) + goto number; +c010b7f3: e9 a8 00 00 00 jmp c010b8a0 + + // unsigned decimal + case 'u': + num = getuint(&ap, lflag); +c010b7f8: 8b 45 e0 mov -0x20(%ebp),%eax +c010b7fb: 89 44 24 04 mov %eax,0x4(%esp) +c010b7ff: 8d 45 14 lea 0x14(%ebp),%eax +c010b802: 89 04 24 mov %eax,(%esp) +c010b805: e8 73 fc ff ff call c010b47d +c010b80a: 89 45 f0 mov %eax,-0x10(%ebp) +c010b80d: 89 55 f4 mov %edx,-0xc(%ebp) + base = 10; +c010b810: c7 45 ec 0a 00 00 00 movl $0xa,-0x14(%ebp) + goto number; +c010b817: e9 84 00 00 00 jmp c010b8a0 + + // (unsigned) octal + case 'o': + num = getuint(&ap, lflag); +c010b81c: 8b 45 e0 mov -0x20(%ebp),%eax +c010b81f: 89 44 24 04 mov %eax,0x4(%esp) +c010b823: 8d 45 14 lea 0x14(%ebp),%eax +c010b826: 89 04 24 mov %eax,(%esp) +c010b829: e8 4f fc ff ff call c010b47d +c010b82e: 89 45 f0 mov %eax,-0x10(%ebp) +c010b831: 89 55 f4 mov %edx,-0xc(%ebp) + base = 8; +c010b834: c7 45 ec 08 00 00 00 movl $0x8,-0x14(%ebp) + goto number; +c010b83b: eb 63 jmp c010b8a0 + + // pointer + case 'p': + putch('0', putdat); +c010b83d: 8b 45 0c mov 0xc(%ebp),%eax +c010b840: 89 44 24 04 mov %eax,0x4(%esp) +c010b844: c7 04 24 30 00 00 00 movl $0x30,(%esp) +c010b84b: 8b 45 08 mov 0x8(%ebp),%eax +c010b84e: ff d0 call *%eax + putch('x', putdat); +c010b850: 8b 45 0c mov 0xc(%ebp),%eax +c010b853: 89 44 24 04 mov %eax,0x4(%esp) +c010b857: c7 04 24 78 00 00 00 movl $0x78,(%esp) +c010b85e: 8b 45 08 mov 0x8(%ebp),%eax +c010b861: ff d0 call *%eax + num = (unsigned long long)(uintptr_t)va_arg(ap, void *); +c010b863: 8b 45 14 mov 0x14(%ebp),%eax +c010b866: 8d 50 04 lea 0x4(%eax),%edx +c010b869: 89 55 14 mov %edx,0x14(%ebp) +c010b86c: 8b 00 mov (%eax),%eax +c010b86e: 89 45 f0 mov %eax,-0x10(%ebp) +c010b871: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + base = 16; +c010b878: c7 45 ec 10 00 00 00 movl $0x10,-0x14(%ebp) + goto number; +c010b87f: eb 1f jmp c010b8a0 + + // (unsigned) hexadecimal + case 'x': + num = getuint(&ap, lflag); +c010b881: 8b 45 e0 mov -0x20(%ebp),%eax +c010b884: 89 44 24 04 mov %eax,0x4(%esp) +c010b888: 8d 45 14 lea 0x14(%ebp),%eax +c010b88b: 89 04 24 mov %eax,(%esp) +c010b88e: e8 ea fb ff ff call c010b47d +c010b893: 89 45 f0 mov %eax,-0x10(%ebp) +c010b896: 89 55 f4 mov %edx,-0xc(%ebp) + base = 16; +c010b899: c7 45 ec 10 00 00 00 movl $0x10,-0x14(%ebp) + number: + printnum(putch, putdat, num, base, width, padc); +c010b8a0: 0f be 55 db movsbl -0x25(%ebp),%edx +c010b8a4: 8b 45 ec mov -0x14(%ebp),%eax +c010b8a7: 89 54 24 18 mov %edx,0x18(%esp) +c010b8ab: 8b 55 e8 mov -0x18(%ebp),%edx +c010b8ae: 89 54 24 14 mov %edx,0x14(%esp) +c010b8b2: 89 44 24 10 mov %eax,0x10(%esp) +c010b8b6: 8b 45 f0 mov -0x10(%ebp),%eax +c010b8b9: 8b 55 f4 mov -0xc(%ebp),%edx +c010b8bc: 89 44 24 08 mov %eax,0x8(%esp) +c010b8c0: 89 54 24 0c mov %edx,0xc(%esp) +c010b8c4: 8b 45 0c mov 0xc(%ebp),%eax +c010b8c7: 89 44 24 04 mov %eax,0x4(%esp) +c010b8cb: 8b 45 08 mov 0x8(%ebp),%eax +c010b8ce: 89 04 24 mov %eax,(%esp) +c010b8d1: e8 a5 fa ff ff call c010b37b + break; +c010b8d6: eb 38 jmp c010b910 + + // escaped '%' character + case '%': + putch(ch, putdat); +c010b8d8: 8b 45 0c mov 0xc(%ebp),%eax +c010b8db: 89 44 24 04 mov %eax,0x4(%esp) +c010b8df: 89 1c 24 mov %ebx,(%esp) +c010b8e2: 8b 45 08 mov 0x8(%ebp),%eax +c010b8e5: ff d0 call *%eax + break; +c010b8e7: eb 27 jmp c010b910 + + // unrecognized escape sequence - just print it literally + default: + putch('%', putdat); +c010b8e9: 8b 45 0c mov 0xc(%ebp),%eax +c010b8ec: 89 44 24 04 mov %eax,0x4(%esp) +c010b8f0: c7 04 24 25 00 00 00 movl $0x25,(%esp) +c010b8f7: 8b 45 08 mov 0x8(%ebp),%eax +c010b8fa: ff d0 call *%eax + for (fmt --; fmt[-1] != '%'; fmt --) +c010b8fc: ff 4d 10 decl 0x10(%ebp) +c010b8ff: eb 03 jmp c010b904 +c010b901: ff 4d 10 decl 0x10(%ebp) +c010b904: 8b 45 10 mov 0x10(%ebp),%eax +c010b907: 48 dec %eax +c010b908: 0f b6 00 movzbl (%eax),%eax +c010b90b: 3c 25 cmp $0x25,%al +c010b90d: 75 f2 jne c010b901 + /* do nothing */; + break; +c010b90f: 90 nop + while (1) { +c010b910: e9 37 fc ff ff jmp c010b54c + return; +c010b915: 90 nop + } + } +} +c010b916: 83 c4 40 add $0x40,%esp +c010b919: 5b pop %ebx +c010b91a: 5e pop %esi +c010b91b: 5d pop %ebp +c010b91c: c3 ret + +c010b91d : + * sprintputch - 'print' a single character in a buffer + * @ch: the character will be printed + * @b: the buffer to place the character @ch + * */ +static void +sprintputch(int ch, struct sprintbuf *b) { +c010b91d: 55 push %ebp +c010b91e: 89 e5 mov %esp,%ebp + b->cnt ++; +c010b920: 8b 45 0c mov 0xc(%ebp),%eax +c010b923: 8b 40 08 mov 0x8(%eax),%eax +c010b926: 8d 50 01 lea 0x1(%eax),%edx +c010b929: 8b 45 0c mov 0xc(%ebp),%eax +c010b92c: 89 50 08 mov %edx,0x8(%eax) + if (b->buf < b->ebuf) { +c010b92f: 8b 45 0c mov 0xc(%ebp),%eax +c010b932: 8b 10 mov (%eax),%edx +c010b934: 8b 45 0c mov 0xc(%ebp),%eax +c010b937: 8b 40 04 mov 0x4(%eax),%eax +c010b93a: 39 c2 cmp %eax,%edx +c010b93c: 73 12 jae c010b950 + *b->buf ++ = ch; +c010b93e: 8b 45 0c mov 0xc(%ebp),%eax +c010b941: 8b 00 mov (%eax),%eax +c010b943: 8d 48 01 lea 0x1(%eax),%ecx +c010b946: 8b 55 0c mov 0xc(%ebp),%edx +c010b949: 89 0a mov %ecx,(%edx) +c010b94b: 8b 55 08 mov 0x8(%ebp),%edx +c010b94e: 88 10 mov %dl,(%eax) + } +} +c010b950: 90 nop +c010b951: 5d pop %ebp +c010b952: c3 ret + +c010b953 : + * @str: the buffer to place the result into + * @size: the size of buffer, including the trailing null space + * @fmt: the format string to use + * */ +int +snprintf(char *str, size_t size, const char *fmt, ...) { +c010b953: 55 push %ebp +c010b954: 89 e5 mov %esp,%ebp +c010b956: 83 ec 28 sub $0x28,%esp + va_list ap; + int cnt; + va_start(ap, fmt); +c010b959: 8d 45 14 lea 0x14(%ebp),%eax +c010b95c: 89 45 f0 mov %eax,-0x10(%ebp) + cnt = vsnprintf(str, size, fmt, ap); +c010b95f: 8b 45 f0 mov -0x10(%ebp),%eax +c010b962: 89 44 24 0c mov %eax,0xc(%esp) +c010b966: 8b 45 10 mov 0x10(%ebp),%eax +c010b969: 89 44 24 08 mov %eax,0x8(%esp) +c010b96d: 8b 45 0c mov 0xc(%ebp),%eax +c010b970: 89 44 24 04 mov %eax,0x4(%esp) +c010b974: 8b 45 08 mov 0x8(%ebp),%eax +c010b977: 89 04 24 mov %eax,(%esp) +c010b97a: e8 0a 00 00 00 call c010b989 +c010b97f: 89 45 f4 mov %eax,-0xc(%ebp) + va_end(ap); + return cnt; +c010b982: 8b 45 f4 mov -0xc(%ebp),%eax +} +c010b985: 89 ec mov %ebp,%esp +c010b987: 5d pop %ebp +c010b988: c3 ret + +c010b989 : + * + * Call this function if you are already dealing with a va_list. + * Or you probably want snprintf() instead. + * */ +int +vsnprintf(char *str, size_t size, const char *fmt, va_list ap) { +c010b989: 55 push %ebp +c010b98a: 89 e5 mov %esp,%ebp +c010b98c: 83 ec 28 sub $0x28,%esp + struct sprintbuf b = {str, str + size - 1, 0}; +c010b98f: 8b 45 08 mov 0x8(%ebp),%eax +c010b992: 89 45 ec mov %eax,-0x14(%ebp) +c010b995: 8b 45 0c mov 0xc(%ebp),%eax +c010b998: 8d 50 ff lea -0x1(%eax),%edx +c010b99b: 8b 45 08 mov 0x8(%ebp),%eax +c010b99e: 01 d0 add %edx,%eax +c010b9a0: 89 45 f0 mov %eax,-0x10(%ebp) +c010b9a3: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + if (str == NULL || b.buf > b.ebuf) { +c010b9aa: 83 7d 08 00 cmpl $0x0,0x8(%ebp) +c010b9ae: 74 0a je c010b9ba +c010b9b0: 8b 55 ec mov -0x14(%ebp),%edx +c010b9b3: 8b 45 f0 mov -0x10(%ebp),%eax +c010b9b6: 39 c2 cmp %eax,%edx +c010b9b8: 76 07 jbe c010b9c1 + return -E_INVAL; +c010b9ba: b8 fd ff ff ff mov $0xfffffffd,%eax +c010b9bf: eb 2a jmp c010b9eb + } + // print the string to the buffer + vprintfmt((void*)sprintputch, &b, fmt, ap); +c010b9c1: 8b 45 14 mov 0x14(%ebp),%eax +c010b9c4: 89 44 24 0c mov %eax,0xc(%esp) +c010b9c8: 8b 45 10 mov 0x10(%ebp),%eax +c010b9cb: 89 44 24 08 mov %eax,0x8(%esp) +c010b9cf: 8d 45 ec lea -0x14(%ebp),%eax +c010b9d2: 89 44 24 04 mov %eax,0x4(%esp) +c010b9d6: c7 04 24 1d b9 10 c0 movl $0xc010b91d,(%esp) +c010b9dd: e8 62 fb ff ff call c010b544 + // null terminate the buffer + *b.buf = '\0'; +c010b9e2: 8b 45 ec mov -0x14(%ebp),%eax +c010b9e5: c6 00 00 movb $0x0,(%eax) + return b.cnt; +c010b9e8: 8b 45 f4 mov -0xc(%ebp),%eax +} +c010b9eb: 89 ec mov %ebp,%esp +c010b9ed: 5d pop %ebp +c010b9ee: c3 ret + +c010b9ef : + * rand - returns a pseudo-random integer + * + * The rand() function return a value in the range [0, RAND_MAX]. + * */ +int +rand(void) { +c010b9ef: 55 push %ebp +c010b9f0: 89 e5 mov %esp,%ebp +c010b9f2: 57 push %edi +c010b9f3: 56 push %esi +c010b9f4: 53 push %ebx +c010b9f5: 83 ec 24 sub $0x24,%esp + next = (next * 0x5DEECE66DLL + 0xBLL) & ((1LL << 48) - 1); +c010b9f8: a1 20 fb 12 c0 mov 0xc012fb20,%eax +c010b9fd: 8b 15 24 fb 12 c0 mov 0xc012fb24,%edx +c010ba03: 69 fa 6d e6 ec de imul $0xdeece66d,%edx,%edi +c010ba09: 6b f0 05 imul $0x5,%eax,%esi +c010ba0c: 01 fe add %edi,%esi +c010ba0e: bf 6d e6 ec de mov $0xdeece66d,%edi +c010ba13: f7 e7 mul %edi +c010ba15: 01 d6 add %edx,%esi +c010ba17: 89 f2 mov %esi,%edx +c010ba19: 83 c0 0b add $0xb,%eax +c010ba1c: 83 d2 00 adc $0x0,%edx +c010ba1f: 89 c7 mov %eax,%edi +c010ba21: 83 e7 ff and $0xffffffff,%edi +c010ba24: 89 f9 mov %edi,%ecx +c010ba26: 0f b7 da movzwl %dx,%ebx +c010ba29: 89 0d 20 fb 12 c0 mov %ecx,0xc012fb20 +c010ba2f: 89 1d 24 fb 12 c0 mov %ebx,0xc012fb24 + unsigned long long result = (next >> 12); +c010ba35: a1 20 fb 12 c0 mov 0xc012fb20,%eax +c010ba3a: 8b 15 24 fb 12 c0 mov 0xc012fb24,%edx +c010ba40: 0f ac d0 0c shrd $0xc,%edx,%eax +c010ba44: c1 ea 0c shr $0xc,%edx +c010ba47: 89 45 e0 mov %eax,-0x20(%ebp) +c010ba4a: 89 55 e4 mov %edx,-0x1c(%ebp) + return (int)do_div(result, RAND_MAX + 1); +c010ba4d: c7 45 dc 00 00 00 80 movl $0x80000000,-0x24(%ebp) +c010ba54: 8b 45 e0 mov -0x20(%ebp),%eax +c010ba57: 8b 55 e4 mov -0x1c(%ebp),%edx +c010ba5a: 89 45 d8 mov %eax,-0x28(%ebp) +c010ba5d: 89 55 e8 mov %edx,-0x18(%ebp) +c010ba60: 8b 45 e8 mov -0x18(%ebp),%eax +c010ba63: 89 45 ec mov %eax,-0x14(%ebp) +c010ba66: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) +c010ba6a: 74 1c je c010ba88 +c010ba6c: 8b 45 e8 mov -0x18(%ebp),%eax +c010ba6f: ba 00 00 00 00 mov $0x0,%edx +c010ba74: f7 75 dc divl -0x24(%ebp) +c010ba77: 89 55 ec mov %edx,-0x14(%ebp) +c010ba7a: 8b 45 e8 mov -0x18(%ebp),%eax +c010ba7d: ba 00 00 00 00 mov $0x0,%edx +c010ba82: f7 75 dc divl -0x24(%ebp) +c010ba85: 89 45 e8 mov %eax,-0x18(%ebp) +c010ba88: 8b 45 d8 mov -0x28(%ebp),%eax +c010ba8b: 8b 55 ec mov -0x14(%ebp),%edx +c010ba8e: f7 75 dc divl -0x24(%ebp) +c010ba91: 89 45 d8 mov %eax,-0x28(%ebp) +c010ba94: 89 55 d4 mov %edx,-0x2c(%ebp) +c010ba97: 8b 45 d8 mov -0x28(%ebp),%eax +c010ba9a: 8b 55 e8 mov -0x18(%ebp),%edx +c010ba9d: 89 45 e0 mov %eax,-0x20(%ebp) +c010baa0: 89 55 e4 mov %edx,-0x1c(%ebp) +c010baa3: 8b 45 d4 mov -0x2c(%ebp),%eax +} +c010baa6: 83 c4 24 add $0x24,%esp +c010baa9: 5b pop %ebx +c010baaa: 5e pop %esi +c010baab: 5f pop %edi +c010baac: 5d pop %ebp +c010baad: c3 ret + +c010baae : +/* * + * srand - seed the random number generator with the given number + * @seed: the required seed number + * */ +void +srand(unsigned int seed) { +c010baae: 55 push %ebp +c010baaf: 89 e5 mov %esp,%ebp + next = seed; +c010bab1: 8b 45 08 mov 0x8(%ebp),%eax +c010bab4: ba 00 00 00 00 mov $0x0,%edx +c010bab9: a3 20 fb 12 c0 mov %eax,0xc012fb20 +c010babe: 89 15 24 fb 12 c0 mov %edx,0xc012fb24 +} +c010bac4: 90 nop +c010bac5: 5d pop %ebp +c010bac6: c3 ret + +c010bac7 : + * @s: the input string + * + * The strlen() function returns the length of string @s. + * */ +size_t +strlen(const char *s) { +c010bac7: 55 push %ebp +c010bac8: 89 e5 mov %esp,%ebp +c010baca: 83 ec 10 sub $0x10,%esp + size_t cnt = 0; +c010bacd: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + while (*s ++ != '\0') { +c010bad4: eb 03 jmp c010bad9 + cnt ++; +c010bad6: ff 45 fc incl -0x4(%ebp) + while (*s ++ != '\0') { +c010bad9: 8b 45 08 mov 0x8(%ebp),%eax +c010badc: 8d 50 01 lea 0x1(%eax),%edx +c010badf: 89 55 08 mov %edx,0x8(%ebp) +c010bae2: 0f b6 00 movzbl (%eax),%eax +c010bae5: 84 c0 test %al,%al +c010bae7: 75 ed jne c010bad6 + } + return cnt; +c010bae9: 8b 45 fc mov -0x4(%ebp),%eax +} +c010baec: 89 ec mov %ebp,%esp +c010baee: 5d pop %ebp +c010baef: c3 ret + +c010baf0 : + * The return value is strlen(s), if that is less than @len, or + * @len if there is no '\0' character among the first @len characters + * pointed by @s. + * */ +size_t +strnlen(const char *s, size_t len) { +c010baf0: 55 push %ebp +c010baf1: 89 e5 mov %esp,%ebp +c010baf3: 83 ec 10 sub $0x10,%esp + size_t cnt = 0; +c010baf6: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + while (cnt < len && *s ++ != '\0') { +c010bafd: eb 03 jmp c010bb02 + cnt ++; +c010baff: ff 45 fc incl -0x4(%ebp) + while (cnt < len && *s ++ != '\0') { +c010bb02: 8b 45 fc mov -0x4(%ebp),%eax +c010bb05: 3b 45 0c cmp 0xc(%ebp),%eax +c010bb08: 73 10 jae c010bb1a +c010bb0a: 8b 45 08 mov 0x8(%ebp),%eax +c010bb0d: 8d 50 01 lea 0x1(%eax),%edx +c010bb10: 89 55 08 mov %edx,0x8(%ebp) +c010bb13: 0f b6 00 movzbl (%eax),%eax +c010bb16: 84 c0 test %al,%al +c010bb18: 75 e5 jne c010baff + } + return cnt; +c010bb1a: 8b 45 fc mov -0x4(%ebp),%eax +} +c010bb1d: 89 ec mov %ebp,%esp +c010bb1f: 5d pop %ebp +c010bb20: c3 ret + +c010bb21 : + * To avoid overflows, the size of array pointed by @dst should be long enough to + * contain the same string as @src (including the terminating null character), and + * should not overlap in memory with @src. + * */ +char * +strcpy(char *dst, const char *src) { +c010bb21: 55 push %ebp +c010bb22: 89 e5 mov %esp,%ebp +c010bb24: 57 push %edi +c010bb25: 56 push %esi +c010bb26: 83 ec 20 sub $0x20,%esp +c010bb29: 8b 45 08 mov 0x8(%ebp),%eax +c010bb2c: 89 45 f4 mov %eax,-0xc(%ebp) +c010bb2f: 8b 45 0c mov 0xc(%ebp),%eax +c010bb32: 89 45 f0 mov %eax,-0x10(%ebp) +#ifndef __HAVE_ARCH_STRCPY +#define __HAVE_ARCH_STRCPY +static inline char * +__strcpy(char *dst, const char *src) { + int d0, d1, d2; + asm volatile ( +c010bb35: 8b 55 f0 mov -0x10(%ebp),%edx +c010bb38: 8b 45 f4 mov -0xc(%ebp),%eax +c010bb3b: 89 d1 mov %edx,%ecx +c010bb3d: 89 c2 mov %eax,%edx +c010bb3f: 89 ce mov %ecx,%esi +c010bb41: 89 d7 mov %edx,%edi +c010bb43: ac lods %ds:(%esi),%al +c010bb44: aa stos %al,%es:(%edi) +c010bb45: 84 c0 test %al,%al +c010bb47: 75 fa jne c010bb43 +c010bb49: 89 fa mov %edi,%edx +c010bb4b: 89 f1 mov %esi,%ecx +c010bb4d: 89 4d ec mov %ecx,-0x14(%ebp) +c010bb50: 89 55 e8 mov %edx,-0x18(%ebp) +c010bb53: 89 45 e4 mov %eax,-0x1c(%ebp) + "stosb;" + "testb %%al, %%al;" + "jne 1b;" + : "=&S" (d0), "=&D" (d1), "=&a" (d2) + : "0" (src), "1" (dst) : "memory"); + return dst; +c010bb56: 8b 45 f4 mov -0xc(%ebp),%eax + char *p = dst; + while ((*p ++ = *src ++) != '\0') + /* nothing */; + return dst; +#endif /* __HAVE_ARCH_STRCPY */ +} +c010bb59: 83 c4 20 add $0x20,%esp +c010bb5c: 5e pop %esi +c010bb5d: 5f pop %edi +c010bb5e: 5d pop %ebp +c010bb5f: c3 ret + +c010bb60 : + * @len: maximum number of characters to be copied from @src + * + * The return value is @dst + * */ +char * +strncpy(char *dst, const char *src, size_t len) { +c010bb60: 55 push %ebp +c010bb61: 89 e5 mov %esp,%ebp +c010bb63: 83 ec 10 sub $0x10,%esp + char *p = dst; +c010bb66: 8b 45 08 mov 0x8(%ebp),%eax +c010bb69: 89 45 fc mov %eax,-0x4(%ebp) + while (len > 0) { +c010bb6c: eb 1e jmp c010bb8c + if ((*p = *src) != '\0') { +c010bb6e: 8b 45 0c mov 0xc(%ebp),%eax +c010bb71: 0f b6 10 movzbl (%eax),%edx +c010bb74: 8b 45 fc mov -0x4(%ebp),%eax +c010bb77: 88 10 mov %dl,(%eax) +c010bb79: 8b 45 fc mov -0x4(%ebp),%eax +c010bb7c: 0f b6 00 movzbl (%eax),%eax +c010bb7f: 84 c0 test %al,%al +c010bb81: 74 03 je c010bb86 + src ++; +c010bb83: ff 45 0c incl 0xc(%ebp) + } + p ++, len --; +c010bb86: ff 45 fc incl -0x4(%ebp) +c010bb89: ff 4d 10 decl 0x10(%ebp) + while (len > 0) { +c010bb8c: 83 7d 10 00 cmpl $0x0,0x10(%ebp) +c010bb90: 75 dc jne c010bb6e + } + return dst; +c010bb92: 8b 45 08 mov 0x8(%ebp),%eax +} +c010bb95: 89 ec mov %ebp,%esp +c010bb97: 5d pop %ebp +c010bb98: c3 ret + +c010bb99 : + * - A value greater than zero indicates that the first character that does + * not match has a greater value in @s1 than in @s2; + * - And a value less than zero indicates the opposite. + * */ +int +strcmp(const char *s1, const char *s2) { +c010bb99: 55 push %ebp +c010bb9a: 89 e5 mov %esp,%ebp +c010bb9c: 57 push %edi +c010bb9d: 56 push %esi +c010bb9e: 83 ec 20 sub $0x20,%esp +c010bba1: 8b 45 08 mov 0x8(%ebp),%eax +c010bba4: 89 45 f4 mov %eax,-0xc(%ebp) +c010bba7: 8b 45 0c mov 0xc(%ebp),%eax +c010bbaa: 89 45 f0 mov %eax,-0x10(%ebp) + asm volatile ( +c010bbad: 8b 55 f4 mov -0xc(%ebp),%edx +c010bbb0: 8b 45 f0 mov -0x10(%ebp),%eax +c010bbb3: 89 d1 mov %edx,%ecx +c010bbb5: 89 c2 mov %eax,%edx +c010bbb7: 89 ce mov %ecx,%esi +c010bbb9: 89 d7 mov %edx,%edi +c010bbbb: ac lods %ds:(%esi),%al +c010bbbc: ae scas %es:(%edi),%al +c010bbbd: 75 08 jne c010bbc7 +c010bbbf: 84 c0 test %al,%al +c010bbc1: 75 f8 jne c010bbbb +c010bbc3: 31 c0 xor %eax,%eax +c010bbc5: eb 04 jmp c010bbcb +c010bbc7: 19 c0 sbb %eax,%eax +c010bbc9: 0c 01 or $0x1,%al +c010bbcb: 89 fa mov %edi,%edx +c010bbcd: 89 f1 mov %esi,%ecx +c010bbcf: 89 45 ec mov %eax,-0x14(%ebp) +c010bbd2: 89 4d e8 mov %ecx,-0x18(%ebp) +c010bbd5: 89 55 e4 mov %edx,-0x1c(%ebp) + return ret; +c010bbd8: 8b 45 ec mov -0x14(%ebp),%eax + while (*s1 != '\0' && *s1 == *s2) { + s1 ++, s2 ++; + } + return (int)((unsigned char)*s1 - (unsigned char)*s2); +#endif /* __HAVE_ARCH_STRCMP */ +} +c010bbdb: 83 c4 20 add $0x20,%esp +c010bbde: 5e pop %esi +c010bbdf: 5f pop %edi +c010bbe0: 5d pop %ebp +c010bbe1: c3 ret + +c010bbe2 : + * they are equal to each other, it continues with the following pairs until + * the characters differ, until a terminating null-character is reached, or + * until @n characters match in both strings, whichever happens first. + * */ +int +strncmp(const char *s1, const char *s2, size_t n) { +c010bbe2: 55 push %ebp +c010bbe3: 89 e5 mov %esp,%ebp + while (n > 0 && *s1 != '\0' && *s1 == *s2) { +c010bbe5: eb 09 jmp c010bbf0 + n --, s1 ++, s2 ++; +c010bbe7: ff 4d 10 decl 0x10(%ebp) +c010bbea: ff 45 08 incl 0x8(%ebp) +c010bbed: ff 45 0c incl 0xc(%ebp) + while (n > 0 && *s1 != '\0' && *s1 == *s2) { +c010bbf0: 83 7d 10 00 cmpl $0x0,0x10(%ebp) +c010bbf4: 74 1a je c010bc10 +c010bbf6: 8b 45 08 mov 0x8(%ebp),%eax +c010bbf9: 0f b6 00 movzbl (%eax),%eax +c010bbfc: 84 c0 test %al,%al +c010bbfe: 74 10 je c010bc10 +c010bc00: 8b 45 08 mov 0x8(%ebp),%eax +c010bc03: 0f b6 10 movzbl (%eax),%edx +c010bc06: 8b 45 0c mov 0xc(%ebp),%eax +c010bc09: 0f b6 00 movzbl (%eax),%eax +c010bc0c: 38 c2 cmp %al,%dl +c010bc0e: 74 d7 je c010bbe7 + } + return (n == 0) ? 0 : (int)((unsigned char)*s1 - (unsigned char)*s2); +c010bc10: 83 7d 10 00 cmpl $0x0,0x10(%ebp) +c010bc14: 74 18 je c010bc2e +c010bc16: 8b 45 08 mov 0x8(%ebp),%eax +c010bc19: 0f b6 00 movzbl (%eax),%eax +c010bc1c: 0f b6 d0 movzbl %al,%edx +c010bc1f: 8b 45 0c mov 0xc(%ebp),%eax +c010bc22: 0f b6 00 movzbl (%eax),%eax +c010bc25: 0f b6 c8 movzbl %al,%ecx +c010bc28: 89 d0 mov %edx,%eax +c010bc2a: 29 c8 sub %ecx,%eax +c010bc2c: eb 05 jmp c010bc33 +c010bc2e: b8 00 00 00 00 mov $0x0,%eax +} +c010bc33: 5d pop %ebp +c010bc34: c3 ret + +c010bc35 : + * + * The strchr() function returns a pointer to the first occurrence of + * character in @s. If the value is not found, the function returns 'NULL'. + * */ +char * +strchr(const char *s, char c) { +c010bc35: 55 push %ebp +c010bc36: 89 e5 mov %esp,%ebp +c010bc38: 83 ec 04 sub $0x4,%esp +c010bc3b: 8b 45 0c mov 0xc(%ebp),%eax +c010bc3e: 88 45 fc mov %al,-0x4(%ebp) + while (*s != '\0') { +c010bc41: eb 13 jmp c010bc56 + if (*s == c) { +c010bc43: 8b 45 08 mov 0x8(%ebp),%eax +c010bc46: 0f b6 00 movzbl (%eax),%eax +c010bc49: 38 45 fc cmp %al,-0x4(%ebp) +c010bc4c: 75 05 jne c010bc53 + return (char *)s; +c010bc4e: 8b 45 08 mov 0x8(%ebp),%eax +c010bc51: eb 12 jmp c010bc65 + } + s ++; +c010bc53: ff 45 08 incl 0x8(%ebp) + while (*s != '\0') { +c010bc56: 8b 45 08 mov 0x8(%ebp),%eax +c010bc59: 0f b6 00 movzbl (%eax),%eax +c010bc5c: 84 c0 test %al,%al +c010bc5e: 75 e3 jne c010bc43 + } + return NULL; +c010bc60: b8 00 00 00 00 mov $0x0,%eax +} +c010bc65: 89 ec mov %ebp,%esp +c010bc67: 5d pop %ebp +c010bc68: c3 ret + +c010bc69 : + * The strfind() function is like strchr() except that if @c is + * not found in @s, then it returns a pointer to the null byte at the + * end of @s, rather than 'NULL'. + * */ +char * +strfind(const char *s, char c) { +c010bc69: 55 push %ebp +c010bc6a: 89 e5 mov %esp,%ebp +c010bc6c: 83 ec 04 sub $0x4,%esp +c010bc6f: 8b 45 0c mov 0xc(%ebp),%eax +c010bc72: 88 45 fc mov %al,-0x4(%ebp) + while (*s != '\0') { +c010bc75: eb 0e jmp c010bc85 + if (*s == c) { +c010bc77: 8b 45 08 mov 0x8(%ebp),%eax +c010bc7a: 0f b6 00 movzbl (%eax),%eax +c010bc7d: 38 45 fc cmp %al,-0x4(%ebp) +c010bc80: 74 0f je c010bc91 + break; + } + s ++; +c010bc82: ff 45 08 incl 0x8(%ebp) + while (*s != '\0') { +c010bc85: 8b 45 08 mov 0x8(%ebp),%eax +c010bc88: 0f b6 00 movzbl (%eax),%eax +c010bc8b: 84 c0 test %al,%al +c010bc8d: 75 e8 jne c010bc77 +c010bc8f: eb 01 jmp c010bc92 + break; +c010bc91: 90 nop + } + return (char *)s; +c010bc92: 8b 45 08 mov 0x8(%ebp),%eax +} +c010bc95: 89 ec mov %ebp,%esp +c010bc97: 5d pop %ebp +c010bc98: c3 ret + +c010bc99 : + * an optional "0x" or "0X" prefix. + * + * The strtol() function returns the converted integral number as a long int value. + * */ +long +strtol(const char *s, char **endptr, int base) { +c010bc99: 55 push %ebp +c010bc9a: 89 e5 mov %esp,%ebp +c010bc9c: 83 ec 10 sub $0x10,%esp + int neg = 0; +c010bc9f: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + long val = 0; +c010bca6: c7 45 f8 00 00 00 00 movl $0x0,-0x8(%ebp) + + // gobble initial whitespace + while (*s == ' ' || *s == '\t') { +c010bcad: eb 03 jmp c010bcb2 + s ++; +c010bcaf: ff 45 08 incl 0x8(%ebp) + while (*s == ' ' || *s == '\t') { +c010bcb2: 8b 45 08 mov 0x8(%ebp),%eax +c010bcb5: 0f b6 00 movzbl (%eax),%eax +c010bcb8: 3c 20 cmp $0x20,%al +c010bcba: 74 f3 je c010bcaf +c010bcbc: 8b 45 08 mov 0x8(%ebp),%eax +c010bcbf: 0f b6 00 movzbl (%eax),%eax +c010bcc2: 3c 09 cmp $0x9,%al +c010bcc4: 74 e9 je c010bcaf + } + + // plus/minus sign + if (*s == '+') { +c010bcc6: 8b 45 08 mov 0x8(%ebp),%eax +c010bcc9: 0f b6 00 movzbl (%eax),%eax +c010bccc: 3c 2b cmp $0x2b,%al +c010bcce: 75 05 jne c010bcd5 + s ++; +c010bcd0: ff 45 08 incl 0x8(%ebp) +c010bcd3: eb 14 jmp c010bce9 + } + else if (*s == '-') { +c010bcd5: 8b 45 08 mov 0x8(%ebp),%eax +c010bcd8: 0f b6 00 movzbl (%eax),%eax +c010bcdb: 3c 2d cmp $0x2d,%al +c010bcdd: 75 0a jne c010bce9 + s ++, neg = 1; +c010bcdf: ff 45 08 incl 0x8(%ebp) +c010bce2: c7 45 fc 01 00 00 00 movl $0x1,-0x4(%ebp) + } + + // hex or octal base prefix + if ((base == 0 || base == 16) && (s[0] == '0' && s[1] == 'x')) { +c010bce9: 83 7d 10 00 cmpl $0x0,0x10(%ebp) +c010bced: 74 06 je c010bcf5 +c010bcef: 83 7d 10 10 cmpl $0x10,0x10(%ebp) +c010bcf3: 75 22 jne c010bd17 +c010bcf5: 8b 45 08 mov 0x8(%ebp),%eax +c010bcf8: 0f b6 00 movzbl (%eax),%eax +c010bcfb: 3c 30 cmp $0x30,%al +c010bcfd: 75 18 jne c010bd17 +c010bcff: 8b 45 08 mov 0x8(%ebp),%eax +c010bd02: 40 inc %eax +c010bd03: 0f b6 00 movzbl (%eax),%eax +c010bd06: 3c 78 cmp $0x78,%al +c010bd08: 75 0d jne c010bd17 + s += 2, base = 16; +c010bd0a: 83 45 08 02 addl $0x2,0x8(%ebp) +c010bd0e: c7 45 10 10 00 00 00 movl $0x10,0x10(%ebp) +c010bd15: eb 29 jmp c010bd40 + } + else if (base == 0 && s[0] == '0') { +c010bd17: 83 7d 10 00 cmpl $0x0,0x10(%ebp) +c010bd1b: 75 16 jne c010bd33 +c010bd1d: 8b 45 08 mov 0x8(%ebp),%eax +c010bd20: 0f b6 00 movzbl (%eax),%eax +c010bd23: 3c 30 cmp $0x30,%al +c010bd25: 75 0c jne c010bd33 + s ++, base = 8; +c010bd27: ff 45 08 incl 0x8(%ebp) +c010bd2a: c7 45 10 08 00 00 00 movl $0x8,0x10(%ebp) +c010bd31: eb 0d jmp c010bd40 + } + else if (base == 0) { +c010bd33: 83 7d 10 00 cmpl $0x0,0x10(%ebp) +c010bd37: 75 07 jne c010bd40 + base = 10; +c010bd39: c7 45 10 0a 00 00 00 movl $0xa,0x10(%ebp) + + // digits + while (1) { + int dig; + + if (*s >= '0' && *s <= '9') { +c010bd40: 8b 45 08 mov 0x8(%ebp),%eax +c010bd43: 0f b6 00 movzbl (%eax),%eax +c010bd46: 3c 2f cmp $0x2f,%al +c010bd48: 7e 1b jle c010bd65 +c010bd4a: 8b 45 08 mov 0x8(%ebp),%eax +c010bd4d: 0f b6 00 movzbl (%eax),%eax +c010bd50: 3c 39 cmp $0x39,%al +c010bd52: 7f 11 jg c010bd65 + dig = *s - '0'; +c010bd54: 8b 45 08 mov 0x8(%ebp),%eax +c010bd57: 0f b6 00 movzbl (%eax),%eax +c010bd5a: 0f be c0 movsbl %al,%eax +c010bd5d: 83 e8 30 sub $0x30,%eax +c010bd60: 89 45 f4 mov %eax,-0xc(%ebp) +c010bd63: eb 48 jmp c010bdad + } + else if (*s >= 'a' && *s <= 'z') { +c010bd65: 8b 45 08 mov 0x8(%ebp),%eax +c010bd68: 0f b6 00 movzbl (%eax),%eax +c010bd6b: 3c 60 cmp $0x60,%al +c010bd6d: 7e 1b jle c010bd8a +c010bd6f: 8b 45 08 mov 0x8(%ebp),%eax +c010bd72: 0f b6 00 movzbl (%eax),%eax +c010bd75: 3c 7a cmp $0x7a,%al +c010bd77: 7f 11 jg c010bd8a + dig = *s - 'a' + 10; +c010bd79: 8b 45 08 mov 0x8(%ebp),%eax +c010bd7c: 0f b6 00 movzbl (%eax),%eax +c010bd7f: 0f be c0 movsbl %al,%eax +c010bd82: 83 e8 57 sub $0x57,%eax +c010bd85: 89 45 f4 mov %eax,-0xc(%ebp) +c010bd88: eb 23 jmp c010bdad + } + else if (*s >= 'A' && *s <= 'Z') { +c010bd8a: 8b 45 08 mov 0x8(%ebp),%eax +c010bd8d: 0f b6 00 movzbl (%eax),%eax +c010bd90: 3c 40 cmp $0x40,%al +c010bd92: 7e 3b jle c010bdcf +c010bd94: 8b 45 08 mov 0x8(%ebp),%eax +c010bd97: 0f b6 00 movzbl (%eax),%eax +c010bd9a: 3c 5a cmp $0x5a,%al +c010bd9c: 7f 31 jg c010bdcf + dig = *s - 'A' + 10; +c010bd9e: 8b 45 08 mov 0x8(%ebp),%eax +c010bda1: 0f b6 00 movzbl (%eax),%eax +c010bda4: 0f be c0 movsbl %al,%eax +c010bda7: 83 e8 37 sub $0x37,%eax +c010bdaa: 89 45 f4 mov %eax,-0xc(%ebp) + } + else { + break; + } + if (dig >= base) { +c010bdad: 8b 45 f4 mov -0xc(%ebp),%eax +c010bdb0: 3b 45 10 cmp 0x10(%ebp),%eax +c010bdb3: 7d 19 jge c010bdce + break; + } + s ++, val = (val * base) + dig; +c010bdb5: ff 45 08 incl 0x8(%ebp) +c010bdb8: 8b 45 f8 mov -0x8(%ebp),%eax +c010bdbb: 0f af 45 10 imul 0x10(%ebp),%eax +c010bdbf: 89 c2 mov %eax,%edx +c010bdc1: 8b 45 f4 mov -0xc(%ebp),%eax +c010bdc4: 01 d0 add %edx,%eax +c010bdc6: 89 45 f8 mov %eax,-0x8(%ebp) + while (1) { +c010bdc9: e9 72 ff ff ff jmp c010bd40 + break; +c010bdce: 90 nop + // we don't properly detect overflow! + } + + if (endptr) { +c010bdcf: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) +c010bdd3: 74 08 je c010bddd + *endptr = (char *) s; +c010bdd5: 8b 45 0c mov 0xc(%ebp),%eax +c010bdd8: 8b 55 08 mov 0x8(%ebp),%edx +c010bddb: 89 10 mov %edx,(%eax) + } + return (neg ? -val : val); +c010bddd: 83 7d fc 00 cmpl $0x0,-0x4(%ebp) +c010bde1: 74 07 je c010bdea +c010bde3: 8b 45 f8 mov -0x8(%ebp),%eax +c010bde6: f7 d8 neg %eax +c010bde8: eb 03 jmp c010bded +c010bdea: 8b 45 f8 mov -0x8(%ebp),%eax +} +c010bded: 89 ec mov %ebp,%esp +c010bdef: 5d pop %ebp +c010bdf0: c3 ret + +c010bdf1 : + * @n: number of bytes to be set to the value + * + * The memset() function returns @s. + * */ +void * +memset(void *s, char c, size_t n) { +c010bdf1: 55 push %ebp +c010bdf2: 89 e5 mov %esp,%ebp +c010bdf4: 83 ec 28 sub $0x28,%esp +c010bdf7: 89 7d fc mov %edi,-0x4(%ebp) +c010bdfa: 8b 45 0c mov 0xc(%ebp),%eax +c010bdfd: 88 45 d8 mov %al,-0x28(%ebp) +#ifdef __HAVE_ARCH_MEMSET + return __memset(s, c, n); +c010be00: 0f be 55 d8 movsbl -0x28(%ebp),%edx +c010be04: 8b 45 08 mov 0x8(%ebp),%eax +c010be07: 89 45 f8 mov %eax,-0x8(%ebp) +c010be0a: 88 55 f7 mov %dl,-0x9(%ebp) +c010be0d: 8b 45 10 mov 0x10(%ebp),%eax +c010be10: 89 45 f0 mov %eax,-0x10(%ebp) +#ifndef __HAVE_ARCH_MEMSET +#define __HAVE_ARCH_MEMSET +static inline void * +__memset(void *s, char c, size_t n) { + int d0, d1; + asm volatile ( +c010be13: 8b 4d f0 mov -0x10(%ebp),%ecx +c010be16: 0f b6 45 f7 movzbl -0x9(%ebp),%eax +c010be1a: 8b 55 f8 mov -0x8(%ebp),%edx +c010be1d: 89 d7 mov %edx,%edi +c010be1f: f3 aa rep stos %al,%es:(%edi) +c010be21: 89 fa mov %edi,%edx +c010be23: 89 4d ec mov %ecx,-0x14(%ebp) +c010be26: 89 55 e8 mov %edx,-0x18(%ebp) + "rep; stosb;" + : "=&c" (d0), "=&D" (d1) + : "0" (n), "a" (c), "1" (s) + : "memory"); + return s; +c010be29: 8b 45 f8 mov -0x8(%ebp),%eax + while (n -- > 0) { + *p ++ = c; + } + return s; +#endif /* __HAVE_ARCH_MEMSET */ +} +c010be2c: 8b 7d fc mov -0x4(%ebp),%edi +c010be2f: 89 ec mov %ebp,%esp +c010be31: 5d pop %ebp +c010be32: c3 ret + +c010be33 : + * @n: number of bytes to copy + * + * The memmove() function returns @dst. + * */ +void * +memmove(void *dst, const void *src, size_t n) { +c010be33: 55 push %ebp +c010be34: 89 e5 mov %esp,%ebp +c010be36: 57 push %edi +c010be37: 56 push %esi +c010be38: 53 push %ebx +c010be39: 83 ec 30 sub $0x30,%esp +c010be3c: 8b 45 08 mov 0x8(%ebp),%eax +c010be3f: 89 45 f0 mov %eax,-0x10(%ebp) +c010be42: 8b 45 0c mov 0xc(%ebp),%eax +c010be45: 89 45 ec mov %eax,-0x14(%ebp) +c010be48: 8b 45 10 mov 0x10(%ebp),%eax +c010be4b: 89 45 e8 mov %eax,-0x18(%ebp) + +#ifndef __HAVE_ARCH_MEMMOVE +#define __HAVE_ARCH_MEMMOVE +static inline void * +__memmove(void *dst, const void *src, size_t n) { + if (dst < src) { +c010be4e: 8b 45 f0 mov -0x10(%ebp),%eax +c010be51: 3b 45 ec cmp -0x14(%ebp),%eax +c010be54: 73 42 jae c010be98 +c010be56: 8b 45 f0 mov -0x10(%ebp),%eax +c010be59: 89 45 e4 mov %eax,-0x1c(%ebp) +c010be5c: 8b 45 ec mov -0x14(%ebp),%eax +c010be5f: 89 45 e0 mov %eax,-0x20(%ebp) +c010be62: 8b 45 e8 mov -0x18(%ebp),%eax +c010be65: 89 45 dc mov %eax,-0x24(%ebp) + "andl $3, %%ecx;" + "jz 1f;" + "rep; movsb;" + "1:" + : "=&c" (d0), "=&D" (d1), "=&S" (d2) + : "0" (n / 4), "g" (n), "1" (dst), "2" (src) +c010be68: 8b 45 dc mov -0x24(%ebp),%eax +c010be6b: c1 e8 02 shr $0x2,%eax +c010be6e: 89 c1 mov %eax,%ecx + asm volatile ( +c010be70: 8b 55 e4 mov -0x1c(%ebp),%edx +c010be73: 8b 45 e0 mov -0x20(%ebp),%eax +c010be76: 89 d7 mov %edx,%edi +c010be78: 89 c6 mov %eax,%esi +c010be7a: f3 a5 rep movsl %ds:(%esi),%es:(%edi) +c010be7c: 8b 4d dc mov -0x24(%ebp),%ecx +c010be7f: 83 e1 03 and $0x3,%ecx +c010be82: 74 02 je c010be86 +c010be84: f3 a4 rep movsb %ds:(%esi),%es:(%edi) +c010be86: 89 f0 mov %esi,%eax +c010be88: 89 fa mov %edi,%edx +c010be8a: 89 4d d8 mov %ecx,-0x28(%ebp) +c010be8d: 89 55 d4 mov %edx,-0x2c(%ebp) +c010be90: 89 45 d0 mov %eax,-0x30(%ebp) + : "memory"); + return dst; +c010be93: 8b 45 e4 mov -0x1c(%ebp),%eax + return __memcpy(dst, src, n); +c010be96: eb 36 jmp c010bece + : "0" (n), "1" (n - 1 + src), "2" (n - 1 + dst) +c010be98: 8b 45 e8 mov -0x18(%ebp),%eax +c010be9b: 8d 50 ff lea -0x1(%eax),%edx +c010be9e: 8b 45 ec mov -0x14(%ebp),%eax +c010bea1: 01 c2 add %eax,%edx +c010bea3: 8b 45 e8 mov -0x18(%ebp),%eax +c010bea6: 8d 48 ff lea -0x1(%eax),%ecx +c010bea9: 8b 45 f0 mov -0x10(%ebp),%eax +c010beac: 8d 1c 01 lea (%ecx,%eax,1),%ebx + asm volatile ( +c010beaf: 8b 45 e8 mov -0x18(%ebp),%eax +c010beb2: 89 c1 mov %eax,%ecx +c010beb4: 89 d8 mov %ebx,%eax +c010beb6: 89 d6 mov %edx,%esi +c010beb8: 89 c7 mov %eax,%edi +c010beba: fd std +c010bebb: f3 a4 rep movsb %ds:(%esi),%es:(%edi) +c010bebd: fc cld +c010bebe: 89 f8 mov %edi,%eax +c010bec0: 89 f2 mov %esi,%edx +c010bec2: 89 4d cc mov %ecx,-0x34(%ebp) +c010bec5: 89 55 c8 mov %edx,-0x38(%ebp) +c010bec8: 89 45 c4 mov %eax,-0x3c(%ebp) + return dst; +c010becb: 8b 45 f0 mov -0x10(%ebp),%eax + *d ++ = *s ++; + } + } + return dst; +#endif /* __HAVE_ARCH_MEMMOVE */ +} +c010bece: 83 c4 30 add $0x30,%esp +c010bed1: 5b pop %ebx +c010bed2: 5e pop %esi +c010bed3: 5f pop %edi +c010bed4: 5d pop %ebp +c010bed5: c3 ret + +c010bed6 : + * it always copies exactly @n bytes. To avoid overflows, the size of arrays pointed + * by both @src and @dst, should be at least @n bytes, and should not overlap + * (for overlapping memory area, memmove is a safer approach). + * */ +void * +memcpy(void *dst, const void *src, size_t n) { +c010bed6: 55 push %ebp +c010bed7: 89 e5 mov %esp,%ebp +c010bed9: 57 push %edi +c010beda: 56 push %esi +c010bedb: 83 ec 20 sub $0x20,%esp +c010bede: 8b 45 08 mov 0x8(%ebp),%eax +c010bee1: 89 45 f4 mov %eax,-0xc(%ebp) +c010bee4: 8b 45 0c mov 0xc(%ebp),%eax +c010bee7: 89 45 f0 mov %eax,-0x10(%ebp) +c010beea: 8b 45 10 mov 0x10(%ebp),%eax +c010beed: 89 45 ec mov %eax,-0x14(%ebp) + : "0" (n / 4), "g" (n), "1" (dst), "2" (src) +c010bef0: 8b 45 ec mov -0x14(%ebp),%eax +c010bef3: c1 e8 02 shr $0x2,%eax +c010bef6: 89 c1 mov %eax,%ecx + asm volatile ( +c010bef8: 8b 55 f4 mov -0xc(%ebp),%edx +c010befb: 8b 45 f0 mov -0x10(%ebp),%eax +c010befe: 89 d7 mov %edx,%edi +c010bf00: 89 c6 mov %eax,%esi +c010bf02: f3 a5 rep movsl %ds:(%esi),%es:(%edi) +c010bf04: 8b 4d ec mov -0x14(%ebp),%ecx +c010bf07: 83 e1 03 and $0x3,%ecx +c010bf0a: 74 02 je c010bf0e +c010bf0c: f3 a4 rep movsb %ds:(%esi),%es:(%edi) +c010bf0e: 89 f0 mov %esi,%eax +c010bf10: 89 fa mov %edi,%edx +c010bf12: 89 4d e8 mov %ecx,-0x18(%ebp) +c010bf15: 89 55 e4 mov %edx,-0x1c(%ebp) +c010bf18: 89 45 e0 mov %eax,-0x20(%ebp) + return dst; +c010bf1b: 8b 45 f4 mov -0xc(%ebp),%eax + while (n -- > 0) { + *d ++ = *s ++; + } + return dst; +#endif /* __HAVE_ARCH_MEMCPY */ +} +c010bf1e: 83 c4 20 add $0x20,%esp +c010bf21: 5e pop %esi +c010bf22: 5f pop %edi +c010bf23: 5d pop %ebp +c010bf24: c3 ret + +c010bf25 : + * match in both memory blocks has a greater value in @v1 than in @v2 + * as if evaluated as unsigned char values; + * - And a value less than zero indicates the opposite. + * */ +int +memcmp(const void *v1, const void *v2, size_t n) { +c010bf25: 55 push %ebp +c010bf26: 89 e5 mov %esp,%ebp +c010bf28: 83 ec 10 sub $0x10,%esp + const char *s1 = (const char *)v1; +c010bf2b: 8b 45 08 mov 0x8(%ebp),%eax +c010bf2e: 89 45 fc mov %eax,-0x4(%ebp) + const char *s2 = (const char *)v2; +c010bf31: 8b 45 0c mov 0xc(%ebp),%eax +c010bf34: 89 45 f8 mov %eax,-0x8(%ebp) + while (n -- > 0) { +c010bf37: eb 2e jmp c010bf67 + if (*s1 != *s2) { +c010bf39: 8b 45 fc mov -0x4(%ebp),%eax +c010bf3c: 0f b6 10 movzbl (%eax),%edx +c010bf3f: 8b 45 f8 mov -0x8(%ebp),%eax +c010bf42: 0f b6 00 movzbl (%eax),%eax +c010bf45: 38 c2 cmp %al,%dl +c010bf47: 74 18 je c010bf61 + return (int)((unsigned char)*s1 - (unsigned char)*s2); +c010bf49: 8b 45 fc mov -0x4(%ebp),%eax +c010bf4c: 0f b6 00 movzbl (%eax),%eax +c010bf4f: 0f b6 d0 movzbl %al,%edx +c010bf52: 8b 45 f8 mov -0x8(%ebp),%eax +c010bf55: 0f b6 00 movzbl (%eax),%eax +c010bf58: 0f b6 c8 movzbl %al,%ecx +c010bf5b: 89 d0 mov %edx,%eax +c010bf5d: 29 c8 sub %ecx,%eax +c010bf5f: eb 18 jmp c010bf79 + } + s1 ++, s2 ++; +c010bf61: ff 45 fc incl -0x4(%ebp) +c010bf64: ff 45 f8 incl -0x8(%ebp) + while (n -- > 0) { +c010bf67: 8b 45 10 mov 0x10(%ebp),%eax +c010bf6a: 8d 50 ff lea -0x1(%eax),%edx +c010bf6d: 89 55 10 mov %edx,0x10(%ebp) +c010bf70: 85 c0 test %eax,%eax +c010bf72: 75 c5 jne c010bf39 + } + return 0; +c010bf74: b8 00 00 00 00 mov $0x0,%eax +} +c010bf79: 89 ec mov %ebp,%esp +c010bf7b: 5d pop %ebp +c010bf7c: c3 ret diff --git a/labcodes/lab5/obj/kernel.sym b/labcodes/lab5/obj/kernel.sym new file mode 100644 index 0000000000000000000000000000000000000000..20031e4d51e5b39a9768b3bbcc7af410ac4a7fe3 --- /dev/null +++ b/labcodes/lab5/obj/kernel.sym @@ -0,0 +1,692 @@ +00000000 entry.o +c010001e next +c0100034 spin +c01a2000 __boot_pt1 +00000400 i +00000000 init.c +c0100156 lab1_print_cur_status +c01a3000 round.0 +c0100216 lab1_switch_to_user +c0100223 lab1_switch_to_kernel +c010022d lab1_switch_test +00000000 readline.c +c01a3020 buf +00000000 stdio.c +c0100320 cputch +00000000 kdebug.c +c0100423 stab_binsearch +c0100aca read_eip +00000000 kmonitor.c +c012f000 commands +c0100ae3 parse +c0100b9c runcmd +00000000 panic.c +c01a3420 is_panic +00000000 clock.c +00000000 console.c +c0100e75 __intr_save +c0100ea1 __intr_restore +c0100eb7 delay +c01a3440 crt_buf +c01a3444 crt_pos +c01a3446 addr_6845 +c0100f02 cga_init +c01a3448 serial_exists +c0100fea serial_init +c01010d7 lpt_putc_sub +c0101155 lpt_putc +c0101197 cga_putc +c010138d serial_putc_sub +c01013e9 serial_putc +c01a3460 cons +c010142b cons_intr +c010147a serial_proc_data +c012f040 shiftcode +c012f140 togglecode +c012f240 normalmap +c012f340 shiftmap +c012f440 ctlmap +c012f540 charcode +c01014f3 kbd_proc_data +c01a3668 shift.0 +c010167a kbd_intr +c0101691 kbd_init +00000000 ide.c +c010c2b4 channels +c01a3680 ide_devices +c010178c ide_wait_ready +00000000 intr.c +00000000 picirq.c +c012f550 irq_mask +c01a3760 did_init +c0101ff9 pic_setmask +00000000 trap.c +c01021d5 print_ticks +c01a3780 idt +c012f560 idt_pd +c0102367 trapname +c010c8e0 excnames.0 +c012f580 IA32flags +c010261a print_pgfault +c010269b pgfault_handler +c01a3f80 in_swap_tick_event +c0102767 trap_dispatch +00000000 default_pmm.c +c01034de page2ppn +c01034f1 page2pa +c0103509 page_ref +c0103513 set_page_ref +c0103521 default_init +c0103552 default_init_memmap +c010369f default_alloc_pages +c0103823 default_free_pages +c0103b3b default_nr_free_pages +c0103b45 basic_check +c0104085 default_check +00000000 kmalloc.c +c01046d7 __intr_save +c0104703 __intr_restore +c0104719 page2ppn +c010472c page2pa +c0104744 pa2page +c010478c page2kva +c01047e2 kva2page +c012f9e0 arena +c012f9e8 slobfree +c01a3f90 bigblocks +c010482e __slob_get_free_pages +c0104869 __slob_free_pages +c01048a1 slob_alloc +c0104a74 slob_free +c0104bd7 find_order +c0104bfc __kmalloc +00000000 pmm.c +c0104e4e page2ppn +c0104e61 page2pa +c0104e79 pa2page +c0104ec1 page2kva +c0104f17 pte2page +c0104f57 pde2page +c0104f71 page_ref +c0104f7b set_page_ref +c0104f89 page_ref_inc +c0104fa0 page_ref_dec +c0104fb7 __intr_save +c0104fe3 __intr_restore +c01a3fc0 ts +c012fa20 gdt +c012fa50 gdt_pd +c0104ff9 lgdt +c010503d gdt_init +c0105129 init_pmm_manager +c010515f init_memmap +c0105250 page_init +c0105603 boot_map_segment +c0105709 boot_alloc_page +c0106093 check_alloc_page +c01060b4 check_pgdir +c0106752 check_boot_pgdir +c01059d2 page_remove_pte +c0106b08 perm2str +c01a4028 str.0 +c0106b4a get_pgtable_items +00000000 swap.c +c0106d65 pa2page +c0106dad pte2page +c0106ded pde2page +c01a4100 sm +c0107342 check_swap +c010716d check_content_set +c0107328 check_content_access +00000000 swap_fifo.c +c01079d6 _fifo_init_mm +c0107a0b _fifo_map_swappable +c0107ab0 _fifo_swap_out_victim +c0107bb5 _fifo_check_swap +c0107f0c _fifo_init +c0107f16 _fifo_set_unswappable +c0107f20 _fifo_tick_event +00000000 vmm.c +c0107f2a lock_init +c0107f39 mm_count +c0107f44 set_mm_count +c0107f53 pa2page +c0107f9b pde2page +c0108141 check_vma_overlap +c0108740 check_vmm +c0108769 check_vma_struct +c0108bfd check_pgfault +00000000 swapfs.c +c010917f page2ppn +c0109192 page2pa +c01091aa page2kva +00000000 proc.c +c010933c test_and_set_bit +c010935e test_and_clear_bit +c0109380 __intr_save +c01093ac __intr_restore +c01093c2 try_lock +c01093e7 lock +c0109409 unlock +c0109447 page2ppn +c010945a page2pa +c0109472 pa2page +c01094ba page2kva +c0109510 kva2page +c010955c mm_count_inc +c0109576 mm_count_dec +c0109590 lock_mm +c01095af unlock_mm +c01a4140 hash_list +c01a6140 nr_process +c01095ce alloc_proc +c01a6144 name.2 +c010974a set_links +c01097f3 remove_links +c0109879 get_pid +c012fa80 last_pid.1 +c012fa84 next_safe.0 +c01099e9 forkret +c0109a04 hash_proc +c0109a87 unhash_proc +c0109ba9 setup_kstack +c0109be7 put_kstack +c0109c10 setup_pgdir +c0109cb9 put_pgdir +c0109ce2 copy_mm +c0109e03 copy_thread +c010a1e0 load_icode +c010ab83 kernel_execve +c010abbd user_main +c010ac1c init_main +00000000 sched.c +c010afb3 __intr_save +c010afdf __intr_restore +00000000 syscall.c +c010b146 sys_exit +c010b163 sys_fork +c010b19b sys_wait +c010b1ca sys_exec +c010b21d sys_yield +c010b22c sys_kill +c010b249 sys_getpid +c010b256 sys_putc +c010b278 sys_pgdir +c012faa0 syscalls +00000000 hash.c +00000000 printfmt.c +c010e600 error_string +c010b37b printnum +c010b47d getuint +c010b4cc getint +c010b91d sprintputch +00000000 rand.c +c012fb20 next +00000000 string.c +c0103436 vector242 +c0102e8d vector119 +c0100991 print_kerninfo +c0102d6d vector87 +c0102d64 vector86 +c01034a2 vector251 +c010bb21 strcpy +c0101aea ide_device_valid +c0102d91 vector91 +c0102b87 vector33 +c0103076 vector162 +c01032da vector213 +c0102e2a vector108 +c0102be1 vector43 +000077f4 _binary_obj___user_yield_out_size +c0104bc3 slob_allocated +c0100000 kern_entry +c0100d27 mon_backtrace +c010309a vector165 +c0137320 _binary_obj___user_badsegment_out_start +c010318a vector185 +c0102e69 vector115 +c0102ea8 vector122 +000077f4 _binary_obj___user_hello_out_size +c0108689 copy_from_user +c0164370 _binary_obj___user_forktest_out_end +c0105ea3 page_insert +c010302e vector156 +c010345a vector245 +c01031ba vector189 +c0102aab vector7 +c0102c83 vector61 +c0102b36 vector24 +c0102e45 vector111 +c010323e vector200 +0000783c _binary_obj___user_testbss_out_size +c0102cb9 vector67 +c010aff5 wakeup_proc +c0104bcd kallocated +c0105fbd pgdir_alloc_page +c0102f56 vector138 +c0102cf8 vector74 +c010be33 memmove +c0102c5f vector57 +c014db64 _binary_obj___user_exit_out_end +c0107fb5 mm_create +c010b953 snprintf +c010b28c syscall +c01023ad print_trapframe +c01032e6 vector214 +c010b544 vprintfmt +c0102dd9 vector99 +c0105977 get_page +c0102a44 __alltraps +c010171b cons_getc +c0102f7a vector141 +c0100e02 is_kernel_panic +c01030ee vector172 +c0100add print_stackframe +c010342a vector241 +c01a4104 pra_list_head +c01034ba vector253 +c0102a87 vector3 +c0102a66 forkrets +c0102a7e vector2 +c0109ee9 do_fork +c0103382 vector227 +c0109b33 kernel_thread +c01032b6 vector210 +c01a4128 idleproc +c010335e vector224 +c0102bcf vector41 +c012fa60 swap_manager_fifo +c0100378 cprintf +c01913ac _binary_obj___user_testbss_out_end +c01a4120 proc_list +c0102b1b vector21 +c010312a vector177 +c0102e84 vector118 +c0102cd4 vector70 +c0108392 mm_map +c0102ccb vector69 +c01033fa vector237 +c0102c9e vector64 +c0102b51 vector27 +c01084ac dup_mmap +c0108730 vmm_init +c0102f0e vector132 +c012fb28 _binary_obj___user_badarg_out_start +c01085ad exit_mmap +c0103196 vector186 +000077f8 _binary_obj___user_badarg_out_size +c010330a vector217 +c010831e mm_destroy +c0109333 kernel_thread_entry +c010a98d do_wait +c010bed6 memcpy +c0102a75 vector1 +c0103136 vector178 +c0102bb4 vector38 +c0104d0d kfree +c017ab84 _binary_obj___user_pgdir_out_end +c0103406 vector238 +c0198c54 _binary_obj___user_yield_out_start +c0100269 readline +c016bb9c _binary_obj___user_hello_out_start +c0102f1a vector133 +c0102cef vector73 +c0102f9e vector144 +c010ce48 vpd +c0100036 kern_init +c0146354 _binary_obj___user_exit_out_start +c01034c6 vector254 +c0102deb vector101 +c01032c2 vector211 +c0103106 vector174 +c0103442 vector243 +c0105c37 copy_range +c0102ede vector128 +c0102d37 vector81 +c01051ee free_pages +c0102ad9 vector13 +c010b989 vsnprintf +c0102c29 vector51 +c0102af0 vector16 +c01a3000 edata +c01016ad cons_init +c0107095 swap_in +c0101da8 ide_write_secs +c01a3fac pmm_manager +c010341e vector240 +c0102c44 vector54 +c0102b09 vector19 +c0124c5c __STAB_END__ +c0102d9a vector92 +c010344e vector244 +c01a4044 swap_init_ok +c010502f load_esp0 +c0102f6e vector140 +c0102bf3 vector45 +c0102d25 vector79 +c010339a vector229 +c0106e07 swap_init +c0103046 vector158 +c0102056 pic_enable +c0109200 swapfs_init +c01a40cc check_rp +000077f8 _binary_obj___user_softint_out_size +c0105b2d exit_range +c0102bbd vector39 +c01030be vector168 +c0198c54 _binary_obj___user_waitkill_out_end +c0102b99 vector35 +c0102e57 vector113 +c0124c5d __STABSTR_BEGIN__ +c010ab1f do_kill +c0102ec3 vector125 +c0100d3b __panic +c0173390 _binary_obj___user_hello_out_end +c01a412c initproc +c01032fe vector216 +c0102c95 vector63 +c0102b48 vector26 +c01014d3 serial_intr +c01031ea vector193 +c010320e vector196 +c0100111 grade_backtrace0 +c01032aa vector209 +c0102a90 vector4 +c01030d6 vector170 +c010b07c schedule +c0102f3e vector136 +c0102ac4 vector10 +c018237c _binary_obj___user_softint_out_end +c0103286 vector206 +c01034d2 vector255 +c010315a vector181 +c0102c71 vector59 +c010012e grade_backtrace +c0102d5b vector85 +c0102d52 vector84 +c010af7c switch_to +c0103172 vector183 +c0103052 vector159 +c01032ce vector212 +c0102c05 vector47 +c010bc99 strtol +c010338e vector228 +c0102bd8 vector42 +c0102e60 vector114 +c010baf0 strnlen +c017ab84 _binary_obj___user_softint_out_start +c014db64 _binary_obj___user_faultread_out_start +c0103112 vector175 +c0102f92 vector143 +c0102ef6 vector130 +c010ccc0 default_pmm_manager +c0103466 vector246 +c0102abb vector9 +c0102f86 vector142 +c0102de2 vector100 +0000782c _binary_obj___user_forktree_out_size +c010324a vector201 +c01021f4 idt_init +c0100a25 print_debuginfo +c010808e find_vma +c01a4060 swap_in_seq_no +c0164370 _binary_obj___user_forktree_out_start +c0102c7a vector60 +c0102b2d vector23 +c01033ee vector236 +c01a3fa4 npage +c0108e43 do_pgfault +c01033b2 vector231 +00007838 _binary_obj___user_divzero_out_size +c01096c1 set_proc_name +c0102cb0 vector66 +c0102b63 vector29 +c0106bfe print_pgdir +c0102f32 vector135 +c0100c54 kmonitor +000077fc _binary_obj___user_badsegment_out_size +c0102d13 vector77 +c010314e vector180 +c0100e0c clock_init +c010329e vector208 +c0102dd0 vector98 +c0102dc7 vector97 +c0105223 nr_free_pages +c0104dcc ksize +000077f4 _binary_obj___user_pgdir_out_size +c010311e vector176 +c0189b70 _binary_obj___user_testbss_out_start +c01031f6 vector194 +c0102b7e vector32 +c01a3fa8 boot_cr3 +c01a6154 end +c0103232 vector199 +c010a010 do_exit +c0102f02 vector131 +c01034ae vector252 +c0102a6c vector0 +c015535c _binary_obj___user_faultreadkernel_out_start +c013eb1c _binary_obj___user_badsegment_out_end +c010bc69 strfind +000078a8 _binary_obj___user_waitkill_out_size +c01016dc cons_putc +c01a40a0 swap_out_seq_no +c010bf7d etext +c0102faa vector145 +c0102e21 vector107 +c012fa00 boot_pgdir +c0102bc6 vector40 +c0101fe9 intr_enable +c0102df4 vector102 +c0189b70 _binary_obj___user_spin_out_end +c0102c56 vector56 +c0102cc2 vector68 +c0102aa2 vector6 +c010b9ef rand +c0102eea vector129 +c010321a vector197 +c0102ffe vector152 +c012f5e0 __vectors +c01033a6 vector230 +c010bbe2 strncmp +c0104b90 slob_init +c010583c get_pte +c0101b2a ide_device_size +c0102bab vector37 +c01a40ec check_swap_addr +c010327a vector205 +c010306a vector161 +c01a4130 current +c010bb60 strncpy +c01086dc copy_to_user +c0102cdd vector71 +c010305e vector160 +c015cb5c _binary_obj___user_forktest_out_start +c0104ba7 kmalloc_init +c01032f2 vector215 +000077f4 _binary_obj___user_spin_out_size +c010303a vector157 +c0101ff1 intr_disable +c0102560 print_regs +c0102e4e vector112 +c01000b9 grade_backtrace2 +c0103166 vector182 +c0102ad2 vector12 +c010bf25 memcmp +c0102e33 vector109 +c0102b12 vector20 +c0102c3b vector53 +c0102b00 vector18 +c010af63 cpu_idle +c0102db5 vector95 +c010a83c do_execve +c0103376 vector226 +c0102c17 vector49 +c0102bea vector44 +c0102d1c vector78 +c01030fa vector173 +c010924b swapfs_read +c0102e7b vector117 +c0102398 trap_in_kernel +c0106efc swap_set_unswappable +c0102d40 vector82 +c0103346 vector222 +c0102ab4 vector8 +c0102fda vector149 +c01003a0 cputchar +c010bdf1 memset +c01033be vector232 +c0101b67 ide_read_secs +c0102e18 vector106 +c010332e vector220 +c0102d88 vector90 +c0103082 vector163 +c010baae srand +c01033d6 vector234 +c0106ecd swap_map_swappable +c0102c8c vector62 +c0102b3f vector25 +c0103226 vector198 +c0102e96 vector120 +c0137320 _binary_obj___user_badarg_out_end +c0100407 getchar +c0105e5c page_remove +c010b354 hash32 +c0102c20 vector50 +c0102ae7 vector15 +c01a40c8 swap_out_num +c010b513 printfmt +c015cb5c _binary_obj___user_faultreadkernel_out_end +c010a977 do_yield +c0102ff2 vector151 +c0102d49 vector83 +c0102d7f vector89 +c0102d76 vector88 +c01029b7 trap +c0103142 vector179 +c0102b90 vector34 +c012c98d __STABSTR_END__ +c0102bfc vector46 +c010bb99 strcmp +c0102f26 vector134 +c0103352 vector223 +c0103316 vector218 +c0100573 debuginfo_eip +c01a4040 max_swap_offset +00007800 _binary_obj___user_faultreadkernel_out_size +c01081e8 insert_vma_struct +c010208b pic_init +c010336a vector225 +c01031a2 vector187 +c010574f pmm_init +c0102b6c vector30 +c0102ed5 vector127 +c01a3424 ticks +c01031de vector192 +c01030a6 vector166 +c0102d0a vector76 +c0102d01 vector75 +c0103202 vector195 +c0102fe6 vector150 +c0102c68 vector58 +c010347e vector248 +c016bb9c _binary_obj___user_forktree_out_end +c0102eb1 vector123 +c0102dbe vector96 +00007810 _binary_obj___user_exit_out_size +c0102b75 vector31 +c0103262 vector203 +c0105181 alloc_pages +c01913ac _binary_obj___user_waitkill_out_start +c0102f62 vector139 +c010300a vector153 +c010308e vector164 +c0102e9f vector121 +c0102a99 vector5 +c018237c _binary_obj___user_spin_out_start +c01030b2 vector167 +c0103022 vector155 +c010348a vector249 +c010ce44 vpt +c0103496 vector250 +c0102eba vector124 +c0102e3c vector110 +c010326e vector204 +c015535c _binary_obj___user_faultread_out_end +c01a4048 swap_page +c0173390 _binary_obj___user_pgdir_out_start +c0102a5b __trapret +c0100343 vcprintf +c0102f4a vector137 +000077f8 _binary_obj___user_faultread_out_size +c0100db9 __warn +c0103472 vector247 +c0102b24 vector22 +c0103256 vector202 +c0102ce6 vector72 +c0102c4d vector55 +c01003b6 cputs +c012f000 bootstacktop +c0109abf find_proc +c0102ecc vector126 +c0102ca7 vector65 +c0102b5a vector28 +c01030ca vector169 +c0106eb3 swap_tick_event +c01033ca vector233 +c0106f1d swap_out +c0104cf0 kmalloc +c0146354 _binary_obj___user_divzero_out_end +c0108051 vma_create +c0102fc2 vector147 +c0109970 proc_run +c012d000 bootstack +c01a1000 __boot_pgdir +c0102e06 vector104 +c01a3f84 free_area +c0102e72 vector116 +c013eb1c _binary_obj___user_divzero_out_start +c01092bf swapfs_write +c010e7e0 __STAB_BEGIN__ +c010905a user_mem_check +c01a40dc check_ptep +c0102c32 vector52 +c0102af9 vector17 +c010317e vector184 +c010bac7 strlen +c0109706 get_proc_name +c01a4110 pgfault_num +c0103292 vector207 +c01a0448 _binary_obj___user_yield_out_end +c01031c6 vector190 +c01017e7 ide_init +c0103412 vector239 +c0102dac vector94 +c0102da3 vector93 +c01031ae vector188 +c010bc35 strchr +c0102c0e vector48 +c01a410c check_mm_struct +c0106e99 swap_init_mm +c01000e0 grade_backtrace1 +c0103322 vector219 +c0102fce vector148 +c010333a vector221 +c0102d2e vector80 +c01030e2 vector171 +c0103016 vector154 +c0102ba2 vector36 +c01033e2 vector235 +c0102e0f vector105 +c0100d13 mon_kerninfo +c01a3fa0 pages +c0102fb6 vector146 +c0105a36 unmap_range +c01031d2 vector191 +c010ada2 proc_init +c0102dfd vector103 +c0100cb6 mon_help +c0102acb vector11 +00007814 _binary_obj___user_forktest_out_size +c0105f5e tlb_invalidate +c0102ae0 vector14 diff --git a/labcodes/lab5/obj/libs/hash.d b/labcodes/lab5/obj/libs/hash.d new file mode 100644 index 0000000000000000000000000000000000000000..15c8e8ac6bd672efbc8ca7678fb4dba6593fbc10 --- /dev/null +++ b/labcodes/lab5/obj/libs/hash.d @@ -0,0 +1 @@ +obj/libs/hash.o obj/libs/hash.d: libs/hash.c libs/stdlib.h libs/defs.h diff --git a/labcodes/lab5/obj/libs/hash.o b/labcodes/lab5/obj/libs/hash.o new file mode 100644 index 0000000000000000000000000000000000000000..c81a1fceeb3ccc82c17b4f30e44038a75e69409a Binary files /dev/null and b/labcodes/lab5/obj/libs/hash.o differ diff --git a/labcodes/lab5/obj/libs/printfmt.d b/labcodes/lab5/obj/libs/printfmt.d new file mode 100644 index 0000000000000000000000000000000000000000..7f093e2c5c51f8fe66f4042d3156c2cdb20748d9 --- /dev/null +++ b/labcodes/lab5/obj/libs/printfmt.d @@ -0,0 +1,2 @@ +obj/libs/printfmt.o obj/libs/printfmt.d: libs/printfmt.c libs/defs.h \ + libs/x86.h libs/error.h libs/stdio.h libs/stdarg.h libs/string.h diff --git a/labcodes/lab5/obj/libs/printfmt.o b/labcodes/lab5/obj/libs/printfmt.o new file mode 100644 index 0000000000000000000000000000000000000000..0aca40d9cec67c108ca4015f5d7d39d25cfb0937 Binary files /dev/null and b/labcodes/lab5/obj/libs/printfmt.o differ diff --git a/labcodes/lab5/obj/libs/rand.d b/labcodes/lab5/obj/libs/rand.d new file mode 100644 index 0000000000000000000000000000000000000000..fa05545e25213dc43dca26b8e504180acd762ca0 --- /dev/null +++ b/labcodes/lab5/obj/libs/rand.d @@ -0,0 +1,2 @@ +obj/libs/rand.o obj/libs/rand.d: libs/rand.c libs/x86.h libs/defs.h \ + libs/stdlib.h diff --git a/labcodes/lab5/obj/libs/rand.o b/labcodes/lab5/obj/libs/rand.o new file mode 100644 index 0000000000000000000000000000000000000000..86760c36aa0cfc7da8ee2a3b3e538a668e5ef1f5 Binary files /dev/null and b/labcodes/lab5/obj/libs/rand.o differ diff --git a/labcodes/lab5/obj/libs/string.d b/labcodes/lab5/obj/libs/string.d new file mode 100644 index 0000000000000000000000000000000000000000..dd7b1bae04cf9987465c430bc7f27da31336fc79 --- /dev/null +++ b/labcodes/lab5/obj/libs/string.d @@ -0,0 +1,2 @@ +obj/libs/string.o obj/libs/string.d: libs/string.c libs/string.h \ + libs/defs.h libs/x86.h diff --git a/labcodes/lab5/obj/libs/string.o b/labcodes/lab5/obj/libs/string.o new file mode 100644 index 0000000000000000000000000000000000000000..1e3bf53a07d3ded3268b428698b7a04ae324ab42 Binary files /dev/null and b/labcodes/lab5/obj/libs/string.o differ diff --git a/labcodes/lab5/obj/sign/tools/sign.d b/labcodes/lab5/obj/sign/tools/sign.d new file mode 100644 index 0000000000000000000000000000000000000000..c988243d10c66a835d03e66608f80a6996f2cde4 --- /dev/null +++ b/labcodes/lab5/obj/sign/tools/sign.d @@ -0,0 +1 @@ +obj/sign/tools/sign.o obj/sign/tools/sign.d: tools/sign.c diff --git a/labcodes/lab5/obj/sign/tools/sign.o b/labcodes/lab5/obj/sign/tools/sign.o new file mode 100644 index 0000000000000000000000000000000000000000..e0c5c83faaaea2512b4f03155aee30e179b623b2 Binary files /dev/null and b/labcodes/lab5/obj/sign/tools/sign.o differ diff --git a/labcodes/lab5/obj/user/badarg.asm b/labcodes/lab5/obj/user/badarg.asm new file mode 100644 index 0000000000000000000000000000000000000000..4a1d45de32c02338ce9595adf5216952954701a8 --- /dev/null +++ b/labcodes/lab5/obj/user/badarg.asm @@ -0,0 +1,2405 @@ + +obj/__user_badarg.out: file format elf32-i386 + + +Disassembly of section .text: + +00800020 <_start>: +.text +.globl _start +_start: + # set ebp for backtrace + movl $0x0, %ebp + 800020: bd 00 00 00 00 mov $0x0,%ebp + + # move down the esp register + # since it may cause page fault in backtrace + subl $0x20, %esp + 800025: 83 ec 20 sub $0x20,%esp + + # call user-program function + call umain + 800028: e8 40 03 00 00 call 80036d +1: jmp 1b + 80002d: eb fe jmp 80002d <_start+0xd> + +0080002f <__panic>: +#include +#include +#include + +void +__panic(const char *file, int line, const char *fmt, ...) { + 80002f: 55 push %ebp + 800030: 89 e5 mov %esp,%ebp + 800032: 83 ec 28 sub $0x28,%esp + // print the 'message' + va_list ap; + va_start(ap, fmt); + 800035: 8d 45 14 lea 0x14(%ebp),%eax + 800038: 89 45 f4 mov %eax,-0xc(%ebp) + cprintf("user panic at %s:%d:\n ", file, line); + 80003b: 8b 45 0c mov 0xc(%ebp),%eax + 80003e: 89 44 24 08 mov %eax,0x8(%esp) + 800042: 8b 45 08 mov 0x8(%ebp),%eax + 800045: 89 44 24 04 mov %eax,0x4(%esp) + 800049: c7 04 24 00 11 80 00 movl $0x801100,(%esp) + 800050: e8 cb 00 00 00 call 800120 + vcprintf(fmt, ap); + 800055: 8b 45 f4 mov -0xc(%ebp),%eax + 800058: 89 44 24 04 mov %eax,0x4(%esp) + 80005c: 8b 45 10 mov 0x10(%ebp),%eax + 80005f: 89 04 24 mov %eax,(%esp) + 800062: e8 84 00 00 00 call 8000eb + cprintf("\n"); + 800067: c7 04 24 1a 11 80 00 movl $0x80111a,(%esp) + 80006e: e8 ad 00 00 00 call 800120 + va_end(ap); + exit(-E_PANIC); + 800073: c7 04 24 f6 ff ff ff movl $0xfffffff6,(%esp) + 80007a: e8 42 02 00 00 call 8002c1 + +0080007f <__warn>: +} + +void +__warn(const char *file, int line, const char *fmt, ...) { + 80007f: 55 push %ebp + 800080: 89 e5 mov %esp,%ebp + 800082: 83 ec 28 sub $0x28,%esp + va_list ap; + va_start(ap, fmt); + 800085: 8d 45 14 lea 0x14(%ebp),%eax + 800088: 89 45 f4 mov %eax,-0xc(%ebp) + cprintf("user warning at %s:%d:\n ", file, line); + 80008b: 8b 45 0c mov 0xc(%ebp),%eax + 80008e: 89 44 24 08 mov %eax,0x8(%esp) + 800092: 8b 45 08 mov 0x8(%ebp),%eax + 800095: 89 44 24 04 mov %eax,0x4(%esp) + 800099: c7 04 24 1c 11 80 00 movl $0x80111c,(%esp) + 8000a0: e8 7b 00 00 00 call 800120 + vcprintf(fmt, ap); + 8000a5: 8b 45 f4 mov -0xc(%ebp),%eax + 8000a8: 89 44 24 04 mov %eax,0x4(%esp) + 8000ac: 8b 45 10 mov 0x10(%ebp),%eax + 8000af: 89 04 24 mov %eax,(%esp) + 8000b2: e8 34 00 00 00 call 8000eb + cprintf("\n"); + 8000b7: c7 04 24 1a 11 80 00 movl $0x80111a,(%esp) + 8000be: e8 5d 00 00 00 call 800120 + va_end(ap); +} + 8000c3: 90 nop + 8000c4: 89 ec mov %ebp,%esp + 8000c6: 5d pop %ebp + 8000c7: c3 ret + +008000c8 : +/* * + * cputch - writes a single character @c to stdout, and it will + * increace the value of counter pointed by @cnt. + * */ +static void +cputch(int c, int *cnt) { + 8000c8: 55 push %ebp + 8000c9: 89 e5 mov %esp,%ebp + 8000cb: 83 ec 18 sub $0x18,%esp + sys_putc(c); + 8000ce: 8b 45 08 mov 0x8(%ebp),%eax + 8000d1: 89 04 24 mov %eax,(%esp) + 8000d4: e8 b5 01 00 00 call 80028e + (*cnt) ++; + 8000d9: 8b 45 0c mov 0xc(%ebp),%eax + 8000dc: 8b 00 mov (%eax),%eax + 8000de: 8d 50 01 lea 0x1(%eax),%edx + 8000e1: 8b 45 0c mov 0xc(%ebp),%eax + 8000e4: 89 10 mov %edx,(%eax) +} + 8000e6: 90 nop + 8000e7: 89 ec mov %ebp,%esp + 8000e9: 5d pop %ebp + 8000ea: c3 ret + +008000eb : + * + * Call this function if you are already dealing with a va_list. + * Or you probably want cprintf() instead. + * */ +int +vcprintf(const char *fmt, va_list ap) { + 8000eb: 55 push %ebp + 8000ec: 89 e5 mov %esp,%ebp + 8000ee: 83 ec 28 sub $0x28,%esp + int cnt = 0; + 8000f1: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + vprintfmt((void*)cputch, &cnt, fmt, ap); + 8000f8: 8b 45 0c mov 0xc(%ebp),%eax + 8000fb: 89 44 24 0c mov %eax,0xc(%esp) + 8000ff: 8b 45 08 mov 0x8(%ebp),%eax + 800102: 89 44 24 08 mov %eax,0x8(%esp) + 800106: 8d 45 f4 lea -0xc(%ebp),%eax + 800109: 89 44 24 04 mov %eax,0x4(%esp) + 80010d: c7 04 24 c8 00 80 00 movl $0x8000c8,(%esp) + 800114: e8 5d 04 00 00 call 800576 + return cnt; + 800119: 8b 45 f4 mov -0xc(%ebp),%eax +} + 80011c: 89 ec mov %ebp,%esp + 80011e: 5d pop %ebp + 80011f: c3 ret + +00800120 : + * + * The return value is the number of characters which would be + * written to stdout. + * */ +int +cprintf(const char *fmt, ...) { + 800120: 55 push %ebp + 800121: 89 e5 mov %esp,%ebp + 800123: 83 ec 28 sub $0x28,%esp + va_list ap; + + va_start(ap, fmt); + 800126: 8d 45 0c lea 0xc(%ebp),%eax + 800129: 89 45 f0 mov %eax,-0x10(%ebp) + int cnt = vcprintf(fmt, ap); + 80012c: 8b 45 f0 mov -0x10(%ebp),%eax + 80012f: 89 44 24 04 mov %eax,0x4(%esp) + 800133: 8b 45 08 mov 0x8(%ebp),%eax + 800136: 89 04 24 mov %eax,(%esp) + 800139: e8 ad ff ff ff call 8000eb + 80013e: 89 45 f4 mov %eax,-0xc(%ebp) + va_end(ap); + + return cnt; + 800141: 8b 45 f4 mov -0xc(%ebp),%eax +} + 800144: 89 ec mov %ebp,%esp + 800146: 5d pop %ebp + 800147: c3 ret + +00800148 : +/* * + * cputs- writes the string pointed by @str to stdout and + * appends a newline character. + * */ +int +cputs(const char *str) { + 800148: 55 push %ebp + 800149: 89 e5 mov %esp,%ebp + 80014b: 83 ec 28 sub $0x28,%esp + int cnt = 0; + 80014e: c7 45 f0 00 00 00 00 movl $0x0,-0x10(%ebp) + char c; + while ((c = *str ++) != '\0') { + 800155: eb 13 jmp 80016a + cputch(c, &cnt); + 800157: 0f be 45 f7 movsbl -0x9(%ebp),%eax + 80015b: 8d 55 f0 lea -0x10(%ebp),%edx + 80015e: 89 54 24 04 mov %edx,0x4(%esp) + 800162: 89 04 24 mov %eax,(%esp) + 800165: e8 5e ff ff ff call 8000c8 + while ((c = *str ++) != '\0') { + 80016a: 8b 45 08 mov 0x8(%ebp),%eax + 80016d: 8d 50 01 lea 0x1(%eax),%edx + 800170: 89 55 08 mov %edx,0x8(%ebp) + 800173: 0f b6 00 movzbl (%eax),%eax + 800176: 88 45 f7 mov %al,-0x9(%ebp) + 800179: 80 7d f7 00 cmpb $0x0,-0x9(%ebp) + 80017d: 75 d8 jne 800157 + } + cputch('\n', &cnt); + 80017f: 8d 45 f0 lea -0x10(%ebp),%eax + 800182: 89 44 24 04 mov %eax,0x4(%esp) + 800186: c7 04 24 0a 00 00 00 movl $0xa,(%esp) + 80018d: e8 36 ff ff ff call 8000c8 + return cnt; + 800192: 8b 45 f0 mov -0x10(%ebp),%eax +} + 800195: 89 ec mov %ebp,%esp + 800197: 5d pop %ebp + 800198: c3 ret + +00800199 : +#include + +#define MAX_ARGS 5 + +static inline int +syscall(int num, ...) { + 800199: 55 push %ebp + 80019a: 89 e5 mov %esp,%ebp + 80019c: 57 push %edi + 80019d: 56 push %esi + 80019e: 53 push %ebx + 80019f: 83 ec 20 sub $0x20,%esp + va_list ap; + va_start(ap, num); + 8001a2: 8d 45 0c lea 0xc(%ebp),%eax + 8001a5: 89 45 e8 mov %eax,-0x18(%ebp) + uint32_t a[MAX_ARGS]; + int i, ret; + for (i = 0; i < MAX_ARGS; i ++) { + 8001a8: c7 45 f0 00 00 00 00 movl $0x0,-0x10(%ebp) + 8001af: eb 15 jmp 8001c6 + a[i] = va_arg(ap, uint32_t); + 8001b1: 8b 45 e8 mov -0x18(%ebp),%eax + 8001b4: 8d 50 04 lea 0x4(%eax),%edx + 8001b7: 89 55 e8 mov %edx,-0x18(%ebp) + 8001ba: 8b 10 mov (%eax),%edx + 8001bc: 8b 45 f0 mov -0x10(%ebp),%eax + 8001bf: 89 54 85 d4 mov %edx,-0x2c(%ebp,%eax,4) + for (i = 0; i < MAX_ARGS; i ++) { + 8001c3: ff 45 f0 incl -0x10(%ebp) + 8001c6: 83 7d f0 04 cmpl $0x4,-0x10(%ebp) + 8001ca: 7e e5 jle 8001b1 + asm volatile ( + "int %1;" + : "=a" (ret) + : "i" (T_SYSCALL), + "a" (num), + "d" (a[0]), + 8001cc: 8b 55 d4 mov -0x2c(%ebp),%edx + "c" (a[1]), + 8001cf: 8b 4d d8 mov -0x28(%ebp),%ecx + "b" (a[2]), + 8001d2: 8b 5d dc mov -0x24(%ebp),%ebx + "D" (a[3]), + 8001d5: 8b 7d e0 mov -0x20(%ebp),%edi + "S" (a[4]) + 8001d8: 8b 75 e4 mov -0x1c(%ebp),%esi + asm volatile ( + 8001db: 8b 45 08 mov 0x8(%ebp),%eax + 8001de: cd 80 int $0x80 + 8001e0: 89 45 ec mov %eax,-0x14(%ebp) + : "cc", "memory"); + return ret; + 8001e3: 8b 45 ec mov -0x14(%ebp),%eax +} + 8001e6: 83 c4 20 add $0x20,%esp + 8001e9: 5b pop %ebx + 8001ea: 5e pop %esi + 8001eb: 5f pop %edi + 8001ec: 5d pop %ebp + 8001ed: c3 ret + +008001ee : + +int +sys_exit(int error_code) { + 8001ee: 55 push %ebp + 8001ef: 89 e5 mov %esp,%ebp + 8001f1: 83 ec 08 sub $0x8,%esp + return syscall(SYS_exit, error_code); + 8001f4: 8b 45 08 mov 0x8(%ebp),%eax + 8001f7: 89 44 24 04 mov %eax,0x4(%esp) + 8001fb: c7 04 24 01 00 00 00 movl $0x1,(%esp) + 800202: e8 92 ff ff ff call 800199 +} + 800207: 89 ec mov %ebp,%esp + 800209: 5d pop %ebp + 80020a: c3 ret + +0080020b : + +int +sys_fork(void) { + 80020b: 55 push %ebp + 80020c: 89 e5 mov %esp,%ebp + 80020e: 83 ec 04 sub $0x4,%esp + return syscall(SYS_fork); + 800211: c7 04 24 02 00 00 00 movl $0x2,(%esp) + 800218: e8 7c ff ff ff call 800199 +} + 80021d: 89 ec mov %ebp,%esp + 80021f: 5d pop %ebp + 800220: c3 ret + +00800221 : + +int +sys_wait(int pid, int *store) { + 800221: 55 push %ebp + 800222: 89 e5 mov %esp,%ebp + 800224: 83 ec 0c sub $0xc,%esp + return syscall(SYS_wait, pid, store); + 800227: 8b 45 0c mov 0xc(%ebp),%eax + 80022a: 89 44 24 08 mov %eax,0x8(%esp) + 80022e: 8b 45 08 mov 0x8(%ebp),%eax + 800231: 89 44 24 04 mov %eax,0x4(%esp) + 800235: c7 04 24 03 00 00 00 movl $0x3,(%esp) + 80023c: e8 58 ff ff ff call 800199 +} + 800241: 89 ec mov %ebp,%esp + 800243: 5d pop %ebp + 800244: c3 ret + +00800245 : + +int +sys_yield(void) { + 800245: 55 push %ebp + 800246: 89 e5 mov %esp,%ebp + 800248: 83 ec 04 sub $0x4,%esp + return syscall(SYS_yield); + 80024b: c7 04 24 0a 00 00 00 movl $0xa,(%esp) + 800252: e8 42 ff ff ff call 800199 +} + 800257: 89 ec mov %ebp,%esp + 800259: 5d pop %ebp + 80025a: c3 ret + +0080025b : + +int +sys_kill(int pid) { + 80025b: 55 push %ebp + 80025c: 89 e5 mov %esp,%ebp + 80025e: 83 ec 08 sub $0x8,%esp + return syscall(SYS_kill, pid); + 800261: 8b 45 08 mov 0x8(%ebp),%eax + 800264: 89 44 24 04 mov %eax,0x4(%esp) + 800268: c7 04 24 0c 00 00 00 movl $0xc,(%esp) + 80026f: e8 25 ff ff ff call 800199 +} + 800274: 89 ec mov %ebp,%esp + 800276: 5d pop %ebp + 800277: c3 ret + +00800278 : + +int +sys_getpid(void) { + 800278: 55 push %ebp + 800279: 89 e5 mov %esp,%ebp + 80027b: 83 ec 04 sub $0x4,%esp + return syscall(SYS_getpid); + 80027e: c7 04 24 12 00 00 00 movl $0x12,(%esp) + 800285: e8 0f ff ff ff call 800199 +} + 80028a: 89 ec mov %ebp,%esp + 80028c: 5d pop %ebp + 80028d: c3 ret + +0080028e : + +int +sys_putc(int c) { + 80028e: 55 push %ebp + 80028f: 89 e5 mov %esp,%ebp + 800291: 83 ec 08 sub $0x8,%esp + return syscall(SYS_putc, c); + 800294: 8b 45 08 mov 0x8(%ebp),%eax + 800297: 89 44 24 04 mov %eax,0x4(%esp) + 80029b: c7 04 24 1e 00 00 00 movl $0x1e,(%esp) + 8002a2: e8 f2 fe ff ff call 800199 +} + 8002a7: 89 ec mov %ebp,%esp + 8002a9: 5d pop %ebp + 8002aa: c3 ret + +008002ab : + +int +sys_pgdir(void) { + 8002ab: 55 push %ebp + 8002ac: 89 e5 mov %esp,%ebp + 8002ae: 83 ec 04 sub $0x4,%esp + return syscall(SYS_pgdir); + 8002b1: c7 04 24 1f 00 00 00 movl $0x1f,(%esp) + 8002b8: e8 dc fe ff ff call 800199 +} + 8002bd: 89 ec mov %ebp,%esp + 8002bf: 5d pop %ebp + 8002c0: c3 ret + +008002c1 : +#include +#include +#include + +void +exit(int error_code) { + 8002c1: 55 push %ebp + 8002c2: 89 e5 mov %esp,%ebp + 8002c4: 83 ec 18 sub $0x18,%esp + sys_exit(error_code); + 8002c7: 8b 45 08 mov 0x8(%ebp),%eax + 8002ca: 89 04 24 mov %eax,(%esp) + 8002cd: e8 1c ff ff ff call 8001ee + cprintf("BUG: exit failed.\n"); + 8002d2: c7 04 24 38 11 80 00 movl $0x801138,(%esp) + 8002d9: e8 42 fe ff ff call 800120 + while (1); + 8002de: eb fe jmp 8002de + +008002e0 : +} + +int +fork(void) { + 8002e0: 55 push %ebp + 8002e1: 89 e5 mov %esp,%ebp + 8002e3: 83 ec 08 sub $0x8,%esp + return sys_fork(); + 8002e6: e8 20 ff ff ff call 80020b +} + 8002eb: 89 ec mov %ebp,%esp + 8002ed: 5d pop %ebp + 8002ee: c3 ret + +008002ef : + +int +wait(void) { + 8002ef: 55 push %ebp + 8002f0: 89 e5 mov %esp,%ebp + 8002f2: 83 ec 18 sub $0x18,%esp + return sys_wait(0, NULL); + 8002f5: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) + 8002fc: 00 + 8002fd: c7 04 24 00 00 00 00 movl $0x0,(%esp) + 800304: e8 18 ff ff ff call 800221 +} + 800309: 89 ec mov %ebp,%esp + 80030b: 5d pop %ebp + 80030c: c3 ret + +0080030d : + +int +waitpid(int pid, int *store) { + 80030d: 55 push %ebp + 80030e: 89 e5 mov %esp,%ebp + 800310: 83 ec 18 sub $0x18,%esp + return sys_wait(pid, store); + 800313: 8b 45 0c mov 0xc(%ebp),%eax + 800316: 89 44 24 04 mov %eax,0x4(%esp) + 80031a: 8b 45 08 mov 0x8(%ebp),%eax + 80031d: 89 04 24 mov %eax,(%esp) + 800320: e8 fc fe ff ff call 800221 +} + 800325: 89 ec mov %ebp,%esp + 800327: 5d pop %ebp + 800328: c3 ret + +00800329 : + +void +yield(void) { + 800329: 55 push %ebp + 80032a: 89 e5 mov %esp,%ebp + 80032c: 83 ec 08 sub $0x8,%esp + sys_yield(); + 80032f: e8 11 ff ff ff call 800245 +} + 800334: 90 nop + 800335: 89 ec mov %ebp,%esp + 800337: 5d pop %ebp + 800338: c3 ret + +00800339 : + +int +kill(int pid) { + 800339: 55 push %ebp + 80033a: 89 e5 mov %esp,%ebp + 80033c: 83 ec 18 sub $0x18,%esp + return sys_kill(pid); + 80033f: 8b 45 08 mov 0x8(%ebp),%eax + 800342: 89 04 24 mov %eax,(%esp) + 800345: e8 11 ff ff ff call 80025b +} + 80034a: 89 ec mov %ebp,%esp + 80034c: 5d pop %ebp + 80034d: c3 ret + +0080034e : + +int +getpid(void) { + 80034e: 55 push %ebp + 80034f: 89 e5 mov %esp,%ebp + 800351: 83 ec 08 sub $0x8,%esp + return sys_getpid(); + 800354: e8 1f ff ff ff call 800278 +} + 800359: 89 ec mov %ebp,%esp + 80035b: 5d pop %ebp + 80035c: c3 ret + +0080035d : + +//print_pgdir - print the PDT&PT +void +print_pgdir(void) { + 80035d: 55 push %ebp + 80035e: 89 e5 mov %esp,%ebp + 800360: 83 ec 08 sub $0x8,%esp + sys_pgdir(); + 800363: e8 43 ff ff ff call 8002ab +} + 800368: 90 nop + 800369: 89 ec mov %ebp,%esp + 80036b: 5d pop %ebp + 80036c: c3 ret + +0080036d : +#include + +int main(void); + +void +umain(void) { + 80036d: 55 push %ebp + 80036e: 89 e5 mov %esp,%ebp + 800370: 83 ec 28 sub $0x28,%esp + int ret = main(); + 800373: e8 37 0c 00 00 call 800faf
+ 800378: 89 45 f4 mov %eax,-0xc(%ebp) + exit(ret); + 80037b: 8b 45 f4 mov -0xc(%ebp),%eax + 80037e: 89 04 24 mov %eax,(%esp) + 800381: e8 3b ff ff ff call 8002c1 + +00800386 : + * @bits: the number of bits in a return value + * + * High bits are more random, so we use them. + * */ +uint32_t +hash32(uint32_t val, unsigned int bits) { + 800386: 55 push %ebp + 800387: 89 e5 mov %esp,%ebp + 800389: 83 ec 10 sub $0x10,%esp + uint32_t hash = val * GOLDEN_RATIO_PRIME_32; + 80038c: 8b 45 08 mov 0x8(%ebp),%eax + 80038f: 69 c0 01 00 37 9e imul $0x9e370001,%eax,%eax + 800395: 89 45 fc mov %eax,-0x4(%ebp) + return (hash >> (32 - bits)); + 800398: b8 20 00 00 00 mov $0x20,%eax + 80039d: 2b 45 0c sub 0xc(%ebp),%eax + 8003a0: 8b 55 fc mov -0x4(%ebp),%edx + 8003a3: 88 c1 mov %al,%cl + 8003a5: d3 ea shr %cl,%edx + 8003a7: 89 d0 mov %edx,%eax +} + 8003a9: 89 ec mov %ebp,%esp + 8003ab: 5d pop %ebp + 8003ac: c3 ret + +008003ad : + * @width: maximum number of digits, if the actual width is less than @width, use @padc instead + * @padc: character that padded on the left if the actual width is less than @width + * */ +static void +printnum(void (*putch)(int, void*), void *putdat, + unsigned long long num, unsigned base, int width, int padc) { + 8003ad: 55 push %ebp + 8003ae: 89 e5 mov %esp,%ebp + 8003b0: 83 ec 58 sub $0x58,%esp + 8003b3: 8b 45 10 mov 0x10(%ebp),%eax + 8003b6: 89 45 d0 mov %eax,-0x30(%ebp) + 8003b9: 8b 45 14 mov 0x14(%ebp),%eax + 8003bc: 89 45 d4 mov %eax,-0x2c(%ebp) + unsigned long long result = num; + 8003bf: 8b 45 d0 mov -0x30(%ebp),%eax + 8003c2: 8b 55 d4 mov -0x2c(%ebp),%edx + 8003c5: 89 45 e8 mov %eax,-0x18(%ebp) + 8003c8: 89 55 ec mov %edx,-0x14(%ebp) + unsigned mod = do_div(result, base); + 8003cb: 8b 45 18 mov 0x18(%ebp),%eax + 8003ce: 89 45 e4 mov %eax,-0x1c(%ebp) + 8003d1: 8b 45 e8 mov -0x18(%ebp),%eax + 8003d4: 8b 55 ec mov -0x14(%ebp),%edx + 8003d7: 89 45 e0 mov %eax,-0x20(%ebp) + 8003da: 89 55 f0 mov %edx,-0x10(%ebp) + 8003dd: 8b 45 f0 mov -0x10(%ebp),%eax + 8003e0: 89 45 f4 mov %eax,-0xc(%ebp) + 8003e3: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) + 8003e7: 74 1c je 800405 + 8003e9: 8b 45 f0 mov -0x10(%ebp),%eax + 8003ec: ba 00 00 00 00 mov $0x0,%edx + 8003f1: f7 75 e4 divl -0x1c(%ebp) + 8003f4: 89 55 f4 mov %edx,-0xc(%ebp) + 8003f7: 8b 45 f0 mov -0x10(%ebp),%eax + 8003fa: ba 00 00 00 00 mov $0x0,%edx + 8003ff: f7 75 e4 divl -0x1c(%ebp) + 800402: 89 45 f0 mov %eax,-0x10(%ebp) + 800405: 8b 45 e0 mov -0x20(%ebp),%eax + 800408: 8b 55 f4 mov -0xc(%ebp),%edx + 80040b: f7 75 e4 divl -0x1c(%ebp) + 80040e: 89 45 e0 mov %eax,-0x20(%ebp) + 800411: 89 55 dc mov %edx,-0x24(%ebp) + 800414: 8b 45 e0 mov -0x20(%ebp),%eax + 800417: 8b 55 f0 mov -0x10(%ebp),%edx + 80041a: 89 45 e8 mov %eax,-0x18(%ebp) + 80041d: 89 55 ec mov %edx,-0x14(%ebp) + 800420: 8b 45 dc mov -0x24(%ebp),%eax + 800423: 89 45 d8 mov %eax,-0x28(%ebp) + + // first recursively print all preceding (more significant) digits + if (num >= base) { + 800426: 8b 45 18 mov 0x18(%ebp),%eax + 800429: ba 00 00 00 00 mov $0x0,%edx + 80042e: 8b 4d d4 mov -0x2c(%ebp),%ecx + 800431: 39 45 d0 cmp %eax,-0x30(%ebp) + 800434: 19 d1 sbb %edx,%ecx + 800436: 72 4c jb 800484 + printnum(putch, putdat, result, base, width - 1, padc); + 800438: 8b 45 1c mov 0x1c(%ebp),%eax + 80043b: 8d 50 ff lea -0x1(%eax),%edx + 80043e: 8b 45 20 mov 0x20(%ebp),%eax + 800441: 89 44 24 18 mov %eax,0x18(%esp) + 800445: 89 54 24 14 mov %edx,0x14(%esp) + 800449: 8b 45 18 mov 0x18(%ebp),%eax + 80044c: 89 44 24 10 mov %eax,0x10(%esp) + 800450: 8b 45 e8 mov -0x18(%ebp),%eax + 800453: 8b 55 ec mov -0x14(%ebp),%edx + 800456: 89 44 24 08 mov %eax,0x8(%esp) + 80045a: 89 54 24 0c mov %edx,0xc(%esp) + 80045e: 8b 45 0c mov 0xc(%ebp),%eax + 800461: 89 44 24 04 mov %eax,0x4(%esp) + 800465: 8b 45 08 mov 0x8(%ebp),%eax + 800468: 89 04 24 mov %eax,(%esp) + 80046b: e8 3d ff ff ff call 8003ad + 800470: eb 1b jmp 80048d + } else { + // print any needed pad characters before first digit + while (-- width > 0) + putch(padc, putdat); + 800472: 8b 45 0c mov 0xc(%ebp),%eax + 800475: 89 44 24 04 mov %eax,0x4(%esp) + 800479: 8b 45 20 mov 0x20(%ebp),%eax + 80047c: 89 04 24 mov %eax,(%esp) + 80047f: 8b 45 08 mov 0x8(%ebp),%eax + 800482: ff d0 call *%eax + while (-- width > 0) + 800484: ff 4d 1c decl 0x1c(%ebp) + 800487: 83 7d 1c 00 cmpl $0x0,0x1c(%ebp) + 80048b: 7f e5 jg 800472 + } + // then print this (the least significant) digit + putch("0123456789abcdef"[mod], putdat); + 80048d: 8b 45 d8 mov -0x28(%ebp),%eax + 800490: 05 64 12 80 00 add $0x801264,%eax + 800495: 0f b6 00 movzbl (%eax),%eax + 800498: 0f be c0 movsbl %al,%eax + 80049b: 8b 55 0c mov 0xc(%ebp),%edx + 80049e: 89 54 24 04 mov %edx,0x4(%esp) + 8004a2: 89 04 24 mov %eax,(%esp) + 8004a5: 8b 45 08 mov 0x8(%ebp),%eax + 8004a8: ff d0 call *%eax +} + 8004aa: 90 nop + 8004ab: 89 ec mov %ebp,%esp + 8004ad: 5d pop %ebp + 8004ae: c3 ret + +008004af : + * getuint - get an unsigned int of various possible sizes from a varargs list + * @ap: a varargs list pointer + * @lflag: determines the size of the vararg that @ap points to + * */ +static unsigned long long +getuint(va_list *ap, int lflag) { + 8004af: 55 push %ebp + 8004b0: 89 e5 mov %esp,%ebp + if (lflag >= 2) { + 8004b2: 83 7d 0c 01 cmpl $0x1,0xc(%ebp) + 8004b6: 7e 14 jle 8004cc + return va_arg(*ap, unsigned long long); + 8004b8: 8b 45 08 mov 0x8(%ebp),%eax + 8004bb: 8b 00 mov (%eax),%eax + 8004bd: 8d 48 08 lea 0x8(%eax),%ecx + 8004c0: 8b 55 08 mov 0x8(%ebp),%edx + 8004c3: 89 0a mov %ecx,(%edx) + 8004c5: 8b 50 04 mov 0x4(%eax),%edx + 8004c8: 8b 00 mov (%eax),%eax + 8004ca: eb 30 jmp 8004fc + } + else if (lflag) { + 8004cc: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) + 8004d0: 74 16 je 8004e8 + return va_arg(*ap, unsigned long); + 8004d2: 8b 45 08 mov 0x8(%ebp),%eax + 8004d5: 8b 00 mov (%eax),%eax + 8004d7: 8d 48 04 lea 0x4(%eax),%ecx + 8004da: 8b 55 08 mov 0x8(%ebp),%edx + 8004dd: 89 0a mov %ecx,(%edx) + 8004df: 8b 00 mov (%eax),%eax + 8004e1: ba 00 00 00 00 mov $0x0,%edx + 8004e6: eb 14 jmp 8004fc + } + else { + return va_arg(*ap, unsigned int); + 8004e8: 8b 45 08 mov 0x8(%ebp),%eax + 8004eb: 8b 00 mov (%eax),%eax + 8004ed: 8d 48 04 lea 0x4(%eax),%ecx + 8004f0: 8b 55 08 mov 0x8(%ebp),%edx + 8004f3: 89 0a mov %ecx,(%edx) + 8004f5: 8b 00 mov (%eax),%eax + 8004f7: ba 00 00 00 00 mov $0x0,%edx + } +} + 8004fc: 5d pop %ebp + 8004fd: c3 ret + +008004fe : + * getint - same as getuint but signed, we can't use getuint because of sign extension + * @ap: a varargs list pointer + * @lflag: determines the size of the vararg that @ap points to + * */ +static long long +getint(va_list *ap, int lflag) { + 8004fe: 55 push %ebp + 8004ff: 89 e5 mov %esp,%ebp + if (lflag >= 2) { + 800501: 83 7d 0c 01 cmpl $0x1,0xc(%ebp) + 800505: 7e 14 jle 80051b + return va_arg(*ap, long long); + 800507: 8b 45 08 mov 0x8(%ebp),%eax + 80050a: 8b 00 mov (%eax),%eax + 80050c: 8d 48 08 lea 0x8(%eax),%ecx + 80050f: 8b 55 08 mov 0x8(%ebp),%edx + 800512: 89 0a mov %ecx,(%edx) + 800514: 8b 50 04 mov 0x4(%eax),%edx + 800517: 8b 00 mov (%eax),%eax + 800519: eb 28 jmp 800543 + } + else if (lflag) { + 80051b: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) + 80051f: 74 12 je 800533 + return va_arg(*ap, long); + 800521: 8b 45 08 mov 0x8(%ebp),%eax + 800524: 8b 00 mov (%eax),%eax + 800526: 8d 48 04 lea 0x4(%eax),%ecx + 800529: 8b 55 08 mov 0x8(%ebp),%edx + 80052c: 89 0a mov %ecx,(%edx) + 80052e: 8b 00 mov (%eax),%eax + 800530: 99 cltd + 800531: eb 10 jmp 800543 + } + else { + return va_arg(*ap, int); + 800533: 8b 45 08 mov 0x8(%ebp),%eax + 800536: 8b 00 mov (%eax),%eax + 800538: 8d 48 04 lea 0x4(%eax),%ecx + 80053b: 8b 55 08 mov 0x8(%ebp),%edx + 80053e: 89 0a mov %ecx,(%edx) + 800540: 8b 00 mov (%eax),%eax + 800542: 99 cltd + } +} + 800543: 5d pop %ebp + 800544: c3 ret + +00800545 : + * @putch: specified putch function, print a single character + * @putdat: used by @putch function + * @fmt: the format string to use + * */ +void +printfmt(void (*putch)(int, void*), void *putdat, const char *fmt, ...) { + 800545: 55 push %ebp + 800546: 89 e5 mov %esp,%ebp + 800548: 83 ec 28 sub $0x28,%esp + va_list ap; + + va_start(ap, fmt); + 80054b: 8d 45 14 lea 0x14(%ebp),%eax + 80054e: 89 45 f4 mov %eax,-0xc(%ebp) + vprintfmt(putch, putdat, fmt, ap); + 800551: 8b 45 f4 mov -0xc(%ebp),%eax + 800554: 89 44 24 0c mov %eax,0xc(%esp) + 800558: 8b 45 10 mov 0x10(%ebp),%eax + 80055b: 89 44 24 08 mov %eax,0x8(%esp) + 80055f: 8b 45 0c mov 0xc(%ebp),%eax + 800562: 89 44 24 04 mov %eax,0x4(%esp) + 800566: 8b 45 08 mov 0x8(%ebp),%eax + 800569: 89 04 24 mov %eax,(%esp) + 80056c: e8 05 00 00 00 call 800576 + va_end(ap); +} + 800571: 90 nop + 800572: 89 ec mov %ebp,%esp + 800574: 5d pop %ebp + 800575: c3 ret + +00800576 : + * + * Call this function if you are already dealing with a va_list. + * Or you probably want printfmt() instead. + * */ +void +vprintfmt(void (*putch)(int, void*), void *putdat, const char *fmt, va_list ap) { + 800576: 55 push %ebp + 800577: 89 e5 mov %esp,%ebp + 800579: 56 push %esi + 80057a: 53 push %ebx + 80057b: 83 ec 40 sub $0x40,%esp + register int ch, err; + unsigned long long num; + int base, width, precision, lflag, altflag; + + while (1) { + while ((ch = *(unsigned char *)fmt ++) != '%') { + 80057e: eb 17 jmp 800597 + if (ch == '\0') { + 800580: 85 db test %ebx,%ebx + 800582: 0f 84 bf 03 00 00 je 800947 + return; + } + putch(ch, putdat); + 800588: 8b 45 0c mov 0xc(%ebp),%eax + 80058b: 89 44 24 04 mov %eax,0x4(%esp) + 80058f: 89 1c 24 mov %ebx,(%esp) + 800592: 8b 45 08 mov 0x8(%ebp),%eax + 800595: ff d0 call *%eax + while ((ch = *(unsigned char *)fmt ++) != '%') { + 800597: 8b 45 10 mov 0x10(%ebp),%eax + 80059a: 8d 50 01 lea 0x1(%eax),%edx + 80059d: 89 55 10 mov %edx,0x10(%ebp) + 8005a0: 0f b6 00 movzbl (%eax),%eax + 8005a3: 0f b6 d8 movzbl %al,%ebx + 8005a6: 83 fb 25 cmp $0x25,%ebx + 8005a9: 75 d5 jne 800580 + } + + // Process a %-escape sequence + char padc = ' '; + 8005ab: c6 45 db 20 movb $0x20,-0x25(%ebp) + width = precision = -1; + 8005af: c7 45 e4 ff ff ff ff movl $0xffffffff,-0x1c(%ebp) + 8005b6: 8b 45 e4 mov -0x1c(%ebp),%eax + 8005b9: 89 45 e8 mov %eax,-0x18(%ebp) + lflag = altflag = 0; + 8005bc: c7 45 dc 00 00 00 00 movl $0x0,-0x24(%ebp) + 8005c3: 8b 45 dc mov -0x24(%ebp),%eax + 8005c6: 89 45 e0 mov %eax,-0x20(%ebp) + + reswitch: + switch (ch = *(unsigned char *)fmt ++) { + 8005c9: 8b 45 10 mov 0x10(%ebp),%eax + 8005cc: 8d 50 01 lea 0x1(%eax),%edx + 8005cf: 89 55 10 mov %edx,0x10(%ebp) + 8005d2: 0f b6 00 movzbl (%eax),%eax + 8005d5: 0f b6 d8 movzbl %al,%ebx + 8005d8: 8d 43 dd lea -0x23(%ebx),%eax + 8005db: 83 f8 55 cmp $0x55,%eax + 8005de: 0f 87 37 03 00 00 ja 80091b + 8005e4: 8b 04 85 88 12 80 00 mov 0x801288(,%eax,4),%eax + 8005eb: ff e0 jmp *%eax + + // flag to pad on the right + case '-': + padc = '-'; + 8005ed: c6 45 db 2d movb $0x2d,-0x25(%ebp) + goto reswitch; + 8005f1: eb d6 jmp 8005c9 + + // flag to pad with 0's instead of spaces + case '0': + padc = '0'; + 8005f3: c6 45 db 30 movb $0x30,-0x25(%ebp) + goto reswitch; + 8005f7: eb d0 jmp 8005c9 + + // width field + case '1' ... '9': + for (precision = 0; ; ++ fmt) { + 8005f9: c7 45 e4 00 00 00 00 movl $0x0,-0x1c(%ebp) + precision = precision * 10 + ch - '0'; + 800600: 8b 55 e4 mov -0x1c(%ebp),%edx + 800603: 89 d0 mov %edx,%eax + 800605: c1 e0 02 shl $0x2,%eax + 800608: 01 d0 add %edx,%eax + 80060a: 01 c0 add %eax,%eax + 80060c: 01 d8 add %ebx,%eax + 80060e: 83 e8 30 sub $0x30,%eax + 800611: 89 45 e4 mov %eax,-0x1c(%ebp) + ch = *fmt; + 800614: 8b 45 10 mov 0x10(%ebp),%eax + 800617: 0f b6 00 movzbl (%eax),%eax + 80061a: 0f be d8 movsbl %al,%ebx + if (ch < '0' || ch > '9') { + 80061d: 83 fb 2f cmp $0x2f,%ebx + 800620: 7e 38 jle 80065a + 800622: 83 fb 39 cmp $0x39,%ebx + 800625: 7f 33 jg 80065a + for (precision = 0; ; ++ fmt) { + 800627: ff 45 10 incl 0x10(%ebp) + precision = precision * 10 + ch - '0'; + 80062a: eb d4 jmp 800600 + } + } + goto process_precision; + + case '*': + precision = va_arg(ap, int); + 80062c: 8b 45 14 mov 0x14(%ebp),%eax + 80062f: 8d 50 04 lea 0x4(%eax),%edx + 800632: 89 55 14 mov %edx,0x14(%ebp) + 800635: 8b 00 mov (%eax),%eax + 800637: 89 45 e4 mov %eax,-0x1c(%ebp) + goto process_precision; + 80063a: eb 1f jmp 80065b + + case '.': + if (width < 0) + 80063c: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 800640: 79 87 jns 8005c9 + width = 0; + 800642: c7 45 e8 00 00 00 00 movl $0x0,-0x18(%ebp) + goto reswitch; + 800649: e9 7b ff ff ff jmp 8005c9 + + case '#': + altflag = 1; + 80064e: c7 45 dc 01 00 00 00 movl $0x1,-0x24(%ebp) + goto reswitch; + 800655: e9 6f ff ff ff jmp 8005c9 + goto process_precision; + 80065a: 90 nop + + process_precision: + if (width < 0) + 80065b: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 80065f: 0f 89 64 ff ff ff jns 8005c9 + width = precision, precision = -1; + 800665: 8b 45 e4 mov -0x1c(%ebp),%eax + 800668: 89 45 e8 mov %eax,-0x18(%ebp) + 80066b: c7 45 e4 ff ff ff ff movl $0xffffffff,-0x1c(%ebp) + goto reswitch; + 800672: e9 52 ff ff ff jmp 8005c9 + + // long flag (doubled for long long) + case 'l': + lflag ++; + 800677: ff 45 e0 incl -0x20(%ebp) + goto reswitch; + 80067a: e9 4a ff ff ff jmp 8005c9 + + // character + case 'c': + putch(va_arg(ap, int), putdat); + 80067f: 8b 45 14 mov 0x14(%ebp),%eax + 800682: 8d 50 04 lea 0x4(%eax),%edx + 800685: 89 55 14 mov %edx,0x14(%ebp) + 800688: 8b 00 mov (%eax),%eax + 80068a: 8b 55 0c mov 0xc(%ebp),%edx + 80068d: 89 54 24 04 mov %edx,0x4(%esp) + 800691: 89 04 24 mov %eax,(%esp) + 800694: 8b 45 08 mov 0x8(%ebp),%eax + 800697: ff d0 call *%eax + break; + 800699: e9 a4 02 00 00 jmp 800942 + + // error message + case 'e': + err = va_arg(ap, int); + 80069e: 8b 45 14 mov 0x14(%ebp),%eax + 8006a1: 8d 50 04 lea 0x4(%eax),%edx + 8006a4: 89 55 14 mov %edx,0x14(%ebp) + 8006a7: 8b 18 mov (%eax),%ebx + if (err < 0) { + 8006a9: 85 db test %ebx,%ebx + 8006ab: 79 02 jns 8006af + err = -err; + 8006ad: f7 db neg %ebx + } + if (err > MAXERROR || (p = error_string[err]) == NULL) { + 8006af: 83 fb 18 cmp $0x18,%ebx + 8006b2: 7f 0b jg 8006bf + 8006b4: 8b 34 9d 00 12 80 00 mov 0x801200(,%ebx,4),%esi + 8006bb: 85 f6 test %esi,%esi + 8006bd: 75 23 jne 8006e2 + printfmt(putch, putdat, "error %d", err); + 8006bf: 89 5c 24 0c mov %ebx,0xc(%esp) + 8006c3: c7 44 24 08 75 12 80 movl $0x801275,0x8(%esp) + 8006ca: 00 + 8006cb: 8b 45 0c mov 0xc(%ebp),%eax + 8006ce: 89 44 24 04 mov %eax,0x4(%esp) + 8006d2: 8b 45 08 mov 0x8(%ebp),%eax + 8006d5: 89 04 24 mov %eax,(%esp) + 8006d8: e8 68 fe ff ff call 800545 + } + else { + printfmt(putch, putdat, "%s", p); + } + break; + 8006dd: e9 60 02 00 00 jmp 800942 + printfmt(putch, putdat, "%s", p); + 8006e2: 89 74 24 0c mov %esi,0xc(%esp) + 8006e6: c7 44 24 08 7e 12 80 movl $0x80127e,0x8(%esp) + 8006ed: 00 + 8006ee: 8b 45 0c mov 0xc(%ebp),%eax + 8006f1: 89 44 24 04 mov %eax,0x4(%esp) + 8006f5: 8b 45 08 mov 0x8(%ebp),%eax + 8006f8: 89 04 24 mov %eax,(%esp) + 8006fb: e8 45 fe ff ff call 800545 + break; + 800700: e9 3d 02 00 00 jmp 800942 + + // string + case 's': + if ((p = va_arg(ap, char *)) == NULL) { + 800705: 8b 45 14 mov 0x14(%ebp),%eax + 800708: 8d 50 04 lea 0x4(%eax),%edx + 80070b: 89 55 14 mov %edx,0x14(%ebp) + 80070e: 8b 30 mov (%eax),%esi + 800710: 85 f6 test %esi,%esi + 800712: 75 05 jne 800719 + p = "(null)"; + 800714: be 81 12 80 00 mov $0x801281,%esi + } + if (width > 0 && padc != '-') { + 800719: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 80071d: 7e 76 jle 800795 + 80071f: 80 7d db 2d cmpb $0x2d,-0x25(%ebp) + 800723: 74 70 je 800795 + for (width -= strnlen(p, precision); width > 0; width --) { + 800725: 8b 45 e4 mov -0x1c(%ebp),%eax + 800728: 89 44 24 04 mov %eax,0x4(%esp) + 80072c: 89 34 24 mov %esi,(%esp) + 80072f: e8 ee 03 00 00 call 800b22 + 800734: 89 c2 mov %eax,%edx + 800736: 8b 45 e8 mov -0x18(%ebp),%eax + 800739: 29 d0 sub %edx,%eax + 80073b: 89 45 e8 mov %eax,-0x18(%ebp) + 80073e: eb 16 jmp 800756 + putch(padc, putdat); + 800740: 0f be 45 db movsbl -0x25(%ebp),%eax + 800744: 8b 55 0c mov 0xc(%ebp),%edx + 800747: 89 54 24 04 mov %edx,0x4(%esp) + 80074b: 89 04 24 mov %eax,(%esp) + 80074e: 8b 45 08 mov 0x8(%ebp),%eax + 800751: ff d0 call *%eax + for (width -= strnlen(p, precision); width > 0; width --) { + 800753: ff 4d e8 decl -0x18(%ebp) + 800756: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 80075a: 7f e4 jg 800740 + } + } + for (; (ch = *p ++) != '\0' && (precision < 0 || -- precision >= 0); width --) { + 80075c: eb 37 jmp 800795 + if (altflag && (ch < ' ' || ch > '~')) { + 80075e: 83 7d dc 00 cmpl $0x0,-0x24(%ebp) + 800762: 74 1f je 800783 + 800764: 83 fb 1f cmp $0x1f,%ebx + 800767: 7e 05 jle 80076e + 800769: 83 fb 7e cmp $0x7e,%ebx + 80076c: 7e 15 jle 800783 + putch('?', putdat); + 80076e: 8b 45 0c mov 0xc(%ebp),%eax + 800771: 89 44 24 04 mov %eax,0x4(%esp) + 800775: c7 04 24 3f 00 00 00 movl $0x3f,(%esp) + 80077c: 8b 45 08 mov 0x8(%ebp),%eax + 80077f: ff d0 call *%eax + 800781: eb 0f jmp 800792 + } + else { + putch(ch, putdat); + 800783: 8b 45 0c mov 0xc(%ebp),%eax + 800786: 89 44 24 04 mov %eax,0x4(%esp) + 80078a: 89 1c 24 mov %ebx,(%esp) + 80078d: 8b 45 08 mov 0x8(%ebp),%eax + 800790: ff d0 call *%eax + for (; (ch = *p ++) != '\0' && (precision < 0 || -- precision >= 0); width --) { + 800792: ff 4d e8 decl -0x18(%ebp) + 800795: 89 f0 mov %esi,%eax + 800797: 8d 70 01 lea 0x1(%eax),%esi + 80079a: 0f b6 00 movzbl (%eax),%eax + 80079d: 0f be d8 movsbl %al,%ebx + 8007a0: 85 db test %ebx,%ebx + 8007a2: 74 27 je 8007cb + 8007a4: 83 7d e4 00 cmpl $0x0,-0x1c(%ebp) + 8007a8: 78 b4 js 80075e + 8007aa: ff 4d e4 decl -0x1c(%ebp) + 8007ad: 83 7d e4 00 cmpl $0x0,-0x1c(%ebp) + 8007b1: 79 ab jns 80075e + } + } + for (; width > 0; width --) { + 8007b3: eb 16 jmp 8007cb + putch(' ', putdat); + 8007b5: 8b 45 0c mov 0xc(%ebp),%eax + 8007b8: 89 44 24 04 mov %eax,0x4(%esp) + 8007bc: c7 04 24 20 00 00 00 movl $0x20,(%esp) + 8007c3: 8b 45 08 mov 0x8(%ebp),%eax + 8007c6: ff d0 call *%eax + for (; width > 0; width --) { + 8007c8: ff 4d e8 decl -0x18(%ebp) + 8007cb: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 8007cf: 7f e4 jg 8007b5 + } + break; + 8007d1: e9 6c 01 00 00 jmp 800942 + + // (signed) decimal + case 'd': + num = getint(&ap, lflag); + 8007d6: 8b 45 e0 mov -0x20(%ebp),%eax + 8007d9: 89 44 24 04 mov %eax,0x4(%esp) + 8007dd: 8d 45 14 lea 0x14(%ebp),%eax + 8007e0: 89 04 24 mov %eax,(%esp) + 8007e3: e8 16 fd ff ff call 8004fe + 8007e8: 89 45 f0 mov %eax,-0x10(%ebp) + 8007eb: 89 55 f4 mov %edx,-0xc(%ebp) + if ((long long)num < 0) { + 8007ee: 8b 45 f0 mov -0x10(%ebp),%eax + 8007f1: 8b 55 f4 mov -0xc(%ebp),%edx + 8007f4: 85 d2 test %edx,%edx + 8007f6: 79 26 jns 80081e + putch('-', putdat); + 8007f8: 8b 45 0c mov 0xc(%ebp),%eax + 8007fb: 89 44 24 04 mov %eax,0x4(%esp) + 8007ff: c7 04 24 2d 00 00 00 movl $0x2d,(%esp) + 800806: 8b 45 08 mov 0x8(%ebp),%eax + 800809: ff d0 call *%eax + num = -(long long)num; + 80080b: 8b 45 f0 mov -0x10(%ebp),%eax + 80080e: 8b 55 f4 mov -0xc(%ebp),%edx + 800811: f7 d8 neg %eax + 800813: 83 d2 00 adc $0x0,%edx + 800816: f7 da neg %edx + 800818: 89 45 f0 mov %eax,-0x10(%ebp) + 80081b: 89 55 f4 mov %edx,-0xc(%ebp) + } + base = 10; + 80081e: c7 45 ec 0a 00 00 00 movl $0xa,-0x14(%ebp) + goto number; + 800825: e9 a8 00 00 00 jmp 8008d2 + + // unsigned decimal + case 'u': + num = getuint(&ap, lflag); + 80082a: 8b 45 e0 mov -0x20(%ebp),%eax + 80082d: 89 44 24 04 mov %eax,0x4(%esp) + 800831: 8d 45 14 lea 0x14(%ebp),%eax + 800834: 89 04 24 mov %eax,(%esp) + 800837: e8 73 fc ff ff call 8004af + 80083c: 89 45 f0 mov %eax,-0x10(%ebp) + 80083f: 89 55 f4 mov %edx,-0xc(%ebp) + base = 10; + 800842: c7 45 ec 0a 00 00 00 movl $0xa,-0x14(%ebp) + goto number; + 800849: e9 84 00 00 00 jmp 8008d2 + + // (unsigned) octal + case 'o': + num = getuint(&ap, lflag); + 80084e: 8b 45 e0 mov -0x20(%ebp),%eax + 800851: 89 44 24 04 mov %eax,0x4(%esp) + 800855: 8d 45 14 lea 0x14(%ebp),%eax + 800858: 89 04 24 mov %eax,(%esp) + 80085b: e8 4f fc ff ff call 8004af + 800860: 89 45 f0 mov %eax,-0x10(%ebp) + 800863: 89 55 f4 mov %edx,-0xc(%ebp) + base = 8; + 800866: c7 45 ec 08 00 00 00 movl $0x8,-0x14(%ebp) + goto number; + 80086d: eb 63 jmp 8008d2 + + // pointer + case 'p': + putch('0', putdat); + 80086f: 8b 45 0c mov 0xc(%ebp),%eax + 800872: 89 44 24 04 mov %eax,0x4(%esp) + 800876: c7 04 24 30 00 00 00 movl $0x30,(%esp) + 80087d: 8b 45 08 mov 0x8(%ebp),%eax + 800880: ff d0 call *%eax + putch('x', putdat); + 800882: 8b 45 0c mov 0xc(%ebp),%eax + 800885: 89 44 24 04 mov %eax,0x4(%esp) + 800889: c7 04 24 78 00 00 00 movl $0x78,(%esp) + 800890: 8b 45 08 mov 0x8(%ebp),%eax + 800893: ff d0 call *%eax + num = (unsigned long long)(uintptr_t)va_arg(ap, void *); + 800895: 8b 45 14 mov 0x14(%ebp),%eax + 800898: 8d 50 04 lea 0x4(%eax),%edx + 80089b: 89 55 14 mov %edx,0x14(%ebp) + 80089e: 8b 00 mov (%eax),%eax + 8008a0: 89 45 f0 mov %eax,-0x10(%ebp) + 8008a3: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + base = 16; + 8008aa: c7 45 ec 10 00 00 00 movl $0x10,-0x14(%ebp) + goto number; + 8008b1: eb 1f jmp 8008d2 + + // (unsigned) hexadecimal + case 'x': + num = getuint(&ap, lflag); + 8008b3: 8b 45 e0 mov -0x20(%ebp),%eax + 8008b6: 89 44 24 04 mov %eax,0x4(%esp) + 8008ba: 8d 45 14 lea 0x14(%ebp),%eax + 8008bd: 89 04 24 mov %eax,(%esp) + 8008c0: e8 ea fb ff ff call 8004af + 8008c5: 89 45 f0 mov %eax,-0x10(%ebp) + 8008c8: 89 55 f4 mov %edx,-0xc(%ebp) + base = 16; + 8008cb: c7 45 ec 10 00 00 00 movl $0x10,-0x14(%ebp) + number: + printnum(putch, putdat, num, base, width, padc); + 8008d2: 0f be 55 db movsbl -0x25(%ebp),%edx + 8008d6: 8b 45 ec mov -0x14(%ebp),%eax + 8008d9: 89 54 24 18 mov %edx,0x18(%esp) + 8008dd: 8b 55 e8 mov -0x18(%ebp),%edx + 8008e0: 89 54 24 14 mov %edx,0x14(%esp) + 8008e4: 89 44 24 10 mov %eax,0x10(%esp) + 8008e8: 8b 45 f0 mov -0x10(%ebp),%eax + 8008eb: 8b 55 f4 mov -0xc(%ebp),%edx + 8008ee: 89 44 24 08 mov %eax,0x8(%esp) + 8008f2: 89 54 24 0c mov %edx,0xc(%esp) + 8008f6: 8b 45 0c mov 0xc(%ebp),%eax + 8008f9: 89 44 24 04 mov %eax,0x4(%esp) + 8008fd: 8b 45 08 mov 0x8(%ebp),%eax + 800900: 89 04 24 mov %eax,(%esp) + 800903: e8 a5 fa ff ff call 8003ad + break; + 800908: eb 38 jmp 800942 + + // escaped '%' character + case '%': + putch(ch, putdat); + 80090a: 8b 45 0c mov 0xc(%ebp),%eax + 80090d: 89 44 24 04 mov %eax,0x4(%esp) + 800911: 89 1c 24 mov %ebx,(%esp) + 800914: 8b 45 08 mov 0x8(%ebp),%eax + 800917: ff d0 call *%eax + break; + 800919: eb 27 jmp 800942 + + // unrecognized escape sequence - just print it literally + default: + putch('%', putdat); + 80091b: 8b 45 0c mov 0xc(%ebp),%eax + 80091e: 89 44 24 04 mov %eax,0x4(%esp) + 800922: c7 04 24 25 00 00 00 movl $0x25,(%esp) + 800929: 8b 45 08 mov 0x8(%ebp),%eax + 80092c: ff d0 call *%eax + for (fmt --; fmt[-1] != '%'; fmt --) + 80092e: ff 4d 10 decl 0x10(%ebp) + 800931: eb 03 jmp 800936 + 800933: ff 4d 10 decl 0x10(%ebp) + 800936: 8b 45 10 mov 0x10(%ebp),%eax + 800939: 48 dec %eax + 80093a: 0f b6 00 movzbl (%eax),%eax + 80093d: 3c 25 cmp $0x25,%al + 80093f: 75 f2 jne 800933 + /* do nothing */; + break; + 800941: 90 nop + while (1) { + 800942: e9 37 fc ff ff jmp 80057e + return; + 800947: 90 nop + } + } +} + 800948: 83 c4 40 add $0x40,%esp + 80094b: 5b pop %ebx + 80094c: 5e pop %esi + 80094d: 5d pop %ebp + 80094e: c3 ret + +0080094f : + * sprintputch - 'print' a single character in a buffer + * @ch: the character will be printed + * @b: the buffer to place the character @ch + * */ +static void +sprintputch(int ch, struct sprintbuf *b) { + 80094f: 55 push %ebp + 800950: 89 e5 mov %esp,%ebp + b->cnt ++; + 800952: 8b 45 0c mov 0xc(%ebp),%eax + 800955: 8b 40 08 mov 0x8(%eax),%eax + 800958: 8d 50 01 lea 0x1(%eax),%edx + 80095b: 8b 45 0c mov 0xc(%ebp),%eax + 80095e: 89 50 08 mov %edx,0x8(%eax) + if (b->buf < b->ebuf) { + 800961: 8b 45 0c mov 0xc(%ebp),%eax + 800964: 8b 10 mov (%eax),%edx + 800966: 8b 45 0c mov 0xc(%ebp),%eax + 800969: 8b 40 04 mov 0x4(%eax),%eax + 80096c: 39 c2 cmp %eax,%edx + 80096e: 73 12 jae 800982 + *b->buf ++ = ch; + 800970: 8b 45 0c mov 0xc(%ebp),%eax + 800973: 8b 00 mov (%eax),%eax + 800975: 8d 48 01 lea 0x1(%eax),%ecx + 800978: 8b 55 0c mov 0xc(%ebp),%edx + 80097b: 89 0a mov %ecx,(%edx) + 80097d: 8b 55 08 mov 0x8(%ebp),%edx + 800980: 88 10 mov %dl,(%eax) + } +} + 800982: 90 nop + 800983: 5d pop %ebp + 800984: c3 ret + +00800985 : + * @str: the buffer to place the result into + * @size: the size of buffer, including the trailing null space + * @fmt: the format string to use + * */ +int +snprintf(char *str, size_t size, const char *fmt, ...) { + 800985: 55 push %ebp + 800986: 89 e5 mov %esp,%ebp + 800988: 83 ec 28 sub $0x28,%esp + va_list ap; + int cnt; + va_start(ap, fmt); + 80098b: 8d 45 14 lea 0x14(%ebp),%eax + 80098e: 89 45 f0 mov %eax,-0x10(%ebp) + cnt = vsnprintf(str, size, fmt, ap); + 800991: 8b 45 f0 mov -0x10(%ebp),%eax + 800994: 89 44 24 0c mov %eax,0xc(%esp) + 800998: 8b 45 10 mov 0x10(%ebp),%eax + 80099b: 89 44 24 08 mov %eax,0x8(%esp) + 80099f: 8b 45 0c mov 0xc(%ebp),%eax + 8009a2: 89 44 24 04 mov %eax,0x4(%esp) + 8009a6: 8b 45 08 mov 0x8(%ebp),%eax + 8009a9: 89 04 24 mov %eax,(%esp) + 8009ac: e8 0a 00 00 00 call 8009bb + 8009b1: 89 45 f4 mov %eax,-0xc(%ebp) + va_end(ap); + return cnt; + 8009b4: 8b 45 f4 mov -0xc(%ebp),%eax +} + 8009b7: 89 ec mov %ebp,%esp + 8009b9: 5d pop %ebp + 8009ba: c3 ret + +008009bb : + * + * Call this function if you are already dealing with a va_list. + * Or you probably want snprintf() instead. + * */ +int +vsnprintf(char *str, size_t size, const char *fmt, va_list ap) { + 8009bb: 55 push %ebp + 8009bc: 89 e5 mov %esp,%ebp + 8009be: 83 ec 28 sub $0x28,%esp + struct sprintbuf b = {str, str + size - 1, 0}; + 8009c1: 8b 45 08 mov 0x8(%ebp),%eax + 8009c4: 89 45 ec mov %eax,-0x14(%ebp) + 8009c7: 8b 45 0c mov 0xc(%ebp),%eax + 8009ca: 8d 50 ff lea -0x1(%eax),%edx + 8009cd: 8b 45 08 mov 0x8(%ebp),%eax + 8009d0: 01 d0 add %edx,%eax + 8009d2: 89 45 f0 mov %eax,-0x10(%ebp) + 8009d5: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + if (str == NULL || b.buf > b.ebuf) { + 8009dc: 83 7d 08 00 cmpl $0x0,0x8(%ebp) + 8009e0: 74 0a je 8009ec + 8009e2: 8b 55 ec mov -0x14(%ebp),%edx + 8009e5: 8b 45 f0 mov -0x10(%ebp),%eax + 8009e8: 39 c2 cmp %eax,%edx + 8009ea: 76 07 jbe 8009f3 + return -E_INVAL; + 8009ec: b8 fd ff ff ff mov $0xfffffffd,%eax + 8009f1: eb 2a jmp 800a1d + } + // print the string to the buffer + vprintfmt((void*)sprintputch, &b, fmt, ap); + 8009f3: 8b 45 14 mov 0x14(%ebp),%eax + 8009f6: 89 44 24 0c mov %eax,0xc(%esp) + 8009fa: 8b 45 10 mov 0x10(%ebp),%eax + 8009fd: 89 44 24 08 mov %eax,0x8(%esp) + 800a01: 8d 45 ec lea -0x14(%ebp),%eax + 800a04: 89 44 24 04 mov %eax,0x4(%esp) + 800a08: c7 04 24 4f 09 80 00 movl $0x80094f,(%esp) + 800a0f: e8 62 fb ff ff call 800576 + // null terminate the buffer + *b.buf = '\0'; + 800a14: 8b 45 ec mov -0x14(%ebp),%eax + 800a17: c6 00 00 movb $0x0,(%eax) + return b.cnt; + 800a1a: 8b 45 f4 mov -0xc(%ebp),%eax +} + 800a1d: 89 ec mov %ebp,%esp + 800a1f: 5d pop %ebp + 800a20: c3 ret + +00800a21 : + * rand - returns a pseudo-random integer + * + * The rand() function return a value in the range [0, RAND_MAX]. + * */ +int +rand(void) { + 800a21: 55 push %ebp + 800a22: 89 e5 mov %esp,%ebp + 800a24: 57 push %edi + 800a25: 56 push %esi + 800a26: 53 push %ebx + 800a27: 83 ec 24 sub $0x24,%esp + next = (next * 0x5DEECE66DLL + 0xBLL) & ((1LL << 48) - 1); + 800a2a: a1 00 20 80 00 mov 0x802000,%eax + 800a2f: 8b 15 04 20 80 00 mov 0x802004,%edx + 800a35: 69 fa 6d e6 ec de imul $0xdeece66d,%edx,%edi + 800a3b: 6b f0 05 imul $0x5,%eax,%esi + 800a3e: 01 fe add %edi,%esi + 800a40: bf 6d e6 ec de mov $0xdeece66d,%edi + 800a45: f7 e7 mul %edi + 800a47: 01 d6 add %edx,%esi + 800a49: 89 f2 mov %esi,%edx + 800a4b: 83 c0 0b add $0xb,%eax + 800a4e: 83 d2 00 adc $0x0,%edx + 800a51: 89 c7 mov %eax,%edi + 800a53: 83 e7 ff and $0xffffffff,%edi + 800a56: 89 f9 mov %edi,%ecx + 800a58: 0f b7 da movzwl %dx,%ebx + 800a5b: 89 0d 00 20 80 00 mov %ecx,0x802000 + 800a61: 89 1d 04 20 80 00 mov %ebx,0x802004 + unsigned long long result = (next >> 12); + 800a67: a1 00 20 80 00 mov 0x802000,%eax + 800a6c: 8b 15 04 20 80 00 mov 0x802004,%edx + 800a72: 0f ac d0 0c shrd $0xc,%edx,%eax + 800a76: c1 ea 0c shr $0xc,%edx + 800a79: 89 45 e0 mov %eax,-0x20(%ebp) + 800a7c: 89 55 e4 mov %edx,-0x1c(%ebp) + return (int)do_div(result, RAND_MAX + 1); + 800a7f: c7 45 dc 00 00 00 80 movl $0x80000000,-0x24(%ebp) + 800a86: 8b 45 e0 mov -0x20(%ebp),%eax + 800a89: 8b 55 e4 mov -0x1c(%ebp),%edx + 800a8c: 89 45 d8 mov %eax,-0x28(%ebp) + 800a8f: 89 55 e8 mov %edx,-0x18(%ebp) + 800a92: 8b 45 e8 mov -0x18(%ebp),%eax + 800a95: 89 45 ec mov %eax,-0x14(%ebp) + 800a98: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 800a9c: 74 1c je 800aba + 800a9e: 8b 45 e8 mov -0x18(%ebp),%eax + 800aa1: ba 00 00 00 00 mov $0x0,%edx + 800aa6: f7 75 dc divl -0x24(%ebp) + 800aa9: 89 55 ec mov %edx,-0x14(%ebp) + 800aac: 8b 45 e8 mov -0x18(%ebp),%eax + 800aaf: ba 00 00 00 00 mov $0x0,%edx + 800ab4: f7 75 dc divl -0x24(%ebp) + 800ab7: 89 45 e8 mov %eax,-0x18(%ebp) + 800aba: 8b 45 d8 mov -0x28(%ebp),%eax + 800abd: 8b 55 ec mov -0x14(%ebp),%edx + 800ac0: f7 75 dc divl -0x24(%ebp) + 800ac3: 89 45 d8 mov %eax,-0x28(%ebp) + 800ac6: 89 55 d4 mov %edx,-0x2c(%ebp) + 800ac9: 8b 45 d8 mov -0x28(%ebp),%eax + 800acc: 8b 55 e8 mov -0x18(%ebp),%edx + 800acf: 89 45 e0 mov %eax,-0x20(%ebp) + 800ad2: 89 55 e4 mov %edx,-0x1c(%ebp) + 800ad5: 8b 45 d4 mov -0x2c(%ebp),%eax +} + 800ad8: 83 c4 24 add $0x24,%esp + 800adb: 5b pop %ebx + 800adc: 5e pop %esi + 800add: 5f pop %edi + 800ade: 5d pop %ebp + 800adf: c3 ret + +00800ae0 : +/* * + * srand - seed the random number generator with the given number + * @seed: the required seed number + * */ +void +srand(unsigned int seed) { + 800ae0: 55 push %ebp + 800ae1: 89 e5 mov %esp,%ebp + next = seed; + 800ae3: 8b 45 08 mov 0x8(%ebp),%eax + 800ae6: ba 00 00 00 00 mov $0x0,%edx + 800aeb: a3 00 20 80 00 mov %eax,0x802000 + 800af0: 89 15 04 20 80 00 mov %edx,0x802004 +} + 800af6: 90 nop + 800af7: 5d pop %ebp + 800af8: c3 ret + +00800af9 : + * @s: the input string + * + * The strlen() function returns the length of string @s. + * */ +size_t +strlen(const char *s) { + 800af9: 55 push %ebp + 800afa: 89 e5 mov %esp,%ebp + 800afc: 83 ec 10 sub $0x10,%esp + size_t cnt = 0; + 800aff: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + while (*s ++ != '\0') { + 800b06: eb 03 jmp 800b0b + cnt ++; + 800b08: ff 45 fc incl -0x4(%ebp) + while (*s ++ != '\0') { + 800b0b: 8b 45 08 mov 0x8(%ebp),%eax + 800b0e: 8d 50 01 lea 0x1(%eax),%edx + 800b11: 89 55 08 mov %edx,0x8(%ebp) + 800b14: 0f b6 00 movzbl (%eax),%eax + 800b17: 84 c0 test %al,%al + 800b19: 75 ed jne 800b08 + } + return cnt; + 800b1b: 8b 45 fc mov -0x4(%ebp),%eax +} + 800b1e: 89 ec mov %ebp,%esp + 800b20: 5d pop %ebp + 800b21: c3 ret + +00800b22 : + * The return value is strlen(s), if that is less than @len, or + * @len if there is no '\0' character among the first @len characters + * pointed by @s. + * */ +size_t +strnlen(const char *s, size_t len) { + 800b22: 55 push %ebp + 800b23: 89 e5 mov %esp,%ebp + 800b25: 83 ec 10 sub $0x10,%esp + size_t cnt = 0; + 800b28: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + while (cnt < len && *s ++ != '\0') { + 800b2f: eb 03 jmp 800b34 + cnt ++; + 800b31: ff 45 fc incl -0x4(%ebp) + while (cnt < len && *s ++ != '\0') { + 800b34: 8b 45 fc mov -0x4(%ebp),%eax + 800b37: 3b 45 0c cmp 0xc(%ebp),%eax + 800b3a: 73 10 jae 800b4c + 800b3c: 8b 45 08 mov 0x8(%ebp),%eax + 800b3f: 8d 50 01 lea 0x1(%eax),%edx + 800b42: 89 55 08 mov %edx,0x8(%ebp) + 800b45: 0f b6 00 movzbl (%eax),%eax + 800b48: 84 c0 test %al,%al + 800b4a: 75 e5 jne 800b31 + } + return cnt; + 800b4c: 8b 45 fc mov -0x4(%ebp),%eax +} + 800b4f: 89 ec mov %ebp,%esp + 800b51: 5d pop %ebp + 800b52: c3 ret + +00800b53 : + * To avoid overflows, the size of array pointed by @dst should be long enough to + * contain the same string as @src (including the terminating null character), and + * should not overlap in memory with @src. + * */ +char * +strcpy(char *dst, const char *src) { + 800b53: 55 push %ebp + 800b54: 89 e5 mov %esp,%ebp + 800b56: 57 push %edi + 800b57: 56 push %esi + 800b58: 83 ec 20 sub $0x20,%esp + 800b5b: 8b 45 08 mov 0x8(%ebp),%eax + 800b5e: 89 45 f4 mov %eax,-0xc(%ebp) + 800b61: 8b 45 0c mov 0xc(%ebp),%eax + 800b64: 89 45 f0 mov %eax,-0x10(%ebp) +#ifndef __HAVE_ARCH_STRCPY +#define __HAVE_ARCH_STRCPY +static inline char * +__strcpy(char *dst, const char *src) { + int d0, d1, d2; + asm volatile ( + 800b67: 8b 55 f0 mov -0x10(%ebp),%edx + 800b6a: 8b 45 f4 mov -0xc(%ebp),%eax + 800b6d: 89 d1 mov %edx,%ecx + 800b6f: 89 c2 mov %eax,%edx + 800b71: 89 ce mov %ecx,%esi + 800b73: 89 d7 mov %edx,%edi + 800b75: ac lods %ds:(%esi),%al + 800b76: aa stos %al,%es:(%edi) + 800b77: 84 c0 test %al,%al + 800b79: 75 fa jne 800b75 + 800b7b: 89 fa mov %edi,%edx + 800b7d: 89 f1 mov %esi,%ecx + 800b7f: 89 4d ec mov %ecx,-0x14(%ebp) + 800b82: 89 55 e8 mov %edx,-0x18(%ebp) + 800b85: 89 45 e4 mov %eax,-0x1c(%ebp) + "stosb;" + "testb %%al, %%al;" + "jne 1b;" + : "=&S" (d0), "=&D" (d1), "=&a" (d2) + : "0" (src), "1" (dst) : "memory"); + return dst; + 800b88: 8b 45 f4 mov -0xc(%ebp),%eax + char *p = dst; + while ((*p ++ = *src ++) != '\0') + /* nothing */; + return dst; +#endif /* __HAVE_ARCH_STRCPY */ +} + 800b8b: 83 c4 20 add $0x20,%esp + 800b8e: 5e pop %esi + 800b8f: 5f pop %edi + 800b90: 5d pop %ebp + 800b91: c3 ret + +00800b92 : + * @len: maximum number of characters to be copied from @src + * + * The return value is @dst + * */ +char * +strncpy(char *dst, const char *src, size_t len) { + 800b92: 55 push %ebp + 800b93: 89 e5 mov %esp,%ebp + 800b95: 83 ec 10 sub $0x10,%esp + char *p = dst; + 800b98: 8b 45 08 mov 0x8(%ebp),%eax + 800b9b: 89 45 fc mov %eax,-0x4(%ebp) + while (len > 0) { + 800b9e: eb 1e jmp 800bbe + if ((*p = *src) != '\0') { + 800ba0: 8b 45 0c mov 0xc(%ebp),%eax + 800ba3: 0f b6 10 movzbl (%eax),%edx + 800ba6: 8b 45 fc mov -0x4(%ebp),%eax + 800ba9: 88 10 mov %dl,(%eax) + 800bab: 8b 45 fc mov -0x4(%ebp),%eax + 800bae: 0f b6 00 movzbl (%eax),%eax + 800bb1: 84 c0 test %al,%al + 800bb3: 74 03 je 800bb8 + src ++; + 800bb5: ff 45 0c incl 0xc(%ebp) + } + p ++, len --; + 800bb8: ff 45 fc incl -0x4(%ebp) + 800bbb: ff 4d 10 decl 0x10(%ebp) + while (len > 0) { + 800bbe: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800bc2: 75 dc jne 800ba0 + } + return dst; + 800bc4: 8b 45 08 mov 0x8(%ebp),%eax +} + 800bc7: 89 ec mov %ebp,%esp + 800bc9: 5d pop %ebp + 800bca: c3 ret + +00800bcb : + * - A value greater than zero indicates that the first character that does + * not match has a greater value in @s1 than in @s2; + * - And a value less than zero indicates the opposite. + * */ +int +strcmp(const char *s1, const char *s2) { + 800bcb: 55 push %ebp + 800bcc: 89 e5 mov %esp,%ebp + 800bce: 57 push %edi + 800bcf: 56 push %esi + 800bd0: 83 ec 20 sub $0x20,%esp + 800bd3: 8b 45 08 mov 0x8(%ebp),%eax + 800bd6: 89 45 f4 mov %eax,-0xc(%ebp) + 800bd9: 8b 45 0c mov 0xc(%ebp),%eax + 800bdc: 89 45 f0 mov %eax,-0x10(%ebp) + asm volatile ( + 800bdf: 8b 55 f4 mov -0xc(%ebp),%edx + 800be2: 8b 45 f0 mov -0x10(%ebp),%eax + 800be5: 89 d1 mov %edx,%ecx + 800be7: 89 c2 mov %eax,%edx + 800be9: 89 ce mov %ecx,%esi + 800beb: 89 d7 mov %edx,%edi + 800bed: ac lods %ds:(%esi),%al + 800bee: ae scas %es:(%edi),%al + 800bef: 75 08 jne 800bf9 + 800bf1: 84 c0 test %al,%al + 800bf3: 75 f8 jne 800bed + 800bf5: 31 c0 xor %eax,%eax + 800bf7: eb 04 jmp 800bfd + 800bf9: 19 c0 sbb %eax,%eax + 800bfb: 0c 01 or $0x1,%al + 800bfd: 89 fa mov %edi,%edx + 800bff: 89 f1 mov %esi,%ecx + 800c01: 89 45 ec mov %eax,-0x14(%ebp) + 800c04: 89 4d e8 mov %ecx,-0x18(%ebp) + 800c07: 89 55 e4 mov %edx,-0x1c(%ebp) + return ret; + 800c0a: 8b 45 ec mov -0x14(%ebp),%eax + while (*s1 != '\0' && *s1 == *s2) { + s1 ++, s2 ++; + } + return (int)((unsigned char)*s1 - (unsigned char)*s2); +#endif /* __HAVE_ARCH_STRCMP */ +} + 800c0d: 83 c4 20 add $0x20,%esp + 800c10: 5e pop %esi + 800c11: 5f pop %edi + 800c12: 5d pop %ebp + 800c13: c3 ret + +00800c14 : + * they are equal to each other, it continues with the following pairs until + * the characters differ, until a terminating null-character is reached, or + * until @n characters match in both strings, whichever happens first. + * */ +int +strncmp(const char *s1, const char *s2, size_t n) { + 800c14: 55 push %ebp + 800c15: 89 e5 mov %esp,%ebp + while (n > 0 && *s1 != '\0' && *s1 == *s2) { + 800c17: eb 09 jmp 800c22 + n --, s1 ++, s2 ++; + 800c19: ff 4d 10 decl 0x10(%ebp) + 800c1c: ff 45 08 incl 0x8(%ebp) + 800c1f: ff 45 0c incl 0xc(%ebp) + while (n > 0 && *s1 != '\0' && *s1 == *s2) { + 800c22: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800c26: 74 1a je 800c42 + 800c28: 8b 45 08 mov 0x8(%ebp),%eax + 800c2b: 0f b6 00 movzbl (%eax),%eax + 800c2e: 84 c0 test %al,%al + 800c30: 74 10 je 800c42 + 800c32: 8b 45 08 mov 0x8(%ebp),%eax + 800c35: 0f b6 10 movzbl (%eax),%edx + 800c38: 8b 45 0c mov 0xc(%ebp),%eax + 800c3b: 0f b6 00 movzbl (%eax),%eax + 800c3e: 38 c2 cmp %al,%dl + 800c40: 74 d7 je 800c19 + } + return (n == 0) ? 0 : (int)((unsigned char)*s1 - (unsigned char)*s2); + 800c42: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800c46: 74 18 je 800c60 + 800c48: 8b 45 08 mov 0x8(%ebp),%eax + 800c4b: 0f b6 00 movzbl (%eax),%eax + 800c4e: 0f b6 d0 movzbl %al,%edx + 800c51: 8b 45 0c mov 0xc(%ebp),%eax + 800c54: 0f b6 00 movzbl (%eax),%eax + 800c57: 0f b6 c8 movzbl %al,%ecx + 800c5a: 89 d0 mov %edx,%eax + 800c5c: 29 c8 sub %ecx,%eax + 800c5e: eb 05 jmp 800c65 + 800c60: b8 00 00 00 00 mov $0x0,%eax +} + 800c65: 5d pop %ebp + 800c66: c3 ret + +00800c67 : + * + * The strchr() function returns a pointer to the first occurrence of + * character in @s. If the value is not found, the function returns 'NULL'. + * */ +char * +strchr(const char *s, char c) { + 800c67: 55 push %ebp + 800c68: 89 e5 mov %esp,%ebp + 800c6a: 83 ec 04 sub $0x4,%esp + 800c6d: 8b 45 0c mov 0xc(%ebp),%eax + 800c70: 88 45 fc mov %al,-0x4(%ebp) + while (*s != '\0') { + 800c73: eb 13 jmp 800c88 + if (*s == c) { + 800c75: 8b 45 08 mov 0x8(%ebp),%eax + 800c78: 0f b6 00 movzbl (%eax),%eax + 800c7b: 38 45 fc cmp %al,-0x4(%ebp) + 800c7e: 75 05 jne 800c85 + return (char *)s; + 800c80: 8b 45 08 mov 0x8(%ebp),%eax + 800c83: eb 12 jmp 800c97 + } + s ++; + 800c85: ff 45 08 incl 0x8(%ebp) + while (*s != '\0') { + 800c88: 8b 45 08 mov 0x8(%ebp),%eax + 800c8b: 0f b6 00 movzbl (%eax),%eax + 800c8e: 84 c0 test %al,%al + 800c90: 75 e3 jne 800c75 + } + return NULL; + 800c92: b8 00 00 00 00 mov $0x0,%eax +} + 800c97: 89 ec mov %ebp,%esp + 800c99: 5d pop %ebp + 800c9a: c3 ret + +00800c9b : + * The strfind() function is like strchr() except that if @c is + * not found in @s, then it returns a pointer to the null byte at the + * end of @s, rather than 'NULL'. + * */ +char * +strfind(const char *s, char c) { + 800c9b: 55 push %ebp + 800c9c: 89 e5 mov %esp,%ebp + 800c9e: 83 ec 04 sub $0x4,%esp + 800ca1: 8b 45 0c mov 0xc(%ebp),%eax + 800ca4: 88 45 fc mov %al,-0x4(%ebp) + while (*s != '\0') { + 800ca7: eb 0e jmp 800cb7 + if (*s == c) { + 800ca9: 8b 45 08 mov 0x8(%ebp),%eax + 800cac: 0f b6 00 movzbl (%eax),%eax + 800caf: 38 45 fc cmp %al,-0x4(%ebp) + 800cb2: 74 0f je 800cc3 + break; + } + s ++; + 800cb4: ff 45 08 incl 0x8(%ebp) + while (*s != '\0') { + 800cb7: 8b 45 08 mov 0x8(%ebp),%eax + 800cba: 0f b6 00 movzbl (%eax),%eax + 800cbd: 84 c0 test %al,%al + 800cbf: 75 e8 jne 800ca9 + 800cc1: eb 01 jmp 800cc4 + break; + 800cc3: 90 nop + } + return (char *)s; + 800cc4: 8b 45 08 mov 0x8(%ebp),%eax +} + 800cc7: 89 ec mov %ebp,%esp + 800cc9: 5d pop %ebp + 800cca: c3 ret + +00800ccb : + * an optional "0x" or "0X" prefix. + * + * The strtol() function returns the converted integral number as a long int value. + * */ +long +strtol(const char *s, char **endptr, int base) { + 800ccb: 55 push %ebp + 800ccc: 89 e5 mov %esp,%ebp + 800cce: 83 ec 10 sub $0x10,%esp + int neg = 0; + 800cd1: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + long val = 0; + 800cd8: c7 45 f8 00 00 00 00 movl $0x0,-0x8(%ebp) + + // gobble initial whitespace + while (*s == ' ' || *s == '\t') { + 800cdf: eb 03 jmp 800ce4 + s ++; + 800ce1: ff 45 08 incl 0x8(%ebp) + while (*s == ' ' || *s == '\t') { + 800ce4: 8b 45 08 mov 0x8(%ebp),%eax + 800ce7: 0f b6 00 movzbl (%eax),%eax + 800cea: 3c 20 cmp $0x20,%al + 800cec: 74 f3 je 800ce1 + 800cee: 8b 45 08 mov 0x8(%ebp),%eax + 800cf1: 0f b6 00 movzbl (%eax),%eax + 800cf4: 3c 09 cmp $0x9,%al + 800cf6: 74 e9 je 800ce1 + } + + // plus/minus sign + if (*s == '+') { + 800cf8: 8b 45 08 mov 0x8(%ebp),%eax + 800cfb: 0f b6 00 movzbl (%eax),%eax + 800cfe: 3c 2b cmp $0x2b,%al + 800d00: 75 05 jne 800d07 + s ++; + 800d02: ff 45 08 incl 0x8(%ebp) + 800d05: eb 14 jmp 800d1b + } + else if (*s == '-') { + 800d07: 8b 45 08 mov 0x8(%ebp),%eax + 800d0a: 0f b6 00 movzbl (%eax),%eax + 800d0d: 3c 2d cmp $0x2d,%al + 800d0f: 75 0a jne 800d1b + s ++, neg = 1; + 800d11: ff 45 08 incl 0x8(%ebp) + 800d14: c7 45 fc 01 00 00 00 movl $0x1,-0x4(%ebp) + } + + // hex or octal base prefix + if ((base == 0 || base == 16) && (s[0] == '0' && s[1] == 'x')) { + 800d1b: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800d1f: 74 06 je 800d27 + 800d21: 83 7d 10 10 cmpl $0x10,0x10(%ebp) + 800d25: 75 22 jne 800d49 + 800d27: 8b 45 08 mov 0x8(%ebp),%eax + 800d2a: 0f b6 00 movzbl (%eax),%eax + 800d2d: 3c 30 cmp $0x30,%al + 800d2f: 75 18 jne 800d49 + 800d31: 8b 45 08 mov 0x8(%ebp),%eax + 800d34: 40 inc %eax + 800d35: 0f b6 00 movzbl (%eax),%eax + 800d38: 3c 78 cmp $0x78,%al + 800d3a: 75 0d jne 800d49 + s += 2, base = 16; + 800d3c: 83 45 08 02 addl $0x2,0x8(%ebp) + 800d40: c7 45 10 10 00 00 00 movl $0x10,0x10(%ebp) + 800d47: eb 29 jmp 800d72 + } + else if (base == 0 && s[0] == '0') { + 800d49: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800d4d: 75 16 jne 800d65 + 800d4f: 8b 45 08 mov 0x8(%ebp),%eax + 800d52: 0f b6 00 movzbl (%eax),%eax + 800d55: 3c 30 cmp $0x30,%al + 800d57: 75 0c jne 800d65 + s ++, base = 8; + 800d59: ff 45 08 incl 0x8(%ebp) + 800d5c: c7 45 10 08 00 00 00 movl $0x8,0x10(%ebp) + 800d63: eb 0d jmp 800d72 + } + else if (base == 0) { + 800d65: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800d69: 75 07 jne 800d72 + base = 10; + 800d6b: c7 45 10 0a 00 00 00 movl $0xa,0x10(%ebp) + + // digits + while (1) { + int dig; + + if (*s >= '0' && *s <= '9') { + 800d72: 8b 45 08 mov 0x8(%ebp),%eax + 800d75: 0f b6 00 movzbl (%eax),%eax + 800d78: 3c 2f cmp $0x2f,%al + 800d7a: 7e 1b jle 800d97 + 800d7c: 8b 45 08 mov 0x8(%ebp),%eax + 800d7f: 0f b6 00 movzbl (%eax),%eax + 800d82: 3c 39 cmp $0x39,%al + 800d84: 7f 11 jg 800d97 + dig = *s - '0'; + 800d86: 8b 45 08 mov 0x8(%ebp),%eax + 800d89: 0f b6 00 movzbl (%eax),%eax + 800d8c: 0f be c0 movsbl %al,%eax + 800d8f: 83 e8 30 sub $0x30,%eax + 800d92: 89 45 f4 mov %eax,-0xc(%ebp) + 800d95: eb 48 jmp 800ddf + } + else if (*s >= 'a' && *s <= 'z') { + 800d97: 8b 45 08 mov 0x8(%ebp),%eax + 800d9a: 0f b6 00 movzbl (%eax),%eax + 800d9d: 3c 60 cmp $0x60,%al + 800d9f: 7e 1b jle 800dbc + 800da1: 8b 45 08 mov 0x8(%ebp),%eax + 800da4: 0f b6 00 movzbl (%eax),%eax + 800da7: 3c 7a cmp $0x7a,%al + 800da9: 7f 11 jg 800dbc + dig = *s - 'a' + 10; + 800dab: 8b 45 08 mov 0x8(%ebp),%eax + 800dae: 0f b6 00 movzbl (%eax),%eax + 800db1: 0f be c0 movsbl %al,%eax + 800db4: 83 e8 57 sub $0x57,%eax + 800db7: 89 45 f4 mov %eax,-0xc(%ebp) + 800dba: eb 23 jmp 800ddf + } + else if (*s >= 'A' && *s <= 'Z') { + 800dbc: 8b 45 08 mov 0x8(%ebp),%eax + 800dbf: 0f b6 00 movzbl (%eax),%eax + 800dc2: 3c 40 cmp $0x40,%al + 800dc4: 7e 3b jle 800e01 + 800dc6: 8b 45 08 mov 0x8(%ebp),%eax + 800dc9: 0f b6 00 movzbl (%eax),%eax + 800dcc: 3c 5a cmp $0x5a,%al + 800dce: 7f 31 jg 800e01 + dig = *s - 'A' + 10; + 800dd0: 8b 45 08 mov 0x8(%ebp),%eax + 800dd3: 0f b6 00 movzbl (%eax),%eax + 800dd6: 0f be c0 movsbl %al,%eax + 800dd9: 83 e8 37 sub $0x37,%eax + 800ddc: 89 45 f4 mov %eax,-0xc(%ebp) + } + else { + break; + } + if (dig >= base) { + 800ddf: 8b 45 f4 mov -0xc(%ebp),%eax + 800de2: 3b 45 10 cmp 0x10(%ebp),%eax + 800de5: 7d 19 jge 800e00 + break; + } + s ++, val = (val * base) + dig; + 800de7: ff 45 08 incl 0x8(%ebp) + 800dea: 8b 45 f8 mov -0x8(%ebp),%eax + 800ded: 0f af 45 10 imul 0x10(%ebp),%eax + 800df1: 89 c2 mov %eax,%edx + 800df3: 8b 45 f4 mov -0xc(%ebp),%eax + 800df6: 01 d0 add %edx,%eax + 800df8: 89 45 f8 mov %eax,-0x8(%ebp) + while (1) { + 800dfb: e9 72 ff ff ff jmp 800d72 + break; + 800e00: 90 nop + // we don't properly detect overflow! + } + + if (endptr) { + 800e01: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) + 800e05: 74 08 je 800e0f + *endptr = (char *) s; + 800e07: 8b 45 0c mov 0xc(%ebp),%eax + 800e0a: 8b 55 08 mov 0x8(%ebp),%edx + 800e0d: 89 10 mov %edx,(%eax) + } + return (neg ? -val : val); + 800e0f: 83 7d fc 00 cmpl $0x0,-0x4(%ebp) + 800e13: 74 07 je 800e1c + 800e15: 8b 45 f8 mov -0x8(%ebp),%eax + 800e18: f7 d8 neg %eax + 800e1a: eb 03 jmp 800e1f + 800e1c: 8b 45 f8 mov -0x8(%ebp),%eax +} + 800e1f: 89 ec mov %ebp,%esp + 800e21: 5d pop %ebp + 800e22: c3 ret + +00800e23 : + * @n: number of bytes to be set to the value + * + * The memset() function returns @s. + * */ +void * +memset(void *s, char c, size_t n) { + 800e23: 55 push %ebp + 800e24: 89 e5 mov %esp,%ebp + 800e26: 83 ec 28 sub $0x28,%esp + 800e29: 89 7d fc mov %edi,-0x4(%ebp) + 800e2c: 8b 45 0c mov 0xc(%ebp),%eax + 800e2f: 88 45 d8 mov %al,-0x28(%ebp) +#ifdef __HAVE_ARCH_MEMSET + return __memset(s, c, n); + 800e32: 0f be 55 d8 movsbl -0x28(%ebp),%edx + 800e36: 8b 45 08 mov 0x8(%ebp),%eax + 800e39: 89 45 f8 mov %eax,-0x8(%ebp) + 800e3c: 88 55 f7 mov %dl,-0x9(%ebp) + 800e3f: 8b 45 10 mov 0x10(%ebp),%eax + 800e42: 89 45 f0 mov %eax,-0x10(%ebp) +#ifndef __HAVE_ARCH_MEMSET +#define __HAVE_ARCH_MEMSET +static inline void * +__memset(void *s, char c, size_t n) { + int d0, d1; + asm volatile ( + 800e45: 8b 4d f0 mov -0x10(%ebp),%ecx + 800e48: 0f b6 45 f7 movzbl -0x9(%ebp),%eax + 800e4c: 8b 55 f8 mov -0x8(%ebp),%edx + 800e4f: 89 d7 mov %edx,%edi + 800e51: f3 aa rep stos %al,%es:(%edi) + 800e53: 89 fa mov %edi,%edx + 800e55: 89 4d ec mov %ecx,-0x14(%ebp) + 800e58: 89 55 e8 mov %edx,-0x18(%ebp) + "rep; stosb;" + : "=&c" (d0), "=&D" (d1) + : "0" (n), "a" (c), "1" (s) + : "memory"); + return s; + 800e5b: 8b 45 f8 mov -0x8(%ebp),%eax + while (n -- > 0) { + *p ++ = c; + } + return s; +#endif /* __HAVE_ARCH_MEMSET */ +} + 800e5e: 8b 7d fc mov -0x4(%ebp),%edi + 800e61: 89 ec mov %ebp,%esp + 800e63: 5d pop %ebp + 800e64: c3 ret + +00800e65 : + * @n: number of bytes to copy + * + * The memmove() function returns @dst. + * */ +void * +memmove(void *dst, const void *src, size_t n) { + 800e65: 55 push %ebp + 800e66: 89 e5 mov %esp,%ebp + 800e68: 57 push %edi + 800e69: 56 push %esi + 800e6a: 53 push %ebx + 800e6b: 83 ec 30 sub $0x30,%esp + 800e6e: 8b 45 08 mov 0x8(%ebp),%eax + 800e71: 89 45 f0 mov %eax,-0x10(%ebp) + 800e74: 8b 45 0c mov 0xc(%ebp),%eax + 800e77: 89 45 ec mov %eax,-0x14(%ebp) + 800e7a: 8b 45 10 mov 0x10(%ebp),%eax + 800e7d: 89 45 e8 mov %eax,-0x18(%ebp) + +#ifndef __HAVE_ARCH_MEMMOVE +#define __HAVE_ARCH_MEMMOVE +static inline void * +__memmove(void *dst, const void *src, size_t n) { + if (dst < src) { + 800e80: 8b 45 f0 mov -0x10(%ebp),%eax + 800e83: 3b 45 ec cmp -0x14(%ebp),%eax + 800e86: 73 42 jae 800eca + 800e88: 8b 45 f0 mov -0x10(%ebp),%eax + 800e8b: 89 45 e4 mov %eax,-0x1c(%ebp) + 800e8e: 8b 45 ec mov -0x14(%ebp),%eax + 800e91: 89 45 e0 mov %eax,-0x20(%ebp) + 800e94: 8b 45 e8 mov -0x18(%ebp),%eax + 800e97: 89 45 dc mov %eax,-0x24(%ebp) + "andl $3, %%ecx;" + "jz 1f;" + "rep; movsb;" + "1:" + : "=&c" (d0), "=&D" (d1), "=&S" (d2) + : "0" (n / 4), "g" (n), "1" (dst), "2" (src) + 800e9a: 8b 45 dc mov -0x24(%ebp),%eax + 800e9d: c1 e8 02 shr $0x2,%eax + 800ea0: 89 c1 mov %eax,%ecx + asm volatile ( + 800ea2: 8b 55 e4 mov -0x1c(%ebp),%edx + 800ea5: 8b 45 e0 mov -0x20(%ebp),%eax + 800ea8: 89 d7 mov %edx,%edi + 800eaa: 89 c6 mov %eax,%esi + 800eac: f3 a5 rep movsl %ds:(%esi),%es:(%edi) + 800eae: 8b 4d dc mov -0x24(%ebp),%ecx + 800eb1: 83 e1 03 and $0x3,%ecx + 800eb4: 74 02 je 800eb8 + 800eb6: f3 a4 rep movsb %ds:(%esi),%es:(%edi) + 800eb8: 89 f0 mov %esi,%eax + 800eba: 89 fa mov %edi,%edx + 800ebc: 89 4d d8 mov %ecx,-0x28(%ebp) + 800ebf: 89 55 d4 mov %edx,-0x2c(%ebp) + 800ec2: 89 45 d0 mov %eax,-0x30(%ebp) + : "memory"); + return dst; + 800ec5: 8b 45 e4 mov -0x1c(%ebp),%eax + return __memcpy(dst, src, n); + 800ec8: eb 36 jmp 800f00 + : "0" (n), "1" (n - 1 + src), "2" (n - 1 + dst) + 800eca: 8b 45 e8 mov -0x18(%ebp),%eax + 800ecd: 8d 50 ff lea -0x1(%eax),%edx + 800ed0: 8b 45 ec mov -0x14(%ebp),%eax + 800ed3: 01 c2 add %eax,%edx + 800ed5: 8b 45 e8 mov -0x18(%ebp),%eax + 800ed8: 8d 48 ff lea -0x1(%eax),%ecx + 800edb: 8b 45 f0 mov -0x10(%ebp),%eax + 800ede: 8d 1c 01 lea (%ecx,%eax,1),%ebx + asm volatile ( + 800ee1: 8b 45 e8 mov -0x18(%ebp),%eax + 800ee4: 89 c1 mov %eax,%ecx + 800ee6: 89 d8 mov %ebx,%eax + 800ee8: 89 d6 mov %edx,%esi + 800eea: 89 c7 mov %eax,%edi + 800eec: fd std + 800eed: f3 a4 rep movsb %ds:(%esi),%es:(%edi) + 800eef: fc cld + 800ef0: 89 f8 mov %edi,%eax + 800ef2: 89 f2 mov %esi,%edx + 800ef4: 89 4d cc mov %ecx,-0x34(%ebp) + 800ef7: 89 55 c8 mov %edx,-0x38(%ebp) + 800efa: 89 45 c4 mov %eax,-0x3c(%ebp) + return dst; + 800efd: 8b 45 f0 mov -0x10(%ebp),%eax + *d ++ = *s ++; + } + } + return dst; +#endif /* __HAVE_ARCH_MEMMOVE */ +} + 800f00: 83 c4 30 add $0x30,%esp + 800f03: 5b pop %ebx + 800f04: 5e pop %esi + 800f05: 5f pop %edi + 800f06: 5d pop %ebp + 800f07: c3 ret + +00800f08 : + * it always copies exactly @n bytes. To avoid overflows, the size of arrays pointed + * by both @src and @dst, should be at least @n bytes, and should not overlap + * (for overlapping memory area, memmove is a safer approach). + * */ +void * +memcpy(void *dst, const void *src, size_t n) { + 800f08: 55 push %ebp + 800f09: 89 e5 mov %esp,%ebp + 800f0b: 57 push %edi + 800f0c: 56 push %esi + 800f0d: 83 ec 20 sub $0x20,%esp + 800f10: 8b 45 08 mov 0x8(%ebp),%eax + 800f13: 89 45 f4 mov %eax,-0xc(%ebp) + 800f16: 8b 45 0c mov 0xc(%ebp),%eax + 800f19: 89 45 f0 mov %eax,-0x10(%ebp) + 800f1c: 8b 45 10 mov 0x10(%ebp),%eax + 800f1f: 89 45 ec mov %eax,-0x14(%ebp) + : "0" (n / 4), "g" (n), "1" (dst), "2" (src) + 800f22: 8b 45 ec mov -0x14(%ebp),%eax + 800f25: c1 e8 02 shr $0x2,%eax + 800f28: 89 c1 mov %eax,%ecx + asm volatile ( + 800f2a: 8b 55 f4 mov -0xc(%ebp),%edx + 800f2d: 8b 45 f0 mov -0x10(%ebp),%eax + 800f30: 89 d7 mov %edx,%edi + 800f32: 89 c6 mov %eax,%esi + 800f34: f3 a5 rep movsl %ds:(%esi),%es:(%edi) + 800f36: 8b 4d ec mov -0x14(%ebp),%ecx + 800f39: 83 e1 03 and $0x3,%ecx + 800f3c: 74 02 je 800f40 + 800f3e: f3 a4 rep movsb %ds:(%esi),%es:(%edi) + 800f40: 89 f0 mov %esi,%eax + 800f42: 89 fa mov %edi,%edx + 800f44: 89 4d e8 mov %ecx,-0x18(%ebp) + 800f47: 89 55 e4 mov %edx,-0x1c(%ebp) + 800f4a: 89 45 e0 mov %eax,-0x20(%ebp) + return dst; + 800f4d: 8b 45 f4 mov -0xc(%ebp),%eax + while (n -- > 0) { + *d ++ = *s ++; + } + return dst; +#endif /* __HAVE_ARCH_MEMCPY */ +} + 800f50: 83 c4 20 add $0x20,%esp + 800f53: 5e pop %esi + 800f54: 5f pop %edi + 800f55: 5d pop %ebp + 800f56: c3 ret + +00800f57 : + * match in both memory blocks has a greater value in @v1 than in @v2 + * as if evaluated as unsigned char values; + * - And a value less than zero indicates the opposite. + * */ +int +memcmp(const void *v1, const void *v2, size_t n) { + 800f57: 55 push %ebp + 800f58: 89 e5 mov %esp,%ebp + 800f5a: 83 ec 10 sub $0x10,%esp + const char *s1 = (const char *)v1; + 800f5d: 8b 45 08 mov 0x8(%ebp),%eax + 800f60: 89 45 fc mov %eax,-0x4(%ebp) + const char *s2 = (const char *)v2; + 800f63: 8b 45 0c mov 0xc(%ebp),%eax + 800f66: 89 45 f8 mov %eax,-0x8(%ebp) + while (n -- > 0) { + 800f69: eb 2e jmp 800f99 + if (*s1 != *s2) { + 800f6b: 8b 45 fc mov -0x4(%ebp),%eax + 800f6e: 0f b6 10 movzbl (%eax),%edx + 800f71: 8b 45 f8 mov -0x8(%ebp),%eax + 800f74: 0f b6 00 movzbl (%eax),%eax + 800f77: 38 c2 cmp %al,%dl + 800f79: 74 18 je 800f93 + return (int)((unsigned char)*s1 - (unsigned char)*s2); + 800f7b: 8b 45 fc mov -0x4(%ebp),%eax + 800f7e: 0f b6 00 movzbl (%eax),%eax + 800f81: 0f b6 d0 movzbl %al,%edx + 800f84: 8b 45 f8 mov -0x8(%ebp),%eax + 800f87: 0f b6 00 movzbl (%eax),%eax + 800f8a: 0f b6 c8 movzbl %al,%ecx + 800f8d: 89 d0 mov %edx,%eax + 800f8f: 29 c8 sub %ecx,%eax + 800f91: eb 18 jmp 800fab + } + s1 ++, s2 ++; + 800f93: ff 45 fc incl -0x4(%ebp) + 800f96: ff 45 f8 incl -0x8(%ebp) + while (n -- > 0) { + 800f99: 8b 45 10 mov 0x10(%ebp),%eax + 800f9c: 8d 50 ff lea -0x1(%eax),%edx + 800f9f: 89 55 10 mov %edx,0x10(%ebp) + 800fa2: 85 c0 test %eax,%eax + 800fa4: 75 c5 jne 800f6b + } + return 0; + 800fa6: b8 00 00 00 00 mov $0x0,%eax +} + 800fab: 89 ec mov %ebp,%esp + 800fad: 5d pop %ebp + 800fae: c3 ret + +00800faf
: +#include +#include + +int +main(void) { + 800faf: 55 push %ebp + 800fb0: 89 e5 mov %esp,%ebp + 800fb2: 83 e4 f0 and $0xfffffff0,%esp + 800fb5: 83 ec 20 sub $0x20,%esp + int pid, exit_code; + if ((pid = fork()) == 0) { + 800fb8: e8 23 f3 ff ff call 8002e0 + 800fbd: 89 44 24 18 mov %eax,0x18(%esp) + 800fc1: 83 7c 24 18 00 cmpl $0x0,0x18(%esp) + 800fc6: 75 32 jne 800ffa + cprintf("fork ok.\n"); + 800fc8: c7 04 24 e0 13 80 00 movl $0x8013e0,(%esp) + 800fcf: e8 4c f1 ff ff call 800120 + int i; + for (i = 0; i < 10; i ++) { + 800fd4: c7 44 24 1c 00 00 00 movl $0x0,0x1c(%esp) + 800fdb: 00 + 800fdc: eb 09 jmp 800fe7 + yield(); + 800fde: e8 46 f3 ff ff call 800329 + for (i = 0; i < 10; i ++) { + 800fe3: ff 44 24 1c incl 0x1c(%esp) + 800fe7: 83 7c 24 1c 09 cmpl $0x9,0x1c(%esp) + 800fec: 7e f0 jle 800fde + } + exit(0xbeaf); + 800fee: c7 04 24 af be 00 00 movl $0xbeaf,(%esp) + 800ff5: e8 c7 f2 ff ff call 8002c1 + } + assert(pid > 0); + 800ffa: 83 7c 24 18 00 cmpl $0x0,0x18(%esp) + 800fff: 7f 24 jg 801025 + 801001: c7 44 24 0c ea 13 80 movl $0x8013ea,0xc(%esp) + 801008: 00 + 801009: c7 44 24 08 f2 13 80 movl $0x8013f2,0x8(%esp) + 801010: 00 + 801011: c7 44 24 04 0f 00 00 movl $0xf,0x4(%esp) + 801018: 00 + 801019: c7 04 24 07 14 80 00 movl $0x801407,(%esp) + 801020: e8 0a f0 ff ff call 80002f <__panic> + assert(waitpid(-1, NULL) != 0); + 801025: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) + 80102c: 00 + 80102d: c7 04 24 ff ff ff ff movl $0xffffffff,(%esp) + 801034: e8 d4 f2 ff ff call 80030d + 801039: 85 c0 test %eax,%eax + 80103b: 75 24 jne 801061 + 80103d: c7 44 24 0c 15 14 80 movl $0x801415,0xc(%esp) + 801044: 00 + 801045: c7 44 24 08 f2 13 80 movl $0x8013f2,0x8(%esp) + 80104c: 00 + 80104d: c7 44 24 04 10 00 00 movl $0x10,0x4(%esp) + 801054: 00 + 801055: c7 04 24 07 14 80 00 movl $0x801407,(%esp) + 80105c: e8 ce ef ff ff call 80002f <__panic> + assert(waitpid(pid, (void *)0xC0000000) != 0); + 801061: c7 44 24 04 00 00 00 movl $0xc0000000,0x4(%esp) + 801068: c0 + 801069: 8b 44 24 18 mov 0x18(%esp),%eax + 80106d: 89 04 24 mov %eax,(%esp) + 801070: e8 98 f2 ff ff call 80030d + 801075: 85 c0 test %eax,%eax + 801077: 75 24 jne 80109d + 801079: c7 44 24 0c 2c 14 80 movl $0x80142c,0xc(%esp) + 801080: 00 + 801081: c7 44 24 08 f2 13 80 movl $0x8013f2,0x8(%esp) + 801088: 00 + 801089: c7 44 24 04 11 00 00 movl $0x11,0x4(%esp) + 801090: 00 + 801091: c7 04 24 07 14 80 00 movl $0x801407,(%esp) + 801098: e8 92 ef ff ff call 80002f <__panic> + assert(waitpid(pid, &exit_code) == 0 && exit_code == 0xbeaf); + 80109d: 8d 44 24 14 lea 0x14(%esp),%eax + 8010a1: 89 44 24 04 mov %eax,0x4(%esp) + 8010a5: 8b 44 24 18 mov 0x18(%esp),%eax + 8010a9: 89 04 24 mov %eax,(%esp) + 8010ac: e8 5c f2 ff ff call 80030d + 8010b1: 85 c0 test %eax,%eax + 8010b3: 75 0b jne 8010c0 + 8010b5: 8b 44 24 14 mov 0x14(%esp),%eax + 8010b9: 3d af be 00 00 cmp $0xbeaf,%eax + 8010be: 74 24 je 8010e4 + 8010c0: c7 44 24 0c 54 14 80 movl $0x801454,0xc(%esp) + 8010c7: 00 + 8010c8: c7 44 24 08 f2 13 80 movl $0x8013f2,0x8(%esp) + 8010cf: 00 + 8010d0: c7 44 24 04 12 00 00 movl $0x12,0x4(%esp) + 8010d7: 00 + 8010d8: c7 04 24 07 14 80 00 movl $0x801407,(%esp) + 8010df: e8 4b ef ff ff call 80002f <__panic> + cprintf("badarg pass.\n"); + 8010e4: c7 04 24 89 14 80 00 movl $0x801489,(%esp) + 8010eb: e8 30 f0 ff ff call 800120 + return 0; + 8010f0: b8 00 00 00 00 mov $0x0,%eax +} + 8010f5: 89 ec mov %ebp,%esp + 8010f7: 5d pop %ebp + 8010f8: c3 ret diff --git a/labcodes/lab5/obj/user/badarg.d b/labcodes/lab5/obj/user/badarg.d new file mode 100644 index 0000000000000000000000000000000000000000..1b28df1d8cd9f068705bac7b8402172b731ca776 --- /dev/null +++ b/labcodes/lab5/obj/user/badarg.d @@ -0,0 +1,2 @@ +obj/user/badarg.o obj/user/badarg.d: user/badarg.c libs/stdio.h \ + libs/defs.h libs/stdarg.h user/libs/ulib.h diff --git a/labcodes/lab5/obj/user/badarg.o b/labcodes/lab5/obj/user/badarg.o new file mode 100644 index 0000000000000000000000000000000000000000..d2f3dc1a3e76fc3aafc992791460b104487cf43e Binary files /dev/null and b/labcodes/lab5/obj/user/badarg.o differ diff --git a/labcodes/lab5/obj/user/badarg.sym b/labcodes/lab5/obj/user/badarg.sym new file mode 100644 index 0000000000000000000000000000000000000000..82a87ca1b981e9a2dd128431017f7f65affc9eca --- /dev/null +++ b/labcodes/lab5/obj/user/badarg.sym @@ -0,0 +1,66 @@ +00000000 panic.c +00000000 stdio.c +008000c8 cputch +00000000 syscall.c +00800199 syscall +00000000 ulib.c +00000000 umain.c +00000000 hash.c +00000000 printfmt.c +00801200 error_string +008003ad printnum +008004af getuint +008004fe getint +0080094f sprintputch +00000000 rand.c +00802000 next +00000000 string.c +00000000 badarg.c +00800b53 strcpy +00800329 yield +0080030d waitpid +00800245 sys_yield +00800e65 memmove +00800985 snprintf +00800576 vprintfmt +0080020b sys_fork +00800120 cprintf +0080034e getpid +00800f08 memcpy +008009bb vsnprintf +0080036d umain +00202800 __STAB_END__ +0080025b sys_kill +00202801 __STABSTR_BEGIN__ +0080002f __panic +00800ccb strtol +00800b22 strnlen +0080035d print_pgdir +00800339 kill +00800c9b strfind +008002ef wait +00800020 _start +00800a21 rand +00800c14 strncmp +0080028e sys_putc +00800b92 strncpy +00800f57 memcmp +008002e0 fork +00800e23 memset +00800faf main +00800ae0 srand +00800386 hash32 +00800545 printfmt +0020373b __STABSTR_END__ +00800bcb strcmp +008000eb vcprintf +0080007f __warn +00800148 cputs +008002c1 exit +00800221 sys_wait +008001ee sys_exit +00200010 __STAB_BEGIN__ +00800af9 strlen +008002ab sys_pgdir +00800c67 strchr +00800278 sys_getpid diff --git a/labcodes/lab5/obj/user/badsegment.asm b/labcodes/lab5/obj/user/badsegment.asm new file mode 100644 index 0000000000000000000000000000000000000000..bad38bdcb4250b8d14695a71c20f8a732f1a0a75 --- /dev/null +++ b/labcodes/lab5/obj/user/badsegment.asm @@ -0,0 +1,2321 @@ + +obj/__user_badsegment.out: file format elf32-i386 + + +Disassembly of section .text: + +00800020 <_start>: +.text +.globl _start +_start: + # set ebp for backtrace + movl $0x0, %ebp + 800020: bd 00 00 00 00 mov $0x0,%ebp + + # move down the esp register + # since it may cause page fault in backtrace + subl $0x20, %esp + 800025: 83 ec 20 sub $0x20,%esp + + # call user-program function + call umain + 800028: e8 40 03 00 00 call 80036d +1: jmp 1b + 80002d: eb fe jmp 80002d <_start+0xd> + +0080002f <__panic>: +#include +#include +#include + +void +__panic(const char *file, int line, const char *fmt, ...) { + 80002f: 55 push %ebp + 800030: 89 e5 mov %esp,%ebp + 800032: 83 ec 28 sub $0x28,%esp + // print the 'message' + va_list ap; + va_start(ap, fmt); + 800035: 8d 45 14 lea 0x14(%ebp),%eax + 800038: 89 45 f4 mov %eax,-0xc(%ebp) + cprintf("user panic at %s:%d:\n ", file, line); + 80003b: 8b 45 0c mov 0xc(%ebp),%eax + 80003e: 89 44 24 08 mov %eax,0x8(%esp) + 800042: 8b 45 08 mov 0x8(%ebp),%eax + 800045: 89 44 24 04 mov %eax,0x4(%esp) + 800049: c7 04 24 e0 0f 80 00 movl $0x800fe0,(%esp) + 800050: e8 cb 00 00 00 call 800120 + vcprintf(fmt, ap); + 800055: 8b 45 f4 mov -0xc(%ebp),%eax + 800058: 89 44 24 04 mov %eax,0x4(%esp) + 80005c: 8b 45 10 mov 0x10(%ebp),%eax + 80005f: 89 04 24 mov %eax,(%esp) + 800062: e8 84 00 00 00 call 8000eb + cprintf("\n"); + 800067: c7 04 24 fa 0f 80 00 movl $0x800ffa,(%esp) + 80006e: e8 ad 00 00 00 call 800120 + va_end(ap); + exit(-E_PANIC); + 800073: c7 04 24 f6 ff ff ff movl $0xfffffff6,(%esp) + 80007a: e8 42 02 00 00 call 8002c1 + +0080007f <__warn>: +} + +void +__warn(const char *file, int line, const char *fmt, ...) { + 80007f: 55 push %ebp + 800080: 89 e5 mov %esp,%ebp + 800082: 83 ec 28 sub $0x28,%esp + va_list ap; + va_start(ap, fmt); + 800085: 8d 45 14 lea 0x14(%ebp),%eax + 800088: 89 45 f4 mov %eax,-0xc(%ebp) + cprintf("user warning at %s:%d:\n ", file, line); + 80008b: 8b 45 0c mov 0xc(%ebp),%eax + 80008e: 89 44 24 08 mov %eax,0x8(%esp) + 800092: 8b 45 08 mov 0x8(%ebp),%eax + 800095: 89 44 24 04 mov %eax,0x4(%esp) + 800099: c7 04 24 fc 0f 80 00 movl $0x800ffc,(%esp) + 8000a0: e8 7b 00 00 00 call 800120 + vcprintf(fmt, ap); + 8000a5: 8b 45 f4 mov -0xc(%ebp),%eax + 8000a8: 89 44 24 04 mov %eax,0x4(%esp) + 8000ac: 8b 45 10 mov 0x10(%ebp),%eax + 8000af: 89 04 24 mov %eax,(%esp) + 8000b2: e8 34 00 00 00 call 8000eb + cprintf("\n"); + 8000b7: c7 04 24 fa 0f 80 00 movl $0x800ffa,(%esp) + 8000be: e8 5d 00 00 00 call 800120 + va_end(ap); +} + 8000c3: 90 nop + 8000c4: 89 ec mov %ebp,%esp + 8000c6: 5d pop %ebp + 8000c7: c3 ret + +008000c8 : +/* * + * cputch - writes a single character @c to stdout, and it will + * increace the value of counter pointed by @cnt. + * */ +static void +cputch(int c, int *cnt) { + 8000c8: 55 push %ebp + 8000c9: 89 e5 mov %esp,%ebp + 8000cb: 83 ec 18 sub $0x18,%esp + sys_putc(c); + 8000ce: 8b 45 08 mov 0x8(%ebp),%eax + 8000d1: 89 04 24 mov %eax,(%esp) + 8000d4: e8 b5 01 00 00 call 80028e + (*cnt) ++; + 8000d9: 8b 45 0c mov 0xc(%ebp),%eax + 8000dc: 8b 00 mov (%eax),%eax + 8000de: 8d 50 01 lea 0x1(%eax),%edx + 8000e1: 8b 45 0c mov 0xc(%ebp),%eax + 8000e4: 89 10 mov %edx,(%eax) +} + 8000e6: 90 nop + 8000e7: 89 ec mov %ebp,%esp + 8000e9: 5d pop %ebp + 8000ea: c3 ret + +008000eb : + * + * Call this function if you are already dealing with a va_list. + * Or you probably want cprintf() instead. + * */ +int +vcprintf(const char *fmt, va_list ap) { + 8000eb: 55 push %ebp + 8000ec: 89 e5 mov %esp,%ebp + 8000ee: 83 ec 28 sub $0x28,%esp + int cnt = 0; + 8000f1: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + vprintfmt((void*)cputch, &cnt, fmt, ap); + 8000f8: 8b 45 0c mov 0xc(%ebp),%eax + 8000fb: 89 44 24 0c mov %eax,0xc(%esp) + 8000ff: 8b 45 08 mov 0x8(%ebp),%eax + 800102: 89 44 24 08 mov %eax,0x8(%esp) + 800106: 8d 45 f4 lea -0xc(%ebp),%eax + 800109: 89 44 24 04 mov %eax,0x4(%esp) + 80010d: c7 04 24 c8 00 80 00 movl $0x8000c8,(%esp) + 800114: e8 5d 04 00 00 call 800576 + return cnt; + 800119: 8b 45 f4 mov -0xc(%ebp),%eax +} + 80011c: 89 ec mov %ebp,%esp + 80011e: 5d pop %ebp + 80011f: c3 ret + +00800120 : + * + * The return value is the number of characters which would be + * written to stdout. + * */ +int +cprintf(const char *fmt, ...) { + 800120: 55 push %ebp + 800121: 89 e5 mov %esp,%ebp + 800123: 83 ec 28 sub $0x28,%esp + va_list ap; + + va_start(ap, fmt); + 800126: 8d 45 0c lea 0xc(%ebp),%eax + 800129: 89 45 f0 mov %eax,-0x10(%ebp) + int cnt = vcprintf(fmt, ap); + 80012c: 8b 45 f0 mov -0x10(%ebp),%eax + 80012f: 89 44 24 04 mov %eax,0x4(%esp) + 800133: 8b 45 08 mov 0x8(%ebp),%eax + 800136: 89 04 24 mov %eax,(%esp) + 800139: e8 ad ff ff ff call 8000eb + 80013e: 89 45 f4 mov %eax,-0xc(%ebp) + va_end(ap); + + return cnt; + 800141: 8b 45 f4 mov -0xc(%ebp),%eax +} + 800144: 89 ec mov %ebp,%esp + 800146: 5d pop %ebp + 800147: c3 ret + +00800148 : +/* * + * cputs- writes the string pointed by @str to stdout and + * appends a newline character. + * */ +int +cputs(const char *str) { + 800148: 55 push %ebp + 800149: 89 e5 mov %esp,%ebp + 80014b: 83 ec 28 sub $0x28,%esp + int cnt = 0; + 80014e: c7 45 f0 00 00 00 00 movl $0x0,-0x10(%ebp) + char c; + while ((c = *str ++) != '\0') { + 800155: eb 13 jmp 80016a + cputch(c, &cnt); + 800157: 0f be 45 f7 movsbl -0x9(%ebp),%eax + 80015b: 8d 55 f0 lea -0x10(%ebp),%edx + 80015e: 89 54 24 04 mov %edx,0x4(%esp) + 800162: 89 04 24 mov %eax,(%esp) + 800165: e8 5e ff ff ff call 8000c8 + while ((c = *str ++) != '\0') { + 80016a: 8b 45 08 mov 0x8(%ebp),%eax + 80016d: 8d 50 01 lea 0x1(%eax),%edx + 800170: 89 55 08 mov %edx,0x8(%ebp) + 800173: 0f b6 00 movzbl (%eax),%eax + 800176: 88 45 f7 mov %al,-0x9(%ebp) + 800179: 80 7d f7 00 cmpb $0x0,-0x9(%ebp) + 80017d: 75 d8 jne 800157 + } + cputch('\n', &cnt); + 80017f: 8d 45 f0 lea -0x10(%ebp),%eax + 800182: 89 44 24 04 mov %eax,0x4(%esp) + 800186: c7 04 24 0a 00 00 00 movl $0xa,(%esp) + 80018d: e8 36 ff ff ff call 8000c8 + return cnt; + 800192: 8b 45 f0 mov -0x10(%ebp),%eax +} + 800195: 89 ec mov %ebp,%esp + 800197: 5d pop %ebp + 800198: c3 ret + +00800199 : +#include + +#define MAX_ARGS 5 + +static inline int +syscall(int num, ...) { + 800199: 55 push %ebp + 80019a: 89 e5 mov %esp,%ebp + 80019c: 57 push %edi + 80019d: 56 push %esi + 80019e: 53 push %ebx + 80019f: 83 ec 20 sub $0x20,%esp + va_list ap; + va_start(ap, num); + 8001a2: 8d 45 0c lea 0xc(%ebp),%eax + 8001a5: 89 45 e8 mov %eax,-0x18(%ebp) + uint32_t a[MAX_ARGS]; + int i, ret; + for (i = 0; i < MAX_ARGS; i ++) { + 8001a8: c7 45 f0 00 00 00 00 movl $0x0,-0x10(%ebp) + 8001af: eb 15 jmp 8001c6 + a[i] = va_arg(ap, uint32_t); + 8001b1: 8b 45 e8 mov -0x18(%ebp),%eax + 8001b4: 8d 50 04 lea 0x4(%eax),%edx + 8001b7: 89 55 e8 mov %edx,-0x18(%ebp) + 8001ba: 8b 10 mov (%eax),%edx + 8001bc: 8b 45 f0 mov -0x10(%ebp),%eax + 8001bf: 89 54 85 d4 mov %edx,-0x2c(%ebp,%eax,4) + for (i = 0; i < MAX_ARGS; i ++) { + 8001c3: ff 45 f0 incl -0x10(%ebp) + 8001c6: 83 7d f0 04 cmpl $0x4,-0x10(%ebp) + 8001ca: 7e e5 jle 8001b1 + asm volatile ( + "int %1;" + : "=a" (ret) + : "i" (T_SYSCALL), + "a" (num), + "d" (a[0]), + 8001cc: 8b 55 d4 mov -0x2c(%ebp),%edx + "c" (a[1]), + 8001cf: 8b 4d d8 mov -0x28(%ebp),%ecx + "b" (a[2]), + 8001d2: 8b 5d dc mov -0x24(%ebp),%ebx + "D" (a[3]), + 8001d5: 8b 7d e0 mov -0x20(%ebp),%edi + "S" (a[4]) + 8001d8: 8b 75 e4 mov -0x1c(%ebp),%esi + asm volatile ( + 8001db: 8b 45 08 mov 0x8(%ebp),%eax + 8001de: cd 80 int $0x80 + 8001e0: 89 45 ec mov %eax,-0x14(%ebp) + : "cc", "memory"); + return ret; + 8001e3: 8b 45 ec mov -0x14(%ebp),%eax +} + 8001e6: 83 c4 20 add $0x20,%esp + 8001e9: 5b pop %ebx + 8001ea: 5e pop %esi + 8001eb: 5f pop %edi + 8001ec: 5d pop %ebp + 8001ed: c3 ret + +008001ee : + +int +sys_exit(int error_code) { + 8001ee: 55 push %ebp + 8001ef: 89 e5 mov %esp,%ebp + 8001f1: 83 ec 08 sub $0x8,%esp + return syscall(SYS_exit, error_code); + 8001f4: 8b 45 08 mov 0x8(%ebp),%eax + 8001f7: 89 44 24 04 mov %eax,0x4(%esp) + 8001fb: c7 04 24 01 00 00 00 movl $0x1,(%esp) + 800202: e8 92 ff ff ff call 800199 +} + 800207: 89 ec mov %ebp,%esp + 800209: 5d pop %ebp + 80020a: c3 ret + +0080020b : + +int +sys_fork(void) { + 80020b: 55 push %ebp + 80020c: 89 e5 mov %esp,%ebp + 80020e: 83 ec 04 sub $0x4,%esp + return syscall(SYS_fork); + 800211: c7 04 24 02 00 00 00 movl $0x2,(%esp) + 800218: e8 7c ff ff ff call 800199 +} + 80021d: 89 ec mov %ebp,%esp + 80021f: 5d pop %ebp + 800220: c3 ret + +00800221 : + +int +sys_wait(int pid, int *store) { + 800221: 55 push %ebp + 800222: 89 e5 mov %esp,%ebp + 800224: 83 ec 0c sub $0xc,%esp + return syscall(SYS_wait, pid, store); + 800227: 8b 45 0c mov 0xc(%ebp),%eax + 80022a: 89 44 24 08 mov %eax,0x8(%esp) + 80022e: 8b 45 08 mov 0x8(%ebp),%eax + 800231: 89 44 24 04 mov %eax,0x4(%esp) + 800235: c7 04 24 03 00 00 00 movl $0x3,(%esp) + 80023c: e8 58 ff ff ff call 800199 +} + 800241: 89 ec mov %ebp,%esp + 800243: 5d pop %ebp + 800244: c3 ret + +00800245 : + +int +sys_yield(void) { + 800245: 55 push %ebp + 800246: 89 e5 mov %esp,%ebp + 800248: 83 ec 04 sub $0x4,%esp + return syscall(SYS_yield); + 80024b: c7 04 24 0a 00 00 00 movl $0xa,(%esp) + 800252: e8 42 ff ff ff call 800199 +} + 800257: 89 ec mov %ebp,%esp + 800259: 5d pop %ebp + 80025a: c3 ret + +0080025b : + +int +sys_kill(int pid) { + 80025b: 55 push %ebp + 80025c: 89 e5 mov %esp,%ebp + 80025e: 83 ec 08 sub $0x8,%esp + return syscall(SYS_kill, pid); + 800261: 8b 45 08 mov 0x8(%ebp),%eax + 800264: 89 44 24 04 mov %eax,0x4(%esp) + 800268: c7 04 24 0c 00 00 00 movl $0xc,(%esp) + 80026f: e8 25 ff ff ff call 800199 +} + 800274: 89 ec mov %ebp,%esp + 800276: 5d pop %ebp + 800277: c3 ret + +00800278 : + +int +sys_getpid(void) { + 800278: 55 push %ebp + 800279: 89 e5 mov %esp,%ebp + 80027b: 83 ec 04 sub $0x4,%esp + return syscall(SYS_getpid); + 80027e: c7 04 24 12 00 00 00 movl $0x12,(%esp) + 800285: e8 0f ff ff ff call 800199 +} + 80028a: 89 ec mov %ebp,%esp + 80028c: 5d pop %ebp + 80028d: c3 ret + +0080028e : + +int +sys_putc(int c) { + 80028e: 55 push %ebp + 80028f: 89 e5 mov %esp,%ebp + 800291: 83 ec 08 sub $0x8,%esp + return syscall(SYS_putc, c); + 800294: 8b 45 08 mov 0x8(%ebp),%eax + 800297: 89 44 24 04 mov %eax,0x4(%esp) + 80029b: c7 04 24 1e 00 00 00 movl $0x1e,(%esp) + 8002a2: e8 f2 fe ff ff call 800199 +} + 8002a7: 89 ec mov %ebp,%esp + 8002a9: 5d pop %ebp + 8002aa: c3 ret + +008002ab : + +int +sys_pgdir(void) { + 8002ab: 55 push %ebp + 8002ac: 89 e5 mov %esp,%ebp + 8002ae: 83 ec 04 sub $0x4,%esp + return syscall(SYS_pgdir); + 8002b1: c7 04 24 1f 00 00 00 movl $0x1f,(%esp) + 8002b8: e8 dc fe ff ff call 800199 +} + 8002bd: 89 ec mov %ebp,%esp + 8002bf: 5d pop %ebp + 8002c0: c3 ret + +008002c1 : +#include +#include +#include + +void +exit(int error_code) { + 8002c1: 55 push %ebp + 8002c2: 89 e5 mov %esp,%ebp + 8002c4: 83 ec 18 sub $0x18,%esp + sys_exit(error_code); + 8002c7: 8b 45 08 mov 0x8(%ebp),%eax + 8002ca: 89 04 24 mov %eax,(%esp) + 8002cd: e8 1c ff ff ff call 8001ee + cprintf("BUG: exit failed.\n"); + 8002d2: c7 04 24 18 10 80 00 movl $0x801018,(%esp) + 8002d9: e8 42 fe ff ff call 800120 + while (1); + 8002de: eb fe jmp 8002de + +008002e0 : +} + +int +fork(void) { + 8002e0: 55 push %ebp + 8002e1: 89 e5 mov %esp,%ebp + 8002e3: 83 ec 08 sub $0x8,%esp + return sys_fork(); + 8002e6: e8 20 ff ff ff call 80020b +} + 8002eb: 89 ec mov %ebp,%esp + 8002ed: 5d pop %ebp + 8002ee: c3 ret + +008002ef : + +int +wait(void) { + 8002ef: 55 push %ebp + 8002f0: 89 e5 mov %esp,%ebp + 8002f2: 83 ec 18 sub $0x18,%esp + return sys_wait(0, NULL); + 8002f5: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) + 8002fc: 00 + 8002fd: c7 04 24 00 00 00 00 movl $0x0,(%esp) + 800304: e8 18 ff ff ff call 800221 +} + 800309: 89 ec mov %ebp,%esp + 80030b: 5d pop %ebp + 80030c: c3 ret + +0080030d : + +int +waitpid(int pid, int *store) { + 80030d: 55 push %ebp + 80030e: 89 e5 mov %esp,%ebp + 800310: 83 ec 18 sub $0x18,%esp + return sys_wait(pid, store); + 800313: 8b 45 0c mov 0xc(%ebp),%eax + 800316: 89 44 24 04 mov %eax,0x4(%esp) + 80031a: 8b 45 08 mov 0x8(%ebp),%eax + 80031d: 89 04 24 mov %eax,(%esp) + 800320: e8 fc fe ff ff call 800221 +} + 800325: 89 ec mov %ebp,%esp + 800327: 5d pop %ebp + 800328: c3 ret + +00800329 : + +void +yield(void) { + 800329: 55 push %ebp + 80032a: 89 e5 mov %esp,%ebp + 80032c: 83 ec 08 sub $0x8,%esp + sys_yield(); + 80032f: e8 11 ff ff ff call 800245 +} + 800334: 90 nop + 800335: 89 ec mov %ebp,%esp + 800337: 5d pop %ebp + 800338: c3 ret + +00800339 : + +int +kill(int pid) { + 800339: 55 push %ebp + 80033a: 89 e5 mov %esp,%ebp + 80033c: 83 ec 18 sub $0x18,%esp + return sys_kill(pid); + 80033f: 8b 45 08 mov 0x8(%ebp),%eax + 800342: 89 04 24 mov %eax,(%esp) + 800345: e8 11 ff ff ff call 80025b +} + 80034a: 89 ec mov %ebp,%esp + 80034c: 5d pop %ebp + 80034d: c3 ret + +0080034e : + +int +getpid(void) { + 80034e: 55 push %ebp + 80034f: 89 e5 mov %esp,%ebp + 800351: 83 ec 08 sub $0x8,%esp + return sys_getpid(); + 800354: e8 1f ff ff ff call 800278 +} + 800359: 89 ec mov %ebp,%esp + 80035b: 5d pop %ebp + 80035c: c3 ret + +0080035d : + +//print_pgdir - print the PDT&PT +void +print_pgdir(void) { + 80035d: 55 push %ebp + 80035e: 89 e5 mov %esp,%ebp + 800360: 83 ec 08 sub $0x8,%esp + sys_pgdir(); + 800363: e8 43 ff ff ff call 8002ab +} + 800368: 90 nop + 800369: 89 ec mov %ebp,%esp + 80036b: 5d pop %ebp + 80036c: c3 ret + +0080036d : +#include + +int main(void); + +void +umain(void) { + 80036d: 55 push %ebp + 80036e: 89 e5 mov %esp,%ebp + 800370: 83 ec 28 sub $0x28,%esp + int ret = main(); + 800373: e8 37 0c 00 00 call 800faf
+ 800378: 89 45 f4 mov %eax,-0xc(%ebp) + exit(ret); + 80037b: 8b 45 f4 mov -0xc(%ebp),%eax + 80037e: 89 04 24 mov %eax,(%esp) + 800381: e8 3b ff ff ff call 8002c1 + +00800386 : + * @bits: the number of bits in a return value + * + * High bits are more random, so we use them. + * */ +uint32_t +hash32(uint32_t val, unsigned int bits) { + 800386: 55 push %ebp + 800387: 89 e5 mov %esp,%ebp + 800389: 83 ec 10 sub $0x10,%esp + uint32_t hash = val * GOLDEN_RATIO_PRIME_32; + 80038c: 8b 45 08 mov 0x8(%ebp),%eax + 80038f: 69 c0 01 00 37 9e imul $0x9e370001,%eax,%eax + 800395: 89 45 fc mov %eax,-0x4(%ebp) + return (hash >> (32 - bits)); + 800398: b8 20 00 00 00 mov $0x20,%eax + 80039d: 2b 45 0c sub 0xc(%ebp),%eax + 8003a0: 8b 55 fc mov -0x4(%ebp),%edx + 8003a3: 88 c1 mov %al,%cl + 8003a5: d3 ea shr %cl,%edx + 8003a7: 89 d0 mov %edx,%eax +} + 8003a9: 89 ec mov %ebp,%esp + 8003ab: 5d pop %ebp + 8003ac: c3 ret + +008003ad : + * @width: maximum number of digits, if the actual width is less than @width, use @padc instead + * @padc: character that padded on the left if the actual width is less than @width + * */ +static void +printnum(void (*putch)(int, void*), void *putdat, + unsigned long long num, unsigned base, int width, int padc) { + 8003ad: 55 push %ebp + 8003ae: 89 e5 mov %esp,%ebp + 8003b0: 83 ec 58 sub $0x58,%esp + 8003b3: 8b 45 10 mov 0x10(%ebp),%eax + 8003b6: 89 45 d0 mov %eax,-0x30(%ebp) + 8003b9: 8b 45 14 mov 0x14(%ebp),%eax + 8003bc: 89 45 d4 mov %eax,-0x2c(%ebp) + unsigned long long result = num; + 8003bf: 8b 45 d0 mov -0x30(%ebp),%eax + 8003c2: 8b 55 d4 mov -0x2c(%ebp),%edx + 8003c5: 89 45 e8 mov %eax,-0x18(%ebp) + 8003c8: 89 55 ec mov %edx,-0x14(%ebp) + unsigned mod = do_div(result, base); + 8003cb: 8b 45 18 mov 0x18(%ebp),%eax + 8003ce: 89 45 e4 mov %eax,-0x1c(%ebp) + 8003d1: 8b 45 e8 mov -0x18(%ebp),%eax + 8003d4: 8b 55 ec mov -0x14(%ebp),%edx + 8003d7: 89 45 e0 mov %eax,-0x20(%ebp) + 8003da: 89 55 f0 mov %edx,-0x10(%ebp) + 8003dd: 8b 45 f0 mov -0x10(%ebp),%eax + 8003e0: 89 45 f4 mov %eax,-0xc(%ebp) + 8003e3: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) + 8003e7: 74 1c je 800405 + 8003e9: 8b 45 f0 mov -0x10(%ebp),%eax + 8003ec: ba 00 00 00 00 mov $0x0,%edx + 8003f1: f7 75 e4 divl -0x1c(%ebp) + 8003f4: 89 55 f4 mov %edx,-0xc(%ebp) + 8003f7: 8b 45 f0 mov -0x10(%ebp),%eax + 8003fa: ba 00 00 00 00 mov $0x0,%edx + 8003ff: f7 75 e4 divl -0x1c(%ebp) + 800402: 89 45 f0 mov %eax,-0x10(%ebp) + 800405: 8b 45 e0 mov -0x20(%ebp),%eax + 800408: 8b 55 f4 mov -0xc(%ebp),%edx + 80040b: f7 75 e4 divl -0x1c(%ebp) + 80040e: 89 45 e0 mov %eax,-0x20(%ebp) + 800411: 89 55 dc mov %edx,-0x24(%ebp) + 800414: 8b 45 e0 mov -0x20(%ebp),%eax + 800417: 8b 55 f0 mov -0x10(%ebp),%edx + 80041a: 89 45 e8 mov %eax,-0x18(%ebp) + 80041d: 89 55 ec mov %edx,-0x14(%ebp) + 800420: 8b 45 dc mov -0x24(%ebp),%eax + 800423: 89 45 d8 mov %eax,-0x28(%ebp) + + // first recursively print all preceding (more significant) digits + if (num >= base) { + 800426: 8b 45 18 mov 0x18(%ebp),%eax + 800429: ba 00 00 00 00 mov $0x0,%edx + 80042e: 8b 4d d4 mov -0x2c(%ebp),%ecx + 800431: 39 45 d0 cmp %eax,-0x30(%ebp) + 800434: 19 d1 sbb %edx,%ecx + 800436: 72 4c jb 800484 + printnum(putch, putdat, result, base, width - 1, padc); + 800438: 8b 45 1c mov 0x1c(%ebp),%eax + 80043b: 8d 50 ff lea -0x1(%eax),%edx + 80043e: 8b 45 20 mov 0x20(%ebp),%eax + 800441: 89 44 24 18 mov %eax,0x18(%esp) + 800445: 89 54 24 14 mov %edx,0x14(%esp) + 800449: 8b 45 18 mov 0x18(%ebp),%eax + 80044c: 89 44 24 10 mov %eax,0x10(%esp) + 800450: 8b 45 e8 mov -0x18(%ebp),%eax + 800453: 8b 55 ec mov -0x14(%ebp),%edx + 800456: 89 44 24 08 mov %eax,0x8(%esp) + 80045a: 89 54 24 0c mov %edx,0xc(%esp) + 80045e: 8b 45 0c mov 0xc(%ebp),%eax + 800461: 89 44 24 04 mov %eax,0x4(%esp) + 800465: 8b 45 08 mov 0x8(%ebp),%eax + 800468: 89 04 24 mov %eax,(%esp) + 80046b: e8 3d ff ff ff call 8003ad + 800470: eb 1b jmp 80048d + } else { + // print any needed pad characters before first digit + while (-- width > 0) + putch(padc, putdat); + 800472: 8b 45 0c mov 0xc(%ebp),%eax + 800475: 89 44 24 04 mov %eax,0x4(%esp) + 800479: 8b 45 20 mov 0x20(%ebp),%eax + 80047c: 89 04 24 mov %eax,(%esp) + 80047f: 8b 45 08 mov 0x8(%ebp),%eax + 800482: ff d0 call *%eax + while (-- width > 0) + 800484: ff 4d 1c decl 0x1c(%ebp) + 800487: 83 7d 1c 00 cmpl $0x0,0x1c(%ebp) + 80048b: 7f e5 jg 800472 + } + // then print this (the least significant) digit + putch("0123456789abcdef"[mod], putdat); + 80048d: 8b 45 d8 mov -0x28(%ebp),%eax + 800490: 05 44 11 80 00 add $0x801144,%eax + 800495: 0f b6 00 movzbl (%eax),%eax + 800498: 0f be c0 movsbl %al,%eax + 80049b: 8b 55 0c mov 0xc(%ebp),%edx + 80049e: 89 54 24 04 mov %edx,0x4(%esp) + 8004a2: 89 04 24 mov %eax,(%esp) + 8004a5: 8b 45 08 mov 0x8(%ebp),%eax + 8004a8: ff d0 call *%eax +} + 8004aa: 90 nop + 8004ab: 89 ec mov %ebp,%esp + 8004ad: 5d pop %ebp + 8004ae: c3 ret + +008004af : + * getuint - get an unsigned int of various possible sizes from a varargs list + * @ap: a varargs list pointer + * @lflag: determines the size of the vararg that @ap points to + * */ +static unsigned long long +getuint(va_list *ap, int lflag) { + 8004af: 55 push %ebp + 8004b0: 89 e5 mov %esp,%ebp + if (lflag >= 2) { + 8004b2: 83 7d 0c 01 cmpl $0x1,0xc(%ebp) + 8004b6: 7e 14 jle 8004cc + return va_arg(*ap, unsigned long long); + 8004b8: 8b 45 08 mov 0x8(%ebp),%eax + 8004bb: 8b 00 mov (%eax),%eax + 8004bd: 8d 48 08 lea 0x8(%eax),%ecx + 8004c0: 8b 55 08 mov 0x8(%ebp),%edx + 8004c3: 89 0a mov %ecx,(%edx) + 8004c5: 8b 50 04 mov 0x4(%eax),%edx + 8004c8: 8b 00 mov (%eax),%eax + 8004ca: eb 30 jmp 8004fc + } + else if (lflag) { + 8004cc: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) + 8004d0: 74 16 je 8004e8 + return va_arg(*ap, unsigned long); + 8004d2: 8b 45 08 mov 0x8(%ebp),%eax + 8004d5: 8b 00 mov (%eax),%eax + 8004d7: 8d 48 04 lea 0x4(%eax),%ecx + 8004da: 8b 55 08 mov 0x8(%ebp),%edx + 8004dd: 89 0a mov %ecx,(%edx) + 8004df: 8b 00 mov (%eax),%eax + 8004e1: ba 00 00 00 00 mov $0x0,%edx + 8004e6: eb 14 jmp 8004fc + } + else { + return va_arg(*ap, unsigned int); + 8004e8: 8b 45 08 mov 0x8(%ebp),%eax + 8004eb: 8b 00 mov (%eax),%eax + 8004ed: 8d 48 04 lea 0x4(%eax),%ecx + 8004f0: 8b 55 08 mov 0x8(%ebp),%edx + 8004f3: 89 0a mov %ecx,(%edx) + 8004f5: 8b 00 mov (%eax),%eax + 8004f7: ba 00 00 00 00 mov $0x0,%edx + } +} + 8004fc: 5d pop %ebp + 8004fd: c3 ret + +008004fe : + * getint - same as getuint but signed, we can't use getuint because of sign extension + * @ap: a varargs list pointer + * @lflag: determines the size of the vararg that @ap points to + * */ +static long long +getint(va_list *ap, int lflag) { + 8004fe: 55 push %ebp + 8004ff: 89 e5 mov %esp,%ebp + if (lflag >= 2) { + 800501: 83 7d 0c 01 cmpl $0x1,0xc(%ebp) + 800505: 7e 14 jle 80051b + return va_arg(*ap, long long); + 800507: 8b 45 08 mov 0x8(%ebp),%eax + 80050a: 8b 00 mov (%eax),%eax + 80050c: 8d 48 08 lea 0x8(%eax),%ecx + 80050f: 8b 55 08 mov 0x8(%ebp),%edx + 800512: 89 0a mov %ecx,(%edx) + 800514: 8b 50 04 mov 0x4(%eax),%edx + 800517: 8b 00 mov (%eax),%eax + 800519: eb 28 jmp 800543 + } + else if (lflag) { + 80051b: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) + 80051f: 74 12 je 800533 + return va_arg(*ap, long); + 800521: 8b 45 08 mov 0x8(%ebp),%eax + 800524: 8b 00 mov (%eax),%eax + 800526: 8d 48 04 lea 0x4(%eax),%ecx + 800529: 8b 55 08 mov 0x8(%ebp),%edx + 80052c: 89 0a mov %ecx,(%edx) + 80052e: 8b 00 mov (%eax),%eax + 800530: 99 cltd + 800531: eb 10 jmp 800543 + } + else { + return va_arg(*ap, int); + 800533: 8b 45 08 mov 0x8(%ebp),%eax + 800536: 8b 00 mov (%eax),%eax + 800538: 8d 48 04 lea 0x4(%eax),%ecx + 80053b: 8b 55 08 mov 0x8(%ebp),%edx + 80053e: 89 0a mov %ecx,(%edx) + 800540: 8b 00 mov (%eax),%eax + 800542: 99 cltd + } +} + 800543: 5d pop %ebp + 800544: c3 ret + +00800545 : + * @putch: specified putch function, print a single character + * @putdat: used by @putch function + * @fmt: the format string to use + * */ +void +printfmt(void (*putch)(int, void*), void *putdat, const char *fmt, ...) { + 800545: 55 push %ebp + 800546: 89 e5 mov %esp,%ebp + 800548: 83 ec 28 sub $0x28,%esp + va_list ap; + + va_start(ap, fmt); + 80054b: 8d 45 14 lea 0x14(%ebp),%eax + 80054e: 89 45 f4 mov %eax,-0xc(%ebp) + vprintfmt(putch, putdat, fmt, ap); + 800551: 8b 45 f4 mov -0xc(%ebp),%eax + 800554: 89 44 24 0c mov %eax,0xc(%esp) + 800558: 8b 45 10 mov 0x10(%ebp),%eax + 80055b: 89 44 24 08 mov %eax,0x8(%esp) + 80055f: 8b 45 0c mov 0xc(%ebp),%eax + 800562: 89 44 24 04 mov %eax,0x4(%esp) + 800566: 8b 45 08 mov 0x8(%ebp),%eax + 800569: 89 04 24 mov %eax,(%esp) + 80056c: e8 05 00 00 00 call 800576 + va_end(ap); +} + 800571: 90 nop + 800572: 89 ec mov %ebp,%esp + 800574: 5d pop %ebp + 800575: c3 ret + +00800576 : + * + * Call this function if you are already dealing with a va_list. + * Or you probably want printfmt() instead. + * */ +void +vprintfmt(void (*putch)(int, void*), void *putdat, const char *fmt, va_list ap) { + 800576: 55 push %ebp + 800577: 89 e5 mov %esp,%ebp + 800579: 56 push %esi + 80057a: 53 push %ebx + 80057b: 83 ec 40 sub $0x40,%esp + register int ch, err; + unsigned long long num; + int base, width, precision, lflag, altflag; + + while (1) { + while ((ch = *(unsigned char *)fmt ++) != '%') { + 80057e: eb 17 jmp 800597 + if (ch == '\0') { + 800580: 85 db test %ebx,%ebx + 800582: 0f 84 bf 03 00 00 je 800947 + return; + } + putch(ch, putdat); + 800588: 8b 45 0c mov 0xc(%ebp),%eax + 80058b: 89 44 24 04 mov %eax,0x4(%esp) + 80058f: 89 1c 24 mov %ebx,(%esp) + 800592: 8b 45 08 mov 0x8(%ebp),%eax + 800595: ff d0 call *%eax + while ((ch = *(unsigned char *)fmt ++) != '%') { + 800597: 8b 45 10 mov 0x10(%ebp),%eax + 80059a: 8d 50 01 lea 0x1(%eax),%edx + 80059d: 89 55 10 mov %edx,0x10(%ebp) + 8005a0: 0f b6 00 movzbl (%eax),%eax + 8005a3: 0f b6 d8 movzbl %al,%ebx + 8005a6: 83 fb 25 cmp $0x25,%ebx + 8005a9: 75 d5 jne 800580 + } + + // Process a %-escape sequence + char padc = ' '; + 8005ab: c6 45 db 20 movb $0x20,-0x25(%ebp) + width = precision = -1; + 8005af: c7 45 e4 ff ff ff ff movl $0xffffffff,-0x1c(%ebp) + 8005b6: 8b 45 e4 mov -0x1c(%ebp),%eax + 8005b9: 89 45 e8 mov %eax,-0x18(%ebp) + lflag = altflag = 0; + 8005bc: c7 45 dc 00 00 00 00 movl $0x0,-0x24(%ebp) + 8005c3: 8b 45 dc mov -0x24(%ebp),%eax + 8005c6: 89 45 e0 mov %eax,-0x20(%ebp) + + reswitch: + switch (ch = *(unsigned char *)fmt ++) { + 8005c9: 8b 45 10 mov 0x10(%ebp),%eax + 8005cc: 8d 50 01 lea 0x1(%eax),%edx + 8005cf: 89 55 10 mov %edx,0x10(%ebp) + 8005d2: 0f b6 00 movzbl (%eax),%eax + 8005d5: 0f b6 d8 movzbl %al,%ebx + 8005d8: 8d 43 dd lea -0x23(%ebx),%eax + 8005db: 83 f8 55 cmp $0x55,%eax + 8005de: 0f 87 37 03 00 00 ja 80091b + 8005e4: 8b 04 85 68 11 80 00 mov 0x801168(,%eax,4),%eax + 8005eb: ff e0 jmp *%eax + + // flag to pad on the right + case '-': + padc = '-'; + 8005ed: c6 45 db 2d movb $0x2d,-0x25(%ebp) + goto reswitch; + 8005f1: eb d6 jmp 8005c9 + + // flag to pad with 0's instead of spaces + case '0': + padc = '0'; + 8005f3: c6 45 db 30 movb $0x30,-0x25(%ebp) + goto reswitch; + 8005f7: eb d0 jmp 8005c9 + + // width field + case '1' ... '9': + for (precision = 0; ; ++ fmt) { + 8005f9: c7 45 e4 00 00 00 00 movl $0x0,-0x1c(%ebp) + precision = precision * 10 + ch - '0'; + 800600: 8b 55 e4 mov -0x1c(%ebp),%edx + 800603: 89 d0 mov %edx,%eax + 800605: c1 e0 02 shl $0x2,%eax + 800608: 01 d0 add %edx,%eax + 80060a: 01 c0 add %eax,%eax + 80060c: 01 d8 add %ebx,%eax + 80060e: 83 e8 30 sub $0x30,%eax + 800611: 89 45 e4 mov %eax,-0x1c(%ebp) + ch = *fmt; + 800614: 8b 45 10 mov 0x10(%ebp),%eax + 800617: 0f b6 00 movzbl (%eax),%eax + 80061a: 0f be d8 movsbl %al,%ebx + if (ch < '0' || ch > '9') { + 80061d: 83 fb 2f cmp $0x2f,%ebx + 800620: 7e 38 jle 80065a + 800622: 83 fb 39 cmp $0x39,%ebx + 800625: 7f 33 jg 80065a + for (precision = 0; ; ++ fmt) { + 800627: ff 45 10 incl 0x10(%ebp) + precision = precision * 10 + ch - '0'; + 80062a: eb d4 jmp 800600 + } + } + goto process_precision; + + case '*': + precision = va_arg(ap, int); + 80062c: 8b 45 14 mov 0x14(%ebp),%eax + 80062f: 8d 50 04 lea 0x4(%eax),%edx + 800632: 89 55 14 mov %edx,0x14(%ebp) + 800635: 8b 00 mov (%eax),%eax + 800637: 89 45 e4 mov %eax,-0x1c(%ebp) + goto process_precision; + 80063a: eb 1f jmp 80065b + + case '.': + if (width < 0) + 80063c: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 800640: 79 87 jns 8005c9 + width = 0; + 800642: c7 45 e8 00 00 00 00 movl $0x0,-0x18(%ebp) + goto reswitch; + 800649: e9 7b ff ff ff jmp 8005c9 + + case '#': + altflag = 1; + 80064e: c7 45 dc 01 00 00 00 movl $0x1,-0x24(%ebp) + goto reswitch; + 800655: e9 6f ff ff ff jmp 8005c9 + goto process_precision; + 80065a: 90 nop + + process_precision: + if (width < 0) + 80065b: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 80065f: 0f 89 64 ff ff ff jns 8005c9 + width = precision, precision = -1; + 800665: 8b 45 e4 mov -0x1c(%ebp),%eax + 800668: 89 45 e8 mov %eax,-0x18(%ebp) + 80066b: c7 45 e4 ff ff ff ff movl $0xffffffff,-0x1c(%ebp) + goto reswitch; + 800672: e9 52 ff ff ff jmp 8005c9 + + // long flag (doubled for long long) + case 'l': + lflag ++; + 800677: ff 45 e0 incl -0x20(%ebp) + goto reswitch; + 80067a: e9 4a ff ff ff jmp 8005c9 + + // character + case 'c': + putch(va_arg(ap, int), putdat); + 80067f: 8b 45 14 mov 0x14(%ebp),%eax + 800682: 8d 50 04 lea 0x4(%eax),%edx + 800685: 89 55 14 mov %edx,0x14(%ebp) + 800688: 8b 00 mov (%eax),%eax + 80068a: 8b 55 0c mov 0xc(%ebp),%edx + 80068d: 89 54 24 04 mov %edx,0x4(%esp) + 800691: 89 04 24 mov %eax,(%esp) + 800694: 8b 45 08 mov 0x8(%ebp),%eax + 800697: ff d0 call *%eax + break; + 800699: e9 a4 02 00 00 jmp 800942 + + // error message + case 'e': + err = va_arg(ap, int); + 80069e: 8b 45 14 mov 0x14(%ebp),%eax + 8006a1: 8d 50 04 lea 0x4(%eax),%edx + 8006a4: 89 55 14 mov %edx,0x14(%ebp) + 8006a7: 8b 18 mov (%eax),%ebx + if (err < 0) { + 8006a9: 85 db test %ebx,%ebx + 8006ab: 79 02 jns 8006af + err = -err; + 8006ad: f7 db neg %ebx + } + if (err > MAXERROR || (p = error_string[err]) == NULL) { + 8006af: 83 fb 18 cmp $0x18,%ebx + 8006b2: 7f 0b jg 8006bf + 8006b4: 8b 34 9d e0 10 80 00 mov 0x8010e0(,%ebx,4),%esi + 8006bb: 85 f6 test %esi,%esi + 8006bd: 75 23 jne 8006e2 + printfmt(putch, putdat, "error %d", err); + 8006bf: 89 5c 24 0c mov %ebx,0xc(%esp) + 8006c3: c7 44 24 08 55 11 80 movl $0x801155,0x8(%esp) + 8006ca: 00 + 8006cb: 8b 45 0c mov 0xc(%ebp),%eax + 8006ce: 89 44 24 04 mov %eax,0x4(%esp) + 8006d2: 8b 45 08 mov 0x8(%ebp),%eax + 8006d5: 89 04 24 mov %eax,(%esp) + 8006d8: e8 68 fe ff ff call 800545 + } + else { + printfmt(putch, putdat, "%s", p); + } + break; + 8006dd: e9 60 02 00 00 jmp 800942 + printfmt(putch, putdat, "%s", p); + 8006e2: 89 74 24 0c mov %esi,0xc(%esp) + 8006e6: c7 44 24 08 5e 11 80 movl $0x80115e,0x8(%esp) + 8006ed: 00 + 8006ee: 8b 45 0c mov 0xc(%ebp),%eax + 8006f1: 89 44 24 04 mov %eax,0x4(%esp) + 8006f5: 8b 45 08 mov 0x8(%ebp),%eax + 8006f8: 89 04 24 mov %eax,(%esp) + 8006fb: e8 45 fe ff ff call 800545 + break; + 800700: e9 3d 02 00 00 jmp 800942 + + // string + case 's': + if ((p = va_arg(ap, char *)) == NULL) { + 800705: 8b 45 14 mov 0x14(%ebp),%eax + 800708: 8d 50 04 lea 0x4(%eax),%edx + 80070b: 89 55 14 mov %edx,0x14(%ebp) + 80070e: 8b 30 mov (%eax),%esi + 800710: 85 f6 test %esi,%esi + 800712: 75 05 jne 800719 + p = "(null)"; + 800714: be 61 11 80 00 mov $0x801161,%esi + } + if (width > 0 && padc != '-') { + 800719: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 80071d: 7e 76 jle 800795 + 80071f: 80 7d db 2d cmpb $0x2d,-0x25(%ebp) + 800723: 74 70 je 800795 + for (width -= strnlen(p, precision); width > 0; width --) { + 800725: 8b 45 e4 mov -0x1c(%ebp),%eax + 800728: 89 44 24 04 mov %eax,0x4(%esp) + 80072c: 89 34 24 mov %esi,(%esp) + 80072f: e8 ee 03 00 00 call 800b22 + 800734: 89 c2 mov %eax,%edx + 800736: 8b 45 e8 mov -0x18(%ebp),%eax + 800739: 29 d0 sub %edx,%eax + 80073b: 89 45 e8 mov %eax,-0x18(%ebp) + 80073e: eb 16 jmp 800756 + putch(padc, putdat); + 800740: 0f be 45 db movsbl -0x25(%ebp),%eax + 800744: 8b 55 0c mov 0xc(%ebp),%edx + 800747: 89 54 24 04 mov %edx,0x4(%esp) + 80074b: 89 04 24 mov %eax,(%esp) + 80074e: 8b 45 08 mov 0x8(%ebp),%eax + 800751: ff d0 call *%eax + for (width -= strnlen(p, precision); width > 0; width --) { + 800753: ff 4d e8 decl -0x18(%ebp) + 800756: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 80075a: 7f e4 jg 800740 + } + } + for (; (ch = *p ++) != '\0' && (precision < 0 || -- precision >= 0); width --) { + 80075c: eb 37 jmp 800795 + if (altflag && (ch < ' ' || ch > '~')) { + 80075e: 83 7d dc 00 cmpl $0x0,-0x24(%ebp) + 800762: 74 1f je 800783 + 800764: 83 fb 1f cmp $0x1f,%ebx + 800767: 7e 05 jle 80076e + 800769: 83 fb 7e cmp $0x7e,%ebx + 80076c: 7e 15 jle 800783 + putch('?', putdat); + 80076e: 8b 45 0c mov 0xc(%ebp),%eax + 800771: 89 44 24 04 mov %eax,0x4(%esp) + 800775: c7 04 24 3f 00 00 00 movl $0x3f,(%esp) + 80077c: 8b 45 08 mov 0x8(%ebp),%eax + 80077f: ff d0 call *%eax + 800781: eb 0f jmp 800792 + } + else { + putch(ch, putdat); + 800783: 8b 45 0c mov 0xc(%ebp),%eax + 800786: 89 44 24 04 mov %eax,0x4(%esp) + 80078a: 89 1c 24 mov %ebx,(%esp) + 80078d: 8b 45 08 mov 0x8(%ebp),%eax + 800790: ff d0 call *%eax + for (; (ch = *p ++) != '\0' && (precision < 0 || -- precision >= 0); width --) { + 800792: ff 4d e8 decl -0x18(%ebp) + 800795: 89 f0 mov %esi,%eax + 800797: 8d 70 01 lea 0x1(%eax),%esi + 80079a: 0f b6 00 movzbl (%eax),%eax + 80079d: 0f be d8 movsbl %al,%ebx + 8007a0: 85 db test %ebx,%ebx + 8007a2: 74 27 je 8007cb + 8007a4: 83 7d e4 00 cmpl $0x0,-0x1c(%ebp) + 8007a8: 78 b4 js 80075e + 8007aa: ff 4d e4 decl -0x1c(%ebp) + 8007ad: 83 7d e4 00 cmpl $0x0,-0x1c(%ebp) + 8007b1: 79 ab jns 80075e + } + } + for (; width > 0; width --) { + 8007b3: eb 16 jmp 8007cb + putch(' ', putdat); + 8007b5: 8b 45 0c mov 0xc(%ebp),%eax + 8007b8: 89 44 24 04 mov %eax,0x4(%esp) + 8007bc: c7 04 24 20 00 00 00 movl $0x20,(%esp) + 8007c3: 8b 45 08 mov 0x8(%ebp),%eax + 8007c6: ff d0 call *%eax + for (; width > 0; width --) { + 8007c8: ff 4d e8 decl -0x18(%ebp) + 8007cb: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 8007cf: 7f e4 jg 8007b5 + } + break; + 8007d1: e9 6c 01 00 00 jmp 800942 + + // (signed) decimal + case 'd': + num = getint(&ap, lflag); + 8007d6: 8b 45 e0 mov -0x20(%ebp),%eax + 8007d9: 89 44 24 04 mov %eax,0x4(%esp) + 8007dd: 8d 45 14 lea 0x14(%ebp),%eax + 8007e0: 89 04 24 mov %eax,(%esp) + 8007e3: e8 16 fd ff ff call 8004fe + 8007e8: 89 45 f0 mov %eax,-0x10(%ebp) + 8007eb: 89 55 f4 mov %edx,-0xc(%ebp) + if ((long long)num < 0) { + 8007ee: 8b 45 f0 mov -0x10(%ebp),%eax + 8007f1: 8b 55 f4 mov -0xc(%ebp),%edx + 8007f4: 85 d2 test %edx,%edx + 8007f6: 79 26 jns 80081e + putch('-', putdat); + 8007f8: 8b 45 0c mov 0xc(%ebp),%eax + 8007fb: 89 44 24 04 mov %eax,0x4(%esp) + 8007ff: c7 04 24 2d 00 00 00 movl $0x2d,(%esp) + 800806: 8b 45 08 mov 0x8(%ebp),%eax + 800809: ff d0 call *%eax + num = -(long long)num; + 80080b: 8b 45 f0 mov -0x10(%ebp),%eax + 80080e: 8b 55 f4 mov -0xc(%ebp),%edx + 800811: f7 d8 neg %eax + 800813: 83 d2 00 adc $0x0,%edx + 800816: f7 da neg %edx + 800818: 89 45 f0 mov %eax,-0x10(%ebp) + 80081b: 89 55 f4 mov %edx,-0xc(%ebp) + } + base = 10; + 80081e: c7 45 ec 0a 00 00 00 movl $0xa,-0x14(%ebp) + goto number; + 800825: e9 a8 00 00 00 jmp 8008d2 + + // unsigned decimal + case 'u': + num = getuint(&ap, lflag); + 80082a: 8b 45 e0 mov -0x20(%ebp),%eax + 80082d: 89 44 24 04 mov %eax,0x4(%esp) + 800831: 8d 45 14 lea 0x14(%ebp),%eax + 800834: 89 04 24 mov %eax,(%esp) + 800837: e8 73 fc ff ff call 8004af + 80083c: 89 45 f0 mov %eax,-0x10(%ebp) + 80083f: 89 55 f4 mov %edx,-0xc(%ebp) + base = 10; + 800842: c7 45 ec 0a 00 00 00 movl $0xa,-0x14(%ebp) + goto number; + 800849: e9 84 00 00 00 jmp 8008d2 + + // (unsigned) octal + case 'o': + num = getuint(&ap, lflag); + 80084e: 8b 45 e0 mov -0x20(%ebp),%eax + 800851: 89 44 24 04 mov %eax,0x4(%esp) + 800855: 8d 45 14 lea 0x14(%ebp),%eax + 800858: 89 04 24 mov %eax,(%esp) + 80085b: e8 4f fc ff ff call 8004af + 800860: 89 45 f0 mov %eax,-0x10(%ebp) + 800863: 89 55 f4 mov %edx,-0xc(%ebp) + base = 8; + 800866: c7 45 ec 08 00 00 00 movl $0x8,-0x14(%ebp) + goto number; + 80086d: eb 63 jmp 8008d2 + + // pointer + case 'p': + putch('0', putdat); + 80086f: 8b 45 0c mov 0xc(%ebp),%eax + 800872: 89 44 24 04 mov %eax,0x4(%esp) + 800876: c7 04 24 30 00 00 00 movl $0x30,(%esp) + 80087d: 8b 45 08 mov 0x8(%ebp),%eax + 800880: ff d0 call *%eax + putch('x', putdat); + 800882: 8b 45 0c mov 0xc(%ebp),%eax + 800885: 89 44 24 04 mov %eax,0x4(%esp) + 800889: c7 04 24 78 00 00 00 movl $0x78,(%esp) + 800890: 8b 45 08 mov 0x8(%ebp),%eax + 800893: ff d0 call *%eax + num = (unsigned long long)(uintptr_t)va_arg(ap, void *); + 800895: 8b 45 14 mov 0x14(%ebp),%eax + 800898: 8d 50 04 lea 0x4(%eax),%edx + 80089b: 89 55 14 mov %edx,0x14(%ebp) + 80089e: 8b 00 mov (%eax),%eax + 8008a0: 89 45 f0 mov %eax,-0x10(%ebp) + 8008a3: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + base = 16; + 8008aa: c7 45 ec 10 00 00 00 movl $0x10,-0x14(%ebp) + goto number; + 8008b1: eb 1f jmp 8008d2 + + // (unsigned) hexadecimal + case 'x': + num = getuint(&ap, lflag); + 8008b3: 8b 45 e0 mov -0x20(%ebp),%eax + 8008b6: 89 44 24 04 mov %eax,0x4(%esp) + 8008ba: 8d 45 14 lea 0x14(%ebp),%eax + 8008bd: 89 04 24 mov %eax,(%esp) + 8008c0: e8 ea fb ff ff call 8004af + 8008c5: 89 45 f0 mov %eax,-0x10(%ebp) + 8008c8: 89 55 f4 mov %edx,-0xc(%ebp) + base = 16; + 8008cb: c7 45 ec 10 00 00 00 movl $0x10,-0x14(%ebp) + number: + printnum(putch, putdat, num, base, width, padc); + 8008d2: 0f be 55 db movsbl -0x25(%ebp),%edx + 8008d6: 8b 45 ec mov -0x14(%ebp),%eax + 8008d9: 89 54 24 18 mov %edx,0x18(%esp) + 8008dd: 8b 55 e8 mov -0x18(%ebp),%edx + 8008e0: 89 54 24 14 mov %edx,0x14(%esp) + 8008e4: 89 44 24 10 mov %eax,0x10(%esp) + 8008e8: 8b 45 f0 mov -0x10(%ebp),%eax + 8008eb: 8b 55 f4 mov -0xc(%ebp),%edx + 8008ee: 89 44 24 08 mov %eax,0x8(%esp) + 8008f2: 89 54 24 0c mov %edx,0xc(%esp) + 8008f6: 8b 45 0c mov 0xc(%ebp),%eax + 8008f9: 89 44 24 04 mov %eax,0x4(%esp) + 8008fd: 8b 45 08 mov 0x8(%ebp),%eax + 800900: 89 04 24 mov %eax,(%esp) + 800903: e8 a5 fa ff ff call 8003ad + break; + 800908: eb 38 jmp 800942 + + // escaped '%' character + case '%': + putch(ch, putdat); + 80090a: 8b 45 0c mov 0xc(%ebp),%eax + 80090d: 89 44 24 04 mov %eax,0x4(%esp) + 800911: 89 1c 24 mov %ebx,(%esp) + 800914: 8b 45 08 mov 0x8(%ebp),%eax + 800917: ff d0 call *%eax + break; + 800919: eb 27 jmp 800942 + + // unrecognized escape sequence - just print it literally + default: + putch('%', putdat); + 80091b: 8b 45 0c mov 0xc(%ebp),%eax + 80091e: 89 44 24 04 mov %eax,0x4(%esp) + 800922: c7 04 24 25 00 00 00 movl $0x25,(%esp) + 800929: 8b 45 08 mov 0x8(%ebp),%eax + 80092c: ff d0 call *%eax + for (fmt --; fmt[-1] != '%'; fmt --) + 80092e: ff 4d 10 decl 0x10(%ebp) + 800931: eb 03 jmp 800936 + 800933: ff 4d 10 decl 0x10(%ebp) + 800936: 8b 45 10 mov 0x10(%ebp),%eax + 800939: 48 dec %eax + 80093a: 0f b6 00 movzbl (%eax),%eax + 80093d: 3c 25 cmp $0x25,%al + 80093f: 75 f2 jne 800933 + /* do nothing */; + break; + 800941: 90 nop + while (1) { + 800942: e9 37 fc ff ff jmp 80057e + return; + 800947: 90 nop + } + } +} + 800948: 83 c4 40 add $0x40,%esp + 80094b: 5b pop %ebx + 80094c: 5e pop %esi + 80094d: 5d pop %ebp + 80094e: c3 ret + +0080094f : + * sprintputch - 'print' a single character in a buffer + * @ch: the character will be printed + * @b: the buffer to place the character @ch + * */ +static void +sprintputch(int ch, struct sprintbuf *b) { + 80094f: 55 push %ebp + 800950: 89 e5 mov %esp,%ebp + b->cnt ++; + 800952: 8b 45 0c mov 0xc(%ebp),%eax + 800955: 8b 40 08 mov 0x8(%eax),%eax + 800958: 8d 50 01 lea 0x1(%eax),%edx + 80095b: 8b 45 0c mov 0xc(%ebp),%eax + 80095e: 89 50 08 mov %edx,0x8(%eax) + if (b->buf < b->ebuf) { + 800961: 8b 45 0c mov 0xc(%ebp),%eax + 800964: 8b 10 mov (%eax),%edx + 800966: 8b 45 0c mov 0xc(%ebp),%eax + 800969: 8b 40 04 mov 0x4(%eax),%eax + 80096c: 39 c2 cmp %eax,%edx + 80096e: 73 12 jae 800982 + *b->buf ++ = ch; + 800970: 8b 45 0c mov 0xc(%ebp),%eax + 800973: 8b 00 mov (%eax),%eax + 800975: 8d 48 01 lea 0x1(%eax),%ecx + 800978: 8b 55 0c mov 0xc(%ebp),%edx + 80097b: 89 0a mov %ecx,(%edx) + 80097d: 8b 55 08 mov 0x8(%ebp),%edx + 800980: 88 10 mov %dl,(%eax) + } +} + 800982: 90 nop + 800983: 5d pop %ebp + 800984: c3 ret + +00800985 : + * @str: the buffer to place the result into + * @size: the size of buffer, including the trailing null space + * @fmt: the format string to use + * */ +int +snprintf(char *str, size_t size, const char *fmt, ...) { + 800985: 55 push %ebp + 800986: 89 e5 mov %esp,%ebp + 800988: 83 ec 28 sub $0x28,%esp + va_list ap; + int cnt; + va_start(ap, fmt); + 80098b: 8d 45 14 lea 0x14(%ebp),%eax + 80098e: 89 45 f0 mov %eax,-0x10(%ebp) + cnt = vsnprintf(str, size, fmt, ap); + 800991: 8b 45 f0 mov -0x10(%ebp),%eax + 800994: 89 44 24 0c mov %eax,0xc(%esp) + 800998: 8b 45 10 mov 0x10(%ebp),%eax + 80099b: 89 44 24 08 mov %eax,0x8(%esp) + 80099f: 8b 45 0c mov 0xc(%ebp),%eax + 8009a2: 89 44 24 04 mov %eax,0x4(%esp) + 8009a6: 8b 45 08 mov 0x8(%ebp),%eax + 8009a9: 89 04 24 mov %eax,(%esp) + 8009ac: e8 0a 00 00 00 call 8009bb + 8009b1: 89 45 f4 mov %eax,-0xc(%ebp) + va_end(ap); + return cnt; + 8009b4: 8b 45 f4 mov -0xc(%ebp),%eax +} + 8009b7: 89 ec mov %ebp,%esp + 8009b9: 5d pop %ebp + 8009ba: c3 ret + +008009bb : + * + * Call this function if you are already dealing with a va_list. + * Or you probably want snprintf() instead. + * */ +int +vsnprintf(char *str, size_t size, const char *fmt, va_list ap) { + 8009bb: 55 push %ebp + 8009bc: 89 e5 mov %esp,%ebp + 8009be: 83 ec 28 sub $0x28,%esp + struct sprintbuf b = {str, str + size - 1, 0}; + 8009c1: 8b 45 08 mov 0x8(%ebp),%eax + 8009c4: 89 45 ec mov %eax,-0x14(%ebp) + 8009c7: 8b 45 0c mov 0xc(%ebp),%eax + 8009ca: 8d 50 ff lea -0x1(%eax),%edx + 8009cd: 8b 45 08 mov 0x8(%ebp),%eax + 8009d0: 01 d0 add %edx,%eax + 8009d2: 89 45 f0 mov %eax,-0x10(%ebp) + 8009d5: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + if (str == NULL || b.buf > b.ebuf) { + 8009dc: 83 7d 08 00 cmpl $0x0,0x8(%ebp) + 8009e0: 74 0a je 8009ec + 8009e2: 8b 55 ec mov -0x14(%ebp),%edx + 8009e5: 8b 45 f0 mov -0x10(%ebp),%eax + 8009e8: 39 c2 cmp %eax,%edx + 8009ea: 76 07 jbe 8009f3 + return -E_INVAL; + 8009ec: b8 fd ff ff ff mov $0xfffffffd,%eax + 8009f1: eb 2a jmp 800a1d + } + // print the string to the buffer + vprintfmt((void*)sprintputch, &b, fmt, ap); + 8009f3: 8b 45 14 mov 0x14(%ebp),%eax + 8009f6: 89 44 24 0c mov %eax,0xc(%esp) + 8009fa: 8b 45 10 mov 0x10(%ebp),%eax + 8009fd: 89 44 24 08 mov %eax,0x8(%esp) + 800a01: 8d 45 ec lea -0x14(%ebp),%eax + 800a04: 89 44 24 04 mov %eax,0x4(%esp) + 800a08: c7 04 24 4f 09 80 00 movl $0x80094f,(%esp) + 800a0f: e8 62 fb ff ff call 800576 + // null terminate the buffer + *b.buf = '\0'; + 800a14: 8b 45 ec mov -0x14(%ebp),%eax + 800a17: c6 00 00 movb $0x0,(%eax) + return b.cnt; + 800a1a: 8b 45 f4 mov -0xc(%ebp),%eax +} + 800a1d: 89 ec mov %ebp,%esp + 800a1f: 5d pop %ebp + 800a20: c3 ret + +00800a21 : + * rand - returns a pseudo-random integer + * + * The rand() function return a value in the range [0, RAND_MAX]. + * */ +int +rand(void) { + 800a21: 55 push %ebp + 800a22: 89 e5 mov %esp,%ebp + 800a24: 57 push %edi + 800a25: 56 push %esi + 800a26: 53 push %ebx + 800a27: 83 ec 24 sub $0x24,%esp + next = (next * 0x5DEECE66DLL + 0xBLL) & ((1LL << 48) - 1); + 800a2a: a1 00 20 80 00 mov 0x802000,%eax + 800a2f: 8b 15 04 20 80 00 mov 0x802004,%edx + 800a35: 69 fa 6d e6 ec de imul $0xdeece66d,%edx,%edi + 800a3b: 6b f0 05 imul $0x5,%eax,%esi + 800a3e: 01 fe add %edi,%esi + 800a40: bf 6d e6 ec de mov $0xdeece66d,%edi + 800a45: f7 e7 mul %edi + 800a47: 01 d6 add %edx,%esi + 800a49: 89 f2 mov %esi,%edx + 800a4b: 83 c0 0b add $0xb,%eax + 800a4e: 83 d2 00 adc $0x0,%edx + 800a51: 89 c7 mov %eax,%edi + 800a53: 83 e7 ff and $0xffffffff,%edi + 800a56: 89 f9 mov %edi,%ecx + 800a58: 0f b7 da movzwl %dx,%ebx + 800a5b: 89 0d 00 20 80 00 mov %ecx,0x802000 + 800a61: 89 1d 04 20 80 00 mov %ebx,0x802004 + unsigned long long result = (next >> 12); + 800a67: a1 00 20 80 00 mov 0x802000,%eax + 800a6c: 8b 15 04 20 80 00 mov 0x802004,%edx + 800a72: 0f ac d0 0c shrd $0xc,%edx,%eax + 800a76: c1 ea 0c shr $0xc,%edx + 800a79: 89 45 e0 mov %eax,-0x20(%ebp) + 800a7c: 89 55 e4 mov %edx,-0x1c(%ebp) + return (int)do_div(result, RAND_MAX + 1); + 800a7f: c7 45 dc 00 00 00 80 movl $0x80000000,-0x24(%ebp) + 800a86: 8b 45 e0 mov -0x20(%ebp),%eax + 800a89: 8b 55 e4 mov -0x1c(%ebp),%edx + 800a8c: 89 45 d8 mov %eax,-0x28(%ebp) + 800a8f: 89 55 e8 mov %edx,-0x18(%ebp) + 800a92: 8b 45 e8 mov -0x18(%ebp),%eax + 800a95: 89 45 ec mov %eax,-0x14(%ebp) + 800a98: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 800a9c: 74 1c je 800aba + 800a9e: 8b 45 e8 mov -0x18(%ebp),%eax + 800aa1: ba 00 00 00 00 mov $0x0,%edx + 800aa6: f7 75 dc divl -0x24(%ebp) + 800aa9: 89 55 ec mov %edx,-0x14(%ebp) + 800aac: 8b 45 e8 mov -0x18(%ebp),%eax + 800aaf: ba 00 00 00 00 mov $0x0,%edx + 800ab4: f7 75 dc divl -0x24(%ebp) + 800ab7: 89 45 e8 mov %eax,-0x18(%ebp) + 800aba: 8b 45 d8 mov -0x28(%ebp),%eax + 800abd: 8b 55 ec mov -0x14(%ebp),%edx + 800ac0: f7 75 dc divl -0x24(%ebp) + 800ac3: 89 45 d8 mov %eax,-0x28(%ebp) + 800ac6: 89 55 d4 mov %edx,-0x2c(%ebp) + 800ac9: 8b 45 d8 mov -0x28(%ebp),%eax + 800acc: 8b 55 e8 mov -0x18(%ebp),%edx + 800acf: 89 45 e0 mov %eax,-0x20(%ebp) + 800ad2: 89 55 e4 mov %edx,-0x1c(%ebp) + 800ad5: 8b 45 d4 mov -0x2c(%ebp),%eax +} + 800ad8: 83 c4 24 add $0x24,%esp + 800adb: 5b pop %ebx + 800adc: 5e pop %esi + 800add: 5f pop %edi + 800ade: 5d pop %ebp + 800adf: c3 ret + +00800ae0 : +/* * + * srand - seed the random number generator with the given number + * @seed: the required seed number + * */ +void +srand(unsigned int seed) { + 800ae0: 55 push %ebp + 800ae1: 89 e5 mov %esp,%ebp + next = seed; + 800ae3: 8b 45 08 mov 0x8(%ebp),%eax + 800ae6: ba 00 00 00 00 mov $0x0,%edx + 800aeb: a3 00 20 80 00 mov %eax,0x802000 + 800af0: 89 15 04 20 80 00 mov %edx,0x802004 +} + 800af6: 90 nop + 800af7: 5d pop %ebp + 800af8: c3 ret + +00800af9 : + * @s: the input string + * + * The strlen() function returns the length of string @s. + * */ +size_t +strlen(const char *s) { + 800af9: 55 push %ebp + 800afa: 89 e5 mov %esp,%ebp + 800afc: 83 ec 10 sub $0x10,%esp + size_t cnt = 0; + 800aff: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + while (*s ++ != '\0') { + 800b06: eb 03 jmp 800b0b + cnt ++; + 800b08: ff 45 fc incl -0x4(%ebp) + while (*s ++ != '\0') { + 800b0b: 8b 45 08 mov 0x8(%ebp),%eax + 800b0e: 8d 50 01 lea 0x1(%eax),%edx + 800b11: 89 55 08 mov %edx,0x8(%ebp) + 800b14: 0f b6 00 movzbl (%eax),%eax + 800b17: 84 c0 test %al,%al + 800b19: 75 ed jne 800b08 + } + return cnt; + 800b1b: 8b 45 fc mov -0x4(%ebp),%eax +} + 800b1e: 89 ec mov %ebp,%esp + 800b20: 5d pop %ebp + 800b21: c3 ret + +00800b22 : + * The return value is strlen(s), if that is less than @len, or + * @len if there is no '\0' character among the first @len characters + * pointed by @s. + * */ +size_t +strnlen(const char *s, size_t len) { + 800b22: 55 push %ebp + 800b23: 89 e5 mov %esp,%ebp + 800b25: 83 ec 10 sub $0x10,%esp + size_t cnt = 0; + 800b28: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + while (cnt < len && *s ++ != '\0') { + 800b2f: eb 03 jmp 800b34 + cnt ++; + 800b31: ff 45 fc incl -0x4(%ebp) + while (cnt < len && *s ++ != '\0') { + 800b34: 8b 45 fc mov -0x4(%ebp),%eax + 800b37: 3b 45 0c cmp 0xc(%ebp),%eax + 800b3a: 73 10 jae 800b4c + 800b3c: 8b 45 08 mov 0x8(%ebp),%eax + 800b3f: 8d 50 01 lea 0x1(%eax),%edx + 800b42: 89 55 08 mov %edx,0x8(%ebp) + 800b45: 0f b6 00 movzbl (%eax),%eax + 800b48: 84 c0 test %al,%al + 800b4a: 75 e5 jne 800b31 + } + return cnt; + 800b4c: 8b 45 fc mov -0x4(%ebp),%eax +} + 800b4f: 89 ec mov %ebp,%esp + 800b51: 5d pop %ebp + 800b52: c3 ret + +00800b53 : + * To avoid overflows, the size of array pointed by @dst should be long enough to + * contain the same string as @src (including the terminating null character), and + * should not overlap in memory with @src. + * */ +char * +strcpy(char *dst, const char *src) { + 800b53: 55 push %ebp + 800b54: 89 e5 mov %esp,%ebp + 800b56: 57 push %edi + 800b57: 56 push %esi + 800b58: 83 ec 20 sub $0x20,%esp + 800b5b: 8b 45 08 mov 0x8(%ebp),%eax + 800b5e: 89 45 f4 mov %eax,-0xc(%ebp) + 800b61: 8b 45 0c mov 0xc(%ebp),%eax + 800b64: 89 45 f0 mov %eax,-0x10(%ebp) +#ifndef __HAVE_ARCH_STRCPY +#define __HAVE_ARCH_STRCPY +static inline char * +__strcpy(char *dst, const char *src) { + int d0, d1, d2; + asm volatile ( + 800b67: 8b 55 f0 mov -0x10(%ebp),%edx + 800b6a: 8b 45 f4 mov -0xc(%ebp),%eax + 800b6d: 89 d1 mov %edx,%ecx + 800b6f: 89 c2 mov %eax,%edx + 800b71: 89 ce mov %ecx,%esi + 800b73: 89 d7 mov %edx,%edi + 800b75: ac lods %ds:(%esi),%al + 800b76: aa stos %al,%es:(%edi) + 800b77: 84 c0 test %al,%al + 800b79: 75 fa jne 800b75 + 800b7b: 89 fa mov %edi,%edx + 800b7d: 89 f1 mov %esi,%ecx + 800b7f: 89 4d ec mov %ecx,-0x14(%ebp) + 800b82: 89 55 e8 mov %edx,-0x18(%ebp) + 800b85: 89 45 e4 mov %eax,-0x1c(%ebp) + "stosb;" + "testb %%al, %%al;" + "jne 1b;" + : "=&S" (d0), "=&D" (d1), "=&a" (d2) + : "0" (src), "1" (dst) : "memory"); + return dst; + 800b88: 8b 45 f4 mov -0xc(%ebp),%eax + char *p = dst; + while ((*p ++ = *src ++) != '\0') + /* nothing */; + return dst; +#endif /* __HAVE_ARCH_STRCPY */ +} + 800b8b: 83 c4 20 add $0x20,%esp + 800b8e: 5e pop %esi + 800b8f: 5f pop %edi + 800b90: 5d pop %ebp + 800b91: c3 ret + +00800b92 : + * @len: maximum number of characters to be copied from @src + * + * The return value is @dst + * */ +char * +strncpy(char *dst, const char *src, size_t len) { + 800b92: 55 push %ebp + 800b93: 89 e5 mov %esp,%ebp + 800b95: 83 ec 10 sub $0x10,%esp + char *p = dst; + 800b98: 8b 45 08 mov 0x8(%ebp),%eax + 800b9b: 89 45 fc mov %eax,-0x4(%ebp) + while (len > 0) { + 800b9e: eb 1e jmp 800bbe + if ((*p = *src) != '\0') { + 800ba0: 8b 45 0c mov 0xc(%ebp),%eax + 800ba3: 0f b6 10 movzbl (%eax),%edx + 800ba6: 8b 45 fc mov -0x4(%ebp),%eax + 800ba9: 88 10 mov %dl,(%eax) + 800bab: 8b 45 fc mov -0x4(%ebp),%eax + 800bae: 0f b6 00 movzbl (%eax),%eax + 800bb1: 84 c0 test %al,%al + 800bb3: 74 03 je 800bb8 + src ++; + 800bb5: ff 45 0c incl 0xc(%ebp) + } + p ++, len --; + 800bb8: ff 45 fc incl -0x4(%ebp) + 800bbb: ff 4d 10 decl 0x10(%ebp) + while (len > 0) { + 800bbe: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800bc2: 75 dc jne 800ba0 + } + return dst; + 800bc4: 8b 45 08 mov 0x8(%ebp),%eax +} + 800bc7: 89 ec mov %ebp,%esp + 800bc9: 5d pop %ebp + 800bca: c3 ret + +00800bcb : + * - A value greater than zero indicates that the first character that does + * not match has a greater value in @s1 than in @s2; + * - And a value less than zero indicates the opposite. + * */ +int +strcmp(const char *s1, const char *s2) { + 800bcb: 55 push %ebp + 800bcc: 89 e5 mov %esp,%ebp + 800bce: 57 push %edi + 800bcf: 56 push %esi + 800bd0: 83 ec 20 sub $0x20,%esp + 800bd3: 8b 45 08 mov 0x8(%ebp),%eax + 800bd6: 89 45 f4 mov %eax,-0xc(%ebp) + 800bd9: 8b 45 0c mov 0xc(%ebp),%eax + 800bdc: 89 45 f0 mov %eax,-0x10(%ebp) + asm volatile ( + 800bdf: 8b 55 f4 mov -0xc(%ebp),%edx + 800be2: 8b 45 f0 mov -0x10(%ebp),%eax + 800be5: 89 d1 mov %edx,%ecx + 800be7: 89 c2 mov %eax,%edx + 800be9: 89 ce mov %ecx,%esi + 800beb: 89 d7 mov %edx,%edi + 800bed: ac lods %ds:(%esi),%al + 800bee: ae scas %es:(%edi),%al + 800bef: 75 08 jne 800bf9 + 800bf1: 84 c0 test %al,%al + 800bf3: 75 f8 jne 800bed + 800bf5: 31 c0 xor %eax,%eax + 800bf7: eb 04 jmp 800bfd + 800bf9: 19 c0 sbb %eax,%eax + 800bfb: 0c 01 or $0x1,%al + 800bfd: 89 fa mov %edi,%edx + 800bff: 89 f1 mov %esi,%ecx + 800c01: 89 45 ec mov %eax,-0x14(%ebp) + 800c04: 89 4d e8 mov %ecx,-0x18(%ebp) + 800c07: 89 55 e4 mov %edx,-0x1c(%ebp) + return ret; + 800c0a: 8b 45 ec mov -0x14(%ebp),%eax + while (*s1 != '\0' && *s1 == *s2) { + s1 ++, s2 ++; + } + return (int)((unsigned char)*s1 - (unsigned char)*s2); +#endif /* __HAVE_ARCH_STRCMP */ +} + 800c0d: 83 c4 20 add $0x20,%esp + 800c10: 5e pop %esi + 800c11: 5f pop %edi + 800c12: 5d pop %ebp + 800c13: c3 ret + +00800c14 : + * they are equal to each other, it continues with the following pairs until + * the characters differ, until a terminating null-character is reached, or + * until @n characters match in both strings, whichever happens first. + * */ +int +strncmp(const char *s1, const char *s2, size_t n) { + 800c14: 55 push %ebp + 800c15: 89 e5 mov %esp,%ebp + while (n > 0 && *s1 != '\0' && *s1 == *s2) { + 800c17: eb 09 jmp 800c22 + n --, s1 ++, s2 ++; + 800c19: ff 4d 10 decl 0x10(%ebp) + 800c1c: ff 45 08 incl 0x8(%ebp) + 800c1f: ff 45 0c incl 0xc(%ebp) + while (n > 0 && *s1 != '\0' && *s1 == *s2) { + 800c22: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800c26: 74 1a je 800c42 + 800c28: 8b 45 08 mov 0x8(%ebp),%eax + 800c2b: 0f b6 00 movzbl (%eax),%eax + 800c2e: 84 c0 test %al,%al + 800c30: 74 10 je 800c42 + 800c32: 8b 45 08 mov 0x8(%ebp),%eax + 800c35: 0f b6 10 movzbl (%eax),%edx + 800c38: 8b 45 0c mov 0xc(%ebp),%eax + 800c3b: 0f b6 00 movzbl (%eax),%eax + 800c3e: 38 c2 cmp %al,%dl + 800c40: 74 d7 je 800c19 + } + return (n == 0) ? 0 : (int)((unsigned char)*s1 - (unsigned char)*s2); + 800c42: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800c46: 74 18 je 800c60 + 800c48: 8b 45 08 mov 0x8(%ebp),%eax + 800c4b: 0f b6 00 movzbl (%eax),%eax + 800c4e: 0f b6 d0 movzbl %al,%edx + 800c51: 8b 45 0c mov 0xc(%ebp),%eax + 800c54: 0f b6 00 movzbl (%eax),%eax + 800c57: 0f b6 c8 movzbl %al,%ecx + 800c5a: 89 d0 mov %edx,%eax + 800c5c: 29 c8 sub %ecx,%eax + 800c5e: eb 05 jmp 800c65 + 800c60: b8 00 00 00 00 mov $0x0,%eax +} + 800c65: 5d pop %ebp + 800c66: c3 ret + +00800c67 : + * + * The strchr() function returns a pointer to the first occurrence of + * character in @s. If the value is not found, the function returns 'NULL'. + * */ +char * +strchr(const char *s, char c) { + 800c67: 55 push %ebp + 800c68: 89 e5 mov %esp,%ebp + 800c6a: 83 ec 04 sub $0x4,%esp + 800c6d: 8b 45 0c mov 0xc(%ebp),%eax + 800c70: 88 45 fc mov %al,-0x4(%ebp) + while (*s != '\0') { + 800c73: eb 13 jmp 800c88 + if (*s == c) { + 800c75: 8b 45 08 mov 0x8(%ebp),%eax + 800c78: 0f b6 00 movzbl (%eax),%eax + 800c7b: 38 45 fc cmp %al,-0x4(%ebp) + 800c7e: 75 05 jne 800c85 + return (char *)s; + 800c80: 8b 45 08 mov 0x8(%ebp),%eax + 800c83: eb 12 jmp 800c97 + } + s ++; + 800c85: ff 45 08 incl 0x8(%ebp) + while (*s != '\0') { + 800c88: 8b 45 08 mov 0x8(%ebp),%eax + 800c8b: 0f b6 00 movzbl (%eax),%eax + 800c8e: 84 c0 test %al,%al + 800c90: 75 e3 jne 800c75 + } + return NULL; + 800c92: b8 00 00 00 00 mov $0x0,%eax +} + 800c97: 89 ec mov %ebp,%esp + 800c99: 5d pop %ebp + 800c9a: c3 ret + +00800c9b : + * The strfind() function is like strchr() except that if @c is + * not found in @s, then it returns a pointer to the null byte at the + * end of @s, rather than 'NULL'. + * */ +char * +strfind(const char *s, char c) { + 800c9b: 55 push %ebp + 800c9c: 89 e5 mov %esp,%ebp + 800c9e: 83 ec 04 sub $0x4,%esp + 800ca1: 8b 45 0c mov 0xc(%ebp),%eax + 800ca4: 88 45 fc mov %al,-0x4(%ebp) + while (*s != '\0') { + 800ca7: eb 0e jmp 800cb7 + if (*s == c) { + 800ca9: 8b 45 08 mov 0x8(%ebp),%eax + 800cac: 0f b6 00 movzbl (%eax),%eax + 800caf: 38 45 fc cmp %al,-0x4(%ebp) + 800cb2: 74 0f je 800cc3 + break; + } + s ++; + 800cb4: ff 45 08 incl 0x8(%ebp) + while (*s != '\0') { + 800cb7: 8b 45 08 mov 0x8(%ebp),%eax + 800cba: 0f b6 00 movzbl (%eax),%eax + 800cbd: 84 c0 test %al,%al + 800cbf: 75 e8 jne 800ca9 + 800cc1: eb 01 jmp 800cc4 + break; + 800cc3: 90 nop + } + return (char *)s; + 800cc4: 8b 45 08 mov 0x8(%ebp),%eax +} + 800cc7: 89 ec mov %ebp,%esp + 800cc9: 5d pop %ebp + 800cca: c3 ret + +00800ccb : + * an optional "0x" or "0X" prefix. + * + * The strtol() function returns the converted integral number as a long int value. + * */ +long +strtol(const char *s, char **endptr, int base) { + 800ccb: 55 push %ebp + 800ccc: 89 e5 mov %esp,%ebp + 800cce: 83 ec 10 sub $0x10,%esp + int neg = 0; + 800cd1: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + long val = 0; + 800cd8: c7 45 f8 00 00 00 00 movl $0x0,-0x8(%ebp) + + // gobble initial whitespace + while (*s == ' ' || *s == '\t') { + 800cdf: eb 03 jmp 800ce4 + s ++; + 800ce1: ff 45 08 incl 0x8(%ebp) + while (*s == ' ' || *s == '\t') { + 800ce4: 8b 45 08 mov 0x8(%ebp),%eax + 800ce7: 0f b6 00 movzbl (%eax),%eax + 800cea: 3c 20 cmp $0x20,%al + 800cec: 74 f3 je 800ce1 + 800cee: 8b 45 08 mov 0x8(%ebp),%eax + 800cf1: 0f b6 00 movzbl (%eax),%eax + 800cf4: 3c 09 cmp $0x9,%al + 800cf6: 74 e9 je 800ce1 + } + + // plus/minus sign + if (*s == '+') { + 800cf8: 8b 45 08 mov 0x8(%ebp),%eax + 800cfb: 0f b6 00 movzbl (%eax),%eax + 800cfe: 3c 2b cmp $0x2b,%al + 800d00: 75 05 jne 800d07 + s ++; + 800d02: ff 45 08 incl 0x8(%ebp) + 800d05: eb 14 jmp 800d1b + } + else if (*s == '-') { + 800d07: 8b 45 08 mov 0x8(%ebp),%eax + 800d0a: 0f b6 00 movzbl (%eax),%eax + 800d0d: 3c 2d cmp $0x2d,%al + 800d0f: 75 0a jne 800d1b + s ++, neg = 1; + 800d11: ff 45 08 incl 0x8(%ebp) + 800d14: c7 45 fc 01 00 00 00 movl $0x1,-0x4(%ebp) + } + + // hex or octal base prefix + if ((base == 0 || base == 16) && (s[0] == '0' && s[1] == 'x')) { + 800d1b: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800d1f: 74 06 je 800d27 + 800d21: 83 7d 10 10 cmpl $0x10,0x10(%ebp) + 800d25: 75 22 jne 800d49 + 800d27: 8b 45 08 mov 0x8(%ebp),%eax + 800d2a: 0f b6 00 movzbl (%eax),%eax + 800d2d: 3c 30 cmp $0x30,%al + 800d2f: 75 18 jne 800d49 + 800d31: 8b 45 08 mov 0x8(%ebp),%eax + 800d34: 40 inc %eax + 800d35: 0f b6 00 movzbl (%eax),%eax + 800d38: 3c 78 cmp $0x78,%al + 800d3a: 75 0d jne 800d49 + s += 2, base = 16; + 800d3c: 83 45 08 02 addl $0x2,0x8(%ebp) + 800d40: c7 45 10 10 00 00 00 movl $0x10,0x10(%ebp) + 800d47: eb 29 jmp 800d72 + } + else if (base == 0 && s[0] == '0') { + 800d49: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800d4d: 75 16 jne 800d65 + 800d4f: 8b 45 08 mov 0x8(%ebp),%eax + 800d52: 0f b6 00 movzbl (%eax),%eax + 800d55: 3c 30 cmp $0x30,%al + 800d57: 75 0c jne 800d65 + s ++, base = 8; + 800d59: ff 45 08 incl 0x8(%ebp) + 800d5c: c7 45 10 08 00 00 00 movl $0x8,0x10(%ebp) + 800d63: eb 0d jmp 800d72 + } + else if (base == 0) { + 800d65: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800d69: 75 07 jne 800d72 + base = 10; + 800d6b: c7 45 10 0a 00 00 00 movl $0xa,0x10(%ebp) + + // digits + while (1) { + int dig; + + if (*s >= '0' && *s <= '9') { + 800d72: 8b 45 08 mov 0x8(%ebp),%eax + 800d75: 0f b6 00 movzbl (%eax),%eax + 800d78: 3c 2f cmp $0x2f,%al + 800d7a: 7e 1b jle 800d97 + 800d7c: 8b 45 08 mov 0x8(%ebp),%eax + 800d7f: 0f b6 00 movzbl (%eax),%eax + 800d82: 3c 39 cmp $0x39,%al + 800d84: 7f 11 jg 800d97 + dig = *s - '0'; + 800d86: 8b 45 08 mov 0x8(%ebp),%eax + 800d89: 0f b6 00 movzbl (%eax),%eax + 800d8c: 0f be c0 movsbl %al,%eax + 800d8f: 83 e8 30 sub $0x30,%eax + 800d92: 89 45 f4 mov %eax,-0xc(%ebp) + 800d95: eb 48 jmp 800ddf + } + else if (*s >= 'a' && *s <= 'z') { + 800d97: 8b 45 08 mov 0x8(%ebp),%eax + 800d9a: 0f b6 00 movzbl (%eax),%eax + 800d9d: 3c 60 cmp $0x60,%al + 800d9f: 7e 1b jle 800dbc + 800da1: 8b 45 08 mov 0x8(%ebp),%eax + 800da4: 0f b6 00 movzbl (%eax),%eax + 800da7: 3c 7a cmp $0x7a,%al + 800da9: 7f 11 jg 800dbc + dig = *s - 'a' + 10; + 800dab: 8b 45 08 mov 0x8(%ebp),%eax + 800dae: 0f b6 00 movzbl (%eax),%eax + 800db1: 0f be c0 movsbl %al,%eax + 800db4: 83 e8 57 sub $0x57,%eax + 800db7: 89 45 f4 mov %eax,-0xc(%ebp) + 800dba: eb 23 jmp 800ddf + } + else if (*s >= 'A' && *s <= 'Z') { + 800dbc: 8b 45 08 mov 0x8(%ebp),%eax + 800dbf: 0f b6 00 movzbl (%eax),%eax + 800dc2: 3c 40 cmp $0x40,%al + 800dc4: 7e 3b jle 800e01 + 800dc6: 8b 45 08 mov 0x8(%ebp),%eax + 800dc9: 0f b6 00 movzbl (%eax),%eax + 800dcc: 3c 5a cmp $0x5a,%al + 800dce: 7f 31 jg 800e01 + dig = *s - 'A' + 10; + 800dd0: 8b 45 08 mov 0x8(%ebp),%eax + 800dd3: 0f b6 00 movzbl (%eax),%eax + 800dd6: 0f be c0 movsbl %al,%eax + 800dd9: 83 e8 37 sub $0x37,%eax + 800ddc: 89 45 f4 mov %eax,-0xc(%ebp) + } + else { + break; + } + if (dig >= base) { + 800ddf: 8b 45 f4 mov -0xc(%ebp),%eax + 800de2: 3b 45 10 cmp 0x10(%ebp),%eax + 800de5: 7d 19 jge 800e00 + break; + } + s ++, val = (val * base) + dig; + 800de7: ff 45 08 incl 0x8(%ebp) + 800dea: 8b 45 f8 mov -0x8(%ebp),%eax + 800ded: 0f af 45 10 imul 0x10(%ebp),%eax + 800df1: 89 c2 mov %eax,%edx + 800df3: 8b 45 f4 mov -0xc(%ebp),%eax + 800df6: 01 d0 add %edx,%eax + 800df8: 89 45 f8 mov %eax,-0x8(%ebp) + while (1) { + 800dfb: e9 72 ff ff ff jmp 800d72 + break; + 800e00: 90 nop + // we don't properly detect overflow! + } + + if (endptr) { + 800e01: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) + 800e05: 74 08 je 800e0f + *endptr = (char *) s; + 800e07: 8b 45 0c mov 0xc(%ebp),%eax + 800e0a: 8b 55 08 mov 0x8(%ebp),%edx + 800e0d: 89 10 mov %edx,(%eax) + } + return (neg ? -val : val); + 800e0f: 83 7d fc 00 cmpl $0x0,-0x4(%ebp) + 800e13: 74 07 je 800e1c + 800e15: 8b 45 f8 mov -0x8(%ebp),%eax + 800e18: f7 d8 neg %eax + 800e1a: eb 03 jmp 800e1f + 800e1c: 8b 45 f8 mov -0x8(%ebp),%eax +} + 800e1f: 89 ec mov %ebp,%esp + 800e21: 5d pop %ebp + 800e22: c3 ret + +00800e23 : + * @n: number of bytes to be set to the value + * + * The memset() function returns @s. + * */ +void * +memset(void *s, char c, size_t n) { + 800e23: 55 push %ebp + 800e24: 89 e5 mov %esp,%ebp + 800e26: 83 ec 28 sub $0x28,%esp + 800e29: 89 7d fc mov %edi,-0x4(%ebp) + 800e2c: 8b 45 0c mov 0xc(%ebp),%eax + 800e2f: 88 45 d8 mov %al,-0x28(%ebp) +#ifdef __HAVE_ARCH_MEMSET + return __memset(s, c, n); + 800e32: 0f be 55 d8 movsbl -0x28(%ebp),%edx + 800e36: 8b 45 08 mov 0x8(%ebp),%eax + 800e39: 89 45 f8 mov %eax,-0x8(%ebp) + 800e3c: 88 55 f7 mov %dl,-0x9(%ebp) + 800e3f: 8b 45 10 mov 0x10(%ebp),%eax + 800e42: 89 45 f0 mov %eax,-0x10(%ebp) +#ifndef __HAVE_ARCH_MEMSET +#define __HAVE_ARCH_MEMSET +static inline void * +__memset(void *s, char c, size_t n) { + int d0, d1; + asm volatile ( + 800e45: 8b 4d f0 mov -0x10(%ebp),%ecx + 800e48: 0f b6 45 f7 movzbl -0x9(%ebp),%eax + 800e4c: 8b 55 f8 mov -0x8(%ebp),%edx + 800e4f: 89 d7 mov %edx,%edi + 800e51: f3 aa rep stos %al,%es:(%edi) + 800e53: 89 fa mov %edi,%edx + 800e55: 89 4d ec mov %ecx,-0x14(%ebp) + 800e58: 89 55 e8 mov %edx,-0x18(%ebp) + "rep; stosb;" + : "=&c" (d0), "=&D" (d1) + : "0" (n), "a" (c), "1" (s) + : "memory"); + return s; + 800e5b: 8b 45 f8 mov -0x8(%ebp),%eax + while (n -- > 0) { + *p ++ = c; + } + return s; +#endif /* __HAVE_ARCH_MEMSET */ +} + 800e5e: 8b 7d fc mov -0x4(%ebp),%edi + 800e61: 89 ec mov %ebp,%esp + 800e63: 5d pop %ebp + 800e64: c3 ret + +00800e65 : + * @n: number of bytes to copy + * + * The memmove() function returns @dst. + * */ +void * +memmove(void *dst, const void *src, size_t n) { + 800e65: 55 push %ebp + 800e66: 89 e5 mov %esp,%ebp + 800e68: 57 push %edi + 800e69: 56 push %esi + 800e6a: 53 push %ebx + 800e6b: 83 ec 30 sub $0x30,%esp + 800e6e: 8b 45 08 mov 0x8(%ebp),%eax + 800e71: 89 45 f0 mov %eax,-0x10(%ebp) + 800e74: 8b 45 0c mov 0xc(%ebp),%eax + 800e77: 89 45 ec mov %eax,-0x14(%ebp) + 800e7a: 8b 45 10 mov 0x10(%ebp),%eax + 800e7d: 89 45 e8 mov %eax,-0x18(%ebp) + +#ifndef __HAVE_ARCH_MEMMOVE +#define __HAVE_ARCH_MEMMOVE +static inline void * +__memmove(void *dst, const void *src, size_t n) { + if (dst < src) { + 800e80: 8b 45 f0 mov -0x10(%ebp),%eax + 800e83: 3b 45 ec cmp -0x14(%ebp),%eax + 800e86: 73 42 jae 800eca + 800e88: 8b 45 f0 mov -0x10(%ebp),%eax + 800e8b: 89 45 e4 mov %eax,-0x1c(%ebp) + 800e8e: 8b 45 ec mov -0x14(%ebp),%eax + 800e91: 89 45 e0 mov %eax,-0x20(%ebp) + 800e94: 8b 45 e8 mov -0x18(%ebp),%eax + 800e97: 89 45 dc mov %eax,-0x24(%ebp) + "andl $3, %%ecx;" + "jz 1f;" + "rep; movsb;" + "1:" + : "=&c" (d0), "=&D" (d1), "=&S" (d2) + : "0" (n / 4), "g" (n), "1" (dst), "2" (src) + 800e9a: 8b 45 dc mov -0x24(%ebp),%eax + 800e9d: c1 e8 02 shr $0x2,%eax + 800ea0: 89 c1 mov %eax,%ecx + asm volatile ( + 800ea2: 8b 55 e4 mov -0x1c(%ebp),%edx + 800ea5: 8b 45 e0 mov -0x20(%ebp),%eax + 800ea8: 89 d7 mov %edx,%edi + 800eaa: 89 c6 mov %eax,%esi + 800eac: f3 a5 rep movsl %ds:(%esi),%es:(%edi) + 800eae: 8b 4d dc mov -0x24(%ebp),%ecx + 800eb1: 83 e1 03 and $0x3,%ecx + 800eb4: 74 02 je 800eb8 + 800eb6: f3 a4 rep movsb %ds:(%esi),%es:(%edi) + 800eb8: 89 f0 mov %esi,%eax + 800eba: 89 fa mov %edi,%edx + 800ebc: 89 4d d8 mov %ecx,-0x28(%ebp) + 800ebf: 89 55 d4 mov %edx,-0x2c(%ebp) + 800ec2: 89 45 d0 mov %eax,-0x30(%ebp) + : "memory"); + return dst; + 800ec5: 8b 45 e4 mov -0x1c(%ebp),%eax + return __memcpy(dst, src, n); + 800ec8: eb 36 jmp 800f00 + : "0" (n), "1" (n - 1 + src), "2" (n - 1 + dst) + 800eca: 8b 45 e8 mov -0x18(%ebp),%eax + 800ecd: 8d 50 ff lea -0x1(%eax),%edx + 800ed0: 8b 45 ec mov -0x14(%ebp),%eax + 800ed3: 01 c2 add %eax,%edx + 800ed5: 8b 45 e8 mov -0x18(%ebp),%eax + 800ed8: 8d 48 ff lea -0x1(%eax),%ecx + 800edb: 8b 45 f0 mov -0x10(%ebp),%eax + 800ede: 8d 1c 01 lea (%ecx,%eax,1),%ebx + asm volatile ( + 800ee1: 8b 45 e8 mov -0x18(%ebp),%eax + 800ee4: 89 c1 mov %eax,%ecx + 800ee6: 89 d8 mov %ebx,%eax + 800ee8: 89 d6 mov %edx,%esi + 800eea: 89 c7 mov %eax,%edi + 800eec: fd std + 800eed: f3 a4 rep movsb %ds:(%esi),%es:(%edi) + 800eef: fc cld + 800ef0: 89 f8 mov %edi,%eax + 800ef2: 89 f2 mov %esi,%edx + 800ef4: 89 4d cc mov %ecx,-0x34(%ebp) + 800ef7: 89 55 c8 mov %edx,-0x38(%ebp) + 800efa: 89 45 c4 mov %eax,-0x3c(%ebp) + return dst; + 800efd: 8b 45 f0 mov -0x10(%ebp),%eax + *d ++ = *s ++; + } + } + return dst; +#endif /* __HAVE_ARCH_MEMMOVE */ +} + 800f00: 83 c4 30 add $0x30,%esp + 800f03: 5b pop %ebx + 800f04: 5e pop %esi + 800f05: 5f pop %edi + 800f06: 5d pop %ebp + 800f07: c3 ret + +00800f08 : + * it always copies exactly @n bytes. To avoid overflows, the size of arrays pointed + * by both @src and @dst, should be at least @n bytes, and should not overlap + * (for overlapping memory area, memmove is a safer approach). + * */ +void * +memcpy(void *dst, const void *src, size_t n) { + 800f08: 55 push %ebp + 800f09: 89 e5 mov %esp,%ebp + 800f0b: 57 push %edi + 800f0c: 56 push %esi + 800f0d: 83 ec 20 sub $0x20,%esp + 800f10: 8b 45 08 mov 0x8(%ebp),%eax + 800f13: 89 45 f4 mov %eax,-0xc(%ebp) + 800f16: 8b 45 0c mov 0xc(%ebp),%eax + 800f19: 89 45 f0 mov %eax,-0x10(%ebp) + 800f1c: 8b 45 10 mov 0x10(%ebp),%eax + 800f1f: 89 45 ec mov %eax,-0x14(%ebp) + : "0" (n / 4), "g" (n), "1" (dst), "2" (src) + 800f22: 8b 45 ec mov -0x14(%ebp),%eax + 800f25: c1 e8 02 shr $0x2,%eax + 800f28: 89 c1 mov %eax,%ecx + asm volatile ( + 800f2a: 8b 55 f4 mov -0xc(%ebp),%edx + 800f2d: 8b 45 f0 mov -0x10(%ebp),%eax + 800f30: 89 d7 mov %edx,%edi + 800f32: 89 c6 mov %eax,%esi + 800f34: f3 a5 rep movsl %ds:(%esi),%es:(%edi) + 800f36: 8b 4d ec mov -0x14(%ebp),%ecx + 800f39: 83 e1 03 and $0x3,%ecx + 800f3c: 74 02 je 800f40 + 800f3e: f3 a4 rep movsb %ds:(%esi),%es:(%edi) + 800f40: 89 f0 mov %esi,%eax + 800f42: 89 fa mov %edi,%edx + 800f44: 89 4d e8 mov %ecx,-0x18(%ebp) + 800f47: 89 55 e4 mov %edx,-0x1c(%ebp) + 800f4a: 89 45 e0 mov %eax,-0x20(%ebp) + return dst; + 800f4d: 8b 45 f4 mov -0xc(%ebp),%eax + while (n -- > 0) { + *d ++ = *s ++; + } + return dst; +#endif /* __HAVE_ARCH_MEMCPY */ +} + 800f50: 83 c4 20 add $0x20,%esp + 800f53: 5e pop %esi + 800f54: 5f pop %edi + 800f55: 5d pop %ebp + 800f56: c3 ret + +00800f57 : + * match in both memory blocks has a greater value in @v1 than in @v2 + * as if evaluated as unsigned char values; + * - And a value less than zero indicates the opposite. + * */ +int +memcmp(const void *v1, const void *v2, size_t n) { + 800f57: 55 push %ebp + 800f58: 89 e5 mov %esp,%ebp + 800f5a: 83 ec 10 sub $0x10,%esp + const char *s1 = (const char *)v1; + 800f5d: 8b 45 08 mov 0x8(%ebp),%eax + 800f60: 89 45 fc mov %eax,-0x4(%ebp) + const char *s2 = (const char *)v2; + 800f63: 8b 45 0c mov 0xc(%ebp),%eax + 800f66: 89 45 f8 mov %eax,-0x8(%ebp) + while (n -- > 0) { + 800f69: eb 2e jmp 800f99 + if (*s1 != *s2) { + 800f6b: 8b 45 fc mov -0x4(%ebp),%eax + 800f6e: 0f b6 10 movzbl (%eax),%edx + 800f71: 8b 45 f8 mov -0x8(%ebp),%eax + 800f74: 0f b6 00 movzbl (%eax),%eax + 800f77: 38 c2 cmp %al,%dl + 800f79: 74 18 je 800f93 + return (int)((unsigned char)*s1 - (unsigned char)*s2); + 800f7b: 8b 45 fc mov -0x4(%ebp),%eax + 800f7e: 0f b6 00 movzbl (%eax),%eax + 800f81: 0f b6 d0 movzbl %al,%edx + 800f84: 8b 45 f8 mov -0x8(%ebp),%eax + 800f87: 0f b6 00 movzbl (%eax),%eax + 800f8a: 0f b6 c8 movzbl %al,%ecx + 800f8d: 89 d0 mov %edx,%eax + 800f8f: 29 c8 sub %ecx,%eax + 800f91: eb 18 jmp 800fab + } + s1 ++, s2 ++; + 800f93: ff 45 fc incl -0x4(%ebp) + 800f96: ff 45 f8 incl -0x8(%ebp) + while (n -- > 0) { + 800f99: 8b 45 10 mov 0x10(%ebp),%eax + 800f9c: 8d 50 ff lea -0x1(%eax),%edx + 800f9f: 89 55 10 mov %edx,0x10(%ebp) + 800fa2: 85 c0 test %eax,%eax + 800fa4: 75 c5 jne 800f6b + } + return 0; + 800fa6: b8 00 00 00 00 mov $0x0,%eax +} + 800fab: 89 ec mov %ebp,%esp + 800fad: 5d pop %ebp + 800fae: c3 ret + +00800faf
: +#include + +/* try to load the kernel's TSS selector into the DS register */ + +int +main(void) { + 800faf: 55 push %ebp + 800fb0: 89 e5 mov %esp,%ebp + 800fb2: 83 e4 f0 and $0xfffffff0,%esp + 800fb5: 83 ec 10 sub $0x10,%esp + asm volatile("movw $0x28,%ax; movw %ax,%ds"); + 800fb8: 66 b8 28 00 mov $0x28,%ax + 800fbc: 8e d8 mov %eax,%ds + panic("FAIL: T.T\n"); + 800fbe: c7 44 24 08 c0 12 80 movl $0x8012c0,0x8(%esp) + 800fc5: 00 + 800fc6: c7 44 24 04 09 00 00 movl $0x9,0x4(%esp) + 800fcd: 00 + 800fce: c7 04 24 cb 12 80 00 movl $0x8012cb,(%esp) + 800fd5: e8 55 f0 ff ff call 80002f <__panic> diff --git a/labcodes/lab5/obj/user/badsegment.d b/labcodes/lab5/obj/user/badsegment.d new file mode 100644 index 0000000000000000000000000000000000000000..8dcc1d638c3f2d8ea3cc748e1c00c6b0a5a2a20b --- /dev/null +++ b/labcodes/lab5/obj/user/badsegment.d @@ -0,0 +1,2 @@ +obj/user/badsegment.o obj/user/badsegment.d: user/badsegment.c \ + libs/stdio.h libs/defs.h libs/stdarg.h user/libs/ulib.h diff --git a/labcodes/lab5/obj/user/badsegment.o b/labcodes/lab5/obj/user/badsegment.o new file mode 100644 index 0000000000000000000000000000000000000000..9bb76fda7896bad9d2b04cd484dc782eee520408 Binary files /dev/null and b/labcodes/lab5/obj/user/badsegment.o differ diff --git a/labcodes/lab5/obj/user/badsegment.sym b/labcodes/lab5/obj/user/badsegment.sym new file mode 100644 index 0000000000000000000000000000000000000000..dadbb2b639517e45fcc34b98dced5e4447b95e4d --- /dev/null +++ b/labcodes/lab5/obj/user/badsegment.sym @@ -0,0 +1,66 @@ +00000000 panic.c +00000000 stdio.c +008000c8 cputch +00000000 syscall.c +00800199 syscall +00000000 ulib.c +00000000 umain.c +00000000 hash.c +00000000 printfmt.c +008010e0 error_string +008003ad printnum +008004af getuint +008004fe getint +0080094f sprintputch +00000000 rand.c +00802000 next +00000000 string.c +00000000 badsegment.c +00800b53 strcpy +00800329 yield +0080030d waitpid +00800245 sys_yield +00800e65 memmove +00800985 snprintf +00800576 vprintfmt +0080020b sys_fork +00800120 cprintf +0080034e getpid +00800f08 memcpy +008009bb vsnprintf +0080036d umain +002026bc __STAB_END__ +0080025b sys_kill +002026bd __STABSTR_BEGIN__ +0080002f __panic +00800ccb strtol +00800b22 strnlen +0080035d print_pgdir +00800339 kill +00800c9b strfind +008002ef wait +00800020 _start +00800a21 rand +00800c14 strncmp +0080028e sys_putc +00800b92 strncpy +00800f57 memcmp +008002e0 fork +00800e23 memset +00800faf main +00800ae0 srand +00800386 hash32 +00800545 printfmt +002035cf __STABSTR_END__ +00800bcb strcmp +008000eb vcprintf +0080007f __warn +00800148 cputs +008002c1 exit +00800221 sys_wait +008001ee sys_exit +00200010 __STAB_BEGIN__ +00800af9 strlen +008002ab sys_pgdir +00800c67 strchr +00800278 sys_getpid diff --git a/labcodes/lab5/obj/user/divzero.asm b/labcodes/lab5/obj/user/divzero.asm new file mode 100644 index 0000000000000000000000000000000000000000..06480dd0d0ff2e493cf0655afbf59cdf9e2f8434 --- /dev/null +++ b/labcodes/lab5/obj/user/divzero.asm @@ -0,0 +1,2326 @@ + +obj/__user_divzero.out: file format elf32-i386 + + +Disassembly of section .text: + +00800020 <_start>: +.text +.globl _start +_start: + # set ebp for backtrace + movl $0x0, %ebp + 800020: bd 00 00 00 00 mov $0x0,%ebp + + # move down the esp register + # since it may cause page fault in backtrace + subl $0x20, %esp + 800025: 83 ec 20 sub $0x20,%esp + + # call user-program function + call umain + 800028: e8 40 03 00 00 call 80036d +1: jmp 1b + 80002d: eb fe jmp 80002d <_start+0xd> + +0080002f <__panic>: +#include +#include +#include + +void +__panic(const char *file, int line, const char *fmt, ...) { + 80002f: 55 push %ebp + 800030: 89 e5 mov %esp,%ebp + 800032: 83 ec 28 sub $0x28,%esp + // print the 'message' + va_list ap; + va_start(ap, fmt); + 800035: 8d 45 14 lea 0x14(%ebp),%eax + 800038: 89 45 f4 mov %eax,-0xc(%ebp) + cprintf("user panic at %s:%d:\n ", file, line); + 80003b: 8b 45 0c mov 0xc(%ebp),%eax + 80003e: 89 44 24 08 mov %eax,0x8(%esp) + 800042: 8b 45 08 mov 0x8(%ebp),%eax + 800045: 89 44 24 04 mov %eax,0x4(%esp) + 800049: c7 04 24 00 10 80 00 movl $0x801000,(%esp) + 800050: e8 cb 00 00 00 call 800120 + vcprintf(fmt, ap); + 800055: 8b 45 f4 mov -0xc(%ebp),%eax + 800058: 89 44 24 04 mov %eax,0x4(%esp) + 80005c: 8b 45 10 mov 0x10(%ebp),%eax + 80005f: 89 04 24 mov %eax,(%esp) + 800062: e8 84 00 00 00 call 8000eb + cprintf("\n"); + 800067: c7 04 24 1a 10 80 00 movl $0x80101a,(%esp) + 80006e: e8 ad 00 00 00 call 800120 + va_end(ap); + exit(-E_PANIC); + 800073: c7 04 24 f6 ff ff ff movl $0xfffffff6,(%esp) + 80007a: e8 42 02 00 00 call 8002c1 + +0080007f <__warn>: +} + +void +__warn(const char *file, int line, const char *fmt, ...) { + 80007f: 55 push %ebp + 800080: 89 e5 mov %esp,%ebp + 800082: 83 ec 28 sub $0x28,%esp + va_list ap; + va_start(ap, fmt); + 800085: 8d 45 14 lea 0x14(%ebp),%eax + 800088: 89 45 f4 mov %eax,-0xc(%ebp) + cprintf("user warning at %s:%d:\n ", file, line); + 80008b: 8b 45 0c mov 0xc(%ebp),%eax + 80008e: 89 44 24 08 mov %eax,0x8(%esp) + 800092: 8b 45 08 mov 0x8(%ebp),%eax + 800095: 89 44 24 04 mov %eax,0x4(%esp) + 800099: c7 04 24 1c 10 80 00 movl $0x80101c,(%esp) + 8000a0: e8 7b 00 00 00 call 800120 + vcprintf(fmt, ap); + 8000a5: 8b 45 f4 mov -0xc(%ebp),%eax + 8000a8: 89 44 24 04 mov %eax,0x4(%esp) + 8000ac: 8b 45 10 mov 0x10(%ebp),%eax + 8000af: 89 04 24 mov %eax,(%esp) + 8000b2: e8 34 00 00 00 call 8000eb + cprintf("\n"); + 8000b7: c7 04 24 1a 10 80 00 movl $0x80101a,(%esp) + 8000be: e8 5d 00 00 00 call 800120 + va_end(ap); +} + 8000c3: 90 nop + 8000c4: 89 ec mov %ebp,%esp + 8000c6: 5d pop %ebp + 8000c7: c3 ret + +008000c8 : +/* * + * cputch - writes a single character @c to stdout, and it will + * increace the value of counter pointed by @cnt. + * */ +static void +cputch(int c, int *cnt) { + 8000c8: 55 push %ebp + 8000c9: 89 e5 mov %esp,%ebp + 8000cb: 83 ec 18 sub $0x18,%esp + sys_putc(c); + 8000ce: 8b 45 08 mov 0x8(%ebp),%eax + 8000d1: 89 04 24 mov %eax,(%esp) + 8000d4: e8 b5 01 00 00 call 80028e + (*cnt) ++; + 8000d9: 8b 45 0c mov 0xc(%ebp),%eax + 8000dc: 8b 00 mov (%eax),%eax + 8000de: 8d 50 01 lea 0x1(%eax),%edx + 8000e1: 8b 45 0c mov 0xc(%ebp),%eax + 8000e4: 89 10 mov %edx,(%eax) +} + 8000e6: 90 nop + 8000e7: 89 ec mov %ebp,%esp + 8000e9: 5d pop %ebp + 8000ea: c3 ret + +008000eb : + * + * Call this function if you are already dealing with a va_list. + * Or you probably want cprintf() instead. + * */ +int +vcprintf(const char *fmt, va_list ap) { + 8000eb: 55 push %ebp + 8000ec: 89 e5 mov %esp,%ebp + 8000ee: 83 ec 28 sub $0x28,%esp + int cnt = 0; + 8000f1: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + vprintfmt((void*)cputch, &cnt, fmt, ap); + 8000f8: 8b 45 0c mov 0xc(%ebp),%eax + 8000fb: 89 44 24 0c mov %eax,0xc(%esp) + 8000ff: 8b 45 08 mov 0x8(%ebp),%eax + 800102: 89 44 24 08 mov %eax,0x8(%esp) + 800106: 8d 45 f4 lea -0xc(%ebp),%eax + 800109: 89 44 24 04 mov %eax,0x4(%esp) + 80010d: c7 04 24 c8 00 80 00 movl $0x8000c8,(%esp) + 800114: e8 5d 04 00 00 call 800576 + return cnt; + 800119: 8b 45 f4 mov -0xc(%ebp),%eax +} + 80011c: 89 ec mov %ebp,%esp + 80011e: 5d pop %ebp + 80011f: c3 ret + +00800120 : + * + * The return value is the number of characters which would be + * written to stdout. + * */ +int +cprintf(const char *fmt, ...) { + 800120: 55 push %ebp + 800121: 89 e5 mov %esp,%ebp + 800123: 83 ec 28 sub $0x28,%esp + va_list ap; + + va_start(ap, fmt); + 800126: 8d 45 0c lea 0xc(%ebp),%eax + 800129: 89 45 f0 mov %eax,-0x10(%ebp) + int cnt = vcprintf(fmt, ap); + 80012c: 8b 45 f0 mov -0x10(%ebp),%eax + 80012f: 89 44 24 04 mov %eax,0x4(%esp) + 800133: 8b 45 08 mov 0x8(%ebp),%eax + 800136: 89 04 24 mov %eax,(%esp) + 800139: e8 ad ff ff ff call 8000eb + 80013e: 89 45 f4 mov %eax,-0xc(%ebp) + va_end(ap); + + return cnt; + 800141: 8b 45 f4 mov -0xc(%ebp),%eax +} + 800144: 89 ec mov %ebp,%esp + 800146: 5d pop %ebp + 800147: c3 ret + +00800148 : +/* * + * cputs- writes the string pointed by @str to stdout and + * appends a newline character. + * */ +int +cputs(const char *str) { + 800148: 55 push %ebp + 800149: 89 e5 mov %esp,%ebp + 80014b: 83 ec 28 sub $0x28,%esp + int cnt = 0; + 80014e: c7 45 f0 00 00 00 00 movl $0x0,-0x10(%ebp) + char c; + while ((c = *str ++) != '\0') { + 800155: eb 13 jmp 80016a + cputch(c, &cnt); + 800157: 0f be 45 f7 movsbl -0x9(%ebp),%eax + 80015b: 8d 55 f0 lea -0x10(%ebp),%edx + 80015e: 89 54 24 04 mov %edx,0x4(%esp) + 800162: 89 04 24 mov %eax,(%esp) + 800165: e8 5e ff ff ff call 8000c8 + while ((c = *str ++) != '\0') { + 80016a: 8b 45 08 mov 0x8(%ebp),%eax + 80016d: 8d 50 01 lea 0x1(%eax),%edx + 800170: 89 55 08 mov %edx,0x8(%ebp) + 800173: 0f b6 00 movzbl (%eax),%eax + 800176: 88 45 f7 mov %al,-0x9(%ebp) + 800179: 80 7d f7 00 cmpb $0x0,-0x9(%ebp) + 80017d: 75 d8 jne 800157 + } + cputch('\n', &cnt); + 80017f: 8d 45 f0 lea -0x10(%ebp),%eax + 800182: 89 44 24 04 mov %eax,0x4(%esp) + 800186: c7 04 24 0a 00 00 00 movl $0xa,(%esp) + 80018d: e8 36 ff ff ff call 8000c8 + return cnt; + 800192: 8b 45 f0 mov -0x10(%ebp),%eax +} + 800195: 89 ec mov %ebp,%esp + 800197: 5d pop %ebp + 800198: c3 ret + +00800199 : +#include + +#define MAX_ARGS 5 + +static inline int +syscall(int num, ...) { + 800199: 55 push %ebp + 80019a: 89 e5 mov %esp,%ebp + 80019c: 57 push %edi + 80019d: 56 push %esi + 80019e: 53 push %ebx + 80019f: 83 ec 20 sub $0x20,%esp + va_list ap; + va_start(ap, num); + 8001a2: 8d 45 0c lea 0xc(%ebp),%eax + 8001a5: 89 45 e8 mov %eax,-0x18(%ebp) + uint32_t a[MAX_ARGS]; + int i, ret; + for (i = 0; i < MAX_ARGS; i ++) { + 8001a8: c7 45 f0 00 00 00 00 movl $0x0,-0x10(%ebp) + 8001af: eb 15 jmp 8001c6 + a[i] = va_arg(ap, uint32_t); + 8001b1: 8b 45 e8 mov -0x18(%ebp),%eax + 8001b4: 8d 50 04 lea 0x4(%eax),%edx + 8001b7: 89 55 e8 mov %edx,-0x18(%ebp) + 8001ba: 8b 10 mov (%eax),%edx + 8001bc: 8b 45 f0 mov -0x10(%ebp),%eax + 8001bf: 89 54 85 d4 mov %edx,-0x2c(%ebp,%eax,4) + for (i = 0; i < MAX_ARGS; i ++) { + 8001c3: ff 45 f0 incl -0x10(%ebp) + 8001c6: 83 7d f0 04 cmpl $0x4,-0x10(%ebp) + 8001ca: 7e e5 jle 8001b1 + asm volatile ( + "int %1;" + : "=a" (ret) + : "i" (T_SYSCALL), + "a" (num), + "d" (a[0]), + 8001cc: 8b 55 d4 mov -0x2c(%ebp),%edx + "c" (a[1]), + 8001cf: 8b 4d d8 mov -0x28(%ebp),%ecx + "b" (a[2]), + 8001d2: 8b 5d dc mov -0x24(%ebp),%ebx + "D" (a[3]), + 8001d5: 8b 7d e0 mov -0x20(%ebp),%edi + "S" (a[4]) + 8001d8: 8b 75 e4 mov -0x1c(%ebp),%esi + asm volatile ( + 8001db: 8b 45 08 mov 0x8(%ebp),%eax + 8001de: cd 80 int $0x80 + 8001e0: 89 45 ec mov %eax,-0x14(%ebp) + : "cc", "memory"); + return ret; + 8001e3: 8b 45 ec mov -0x14(%ebp),%eax +} + 8001e6: 83 c4 20 add $0x20,%esp + 8001e9: 5b pop %ebx + 8001ea: 5e pop %esi + 8001eb: 5f pop %edi + 8001ec: 5d pop %ebp + 8001ed: c3 ret + +008001ee : + +int +sys_exit(int error_code) { + 8001ee: 55 push %ebp + 8001ef: 89 e5 mov %esp,%ebp + 8001f1: 83 ec 08 sub $0x8,%esp + return syscall(SYS_exit, error_code); + 8001f4: 8b 45 08 mov 0x8(%ebp),%eax + 8001f7: 89 44 24 04 mov %eax,0x4(%esp) + 8001fb: c7 04 24 01 00 00 00 movl $0x1,(%esp) + 800202: e8 92 ff ff ff call 800199 +} + 800207: 89 ec mov %ebp,%esp + 800209: 5d pop %ebp + 80020a: c3 ret + +0080020b : + +int +sys_fork(void) { + 80020b: 55 push %ebp + 80020c: 89 e5 mov %esp,%ebp + 80020e: 83 ec 04 sub $0x4,%esp + return syscall(SYS_fork); + 800211: c7 04 24 02 00 00 00 movl $0x2,(%esp) + 800218: e8 7c ff ff ff call 800199 +} + 80021d: 89 ec mov %ebp,%esp + 80021f: 5d pop %ebp + 800220: c3 ret + +00800221 : + +int +sys_wait(int pid, int *store) { + 800221: 55 push %ebp + 800222: 89 e5 mov %esp,%ebp + 800224: 83 ec 0c sub $0xc,%esp + return syscall(SYS_wait, pid, store); + 800227: 8b 45 0c mov 0xc(%ebp),%eax + 80022a: 89 44 24 08 mov %eax,0x8(%esp) + 80022e: 8b 45 08 mov 0x8(%ebp),%eax + 800231: 89 44 24 04 mov %eax,0x4(%esp) + 800235: c7 04 24 03 00 00 00 movl $0x3,(%esp) + 80023c: e8 58 ff ff ff call 800199 +} + 800241: 89 ec mov %ebp,%esp + 800243: 5d pop %ebp + 800244: c3 ret + +00800245 : + +int +sys_yield(void) { + 800245: 55 push %ebp + 800246: 89 e5 mov %esp,%ebp + 800248: 83 ec 04 sub $0x4,%esp + return syscall(SYS_yield); + 80024b: c7 04 24 0a 00 00 00 movl $0xa,(%esp) + 800252: e8 42 ff ff ff call 800199 +} + 800257: 89 ec mov %ebp,%esp + 800259: 5d pop %ebp + 80025a: c3 ret + +0080025b : + +int +sys_kill(int pid) { + 80025b: 55 push %ebp + 80025c: 89 e5 mov %esp,%ebp + 80025e: 83 ec 08 sub $0x8,%esp + return syscall(SYS_kill, pid); + 800261: 8b 45 08 mov 0x8(%ebp),%eax + 800264: 89 44 24 04 mov %eax,0x4(%esp) + 800268: c7 04 24 0c 00 00 00 movl $0xc,(%esp) + 80026f: e8 25 ff ff ff call 800199 +} + 800274: 89 ec mov %ebp,%esp + 800276: 5d pop %ebp + 800277: c3 ret + +00800278 : + +int +sys_getpid(void) { + 800278: 55 push %ebp + 800279: 89 e5 mov %esp,%ebp + 80027b: 83 ec 04 sub $0x4,%esp + return syscall(SYS_getpid); + 80027e: c7 04 24 12 00 00 00 movl $0x12,(%esp) + 800285: e8 0f ff ff ff call 800199 +} + 80028a: 89 ec mov %ebp,%esp + 80028c: 5d pop %ebp + 80028d: c3 ret + +0080028e : + +int +sys_putc(int c) { + 80028e: 55 push %ebp + 80028f: 89 e5 mov %esp,%ebp + 800291: 83 ec 08 sub $0x8,%esp + return syscall(SYS_putc, c); + 800294: 8b 45 08 mov 0x8(%ebp),%eax + 800297: 89 44 24 04 mov %eax,0x4(%esp) + 80029b: c7 04 24 1e 00 00 00 movl $0x1e,(%esp) + 8002a2: e8 f2 fe ff ff call 800199 +} + 8002a7: 89 ec mov %ebp,%esp + 8002a9: 5d pop %ebp + 8002aa: c3 ret + +008002ab : + +int +sys_pgdir(void) { + 8002ab: 55 push %ebp + 8002ac: 89 e5 mov %esp,%ebp + 8002ae: 83 ec 04 sub $0x4,%esp + return syscall(SYS_pgdir); + 8002b1: c7 04 24 1f 00 00 00 movl $0x1f,(%esp) + 8002b8: e8 dc fe ff ff call 800199 +} + 8002bd: 89 ec mov %ebp,%esp + 8002bf: 5d pop %ebp + 8002c0: c3 ret + +008002c1 : +#include +#include +#include + +void +exit(int error_code) { + 8002c1: 55 push %ebp + 8002c2: 89 e5 mov %esp,%ebp + 8002c4: 83 ec 18 sub $0x18,%esp + sys_exit(error_code); + 8002c7: 8b 45 08 mov 0x8(%ebp),%eax + 8002ca: 89 04 24 mov %eax,(%esp) + 8002cd: e8 1c ff ff ff call 8001ee + cprintf("BUG: exit failed.\n"); + 8002d2: c7 04 24 38 10 80 00 movl $0x801038,(%esp) + 8002d9: e8 42 fe ff ff call 800120 + while (1); + 8002de: eb fe jmp 8002de + +008002e0 : +} + +int +fork(void) { + 8002e0: 55 push %ebp + 8002e1: 89 e5 mov %esp,%ebp + 8002e3: 83 ec 08 sub $0x8,%esp + return sys_fork(); + 8002e6: e8 20 ff ff ff call 80020b +} + 8002eb: 89 ec mov %ebp,%esp + 8002ed: 5d pop %ebp + 8002ee: c3 ret + +008002ef : + +int +wait(void) { + 8002ef: 55 push %ebp + 8002f0: 89 e5 mov %esp,%ebp + 8002f2: 83 ec 18 sub $0x18,%esp + return sys_wait(0, NULL); + 8002f5: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) + 8002fc: 00 + 8002fd: c7 04 24 00 00 00 00 movl $0x0,(%esp) + 800304: e8 18 ff ff ff call 800221 +} + 800309: 89 ec mov %ebp,%esp + 80030b: 5d pop %ebp + 80030c: c3 ret + +0080030d : + +int +waitpid(int pid, int *store) { + 80030d: 55 push %ebp + 80030e: 89 e5 mov %esp,%ebp + 800310: 83 ec 18 sub $0x18,%esp + return sys_wait(pid, store); + 800313: 8b 45 0c mov 0xc(%ebp),%eax + 800316: 89 44 24 04 mov %eax,0x4(%esp) + 80031a: 8b 45 08 mov 0x8(%ebp),%eax + 80031d: 89 04 24 mov %eax,(%esp) + 800320: e8 fc fe ff ff call 800221 +} + 800325: 89 ec mov %ebp,%esp + 800327: 5d pop %ebp + 800328: c3 ret + +00800329 : + +void +yield(void) { + 800329: 55 push %ebp + 80032a: 89 e5 mov %esp,%ebp + 80032c: 83 ec 08 sub $0x8,%esp + sys_yield(); + 80032f: e8 11 ff ff ff call 800245 +} + 800334: 90 nop + 800335: 89 ec mov %ebp,%esp + 800337: 5d pop %ebp + 800338: c3 ret + +00800339 : + +int +kill(int pid) { + 800339: 55 push %ebp + 80033a: 89 e5 mov %esp,%ebp + 80033c: 83 ec 18 sub $0x18,%esp + return sys_kill(pid); + 80033f: 8b 45 08 mov 0x8(%ebp),%eax + 800342: 89 04 24 mov %eax,(%esp) + 800345: e8 11 ff ff ff call 80025b +} + 80034a: 89 ec mov %ebp,%esp + 80034c: 5d pop %ebp + 80034d: c3 ret + +0080034e : + +int +getpid(void) { + 80034e: 55 push %ebp + 80034f: 89 e5 mov %esp,%ebp + 800351: 83 ec 08 sub $0x8,%esp + return sys_getpid(); + 800354: e8 1f ff ff ff call 800278 +} + 800359: 89 ec mov %ebp,%esp + 80035b: 5d pop %ebp + 80035c: c3 ret + +0080035d : + +//print_pgdir - print the PDT&PT +void +print_pgdir(void) { + 80035d: 55 push %ebp + 80035e: 89 e5 mov %esp,%ebp + 800360: 83 ec 08 sub $0x8,%esp + sys_pgdir(); + 800363: e8 43 ff ff ff call 8002ab +} + 800368: 90 nop + 800369: 89 ec mov %ebp,%esp + 80036b: 5d pop %ebp + 80036c: c3 ret + +0080036d : +#include + +int main(void); + +void +umain(void) { + 80036d: 55 push %ebp + 80036e: 89 e5 mov %esp,%ebp + 800370: 83 ec 28 sub $0x28,%esp + int ret = main(); + 800373: e8 37 0c 00 00 call 800faf
+ 800378: 89 45 f4 mov %eax,-0xc(%ebp) + exit(ret); + 80037b: 8b 45 f4 mov -0xc(%ebp),%eax + 80037e: 89 04 24 mov %eax,(%esp) + 800381: e8 3b ff ff ff call 8002c1 + +00800386 : + * @bits: the number of bits in a return value + * + * High bits are more random, so we use them. + * */ +uint32_t +hash32(uint32_t val, unsigned int bits) { + 800386: 55 push %ebp + 800387: 89 e5 mov %esp,%ebp + 800389: 83 ec 10 sub $0x10,%esp + uint32_t hash = val * GOLDEN_RATIO_PRIME_32; + 80038c: 8b 45 08 mov 0x8(%ebp),%eax + 80038f: 69 c0 01 00 37 9e imul $0x9e370001,%eax,%eax + 800395: 89 45 fc mov %eax,-0x4(%ebp) + return (hash >> (32 - bits)); + 800398: b8 20 00 00 00 mov $0x20,%eax + 80039d: 2b 45 0c sub 0xc(%ebp),%eax + 8003a0: 8b 55 fc mov -0x4(%ebp),%edx + 8003a3: 88 c1 mov %al,%cl + 8003a5: d3 ea shr %cl,%edx + 8003a7: 89 d0 mov %edx,%eax +} + 8003a9: 89 ec mov %ebp,%esp + 8003ab: 5d pop %ebp + 8003ac: c3 ret + +008003ad : + * @width: maximum number of digits, if the actual width is less than @width, use @padc instead + * @padc: character that padded on the left if the actual width is less than @width + * */ +static void +printnum(void (*putch)(int, void*), void *putdat, + unsigned long long num, unsigned base, int width, int padc) { + 8003ad: 55 push %ebp + 8003ae: 89 e5 mov %esp,%ebp + 8003b0: 83 ec 58 sub $0x58,%esp + 8003b3: 8b 45 10 mov 0x10(%ebp),%eax + 8003b6: 89 45 d0 mov %eax,-0x30(%ebp) + 8003b9: 8b 45 14 mov 0x14(%ebp),%eax + 8003bc: 89 45 d4 mov %eax,-0x2c(%ebp) + unsigned long long result = num; + 8003bf: 8b 45 d0 mov -0x30(%ebp),%eax + 8003c2: 8b 55 d4 mov -0x2c(%ebp),%edx + 8003c5: 89 45 e8 mov %eax,-0x18(%ebp) + 8003c8: 89 55 ec mov %edx,-0x14(%ebp) + unsigned mod = do_div(result, base); + 8003cb: 8b 45 18 mov 0x18(%ebp),%eax + 8003ce: 89 45 e4 mov %eax,-0x1c(%ebp) + 8003d1: 8b 45 e8 mov -0x18(%ebp),%eax + 8003d4: 8b 55 ec mov -0x14(%ebp),%edx + 8003d7: 89 45 e0 mov %eax,-0x20(%ebp) + 8003da: 89 55 f0 mov %edx,-0x10(%ebp) + 8003dd: 8b 45 f0 mov -0x10(%ebp),%eax + 8003e0: 89 45 f4 mov %eax,-0xc(%ebp) + 8003e3: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) + 8003e7: 74 1c je 800405 + 8003e9: 8b 45 f0 mov -0x10(%ebp),%eax + 8003ec: ba 00 00 00 00 mov $0x0,%edx + 8003f1: f7 75 e4 divl -0x1c(%ebp) + 8003f4: 89 55 f4 mov %edx,-0xc(%ebp) + 8003f7: 8b 45 f0 mov -0x10(%ebp),%eax + 8003fa: ba 00 00 00 00 mov $0x0,%edx + 8003ff: f7 75 e4 divl -0x1c(%ebp) + 800402: 89 45 f0 mov %eax,-0x10(%ebp) + 800405: 8b 45 e0 mov -0x20(%ebp),%eax + 800408: 8b 55 f4 mov -0xc(%ebp),%edx + 80040b: f7 75 e4 divl -0x1c(%ebp) + 80040e: 89 45 e0 mov %eax,-0x20(%ebp) + 800411: 89 55 dc mov %edx,-0x24(%ebp) + 800414: 8b 45 e0 mov -0x20(%ebp),%eax + 800417: 8b 55 f0 mov -0x10(%ebp),%edx + 80041a: 89 45 e8 mov %eax,-0x18(%ebp) + 80041d: 89 55 ec mov %edx,-0x14(%ebp) + 800420: 8b 45 dc mov -0x24(%ebp),%eax + 800423: 89 45 d8 mov %eax,-0x28(%ebp) + + // first recursively print all preceding (more significant) digits + if (num >= base) { + 800426: 8b 45 18 mov 0x18(%ebp),%eax + 800429: ba 00 00 00 00 mov $0x0,%edx + 80042e: 8b 4d d4 mov -0x2c(%ebp),%ecx + 800431: 39 45 d0 cmp %eax,-0x30(%ebp) + 800434: 19 d1 sbb %edx,%ecx + 800436: 72 4c jb 800484 + printnum(putch, putdat, result, base, width - 1, padc); + 800438: 8b 45 1c mov 0x1c(%ebp),%eax + 80043b: 8d 50 ff lea -0x1(%eax),%edx + 80043e: 8b 45 20 mov 0x20(%ebp),%eax + 800441: 89 44 24 18 mov %eax,0x18(%esp) + 800445: 89 54 24 14 mov %edx,0x14(%esp) + 800449: 8b 45 18 mov 0x18(%ebp),%eax + 80044c: 89 44 24 10 mov %eax,0x10(%esp) + 800450: 8b 45 e8 mov -0x18(%ebp),%eax + 800453: 8b 55 ec mov -0x14(%ebp),%edx + 800456: 89 44 24 08 mov %eax,0x8(%esp) + 80045a: 89 54 24 0c mov %edx,0xc(%esp) + 80045e: 8b 45 0c mov 0xc(%ebp),%eax + 800461: 89 44 24 04 mov %eax,0x4(%esp) + 800465: 8b 45 08 mov 0x8(%ebp),%eax + 800468: 89 04 24 mov %eax,(%esp) + 80046b: e8 3d ff ff ff call 8003ad + 800470: eb 1b jmp 80048d + } else { + // print any needed pad characters before first digit + while (-- width > 0) + putch(padc, putdat); + 800472: 8b 45 0c mov 0xc(%ebp),%eax + 800475: 89 44 24 04 mov %eax,0x4(%esp) + 800479: 8b 45 20 mov 0x20(%ebp),%eax + 80047c: 89 04 24 mov %eax,(%esp) + 80047f: 8b 45 08 mov 0x8(%ebp),%eax + 800482: ff d0 call *%eax + while (-- width > 0) + 800484: ff 4d 1c decl 0x1c(%ebp) + 800487: 83 7d 1c 00 cmpl $0x0,0x1c(%ebp) + 80048b: 7f e5 jg 800472 + } + // then print this (the least significant) digit + putch("0123456789abcdef"[mod], putdat); + 80048d: 8b 45 d8 mov -0x28(%ebp),%eax + 800490: 05 64 11 80 00 add $0x801164,%eax + 800495: 0f b6 00 movzbl (%eax),%eax + 800498: 0f be c0 movsbl %al,%eax + 80049b: 8b 55 0c mov 0xc(%ebp),%edx + 80049e: 89 54 24 04 mov %edx,0x4(%esp) + 8004a2: 89 04 24 mov %eax,(%esp) + 8004a5: 8b 45 08 mov 0x8(%ebp),%eax + 8004a8: ff d0 call *%eax +} + 8004aa: 90 nop + 8004ab: 89 ec mov %ebp,%esp + 8004ad: 5d pop %ebp + 8004ae: c3 ret + +008004af : + * getuint - get an unsigned int of various possible sizes from a varargs list + * @ap: a varargs list pointer + * @lflag: determines the size of the vararg that @ap points to + * */ +static unsigned long long +getuint(va_list *ap, int lflag) { + 8004af: 55 push %ebp + 8004b0: 89 e5 mov %esp,%ebp + if (lflag >= 2) { + 8004b2: 83 7d 0c 01 cmpl $0x1,0xc(%ebp) + 8004b6: 7e 14 jle 8004cc + return va_arg(*ap, unsigned long long); + 8004b8: 8b 45 08 mov 0x8(%ebp),%eax + 8004bb: 8b 00 mov (%eax),%eax + 8004bd: 8d 48 08 lea 0x8(%eax),%ecx + 8004c0: 8b 55 08 mov 0x8(%ebp),%edx + 8004c3: 89 0a mov %ecx,(%edx) + 8004c5: 8b 50 04 mov 0x4(%eax),%edx + 8004c8: 8b 00 mov (%eax),%eax + 8004ca: eb 30 jmp 8004fc + } + else if (lflag) { + 8004cc: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) + 8004d0: 74 16 je 8004e8 + return va_arg(*ap, unsigned long); + 8004d2: 8b 45 08 mov 0x8(%ebp),%eax + 8004d5: 8b 00 mov (%eax),%eax + 8004d7: 8d 48 04 lea 0x4(%eax),%ecx + 8004da: 8b 55 08 mov 0x8(%ebp),%edx + 8004dd: 89 0a mov %ecx,(%edx) + 8004df: 8b 00 mov (%eax),%eax + 8004e1: ba 00 00 00 00 mov $0x0,%edx + 8004e6: eb 14 jmp 8004fc + } + else { + return va_arg(*ap, unsigned int); + 8004e8: 8b 45 08 mov 0x8(%ebp),%eax + 8004eb: 8b 00 mov (%eax),%eax + 8004ed: 8d 48 04 lea 0x4(%eax),%ecx + 8004f0: 8b 55 08 mov 0x8(%ebp),%edx + 8004f3: 89 0a mov %ecx,(%edx) + 8004f5: 8b 00 mov (%eax),%eax + 8004f7: ba 00 00 00 00 mov $0x0,%edx + } +} + 8004fc: 5d pop %ebp + 8004fd: c3 ret + +008004fe : + * getint - same as getuint but signed, we can't use getuint because of sign extension + * @ap: a varargs list pointer + * @lflag: determines the size of the vararg that @ap points to + * */ +static long long +getint(va_list *ap, int lflag) { + 8004fe: 55 push %ebp + 8004ff: 89 e5 mov %esp,%ebp + if (lflag >= 2) { + 800501: 83 7d 0c 01 cmpl $0x1,0xc(%ebp) + 800505: 7e 14 jle 80051b + return va_arg(*ap, long long); + 800507: 8b 45 08 mov 0x8(%ebp),%eax + 80050a: 8b 00 mov (%eax),%eax + 80050c: 8d 48 08 lea 0x8(%eax),%ecx + 80050f: 8b 55 08 mov 0x8(%ebp),%edx + 800512: 89 0a mov %ecx,(%edx) + 800514: 8b 50 04 mov 0x4(%eax),%edx + 800517: 8b 00 mov (%eax),%eax + 800519: eb 28 jmp 800543 + } + else if (lflag) { + 80051b: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) + 80051f: 74 12 je 800533 + return va_arg(*ap, long); + 800521: 8b 45 08 mov 0x8(%ebp),%eax + 800524: 8b 00 mov (%eax),%eax + 800526: 8d 48 04 lea 0x4(%eax),%ecx + 800529: 8b 55 08 mov 0x8(%ebp),%edx + 80052c: 89 0a mov %ecx,(%edx) + 80052e: 8b 00 mov (%eax),%eax + 800530: 99 cltd + 800531: eb 10 jmp 800543 + } + else { + return va_arg(*ap, int); + 800533: 8b 45 08 mov 0x8(%ebp),%eax + 800536: 8b 00 mov (%eax),%eax + 800538: 8d 48 04 lea 0x4(%eax),%ecx + 80053b: 8b 55 08 mov 0x8(%ebp),%edx + 80053e: 89 0a mov %ecx,(%edx) + 800540: 8b 00 mov (%eax),%eax + 800542: 99 cltd + } +} + 800543: 5d pop %ebp + 800544: c3 ret + +00800545 : + * @putch: specified putch function, print a single character + * @putdat: used by @putch function + * @fmt: the format string to use + * */ +void +printfmt(void (*putch)(int, void*), void *putdat, const char *fmt, ...) { + 800545: 55 push %ebp + 800546: 89 e5 mov %esp,%ebp + 800548: 83 ec 28 sub $0x28,%esp + va_list ap; + + va_start(ap, fmt); + 80054b: 8d 45 14 lea 0x14(%ebp),%eax + 80054e: 89 45 f4 mov %eax,-0xc(%ebp) + vprintfmt(putch, putdat, fmt, ap); + 800551: 8b 45 f4 mov -0xc(%ebp),%eax + 800554: 89 44 24 0c mov %eax,0xc(%esp) + 800558: 8b 45 10 mov 0x10(%ebp),%eax + 80055b: 89 44 24 08 mov %eax,0x8(%esp) + 80055f: 8b 45 0c mov 0xc(%ebp),%eax + 800562: 89 44 24 04 mov %eax,0x4(%esp) + 800566: 8b 45 08 mov 0x8(%ebp),%eax + 800569: 89 04 24 mov %eax,(%esp) + 80056c: e8 05 00 00 00 call 800576 + va_end(ap); +} + 800571: 90 nop + 800572: 89 ec mov %ebp,%esp + 800574: 5d pop %ebp + 800575: c3 ret + +00800576 : + * + * Call this function if you are already dealing with a va_list. + * Or you probably want printfmt() instead. + * */ +void +vprintfmt(void (*putch)(int, void*), void *putdat, const char *fmt, va_list ap) { + 800576: 55 push %ebp + 800577: 89 e5 mov %esp,%ebp + 800579: 56 push %esi + 80057a: 53 push %ebx + 80057b: 83 ec 40 sub $0x40,%esp + register int ch, err; + unsigned long long num; + int base, width, precision, lflag, altflag; + + while (1) { + while ((ch = *(unsigned char *)fmt ++) != '%') { + 80057e: eb 17 jmp 800597 + if (ch == '\0') { + 800580: 85 db test %ebx,%ebx + 800582: 0f 84 bf 03 00 00 je 800947 + return; + } + putch(ch, putdat); + 800588: 8b 45 0c mov 0xc(%ebp),%eax + 80058b: 89 44 24 04 mov %eax,0x4(%esp) + 80058f: 89 1c 24 mov %ebx,(%esp) + 800592: 8b 45 08 mov 0x8(%ebp),%eax + 800595: ff d0 call *%eax + while ((ch = *(unsigned char *)fmt ++) != '%') { + 800597: 8b 45 10 mov 0x10(%ebp),%eax + 80059a: 8d 50 01 lea 0x1(%eax),%edx + 80059d: 89 55 10 mov %edx,0x10(%ebp) + 8005a0: 0f b6 00 movzbl (%eax),%eax + 8005a3: 0f b6 d8 movzbl %al,%ebx + 8005a6: 83 fb 25 cmp $0x25,%ebx + 8005a9: 75 d5 jne 800580 + } + + // Process a %-escape sequence + char padc = ' '; + 8005ab: c6 45 db 20 movb $0x20,-0x25(%ebp) + width = precision = -1; + 8005af: c7 45 e4 ff ff ff ff movl $0xffffffff,-0x1c(%ebp) + 8005b6: 8b 45 e4 mov -0x1c(%ebp),%eax + 8005b9: 89 45 e8 mov %eax,-0x18(%ebp) + lflag = altflag = 0; + 8005bc: c7 45 dc 00 00 00 00 movl $0x0,-0x24(%ebp) + 8005c3: 8b 45 dc mov -0x24(%ebp),%eax + 8005c6: 89 45 e0 mov %eax,-0x20(%ebp) + + reswitch: + switch (ch = *(unsigned char *)fmt ++) { + 8005c9: 8b 45 10 mov 0x10(%ebp),%eax + 8005cc: 8d 50 01 lea 0x1(%eax),%edx + 8005cf: 89 55 10 mov %edx,0x10(%ebp) + 8005d2: 0f b6 00 movzbl (%eax),%eax + 8005d5: 0f b6 d8 movzbl %al,%ebx + 8005d8: 8d 43 dd lea -0x23(%ebx),%eax + 8005db: 83 f8 55 cmp $0x55,%eax + 8005de: 0f 87 37 03 00 00 ja 80091b + 8005e4: 8b 04 85 88 11 80 00 mov 0x801188(,%eax,4),%eax + 8005eb: ff e0 jmp *%eax + + // flag to pad on the right + case '-': + padc = '-'; + 8005ed: c6 45 db 2d movb $0x2d,-0x25(%ebp) + goto reswitch; + 8005f1: eb d6 jmp 8005c9 + + // flag to pad with 0's instead of spaces + case '0': + padc = '0'; + 8005f3: c6 45 db 30 movb $0x30,-0x25(%ebp) + goto reswitch; + 8005f7: eb d0 jmp 8005c9 + + // width field + case '1' ... '9': + for (precision = 0; ; ++ fmt) { + 8005f9: c7 45 e4 00 00 00 00 movl $0x0,-0x1c(%ebp) + precision = precision * 10 + ch - '0'; + 800600: 8b 55 e4 mov -0x1c(%ebp),%edx + 800603: 89 d0 mov %edx,%eax + 800605: c1 e0 02 shl $0x2,%eax + 800608: 01 d0 add %edx,%eax + 80060a: 01 c0 add %eax,%eax + 80060c: 01 d8 add %ebx,%eax + 80060e: 83 e8 30 sub $0x30,%eax + 800611: 89 45 e4 mov %eax,-0x1c(%ebp) + ch = *fmt; + 800614: 8b 45 10 mov 0x10(%ebp),%eax + 800617: 0f b6 00 movzbl (%eax),%eax + 80061a: 0f be d8 movsbl %al,%ebx + if (ch < '0' || ch > '9') { + 80061d: 83 fb 2f cmp $0x2f,%ebx + 800620: 7e 38 jle 80065a + 800622: 83 fb 39 cmp $0x39,%ebx + 800625: 7f 33 jg 80065a + for (precision = 0; ; ++ fmt) { + 800627: ff 45 10 incl 0x10(%ebp) + precision = precision * 10 + ch - '0'; + 80062a: eb d4 jmp 800600 + } + } + goto process_precision; + + case '*': + precision = va_arg(ap, int); + 80062c: 8b 45 14 mov 0x14(%ebp),%eax + 80062f: 8d 50 04 lea 0x4(%eax),%edx + 800632: 89 55 14 mov %edx,0x14(%ebp) + 800635: 8b 00 mov (%eax),%eax + 800637: 89 45 e4 mov %eax,-0x1c(%ebp) + goto process_precision; + 80063a: eb 1f jmp 80065b + + case '.': + if (width < 0) + 80063c: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 800640: 79 87 jns 8005c9 + width = 0; + 800642: c7 45 e8 00 00 00 00 movl $0x0,-0x18(%ebp) + goto reswitch; + 800649: e9 7b ff ff ff jmp 8005c9 + + case '#': + altflag = 1; + 80064e: c7 45 dc 01 00 00 00 movl $0x1,-0x24(%ebp) + goto reswitch; + 800655: e9 6f ff ff ff jmp 8005c9 + goto process_precision; + 80065a: 90 nop + + process_precision: + if (width < 0) + 80065b: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 80065f: 0f 89 64 ff ff ff jns 8005c9 + width = precision, precision = -1; + 800665: 8b 45 e4 mov -0x1c(%ebp),%eax + 800668: 89 45 e8 mov %eax,-0x18(%ebp) + 80066b: c7 45 e4 ff ff ff ff movl $0xffffffff,-0x1c(%ebp) + goto reswitch; + 800672: e9 52 ff ff ff jmp 8005c9 + + // long flag (doubled for long long) + case 'l': + lflag ++; + 800677: ff 45 e0 incl -0x20(%ebp) + goto reswitch; + 80067a: e9 4a ff ff ff jmp 8005c9 + + // character + case 'c': + putch(va_arg(ap, int), putdat); + 80067f: 8b 45 14 mov 0x14(%ebp),%eax + 800682: 8d 50 04 lea 0x4(%eax),%edx + 800685: 89 55 14 mov %edx,0x14(%ebp) + 800688: 8b 00 mov (%eax),%eax + 80068a: 8b 55 0c mov 0xc(%ebp),%edx + 80068d: 89 54 24 04 mov %edx,0x4(%esp) + 800691: 89 04 24 mov %eax,(%esp) + 800694: 8b 45 08 mov 0x8(%ebp),%eax + 800697: ff d0 call *%eax + break; + 800699: e9 a4 02 00 00 jmp 800942 + + // error message + case 'e': + err = va_arg(ap, int); + 80069e: 8b 45 14 mov 0x14(%ebp),%eax + 8006a1: 8d 50 04 lea 0x4(%eax),%edx + 8006a4: 89 55 14 mov %edx,0x14(%ebp) + 8006a7: 8b 18 mov (%eax),%ebx + if (err < 0) { + 8006a9: 85 db test %ebx,%ebx + 8006ab: 79 02 jns 8006af + err = -err; + 8006ad: f7 db neg %ebx + } + if (err > MAXERROR || (p = error_string[err]) == NULL) { + 8006af: 83 fb 18 cmp $0x18,%ebx + 8006b2: 7f 0b jg 8006bf + 8006b4: 8b 34 9d 00 11 80 00 mov 0x801100(,%ebx,4),%esi + 8006bb: 85 f6 test %esi,%esi + 8006bd: 75 23 jne 8006e2 + printfmt(putch, putdat, "error %d", err); + 8006bf: 89 5c 24 0c mov %ebx,0xc(%esp) + 8006c3: c7 44 24 08 75 11 80 movl $0x801175,0x8(%esp) + 8006ca: 00 + 8006cb: 8b 45 0c mov 0xc(%ebp),%eax + 8006ce: 89 44 24 04 mov %eax,0x4(%esp) + 8006d2: 8b 45 08 mov 0x8(%ebp),%eax + 8006d5: 89 04 24 mov %eax,(%esp) + 8006d8: e8 68 fe ff ff call 800545 + } + else { + printfmt(putch, putdat, "%s", p); + } + break; + 8006dd: e9 60 02 00 00 jmp 800942 + printfmt(putch, putdat, "%s", p); + 8006e2: 89 74 24 0c mov %esi,0xc(%esp) + 8006e6: c7 44 24 08 7e 11 80 movl $0x80117e,0x8(%esp) + 8006ed: 00 + 8006ee: 8b 45 0c mov 0xc(%ebp),%eax + 8006f1: 89 44 24 04 mov %eax,0x4(%esp) + 8006f5: 8b 45 08 mov 0x8(%ebp),%eax + 8006f8: 89 04 24 mov %eax,(%esp) + 8006fb: e8 45 fe ff ff call 800545 + break; + 800700: e9 3d 02 00 00 jmp 800942 + + // string + case 's': + if ((p = va_arg(ap, char *)) == NULL) { + 800705: 8b 45 14 mov 0x14(%ebp),%eax + 800708: 8d 50 04 lea 0x4(%eax),%edx + 80070b: 89 55 14 mov %edx,0x14(%ebp) + 80070e: 8b 30 mov (%eax),%esi + 800710: 85 f6 test %esi,%esi + 800712: 75 05 jne 800719 + p = "(null)"; + 800714: be 81 11 80 00 mov $0x801181,%esi + } + if (width > 0 && padc != '-') { + 800719: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 80071d: 7e 76 jle 800795 + 80071f: 80 7d db 2d cmpb $0x2d,-0x25(%ebp) + 800723: 74 70 je 800795 + for (width -= strnlen(p, precision); width > 0; width --) { + 800725: 8b 45 e4 mov -0x1c(%ebp),%eax + 800728: 89 44 24 04 mov %eax,0x4(%esp) + 80072c: 89 34 24 mov %esi,(%esp) + 80072f: e8 ee 03 00 00 call 800b22 + 800734: 89 c2 mov %eax,%edx + 800736: 8b 45 e8 mov -0x18(%ebp),%eax + 800739: 29 d0 sub %edx,%eax + 80073b: 89 45 e8 mov %eax,-0x18(%ebp) + 80073e: eb 16 jmp 800756 + putch(padc, putdat); + 800740: 0f be 45 db movsbl -0x25(%ebp),%eax + 800744: 8b 55 0c mov 0xc(%ebp),%edx + 800747: 89 54 24 04 mov %edx,0x4(%esp) + 80074b: 89 04 24 mov %eax,(%esp) + 80074e: 8b 45 08 mov 0x8(%ebp),%eax + 800751: ff d0 call *%eax + for (width -= strnlen(p, precision); width > 0; width --) { + 800753: ff 4d e8 decl -0x18(%ebp) + 800756: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 80075a: 7f e4 jg 800740 + } + } + for (; (ch = *p ++) != '\0' && (precision < 0 || -- precision >= 0); width --) { + 80075c: eb 37 jmp 800795 + if (altflag && (ch < ' ' || ch > '~')) { + 80075e: 83 7d dc 00 cmpl $0x0,-0x24(%ebp) + 800762: 74 1f je 800783 + 800764: 83 fb 1f cmp $0x1f,%ebx + 800767: 7e 05 jle 80076e + 800769: 83 fb 7e cmp $0x7e,%ebx + 80076c: 7e 15 jle 800783 + putch('?', putdat); + 80076e: 8b 45 0c mov 0xc(%ebp),%eax + 800771: 89 44 24 04 mov %eax,0x4(%esp) + 800775: c7 04 24 3f 00 00 00 movl $0x3f,(%esp) + 80077c: 8b 45 08 mov 0x8(%ebp),%eax + 80077f: ff d0 call *%eax + 800781: eb 0f jmp 800792 + } + else { + putch(ch, putdat); + 800783: 8b 45 0c mov 0xc(%ebp),%eax + 800786: 89 44 24 04 mov %eax,0x4(%esp) + 80078a: 89 1c 24 mov %ebx,(%esp) + 80078d: 8b 45 08 mov 0x8(%ebp),%eax + 800790: ff d0 call *%eax + for (; (ch = *p ++) != '\0' && (precision < 0 || -- precision >= 0); width --) { + 800792: ff 4d e8 decl -0x18(%ebp) + 800795: 89 f0 mov %esi,%eax + 800797: 8d 70 01 lea 0x1(%eax),%esi + 80079a: 0f b6 00 movzbl (%eax),%eax + 80079d: 0f be d8 movsbl %al,%ebx + 8007a0: 85 db test %ebx,%ebx + 8007a2: 74 27 je 8007cb + 8007a4: 83 7d e4 00 cmpl $0x0,-0x1c(%ebp) + 8007a8: 78 b4 js 80075e + 8007aa: ff 4d e4 decl -0x1c(%ebp) + 8007ad: 83 7d e4 00 cmpl $0x0,-0x1c(%ebp) + 8007b1: 79 ab jns 80075e + } + } + for (; width > 0; width --) { + 8007b3: eb 16 jmp 8007cb + putch(' ', putdat); + 8007b5: 8b 45 0c mov 0xc(%ebp),%eax + 8007b8: 89 44 24 04 mov %eax,0x4(%esp) + 8007bc: c7 04 24 20 00 00 00 movl $0x20,(%esp) + 8007c3: 8b 45 08 mov 0x8(%ebp),%eax + 8007c6: ff d0 call *%eax + for (; width > 0; width --) { + 8007c8: ff 4d e8 decl -0x18(%ebp) + 8007cb: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 8007cf: 7f e4 jg 8007b5 + } + break; + 8007d1: e9 6c 01 00 00 jmp 800942 + + // (signed) decimal + case 'd': + num = getint(&ap, lflag); + 8007d6: 8b 45 e0 mov -0x20(%ebp),%eax + 8007d9: 89 44 24 04 mov %eax,0x4(%esp) + 8007dd: 8d 45 14 lea 0x14(%ebp),%eax + 8007e0: 89 04 24 mov %eax,(%esp) + 8007e3: e8 16 fd ff ff call 8004fe + 8007e8: 89 45 f0 mov %eax,-0x10(%ebp) + 8007eb: 89 55 f4 mov %edx,-0xc(%ebp) + if ((long long)num < 0) { + 8007ee: 8b 45 f0 mov -0x10(%ebp),%eax + 8007f1: 8b 55 f4 mov -0xc(%ebp),%edx + 8007f4: 85 d2 test %edx,%edx + 8007f6: 79 26 jns 80081e + putch('-', putdat); + 8007f8: 8b 45 0c mov 0xc(%ebp),%eax + 8007fb: 89 44 24 04 mov %eax,0x4(%esp) + 8007ff: c7 04 24 2d 00 00 00 movl $0x2d,(%esp) + 800806: 8b 45 08 mov 0x8(%ebp),%eax + 800809: ff d0 call *%eax + num = -(long long)num; + 80080b: 8b 45 f0 mov -0x10(%ebp),%eax + 80080e: 8b 55 f4 mov -0xc(%ebp),%edx + 800811: f7 d8 neg %eax + 800813: 83 d2 00 adc $0x0,%edx + 800816: f7 da neg %edx + 800818: 89 45 f0 mov %eax,-0x10(%ebp) + 80081b: 89 55 f4 mov %edx,-0xc(%ebp) + } + base = 10; + 80081e: c7 45 ec 0a 00 00 00 movl $0xa,-0x14(%ebp) + goto number; + 800825: e9 a8 00 00 00 jmp 8008d2 + + // unsigned decimal + case 'u': + num = getuint(&ap, lflag); + 80082a: 8b 45 e0 mov -0x20(%ebp),%eax + 80082d: 89 44 24 04 mov %eax,0x4(%esp) + 800831: 8d 45 14 lea 0x14(%ebp),%eax + 800834: 89 04 24 mov %eax,(%esp) + 800837: e8 73 fc ff ff call 8004af + 80083c: 89 45 f0 mov %eax,-0x10(%ebp) + 80083f: 89 55 f4 mov %edx,-0xc(%ebp) + base = 10; + 800842: c7 45 ec 0a 00 00 00 movl $0xa,-0x14(%ebp) + goto number; + 800849: e9 84 00 00 00 jmp 8008d2 + + // (unsigned) octal + case 'o': + num = getuint(&ap, lflag); + 80084e: 8b 45 e0 mov -0x20(%ebp),%eax + 800851: 89 44 24 04 mov %eax,0x4(%esp) + 800855: 8d 45 14 lea 0x14(%ebp),%eax + 800858: 89 04 24 mov %eax,(%esp) + 80085b: e8 4f fc ff ff call 8004af + 800860: 89 45 f0 mov %eax,-0x10(%ebp) + 800863: 89 55 f4 mov %edx,-0xc(%ebp) + base = 8; + 800866: c7 45 ec 08 00 00 00 movl $0x8,-0x14(%ebp) + goto number; + 80086d: eb 63 jmp 8008d2 + + // pointer + case 'p': + putch('0', putdat); + 80086f: 8b 45 0c mov 0xc(%ebp),%eax + 800872: 89 44 24 04 mov %eax,0x4(%esp) + 800876: c7 04 24 30 00 00 00 movl $0x30,(%esp) + 80087d: 8b 45 08 mov 0x8(%ebp),%eax + 800880: ff d0 call *%eax + putch('x', putdat); + 800882: 8b 45 0c mov 0xc(%ebp),%eax + 800885: 89 44 24 04 mov %eax,0x4(%esp) + 800889: c7 04 24 78 00 00 00 movl $0x78,(%esp) + 800890: 8b 45 08 mov 0x8(%ebp),%eax + 800893: ff d0 call *%eax + num = (unsigned long long)(uintptr_t)va_arg(ap, void *); + 800895: 8b 45 14 mov 0x14(%ebp),%eax + 800898: 8d 50 04 lea 0x4(%eax),%edx + 80089b: 89 55 14 mov %edx,0x14(%ebp) + 80089e: 8b 00 mov (%eax),%eax + 8008a0: 89 45 f0 mov %eax,-0x10(%ebp) + 8008a3: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + base = 16; + 8008aa: c7 45 ec 10 00 00 00 movl $0x10,-0x14(%ebp) + goto number; + 8008b1: eb 1f jmp 8008d2 + + // (unsigned) hexadecimal + case 'x': + num = getuint(&ap, lflag); + 8008b3: 8b 45 e0 mov -0x20(%ebp),%eax + 8008b6: 89 44 24 04 mov %eax,0x4(%esp) + 8008ba: 8d 45 14 lea 0x14(%ebp),%eax + 8008bd: 89 04 24 mov %eax,(%esp) + 8008c0: e8 ea fb ff ff call 8004af + 8008c5: 89 45 f0 mov %eax,-0x10(%ebp) + 8008c8: 89 55 f4 mov %edx,-0xc(%ebp) + base = 16; + 8008cb: c7 45 ec 10 00 00 00 movl $0x10,-0x14(%ebp) + number: + printnum(putch, putdat, num, base, width, padc); + 8008d2: 0f be 55 db movsbl -0x25(%ebp),%edx + 8008d6: 8b 45 ec mov -0x14(%ebp),%eax + 8008d9: 89 54 24 18 mov %edx,0x18(%esp) + 8008dd: 8b 55 e8 mov -0x18(%ebp),%edx + 8008e0: 89 54 24 14 mov %edx,0x14(%esp) + 8008e4: 89 44 24 10 mov %eax,0x10(%esp) + 8008e8: 8b 45 f0 mov -0x10(%ebp),%eax + 8008eb: 8b 55 f4 mov -0xc(%ebp),%edx + 8008ee: 89 44 24 08 mov %eax,0x8(%esp) + 8008f2: 89 54 24 0c mov %edx,0xc(%esp) + 8008f6: 8b 45 0c mov 0xc(%ebp),%eax + 8008f9: 89 44 24 04 mov %eax,0x4(%esp) + 8008fd: 8b 45 08 mov 0x8(%ebp),%eax + 800900: 89 04 24 mov %eax,(%esp) + 800903: e8 a5 fa ff ff call 8003ad + break; + 800908: eb 38 jmp 800942 + + // escaped '%' character + case '%': + putch(ch, putdat); + 80090a: 8b 45 0c mov 0xc(%ebp),%eax + 80090d: 89 44 24 04 mov %eax,0x4(%esp) + 800911: 89 1c 24 mov %ebx,(%esp) + 800914: 8b 45 08 mov 0x8(%ebp),%eax + 800917: ff d0 call *%eax + break; + 800919: eb 27 jmp 800942 + + // unrecognized escape sequence - just print it literally + default: + putch('%', putdat); + 80091b: 8b 45 0c mov 0xc(%ebp),%eax + 80091e: 89 44 24 04 mov %eax,0x4(%esp) + 800922: c7 04 24 25 00 00 00 movl $0x25,(%esp) + 800929: 8b 45 08 mov 0x8(%ebp),%eax + 80092c: ff d0 call *%eax + for (fmt --; fmt[-1] != '%'; fmt --) + 80092e: ff 4d 10 decl 0x10(%ebp) + 800931: eb 03 jmp 800936 + 800933: ff 4d 10 decl 0x10(%ebp) + 800936: 8b 45 10 mov 0x10(%ebp),%eax + 800939: 48 dec %eax + 80093a: 0f b6 00 movzbl (%eax),%eax + 80093d: 3c 25 cmp $0x25,%al + 80093f: 75 f2 jne 800933 + /* do nothing */; + break; + 800941: 90 nop + while (1) { + 800942: e9 37 fc ff ff jmp 80057e + return; + 800947: 90 nop + } + } +} + 800948: 83 c4 40 add $0x40,%esp + 80094b: 5b pop %ebx + 80094c: 5e pop %esi + 80094d: 5d pop %ebp + 80094e: c3 ret + +0080094f : + * sprintputch - 'print' a single character in a buffer + * @ch: the character will be printed + * @b: the buffer to place the character @ch + * */ +static void +sprintputch(int ch, struct sprintbuf *b) { + 80094f: 55 push %ebp + 800950: 89 e5 mov %esp,%ebp + b->cnt ++; + 800952: 8b 45 0c mov 0xc(%ebp),%eax + 800955: 8b 40 08 mov 0x8(%eax),%eax + 800958: 8d 50 01 lea 0x1(%eax),%edx + 80095b: 8b 45 0c mov 0xc(%ebp),%eax + 80095e: 89 50 08 mov %edx,0x8(%eax) + if (b->buf < b->ebuf) { + 800961: 8b 45 0c mov 0xc(%ebp),%eax + 800964: 8b 10 mov (%eax),%edx + 800966: 8b 45 0c mov 0xc(%ebp),%eax + 800969: 8b 40 04 mov 0x4(%eax),%eax + 80096c: 39 c2 cmp %eax,%edx + 80096e: 73 12 jae 800982 + *b->buf ++ = ch; + 800970: 8b 45 0c mov 0xc(%ebp),%eax + 800973: 8b 00 mov (%eax),%eax + 800975: 8d 48 01 lea 0x1(%eax),%ecx + 800978: 8b 55 0c mov 0xc(%ebp),%edx + 80097b: 89 0a mov %ecx,(%edx) + 80097d: 8b 55 08 mov 0x8(%ebp),%edx + 800980: 88 10 mov %dl,(%eax) + } +} + 800982: 90 nop + 800983: 5d pop %ebp + 800984: c3 ret + +00800985 : + * @str: the buffer to place the result into + * @size: the size of buffer, including the trailing null space + * @fmt: the format string to use + * */ +int +snprintf(char *str, size_t size, const char *fmt, ...) { + 800985: 55 push %ebp + 800986: 89 e5 mov %esp,%ebp + 800988: 83 ec 28 sub $0x28,%esp + va_list ap; + int cnt; + va_start(ap, fmt); + 80098b: 8d 45 14 lea 0x14(%ebp),%eax + 80098e: 89 45 f0 mov %eax,-0x10(%ebp) + cnt = vsnprintf(str, size, fmt, ap); + 800991: 8b 45 f0 mov -0x10(%ebp),%eax + 800994: 89 44 24 0c mov %eax,0xc(%esp) + 800998: 8b 45 10 mov 0x10(%ebp),%eax + 80099b: 89 44 24 08 mov %eax,0x8(%esp) + 80099f: 8b 45 0c mov 0xc(%ebp),%eax + 8009a2: 89 44 24 04 mov %eax,0x4(%esp) + 8009a6: 8b 45 08 mov 0x8(%ebp),%eax + 8009a9: 89 04 24 mov %eax,(%esp) + 8009ac: e8 0a 00 00 00 call 8009bb + 8009b1: 89 45 f4 mov %eax,-0xc(%ebp) + va_end(ap); + return cnt; + 8009b4: 8b 45 f4 mov -0xc(%ebp),%eax +} + 8009b7: 89 ec mov %ebp,%esp + 8009b9: 5d pop %ebp + 8009ba: c3 ret + +008009bb : + * + * Call this function if you are already dealing with a va_list. + * Or you probably want snprintf() instead. + * */ +int +vsnprintf(char *str, size_t size, const char *fmt, va_list ap) { + 8009bb: 55 push %ebp + 8009bc: 89 e5 mov %esp,%ebp + 8009be: 83 ec 28 sub $0x28,%esp + struct sprintbuf b = {str, str + size - 1, 0}; + 8009c1: 8b 45 08 mov 0x8(%ebp),%eax + 8009c4: 89 45 ec mov %eax,-0x14(%ebp) + 8009c7: 8b 45 0c mov 0xc(%ebp),%eax + 8009ca: 8d 50 ff lea -0x1(%eax),%edx + 8009cd: 8b 45 08 mov 0x8(%ebp),%eax + 8009d0: 01 d0 add %edx,%eax + 8009d2: 89 45 f0 mov %eax,-0x10(%ebp) + 8009d5: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + if (str == NULL || b.buf > b.ebuf) { + 8009dc: 83 7d 08 00 cmpl $0x0,0x8(%ebp) + 8009e0: 74 0a je 8009ec + 8009e2: 8b 55 ec mov -0x14(%ebp),%edx + 8009e5: 8b 45 f0 mov -0x10(%ebp),%eax + 8009e8: 39 c2 cmp %eax,%edx + 8009ea: 76 07 jbe 8009f3 + return -E_INVAL; + 8009ec: b8 fd ff ff ff mov $0xfffffffd,%eax + 8009f1: eb 2a jmp 800a1d + } + // print the string to the buffer + vprintfmt((void*)sprintputch, &b, fmt, ap); + 8009f3: 8b 45 14 mov 0x14(%ebp),%eax + 8009f6: 89 44 24 0c mov %eax,0xc(%esp) + 8009fa: 8b 45 10 mov 0x10(%ebp),%eax + 8009fd: 89 44 24 08 mov %eax,0x8(%esp) + 800a01: 8d 45 ec lea -0x14(%ebp),%eax + 800a04: 89 44 24 04 mov %eax,0x4(%esp) + 800a08: c7 04 24 4f 09 80 00 movl $0x80094f,(%esp) + 800a0f: e8 62 fb ff ff call 800576 + // null terminate the buffer + *b.buf = '\0'; + 800a14: 8b 45 ec mov -0x14(%ebp),%eax + 800a17: c6 00 00 movb $0x0,(%eax) + return b.cnt; + 800a1a: 8b 45 f4 mov -0xc(%ebp),%eax +} + 800a1d: 89 ec mov %ebp,%esp + 800a1f: 5d pop %ebp + 800a20: c3 ret + +00800a21 : + * rand - returns a pseudo-random integer + * + * The rand() function return a value in the range [0, RAND_MAX]. + * */ +int +rand(void) { + 800a21: 55 push %ebp + 800a22: 89 e5 mov %esp,%ebp + 800a24: 57 push %edi + 800a25: 56 push %esi + 800a26: 53 push %ebx + 800a27: 83 ec 24 sub $0x24,%esp + next = (next * 0x5DEECE66DLL + 0xBLL) & ((1LL << 48) - 1); + 800a2a: a1 00 20 80 00 mov 0x802000,%eax + 800a2f: 8b 15 04 20 80 00 mov 0x802004,%edx + 800a35: 69 fa 6d e6 ec de imul $0xdeece66d,%edx,%edi + 800a3b: 6b f0 05 imul $0x5,%eax,%esi + 800a3e: 01 fe add %edi,%esi + 800a40: bf 6d e6 ec de mov $0xdeece66d,%edi + 800a45: f7 e7 mul %edi + 800a47: 01 d6 add %edx,%esi + 800a49: 89 f2 mov %esi,%edx + 800a4b: 83 c0 0b add $0xb,%eax + 800a4e: 83 d2 00 adc $0x0,%edx + 800a51: 89 c7 mov %eax,%edi + 800a53: 83 e7 ff and $0xffffffff,%edi + 800a56: 89 f9 mov %edi,%ecx + 800a58: 0f b7 da movzwl %dx,%ebx + 800a5b: 89 0d 00 20 80 00 mov %ecx,0x802000 + 800a61: 89 1d 04 20 80 00 mov %ebx,0x802004 + unsigned long long result = (next >> 12); + 800a67: a1 00 20 80 00 mov 0x802000,%eax + 800a6c: 8b 15 04 20 80 00 mov 0x802004,%edx + 800a72: 0f ac d0 0c shrd $0xc,%edx,%eax + 800a76: c1 ea 0c shr $0xc,%edx + 800a79: 89 45 e0 mov %eax,-0x20(%ebp) + 800a7c: 89 55 e4 mov %edx,-0x1c(%ebp) + return (int)do_div(result, RAND_MAX + 1); + 800a7f: c7 45 dc 00 00 00 80 movl $0x80000000,-0x24(%ebp) + 800a86: 8b 45 e0 mov -0x20(%ebp),%eax + 800a89: 8b 55 e4 mov -0x1c(%ebp),%edx + 800a8c: 89 45 d8 mov %eax,-0x28(%ebp) + 800a8f: 89 55 e8 mov %edx,-0x18(%ebp) + 800a92: 8b 45 e8 mov -0x18(%ebp),%eax + 800a95: 89 45 ec mov %eax,-0x14(%ebp) + 800a98: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 800a9c: 74 1c je 800aba + 800a9e: 8b 45 e8 mov -0x18(%ebp),%eax + 800aa1: ba 00 00 00 00 mov $0x0,%edx + 800aa6: f7 75 dc divl -0x24(%ebp) + 800aa9: 89 55 ec mov %edx,-0x14(%ebp) + 800aac: 8b 45 e8 mov -0x18(%ebp),%eax + 800aaf: ba 00 00 00 00 mov $0x0,%edx + 800ab4: f7 75 dc divl -0x24(%ebp) + 800ab7: 89 45 e8 mov %eax,-0x18(%ebp) + 800aba: 8b 45 d8 mov -0x28(%ebp),%eax + 800abd: 8b 55 ec mov -0x14(%ebp),%edx + 800ac0: f7 75 dc divl -0x24(%ebp) + 800ac3: 89 45 d8 mov %eax,-0x28(%ebp) + 800ac6: 89 55 d4 mov %edx,-0x2c(%ebp) + 800ac9: 8b 45 d8 mov -0x28(%ebp),%eax + 800acc: 8b 55 e8 mov -0x18(%ebp),%edx + 800acf: 89 45 e0 mov %eax,-0x20(%ebp) + 800ad2: 89 55 e4 mov %edx,-0x1c(%ebp) + 800ad5: 8b 45 d4 mov -0x2c(%ebp),%eax +} + 800ad8: 83 c4 24 add $0x24,%esp + 800adb: 5b pop %ebx + 800adc: 5e pop %esi + 800add: 5f pop %edi + 800ade: 5d pop %ebp + 800adf: c3 ret + +00800ae0 : +/* * + * srand - seed the random number generator with the given number + * @seed: the required seed number + * */ +void +srand(unsigned int seed) { + 800ae0: 55 push %ebp + 800ae1: 89 e5 mov %esp,%ebp + next = seed; + 800ae3: 8b 45 08 mov 0x8(%ebp),%eax + 800ae6: ba 00 00 00 00 mov $0x0,%edx + 800aeb: a3 00 20 80 00 mov %eax,0x802000 + 800af0: 89 15 04 20 80 00 mov %edx,0x802004 +} + 800af6: 90 nop + 800af7: 5d pop %ebp + 800af8: c3 ret + +00800af9 : + * @s: the input string + * + * The strlen() function returns the length of string @s. + * */ +size_t +strlen(const char *s) { + 800af9: 55 push %ebp + 800afa: 89 e5 mov %esp,%ebp + 800afc: 83 ec 10 sub $0x10,%esp + size_t cnt = 0; + 800aff: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + while (*s ++ != '\0') { + 800b06: eb 03 jmp 800b0b + cnt ++; + 800b08: ff 45 fc incl -0x4(%ebp) + while (*s ++ != '\0') { + 800b0b: 8b 45 08 mov 0x8(%ebp),%eax + 800b0e: 8d 50 01 lea 0x1(%eax),%edx + 800b11: 89 55 08 mov %edx,0x8(%ebp) + 800b14: 0f b6 00 movzbl (%eax),%eax + 800b17: 84 c0 test %al,%al + 800b19: 75 ed jne 800b08 + } + return cnt; + 800b1b: 8b 45 fc mov -0x4(%ebp),%eax +} + 800b1e: 89 ec mov %ebp,%esp + 800b20: 5d pop %ebp + 800b21: c3 ret + +00800b22 : + * The return value is strlen(s), if that is less than @len, or + * @len if there is no '\0' character among the first @len characters + * pointed by @s. + * */ +size_t +strnlen(const char *s, size_t len) { + 800b22: 55 push %ebp + 800b23: 89 e5 mov %esp,%ebp + 800b25: 83 ec 10 sub $0x10,%esp + size_t cnt = 0; + 800b28: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + while (cnt < len && *s ++ != '\0') { + 800b2f: eb 03 jmp 800b34 + cnt ++; + 800b31: ff 45 fc incl -0x4(%ebp) + while (cnt < len && *s ++ != '\0') { + 800b34: 8b 45 fc mov -0x4(%ebp),%eax + 800b37: 3b 45 0c cmp 0xc(%ebp),%eax + 800b3a: 73 10 jae 800b4c + 800b3c: 8b 45 08 mov 0x8(%ebp),%eax + 800b3f: 8d 50 01 lea 0x1(%eax),%edx + 800b42: 89 55 08 mov %edx,0x8(%ebp) + 800b45: 0f b6 00 movzbl (%eax),%eax + 800b48: 84 c0 test %al,%al + 800b4a: 75 e5 jne 800b31 + } + return cnt; + 800b4c: 8b 45 fc mov -0x4(%ebp),%eax +} + 800b4f: 89 ec mov %ebp,%esp + 800b51: 5d pop %ebp + 800b52: c3 ret + +00800b53 : + * To avoid overflows, the size of array pointed by @dst should be long enough to + * contain the same string as @src (including the terminating null character), and + * should not overlap in memory with @src. + * */ +char * +strcpy(char *dst, const char *src) { + 800b53: 55 push %ebp + 800b54: 89 e5 mov %esp,%ebp + 800b56: 57 push %edi + 800b57: 56 push %esi + 800b58: 83 ec 20 sub $0x20,%esp + 800b5b: 8b 45 08 mov 0x8(%ebp),%eax + 800b5e: 89 45 f4 mov %eax,-0xc(%ebp) + 800b61: 8b 45 0c mov 0xc(%ebp),%eax + 800b64: 89 45 f0 mov %eax,-0x10(%ebp) +#ifndef __HAVE_ARCH_STRCPY +#define __HAVE_ARCH_STRCPY +static inline char * +__strcpy(char *dst, const char *src) { + int d0, d1, d2; + asm volatile ( + 800b67: 8b 55 f0 mov -0x10(%ebp),%edx + 800b6a: 8b 45 f4 mov -0xc(%ebp),%eax + 800b6d: 89 d1 mov %edx,%ecx + 800b6f: 89 c2 mov %eax,%edx + 800b71: 89 ce mov %ecx,%esi + 800b73: 89 d7 mov %edx,%edi + 800b75: ac lods %ds:(%esi),%al + 800b76: aa stos %al,%es:(%edi) + 800b77: 84 c0 test %al,%al + 800b79: 75 fa jne 800b75 + 800b7b: 89 fa mov %edi,%edx + 800b7d: 89 f1 mov %esi,%ecx + 800b7f: 89 4d ec mov %ecx,-0x14(%ebp) + 800b82: 89 55 e8 mov %edx,-0x18(%ebp) + 800b85: 89 45 e4 mov %eax,-0x1c(%ebp) + "stosb;" + "testb %%al, %%al;" + "jne 1b;" + : "=&S" (d0), "=&D" (d1), "=&a" (d2) + : "0" (src), "1" (dst) : "memory"); + return dst; + 800b88: 8b 45 f4 mov -0xc(%ebp),%eax + char *p = dst; + while ((*p ++ = *src ++) != '\0') + /* nothing */; + return dst; +#endif /* __HAVE_ARCH_STRCPY */ +} + 800b8b: 83 c4 20 add $0x20,%esp + 800b8e: 5e pop %esi + 800b8f: 5f pop %edi + 800b90: 5d pop %ebp + 800b91: c3 ret + +00800b92 : + * @len: maximum number of characters to be copied from @src + * + * The return value is @dst + * */ +char * +strncpy(char *dst, const char *src, size_t len) { + 800b92: 55 push %ebp + 800b93: 89 e5 mov %esp,%ebp + 800b95: 83 ec 10 sub $0x10,%esp + char *p = dst; + 800b98: 8b 45 08 mov 0x8(%ebp),%eax + 800b9b: 89 45 fc mov %eax,-0x4(%ebp) + while (len > 0) { + 800b9e: eb 1e jmp 800bbe + if ((*p = *src) != '\0') { + 800ba0: 8b 45 0c mov 0xc(%ebp),%eax + 800ba3: 0f b6 10 movzbl (%eax),%edx + 800ba6: 8b 45 fc mov -0x4(%ebp),%eax + 800ba9: 88 10 mov %dl,(%eax) + 800bab: 8b 45 fc mov -0x4(%ebp),%eax + 800bae: 0f b6 00 movzbl (%eax),%eax + 800bb1: 84 c0 test %al,%al + 800bb3: 74 03 je 800bb8 + src ++; + 800bb5: ff 45 0c incl 0xc(%ebp) + } + p ++, len --; + 800bb8: ff 45 fc incl -0x4(%ebp) + 800bbb: ff 4d 10 decl 0x10(%ebp) + while (len > 0) { + 800bbe: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800bc2: 75 dc jne 800ba0 + } + return dst; + 800bc4: 8b 45 08 mov 0x8(%ebp),%eax +} + 800bc7: 89 ec mov %ebp,%esp + 800bc9: 5d pop %ebp + 800bca: c3 ret + +00800bcb : + * - A value greater than zero indicates that the first character that does + * not match has a greater value in @s1 than in @s2; + * - And a value less than zero indicates the opposite. + * */ +int +strcmp(const char *s1, const char *s2) { + 800bcb: 55 push %ebp + 800bcc: 89 e5 mov %esp,%ebp + 800bce: 57 push %edi + 800bcf: 56 push %esi + 800bd0: 83 ec 20 sub $0x20,%esp + 800bd3: 8b 45 08 mov 0x8(%ebp),%eax + 800bd6: 89 45 f4 mov %eax,-0xc(%ebp) + 800bd9: 8b 45 0c mov 0xc(%ebp),%eax + 800bdc: 89 45 f0 mov %eax,-0x10(%ebp) + asm volatile ( + 800bdf: 8b 55 f4 mov -0xc(%ebp),%edx + 800be2: 8b 45 f0 mov -0x10(%ebp),%eax + 800be5: 89 d1 mov %edx,%ecx + 800be7: 89 c2 mov %eax,%edx + 800be9: 89 ce mov %ecx,%esi + 800beb: 89 d7 mov %edx,%edi + 800bed: ac lods %ds:(%esi),%al + 800bee: ae scas %es:(%edi),%al + 800bef: 75 08 jne 800bf9 + 800bf1: 84 c0 test %al,%al + 800bf3: 75 f8 jne 800bed + 800bf5: 31 c0 xor %eax,%eax + 800bf7: eb 04 jmp 800bfd + 800bf9: 19 c0 sbb %eax,%eax + 800bfb: 0c 01 or $0x1,%al + 800bfd: 89 fa mov %edi,%edx + 800bff: 89 f1 mov %esi,%ecx + 800c01: 89 45 ec mov %eax,-0x14(%ebp) + 800c04: 89 4d e8 mov %ecx,-0x18(%ebp) + 800c07: 89 55 e4 mov %edx,-0x1c(%ebp) + return ret; + 800c0a: 8b 45 ec mov -0x14(%ebp),%eax + while (*s1 != '\0' && *s1 == *s2) { + s1 ++, s2 ++; + } + return (int)((unsigned char)*s1 - (unsigned char)*s2); +#endif /* __HAVE_ARCH_STRCMP */ +} + 800c0d: 83 c4 20 add $0x20,%esp + 800c10: 5e pop %esi + 800c11: 5f pop %edi + 800c12: 5d pop %ebp + 800c13: c3 ret + +00800c14 : + * they are equal to each other, it continues with the following pairs until + * the characters differ, until a terminating null-character is reached, or + * until @n characters match in both strings, whichever happens first. + * */ +int +strncmp(const char *s1, const char *s2, size_t n) { + 800c14: 55 push %ebp + 800c15: 89 e5 mov %esp,%ebp + while (n > 0 && *s1 != '\0' && *s1 == *s2) { + 800c17: eb 09 jmp 800c22 + n --, s1 ++, s2 ++; + 800c19: ff 4d 10 decl 0x10(%ebp) + 800c1c: ff 45 08 incl 0x8(%ebp) + 800c1f: ff 45 0c incl 0xc(%ebp) + while (n > 0 && *s1 != '\0' && *s1 == *s2) { + 800c22: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800c26: 74 1a je 800c42 + 800c28: 8b 45 08 mov 0x8(%ebp),%eax + 800c2b: 0f b6 00 movzbl (%eax),%eax + 800c2e: 84 c0 test %al,%al + 800c30: 74 10 je 800c42 + 800c32: 8b 45 08 mov 0x8(%ebp),%eax + 800c35: 0f b6 10 movzbl (%eax),%edx + 800c38: 8b 45 0c mov 0xc(%ebp),%eax + 800c3b: 0f b6 00 movzbl (%eax),%eax + 800c3e: 38 c2 cmp %al,%dl + 800c40: 74 d7 je 800c19 + } + return (n == 0) ? 0 : (int)((unsigned char)*s1 - (unsigned char)*s2); + 800c42: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800c46: 74 18 je 800c60 + 800c48: 8b 45 08 mov 0x8(%ebp),%eax + 800c4b: 0f b6 00 movzbl (%eax),%eax + 800c4e: 0f b6 d0 movzbl %al,%edx + 800c51: 8b 45 0c mov 0xc(%ebp),%eax + 800c54: 0f b6 00 movzbl (%eax),%eax + 800c57: 0f b6 c8 movzbl %al,%ecx + 800c5a: 89 d0 mov %edx,%eax + 800c5c: 29 c8 sub %ecx,%eax + 800c5e: eb 05 jmp 800c65 + 800c60: b8 00 00 00 00 mov $0x0,%eax +} + 800c65: 5d pop %ebp + 800c66: c3 ret + +00800c67 : + * + * The strchr() function returns a pointer to the first occurrence of + * character in @s. If the value is not found, the function returns 'NULL'. + * */ +char * +strchr(const char *s, char c) { + 800c67: 55 push %ebp + 800c68: 89 e5 mov %esp,%ebp + 800c6a: 83 ec 04 sub $0x4,%esp + 800c6d: 8b 45 0c mov 0xc(%ebp),%eax + 800c70: 88 45 fc mov %al,-0x4(%ebp) + while (*s != '\0') { + 800c73: eb 13 jmp 800c88 + if (*s == c) { + 800c75: 8b 45 08 mov 0x8(%ebp),%eax + 800c78: 0f b6 00 movzbl (%eax),%eax + 800c7b: 38 45 fc cmp %al,-0x4(%ebp) + 800c7e: 75 05 jne 800c85 + return (char *)s; + 800c80: 8b 45 08 mov 0x8(%ebp),%eax + 800c83: eb 12 jmp 800c97 + } + s ++; + 800c85: ff 45 08 incl 0x8(%ebp) + while (*s != '\0') { + 800c88: 8b 45 08 mov 0x8(%ebp),%eax + 800c8b: 0f b6 00 movzbl (%eax),%eax + 800c8e: 84 c0 test %al,%al + 800c90: 75 e3 jne 800c75 + } + return NULL; + 800c92: b8 00 00 00 00 mov $0x0,%eax +} + 800c97: 89 ec mov %ebp,%esp + 800c99: 5d pop %ebp + 800c9a: c3 ret + +00800c9b : + * The strfind() function is like strchr() except that if @c is + * not found in @s, then it returns a pointer to the null byte at the + * end of @s, rather than 'NULL'. + * */ +char * +strfind(const char *s, char c) { + 800c9b: 55 push %ebp + 800c9c: 89 e5 mov %esp,%ebp + 800c9e: 83 ec 04 sub $0x4,%esp + 800ca1: 8b 45 0c mov 0xc(%ebp),%eax + 800ca4: 88 45 fc mov %al,-0x4(%ebp) + while (*s != '\0') { + 800ca7: eb 0e jmp 800cb7 + if (*s == c) { + 800ca9: 8b 45 08 mov 0x8(%ebp),%eax + 800cac: 0f b6 00 movzbl (%eax),%eax + 800caf: 38 45 fc cmp %al,-0x4(%ebp) + 800cb2: 74 0f je 800cc3 + break; + } + s ++; + 800cb4: ff 45 08 incl 0x8(%ebp) + while (*s != '\0') { + 800cb7: 8b 45 08 mov 0x8(%ebp),%eax + 800cba: 0f b6 00 movzbl (%eax),%eax + 800cbd: 84 c0 test %al,%al + 800cbf: 75 e8 jne 800ca9 + 800cc1: eb 01 jmp 800cc4 + break; + 800cc3: 90 nop + } + return (char *)s; + 800cc4: 8b 45 08 mov 0x8(%ebp),%eax +} + 800cc7: 89 ec mov %ebp,%esp + 800cc9: 5d pop %ebp + 800cca: c3 ret + +00800ccb : + * an optional "0x" or "0X" prefix. + * + * The strtol() function returns the converted integral number as a long int value. + * */ +long +strtol(const char *s, char **endptr, int base) { + 800ccb: 55 push %ebp + 800ccc: 89 e5 mov %esp,%ebp + 800cce: 83 ec 10 sub $0x10,%esp + int neg = 0; + 800cd1: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + long val = 0; + 800cd8: c7 45 f8 00 00 00 00 movl $0x0,-0x8(%ebp) + + // gobble initial whitespace + while (*s == ' ' || *s == '\t') { + 800cdf: eb 03 jmp 800ce4 + s ++; + 800ce1: ff 45 08 incl 0x8(%ebp) + while (*s == ' ' || *s == '\t') { + 800ce4: 8b 45 08 mov 0x8(%ebp),%eax + 800ce7: 0f b6 00 movzbl (%eax),%eax + 800cea: 3c 20 cmp $0x20,%al + 800cec: 74 f3 je 800ce1 + 800cee: 8b 45 08 mov 0x8(%ebp),%eax + 800cf1: 0f b6 00 movzbl (%eax),%eax + 800cf4: 3c 09 cmp $0x9,%al + 800cf6: 74 e9 je 800ce1 + } + + // plus/minus sign + if (*s == '+') { + 800cf8: 8b 45 08 mov 0x8(%ebp),%eax + 800cfb: 0f b6 00 movzbl (%eax),%eax + 800cfe: 3c 2b cmp $0x2b,%al + 800d00: 75 05 jne 800d07 + s ++; + 800d02: ff 45 08 incl 0x8(%ebp) + 800d05: eb 14 jmp 800d1b + } + else if (*s == '-') { + 800d07: 8b 45 08 mov 0x8(%ebp),%eax + 800d0a: 0f b6 00 movzbl (%eax),%eax + 800d0d: 3c 2d cmp $0x2d,%al + 800d0f: 75 0a jne 800d1b + s ++, neg = 1; + 800d11: ff 45 08 incl 0x8(%ebp) + 800d14: c7 45 fc 01 00 00 00 movl $0x1,-0x4(%ebp) + } + + // hex or octal base prefix + if ((base == 0 || base == 16) && (s[0] == '0' && s[1] == 'x')) { + 800d1b: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800d1f: 74 06 je 800d27 + 800d21: 83 7d 10 10 cmpl $0x10,0x10(%ebp) + 800d25: 75 22 jne 800d49 + 800d27: 8b 45 08 mov 0x8(%ebp),%eax + 800d2a: 0f b6 00 movzbl (%eax),%eax + 800d2d: 3c 30 cmp $0x30,%al + 800d2f: 75 18 jne 800d49 + 800d31: 8b 45 08 mov 0x8(%ebp),%eax + 800d34: 40 inc %eax + 800d35: 0f b6 00 movzbl (%eax),%eax + 800d38: 3c 78 cmp $0x78,%al + 800d3a: 75 0d jne 800d49 + s += 2, base = 16; + 800d3c: 83 45 08 02 addl $0x2,0x8(%ebp) + 800d40: c7 45 10 10 00 00 00 movl $0x10,0x10(%ebp) + 800d47: eb 29 jmp 800d72 + } + else if (base == 0 && s[0] == '0') { + 800d49: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800d4d: 75 16 jne 800d65 + 800d4f: 8b 45 08 mov 0x8(%ebp),%eax + 800d52: 0f b6 00 movzbl (%eax),%eax + 800d55: 3c 30 cmp $0x30,%al + 800d57: 75 0c jne 800d65 + s ++, base = 8; + 800d59: ff 45 08 incl 0x8(%ebp) + 800d5c: c7 45 10 08 00 00 00 movl $0x8,0x10(%ebp) + 800d63: eb 0d jmp 800d72 + } + else if (base == 0) { + 800d65: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800d69: 75 07 jne 800d72 + base = 10; + 800d6b: c7 45 10 0a 00 00 00 movl $0xa,0x10(%ebp) + + // digits + while (1) { + int dig; + + if (*s >= '0' && *s <= '9') { + 800d72: 8b 45 08 mov 0x8(%ebp),%eax + 800d75: 0f b6 00 movzbl (%eax),%eax + 800d78: 3c 2f cmp $0x2f,%al + 800d7a: 7e 1b jle 800d97 + 800d7c: 8b 45 08 mov 0x8(%ebp),%eax + 800d7f: 0f b6 00 movzbl (%eax),%eax + 800d82: 3c 39 cmp $0x39,%al + 800d84: 7f 11 jg 800d97 + dig = *s - '0'; + 800d86: 8b 45 08 mov 0x8(%ebp),%eax + 800d89: 0f b6 00 movzbl (%eax),%eax + 800d8c: 0f be c0 movsbl %al,%eax + 800d8f: 83 e8 30 sub $0x30,%eax + 800d92: 89 45 f4 mov %eax,-0xc(%ebp) + 800d95: eb 48 jmp 800ddf + } + else if (*s >= 'a' && *s <= 'z') { + 800d97: 8b 45 08 mov 0x8(%ebp),%eax + 800d9a: 0f b6 00 movzbl (%eax),%eax + 800d9d: 3c 60 cmp $0x60,%al + 800d9f: 7e 1b jle 800dbc + 800da1: 8b 45 08 mov 0x8(%ebp),%eax + 800da4: 0f b6 00 movzbl (%eax),%eax + 800da7: 3c 7a cmp $0x7a,%al + 800da9: 7f 11 jg 800dbc + dig = *s - 'a' + 10; + 800dab: 8b 45 08 mov 0x8(%ebp),%eax + 800dae: 0f b6 00 movzbl (%eax),%eax + 800db1: 0f be c0 movsbl %al,%eax + 800db4: 83 e8 57 sub $0x57,%eax + 800db7: 89 45 f4 mov %eax,-0xc(%ebp) + 800dba: eb 23 jmp 800ddf + } + else if (*s >= 'A' && *s <= 'Z') { + 800dbc: 8b 45 08 mov 0x8(%ebp),%eax + 800dbf: 0f b6 00 movzbl (%eax),%eax + 800dc2: 3c 40 cmp $0x40,%al + 800dc4: 7e 3b jle 800e01 + 800dc6: 8b 45 08 mov 0x8(%ebp),%eax + 800dc9: 0f b6 00 movzbl (%eax),%eax + 800dcc: 3c 5a cmp $0x5a,%al + 800dce: 7f 31 jg 800e01 + dig = *s - 'A' + 10; + 800dd0: 8b 45 08 mov 0x8(%ebp),%eax + 800dd3: 0f b6 00 movzbl (%eax),%eax + 800dd6: 0f be c0 movsbl %al,%eax + 800dd9: 83 e8 37 sub $0x37,%eax + 800ddc: 89 45 f4 mov %eax,-0xc(%ebp) + } + else { + break; + } + if (dig >= base) { + 800ddf: 8b 45 f4 mov -0xc(%ebp),%eax + 800de2: 3b 45 10 cmp 0x10(%ebp),%eax + 800de5: 7d 19 jge 800e00 + break; + } + s ++, val = (val * base) + dig; + 800de7: ff 45 08 incl 0x8(%ebp) + 800dea: 8b 45 f8 mov -0x8(%ebp),%eax + 800ded: 0f af 45 10 imul 0x10(%ebp),%eax + 800df1: 89 c2 mov %eax,%edx + 800df3: 8b 45 f4 mov -0xc(%ebp),%eax + 800df6: 01 d0 add %edx,%eax + 800df8: 89 45 f8 mov %eax,-0x8(%ebp) + while (1) { + 800dfb: e9 72 ff ff ff jmp 800d72 + break; + 800e00: 90 nop + // we don't properly detect overflow! + } + + if (endptr) { + 800e01: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) + 800e05: 74 08 je 800e0f + *endptr = (char *) s; + 800e07: 8b 45 0c mov 0xc(%ebp),%eax + 800e0a: 8b 55 08 mov 0x8(%ebp),%edx + 800e0d: 89 10 mov %edx,(%eax) + } + return (neg ? -val : val); + 800e0f: 83 7d fc 00 cmpl $0x0,-0x4(%ebp) + 800e13: 74 07 je 800e1c + 800e15: 8b 45 f8 mov -0x8(%ebp),%eax + 800e18: f7 d8 neg %eax + 800e1a: eb 03 jmp 800e1f + 800e1c: 8b 45 f8 mov -0x8(%ebp),%eax +} + 800e1f: 89 ec mov %ebp,%esp + 800e21: 5d pop %ebp + 800e22: c3 ret + +00800e23 : + * @n: number of bytes to be set to the value + * + * The memset() function returns @s. + * */ +void * +memset(void *s, char c, size_t n) { + 800e23: 55 push %ebp + 800e24: 89 e5 mov %esp,%ebp + 800e26: 83 ec 28 sub $0x28,%esp + 800e29: 89 7d fc mov %edi,-0x4(%ebp) + 800e2c: 8b 45 0c mov 0xc(%ebp),%eax + 800e2f: 88 45 d8 mov %al,-0x28(%ebp) +#ifdef __HAVE_ARCH_MEMSET + return __memset(s, c, n); + 800e32: 0f be 55 d8 movsbl -0x28(%ebp),%edx + 800e36: 8b 45 08 mov 0x8(%ebp),%eax + 800e39: 89 45 f8 mov %eax,-0x8(%ebp) + 800e3c: 88 55 f7 mov %dl,-0x9(%ebp) + 800e3f: 8b 45 10 mov 0x10(%ebp),%eax + 800e42: 89 45 f0 mov %eax,-0x10(%ebp) +#ifndef __HAVE_ARCH_MEMSET +#define __HAVE_ARCH_MEMSET +static inline void * +__memset(void *s, char c, size_t n) { + int d0, d1; + asm volatile ( + 800e45: 8b 4d f0 mov -0x10(%ebp),%ecx + 800e48: 0f b6 45 f7 movzbl -0x9(%ebp),%eax + 800e4c: 8b 55 f8 mov -0x8(%ebp),%edx + 800e4f: 89 d7 mov %edx,%edi + 800e51: f3 aa rep stos %al,%es:(%edi) + 800e53: 89 fa mov %edi,%edx + 800e55: 89 4d ec mov %ecx,-0x14(%ebp) + 800e58: 89 55 e8 mov %edx,-0x18(%ebp) + "rep; stosb;" + : "=&c" (d0), "=&D" (d1) + : "0" (n), "a" (c), "1" (s) + : "memory"); + return s; + 800e5b: 8b 45 f8 mov -0x8(%ebp),%eax + while (n -- > 0) { + *p ++ = c; + } + return s; +#endif /* __HAVE_ARCH_MEMSET */ +} + 800e5e: 8b 7d fc mov -0x4(%ebp),%edi + 800e61: 89 ec mov %ebp,%esp + 800e63: 5d pop %ebp + 800e64: c3 ret + +00800e65 : + * @n: number of bytes to copy + * + * The memmove() function returns @dst. + * */ +void * +memmove(void *dst, const void *src, size_t n) { + 800e65: 55 push %ebp + 800e66: 89 e5 mov %esp,%ebp + 800e68: 57 push %edi + 800e69: 56 push %esi + 800e6a: 53 push %ebx + 800e6b: 83 ec 30 sub $0x30,%esp + 800e6e: 8b 45 08 mov 0x8(%ebp),%eax + 800e71: 89 45 f0 mov %eax,-0x10(%ebp) + 800e74: 8b 45 0c mov 0xc(%ebp),%eax + 800e77: 89 45 ec mov %eax,-0x14(%ebp) + 800e7a: 8b 45 10 mov 0x10(%ebp),%eax + 800e7d: 89 45 e8 mov %eax,-0x18(%ebp) + +#ifndef __HAVE_ARCH_MEMMOVE +#define __HAVE_ARCH_MEMMOVE +static inline void * +__memmove(void *dst, const void *src, size_t n) { + if (dst < src) { + 800e80: 8b 45 f0 mov -0x10(%ebp),%eax + 800e83: 3b 45 ec cmp -0x14(%ebp),%eax + 800e86: 73 42 jae 800eca + 800e88: 8b 45 f0 mov -0x10(%ebp),%eax + 800e8b: 89 45 e4 mov %eax,-0x1c(%ebp) + 800e8e: 8b 45 ec mov -0x14(%ebp),%eax + 800e91: 89 45 e0 mov %eax,-0x20(%ebp) + 800e94: 8b 45 e8 mov -0x18(%ebp),%eax + 800e97: 89 45 dc mov %eax,-0x24(%ebp) + "andl $3, %%ecx;" + "jz 1f;" + "rep; movsb;" + "1:" + : "=&c" (d0), "=&D" (d1), "=&S" (d2) + : "0" (n / 4), "g" (n), "1" (dst), "2" (src) + 800e9a: 8b 45 dc mov -0x24(%ebp),%eax + 800e9d: c1 e8 02 shr $0x2,%eax + 800ea0: 89 c1 mov %eax,%ecx + asm volatile ( + 800ea2: 8b 55 e4 mov -0x1c(%ebp),%edx + 800ea5: 8b 45 e0 mov -0x20(%ebp),%eax + 800ea8: 89 d7 mov %edx,%edi + 800eaa: 89 c6 mov %eax,%esi + 800eac: f3 a5 rep movsl %ds:(%esi),%es:(%edi) + 800eae: 8b 4d dc mov -0x24(%ebp),%ecx + 800eb1: 83 e1 03 and $0x3,%ecx + 800eb4: 74 02 je 800eb8 + 800eb6: f3 a4 rep movsb %ds:(%esi),%es:(%edi) + 800eb8: 89 f0 mov %esi,%eax + 800eba: 89 fa mov %edi,%edx + 800ebc: 89 4d d8 mov %ecx,-0x28(%ebp) + 800ebf: 89 55 d4 mov %edx,-0x2c(%ebp) + 800ec2: 89 45 d0 mov %eax,-0x30(%ebp) + : "memory"); + return dst; + 800ec5: 8b 45 e4 mov -0x1c(%ebp),%eax + return __memcpy(dst, src, n); + 800ec8: eb 36 jmp 800f00 + : "0" (n), "1" (n - 1 + src), "2" (n - 1 + dst) + 800eca: 8b 45 e8 mov -0x18(%ebp),%eax + 800ecd: 8d 50 ff lea -0x1(%eax),%edx + 800ed0: 8b 45 ec mov -0x14(%ebp),%eax + 800ed3: 01 c2 add %eax,%edx + 800ed5: 8b 45 e8 mov -0x18(%ebp),%eax + 800ed8: 8d 48 ff lea -0x1(%eax),%ecx + 800edb: 8b 45 f0 mov -0x10(%ebp),%eax + 800ede: 8d 1c 01 lea (%ecx,%eax,1),%ebx + asm volatile ( + 800ee1: 8b 45 e8 mov -0x18(%ebp),%eax + 800ee4: 89 c1 mov %eax,%ecx + 800ee6: 89 d8 mov %ebx,%eax + 800ee8: 89 d6 mov %edx,%esi + 800eea: 89 c7 mov %eax,%edi + 800eec: fd std + 800eed: f3 a4 rep movsb %ds:(%esi),%es:(%edi) + 800eef: fc cld + 800ef0: 89 f8 mov %edi,%eax + 800ef2: 89 f2 mov %esi,%edx + 800ef4: 89 4d cc mov %ecx,-0x34(%ebp) + 800ef7: 89 55 c8 mov %edx,-0x38(%ebp) + 800efa: 89 45 c4 mov %eax,-0x3c(%ebp) + return dst; + 800efd: 8b 45 f0 mov -0x10(%ebp),%eax + *d ++ = *s ++; + } + } + return dst; +#endif /* __HAVE_ARCH_MEMMOVE */ +} + 800f00: 83 c4 30 add $0x30,%esp + 800f03: 5b pop %ebx + 800f04: 5e pop %esi + 800f05: 5f pop %edi + 800f06: 5d pop %ebp + 800f07: c3 ret + +00800f08 : + * it always copies exactly @n bytes. To avoid overflows, the size of arrays pointed + * by both @src and @dst, should be at least @n bytes, and should not overlap + * (for overlapping memory area, memmove is a safer approach). + * */ +void * +memcpy(void *dst, const void *src, size_t n) { + 800f08: 55 push %ebp + 800f09: 89 e5 mov %esp,%ebp + 800f0b: 57 push %edi + 800f0c: 56 push %esi + 800f0d: 83 ec 20 sub $0x20,%esp + 800f10: 8b 45 08 mov 0x8(%ebp),%eax + 800f13: 89 45 f4 mov %eax,-0xc(%ebp) + 800f16: 8b 45 0c mov 0xc(%ebp),%eax + 800f19: 89 45 f0 mov %eax,-0x10(%ebp) + 800f1c: 8b 45 10 mov 0x10(%ebp),%eax + 800f1f: 89 45 ec mov %eax,-0x14(%ebp) + : "0" (n / 4), "g" (n), "1" (dst), "2" (src) + 800f22: 8b 45 ec mov -0x14(%ebp),%eax + 800f25: c1 e8 02 shr $0x2,%eax + 800f28: 89 c1 mov %eax,%ecx + asm volatile ( + 800f2a: 8b 55 f4 mov -0xc(%ebp),%edx + 800f2d: 8b 45 f0 mov -0x10(%ebp),%eax + 800f30: 89 d7 mov %edx,%edi + 800f32: 89 c6 mov %eax,%esi + 800f34: f3 a5 rep movsl %ds:(%esi),%es:(%edi) + 800f36: 8b 4d ec mov -0x14(%ebp),%ecx + 800f39: 83 e1 03 and $0x3,%ecx + 800f3c: 74 02 je 800f40 + 800f3e: f3 a4 rep movsb %ds:(%esi),%es:(%edi) + 800f40: 89 f0 mov %esi,%eax + 800f42: 89 fa mov %edi,%edx + 800f44: 89 4d e8 mov %ecx,-0x18(%ebp) + 800f47: 89 55 e4 mov %edx,-0x1c(%ebp) + 800f4a: 89 45 e0 mov %eax,-0x20(%ebp) + return dst; + 800f4d: 8b 45 f4 mov -0xc(%ebp),%eax + while (n -- > 0) { + *d ++ = *s ++; + } + return dst; +#endif /* __HAVE_ARCH_MEMCPY */ +} + 800f50: 83 c4 20 add $0x20,%esp + 800f53: 5e pop %esi + 800f54: 5f pop %edi + 800f55: 5d pop %ebp + 800f56: c3 ret + +00800f57 : + * match in both memory blocks has a greater value in @v1 than in @v2 + * as if evaluated as unsigned char values; + * - And a value less than zero indicates the opposite. + * */ +int +memcmp(const void *v1, const void *v2, size_t n) { + 800f57: 55 push %ebp + 800f58: 89 e5 mov %esp,%ebp + 800f5a: 83 ec 10 sub $0x10,%esp + const char *s1 = (const char *)v1; + 800f5d: 8b 45 08 mov 0x8(%ebp),%eax + 800f60: 89 45 fc mov %eax,-0x4(%ebp) + const char *s2 = (const char *)v2; + 800f63: 8b 45 0c mov 0xc(%ebp),%eax + 800f66: 89 45 f8 mov %eax,-0x8(%ebp) + while (n -- > 0) { + 800f69: eb 2e jmp 800f99 + if (*s1 != *s2) { + 800f6b: 8b 45 fc mov -0x4(%ebp),%eax + 800f6e: 0f b6 10 movzbl (%eax),%edx + 800f71: 8b 45 f8 mov -0x8(%ebp),%eax + 800f74: 0f b6 00 movzbl (%eax),%eax + 800f77: 38 c2 cmp %al,%dl + 800f79: 74 18 je 800f93 + return (int)((unsigned char)*s1 - (unsigned char)*s2); + 800f7b: 8b 45 fc mov -0x4(%ebp),%eax + 800f7e: 0f b6 00 movzbl (%eax),%eax + 800f81: 0f b6 d0 movzbl %al,%edx + 800f84: 8b 45 f8 mov -0x8(%ebp),%eax + 800f87: 0f b6 00 movzbl (%eax),%eax + 800f8a: 0f b6 c8 movzbl %al,%ecx + 800f8d: 89 d0 mov %edx,%eax + 800f8f: 29 c8 sub %ecx,%eax + 800f91: eb 18 jmp 800fab + } + s1 ++, s2 ++; + 800f93: ff 45 fc incl -0x4(%ebp) + 800f96: ff 45 f8 incl -0x8(%ebp) + while (n -- > 0) { + 800f99: 8b 45 10 mov 0x10(%ebp),%eax + 800f9c: 8d 50 ff lea -0x1(%eax),%edx + 800f9f: 89 55 10 mov %edx,0x10(%ebp) + 800fa2: 85 c0 test %eax,%eax + 800fa4: 75 c5 jne 800f6b + } + return 0; + 800fa6: b8 00 00 00 00 mov $0x0,%eax +} + 800fab: 89 ec mov %ebp,%esp + 800fad: 5d pop %ebp + 800fae: c3 ret + +00800faf
: +#include + +int zero; + +int +main(void) { + 800faf: 55 push %ebp + 800fb0: 89 e5 mov %esp,%ebp + 800fb2: 83 e4 f0 and $0xfffffff0,%esp + 800fb5: 83 ec 10 sub $0x10,%esp + cprintf("value is %d.\n", 1 / zero); + 800fb8: 8b 0d 08 20 80 00 mov 0x802008,%ecx + 800fbe: b8 01 00 00 00 mov $0x1,%eax + 800fc3: 99 cltd + 800fc4: f7 f9 idiv %ecx + 800fc6: 89 44 24 04 mov %eax,0x4(%esp) + 800fca: c7 04 24 e0 12 80 00 movl $0x8012e0,(%esp) + 800fd1: e8 4a f1 ff ff call 800120 + panic("FAIL: T.T\n"); + 800fd6: c7 44 24 08 ee 12 80 movl $0x8012ee,0x8(%esp) + 800fdd: 00 + 800fde: c7 44 24 04 09 00 00 movl $0x9,0x4(%esp) + 800fe5: 00 + 800fe6: c7 04 24 f9 12 80 00 movl $0x8012f9,(%esp) + 800fed: e8 3d f0 ff ff call 80002f <__panic> diff --git a/labcodes/lab5/obj/user/divzero.d b/labcodes/lab5/obj/user/divzero.d new file mode 100644 index 0000000000000000000000000000000000000000..2237faf800b2e178f2133da258addc1feeaf5d9d --- /dev/null +++ b/labcodes/lab5/obj/user/divzero.d @@ -0,0 +1,2 @@ +obj/user/divzero.o obj/user/divzero.d: user/divzero.c libs/stdio.h \ + libs/defs.h libs/stdarg.h user/libs/ulib.h diff --git a/labcodes/lab5/obj/user/divzero.o b/labcodes/lab5/obj/user/divzero.o new file mode 100644 index 0000000000000000000000000000000000000000..735775a61884211743ee1f737e901f51db667f26 Binary files /dev/null and b/labcodes/lab5/obj/user/divzero.o differ diff --git a/labcodes/lab5/obj/user/divzero.sym b/labcodes/lab5/obj/user/divzero.sym new file mode 100644 index 0000000000000000000000000000000000000000..4275c0623deee0729fd8da0338f1ca9966307934 --- /dev/null +++ b/labcodes/lab5/obj/user/divzero.sym @@ -0,0 +1,67 @@ +00000000 panic.c +00000000 stdio.c +008000c8 cputch +00000000 syscall.c +00800199 syscall +00000000 ulib.c +00000000 umain.c +00000000 hash.c +00000000 printfmt.c +00801100 error_string +008003ad printnum +008004af getuint +008004fe getint +0080094f sprintputch +00000000 rand.c +00802000 next +00000000 string.c +00000000 divzero.c +00800b53 strcpy +00800329 yield +0080030d waitpid +00800245 sys_yield +00800e65 memmove +00800985 snprintf +00800576 vprintfmt +0080020b sys_fork +00800120 cprintf +0080034e getpid +00800f08 memcpy +008009bb vsnprintf +0080036d umain +002026c8 __STAB_END__ +0080025b sys_kill +002026c9 __STABSTR_BEGIN__ +0080002f __panic +00800ccb strtol +00800b22 strnlen +0080035d print_pgdir +00800339 kill +00800c9b strfind +008002ef wait +00800020 _start +00800a21 rand +00800c14 strncmp +0080028e sys_putc +00800b92 strncpy +00800f57 memcmp +008002e0 fork +00800e23 memset +00800faf main +00800ae0 srand +00800386 hash32 +00800545 printfmt +002035e4 __STABSTR_END__ +00800bcb strcmp +00802008 zero +008000eb vcprintf +0080007f __warn +00800148 cputs +008002c1 exit +00800221 sys_wait +008001ee sys_exit +00200010 __STAB_BEGIN__ +00800af9 strlen +008002ab sys_pgdir +00800c67 strchr +00800278 sys_getpid diff --git a/labcodes/lab5/obj/user/exit.asm b/labcodes/lab5/obj/user/exit.asm new file mode 100644 index 0000000000000000000000000000000000000000..3db72a62cf84809d1217808cb8f79bb6095ca10c --- /dev/null +++ b/labcodes/lab5/obj/user/exit.asm @@ -0,0 +1,2418 @@ + +obj/__user_exit.out: file format elf32-i386 + + +Disassembly of section .text: + +00800020 <_start>: +.text +.globl _start +_start: + # set ebp for backtrace + movl $0x0, %ebp + 800020: bd 00 00 00 00 mov $0x0,%ebp + + # move down the esp register + # since it may cause page fault in backtrace + subl $0x20, %esp + 800025: 83 ec 20 sub $0x20,%esp + + # call user-program function + call umain + 800028: e8 40 03 00 00 call 80036d +1: jmp 1b + 80002d: eb fe jmp 80002d <_start+0xd> + +0080002f <__panic>: +#include +#include +#include + +void +__panic(const char *file, int line, const char *fmt, ...) { + 80002f: 55 push %ebp + 800030: 89 e5 mov %esp,%ebp + 800032: 83 ec 28 sub $0x28,%esp + // print the 'message' + va_list ap; + va_start(ap, fmt); + 800035: 8d 45 14 lea 0x14(%ebp),%eax + 800038: 89 45 f4 mov %eax,-0xc(%ebp) + cprintf("user panic at %s:%d:\n ", file, line); + 80003b: 8b 45 0c mov 0xc(%ebp),%eax + 80003e: 89 44 24 08 mov %eax,0x8(%esp) + 800042: 8b 45 08 mov 0x8(%ebp),%eax + 800045: 89 44 24 04 mov %eax,0x4(%esp) + 800049: c7 04 24 20 11 80 00 movl $0x801120,(%esp) + 800050: e8 cb 00 00 00 call 800120 + vcprintf(fmt, ap); + 800055: 8b 45 f4 mov -0xc(%ebp),%eax + 800058: 89 44 24 04 mov %eax,0x4(%esp) + 80005c: 8b 45 10 mov 0x10(%ebp),%eax + 80005f: 89 04 24 mov %eax,(%esp) + 800062: e8 84 00 00 00 call 8000eb + cprintf("\n"); + 800067: c7 04 24 3a 11 80 00 movl $0x80113a,(%esp) + 80006e: e8 ad 00 00 00 call 800120 + va_end(ap); + exit(-E_PANIC); + 800073: c7 04 24 f6 ff ff ff movl $0xfffffff6,(%esp) + 80007a: e8 42 02 00 00 call 8002c1 + +0080007f <__warn>: +} + +void +__warn(const char *file, int line, const char *fmt, ...) { + 80007f: 55 push %ebp + 800080: 89 e5 mov %esp,%ebp + 800082: 83 ec 28 sub $0x28,%esp + va_list ap; + va_start(ap, fmt); + 800085: 8d 45 14 lea 0x14(%ebp),%eax + 800088: 89 45 f4 mov %eax,-0xc(%ebp) + cprintf("user warning at %s:%d:\n ", file, line); + 80008b: 8b 45 0c mov 0xc(%ebp),%eax + 80008e: 89 44 24 08 mov %eax,0x8(%esp) + 800092: 8b 45 08 mov 0x8(%ebp),%eax + 800095: 89 44 24 04 mov %eax,0x4(%esp) + 800099: c7 04 24 3c 11 80 00 movl $0x80113c,(%esp) + 8000a0: e8 7b 00 00 00 call 800120 + vcprintf(fmt, ap); + 8000a5: 8b 45 f4 mov -0xc(%ebp),%eax + 8000a8: 89 44 24 04 mov %eax,0x4(%esp) + 8000ac: 8b 45 10 mov 0x10(%ebp),%eax + 8000af: 89 04 24 mov %eax,(%esp) + 8000b2: e8 34 00 00 00 call 8000eb + cprintf("\n"); + 8000b7: c7 04 24 3a 11 80 00 movl $0x80113a,(%esp) + 8000be: e8 5d 00 00 00 call 800120 + va_end(ap); +} + 8000c3: 90 nop + 8000c4: 89 ec mov %ebp,%esp + 8000c6: 5d pop %ebp + 8000c7: c3 ret + +008000c8 : +/* * + * cputch - writes a single character @c to stdout, and it will + * increace the value of counter pointed by @cnt. + * */ +static void +cputch(int c, int *cnt) { + 8000c8: 55 push %ebp + 8000c9: 89 e5 mov %esp,%ebp + 8000cb: 83 ec 18 sub $0x18,%esp + sys_putc(c); + 8000ce: 8b 45 08 mov 0x8(%ebp),%eax + 8000d1: 89 04 24 mov %eax,(%esp) + 8000d4: e8 b5 01 00 00 call 80028e + (*cnt) ++; + 8000d9: 8b 45 0c mov 0xc(%ebp),%eax + 8000dc: 8b 00 mov (%eax),%eax + 8000de: 8d 50 01 lea 0x1(%eax),%edx + 8000e1: 8b 45 0c mov 0xc(%ebp),%eax + 8000e4: 89 10 mov %edx,(%eax) +} + 8000e6: 90 nop + 8000e7: 89 ec mov %ebp,%esp + 8000e9: 5d pop %ebp + 8000ea: c3 ret + +008000eb : + * + * Call this function if you are already dealing with a va_list. + * Or you probably want cprintf() instead. + * */ +int +vcprintf(const char *fmt, va_list ap) { + 8000eb: 55 push %ebp + 8000ec: 89 e5 mov %esp,%ebp + 8000ee: 83 ec 28 sub $0x28,%esp + int cnt = 0; + 8000f1: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + vprintfmt((void*)cputch, &cnt, fmt, ap); + 8000f8: 8b 45 0c mov 0xc(%ebp),%eax + 8000fb: 89 44 24 0c mov %eax,0xc(%esp) + 8000ff: 8b 45 08 mov 0x8(%ebp),%eax + 800102: 89 44 24 08 mov %eax,0x8(%esp) + 800106: 8d 45 f4 lea -0xc(%ebp),%eax + 800109: 89 44 24 04 mov %eax,0x4(%esp) + 80010d: c7 04 24 c8 00 80 00 movl $0x8000c8,(%esp) + 800114: e8 5d 04 00 00 call 800576 + return cnt; + 800119: 8b 45 f4 mov -0xc(%ebp),%eax +} + 80011c: 89 ec mov %ebp,%esp + 80011e: 5d pop %ebp + 80011f: c3 ret + +00800120 : + * + * The return value is the number of characters which would be + * written to stdout. + * */ +int +cprintf(const char *fmt, ...) { + 800120: 55 push %ebp + 800121: 89 e5 mov %esp,%ebp + 800123: 83 ec 28 sub $0x28,%esp + va_list ap; + + va_start(ap, fmt); + 800126: 8d 45 0c lea 0xc(%ebp),%eax + 800129: 89 45 f0 mov %eax,-0x10(%ebp) + int cnt = vcprintf(fmt, ap); + 80012c: 8b 45 f0 mov -0x10(%ebp),%eax + 80012f: 89 44 24 04 mov %eax,0x4(%esp) + 800133: 8b 45 08 mov 0x8(%ebp),%eax + 800136: 89 04 24 mov %eax,(%esp) + 800139: e8 ad ff ff ff call 8000eb + 80013e: 89 45 f4 mov %eax,-0xc(%ebp) + va_end(ap); + + return cnt; + 800141: 8b 45 f4 mov -0xc(%ebp),%eax +} + 800144: 89 ec mov %ebp,%esp + 800146: 5d pop %ebp + 800147: c3 ret + +00800148 : +/* * + * cputs- writes the string pointed by @str to stdout and + * appends a newline character. + * */ +int +cputs(const char *str) { + 800148: 55 push %ebp + 800149: 89 e5 mov %esp,%ebp + 80014b: 83 ec 28 sub $0x28,%esp + int cnt = 0; + 80014e: c7 45 f0 00 00 00 00 movl $0x0,-0x10(%ebp) + char c; + while ((c = *str ++) != '\0') { + 800155: eb 13 jmp 80016a + cputch(c, &cnt); + 800157: 0f be 45 f7 movsbl -0x9(%ebp),%eax + 80015b: 8d 55 f0 lea -0x10(%ebp),%edx + 80015e: 89 54 24 04 mov %edx,0x4(%esp) + 800162: 89 04 24 mov %eax,(%esp) + 800165: e8 5e ff ff ff call 8000c8 + while ((c = *str ++) != '\0') { + 80016a: 8b 45 08 mov 0x8(%ebp),%eax + 80016d: 8d 50 01 lea 0x1(%eax),%edx + 800170: 89 55 08 mov %edx,0x8(%ebp) + 800173: 0f b6 00 movzbl (%eax),%eax + 800176: 88 45 f7 mov %al,-0x9(%ebp) + 800179: 80 7d f7 00 cmpb $0x0,-0x9(%ebp) + 80017d: 75 d8 jne 800157 + } + cputch('\n', &cnt); + 80017f: 8d 45 f0 lea -0x10(%ebp),%eax + 800182: 89 44 24 04 mov %eax,0x4(%esp) + 800186: c7 04 24 0a 00 00 00 movl $0xa,(%esp) + 80018d: e8 36 ff ff ff call 8000c8 + return cnt; + 800192: 8b 45 f0 mov -0x10(%ebp),%eax +} + 800195: 89 ec mov %ebp,%esp + 800197: 5d pop %ebp + 800198: c3 ret + +00800199 : +#include + +#define MAX_ARGS 5 + +static inline int +syscall(int num, ...) { + 800199: 55 push %ebp + 80019a: 89 e5 mov %esp,%ebp + 80019c: 57 push %edi + 80019d: 56 push %esi + 80019e: 53 push %ebx + 80019f: 83 ec 20 sub $0x20,%esp + va_list ap; + va_start(ap, num); + 8001a2: 8d 45 0c lea 0xc(%ebp),%eax + 8001a5: 89 45 e8 mov %eax,-0x18(%ebp) + uint32_t a[MAX_ARGS]; + int i, ret; + for (i = 0; i < MAX_ARGS; i ++) { + 8001a8: c7 45 f0 00 00 00 00 movl $0x0,-0x10(%ebp) + 8001af: eb 15 jmp 8001c6 + a[i] = va_arg(ap, uint32_t); + 8001b1: 8b 45 e8 mov -0x18(%ebp),%eax + 8001b4: 8d 50 04 lea 0x4(%eax),%edx + 8001b7: 89 55 e8 mov %edx,-0x18(%ebp) + 8001ba: 8b 10 mov (%eax),%edx + 8001bc: 8b 45 f0 mov -0x10(%ebp),%eax + 8001bf: 89 54 85 d4 mov %edx,-0x2c(%ebp,%eax,4) + for (i = 0; i < MAX_ARGS; i ++) { + 8001c3: ff 45 f0 incl -0x10(%ebp) + 8001c6: 83 7d f0 04 cmpl $0x4,-0x10(%ebp) + 8001ca: 7e e5 jle 8001b1 + asm volatile ( + "int %1;" + : "=a" (ret) + : "i" (T_SYSCALL), + "a" (num), + "d" (a[0]), + 8001cc: 8b 55 d4 mov -0x2c(%ebp),%edx + "c" (a[1]), + 8001cf: 8b 4d d8 mov -0x28(%ebp),%ecx + "b" (a[2]), + 8001d2: 8b 5d dc mov -0x24(%ebp),%ebx + "D" (a[3]), + 8001d5: 8b 7d e0 mov -0x20(%ebp),%edi + "S" (a[4]) + 8001d8: 8b 75 e4 mov -0x1c(%ebp),%esi + asm volatile ( + 8001db: 8b 45 08 mov 0x8(%ebp),%eax + 8001de: cd 80 int $0x80 + 8001e0: 89 45 ec mov %eax,-0x14(%ebp) + : "cc", "memory"); + return ret; + 8001e3: 8b 45 ec mov -0x14(%ebp),%eax +} + 8001e6: 83 c4 20 add $0x20,%esp + 8001e9: 5b pop %ebx + 8001ea: 5e pop %esi + 8001eb: 5f pop %edi + 8001ec: 5d pop %ebp + 8001ed: c3 ret + +008001ee : + +int +sys_exit(int error_code) { + 8001ee: 55 push %ebp + 8001ef: 89 e5 mov %esp,%ebp + 8001f1: 83 ec 08 sub $0x8,%esp + return syscall(SYS_exit, error_code); + 8001f4: 8b 45 08 mov 0x8(%ebp),%eax + 8001f7: 89 44 24 04 mov %eax,0x4(%esp) + 8001fb: c7 04 24 01 00 00 00 movl $0x1,(%esp) + 800202: e8 92 ff ff ff call 800199 +} + 800207: 89 ec mov %ebp,%esp + 800209: 5d pop %ebp + 80020a: c3 ret + +0080020b : + +int +sys_fork(void) { + 80020b: 55 push %ebp + 80020c: 89 e5 mov %esp,%ebp + 80020e: 83 ec 04 sub $0x4,%esp + return syscall(SYS_fork); + 800211: c7 04 24 02 00 00 00 movl $0x2,(%esp) + 800218: e8 7c ff ff ff call 800199 +} + 80021d: 89 ec mov %ebp,%esp + 80021f: 5d pop %ebp + 800220: c3 ret + +00800221 : + +int +sys_wait(int pid, int *store) { + 800221: 55 push %ebp + 800222: 89 e5 mov %esp,%ebp + 800224: 83 ec 0c sub $0xc,%esp + return syscall(SYS_wait, pid, store); + 800227: 8b 45 0c mov 0xc(%ebp),%eax + 80022a: 89 44 24 08 mov %eax,0x8(%esp) + 80022e: 8b 45 08 mov 0x8(%ebp),%eax + 800231: 89 44 24 04 mov %eax,0x4(%esp) + 800235: c7 04 24 03 00 00 00 movl $0x3,(%esp) + 80023c: e8 58 ff ff ff call 800199 +} + 800241: 89 ec mov %ebp,%esp + 800243: 5d pop %ebp + 800244: c3 ret + +00800245 : + +int +sys_yield(void) { + 800245: 55 push %ebp + 800246: 89 e5 mov %esp,%ebp + 800248: 83 ec 04 sub $0x4,%esp + return syscall(SYS_yield); + 80024b: c7 04 24 0a 00 00 00 movl $0xa,(%esp) + 800252: e8 42 ff ff ff call 800199 +} + 800257: 89 ec mov %ebp,%esp + 800259: 5d pop %ebp + 80025a: c3 ret + +0080025b : + +int +sys_kill(int pid) { + 80025b: 55 push %ebp + 80025c: 89 e5 mov %esp,%ebp + 80025e: 83 ec 08 sub $0x8,%esp + return syscall(SYS_kill, pid); + 800261: 8b 45 08 mov 0x8(%ebp),%eax + 800264: 89 44 24 04 mov %eax,0x4(%esp) + 800268: c7 04 24 0c 00 00 00 movl $0xc,(%esp) + 80026f: e8 25 ff ff ff call 800199 +} + 800274: 89 ec mov %ebp,%esp + 800276: 5d pop %ebp + 800277: c3 ret + +00800278 : + +int +sys_getpid(void) { + 800278: 55 push %ebp + 800279: 89 e5 mov %esp,%ebp + 80027b: 83 ec 04 sub $0x4,%esp + return syscall(SYS_getpid); + 80027e: c7 04 24 12 00 00 00 movl $0x12,(%esp) + 800285: e8 0f ff ff ff call 800199 +} + 80028a: 89 ec mov %ebp,%esp + 80028c: 5d pop %ebp + 80028d: c3 ret + +0080028e : + +int +sys_putc(int c) { + 80028e: 55 push %ebp + 80028f: 89 e5 mov %esp,%ebp + 800291: 83 ec 08 sub $0x8,%esp + return syscall(SYS_putc, c); + 800294: 8b 45 08 mov 0x8(%ebp),%eax + 800297: 89 44 24 04 mov %eax,0x4(%esp) + 80029b: c7 04 24 1e 00 00 00 movl $0x1e,(%esp) + 8002a2: e8 f2 fe ff ff call 800199 +} + 8002a7: 89 ec mov %ebp,%esp + 8002a9: 5d pop %ebp + 8002aa: c3 ret + +008002ab : + +int +sys_pgdir(void) { + 8002ab: 55 push %ebp + 8002ac: 89 e5 mov %esp,%ebp + 8002ae: 83 ec 04 sub $0x4,%esp + return syscall(SYS_pgdir); + 8002b1: c7 04 24 1f 00 00 00 movl $0x1f,(%esp) + 8002b8: e8 dc fe ff ff call 800199 +} + 8002bd: 89 ec mov %ebp,%esp + 8002bf: 5d pop %ebp + 8002c0: c3 ret + +008002c1 : +#include +#include +#include + +void +exit(int error_code) { + 8002c1: 55 push %ebp + 8002c2: 89 e5 mov %esp,%ebp + 8002c4: 83 ec 18 sub $0x18,%esp + sys_exit(error_code); + 8002c7: 8b 45 08 mov 0x8(%ebp),%eax + 8002ca: 89 04 24 mov %eax,(%esp) + 8002cd: e8 1c ff ff ff call 8001ee + cprintf("BUG: exit failed.\n"); + 8002d2: c7 04 24 58 11 80 00 movl $0x801158,(%esp) + 8002d9: e8 42 fe ff ff call 800120 + while (1); + 8002de: eb fe jmp 8002de + +008002e0 : +} + +int +fork(void) { + 8002e0: 55 push %ebp + 8002e1: 89 e5 mov %esp,%ebp + 8002e3: 83 ec 08 sub $0x8,%esp + return sys_fork(); + 8002e6: e8 20 ff ff ff call 80020b +} + 8002eb: 89 ec mov %ebp,%esp + 8002ed: 5d pop %ebp + 8002ee: c3 ret + +008002ef : + +int +wait(void) { + 8002ef: 55 push %ebp + 8002f0: 89 e5 mov %esp,%ebp + 8002f2: 83 ec 18 sub $0x18,%esp + return sys_wait(0, NULL); + 8002f5: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) + 8002fc: 00 + 8002fd: c7 04 24 00 00 00 00 movl $0x0,(%esp) + 800304: e8 18 ff ff ff call 800221 +} + 800309: 89 ec mov %ebp,%esp + 80030b: 5d pop %ebp + 80030c: c3 ret + +0080030d : + +int +waitpid(int pid, int *store) { + 80030d: 55 push %ebp + 80030e: 89 e5 mov %esp,%ebp + 800310: 83 ec 18 sub $0x18,%esp + return sys_wait(pid, store); + 800313: 8b 45 0c mov 0xc(%ebp),%eax + 800316: 89 44 24 04 mov %eax,0x4(%esp) + 80031a: 8b 45 08 mov 0x8(%ebp),%eax + 80031d: 89 04 24 mov %eax,(%esp) + 800320: e8 fc fe ff ff call 800221 +} + 800325: 89 ec mov %ebp,%esp + 800327: 5d pop %ebp + 800328: c3 ret + +00800329 : + +void +yield(void) { + 800329: 55 push %ebp + 80032a: 89 e5 mov %esp,%ebp + 80032c: 83 ec 08 sub $0x8,%esp + sys_yield(); + 80032f: e8 11 ff ff ff call 800245 +} + 800334: 90 nop + 800335: 89 ec mov %ebp,%esp + 800337: 5d pop %ebp + 800338: c3 ret + +00800339 : + +int +kill(int pid) { + 800339: 55 push %ebp + 80033a: 89 e5 mov %esp,%ebp + 80033c: 83 ec 18 sub $0x18,%esp + return sys_kill(pid); + 80033f: 8b 45 08 mov 0x8(%ebp),%eax + 800342: 89 04 24 mov %eax,(%esp) + 800345: e8 11 ff ff ff call 80025b +} + 80034a: 89 ec mov %ebp,%esp + 80034c: 5d pop %ebp + 80034d: c3 ret + +0080034e : + +int +getpid(void) { + 80034e: 55 push %ebp + 80034f: 89 e5 mov %esp,%ebp + 800351: 83 ec 08 sub $0x8,%esp + return sys_getpid(); + 800354: e8 1f ff ff ff call 800278 +} + 800359: 89 ec mov %ebp,%esp + 80035b: 5d pop %ebp + 80035c: c3 ret + +0080035d : + +//print_pgdir - print the PDT&PT +void +print_pgdir(void) { + 80035d: 55 push %ebp + 80035e: 89 e5 mov %esp,%ebp + 800360: 83 ec 08 sub $0x8,%esp + sys_pgdir(); + 800363: e8 43 ff ff ff call 8002ab +} + 800368: 90 nop + 800369: 89 ec mov %ebp,%esp + 80036b: 5d pop %ebp + 80036c: c3 ret + +0080036d : +#include + +int main(void); + +void +umain(void) { + 80036d: 55 push %ebp + 80036e: 89 e5 mov %esp,%ebp + 800370: 83 ec 28 sub $0x28,%esp + int ret = main(); + 800373: e8 37 0c 00 00 call 800faf
+ 800378: 89 45 f4 mov %eax,-0xc(%ebp) + exit(ret); + 80037b: 8b 45 f4 mov -0xc(%ebp),%eax + 80037e: 89 04 24 mov %eax,(%esp) + 800381: e8 3b ff ff ff call 8002c1 + +00800386 : + * @bits: the number of bits in a return value + * + * High bits are more random, so we use them. + * */ +uint32_t +hash32(uint32_t val, unsigned int bits) { + 800386: 55 push %ebp + 800387: 89 e5 mov %esp,%ebp + 800389: 83 ec 10 sub $0x10,%esp + uint32_t hash = val * GOLDEN_RATIO_PRIME_32; + 80038c: 8b 45 08 mov 0x8(%ebp),%eax + 80038f: 69 c0 01 00 37 9e imul $0x9e370001,%eax,%eax + 800395: 89 45 fc mov %eax,-0x4(%ebp) + return (hash >> (32 - bits)); + 800398: b8 20 00 00 00 mov $0x20,%eax + 80039d: 2b 45 0c sub 0xc(%ebp),%eax + 8003a0: 8b 55 fc mov -0x4(%ebp),%edx + 8003a3: 88 c1 mov %al,%cl + 8003a5: d3 ea shr %cl,%edx + 8003a7: 89 d0 mov %edx,%eax +} + 8003a9: 89 ec mov %ebp,%esp + 8003ab: 5d pop %ebp + 8003ac: c3 ret + +008003ad : + * @width: maximum number of digits, if the actual width is less than @width, use @padc instead + * @padc: character that padded on the left if the actual width is less than @width + * */ +static void +printnum(void (*putch)(int, void*), void *putdat, + unsigned long long num, unsigned base, int width, int padc) { + 8003ad: 55 push %ebp + 8003ae: 89 e5 mov %esp,%ebp + 8003b0: 83 ec 58 sub $0x58,%esp + 8003b3: 8b 45 10 mov 0x10(%ebp),%eax + 8003b6: 89 45 d0 mov %eax,-0x30(%ebp) + 8003b9: 8b 45 14 mov 0x14(%ebp),%eax + 8003bc: 89 45 d4 mov %eax,-0x2c(%ebp) + unsigned long long result = num; + 8003bf: 8b 45 d0 mov -0x30(%ebp),%eax + 8003c2: 8b 55 d4 mov -0x2c(%ebp),%edx + 8003c5: 89 45 e8 mov %eax,-0x18(%ebp) + 8003c8: 89 55 ec mov %edx,-0x14(%ebp) + unsigned mod = do_div(result, base); + 8003cb: 8b 45 18 mov 0x18(%ebp),%eax + 8003ce: 89 45 e4 mov %eax,-0x1c(%ebp) + 8003d1: 8b 45 e8 mov -0x18(%ebp),%eax + 8003d4: 8b 55 ec mov -0x14(%ebp),%edx + 8003d7: 89 45 e0 mov %eax,-0x20(%ebp) + 8003da: 89 55 f0 mov %edx,-0x10(%ebp) + 8003dd: 8b 45 f0 mov -0x10(%ebp),%eax + 8003e0: 89 45 f4 mov %eax,-0xc(%ebp) + 8003e3: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) + 8003e7: 74 1c je 800405 + 8003e9: 8b 45 f0 mov -0x10(%ebp),%eax + 8003ec: ba 00 00 00 00 mov $0x0,%edx + 8003f1: f7 75 e4 divl -0x1c(%ebp) + 8003f4: 89 55 f4 mov %edx,-0xc(%ebp) + 8003f7: 8b 45 f0 mov -0x10(%ebp),%eax + 8003fa: ba 00 00 00 00 mov $0x0,%edx + 8003ff: f7 75 e4 divl -0x1c(%ebp) + 800402: 89 45 f0 mov %eax,-0x10(%ebp) + 800405: 8b 45 e0 mov -0x20(%ebp),%eax + 800408: 8b 55 f4 mov -0xc(%ebp),%edx + 80040b: f7 75 e4 divl -0x1c(%ebp) + 80040e: 89 45 e0 mov %eax,-0x20(%ebp) + 800411: 89 55 dc mov %edx,-0x24(%ebp) + 800414: 8b 45 e0 mov -0x20(%ebp),%eax + 800417: 8b 55 f0 mov -0x10(%ebp),%edx + 80041a: 89 45 e8 mov %eax,-0x18(%ebp) + 80041d: 89 55 ec mov %edx,-0x14(%ebp) + 800420: 8b 45 dc mov -0x24(%ebp),%eax + 800423: 89 45 d8 mov %eax,-0x28(%ebp) + + // first recursively print all preceding (more significant) digits + if (num >= base) { + 800426: 8b 45 18 mov 0x18(%ebp),%eax + 800429: ba 00 00 00 00 mov $0x0,%edx + 80042e: 8b 4d d4 mov -0x2c(%ebp),%ecx + 800431: 39 45 d0 cmp %eax,-0x30(%ebp) + 800434: 19 d1 sbb %edx,%ecx + 800436: 72 4c jb 800484 + printnum(putch, putdat, result, base, width - 1, padc); + 800438: 8b 45 1c mov 0x1c(%ebp),%eax + 80043b: 8d 50 ff lea -0x1(%eax),%edx + 80043e: 8b 45 20 mov 0x20(%ebp),%eax + 800441: 89 44 24 18 mov %eax,0x18(%esp) + 800445: 89 54 24 14 mov %edx,0x14(%esp) + 800449: 8b 45 18 mov 0x18(%ebp),%eax + 80044c: 89 44 24 10 mov %eax,0x10(%esp) + 800450: 8b 45 e8 mov -0x18(%ebp),%eax + 800453: 8b 55 ec mov -0x14(%ebp),%edx + 800456: 89 44 24 08 mov %eax,0x8(%esp) + 80045a: 89 54 24 0c mov %edx,0xc(%esp) + 80045e: 8b 45 0c mov 0xc(%ebp),%eax + 800461: 89 44 24 04 mov %eax,0x4(%esp) + 800465: 8b 45 08 mov 0x8(%ebp),%eax + 800468: 89 04 24 mov %eax,(%esp) + 80046b: e8 3d ff ff ff call 8003ad + 800470: eb 1b jmp 80048d + } else { + // print any needed pad characters before first digit + while (-- width > 0) + putch(padc, putdat); + 800472: 8b 45 0c mov 0xc(%ebp),%eax + 800475: 89 44 24 04 mov %eax,0x4(%esp) + 800479: 8b 45 20 mov 0x20(%ebp),%eax + 80047c: 89 04 24 mov %eax,(%esp) + 80047f: 8b 45 08 mov 0x8(%ebp),%eax + 800482: ff d0 call *%eax + while (-- width > 0) + 800484: ff 4d 1c decl 0x1c(%ebp) + 800487: 83 7d 1c 00 cmpl $0x0,0x1c(%ebp) + 80048b: 7f e5 jg 800472 + } + // then print this (the least significant) digit + putch("0123456789abcdef"[mod], putdat); + 80048d: 8b 45 d8 mov -0x28(%ebp),%eax + 800490: 05 84 12 80 00 add $0x801284,%eax + 800495: 0f b6 00 movzbl (%eax),%eax + 800498: 0f be c0 movsbl %al,%eax + 80049b: 8b 55 0c mov 0xc(%ebp),%edx + 80049e: 89 54 24 04 mov %edx,0x4(%esp) + 8004a2: 89 04 24 mov %eax,(%esp) + 8004a5: 8b 45 08 mov 0x8(%ebp),%eax + 8004a8: ff d0 call *%eax +} + 8004aa: 90 nop + 8004ab: 89 ec mov %ebp,%esp + 8004ad: 5d pop %ebp + 8004ae: c3 ret + +008004af : + * getuint - get an unsigned int of various possible sizes from a varargs list + * @ap: a varargs list pointer + * @lflag: determines the size of the vararg that @ap points to + * */ +static unsigned long long +getuint(va_list *ap, int lflag) { + 8004af: 55 push %ebp + 8004b0: 89 e5 mov %esp,%ebp + if (lflag >= 2) { + 8004b2: 83 7d 0c 01 cmpl $0x1,0xc(%ebp) + 8004b6: 7e 14 jle 8004cc + return va_arg(*ap, unsigned long long); + 8004b8: 8b 45 08 mov 0x8(%ebp),%eax + 8004bb: 8b 00 mov (%eax),%eax + 8004bd: 8d 48 08 lea 0x8(%eax),%ecx + 8004c0: 8b 55 08 mov 0x8(%ebp),%edx + 8004c3: 89 0a mov %ecx,(%edx) + 8004c5: 8b 50 04 mov 0x4(%eax),%edx + 8004c8: 8b 00 mov (%eax),%eax + 8004ca: eb 30 jmp 8004fc + } + else if (lflag) { + 8004cc: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) + 8004d0: 74 16 je 8004e8 + return va_arg(*ap, unsigned long); + 8004d2: 8b 45 08 mov 0x8(%ebp),%eax + 8004d5: 8b 00 mov (%eax),%eax + 8004d7: 8d 48 04 lea 0x4(%eax),%ecx + 8004da: 8b 55 08 mov 0x8(%ebp),%edx + 8004dd: 89 0a mov %ecx,(%edx) + 8004df: 8b 00 mov (%eax),%eax + 8004e1: ba 00 00 00 00 mov $0x0,%edx + 8004e6: eb 14 jmp 8004fc + } + else { + return va_arg(*ap, unsigned int); + 8004e8: 8b 45 08 mov 0x8(%ebp),%eax + 8004eb: 8b 00 mov (%eax),%eax + 8004ed: 8d 48 04 lea 0x4(%eax),%ecx + 8004f0: 8b 55 08 mov 0x8(%ebp),%edx + 8004f3: 89 0a mov %ecx,(%edx) + 8004f5: 8b 00 mov (%eax),%eax + 8004f7: ba 00 00 00 00 mov $0x0,%edx + } +} + 8004fc: 5d pop %ebp + 8004fd: c3 ret + +008004fe : + * getint - same as getuint but signed, we can't use getuint because of sign extension + * @ap: a varargs list pointer + * @lflag: determines the size of the vararg that @ap points to + * */ +static long long +getint(va_list *ap, int lflag) { + 8004fe: 55 push %ebp + 8004ff: 89 e5 mov %esp,%ebp + if (lflag >= 2) { + 800501: 83 7d 0c 01 cmpl $0x1,0xc(%ebp) + 800505: 7e 14 jle 80051b + return va_arg(*ap, long long); + 800507: 8b 45 08 mov 0x8(%ebp),%eax + 80050a: 8b 00 mov (%eax),%eax + 80050c: 8d 48 08 lea 0x8(%eax),%ecx + 80050f: 8b 55 08 mov 0x8(%ebp),%edx + 800512: 89 0a mov %ecx,(%edx) + 800514: 8b 50 04 mov 0x4(%eax),%edx + 800517: 8b 00 mov (%eax),%eax + 800519: eb 28 jmp 800543 + } + else if (lflag) { + 80051b: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) + 80051f: 74 12 je 800533 + return va_arg(*ap, long); + 800521: 8b 45 08 mov 0x8(%ebp),%eax + 800524: 8b 00 mov (%eax),%eax + 800526: 8d 48 04 lea 0x4(%eax),%ecx + 800529: 8b 55 08 mov 0x8(%ebp),%edx + 80052c: 89 0a mov %ecx,(%edx) + 80052e: 8b 00 mov (%eax),%eax + 800530: 99 cltd + 800531: eb 10 jmp 800543 + } + else { + return va_arg(*ap, int); + 800533: 8b 45 08 mov 0x8(%ebp),%eax + 800536: 8b 00 mov (%eax),%eax + 800538: 8d 48 04 lea 0x4(%eax),%ecx + 80053b: 8b 55 08 mov 0x8(%ebp),%edx + 80053e: 89 0a mov %ecx,(%edx) + 800540: 8b 00 mov (%eax),%eax + 800542: 99 cltd + } +} + 800543: 5d pop %ebp + 800544: c3 ret + +00800545 : + * @putch: specified putch function, print a single character + * @putdat: used by @putch function + * @fmt: the format string to use + * */ +void +printfmt(void (*putch)(int, void*), void *putdat, const char *fmt, ...) { + 800545: 55 push %ebp + 800546: 89 e5 mov %esp,%ebp + 800548: 83 ec 28 sub $0x28,%esp + va_list ap; + + va_start(ap, fmt); + 80054b: 8d 45 14 lea 0x14(%ebp),%eax + 80054e: 89 45 f4 mov %eax,-0xc(%ebp) + vprintfmt(putch, putdat, fmt, ap); + 800551: 8b 45 f4 mov -0xc(%ebp),%eax + 800554: 89 44 24 0c mov %eax,0xc(%esp) + 800558: 8b 45 10 mov 0x10(%ebp),%eax + 80055b: 89 44 24 08 mov %eax,0x8(%esp) + 80055f: 8b 45 0c mov 0xc(%ebp),%eax + 800562: 89 44 24 04 mov %eax,0x4(%esp) + 800566: 8b 45 08 mov 0x8(%ebp),%eax + 800569: 89 04 24 mov %eax,(%esp) + 80056c: e8 05 00 00 00 call 800576 + va_end(ap); +} + 800571: 90 nop + 800572: 89 ec mov %ebp,%esp + 800574: 5d pop %ebp + 800575: c3 ret + +00800576 : + * + * Call this function if you are already dealing with a va_list. + * Or you probably want printfmt() instead. + * */ +void +vprintfmt(void (*putch)(int, void*), void *putdat, const char *fmt, va_list ap) { + 800576: 55 push %ebp + 800577: 89 e5 mov %esp,%ebp + 800579: 56 push %esi + 80057a: 53 push %ebx + 80057b: 83 ec 40 sub $0x40,%esp + register int ch, err; + unsigned long long num; + int base, width, precision, lflag, altflag; + + while (1) { + while ((ch = *(unsigned char *)fmt ++) != '%') { + 80057e: eb 17 jmp 800597 + if (ch == '\0') { + 800580: 85 db test %ebx,%ebx + 800582: 0f 84 bf 03 00 00 je 800947 + return; + } + putch(ch, putdat); + 800588: 8b 45 0c mov 0xc(%ebp),%eax + 80058b: 89 44 24 04 mov %eax,0x4(%esp) + 80058f: 89 1c 24 mov %ebx,(%esp) + 800592: 8b 45 08 mov 0x8(%ebp),%eax + 800595: ff d0 call *%eax + while ((ch = *(unsigned char *)fmt ++) != '%') { + 800597: 8b 45 10 mov 0x10(%ebp),%eax + 80059a: 8d 50 01 lea 0x1(%eax),%edx + 80059d: 89 55 10 mov %edx,0x10(%ebp) + 8005a0: 0f b6 00 movzbl (%eax),%eax + 8005a3: 0f b6 d8 movzbl %al,%ebx + 8005a6: 83 fb 25 cmp $0x25,%ebx + 8005a9: 75 d5 jne 800580 + } + + // Process a %-escape sequence + char padc = ' '; + 8005ab: c6 45 db 20 movb $0x20,-0x25(%ebp) + width = precision = -1; + 8005af: c7 45 e4 ff ff ff ff movl $0xffffffff,-0x1c(%ebp) + 8005b6: 8b 45 e4 mov -0x1c(%ebp),%eax + 8005b9: 89 45 e8 mov %eax,-0x18(%ebp) + lflag = altflag = 0; + 8005bc: c7 45 dc 00 00 00 00 movl $0x0,-0x24(%ebp) + 8005c3: 8b 45 dc mov -0x24(%ebp),%eax + 8005c6: 89 45 e0 mov %eax,-0x20(%ebp) + + reswitch: + switch (ch = *(unsigned char *)fmt ++) { + 8005c9: 8b 45 10 mov 0x10(%ebp),%eax + 8005cc: 8d 50 01 lea 0x1(%eax),%edx + 8005cf: 89 55 10 mov %edx,0x10(%ebp) + 8005d2: 0f b6 00 movzbl (%eax),%eax + 8005d5: 0f b6 d8 movzbl %al,%ebx + 8005d8: 8d 43 dd lea -0x23(%ebx),%eax + 8005db: 83 f8 55 cmp $0x55,%eax + 8005de: 0f 87 37 03 00 00 ja 80091b + 8005e4: 8b 04 85 a8 12 80 00 mov 0x8012a8(,%eax,4),%eax + 8005eb: ff e0 jmp *%eax + + // flag to pad on the right + case '-': + padc = '-'; + 8005ed: c6 45 db 2d movb $0x2d,-0x25(%ebp) + goto reswitch; + 8005f1: eb d6 jmp 8005c9 + + // flag to pad with 0's instead of spaces + case '0': + padc = '0'; + 8005f3: c6 45 db 30 movb $0x30,-0x25(%ebp) + goto reswitch; + 8005f7: eb d0 jmp 8005c9 + + // width field + case '1' ... '9': + for (precision = 0; ; ++ fmt) { + 8005f9: c7 45 e4 00 00 00 00 movl $0x0,-0x1c(%ebp) + precision = precision * 10 + ch - '0'; + 800600: 8b 55 e4 mov -0x1c(%ebp),%edx + 800603: 89 d0 mov %edx,%eax + 800605: c1 e0 02 shl $0x2,%eax + 800608: 01 d0 add %edx,%eax + 80060a: 01 c0 add %eax,%eax + 80060c: 01 d8 add %ebx,%eax + 80060e: 83 e8 30 sub $0x30,%eax + 800611: 89 45 e4 mov %eax,-0x1c(%ebp) + ch = *fmt; + 800614: 8b 45 10 mov 0x10(%ebp),%eax + 800617: 0f b6 00 movzbl (%eax),%eax + 80061a: 0f be d8 movsbl %al,%ebx + if (ch < '0' || ch > '9') { + 80061d: 83 fb 2f cmp $0x2f,%ebx + 800620: 7e 38 jle 80065a + 800622: 83 fb 39 cmp $0x39,%ebx + 800625: 7f 33 jg 80065a + for (precision = 0; ; ++ fmt) { + 800627: ff 45 10 incl 0x10(%ebp) + precision = precision * 10 + ch - '0'; + 80062a: eb d4 jmp 800600 + } + } + goto process_precision; + + case '*': + precision = va_arg(ap, int); + 80062c: 8b 45 14 mov 0x14(%ebp),%eax + 80062f: 8d 50 04 lea 0x4(%eax),%edx + 800632: 89 55 14 mov %edx,0x14(%ebp) + 800635: 8b 00 mov (%eax),%eax + 800637: 89 45 e4 mov %eax,-0x1c(%ebp) + goto process_precision; + 80063a: eb 1f jmp 80065b + + case '.': + if (width < 0) + 80063c: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 800640: 79 87 jns 8005c9 + width = 0; + 800642: c7 45 e8 00 00 00 00 movl $0x0,-0x18(%ebp) + goto reswitch; + 800649: e9 7b ff ff ff jmp 8005c9 + + case '#': + altflag = 1; + 80064e: c7 45 dc 01 00 00 00 movl $0x1,-0x24(%ebp) + goto reswitch; + 800655: e9 6f ff ff ff jmp 8005c9 + goto process_precision; + 80065a: 90 nop + + process_precision: + if (width < 0) + 80065b: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 80065f: 0f 89 64 ff ff ff jns 8005c9 + width = precision, precision = -1; + 800665: 8b 45 e4 mov -0x1c(%ebp),%eax + 800668: 89 45 e8 mov %eax,-0x18(%ebp) + 80066b: c7 45 e4 ff ff ff ff movl $0xffffffff,-0x1c(%ebp) + goto reswitch; + 800672: e9 52 ff ff ff jmp 8005c9 + + // long flag (doubled for long long) + case 'l': + lflag ++; + 800677: ff 45 e0 incl -0x20(%ebp) + goto reswitch; + 80067a: e9 4a ff ff ff jmp 8005c9 + + // character + case 'c': + putch(va_arg(ap, int), putdat); + 80067f: 8b 45 14 mov 0x14(%ebp),%eax + 800682: 8d 50 04 lea 0x4(%eax),%edx + 800685: 89 55 14 mov %edx,0x14(%ebp) + 800688: 8b 00 mov (%eax),%eax + 80068a: 8b 55 0c mov 0xc(%ebp),%edx + 80068d: 89 54 24 04 mov %edx,0x4(%esp) + 800691: 89 04 24 mov %eax,(%esp) + 800694: 8b 45 08 mov 0x8(%ebp),%eax + 800697: ff d0 call *%eax + break; + 800699: e9 a4 02 00 00 jmp 800942 + + // error message + case 'e': + err = va_arg(ap, int); + 80069e: 8b 45 14 mov 0x14(%ebp),%eax + 8006a1: 8d 50 04 lea 0x4(%eax),%edx + 8006a4: 89 55 14 mov %edx,0x14(%ebp) + 8006a7: 8b 18 mov (%eax),%ebx + if (err < 0) { + 8006a9: 85 db test %ebx,%ebx + 8006ab: 79 02 jns 8006af + err = -err; + 8006ad: f7 db neg %ebx + } + if (err > MAXERROR || (p = error_string[err]) == NULL) { + 8006af: 83 fb 18 cmp $0x18,%ebx + 8006b2: 7f 0b jg 8006bf + 8006b4: 8b 34 9d 20 12 80 00 mov 0x801220(,%ebx,4),%esi + 8006bb: 85 f6 test %esi,%esi + 8006bd: 75 23 jne 8006e2 + printfmt(putch, putdat, "error %d", err); + 8006bf: 89 5c 24 0c mov %ebx,0xc(%esp) + 8006c3: c7 44 24 08 95 12 80 movl $0x801295,0x8(%esp) + 8006ca: 00 + 8006cb: 8b 45 0c mov 0xc(%ebp),%eax + 8006ce: 89 44 24 04 mov %eax,0x4(%esp) + 8006d2: 8b 45 08 mov 0x8(%ebp),%eax + 8006d5: 89 04 24 mov %eax,(%esp) + 8006d8: e8 68 fe ff ff call 800545 + } + else { + printfmt(putch, putdat, "%s", p); + } + break; + 8006dd: e9 60 02 00 00 jmp 800942 + printfmt(putch, putdat, "%s", p); + 8006e2: 89 74 24 0c mov %esi,0xc(%esp) + 8006e6: c7 44 24 08 9e 12 80 movl $0x80129e,0x8(%esp) + 8006ed: 00 + 8006ee: 8b 45 0c mov 0xc(%ebp),%eax + 8006f1: 89 44 24 04 mov %eax,0x4(%esp) + 8006f5: 8b 45 08 mov 0x8(%ebp),%eax + 8006f8: 89 04 24 mov %eax,(%esp) + 8006fb: e8 45 fe ff ff call 800545 + break; + 800700: e9 3d 02 00 00 jmp 800942 + + // string + case 's': + if ((p = va_arg(ap, char *)) == NULL) { + 800705: 8b 45 14 mov 0x14(%ebp),%eax + 800708: 8d 50 04 lea 0x4(%eax),%edx + 80070b: 89 55 14 mov %edx,0x14(%ebp) + 80070e: 8b 30 mov (%eax),%esi + 800710: 85 f6 test %esi,%esi + 800712: 75 05 jne 800719 + p = "(null)"; + 800714: be a1 12 80 00 mov $0x8012a1,%esi + } + if (width > 0 && padc != '-') { + 800719: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 80071d: 7e 76 jle 800795 + 80071f: 80 7d db 2d cmpb $0x2d,-0x25(%ebp) + 800723: 74 70 je 800795 + for (width -= strnlen(p, precision); width > 0; width --) { + 800725: 8b 45 e4 mov -0x1c(%ebp),%eax + 800728: 89 44 24 04 mov %eax,0x4(%esp) + 80072c: 89 34 24 mov %esi,(%esp) + 80072f: e8 ee 03 00 00 call 800b22 + 800734: 89 c2 mov %eax,%edx + 800736: 8b 45 e8 mov -0x18(%ebp),%eax + 800739: 29 d0 sub %edx,%eax + 80073b: 89 45 e8 mov %eax,-0x18(%ebp) + 80073e: eb 16 jmp 800756 + putch(padc, putdat); + 800740: 0f be 45 db movsbl -0x25(%ebp),%eax + 800744: 8b 55 0c mov 0xc(%ebp),%edx + 800747: 89 54 24 04 mov %edx,0x4(%esp) + 80074b: 89 04 24 mov %eax,(%esp) + 80074e: 8b 45 08 mov 0x8(%ebp),%eax + 800751: ff d0 call *%eax + for (width -= strnlen(p, precision); width > 0; width --) { + 800753: ff 4d e8 decl -0x18(%ebp) + 800756: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 80075a: 7f e4 jg 800740 + } + } + for (; (ch = *p ++) != '\0' && (precision < 0 || -- precision >= 0); width --) { + 80075c: eb 37 jmp 800795 + if (altflag && (ch < ' ' || ch > '~')) { + 80075e: 83 7d dc 00 cmpl $0x0,-0x24(%ebp) + 800762: 74 1f je 800783 + 800764: 83 fb 1f cmp $0x1f,%ebx + 800767: 7e 05 jle 80076e + 800769: 83 fb 7e cmp $0x7e,%ebx + 80076c: 7e 15 jle 800783 + putch('?', putdat); + 80076e: 8b 45 0c mov 0xc(%ebp),%eax + 800771: 89 44 24 04 mov %eax,0x4(%esp) + 800775: c7 04 24 3f 00 00 00 movl $0x3f,(%esp) + 80077c: 8b 45 08 mov 0x8(%ebp),%eax + 80077f: ff d0 call *%eax + 800781: eb 0f jmp 800792 + } + else { + putch(ch, putdat); + 800783: 8b 45 0c mov 0xc(%ebp),%eax + 800786: 89 44 24 04 mov %eax,0x4(%esp) + 80078a: 89 1c 24 mov %ebx,(%esp) + 80078d: 8b 45 08 mov 0x8(%ebp),%eax + 800790: ff d0 call *%eax + for (; (ch = *p ++) != '\0' && (precision < 0 || -- precision >= 0); width --) { + 800792: ff 4d e8 decl -0x18(%ebp) + 800795: 89 f0 mov %esi,%eax + 800797: 8d 70 01 lea 0x1(%eax),%esi + 80079a: 0f b6 00 movzbl (%eax),%eax + 80079d: 0f be d8 movsbl %al,%ebx + 8007a0: 85 db test %ebx,%ebx + 8007a2: 74 27 je 8007cb + 8007a4: 83 7d e4 00 cmpl $0x0,-0x1c(%ebp) + 8007a8: 78 b4 js 80075e + 8007aa: ff 4d e4 decl -0x1c(%ebp) + 8007ad: 83 7d e4 00 cmpl $0x0,-0x1c(%ebp) + 8007b1: 79 ab jns 80075e + } + } + for (; width > 0; width --) { + 8007b3: eb 16 jmp 8007cb + putch(' ', putdat); + 8007b5: 8b 45 0c mov 0xc(%ebp),%eax + 8007b8: 89 44 24 04 mov %eax,0x4(%esp) + 8007bc: c7 04 24 20 00 00 00 movl $0x20,(%esp) + 8007c3: 8b 45 08 mov 0x8(%ebp),%eax + 8007c6: ff d0 call *%eax + for (; width > 0; width --) { + 8007c8: ff 4d e8 decl -0x18(%ebp) + 8007cb: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 8007cf: 7f e4 jg 8007b5 + } + break; + 8007d1: e9 6c 01 00 00 jmp 800942 + + // (signed) decimal + case 'd': + num = getint(&ap, lflag); + 8007d6: 8b 45 e0 mov -0x20(%ebp),%eax + 8007d9: 89 44 24 04 mov %eax,0x4(%esp) + 8007dd: 8d 45 14 lea 0x14(%ebp),%eax + 8007e0: 89 04 24 mov %eax,(%esp) + 8007e3: e8 16 fd ff ff call 8004fe + 8007e8: 89 45 f0 mov %eax,-0x10(%ebp) + 8007eb: 89 55 f4 mov %edx,-0xc(%ebp) + if ((long long)num < 0) { + 8007ee: 8b 45 f0 mov -0x10(%ebp),%eax + 8007f1: 8b 55 f4 mov -0xc(%ebp),%edx + 8007f4: 85 d2 test %edx,%edx + 8007f6: 79 26 jns 80081e + putch('-', putdat); + 8007f8: 8b 45 0c mov 0xc(%ebp),%eax + 8007fb: 89 44 24 04 mov %eax,0x4(%esp) + 8007ff: c7 04 24 2d 00 00 00 movl $0x2d,(%esp) + 800806: 8b 45 08 mov 0x8(%ebp),%eax + 800809: ff d0 call *%eax + num = -(long long)num; + 80080b: 8b 45 f0 mov -0x10(%ebp),%eax + 80080e: 8b 55 f4 mov -0xc(%ebp),%edx + 800811: f7 d8 neg %eax + 800813: 83 d2 00 adc $0x0,%edx + 800816: f7 da neg %edx + 800818: 89 45 f0 mov %eax,-0x10(%ebp) + 80081b: 89 55 f4 mov %edx,-0xc(%ebp) + } + base = 10; + 80081e: c7 45 ec 0a 00 00 00 movl $0xa,-0x14(%ebp) + goto number; + 800825: e9 a8 00 00 00 jmp 8008d2 + + // unsigned decimal + case 'u': + num = getuint(&ap, lflag); + 80082a: 8b 45 e0 mov -0x20(%ebp),%eax + 80082d: 89 44 24 04 mov %eax,0x4(%esp) + 800831: 8d 45 14 lea 0x14(%ebp),%eax + 800834: 89 04 24 mov %eax,(%esp) + 800837: e8 73 fc ff ff call 8004af + 80083c: 89 45 f0 mov %eax,-0x10(%ebp) + 80083f: 89 55 f4 mov %edx,-0xc(%ebp) + base = 10; + 800842: c7 45 ec 0a 00 00 00 movl $0xa,-0x14(%ebp) + goto number; + 800849: e9 84 00 00 00 jmp 8008d2 + + // (unsigned) octal + case 'o': + num = getuint(&ap, lflag); + 80084e: 8b 45 e0 mov -0x20(%ebp),%eax + 800851: 89 44 24 04 mov %eax,0x4(%esp) + 800855: 8d 45 14 lea 0x14(%ebp),%eax + 800858: 89 04 24 mov %eax,(%esp) + 80085b: e8 4f fc ff ff call 8004af + 800860: 89 45 f0 mov %eax,-0x10(%ebp) + 800863: 89 55 f4 mov %edx,-0xc(%ebp) + base = 8; + 800866: c7 45 ec 08 00 00 00 movl $0x8,-0x14(%ebp) + goto number; + 80086d: eb 63 jmp 8008d2 + + // pointer + case 'p': + putch('0', putdat); + 80086f: 8b 45 0c mov 0xc(%ebp),%eax + 800872: 89 44 24 04 mov %eax,0x4(%esp) + 800876: c7 04 24 30 00 00 00 movl $0x30,(%esp) + 80087d: 8b 45 08 mov 0x8(%ebp),%eax + 800880: ff d0 call *%eax + putch('x', putdat); + 800882: 8b 45 0c mov 0xc(%ebp),%eax + 800885: 89 44 24 04 mov %eax,0x4(%esp) + 800889: c7 04 24 78 00 00 00 movl $0x78,(%esp) + 800890: 8b 45 08 mov 0x8(%ebp),%eax + 800893: ff d0 call *%eax + num = (unsigned long long)(uintptr_t)va_arg(ap, void *); + 800895: 8b 45 14 mov 0x14(%ebp),%eax + 800898: 8d 50 04 lea 0x4(%eax),%edx + 80089b: 89 55 14 mov %edx,0x14(%ebp) + 80089e: 8b 00 mov (%eax),%eax + 8008a0: 89 45 f0 mov %eax,-0x10(%ebp) + 8008a3: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + base = 16; + 8008aa: c7 45 ec 10 00 00 00 movl $0x10,-0x14(%ebp) + goto number; + 8008b1: eb 1f jmp 8008d2 + + // (unsigned) hexadecimal + case 'x': + num = getuint(&ap, lflag); + 8008b3: 8b 45 e0 mov -0x20(%ebp),%eax + 8008b6: 89 44 24 04 mov %eax,0x4(%esp) + 8008ba: 8d 45 14 lea 0x14(%ebp),%eax + 8008bd: 89 04 24 mov %eax,(%esp) + 8008c0: e8 ea fb ff ff call 8004af + 8008c5: 89 45 f0 mov %eax,-0x10(%ebp) + 8008c8: 89 55 f4 mov %edx,-0xc(%ebp) + base = 16; + 8008cb: c7 45 ec 10 00 00 00 movl $0x10,-0x14(%ebp) + number: + printnum(putch, putdat, num, base, width, padc); + 8008d2: 0f be 55 db movsbl -0x25(%ebp),%edx + 8008d6: 8b 45 ec mov -0x14(%ebp),%eax + 8008d9: 89 54 24 18 mov %edx,0x18(%esp) + 8008dd: 8b 55 e8 mov -0x18(%ebp),%edx + 8008e0: 89 54 24 14 mov %edx,0x14(%esp) + 8008e4: 89 44 24 10 mov %eax,0x10(%esp) + 8008e8: 8b 45 f0 mov -0x10(%ebp),%eax + 8008eb: 8b 55 f4 mov -0xc(%ebp),%edx + 8008ee: 89 44 24 08 mov %eax,0x8(%esp) + 8008f2: 89 54 24 0c mov %edx,0xc(%esp) + 8008f6: 8b 45 0c mov 0xc(%ebp),%eax + 8008f9: 89 44 24 04 mov %eax,0x4(%esp) + 8008fd: 8b 45 08 mov 0x8(%ebp),%eax + 800900: 89 04 24 mov %eax,(%esp) + 800903: e8 a5 fa ff ff call 8003ad + break; + 800908: eb 38 jmp 800942 + + // escaped '%' character + case '%': + putch(ch, putdat); + 80090a: 8b 45 0c mov 0xc(%ebp),%eax + 80090d: 89 44 24 04 mov %eax,0x4(%esp) + 800911: 89 1c 24 mov %ebx,(%esp) + 800914: 8b 45 08 mov 0x8(%ebp),%eax + 800917: ff d0 call *%eax + break; + 800919: eb 27 jmp 800942 + + // unrecognized escape sequence - just print it literally + default: + putch('%', putdat); + 80091b: 8b 45 0c mov 0xc(%ebp),%eax + 80091e: 89 44 24 04 mov %eax,0x4(%esp) + 800922: c7 04 24 25 00 00 00 movl $0x25,(%esp) + 800929: 8b 45 08 mov 0x8(%ebp),%eax + 80092c: ff d0 call *%eax + for (fmt --; fmt[-1] != '%'; fmt --) + 80092e: ff 4d 10 decl 0x10(%ebp) + 800931: eb 03 jmp 800936 + 800933: ff 4d 10 decl 0x10(%ebp) + 800936: 8b 45 10 mov 0x10(%ebp),%eax + 800939: 48 dec %eax + 80093a: 0f b6 00 movzbl (%eax),%eax + 80093d: 3c 25 cmp $0x25,%al + 80093f: 75 f2 jne 800933 + /* do nothing */; + break; + 800941: 90 nop + while (1) { + 800942: e9 37 fc ff ff jmp 80057e + return; + 800947: 90 nop + } + } +} + 800948: 83 c4 40 add $0x40,%esp + 80094b: 5b pop %ebx + 80094c: 5e pop %esi + 80094d: 5d pop %ebp + 80094e: c3 ret + +0080094f : + * sprintputch - 'print' a single character in a buffer + * @ch: the character will be printed + * @b: the buffer to place the character @ch + * */ +static void +sprintputch(int ch, struct sprintbuf *b) { + 80094f: 55 push %ebp + 800950: 89 e5 mov %esp,%ebp + b->cnt ++; + 800952: 8b 45 0c mov 0xc(%ebp),%eax + 800955: 8b 40 08 mov 0x8(%eax),%eax + 800958: 8d 50 01 lea 0x1(%eax),%edx + 80095b: 8b 45 0c mov 0xc(%ebp),%eax + 80095e: 89 50 08 mov %edx,0x8(%eax) + if (b->buf < b->ebuf) { + 800961: 8b 45 0c mov 0xc(%ebp),%eax + 800964: 8b 10 mov (%eax),%edx + 800966: 8b 45 0c mov 0xc(%ebp),%eax + 800969: 8b 40 04 mov 0x4(%eax),%eax + 80096c: 39 c2 cmp %eax,%edx + 80096e: 73 12 jae 800982 + *b->buf ++ = ch; + 800970: 8b 45 0c mov 0xc(%ebp),%eax + 800973: 8b 00 mov (%eax),%eax + 800975: 8d 48 01 lea 0x1(%eax),%ecx + 800978: 8b 55 0c mov 0xc(%ebp),%edx + 80097b: 89 0a mov %ecx,(%edx) + 80097d: 8b 55 08 mov 0x8(%ebp),%edx + 800980: 88 10 mov %dl,(%eax) + } +} + 800982: 90 nop + 800983: 5d pop %ebp + 800984: c3 ret + +00800985 : + * @str: the buffer to place the result into + * @size: the size of buffer, including the trailing null space + * @fmt: the format string to use + * */ +int +snprintf(char *str, size_t size, const char *fmt, ...) { + 800985: 55 push %ebp + 800986: 89 e5 mov %esp,%ebp + 800988: 83 ec 28 sub $0x28,%esp + va_list ap; + int cnt; + va_start(ap, fmt); + 80098b: 8d 45 14 lea 0x14(%ebp),%eax + 80098e: 89 45 f0 mov %eax,-0x10(%ebp) + cnt = vsnprintf(str, size, fmt, ap); + 800991: 8b 45 f0 mov -0x10(%ebp),%eax + 800994: 89 44 24 0c mov %eax,0xc(%esp) + 800998: 8b 45 10 mov 0x10(%ebp),%eax + 80099b: 89 44 24 08 mov %eax,0x8(%esp) + 80099f: 8b 45 0c mov 0xc(%ebp),%eax + 8009a2: 89 44 24 04 mov %eax,0x4(%esp) + 8009a6: 8b 45 08 mov 0x8(%ebp),%eax + 8009a9: 89 04 24 mov %eax,(%esp) + 8009ac: e8 0a 00 00 00 call 8009bb + 8009b1: 89 45 f4 mov %eax,-0xc(%ebp) + va_end(ap); + return cnt; + 8009b4: 8b 45 f4 mov -0xc(%ebp),%eax +} + 8009b7: 89 ec mov %ebp,%esp + 8009b9: 5d pop %ebp + 8009ba: c3 ret + +008009bb : + * + * Call this function if you are already dealing with a va_list. + * Or you probably want snprintf() instead. + * */ +int +vsnprintf(char *str, size_t size, const char *fmt, va_list ap) { + 8009bb: 55 push %ebp + 8009bc: 89 e5 mov %esp,%ebp + 8009be: 83 ec 28 sub $0x28,%esp + struct sprintbuf b = {str, str + size - 1, 0}; + 8009c1: 8b 45 08 mov 0x8(%ebp),%eax + 8009c4: 89 45 ec mov %eax,-0x14(%ebp) + 8009c7: 8b 45 0c mov 0xc(%ebp),%eax + 8009ca: 8d 50 ff lea -0x1(%eax),%edx + 8009cd: 8b 45 08 mov 0x8(%ebp),%eax + 8009d0: 01 d0 add %edx,%eax + 8009d2: 89 45 f0 mov %eax,-0x10(%ebp) + 8009d5: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + if (str == NULL || b.buf > b.ebuf) { + 8009dc: 83 7d 08 00 cmpl $0x0,0x8(%ebp) + 8009e0: 74 0a je 8009ec + 8009e2: 8b 55 ec mov -0x14(%ebp),%edx + 8009e5: 8b 45 f0 mov -0x10(%ebp),%eax + 8009e8: 39 c2 cmp %eax,%edx + 8009ea: 76 07 jbe 8009f3 + return -E_INVAL; + 8009ec: b8 fd ff ff ff mov $0xfffffffd,%eax + 8009f1: eb 2a jmp 800a1d + } + // print the string to the buffer + vprintfmt((void*)sprintputch, &b, fmt, ap); + 8009f3: 8b 45 14 mov 0x14(%ebp),%eax + 8009f6: 89 44 24 0c mov %eax,0xc(%esp) + 8009fa: 8b 45 10 mov 0x10(%ebp),%eax + 8009fd: 89 44 24 08 mov %eax,0x8(%esp) + 800a01: 8d 45 ec lea -0x14(%ebp),%eax + 800a04: 89 44 24 04 mov %eax,0x4(%esp) + 800a08: c7 04 24 4f 09 80 00 movl $0x80094f,(%esp) + 800a0f: e8 62 fb ff ff call 800576 + // null terminate the buffer + *b.buf = '\0'; + 800a14: 8b 45 ec mov -0x14(%ebp),%eax + 800a17: c6 00 00 movb $0x0,(%eax) + return b.cnt; + 800a1a: 8b 45 f4 mov -0xc(%ebp),%eax +} + 800a1d: 89 ec mov %ebp,%esp + 800a1f: 5d pop %ebp + 800a20: c3 ret + +00800a21 : + * rand - returns a pseudo-random integer + * + * The rand() function return a value in the range [0, RAND_MAX]. + * */ +int +rand(void) { + 800a21: 55 push %ebp + 800a22: 89 e5 mov %esp,%ebp + 800a24: 57 push %edi + 800a25: 56 push %esi + 800a26: 53 push %ebx + 800a27: 83 ec 24 sub $0x24,%esp + next = (next * 0x5DEECE66DLL + 0xBLL) & ((1LL << 48) - 1); + 800a2a: a1 00 20 80 00 mov 0x802000,%eax + 800a2f: 8b 15 04 20 80 00 mov 0x802004,%edx + 800a35: 69 fa 6d e6 ec de imul $0xdeece66d,%edx,%edi + 800a3b: 6b f0 05 imul $0x5,%eax,%esi + 800a3e: 01 fe add %edi,%esi + 800a40: bf 6d e6 ec de mov $0xdeece66d,%edi + 800a45: f7 e7 mul %edi + 800a47: 01 d6 add %edx,%esi + 800a49: 89 f2 mov %esi,%edx + 800a4b: 83 c0 0b add $0xb,%eax + 800a4e: 83 d2 00 adc $0x0,%edx + 800a51: 89 c7 mov %eax,%edi + 800a53: 83 e7 ff and $0xffffffff,%edi + 800a56: 89 f9 mov %edi,%ecx + 800a58: 0f b7 da movzwl %dx,%ebx + 800a5b: 89 0d 00 20 80 00 mov %ecx,0x802000 + 800a61: 89 1d 04 20 80 00 mov %ebx,0x802004 + unsigned long long result = (next >> 12); + 800a67: a1 00 20 80 00 mov 0x802000,%eax + 800a6c: 8b 15 04 20 80 00 mov 0x802004,%edx + 800a72: 0f ac d0 0c shrd $0xc,%edx,%eax + 800a76: c1 ea 0c shr $0xc,%edx + 800a79: 89 45 e0 mov %eax,-0x20(%ebp) + 800a7c: 89 55 e4 mov %edx,-0x1c(%ebp) + return (int)do_div(result, RAND_MAX + 1); + 800a7f: c7 45 dc 00 00 00 80 movl $0x80000000,-0x24(%ebp) + 800a86: 8b 45 e0 mov -0x20(%ebp),%eax + 800a89: 8b 55 e4 mov -0x1c(%ebp),%edx + 800a8c: 89 45 d8 mov %eax,-0x28(%ebp) + 800a8f: 89 55 e8 mov %edx,-0x18(%ebp) + 800a92: 8b 45 e8 mov -0x18(%ebp),%eax + 800a95: 89 45 ec mov %eax,-0x14(%ebp) + 800a98: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 800a9c: 74 1c je 800aba + 800a9e: 8b 45 e8 mov -0x18(%ebp),%eax + 800aa1: ba 00 00 00 00 mov $0x0,%edx + 800aa6: f7 75 dc divl -0x24(%ebp) + 800aa9: 89 55 ec mov %edx,-0x14(%ebp) + 800aac: 8b 45 e8 mov -0x18(%ebp),%eax + 800aaf: ba 00 00 00 00 mov $0x0,%edx + 800ab4: f7 75 dc divl -0x24(%ebp) + 800ab7: 89 45 e8 mov %eax,-0x18(%ebp) + 800aba: 8b 45 d8 mov -0x28(%ebp),%eax + 800abd: 8b 55 ec mov -0x14(%ebp),%edx + 800ac0: f7 75 dc divl -0x24(%ebp) + 800ac3: 89 45 d8 mov %eax,-0x28(%ebp) + 800ac6: 89 55 d4 mov %edx,-0x2c(%ebp) + 800ac9: 8b 45 d8 mov -0x28(%ebp),%eax + 800acc: 8b 55 e8 mov -0x18(%ebp),%edx + 800acf: 89 45 e0 mov %eax,-0x20(%ebp) + 800ad2: 89 55 e4 mov %edx,-0x1c(%ebp) + 800ad5: 8b 45 d4 mov -0x2c(%ebp),%eax +} + 800ad8: 83 c4 24 add $0x24,%esp + 800adb: 5b pop %ebx + 800adc: 5e pop %esi + 800add: 5f pop %edi + 800ade: 5d pop %ebp + 800adf: c3 ret + +00800ae0 : +/* * + * srand - seed the random number generator with the given number + * @seed: the required seed number + * */ +void +srand(unsigned int seed) { + 800ae0: 55 push %ebp + 800ae1: 89 e5 mov %esp,%ebp + next = seed; + 800ae3: 8b 45 08 mov 0x8(%ebp),%eax + 800ae6: ba 00 00 00 00 mov $0x0,%edx + 800aeb: a3 00 20 80 00 mov %eax,0x802000 + 800af0: 89 15 04 20 80 00 mov %edx,0x802004 +} + 800af6: 90 nop + 800af7: 5d pop %ebp + 800af8: c3 ret + +00800af9 : + * @s: the input string + * + * The strlen() function returns the length of string @s. + * */ +size_t +strlen(const char *s) { + 800af9: 55 push %ebp + 800afa: 89 e5 mov %esp,%ebp + 800afc: 83 ec 10 sub $0x10,%esp + size_t cnt = 0; + 800aff: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + while (*s ++ != '\0') { + 800b06: eb 03 jmp 800b0b + cnt ++; + 800b08: ff 45 fc incl -0x4(%ebp) + while (*s ++ != '\0') { + 800b0b: 8b 45 08 mov 0x8(%ebp),%eax + 800b0e: 8d 50 01 lea 0x1(%eax),%edx + 800b11: 89 55 08 mov %edx,0x8(%ebp) + 800b14: 0f b6 00 movzbl (%eax),%eax + 800b17: 84 c0 test %al,%al + 800b19: 75 ed jne 800b08 + } + return cnt; + 800b1b: 8b 45 fc mov -0x4(%ebp),%eax +} + 800b1e: 89 ec mov %ebp,%esp + 800b20: 5d pop %ebp + 800b21: c3 ret + +00800b22 : + * The return value is strlen(s), if that is less than @len, or + * @len if there is no '\0' character among the first @len characters + * pointed by @s. + * */ +size_t +strnlen(const char *s, size_t len) { + 800b22: 55 push %ebp + 800b23: 89 e5 mov %esp,%ebp + 800b25: 83 ec 10 sub $0x10,%esp + size_t cnt = 0; + 800b28: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + while (cnt < len && *s ++ != '\0') { + 800b2f: eb 03 jmp 800b34 + cnt ++; + 800b31: ff 45 fc incl -0x4(%ebp) + while (cnt < len && *s ++ != '\0') { + 800b34: 8b 45 fc mov -0x4(%ebp),%eax + 800b37: 3b 45 0c cmp 0xc(%ebp),%eax + 800b3a: 73 10 jae 800b4c + 800b3c: 8b 45 08 mov 0x8(%ebp),%eax + 800b3f: 8d 50 01 lea 0x1(%eax),%edx + 800b42: 89 55 08 mov %edx,0x8(%ebp) + 800b45: 0f b6 00 movzbl (%eax),%eax + 800b48: 84 c0 test %al,%al + 800b4a: 75 e5 jne 800b31 + } + return cnt; + 800b4c: 8b 45 fc mov -0x4(%ebp),%eax +} + 800b4f: 89 ec mov %ebp,%esp + 800b51: 5d pop %ebp + 800b52: c3 ret + +00800b53 : + * To avoid overflows, the size of array pointed by @dst should be long enough to + * contain the same string as @src (including the terminating null character), and + * should not overlap in memory with @src. + * */ +char * +strcpy(char *dst, const char *src) { + 800b53: 55 push %ebp + 800b54: 89 e5 mov %esp,%ebp + 800b56: 57 push %edi + 800b57: 56 push %esi + 800b58: 83 ec 20 sub $0x20,%esp + 800b5b: 8b 45 08 mov 0x8(%ebp),%eax + 800b5e: 89 45 f4 mov %eax,-0xc(%ebp) + 800b61: 8b 45 0c mov 0xc(%ebp),%eax + 800b64: 89 45 f0 mov %eax,-0x10(%ebp) +#ifndef __HAVE_ARCH_STRCPY +#define __HAVE_ARCH_STRCPY +static inline char * +__strcpy(char *dst, const char *src) { + int d0, d1, d2; + asm volatile ( + 800b67: 8b 55 f0 mov -0x10(%ebp),%edx + 800b6a: 8b 45 f4 mov -0xc(%ebp),%eax + 800b6d: 89 d1 mov %edx,%ecx + 800b6f: 89 c2 mov %eax,%edx + 800b71: 89 ce mov %ecx,%esi + 800b73: 89 d7 mov %edx,%edi + 800b75: ac lods %ds:(%esi),%al + 800b76: aa stos %al,%es:(%edi) + 800b77: 84 c0 test %al,%al + 800b79: 75 fa jne 800b75 + 800b7b: 89 fa mov %edi,%edx + 800b7d: 89 f1 mov %esi,%ecx + 800b7f: 89 4d ec mov %ecx,-0x14(%ebp) + 800b82: 89 55 e8 mov %edx,-0x18(%ebp) + 800b85: 89 45 e4 mov %eax,-0x1c(%ebp) + "stosb;" + "testb %%al, %%al;" + "jne 1b;" + : "=&S" (d0), "=&D" (d1), "=&a" (d2) + : "0" (src), "1" (dst) : "memory"); + return dst; + 800b88: 8b 45 f4 mov -0xc(%ebp),%eax + char *p = dst; + while ((*p ++ = *src ++) != '\0') + /* nothing */; + return dst; +#endif /* __HAVE_ARCH_STRCPY */ +} + 800b8b: 83 c4 20 add $0x20,%esp + 800b8e: 5e pop %esi + 800b8f: 5f pop %edi + 800b90: 5d pop %ebp + 800b91: c3 ret + +00800b92 : + * @len: maximum number of characters to be copied from @src + * + * The return value is @dst + * */ +char * +strncpy(char *dst, const char *src, size_t len) { + 800b92: 55 push %ebp + 800b93: 89 e5 mov %esp,%ebp + 800b95: 83 ec 10 sub $0x10,%esp + char *p = dst; + 800b98: 8b 45 08 mov 0x8(%ebp),%eax + 800b9b: 89 45 fc mov %eax,-0x4(%ebp) + while (len > 0) { + 800b9e: eb 1e jmp 800bbe + if ((*p = *src) != '\0') { + 800ba0: 8b 45 0c mov 0xc(%ebp),%eax + 800ba3: 0f b6 10 movzbl (%eax),%edx + 800ba6: 8b 45 fc mov -0x4(%ebp),%eax + 800ba9: 88 10 mov %dl,(%eax) + 800bab: 8b 45 fc mov -0x4(%ebp),%eax + 800bae: 0f b6 00 movzbl (%eax),%eax + 800bb1: 84 c0 test %al,%al + 800bb3: 74 03 je 800bb8 + src ++; + 800bb5: ff 45 0c incl 0xc(%ebp) + } + p ++, len --; + 800bb8: ff 45 fc incl -0x4(%ebp) + 800bbb: ff 4d 10 decl 0x10(%ebp) + while (len > 0) { + 800bbe: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800bc2: 75 dc jne 800ba0 + } + return dst; + 800bc4: 8b 45 08 mov 0x8(%ebp),%eax +} + 800bc7: 89 ec mov %ebp,%esp + 800bc9: 5d pop %ebp + 800bca: c3 ret + +00800bcb : + * - A value greater than zero indicates that the first character that does + * not match has a greater value in @s1 than in @s2; + * - And a value less than zero indicates the opposite. + * */ +int +strcmp(const char *s1, const char *s2) { + 800bcb: 55 push %ebp + 800bcc: 89 e5 mov %esp,%ebp + 800bce: 57 push %edi + 800bcf: 56 push %esi + 800bd0: 83 ec 20 sub $0x20,%esp + 800bd3: 8b 45 08 mov 0x8(%ebp),%eax + 800bd6: 89 45 f4 mov %eax,-0xc(%ebp) + 800bd9: 8b 45 0c mov 0xc(%ebp),%eax + 800bdc: 89 45 f0 mov %eax,-0x10(%ebp) + asm volatile ( + 800bdf: 8b 55 f4 mov -0xc(%ebp),%edx + 800be2: 8b 45 f0 mov -0x10(%ebp),%eax + 800be5: 89 d1 mov %edx,%ecx + 800be7: 89 c2 mov %eax,%edx + 800be9: 89 ce mov %ecx,%esi + 800beb: 89 d7 mov %edx,%edi + 800bed: ac lods %ds:(%esi),%al + 800bee: ae scas %es:(%edi),%al + 800bef: 75 08 jne 800bf9 + 800bf1: 84 c0 test %al,%al + 800bf3: 75 f8 jne 800bed + 800bf5: 31 c0 xor %eax,%eax + 800bf7: eb 04 jmp 800bfd + 800bf9: 19 c0 sbb %eax,%eax + 800bfb: 0c 01 or $0x1,%al + 800bfd: 89 fa mov %edi,%edx + 800bff: 89 f1 mov %esi,%ecx + 800c01: 89 45 ec mov %eax,-0x14(%ebp) + 800c04: 89 4d e8 mov %ecx,-0x18(%ebp) + 800c07: 89 55 e4 mov %edx,-0x1c(%ebp) + return ret; + 800c0a: 8b 45 ec mov -0x14(%ebp),%eax + while (*s1 != '\0' && *s1 == *s2) { + s1 ++, s2 ++; + } + return (int)((unsigned char)*s1 - (unsigned char)*s2); +#endif /* __HAVE_ARCH_STRCMP */ +} + 800c0d: 83 c4 20 add $0x20,%esp + 800c10: 5e pop %esi + 800c11: 5f pop %edi + 800c12: 5d pop %ebp + 800c13: c3 ret + +00800c14 : + * they are equal to each other, it continues with the following pairs until + * the characters differ, until a terminating null-character is reached, or + * until @n characters match in both strings, whichever happens first. + * */ +int +strncmp(const char *s1, const char *s2, size_t n) { + 800c14: 55 push %ebp + 800c15: 89 e5 mov %esp,%ebp + while (n > 0 && *s1 != '\0' && *s1 == *s2) { + 800c17: eb 09 jmp 800c22 + n --, s1 ++, s2 ++; + 800c19: ff 4d 10 decl 0x10(%ebp) + 800c1c: ff 45 08 incl 0x8(%ebp) + 800c1f: ff 45 0c incl 0xc(%ebp) + while (n > 0 && *s1 != '\0' && *s1 == *s2) { + 800c22: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800c26: 74 1a je 800c42 + 800c28: 8b 45 08 mov 0x8(%ebp),%eax + 800c2b: 0f b6 00 movzbl (%eax),%eax + 800c2e: 84 c0 test %al,%al + 800c30: 74 10 je 800c42 + 800c32: 8b 45 08 mov 0x8(%ebp),%eax + 800c35: 0f b6 10 movzbl (%eax),%edx + 800c38: 8b 45 0c mov 0xc(%ebp),%eax + 800c3b: 0f b6 00 movzbl (%eax),%eax + 800c3e: 38 c2 cmp %al,%dl + 800c40: 74 d7 je 800c19 + } + return (n == 0) ? 0 : (int)((unsigned char)*s1 - (unsigned char)*s2); + 800c42: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800c46: 74 18 je 800c60 + 800c48: 8b 45 08 mov 0x8(%ebp),%eax + 800c4b: 0f b6 00 movzbl (%eax),%eax + 800c4e: 0f b6 d0 movzbl %al,%edx + 800c51: 8b 45 0c mov 0xc(%ebp),%eax + 800c54: 0f b6 00 movzbl (%eax),%eax + 800c57: 0f b6 c8 movzbl %al,%ecx + 800c5a: 89 d0 mov %edx,%eax + 800c5c: 29 c8 sub %ecx,%eax + 800c5e: eb 05 jmp 800c65 + 800c60: b8 00 00 00 00 mov $0x0,%eax +} + 800c65: 5d pop %ebp + 800c66: c3 ret + +00800c67 : + * + * The strchr() function returns a pointer to the first occurrence of + * character in @s. If the value is not found, the function returns 'NULL'. + * */ +char * +strchr(const char *s, char c) { + 800c67: 55 push %ebp + 800c68: 89 e5 mov %esp,%ebp + 800c6a: 83 ec 04 sub $0x4,%esp + 800c6d: 8b 45 0c mov 0xc(%ebp),%eax + 800c70: 88 45 fc mov %al,-0x4(%ebp) + while (*s != '\0') { + 800c73: eb 13 jmp 800c88 + if (*s == c) { + 800c75: 8b 45 08 mov 0x8(%ebp),%eax + 800c78: 0f b6 00 movzbl (%eax),%eax + 800c7b: 38 45 fc cmp %al,-0x4(%ebp) + 800c7e: 75 05 jne 800c85 + return (char *)s; + 800c80: 8b 45 08 mov 0x8(%ebp),%eax + 800c83: eb 12 jmp 800c97 + } + s ++; + 800c85: ff 45 08 incl 0x8(%ebp) + while (*s != '\0') { + 800c88: 8b 45 08 mov 0x8(%ebp),%eax + 800c8b: 0f b6 00 movzbl (%eax),%eax + 800c8e: 84 c0 test %al,%al + 800c90: 75 e3 jne 800c75 + } + return NULL; + 800c92: b8 00 00 00 00 mov $0x0,%eax +} + 800c97: 89 ec mov %ebp,%esp + 800c99: 5d pop %ebp + 800c9a: c3 ret + +00800c9b : + * The strfind() function is like strchr() except that if @c is + * not found in @s, then it returns a pointer to the null byte at the + * end of @s, rather than 'NULL'. + * */ +char * +strfind(const char *s, char c) { + 800c9b: 55 push %ebp + 800c9c: 89 e5 mov %esp,%ebp + 800c9e: 83 ec 04 sub $0x4,%esp + 800ca1: 8b 45 0c mov 0xc(%ebp),%eax + 800ca4: 88 45 fc mov %al,-0x4(%ebp) + while (*s != '\0') { + 800ca7: eb 0e jmp 800cb7 + if (*s == c) { + 800ca9: 8b 45 08 mov 0x8(%ebp),%eax + 800cac: 0f b6 00 movzbl (%eax),%eax + 800caf: 38 45 fc cmp %al,-0x4(%ebp) + 800cb2: 74 0f je 800cc3 + break; + } + s ++; + 800cb4: ff 45 08 incl 0x8(%ebp) + while (*s != '\0') { + 800cb7: 8b 45 08 mov 0x8(%ebp),%eax + 800cba: 0f b6 00 movzbl (%eax),%eax + 800cbd: 84 c0 test %al,%al + 800cbf: 75 e8 jne 800ca9 + 800cc1: eb 01 jmp 800cc4 + break; + 800cc3: 90 nop + } + return (char *)s; + 800cc4: 8b 45 08 mov 0x8(%ebp),%eax +} + 800cc7: 89 ec mov %ebp,%esp + 800cc9: 5d pop %ebp + 800cca: c3 ret + +00800ccb : + * an optional "0x" or "0X" prefix. + * + * The strtol() function returns the converted integral number as a long int value. + * */ +long +strtol(const char *s, char **endptr, int base) { + 800ccb: 55 push %ebp + 800ccc: 89 e5 mov %esp,%ebp + 800cce: 83 ec 10 sub $0x10,%esp + int neg = 0; + 800cd1: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + long val = 0; + 800cd8: c7 45 f8 00 00 00 00 movl $0x0,-0x8(%ebp) + + // gobble initial whitespace + while (*s == ' ' || *s == '\t') { + 800cdf: eb 03 jmp 800ce4 + s ++; + 800ce1: ff 45 08 incl 0x8(%ebp) + while (*s == ' ' || *s == '\t') { + 800ce4: 8b 45 08 mov 0x8(%ebp),%eax + 800ce7: 0f b6 00 movzbl (%eax),%eax + 800cea: 3c 20 cmp $0x20,%al + 800cec: 74 f3 je 800ce1 + 800cee: 8b 45 08 mov 0x8(%ebp),%eax + 800cf1: 0f b6 00 movzbl (%eax),%eax + 800cf4: 3c 09 cmp $0x9,%al + 800cf6: 74 e9 je 800ce1 + } + + // plus/minus sign + if (*s == '+') { + 800cf8: 8b 45 08 mov 0x8(%ebp),%eax + 800cfb: 0f b6 00 movzbl (%eax),%eax + 800cfe: 3c 2b cmp $0x2b,%al + 800d00: 75 05 jne 800d07 + s ++; + 800d02: ff 45 08 incl 0x8(%ebp) + 800d05: eb 14 jmp 800d1b + } + else if (*s == '-') { + 800d07: 8b 45 08 mov 0x8(%ebp),%eax + 800d0a: 0f b6 00 movzbl (%eax),%eax + 800d0d: 3c 2d cmp $0x2d,%al + 800d0f: 75 0a jne 800d1b + s ++, neg = 1; + 800d11: ff 45 08 incl 0x8(%ebp) + 800d14: c7 45 fc 01 00 00 00 movl $0x1,-0x4(%ebp) + } + + // hex or octal base prefix + if ((base == 0 || base == 16) && (s[0] == '0' && s[1] == 'x')) { + 800d1b: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800d1f: 74 06 je 800d27 + 800d21: 83 7d 10 10 cmpl $0x10,0x10(%ebp) + 800d25: 75 22 jne 800d49 + 800d27: 8b 45 08 mov 0x8(%ebp),%eax + 800d2a: 0f b6 00 movzbl (%eax),%eax + 800d2d: 3c 30 cmp $0x30,%al + 800d2f: 75 18 jne 800d49 + 800d31: 8b 45 08 mov 0x8(%ebp),%eax + 800d34: 40 inc %eax + 800d35: 0f b6 00 movzbl (%eax),%eax + 800d38: 3c 78 cmp $0x78,%al + 800d3a: 75 0d jne 800d49 + s += 2, base = 16; + 800d3c: 83 45 08 02 addl $0x2,0x8(%ebp) + 800d40: c7 45 10 10 00 00 00 movl $0x10,0x10(%ebp) + 800d47: eb 29 jmp 800d72 + } + else if (base == 0 && s[0] == '0') { + 800d49: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800d4d: 75 16 jne 800d65 + 800d4f: 8b 45 08 mov 0x8(%ebp),%eax + 800d52: 0f b6 00 movzbl (%eax),%eax + 800d55: 3c 30 cmp $0x30,%al + 800d57: 75 0c jne 800d65 + s ++, base = 8; + 800d59: ff 45 08 incl 0x8(%ebp) + 800d5c: c7 45 10 08 00 00 00 movl $0x8,0x10(%ebp) + 800d63: eb 0d jmp 800d72 + } + else if (base == 0) { + 800d65: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800d69: 75 07 jne 800d72 + base = 10; + 800d6b: c7 45 10 0a 00 00 00 movl $0xa,0x10(%ebp) + + // digits + while (1) { + int dig; + + if (*s >= '0' && *s <= '9') { + 800d72: 8b 45 08 mov 0x8(%ebp),%eax + 800d75: 0f b6 00 movzbl (%eax),%eax + 800d78: 3c 2f cmp $0x2f,%al + 800d7a: 7e 1b jle 800d97 + 800d7c: 8b 45 08 mov 0x8(%ebp),%eax + 800d7f: 0f b6 00 movzbl (%eax),%eax + 800d82: 3c 39 cmp $0x39,%al + 800d84: 7f 11 jg 800d97 + dig = *s - '0'; + 800d86: 8b 45 08 mov 0x8(%ebp),%eax + 800d89: 0f b6 00 movzbl (%eax),%eax + 800d8c: 0f be c0 movsbl %al,%eax + 800d8f: 83 e8 30 sub $0x30,%eax + 800d92: 89 45 f4 mov %eax,-0xc(%ebp) + 800d95: eb 48 jmp 800ddf + } + else if (*s >= 'a' && *s <= 'z') { + 800d97: 8b 45 08 mov 0x8(%ebp),%eax + 800d9a: 0f b6 00 movzbl (%eax),%eax + 800d9d: 3c 60 cmp $0x60,%al + 800d9f: 7e 1b jle 800dbc + 800da1: 8b 45 08 mov 0x8(%ebp),%eax + 800da4: 0f b6 00 movzbl (%eax),%eax + 800da7: 3c 7a cmp $0x7a,%al + 800da9: 7f 11 jg 800dbc + dig = *s - 'a' + 10; + 800dab: 8b 45 08 mov 0x8(%ebp),%eax + 800dae: 0f b6 00 movzbl (%eax),%eax + 800db1: 0f be c0 movsbl %al,%eax + 800db4: 83 e8 57 sub $0x57,%eax + 800db7: 89 45 f4 mov %eax,-0xc(%ebp) + 800dba: eb 23 jmp 800ddf + } + else if (*s >= 'A' && *s <= 'Z') { + 800dbc: 8b 45 08 mov 0x8(%ebp),%eax + 800dbf: 0f b6 00 movzbl (%eax),%eax + 800dc2: 3c 40 cmp $0x40,%al + 800dc4: 7e 3b jle 800e01 + 800dc6: 8b 45 08 mov 0x8(%ebp),%eax + 800dc9: 0f b6 00 movzbl (%eax),%eax + 800dcc: 3c 5a cmp $0x5a,%al + 800dce: 7f 31 jg 800e01 + dig = *s - 'A' + 10; + 800dd0: 8b 45 08 mov 0x8(%ebp),%eax + 800dd3: 0f b6 00 movzbl (%eax),%eax + 800dd6: 0f be c0 movsbl %al,%eax + 800dd9: 83 e8 37 sub $0x37,%eax + 800ddc: 89 45 f4 mov %eax,-0xc(%ebp) + } + else { + break; + } + if (dig >= base) { + 800ddf: 8b 45 f4 mov -0xc(%ebp),%eax + 800de2: 3b 45 10 cmp 0x10(%ebp),%eax + 800de5: 7d 19 jge 800e00 + break; + } + s ++, val = (val * base) + dig; + 800de7: ff 45 08 incl 0x8(%ebp) + 800dea: 8b 45 f8 mov -0x8(%ebp),%eax + 800ded: 0f af 45 10 imul 0x10(%ebp),%eax + 800df1: 89 c2 mov %eax,%edx + 800df3: 8b 45 f4 mov -0xc(%ebp),%eax + 800df6: 01 d0 add %edx,%eax + 800df8: 89 45 f8 mov %eax,-0x8(%ebp) + while (1) { + 800dfb: e9 72 ff ff ff jmp 800d72 + break; + 800e00: 90 nop + // we don't properly detect overflow! + } + + if (endptr) { + 800e01: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) + 800e05: 74 08 je 800e0f + *endptr = (char *) s; + 800e07: 8b 45 0c mov 0xc(%ebp),%eax + 800e0a: 8b 55 08 mov 0x8(%ebp),%edx + 800e0d: 89 10 mov %edx,(%eax) + } + return (neg ? -val : val); + 800e0f: 83 7d fc 00 cmpl $0x0,-0x4(%ebp) + 800e13: 74 07 je 800e1c + 800e15: 8b 45 f8 mov -0x8(%ebp),%eax + 800e18: f7 d8 neg %eax + 800e1a: eb 03 jmp 800e1f + 800e1c: 8b 45 f8 mov -0x8(%ebp),%eax +} + 800e1f: 89 ec mov %ebp,%esp + 800e21: 5d pop %ebp + 800e22: c3 ret + +00800e23 : + * @n: number of bytes to be set to the value + * + * The memset() function returns @s. + * */ +void * +memset(void *s, char c, size_t n) { + 800e23: 55 push %ebp + 800e24: 89 e5 mov %esp,%ebp + 800e26: 83 ec 28 sub $0x28,%esp + 800e29: 89 7d fc mov %edi,-0x4(%ebp) + 800e2c: 8b 45 0c mov 0xc(%ebp),%eax + 800e2f: 88 45 d8 mov %al,-0x28(%ebp) +#ifdef __HAVE_ARCH_MEMSET + return __memset(s, c, n); + 800e32: 0f be 55 d8 movsbl -0x28(%ebp),%edx + 800e36: 8b 45 08 mov 0x8(%ebp),%eax + 800e39: 89 45 f8 mov %eax,-0x8(%ebp) + 800e3c: 88 55 f7 mov %dl,-0x9(%ebp) + 800e3f: 8b 45 10 mov 0x10(%ebp),%eax + 800e42: 89 45 f0 mov %eax,-0x10(%ebp) +#ifndef __HAVE_ARCH_MEMSET +#define __HAVE_ARCH_MEMSET +static inline void * +__memset(void *s, char c, size_t n) { + int d0, d1; + asm volatile ( + 800e45: 8b 4d f0 mov -0x10(%ebp),%ecx + 800e48: 0f b6 45 f7 movzbl -0x9(%ebp),%eax + 800e4c: 8b 55 f8 mov -0x8(%ebp),%edx + 800e4f: 89 d7 mov %edx,%edi + 800e51: f3 aa rep stos %al,%es:(%edi) + 800e53: 89 fa mov %edi,%edx + 800e55: 89 4d ec mov %ecx,-0x14(%ebp) + 800e58: 89 55 e8 mov %edx,-0x18(%ebp) + "rep; stosb;" + : "=&c" (d0), "=&D" (d1) + : "0" (n), "a" (c), "1" (s) + : "memory"); + return s; + 800e5b: 8b 45 f8 mov -0x8(%ebp),%eax + while (n -- > 0) { + *p ++ = c; + } + return s; +#endif /* __HAVE_ARCH_MEMSET */ +} + 800e5e: 8b 7d fc mov -0x4(%ebp),%edi + 800e61: 89 ec mov %ebp,%esp + 800e63: 5d pop %ebp + 800e64: c3 ret + +00800e65 : + * @n: number of bytes to copy + * + * The memmove() function returns @dst. + * */ +void * +memmove(void *dst, const void *src, size_t n) { + 800e65: 55 push %ebp + 800e66: 89 e5 mov %esp,%ebp + 800e68: 57 push %edi + 800e69: 56 push %esi + 800e6a: 53 push %ebx + 800e6b: 83 ec 30 sub $0x30,%esp + 800e6e: 8b 45 08 mov 0x8(%ebp),%eax + 800e71: 89 45 f0 mov %eax,-0x10(%ebp) + 800e74: 8b 45 0c mov 0xc(%ebp),%eax + 800e77: 89 45 ec mov %eax,-0x14(%ebp) + 800e7a: 8b 45 10 mov 0x10(%ebp),%eax + 800e7d: 89 45 e8 mov %eax,-0x18(%ebp) + +#ifndef __HAVE_ARCH_MEMMOVE +#define __HAVE_ARCH_MEMMOVE +static inline void * +__memmove(void *dst, const void *src, size_t n) { + if (dst < src) { + 800e80: 8b 45 f0 mov -0x10(%ebp),%eax + 800e83: 3b 45 ec cmp -0x14(%ebp),%eax + 800e86: 73 42 jae 800eca + 800e88: 8b 45 f0 mov -0x10(%ebp),%eax + 800e8b: 89 45 e4 mov %eax,-0x1c(%ebp) + 800e8e: 8b 45 ec mov -0x14(%ebp),%eax + 800e91: 89 45 e0 mov %eax,-0x20(%ebp) + 800e94: 8b 45 e8 mov -0x18(%ebp),%eax + 800e97: 89 45 dc mov %eax,-0x24(%ebp) + "andl $3, %%ecx;" + "jz 1f;" + "rep; movsb;" + "1:" + : "=&c" (d0), "=&D" (d1), "=&S" (d2) + : "0" (n / 4), "g" (n), "1" (dst), "2" (src) + 800e9a: 8b 45 dc mov -0x24(%ebp),%eax + 800e9d: c1 e8 02 shr $0x2,%eax + 800ea0: 89 c1 mov %eax,%ecx + asm volatile ( + 800ea2: 8b 55 e4 mov -0x1c(%ebp),%edx + 800ea5: 8b 45 e0 mov -0x20(%ebp),%eax + 800ea8: 89 d7 mov %edx,%edi + 800eaa: 89 c6 mov %eax,%esi + 800eac: f3 a5 rep movsl %ds:(%esi),%es:(%edi) + 800eae: 8b 4d dc mov -0x24(%ebp),%ecx + 800eb1: 83 e1 03 and $0x3,%ecx + 800eb4: 74 02 je 800eb8 + 800eb6: f3 a4 rep movsb %ds:(%esi),%es:(%edi) + 800eb8: 89 f0 mov %esi,%eax + 800eba: 89 fa mov %edi,%edx + 800ebc: 89 4d d8 mov %ecx,-0x28(%ebp) + 800ebf: 89 55 d4 mov %edx,-0x2c(%ebp) + 800ec2: 89 45 d0 mov %eax,-0x30(%ebp) + : "memory"); + return dst; + 800ec5: 8b 45 e4 mov -0x1c(%ebp),%eax + return __memcpy(dst, src, n); + 800ec8: eb 36 jmp 800f00 + : "0" (n), "1" (n - 1 + src), "2" (n - 1 + dst) + 800eca: 8b 45 e8 mov -0x18(%ebp),%eax + 800ecd: 8d 50 ff lea -0x1(%eax),%edx + 800ed0: 8b 45 ec mov -0x14(%ebp),%eax + 800ed3: 01 c2 add %eax,%edx + 800ed5: 8b 45 e8 mov -0x18(%ebp),%eax + 800ed8: 8d 48 ff lea -0x1(%eax),%ecx + 800edb: 8b 45 f0 mov -0x10(%ebp),%eax + 800ede: 8d 1c 01 lea (%ecx,%eax,1),%ebx + asm volatile ( + 800ee1: 8b 45 e8 mov -0x18(%ebp),%eax + 800ee4: 89 c1 mov %eax,%ecx + 800ee6: 89 d8 mov %ebx,%eax + 800ee8: 89 d6 mov %edx,%esi + 800eea: 89 c7 mov %eax,%edi + 800eec: fd std + 800eed: f3 a4 rep movsb %ds:(%esi),%es:(%edi) + 800eef: fc cld + 800ef0: 89 f8 mov %edi,%eax + 800ef2: 89 f2 mov %esi,%edx + 800ef4: 89 4d cc mov %ecx,-0x34(%ebp) + 800ef7: 89 55 c8 mov %edx,-0x38(%ebp) + 800efa: 89 45 c4 mov %eax,-0x3c(%ebp) + return dst; + 800efd: 8b 45 f0 mov -0x10(%ebp),%eax + *d ++ = *s ++; + } + } + return dst; +#endif /* __HAVE_ARCH_MEMMOVE */ +} + 800f00: 83 c4 30 add $0x30,%esp + 800f03: 5b pop %ebx + 800f04: 5e pop %esi + 800f05: 5f pop %edi + 800f06: 5d pop %ebp + 800f07: c3 ret + +00800f08 : + * it always copies exactly @n bytes. To avoid overflows, the size of arrays pointed + * by both @src and @dst, should be at least @n bytes, and should not overlap + * (for overlapping memory area, memmove is a safer approach). + * */ +void * +memcpy(void *dst, const void *src, size_t n) { + 800f08: 55 push %ebp + 800f09: 89 e5 mov %esp,%ebp + 800f0b: 57 push %edi + 800f0c: 56 push %esi + 800f0d: 83 ec 20 sub $0x20,%esp + 800f10: 8b 45 08 mov 0x8(%ebp),%eax + 800f13: 89 45 f4 mov %eax,-0xc(%ebp) + 800f16: 8b 45 0c mov 0xc(%ebp),%eax + 800f19: 89 45 f0 mov %eax,-0x10(%ebp) + 800f1c: 8b 45 10 mov 0x10(%ebp),%eax + 800f1f: 89 45 ec mov %eax,-0x14(%ebp) + : "0" (n / 4), "g" (n), "1" (dst), "2" (src) + 800f22: 8b 45 ec mov -0x14(%ebp),%eax + 800f25: c1 e8 02 shr $0x2,%eax + 800f28: 89 c1 mov %eax,%ecx + asm volatile ( + 800f2a: 8b 55 f4 mov -0xc(%ebp),%edx + 800f2d: 8b 45 f0 mov -0x10(%ebp),%eax + 800f30: 89 d7 mov %edx,%edi + 800f32: 89 c6 mov %eax,%esi + 800f34: f3 a5 rep movsl %ds:(%esi),%es:(%edi) + 800f36: 8b 4d ec mov -0x14(%ebp),%ecx + 800f39: 83 e1 03 and $0x3,%ecx + 800f3c: 74 02 je 800f40 + 800f3e: f3 a4 rep movsb %ds:(%esi),%es:(%edi) + 800f40: 89 f0 mov %esi,%eax + 800f42: 89 fa mov %edi,%edx + 800f44: 89 4d e8 mov %ecx,-0x18(%ebp) + 800f47: 89 55 e4 mov %edx,-0x1c(%ebp) + 800f4a: 89 45 e0 mov %eax,-0x20(%ebp) + return dst; + 800f4d: 8b 45 f4 mov -0xc(%ebp),%eax + while (n -- > 0) { + *d ++ = *s ++; + } + return dst; +#endif /* __HAVE_ARCH_MEMCPY */ +} + 800f50: 83 c4 20 add $0x20,%esp + 800f53: 5e pop %esi + 800f54: 5f pop %edi + 800f55: 5d pop %ebp + 800f56: c3 ret + +00800f57 : + * match in both memory blocks has a greater value in @v1 than in @v2 + * as if evaluated as unsigned char values; + * - And a value less than zero indicates the opposite. + * */ +int +memcmp(const void *v1, const void *v2, size_t n) { + 800f57: 55 push %ebp + 800f58: 89 e5 mov %esp,%ebp + 800f5a: 83 ec 10 sub $0x10,%esp + const char *s1 = (const char *)v1; + 800f5d: 8b 45 08 mov 0x8(%ebp),%eax + 800f60: 89 45 fc mov %eax,-0x4(%ebp) + const char *s2 = (const char *)v2; + 800f63: 8b 45 0c mov 0xc(%ebp),%eax + 800f66: 89 45 f8 mov %eax,-0x8(%ebp) + while (n -- > 0) { + 800f69: eb 2e jmp 800f99 + if (*s1 != *s2) { + 800f6b: 8b 45 fc mov -0x4(%ebp),%eax + 800f6e: 0f b6 10 movzbl (%eax),%edx + 800f71: 8b 45 f8 mov -0x8(%ebp),%eax + 800f74: 0f b6 00 movzbl (%eax),%eax + 800f77: 38 c2 cmp %al,%dl + 800f79: 74 18 je 800f93 + return (int)((unsigned char)*s1 - (unsigned char)*s2); + 800f7b: 8b 45 fc mov -0x4(%ebp),%eax + 800f7e: 0f b6 00 movzbl (%eax),%eax + 800f81: 0f b6 d0 movzbl %al,%edx + 800f84: 8b 45 f8 mov -0x8(%ebp),%eax + 800f87: 0f b6 00 movzbl (%eax),%eax + 800f8a: 0f b6 c8 movzbl %al,%ecx + 800f8d: 89 d0 mov %edx,%eax + 800f8f: 29 c8 sub %ecx,%eax + 800f91: eb 18 jmp 800fab + } + s1 ++, s2 ++; + 800f93: ff 45 fc incl -0x4(%ebp) + 800f96: ff 45 f8 incl -0x8(%ebp) + while (n -- > 0) { + 800f99: 8b 45 10 mov 0x10(%ebp),%eax + 800f9c: 8d 50 ff lea -0x1(%eax),%edx + 800f9f: 89 55 10 mov %edx,0x10(%ebp) + 800fa2: 85 c0 test %eax,%eax + 800fa4: 75 c5 jne 800f6b + } + return 0; + 800fa6: b8 00 00 00 00 mov $0x0,%eax +} + 800fab: 89 ec mov %ebp,%esp + 800fad: 5d pop %ebp + 800fae: c3 ret + +00800faf
: +#include + +int magic = -0x10384; + +int +main(void) { + 800faf: 55 push %ebp + 800fb0: 89 e5 mov %esp,%ebp + 800fb2: 83 e4 f0 and $0xfffffff0,%esp + 800fb5: 83 ec 20 sub $0x20,%esp + int pid, code; + cprintf("I am the parent. Forking the child...\n"); + 800fb8: c7 04 24 00 14 80 00 movl $0x801400,(%esp) + 800fbf: e8 5c f1 ff ff call 800120 + if ((pid = fork()) == 0) { + 800fc4: e8 17 f3 ff ff call 8002e0 + 800fc9: 89 44 24 1c mov %eax,0x1c(%esp) + 800fcd: 83 7c 24 1c 00 cmpl $0x0,0x1c(%esp) + 800fd2: 75 3c jne 801010 + cprintf("I am the child.\n"); + 800fd4: c7 04 24 27 14 80 00 movl $0x801427,(%esp) + 800fdb: e8 40 f1 ff ff call 800120 + yield(); + 800fe0: e8 44 f3 ff ff call 800329 + yield(); + 800fe5: e8 3f f3 ff ff call 800329 + yield(); + 800fea: e8 3a f3 ff ff call 800329 + yield(); + 800fef: e8 35 f3 ff ff call 800329 + yield(); + 800ff4: e8 30 f3 ff ff call 800329 + yield(); + 800ff9: e8 2b f3 ff ff call 800329 + yield(); + 800ffe: e8 26 f3 ff ff call 800329 + exit(magic); + 801003: a1 08 20 80 00 mov 0x802008,%eax + 801008: 89 04 24 mov %eax,(%esp) + 80100b: e8 b1 f2 ff ff call 8002c1 + } + else { + cprintf("I am parent, fork a child pid %d\n",pid); + 801010: 8b 44 24 1c mov 0x1c(%esp),%eax + 801014: 89 44 24 04 mov %eax,0x4(%esp) + 801018: c7 04 24 38 14 80 00 movl $0x801438,(%esp) + 80101f: e8 fc f0 ff ff call 800120 + } + assert(pid > 0); + 801024: 83 7c 24 1c 00 cmpl $0x0,0x1c(%esp) + 801029: 7f 24 jg 80104f + 80102b: c7 44 24 0c 5a 14 80 movl $0x80145a,0xc(%esp) + 801032: 00 + 801033: c7 44 24 08 62 14 80 movl $0x801462,0x8(%esp) + 80103a: 00 + 80103b: c7 44 24 04 18 00 00 movl $0x18,0x4(%esp) + 801042: 00 + 801043: c7 04 24 77 14 80 00 movl $0x801477,(%esp) + 80104a: e8 e0 ef ff ff call 80002f <__panic> + cprintf("I am the parent, waiting now..\n"); + 80104f: c7 04 24 84 14 80 00 movl $0x801484,(%esp) + 801056: e8 c5 f0 ff ff call 800120 + + assert(waitpid(pid, &code) == 0 && code == magic); + 80105b: 8d 44 24 18 lea 0x18(%esp),%eax + 80105f: 89 44 24 04 mov %eax,0x4(%esp) + 801063: 8b 44 24 1c mov 0x1c(%esp),%eax + 801067: 89 04 24 mov %eax,(%esp) + 80106a: e8 9e f2 ff ff call 80030d + 80106f: 85 c0 test %eax,%eax + 801071: 75 0d jne 801080 + 801073: 8b 54 24 18 mov 0x18(%esp),%edx + 801077: a1 08 20 80 00 mov 0x802008,%eax + 80107c: 39 c2 cmp %eax,%edx + 80107e: 74 24 je 8010a4 + 801080: c7 44 24 0c a4 14 80 movl $0x8014a4,0xc(%esp) + 801087: 00 + 801088: c7 44 24 08 62 14 80 movl $0x801462,0x8(%esp) + 80108f: 00 + 801090: c7 44 24 04 1b 00 00 movl $0x1b,0x4(%esp) + 801097: 00 + 801098: c7 04 24 77 14 80 00 movl $0x801477,(%esp) + 80109f: e8 8b ef ff ff call 80002f <__panic> + assert(waitpid(pid, &code) != 0 && wait() != 0); + 8010a4: 8d 44 24 18 lea 0x18(%esp),%eax + 8010a8: 89 44 24 04 mov %eax,0x4(%esp) + 8010ac: 8b 44 24 1c mov 0x1c(%esp),%eax + 8010b0: 89 04 24 mov %eax,(%esp) + 8010b3: e8 55 f2 ff ff call 80030d + 8010b8: 85 c0 test %eax,%eax + 8010ba: 74 09 je 8010c5 + 8010bc: e8 2e f2 ff ff call 8002ef + 8010c1: 85 c0 test %eax,%eax + 8010c3: 75 24 jne 8010e9 + 8010c5: c7 44 24 0c d0 14 80 movl $0x8014d0,0xc(%esp) + 8010cc: 00 + 8010cd: c7 44 24 08 62 14 80 movl $0x801462,0x8(%esp) + 8010d4: 00 + 8010d5: c7 44 24 04 1c 00 00 movl $0x1c,0x4(%esp) + 8010dc: 00 + 8010dd: c7 04 24 77 14 80 00 movl $0x801477,(%esp) + 8010e4: e8 46 ef ff ff call 80002f <__panic> + cprintf("waitpid %d ok.\n", pid); + 8010e9: 8b 44 24 1c mov 0x1c(%esp),%eax + 8010ed: 89 44 24 04 mov %eax,0x4(%esp) + 8010f1: c7 04 24 f8 14 80 00 movl $0x8014f8,(%esp) + 8010f8: e8 23 f0 ff ff call 800120 + + cprintf("exit pass.\n"); + 8010fd: c7 04 24 08 15 80 00 movl $0x801508,(%esp) + 801104: e8 17 f0 ff ff call 800120 + return 0; + 801109: b8 00 00 00 00 mov $0x0,%eax +} + 80110e: 89 ec mov %ebp,%esp + 801110: 5d pop %ebp + 801111: c3 ret diff --git a/labcodes/lab5/obj/user/exit.d b/labcodes/lab5/obj/user/exit.d new file mode 100644 index 0000000000000000000000000000000000000000..be977cd574d6cdd94c3d32ac90ebef5db6613edb --- /dev/null +++ b/labcodes/lab5/obj/user/exit.d @@ -0,0 +1,2 @@ +obj/user/exit.o obj/user/exit.d: user/exit.c libs/stdio.h libs/defs.h \ + libs/stdarg.h user/libs/ulib.h diff --git a/labcodes/lab5/obj/user/exit.o b/labcodes/lab5/obj/user/exit.o new file mode 100644 index 0000000000000000000000000000000000000000..b8523c71bb61121c7864b5f3d3df428520fa1853 Binary files /dev/null and b/labcodes/lab5/obj/user/exit.o differ diff --git a/labcodes/lab5/obj/user/exit.sym b/labcodes/lab5/obj/user/exit.sym new file mode 100644 index 0000000000000000000000000000000000000000..ab51fa6999a461c5cf9ff14d9b74018867b71412 --- /dev/null +++ b/labcodes/lab5/obj/user/exit.sym @@ -0,0 +1,67 @@ +00000000 panic.c +00000000 stdio.c +008000c8 cputch +00000000 syscall.c +00800199 syscall +00000000 ulib.c +00000000 umain.c +00000000 hash.c +00000000 printfmt.c +00801220 error_string +008003ad printnum +008004af getuint +008004fe getint +0080094f sprintputch +00000000 rand.c +00802000 next +00000000 string.c +00000000 exit.c +00800b53 strcpy +00800329 yield +0080030d waitpid +00800245 sys_yield +00800e65 memmove +00800985 snprintf +00800576 vprintfmt +0080020b sys_fork +00800120 cprintf +0080034e getpid +00800f08 memcpy +008009bb vsnprintf +0080036d umain +00202818 __STAB_END__ +0080025b sys_kill +00202819 __STABSTR_BEGIN__ +0080002f __panic +00800ccb strtol +00800b22 strnlen +0080035d print_pgdir +00800339 kill +00800c9b strfind +008002ef wait +00800020 _start +00800a21 rand +00800c14 strncmp +0080028e sys_putc +00800b92 strncpy +00800f57 memcmp +008002e0 fork +00800e23 memset +00800faf main +00800ae0 srand +00800386 hash32 +00800545 printfmt +00203747 __STABSTR_END__ +00800bcb strcmp +00802008 magic +008000eb vcprintf +0080007f __warn +00800148 cputs +008002c1 exit +00800221 sys_wait +008001ee sys_exit +00200010 __STAB_BEGIN__ +00800af9 strlen +008002ab sys_pgdir +00800c67 strchr +00800278 sys_getpid diff --git a/labcodes/lab5/obj/user/faultread.asm b/labcodes/lab5/obj/user/faultread.asm new file mode 100644 index 0000000000000000000000000000000000000000..08365ff68ab2ce743f7e1e7bbe4e7a38eb4421a3 --- /dev/null +++ b/labcodes/lab5/obj/user/faultread.asm @@ -0,0 +1,2323 @@ + +obj/__user_faultread.out: file format elf32-i386 + + +Disassembly of section .text: + +00800020 <_start>: +.text +.globl _start +_start: + # set ebp for backtrace + movl $0x0, %ebp + 800020: bd 00 00 00 00 mov $0x0,%ebp + + # move down the esp register + # since it may cause page fault in backtrace + subl $0x20, %esp + 800025: 83 ec 20 sub $0x20,%esp + + # call user-program function + call umain + 800028: e8 40 03 00 00 call 80036d +1: jmp 1b + 80002d: eb fe jmp 80002d <_start+0xd> + +0080002f <__panic>: +#include +#include +#include + +void +__panic(const char *file, int line, const char *fmt, ...) { + 80002f: 55 push %ebp + 800030: 89 e5 mov %esp,%ebp + 800032: 83 ec 28 sub $0x28,%esp + // print the 'message' + va_list ap; + va_start(ap, fmt); + 800035: 8d 45 14 lea 0x14(%ebp),%eax + 800038: 89 45 f4 mov %eax,-0xc(%ebp) + cprintf("user panic at %s:%d:\n ", file, line); + 80003b: 8b 45 0c mov 0xc(%ebp),%eax + 80003e: 89 44 24 08 mov %eax,0x8(%esp) + 800042: 8b 45 08 mov 0x8(%ebp),%eax + 800045: 89 44 24 04 mov %eax,0x4(%esp) + 800049: c7 04 24 00 10 80 00 movl $0x801000,(%esp) + 800050: e8 cb 00 00 00 call 800120 + vcprintf(fmt, ap); + 800055: 8b 45 f4 mov -0xc(%ebp),%eax + 800058: 89 44 24 04 mov %eax,0x4(%esp) + 80005c: 8b 45 10 mov 0x10(%ebp),%eax + 80005f: 89 04 24 mov %eax,(%esp) + 800062: e8 84 00 00 00 call 8000eb + cprintf("\n"); + 800067: c7 04 24 1a 10 80 00 movl $0x80101a,(%esp) + 80006e: e8 ad 00 00 00 call 800120 + va_end(ap); + exit(-E_PANIC); + 800073: c7 04 24 f6 ff ff ff movl $0xfffffff6,(%esp) + 80007a: e8 42 02 00 00 call 8002c1 + +0080007f <__warn>: +} + +void +__warn(const char *file, int line, const char *fmt, ...) { + 80007f: 55 push %ebp + 800080: 89 e5 mov %esp,%ebp + 800082: 83 ec 28 sub $0x28,%esp + va_list ap; + va_start(ap, fmt); + 800085: 8d 45 14 lea 0x14(%ebp),%eax + 800088: 89 45 f4 mov %eax,-0xc(%ebp) + cprintf("user warning at %s:%d:\n ", file, line); + 80008b: 8b 45 0c mov 0xc(%ebp),%eax + 80008e: 89 44 24 08 mov %eax,0x8(%esp) + 800092: 8b 45 08 mov 0x8(%ebp),%eax + 800095: 89 44 24 04 mov %eax,0x4(%esp) + 800099: c7 04 24 1c 10 80 00 movl $0x80101c,(%esp) + 8000a0: e8 7b 00 00 00 call 800120 + vcprintf(fmt, ap); + 8000a5: 8b 45 f4 mov -0xc(%ebp),%eax + 8000a8: 89 44 24 04 mov %eax,0x4(%esp) + 8000ac: 8b 45 10 mov 0x10(%ebp),%eax + 8000af: 89 04 24 mov %eax,(%esp) + 8000b2: e8 34 00 00 00 call 8000eb + cprintf("\n"); + 8000b7: c7 04 24 1a 10 80 00 movl $0x80101a,(%esp) + 8000be: e8 5d 00 00 00 call 800120 + va_end(ap); +} + 8000c3: 90 nop + 8000c4: 89 ec mov %ebp,%esp + 8000c6: 5d pop %ebp + 8000c7: c3 ret + +008000c8 : +/* * + * cputch - writes a single character @c to stdout, and it will + * increace the value of counter pointed by @cnt. + * */ +static void +cputch(int c, int *cnt) { + 8000c8: 55 push %ebp + 8000c9: 89 e5 mov %esp,%ebp + 8000cb: 83 ec 18 sub $0x18,%esp + sys_putc(c); + 8000ce: 8b 45 08 mov 0x8(%ebp),%eax + 8000d1: 89 04 24 mov %eax,(%esp) + 8000d4: e8 b5 01 00 00 call 80028e + (*cnt) ++; + 8000d9: 8b 45 0c mov 0xc(%ebp),%eax + 8000dc: 8b 00 mov (%eax),%eax + 8000de: 8d 50 01 lea 0x1(%eax),%edx + 8000e1: 8b 45 0c mov 0xc(%ebp),%eax + 8000e4: 89 10 mov %edx,(%eax) +} + 8000e6: 90 nop + 8000e7: 89 ec mov %ebp,%esp + 8000e9: 5d pop %ebp + 8000ea: c3 ret + +008000eb : + * + * Call this function if you are already dealing with a va_list. + * Or you probably want cprintf() instead. + * */ +int +vcprintf(const char *fmt, va_list ap) { + 8000eb: 55 push %ebp + 8000ec: 89 e5 mov %esp,%ebp + 8000ee: 83 ec 28 sub $0x28,%esp + int cnt = 0; + 8000f1: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + vprintfmt((void*)cputch, &cnt, fmt, ap); + 8000f8: 8b 45 0c mov 0xc(%ebp),%eax + 8000fb: 89 44 24 0c mov %eax,0xc(%esp) + 8000ff: 8b 45 08 mov 0x8(%ebp),%eax + 800102: 89 44 24 08 mov %eax,0x8(%esp) + 800106: 8d 45 f4 lea -0xc(%ebp),%eax + 800109: 89 44 24 04 mov %eax,0x4(%esp) + 80010d: c7 04 24 c8 00 80 00 movl $0x8000c8,(%esp) + 800114: e8 5d 04 00 00 call 800576 + return cnt; + 800119: 8b 45 f4 mov -0xc(%ebp),%eax +} + 80011c: 89 ec mov %ebp,%esp + 80011e: 5d pop %ebp + 80011f: c3 ret + +00800120 : + * + * The return value is the number of characters which would be + * written to stdout. + * */ +int +cprintf(const char *fmt, ...) { + 800120: 55 push %ebp + 800121: 89 e5 mov %esp,%ebp + 800123: 83 ec 28 sub $0x28,%esp + va_list ap; + + va_start(ap, fmt); + 800126: 8d 45 0c lea 0xc(%ebp),%eax + 800129: 89 45 f0 mov %eax,-0x10(%ebp) + int cnt = vcprintf(fmt, ap); + 80012c: 8b 45 f0 mov -0x10(%ebp),%eax + 80012f: 89 44 24 04 mov %eax,0x4(%esp) + 800133: 8b 45 08 mov 0x8(%ebp),%eax + 800136: 89 04 24 mov %eax,(%esp) + 800139: e8 ad ff ff ff call 8000eb + 80013e: 89 45 f4 mov %eax,-0xc(%ebp) + va_end(ap); + + return cnt; + 800141: 8b 45 f4 mov -0xc(%ebp),%eax +} + 800144: 89 ec mov %ebp,%esp + 800146: 5d pop %ebp + 800147: c3 ret + +00800148 : +/* * + * cputs- writes the string pointed by @str to stdout and + * appends a newline character. + * */ +int +cputs(const char *str) { + 800148: 55 push %ebp + 800149: 89 e5 mov %esp,%ebp + 80014b: 83 ec 28 sub $0x28,%esp + int cnt = 0; + 80014e: c7 45 f0 00 00 00 00 movl $0x0,-0x10(%ebp) + char c; + while ((c = *str ++) != '\0') { + 800155: eb 13 jmp 80016a + cputch(c, &cnt); + 800157: 0f be 45 f7 movsbl -0x9(%ebp),%eax + 80015b: 8d 55 f0 lea -0x10(%ebp),%edx + 80015e: 89 54 24 04 mov %edx,0x4(%esp) + 800162: 89 04 24 mov %eax,(%esp) + 800165: e8 5e ff ff ff call 8000c8 + while ((c = *str ++) != '\0') { + 80016a: 8b 45 08 mov 0x8(%ebp),%eax + 80016d: 8d 50 01 lea 0x1(%eax),%edx + 800170: 89 55 08 mov %edx,0x8(%ebp) + 800173: 0f b6 00 movzbl (%eax),%eax + 800176: 88 45 f7 mov %al,-0x9(%ebp) + 800179: 80 7d f7 00 cmpb $0x0,-0x9(%ebp) + 80017d: 75 d8 jne 800157 + } + cputch('\n', &cnt); + 80017f: 8d 45 f0 lea -0x10(%ebp),%eax + 800182: 89 44 24 04 mov %eax,0x4(%esp) + 800186: c7 04 24 0a 00 00 00 movl $0xa,(%esp) + 80018d: e8 36 ff ff ff call 8000c8 + return cnt; + 800192: 8b 45 f0 mov -0x10(%ebp),%eax +} + 800195: 89 ec mov %ebp,%esp + 800197: 5d pop %ebp + 800198: c3 ret + +00800199 : +#include + +#define MAX_ARGS 5 + +static inline int +syscall(int num, ...) { + 800199: 55 push %ebp + 80019a: 89 e5 mov %esp,%ebp + 80019c: 57 push %edi + 80019d: 56 push %esi + 80019e: 53 push %ebx + 80019f: 83 ec 20 sub $0x20,%esp + va_list ap; + va_start(ap, num); + 8001a2: 8d 45 0c lea 0xc(%ebp),%eax + 8001a5: 89 45 e8 mov %eax,-0x18(%ebp) + uint32_t a[MAX_ARGS]; + int i, ret; + for (i = 0; i < MAX_ARGS; i ++) { + 8001a8: c7 45 f0 00 00 00 00 movl $0x0,-0x10(%ebp) + 8001af: eb 15 jmp 8001c6 + a[i] = va_arg(ap, uint32_t); + 8001b1: 8b 45 e8 mov -0x18(%ebp),%eax + 8001b4: 8d 50 04 lea 0x4(%eax),%edx + 8001b7: 89 55 e8 mov %edx,-0x18(%ebp) + 8001ba: 8b 10 mov (%eax),%edx + 8001bc: 8b 45 f0 mov -0x10(%ebp),%eax + 8001bf: 89 54 85 d4 mov %edx,-0x2c(%ebp,%eax,4) + for (i = 0; i < MAX_ARGS; i ++) { + 8001c3: ff 45 f0 incl -0x10(%ebp) + 8001c6: 83 7d f0 04 cmpl $0x4,-0x10(%ebp) + 8001ca: 7e e5 jle 8001b1 + asm volatile ( + "int %1;" + : "=a" (ret) + : "i" (T_SYSCALL), + "a" (num), + "d" (a[0]), + 8001cc: 8b 55 d4 mov -0x2c(%ebp),%edx + "c" (a[1]), + 8001cf: 8b 4d d8 mov -0x28(%ebp),%ecx + "b" (a[2]), + 8001d2: 8b 5d dc mov -0x24(%ebp),%ebx + "D" (a[3]), + 8001d5: 8b 7d e0 mov -0x20(%ebp),%edi + "S" (a[4]) + 8001d8: 8b 75 e4 mov -0x1c(%ebp),%esi + asm volatile ( + 8001db: 8b 45 08 mov 0x8(%ebp),%eax + 8001de: cd 80 int $0x80 + 8001e0: 89 45 ec mov %eax,-0x14(%ebp) + : "cc", "memory"); + return ret; + 8001e3: 8b 45 ec mov -0x14(%ebp),%eax +} + 8001e6: 83 c4 20 add $0x20,%esp + 8001e9: 5b pop %ebx + 8001ea: 5e pop %esi + 8001eb: 5f pop %edi + 8001ec: 5d pop %ebp + 8001ed: c3 ret + +008001ee : + +int +sys_exit(int error_code) { + 8001ee: 55 push %ebp + 8001ef: 89 e5 mov %esp,%ebp + 8001f1: 83 ec 08 sub $0x8,%esp + return syscall(SYS_exit, error_code); + 8001f4: 8b 45 08 mov 0x8(%ebp),%eax + 8001f7: 89 44 24 04 mov %eax,0x4(%esp) + 8001fb: c7 04 24 01 00 00 00 movl $0x1,(%esp) + 800202: e8 92 ff ff ff call 800199 +} + 800207: 89 ec mov %ebp,%esp + 800209: 5d pop %ebp + 80020a: c3 ret + +0080020b : + +int +sys_fork(void) { + 80020b: 55 push %ebp + 80020c: 89 e5 mov %esp,%ebp + 80020e: 83 ec 04 sub $0x4,%esp + return syscall(SYS_fork); + 800211: c7 04 24 02 00 00 00 movl $0x2,(%esp) + 800218: e8 7c ff ff ff call 800199 +} + 80021d: 89 ec mov %ebp,%esp + 80021f: 5d pop %ebp + 800220: c3 ret + +00800221 : + +int +sys_wait(int pid, int *store) { + 800221: 55 push %ebp + 800222: 89 e5 mov %esp,%ebp + 800224: 83 ec 0c sub $0xc,%esp + return syscall(SYS_wait, pid, store); + 800227: 8b 45 0c mov 0xc(%ebp),%eax + 80022a: 89 44 24 08 mov %eax,0x8(%esp) + 80022e: 8b 45 08 mov 0x8(%ebp),%eax + 800231: 89 44 24 04 mov %eax,0x4(%esp) + 800235: c7 04 24 03 00 00 00 movl $0x3,(%esp) + 80023c: e8 58 ff ff ff call 800199 +} + 800241: 89 ec mov %ebp,%esp + 800243: 5d pop %ebp + 800244: c3 ret + +00800245 : + +int +sys_yield(void) { + 800245: 55 push %ebp + 800246: 89 e5 mov %esp,%ebp + 800248: 83 ec 04 sub $0x4,%esp + return syscall(SYS_yield); + 80024b: c7 04 24 0a 00 00 00 movl $0xa,(%esp) + 800252: e8 42 ff ff ff call 800199 +} + 800257: 89 ec mov %ebp,%esp + 800259: 5d pop %ebp + 80025a: c3 ret + +0080025b : + +int +sys_kill(int pid) { + 80025b: 55 push %ebp + 80025c: 89 e5 mov %esp,%ebp + 80025e: 83 ec 08 sub $0x8,%esp + return syscall(SYS_kill, pid); + 800261: 8b 45 08 mov 0x8(%ebp),%eax + 800264: 89 44 24 04 mov %eax,0x4(%esp) + 800268: c7 04 24 0c 00 00 00 movl $0xc,(%esp) + 80026f: e8 25 ff ff ff call 800199 +} + 800274: 89 ec mov %ebp,%esp + 800276: 5d pop %ebp + 800277: c3 ret + +00800278 : + +int +sys_getpid(void) { + 800278: 55 push %ebp + 800279: 89 e5 mov %esp,%ebp + 80027b: 83 ec 04 sub $0x4,%esp + return syscall(SYS_getpid); + 80027e: c7 04 24 12 00 00 00 movl $0x12,(%esp) + 800285: e8 0f ff ff ff call 800199 +} + 80028a: 89 ec mov %ebp,%esp + 80028c: 5d pop %ebp + 80028d: c3 ret + +0080028e : + +int +sys_putc(int c) { + 80028e: 55 push %ebp + 80028f: 89 e5 mov %esp,%ebp + 800291: 83 ec 08 sub $0x8,%esp + return syscall(SYS_putc, c); + 800294: 8b 45 08 mov 0x8(%ebp),%eax + 800297: 89 44 24 04 mov %eax,0x4(%esp) + 80029b: c7 04 24 1e 00 00 00 movl $0x1e,(%esp) + 8002a2: e8 f2 fe ff ff call 800199 +} + 8002a7: 89 ec mov %ebp,%esp + 8002a9: 5d pop %ebp + 8002aa: c3 ret + +008002ab : + +int +sys_pgdir(void) { + 8002ab: 55 push %ebp + 8002ac: 89 e5 mov %esp,%ebp + 8002ae: 83 ec 04 sub $0x4,%esp + return syscall(SYS_pgdir); + 8002b1: c7 04 24 1f 00 00 00 movl $0x1f,(%esp) + 8002b8: e8 dc fe ff ff call 800199 +} + 8002bd: 89 ec mov %ebp,%esp + 8002bf: 5d pop %ebp + 8002c0: c3 ret + +008002c1 : +#include +#include +#include + +void +exit(int error_code) { + 8002c1: 55 push %ebp + 8002c2: 89 e5 mov %esp,%ebp + 8002c4: 83 ec 18 sub $0x18,%esp + sys_exit(error_code); + 8002c7: 8b 45 08 mov 0x8(%ebp),%eax + 8002ca: 89 04 24 mov %eax,(%esp) + 8002cd: e8 1c ff ff ff call 8001ee + cprintf("BUG: exit failed.\n"); + 8002d2: c7 04 24 38 10 80 00 movl $0x801038,(%esp) + 8002d9: e8 42 fe ff ff call 800120 + while (1); + 8002de: eb fe jmp 8002de + +008002e0 : +} + +int +fork(void) { + 8002e0: 55 push %ebp + 8002e1: 89 e5 mov %esp,%ebp + 8002e3: 83 ec 08 sub $0x8,%esp + return sys_fork(); + 8002e6: e8 20 ff ff ff call 80020b +} + 8002eb: 89 ec mov %ebp,%esp + 8002ed: 5d pop %ebp + 8002ee: c3 ret + +008002ef : + +int +wait(void) { + 8002ef: 55 push %ebp + 8002f0: 89 e5 mov %esp,%ebp + 8002f2: 83 ec 18 sub $0x18,%esp + return sys_wait(0, NULL); + 8002f5: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) + 8002fc: 00 + 8002fd: c7 04 24 00 00 00 00 movl $0x0,(%esp) + 800304: e8 18 ff ff ff call 800221 +} + 800309: 89 ec mov %ebp,%esp + 80030b: 5d pop %ebp + 80030c: c3 ret + +0080030d : + +int +waitpid(int pid, int *store) { + 80030d: 55 push %ebp + 80030e: 89 e5 mov %esp,%ebp + 800310: 83 ec 18 sub $0x18,%esp + return sys_wait(pid, store); + 800313: 8b 45 0c mov 0xc(%ebp),%eax + 800316: 89 44 24 04 mov %eax,0x4(%esp) + 80031a: 8b 45 08 mov 0x8(%ebp),%eax + 80031d: 89 04 24 mov %eax,(%esp) + 800320: e8 fc fe ff ff call 800221 +} + 800325: 89 ec mov %ebp,%esp + 800327: 5d pop %ebp + 800328: c3 ret + +00800329 : + +void +yield(void) { + 800329: 55 push %ebp + 80032a: 89 e5 mov %esp,%ebp + 80032c: 83 ec 08 sub $0x8,%esp + sys_yield(); + 80032f: e8 11 ff ff ff call 800245 +} + 800334: 90 nop + 800335: 89 ec mov %ebp,%esp + 800337: 5d pop %ebp + 800338: c3 ret + +00800339 : + +int +kill(int pid) { + 800339: 55 push %ebp + 80033a: 89 e5 mov %esp,%ebp + 80033c: 83 ec 18 sub $0x18,%esp + return sys_kill(pid); + 80033f: 8b 45 08 mov 0x8(%ebp),%eax + 800342: 89 04 24 mov %eax,(%esp) + 800345: e8 11 ff ff ff call 80025b +} + 80034a: 89 ec mov %ebp,%esp + 80034c: 5d pop %ebp + 80034d: c3 ret + +0080034e : + +int +getpid(void) { + 80034e: 55 push %ebp + 80034f: 89 e5 mov %esp,%ebp + 800351: 83 ec 08 sub $0x8,%esp + return sys_getpid(); + 800354: e8 1f ff ff ff call 800278 +} + 800359: 89 ec mov %ebp,%esp + 80035b: 5d pop %ebp + 80035c: c3 ret + +0080035d : + +//print_pgdir - print the PDT&PT +void +print_pgdir(void) { + 80035d: 55 push %ebp + 80035e: 89 e5 mov %esp,%ebp + 800360: 83 ec 08 sub $0x8,%esp + sys_pgdir(); + 800363: e8 43 ff ff ff call 8002ab +} + 800368: 90 nop + 800369: 89 ec mov %ebp,%esp + 80036b: 5d pop %ebp + 80036c: c3 ret + +0080036d : +#include + +int main(void); + +void +umain(void) { + 80036d: 55 push %ebp + 80036e: 89 e5 mov %esp,%ebp + 800370: 83 ec 28 sub $0x28,%esp + int ret = main(); + 800373: e8 37 0c 00 00 call 800faf
+ 800378: 89 45 f4 mov %eax,-0xc(%ebp) + exit(ret); + 80037b: 8b 45 f4 mov -0xc(%ebp),%eax + 80037e: 89 04 24 mov %eax,(%esp) + 800381: e8 3b ff ff ff call 8002c1 + +00800386 : + * @bits: the number of bits in a return value + * + * High bits are more random, so we use them. + * */ +uint32_t +hash32(uint32_t val, unsigned int bits) { + 800386: 55 push %ebp + 800387: 89 e5 mov %esp,%ebp + 800389: 83 ec 10 sub $0x10,%esp + uint32_t hash = val * GOLDEN_RATIO_PRIME_32; + 80038c: 8b 45 08 mov 0x8(%ebp),%eax + 80038f: 69 c0 01 00 37 9e imul $0x9e370001,%eax,%eax + 800395: 89 45 fc mov %eax,-0x4(%ebp) + return (hash >> (32 - bits)); + 800398: b8 20 00 00 00 mov $0x20,%eax + 80039d: 2b 45 0c sub 0xc(%ebp),%eax + 8003a0: 8b 55 fc mov -0x4(%ebp),%edx + 8003a3: 88 c1 mov %al,%cl + 8003a5: d3 ea shr %cl,%edx + 8003a7: 89 d0 mov %edx,%eax +} + 8003a9: 89 ec mov %ebp,%esp + 8003ab: 5d pop %ebp + 8003ac: c3 ret + +008003ad : + * @width: maximum number of digits, if the actual width is less than @width, use @padc instead + * @padc: character that padded on the left if the actual width is less than @width + * */ +static void +printnum(void (*putch)(int, void*), void *putdat, + unsigned long long num, unsigned base, int width, int padc) { + 8003ad: 55 push %ebp + 8003ae: 89 e5 mov %esp,%ebp + 8003b0: 83 ec 58 sub $0x58,%esp + 8003b3: 8b 45 10 mov 0x10(%ebp),%eax + 8003b6: 89 45 d0 mov %eax,-0x30(%ebp) + 8003b9: 8b 45 14 mov 0x14(%ebp),%eax + 8003bc: 89 45 d4 mov %eax,-0x2c(%ebp) + unsigned long long result = num; + 8003bf: 8b 45 d0 mov -0x30(%ebp),%eax + 8003c2: 8b 55 d4 mov -0x2c(%ebp),%edx + 8003c5: 89 45 e8 mov %eax,-0x18(%ebp) + 8003c8: 89 55 ec mov %edx,-0x14(%ebp) + unsigned mod = do_div(result, base); + 8003cb: 8b 45 18 mov 0x18(%ebp),%eax + 8003ce: 89 45 e4 mov %eax,-0x1c(%ebp) + 8003d1: 8b 45 e8 mov -0x18(%ebp),%eax + 8003d4: 8b 55 ec mov -0x14(%ebp),%edx + 8003d7: 89 45 e0 mov %eax,-0x20(%ebp) + 8003da: 89 55 f0 mov %edx,-0x10(%ebp) + 8003dd: 8b 45 f0 mov -0x10(%ebp),%eax + 8003e0: 89 45 f4 mov %eax,-0xc(%ebp) + 8003e3: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) + 8003e7: 74 1c je 800405 + 8003e9: 8b 45 f0 mov -0x10(%ebp),%eax + 8003ec: ba 00 00 00 00 mov $0x0,%edx + 8003f1: f7 75 e4 divl -0x1c(%ebp) + 8003f4: 89 55 f4 mov %edx,-0xc(%ebp) + 8003f7: 8b 45 f0 mov -0x10(%ebp),%eax + 8003fa: ba 00 00 00 00 mov $0x0,%edx + 8003ff: f7 75 e4 divl -0x1c(%ebp) + 800402: 89 45 f0 mov %eax,-0x10(%ebp) + 800405: 8b 45 e0 mov -0x20(%ebp),%eax + 800408: 8b 55 f4 mov -0xc(%ebp),%edx + 80040b: f7 75 e4 divl -0x1c(%ebp) + 80040e: 89 45 e0 mov %eax,-0x20(%ebp) + 800411: 89 55 dc mov %edx,-0x24(%ebp) + 800414: 8b 45 e0 mov -0x20(%ebp),%eax + 800417: 8b 55 f0 mov -0x10(%ebp),%edx + 80041a: 89 45 e8 mov %eax,-0x18(%ebp) + 80041d: 89 55 ec mov %edx,-0x14(%ebp) + 800420: 8b 45 dc mov -0x24(%ebp),%eax + 800423: 89 45 d8 mov %eax,-0x28(%ebp) + + // first recursively print all preceding (more significant) digits + if (num >= base) { + 800426: 8b 45 18 mov 0x18(%ebp),%eax + 800429: ba 00 00 00 00 mov $0x0,%edx + 80042e: 8b 4d d4 mov -0x2c(%ebp),%ecx + 800431: 39 45 d0 cmp %eax,-0x30(%ebp) + 800434: 19 d1 sbb %edx,%ecx + 800436: 72 4c jb 800484 + printnum(putch, putdat, result, base, width - 1, padc); + 800438: 8b 45 1c mov 0x1c(%ebp),%eax + 80043b: 8d 50 ff lea -0x1(%eax),%edx + 80043e: 8b 45 20 mov 0x20(%ebp),%eax + 800441: 89 44 24 18 mov %eax,0x18(%esp) + 800445: 89 54 24 14 mov %edx,0x14(%esp) + 800449: 8b 45 18 mov 0x18(%ebp),%eax + 80044c: 89 44 24 10 mov %eax,0x10(%esp) + 800450: 8b 45 e8 mov -0x18(%ebp),%eax + 800453: 8b 55 ec mov -0x14(%ebp),%edx + 800456: 89 44 24 08 mov %eax,0x8(%esp) + 80045a: 89 54 24 0c mov %edx,0xc(%esp) + 80045e: 8b 45 0c mov 0xc(%ebp),%eax + 800461: 89 44 24 04 mov %eax,0x4(%esp) + 800465: 8b 45 08 mov 0x8(%ebp),%eax + 800468: 89 04 24 mov %eax,(%esp) + 80046b: e8 3d ff ff ff call 8003ad + 800470: eb 1b jmp 80048d + } else { + // print any needed pad characters before first digit + while (-- width > 0) + putch(padc, putdat); + 800472: 8b 45 0c mov 0xc(%ebp),%eax + 800475: 89 44 24 04 mov %eax,0x4(%esp) + 800479: 8b 45 20 mov 0x20(%ebp),%eax + 80047c: 89 04 24 mov %eax,(%esp) + 80047f: 8b 45 08 mov 0x8(%ebp),%eax + 800482: ff d0 call *%eax + while (-- width > 0) + 800484: ff 4d 1c decl 0x1c(%ebp) + 800487: 83 7d 1c 00 cmpl $0x0,0x1c(%ebp) + 80048b: 7f e5 jg 800472 + } + // then print this (the least significant) digit + putch("0123456789abcdef"[mod], putdat); + 80048d: 8b 45 d8 mov -0x28(%ebp),%eax + 800490: 05 64 11 80 00 add $0x801164,%eax + 800495: 0f b6 00 movzbl (%eax),%eax + 800498: 0f be c0 movsbl %al,%eax + 80049b: 8b 55 0c mov 0xc(%ebp),%edx + 80049e: 89 54 24 04 mov %edx,0x4(%esp) + 8004a2: 89 04 24 mov %eax,(%esp) + 8004a5: 8b 45 08 mov 0x8(%ebp),%eax + 8004a8: ff d0 call *%eax +} + 8004aa: 90 nop + 8004ab: 89 ec mov %ebp,%esp + 8004ad: 5d pop %ebp + 8004ae: c3 ret + +008004af : + * getuint - get an unsigned int of various possible sizes from a varargs list + * @ap: a varargs list pointer + * @lflag: determines the size of the vararg that @ap points to + * */ +static unsigned long long +getuint(va_list *ap, int lflag) { + 8004af: 55 push %ebp + 8004b0: 89 e5 mov %esp,%ebp + if (lflag >= 2) { + 8004b2: 83 7d 0c 01 cmpl $0x1,0xc(%ebp) + 8004b6: 7e 14 jle 8004cc + return va_arg(*ap, unsigned long long); + 8004b8: 8b 45 08 mov 0x8(%ebp),%eax + 8004bb: 8b 00 mov (%eax),%eax + 8004bd: 8d 48 08 lea 0x8(%eax),%ecx + 8004c0: 8b 55 08 mov 0x8(%ebp),%edx + 8004c3: 89 0a mov %ecx,(%edx) + 8004c5: 8b 50 04 mov 0x4(%eax),%edx + 8004c8: 8b 00 mov (%eax),%eax + 8004ca: eb 30 jmp 8004fc + } + else if (lflag) { + 8004cc: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) + 8004d0: 74 16 je 8004e8 + return va_arg(*ap, unsigned long); + 8004d2: 8b 45 08 mov 0x8(%ebp),%eax + 8004d5: 8b 00 mov (%eax),%eax + 8004d7: 8d 48 04 lea 0x4(%eax),%ecx + 8004da: 8b 55 08 mov 0x8(%ebp),%edx + 8004dd: 89 0a mov %ecx,(%edx) + 8004df: 8b 00 mov (%eax),%eax + 8004e1: ba 00 00 00 00 mov $0x0,%edx + 8004e6: eb 14 jmp 8004fc + } + else { + return va_arg(*ap, unsigned int); + 8004e8: 8b 45 08 mov 0x8(%ebp),%eax + 8004eb: 8b 00 mov (%eax),%eax + 8004ed: 8d 48 04 lea 0x4(%eax),%ecx + 8004f0: 8b 55 08 mov 0x8(%ebp),%edx + 8004f3: 89 0a mov %ecx,(%edx) + 8004f5: 8b 00 mov (%eax),%eax + 8004f7: ba 00 00 00 00 mov $0x0,%edx + } +} + 8004fc: 5d pop %ebp + 8004fd: c3 ret + +008004fe : + * getint - same as getuint but signed, we can't use getuint because of sign extension + * @ap: a varargs list pointer + * @lflag: determines the size of the vararg that @ap points to + * */ +static long long +getint(va_list *ap, int lflag) { + 8004fe: 55 push %ebp + 8004ff: 89 e5 mov %esp,%ebp + if (lflag >= 2) { + 800501: 83 7d 0c 01 cmpl $0x1,0xc(%ebp) + 800505: 7e 14 jle 80051b + return va_arg(*ap, long long); + 800507: 8b 45 08 mov 0x8(%ebp),%eax + 80050a: 8b 00 mov (%eax),%eax + 80050c: 8d 48 08 lea 0x8(%eax),%ecx + 80050f: 8b 55 08 mov 0x8(%ebp),%edx + 800512: 89 0a mov %ecx,(%edx) + 800514: 8b 50 04 mov 0x4(%eax),%edx + 800517: 8b 00 mov (%eax),%eax + 800519: eb 28 jmp 800543 + } + else if (lflag) { + 80051b: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) + 80051f: 74 12 je 800533 + return va_arg(*ap, long); + 800521: 8b 45 08 mov 0x8(%ebp),%eax + 800524: 8b 00 mov (%eax),%eax + 800526: 8d 48 04 lea 0x4(%eax),%ecx + 800529: 8b 55 08 mov 0x8(%ebp),%edx + 80052c: 89 0a mov %ecx,(%edx) + 80052e: 8b 00 mov (%eax),%eax + 800530: 99 cltd + 800531: eb 10 jmp 800543 + } + else { + return va_arg(*ap, int); + 800533: 8b 45 08 mov 0x8(%ebp),%eax + 800536: 8b 00 mov (%eax),%eax + 800538: 8d 48 04 lea 0x4(%eax),%ecx + 80053b: 8b 55 08 mov 0x8(%ebp),%edx + 80053e: 89 0a mov %ecx,(%edx) + 800540: 8b 00 mov (%eax),%eax + 800542: 99 cltd + } +} + 800543: 5d pop %ebp + 800544: c3 ret + +00800545 : + * @putch: specified putch function, print a single character + * @putdat: used by @putch function + * @fmt: the format string to use + * */ +void +printfmt(void (*putch)(int, void*), void *putdat, const char *fmt, ...) { + 800545: 55 push %ebp + 800546: 89 e5 mov %esp,%ebp + 800548: 83 ec 28 sub $0x28,%esp + va_list ap; + + va_start(ap, fmt); + 80054b: 8d 45 14 lea 0x14(%ebp),%eax + 80054e: 89 45 f4 mov %eax,-0xc(%ebp) + vprintfmt(putch, putdat, fmt, ap); + 800551: 8b 45 f4 mov -0xc(%ebp),%eax + 800554: 89 44 24 0c mov %eax,0xc(%esp) + 800558: 8b 45 10 mov 0x10(%ebp),%eax + 80055b: 89 44 24 08 mov %eax,0x8(%esp) + 80055f: 8b 45 0c mov 0xc(%ebp),%eax + 800562: 89 44 24 04 mov %eax,0x4(%esp) + 800566: 8b 45 08 mov 0x8(%ebp),%eax + 800569: 89 04 24 mov %eax,(%esp) + 80056c: e8 05 00 00 00 call 800576 + va_end(ap); +} + 800571: 90 nop + 800572: 89 ec mov %ebp,%esp + 800574: 5d pop %ebp + 800575: c3 ret + +00800576 : + * + * Call this function if you are already dealing with a va_list. + * Or you probably want printfmt() instead. + * */ +void +vprintfmt(void (*putch)(int, void*), void *putdat, const char *fmt, va_list ap) { + 800576: 55 push %ebp + 800577: 89 e5 mov %esp,%ebp + 800579: 56 push %esi + 80057a: 53 push %ebx + 80057b: 83 ec 40 sub $0x40,%esp + register int ch, err; + unsigned long long num; + int base, width, precision, lflag, altflag; + + while (1) { + while ((ch = *(unsigned char *)fmt ++) != '%') { + 80057e: eb 17 jmp 800597 + if (ch == '\0') { + 800580: 85 db test %ebx,%ebx + 800582: 0f 84 bf 03 00 00 je 800947 + return; + } + putch(ch, putdat); + 800588: 8b 45 0c mov 0xc(%ebp),%eax + 80058b: 89 44 24 04 mov %eax,0x4(%esp) + 80058f: 89 1c 24 mov %ebx,(%esp) + 800592: 8b 45 08 mov 0x8(%ebp),%eax + 800595: ff d0 call *%eax + while ((ch = *(unsigned char *)fmt ++) != '%') { + 800597: 8b 45 10 mov 0x10(%ebp),%eax + 80059a: 8d 50 01 lea 0x1(%eax),%edx + 80059d: 89 55 10 mov %edx,0x10(%ebp) + 8005a0: 0f b6 00 movzbl (%eax),%eax + 8005a3: 0f b6 d8 movzbl %al,%ebx + 8005a6: 83 fb 25 cmp $0x25,%ebx + 8005a9: 75 d5 jne 800580 + } + + // Process a %-escape sequence + char padc = ' '; + 8005ab: c6 45 db 20 movb $0x20,-0x25(%ebp) + width = precision = -1; + 8005af: c7 45 e4 ff ff ff ff movl $0xffffffff,-0x1c(%ebp) + 8005b6: 8b 45 e4 mov -0x1c(%ebp),%eax + 8005b9: 89 45 e8 mov %eax,-0x18(%ebp) + lflag = altflag = 0; + 8005bc: c7 45 dc 00 00 00 00 movl $0x0,-0x24(%ebp) + 8005c3: 8b 45 dc mov -0x24(%ebp),%eax + 8005c6: 89 45 e0 mov %eax,-0x20(%ebp) + + reswitch: + switch (ch = *(unsigned char *)fmt ++) { + 8005c9: 8b 45 10 mov 0x10(%ebp),%eax + 8005cc: 8d 50 01 lea 0x1(%eax),%edx + 8005cf: 89 55 10 mov %edx,0x10(%ebp) + 8005d2: 0f b6 00 movzbl (%eax),%eax + 8005d5: 0f b6 d8 movzbl %al,%ebx + 8005d8: 8d 43 dd lea -0x23(%ebx),%eax + 8005db: 83 f8 55 cmp $0x55,%eax + 8005de: 0f 87 37 03 00 00 ja 80091b + 8005e4: 8b 04 85 88 11 80 00 mov 0x801188(,%eax,4),%eax + 8005eb: ff e0 jmp *%eax + + // flag to pad on the right + case '-': + padc = '-'; + 8005ed: c6 45 db 2d movb $0x2d,-0x25(%ebp) + goto reswitch; + 8005f1: eb d6 jmp 8005c9 + + // flag to pad with 0's instead of spaces + case '0': + padc = '0'; + 8005f3: c6 45 db 30 movb $0x30,-0x25(%ebp) + goto reswitch; + 8005f7: eb d0 jmp 8005c9 + + // width field + case '1' ... '9': + for (precision = 0; ; ++ fmt) { + 8005f9: c7 45 e4 00 00 00 00 movl $0x0,-0x1c(%ebp) + precision = precision * 10 + ch - '0'; + 800600: 8b 55 e4 mov -0x1c(%ebp),%edx + 800603: 89 d0 mov %edx,%eax + 800605: c1 e0 02 shl $0x2,%eax + 800608: 01 d0 add %edx,%eax + 80060a: 01 c0 add %eax,%eax + 80060c: 01 d8 add %ebx,%eax + 80060e: 83 e8 30 sub $0x30,%eax + 800611: 89 45 e4 mov %eax,-0x1c(%ebp) + ch = *fmt; + 800614: 8b 45 10 mov 0x10(%ebp),%eax + 800617: 0f b6 00 movzbl (%eax),%eax + 80061a: 0f be d8 movsbl %al,%ebx + if (ch < '0' || ch > '9') { + 80061d: 83 fb 2f cmp $0x2f,%ebx + 800620: 7e 38 jle 80065a + 800622: 83 fb 39 cmp $0x39,%ebx + 800625: 7f 33 jg 80065a + for (precision = 0; ; ++ fmt) { + 800627: ff 45 10 incl 0x10(%ebp) + precision = precision * 10 + ch - '0'; + 80062a: eb d4 jmp 800600 + } + } + goto process_precision; + + case '*': + precision = va_arg(ap, int); + 80062c: 8b 45 14 mov 0x14(%ebp),%eax + 80062f: 8d 50 04 lea 0x4(%eax),%edx + 800632: 89 55 14 mov %edx,0x14(%ebp) + 800635: 8b 00 mov (%eax),%eax + 800637: 89 45 e4 mov %eax,-0x1c(%ebp) + goto process_precision; + 80063a: eb 1f jmp 80065b + + case '.': + if (width < 0) + 80063c: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 800640: 79 87 jns 8005c9 + width = 0; + 800642: c7 45 e8 00 00 00 00 movl $0x0,-0x18(%ebp) + goto reswitch; + 800649: e9 7b ff ff ff jmp 8005c9 + + case '#': + altflag = 1; + 80064e: c7 45 dc 01 00 00 00 movl $0x1,-0x24(%ebp) + goto reswitch; + 800655: e9 6f ff ff ff jmp 8005c9 + goto process_precision; + 80065a: 90 nop + + process_precision: + if (width < 0) + 80065b: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 80065f: 0f 89 64 ff ff ff jns 8005c9 + width = precision, precision = -1; + 800665: 8b 45 e4 mov -0x1c(%ebp),%eax + 800668: 89 45 e8 mov %eax,-0x18(%ebp) + 80066b: c7 45 e4 ff ff ff ff movl $0xffffffff,-0x1c(%ebp) + goto reswitch; + 800672: e9 52 ff ff ff jmp 8005c9 + + // long flag (doubled for long long) + case 'l': + lflag ++; + 800677: ff 45 e0 incl -0x20(%ebp) + goto reswitch; + 80067a: e9 4a ff ff ff jmp 8005c9 + + // character + case 'c': + putch(va_arg(ap, int), putdat); + 80067f: 8b 45 14 mov 0x14(%ebp),%eax + 800682: 8d 50 04 lea 0x4(%eax),%edx + 800685: 89 55 14 mov %edx,0x14(%ebp) + 800688: 8b 00 mov (%eax),%eax + 80068a: 8b 55 0c mov 0xc(%ebp),%edx + 80068d: 89 54 24 04 mov %edx,0x4(%esp) + 800691: 89 04 24 mov %eax,(%esp) + 800694: 8b 45 08 mov 0x8(%ebp),%eax + 800697: ff d0 call *%eax + break; + 800699: e9 a4 02 00 00 jmp 800942 + + // error message + case 'e': + err = va_arg(ap, int); + 80069e: 8b 45 14 mov 0x14(%ebp),%eax + 8006a1: 8d 50 04 lea 0x4(%eax),%edx + 8006a4: 89 55 14 mov %edx,0x14(%ebp) + 8006a7: 8b 18 mov (%eax),%ebx + if (err < 0) { + 8006a9: 85 db test %ebx,%ebx + 8006ab: 79 02 jns 8006af + err = -err; + 8006ad: f7 db neg %ebx + } + if (err > MAXERROR || (p = error_string[err]) == NULL) { + 8006af: 83 fb 18 cmp $0x18,%ebx + 8006b2: 7f 0b jg 8006bf + 8006b4: 8b 34 9d 00 11 80 00 mov 0x801100(,%ebx,4),%esi + 8006bb: 85 f6 test %esi,%esi + 8006bd: 75 23 jne 8006e2 + printfmt(putch, putdat, "error %d", err); + 8006bf: 89 5c 24 0c mov %ebx,0xc(%esp) + 8006c3: c7 44 24 08 75 11 80 movl $0x801175,0x8(%esp) + 8006ca: 00 + 8006cb: 8b 45 0c mov 0xc(%ebp),%eax + 8006ce: 89 44 24 04 mov %eax,0x4(%esp) + 8006d2: 8b 45 08 mov 0x8(%ebp),%eax + 8006d5: 89 04 24 mov %eax,(%esp) + 8006d8: e8 68 fe ff ff call 800545 + } + else { + printfmt(putch, putdat, "%s", p); + } + break; + 8006dd: e9 60 02 00 00 jmp 800942 + printfmt(putch, putdat, "%s", p); + 8006e2: 89 74 24 0c mov %esi,0xc(%esp) + 8006e6: c7 44 24 08 7e 11 80 movl $0x80117e,0x8(%esp) + 8006ed: 00 + 8006ee: 8b 45 0c mov 0xc(%ebp),%eax + 8006f1: 89 44 24 04 mov %eax,0x4(%esp) + 8006f5: 8b 45 08 mov 0x8(%ebp),%eax + 8006f8: 89 04 24 mov %eax,(%esp) + 8006fb: e8 45 fe ff ff call 800545 + break; + 800700: e9 3d 02 00 00 jmp 800942 + + // string + case 's': + if ((p = va_arg(ap, char *)) == NULL) { + 800705: 8b 45 14 mov 0x14(%ebp),%eax + 800708: 8d 50 04 lea 0x4(%eax),%edx + 80070b: 89 55 14 mov %edx,0x14(%ebp) + 80070e: 8b 30 mov (%eax),%esi + 800710: 85 f6 test %esi,%esi + 800712: 75 05 jne 800719 + p = "(null)"; + 800714: be 81 11 80 00 mov $0x801181,%esi + } + if (width > 0 && padc != '-') { + 800719: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 80071d: 7e 76 jle 800795 + 80071f: 80 7d db 2d cmpb $0x2d,-0x25(%ebp) + 800723: 74 70 je 800795 + for (width -= strnlen(p, precision); width > 0; width --) { + 800725: 8b 45 e4 mov -0x1c(%ebp),%eax + 800728: 89 44 24 04 mov %eax,0x4(%esp) + 80072c: 89 34 24 mov %esi,(%esp) + 80072f: e8 ee 03 00 00 call 800b22 + 800734: 89 c2 mov %eax,%edx + 800736: 8b 45 e8 mov -0x18(%ebp),%eax + 800739: 29 d0 sub %edx,%eax + 80073b: 89 45 e8 mov %eax,-0x18(%ebp) + 80073e: eb 16 jmp 800756 + putch(padc, putdat); + 800740: 0f be 45 db movsbl -0x25(%ebp),%eax + 800744: 8b 55 0c mov 0xc(%ebp),%edx + 800747: 89 54 24 04 mov %edx,0x4(%esp) + 80074b: 89 04 24 mov %eax,(%esp) + 80074e: 8b 45 08 mov 0x8(%ebp),%eax + 800751: ff d0 call *%eax + for (width -= strnlen(p, precision); width > 0; width --) { + 800753: ff 4d e8 decl -0x18(%ebp) + 800756: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 80075a: 7f e4 jg 800740 + } + } + for (; (ch = *p ++) != '\0' && (precision < 0 || -- precision >= 0); width --) { + 80075c: eb 37 jmp 800795 + if (altflag && (ch < ' ' || ch > '~')) { + 80075e: 83 7d dc 00 cmpl $0x0,-0x24(%ebp) + 800762: 74 1f je 800783 + 800764: 83 fb 1f cmp $0x1f,%ebx + 800767: 7e 05 jle 80076e + 800769: 83 fb 7e cmp $0x7e,%ebx + 80076c: 7e 15 jle 800783 + putch('?', putdat); + 80076e: 8b 45 0c mov 0xc(%ebp),%eax + 800771: 89 44 24 04 mov %eax,0x4(%esp) + 800775: c7 04 24 3f 00 00 00 movl $0x3f,(%esp) + 80077c: 8b 45 08 mov 0x8(%ebp),%eax + 80077f: ff d0 call *%eax + 800781: eb 0f jmp 800792 + } + else { + putch(ch, putdat); + 800783: 8b 45 0c mov 0xc(%ebp),%eax + 800786: 89 44 24 04 mov %eax,0x4(%esp) + 80078a: 89 1c 24 mov %ebx,(%esp) + 80078d: 8b 45 08 mov 0x8(%ebp),%eax + 800790: ff d0 call *%eax + for (; (ch = *p ++) != '\0' && (precision < 0 || -- precision >= 0); width --) { + 800792: ff 4d e8 decl -0x18(%ebp) + 800795: 89 f0 mov %esi,%eax + 800797: 8d 70 01 lea 0x1(%eax),%esi + 80079a: 0f b6 00 movzbl (%eax),%eax + 80079d: 0f be d8 movsbl %al,%ebx + 8007a0: 85 db test %ebx,%ebx + 8007a2: 74 27 je 8007cb + 8007a4: 83 7d e4 00 cmpl $0x0,-0x1c(%ebp) + 8007a8: 78 b4 js 80075e + 8007aa: ff 4d e4 decl -0x1c(%ebp) + 8007ad: 83 7d e4 00 cmpl $0x0,-0x1c(%ebp) + 8007b1: 79 ab jns 80075e + } + } + for (; width > 0; width --) { + 8007b3: eb 16 jmp 8007cb + putch(' ', putdat); + 8007b5: 8b 45 0c mov 0xc(%ebp),%eax + 8007b8: 89 44 24 04 mov %eax,0x4(%esp) + 8007bc: c7 04 24 20 00 00 00 movl $0x20,(%esp) + 8007c3: 8b 45 08 mov 0x8(%ebp),%eax + 8007c6: ff d0 call *%eax + for (; width > 0; width --) { + 8007c8: ff 4d e8 decl -0x18(%ebp) + 8007cb: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 8007cf: 7f e4 jg 8007b5 + } + break; + 8007d1: e9 6c 01 00 00 jmp 800942 + + // (signed) decimal + case 'd': + num = getint(&ap, lflag); + 8007d6: 8b 45 e0 mov -0x20(%ebp),%eax + 8007d9: 89 44 24 04 mov %eax,0x4(%esp) + 8007dd: 8d 45 14 lea 0x14(%ebp),%eax + 8007e0: 89 04 24 mov %eax,(%esp) + 8007e3: e8 16 fd ff ff call 8004fe + 8007e8: 89 45 f0 mov %eax,-0x10(%ebp) + 8007eb: 89 55 f4 mov %edx,-0xc(%ebp) + if ((long long)num < 0) { + 8007ee: 8b 45 f0 mov -0x10(%ebp),%eax + 8007f1: 8b 55 f4 mov -0xc(%ebp),%edx + 8007f4: 85 d2 test %edx,%edx + 8007f6: 79 26 jns 80081e + putch('-', putdat); + 8007f8: 8b 45 0c mov 0xc(%ebp),%eax + 8007fb: 89 44 24 04 mov %eax,0x4(%esp) + 8007ff: c7 04 24 2d 00 00 00 movl $0x2d,(%esp) + 800806: 8b 45 08 mov 0x8(%ebp),%eax + 800809: ff d0 call *%eax + num = -(long long)num; + 80080b: 8b 45 f0 mov -0x10(%ebp),%eax + 80080e: 8b 55 f4 mov -0xc(%ebp),%edx + 800811: f7 d8 neg %eax + 800813: 83 d2 00 adc $0x0,%edx + 800816: f7 da neg %edx + 800818: 89 45 f0 mov %eax,-0x10(%ebp) + 80081b: 89 55 f4 mov %edx,-0xc(%ebp) + } + base = 10; + 80081e: c7 45 ec 0a 00 00 00 movl $0xa,-0x14(%ebp) + goto number; + 800825: e9 a8 00 00 00 jmp 8008d2 + + // unsigned decimal + case 'u': + num = getuint(&ap, lflag); + 80082a: 8b 45 e0 mov -0x20(%ebp),%eax + 80082d: 89 44 24 04 mov %eax,0x4(%esp) + 800831: 8d 45 14 lea 0x14(%ebp),%eax + 800834: 89 04 24 mov %eax,(%esp) + 800837: e8 73 fc ff ff call 8004af + 80083c: 89 45 f0 mov %eax,-0x10(%ebp) + 80083f: 89 55 f4 mov %edx,-0xc(%ebp) + base = 10; + 800842: c7 45 ec 0a 00 00 00 movl $0xa,-0x14(%ebp) + goto number; + 800849: e9 84 00 00 00 jmp 8008d2 + + // (unsigned) octal + case 'o': + num = getuint(&ap, lflag); + 80084e: 8b 45 e0 mov -0x20(%ebp),%eax + 800851: 89 44 24 04 mov %eax,0x4(%esp) + 800855: 8d 45 14 lea 0x14(%ebp),%eax + 800858: 89 04 24 mov %eax,(%esp) + 80085b: e8 4f fc ff ff call 8004af + 800860: 89 45 f0 mov %eax,-0x10(%ebp) + 800863: 89 55 f4 mov %edx,-0xc(%ebp) + base = 8; + 800866: c7 45 ec 08 00 00 00 movl $0x8,-0x14(%ebp) + goto number; + 80086d: eb 63 jmp 8008d2 + + // pointer + case 'p': + putch('0', putdat); + 80086f: 8b 45 0c mov 0xc(%ebp),%eax + 800872: 89 44 24 04 mov %eax,0x4(%esp) + 800876: c7 04 24 30 00 00 00 movl $0x30,(%esp) + 80087d: 8b 45 08 mov 0x8(%ebp),%eax + 800880: ff d0 call *%eax + putch('x', putdat); + 800882: 8b 45 0c mov 0xc(%ebp),%eax + 800885: 89 44 24 04 mov %eax,0x4(%esp) + 800889: c7 04 24 78 00 00 00 movl $0x78,(%esp) + 800890: 8b 45 08 mov 0x8(%ebp),%eax + 800893: ff d0 call *%eax + num = (unsigned long long)(uintptr_t)va_arg(ap, void *); + 800895: 8b 45 14 mov 0x14(%ebp),%eax + 800898: 8d 50 04 lea 0x4(%eax),%edx + 80089b: 89 55 14 mov %edx,0x14(%ebp) + 80089e: 8b 00 mov (%eax),%eax + 8008a0: 89 45 f0 mov %eax,-0x10(%ebp) + 8008a3: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + base = 16; + 8008aa: c7 45 ec 10 00 00 00 movl $0x10,-0x14(%ebp) + goto number; + 8008b1: eb 1f jmp 8008d2 + + // (unsigned) hexadecimal + case 'x': + num = getuint(&ap, lflag); + 8008b3: 8b 45 e0 mov -0x20(%ebp),%eax + 8008b6: 89 44 24 04 mov %eax,0x4(%esp) + 8008ba: 8d 45 14 lea 0x14(%ebp),%eax + 8008bd: 89 04 24 mov %eax,(%esp) + 8008c0: e8 ea fb ff ff call 8004af + 8008c5: 89 45 f0 mov %eax,-0x10(%ebp) + 8008c8: 89 55 f4 mov %edx,-0xc(%ebp) + base = 16; + 8008cb: c7 45 ec 10 00 00 00 movl $0x10,-0x14(%ebp) + number: + printnum(putch, putdat, num, base, width, padc); + 8008d2: 0f be 55 db movsbl -0x25(%ebp),%edx + 8008d6: 8b 45 ec mov -0x14(%ebp),%eax + 8008d9: 89 54 24 18 mov %edx,0x18(%esp) + 8008dd: 8b 55 e8 mov -0x18(%ebp),%edx + 8008e0: 89 54 24 14 mov %edx,0x14(%esp) + 8008e4: 89 44 24 10 mov %eax,0x10(%esp) + 8008e8: 8b 45 f0 mov -0x10(%ebp),%eax + 8008eb: 8b 55 f4 mov -0xc(%ebp),%edx + 8008ee: 89 44 24 08 mov %eax,0x8(%esp) + 8008f2: 89 54 24 0c mov %edx,0xc(%esp) + 8008f6: 8b 45 0c mov 0xc(%ebp),%eax + 8008f9: 89 44 24 04 mov %eax,0x4(%esp) + 8008fd: 8b 45 08 mov 0x8(%ebp),%eax + 800900: 89 04 24 mov %eax,(%esp) + 800903: e8 a5 fa ff ff call 8003ad + break; + 800908: eb 38 jmp 800942 + + // escaped '%' character + case '%': + putch(ch, putdat); + 80090a: 8b 45 0c mov 0xc(%ebp),%eax + 80090d: 89 44 24 04 mov %eax,0x4(%esp) + 800911: 89 1c 24 mov %ebx,(%esp) + 800914: 8b 45 08 mov 0x8(%ebp),%eax + 800917: ff d0 call *%eax + break; + 800919: eb 27 jmp 800942 + + // unrecognized escape sequence - just print it literally + default: + putch('%', putdat); + 80091b: 8b 45 0c mov 0xc(%ebp),%eax + 80091e: 89 44 24 04 mov %eax,0x4(%esp) + 800922: c7 04 24 25 00 00 00 movl $0x25,(%esp) + 800929: 8b 45 08 mov 0x8(%ebp),%eax + 80092c: ff d0 call *%eax + for (fmt --; fmt[-1] != '%'; fmt --) + 80092e: ff 4d 10 decl 0x10(%ebp) + 800931: eb 03 jmp 800936 + 800933: ff 4d 10 decl 0x10(%ebp) + 800936: 8b 45 10 mov 0x10(%ebp),%eax + 800939: 48 dec %eax + 80093a: 0f b6 00 movzbl (%eax),%eax + 80093d: 3c 25 cmp $0x25,%al + 80093f: 75 f2 jne 800933 + /* do nothing */; + break; + 800941: 90 nop + while (1) { + 800942: e9 37 fc ff ff jmp 80057e + return; + 800947: 90 nop + } + } +} + 800948: 83 c4 40 add $0x40,%esp + 80094b: 5b pop %ebx + 80094c: 5e pop %esi + 80094d: 5d pop %ebp + 80094e: c3 ret + +0080094f : + * sprintputch - 'print' a single character in a buffer + * @ch: the character will be printed + * @b: the buffer to place the character @ch + * */ +static void +sprintputch(int ch, struct sprintbuf *b) { + 80094f: 55 push %ebp + 800950: 89 e5 mov %esp,%ebp + b->cnt ++; + 800952: 8b 45 0c mov 0xc(%ebp),%eax + 800955: 8b 40 08 mov 0x8(%eax),%eax + 800958: 8d 50 01 lea 0x1(%eax),%edx + 80095b: 8b 45 0c mov 0xc(%ebp),%eax + 80095e: 89 50 08 mov %edx,0x8(%eax) + if (b->buf < b->ebuf) { + 800961: 8b 45 0c mov 0xc(%ebp),%eax + 800964: 8b 10 mov (%eax),%edx + 800966: 8b 45 0c mov 0xc(%ebp),%eax + 800969: 8b 40 04 mov 0x4(%eax),%eax + 80096c: 39 c2 cmp %eax,%edx + 80096e: 73 12 jae 800982 + *b->buf ++ = ch; + 800970: 8b 45 0c mov 0xc(%ebp),%eax + 800973: 8b 00 mov (%eax),%eax + 800975: 8d 48 01 lea 0x1(%eax),%ecx + 800978: 8b 55 0c mov 0xc(%ebp),%edx + 80097b: 89 0a mov %ecx,(%edx) + 80097d: 8b 55 08 mov 0x8(%ebp),%edx + 800980: 88 10 mov %dl,(%eax) + } +} + 800982: 90 nop + 800983: 5d pop %ebp + 800984: c3 ret + +00800985 : + * @str: the buffer to place the result into + * @size: the size of buffer, including the trailing null space + * @fmt: the format string to use + * */ +int +snprintf(char *str, size_t size, const char *fmt, ...) { + 800985: 55 push %ebp + 800986: 89 e5 mov %esp,%ebp + 800988: 83 ec 28 sub $0x28,%esp + va_list ap; + int cnt; + va_start(ap, fmt); + 80098b: 8d 45 14 lea 0x14(%ebp),%eax + 80098e: 89 45 f0 mov %eax,-0x10(%ebp) + cnt = vsnprintf(str, size, fmt, ap); + 800991: 8b 45 f0 mov -0x10(%ebp),%eax + 800994: 89 44 24 0c mov %eax,0xc(%esp) + 800998: 8b 45 10 mov 0x10(%ebp),%eax + 80099b: 89 44 24 08 mov %eax,0x8(%esp) + 80099f: 8b 45 0c mov 0xc(%ebp),%eax + 8009a2: 89 44 24 04 mov %eax,0x4(%esp) + 8009a6: 8b 45 08 mov 0x8(%ebp),%eax + 8009a9: 89 04 24 mov %eax,(%esp) + 8009ac: e8 0a 00 00 00 call 8009bb + 8009b1: 89 45 f4 mov %eax,-0xc(%ebp) + va_end(ap); + return cnt; + 8009b4: 8b 45 f4 mov -0xc(%ebp),%eax +} + 8009b7: 89 ec mov %ebp,%esp + 8009b9: 5d pop %ebp + 8009ba: c3 ret + +008009bb : + * + * Call this function if you are already dealing with a va_list. + * Or you probably want snprintf() instead. + * */ +int +vsnprintf(char *str, size_t size, const char *fmt, va_list ap) { + 8009bb: 55 push %ebp + 8009bc: 89 e5 mov %esp,%ebp + 8009be: 83 ec 28 sub $0x28,%esp + struct sprintbuf b = {str, str + size - 1, 0}; + 8009c1: 8b 45 08 mov 0x8(%ebp),%eax + 8009c4: 89 45 ec mov %eax,-0x14(%ebp) + 8009c7: 8b 45 0c mov 0xc(%ebp),%eax + 8009ca: 8d 50 ff lea -0x1(%eax),%edx + 8009cd: 8b 45 08 mov 0x8(%ebp),%eax + 8009d0: 01 d0 add %edx,%eax + 8009d2: 89 45 f0 mov %eax,-0x10(%ebp) + 8009d5: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + if (str == NULL || b.buf > b.ebuf) { + 8009dc: 83 7d 08 00 cmpl $0x0,0x8(%ebp) + 8009e0: 74 0a je 8009ec + 8009e2: 8b 55 ec mov -0x14(%ebp),%edx + 8009e5: 8b 45 f0 mov -0x10(%ebp),%eax + 8009e8: 39 c2 cmp %eax,%edx + 8009ea: 76 07 jbe 8009f3 + return -E_INVAL; + 8009ec: b8 fd ff ff ff mov $0xfffffffd,%eax + 8009f1: eb 2a jmp 800a1d + } + // print the string to the buffer + vprintfmt((void*)sprintputch, &b, fmt, ap); + 8009f3: 8b 45 14 mov 0x14(%ebp),%eax + 8009f6: 89 44 24 0c mov %eax,0xc(%esp) + 8009fa: 8b 45 10 mov 0x10(%ebp),%eax + 8009fd: 89 44 24 08 mov %eax,0x8(%esp) + 800a01: 8d 45 ec lea -0x14(%ebp),%eax + 800a04: 89 44 24 04 mov %eax,0x4(%esp) + 800a08: c7 04 24 4f 09 80 00 movl $0x80094f,(%esp) + 800a0f: e8 62 fb ff ff call 800576 + // null terminate the buffer + *b.buf = '\0'; + 800a14: 8b 45 ec mov -0x14(%ebp),%eax + 800a17: c6 00 00 movb $0x0,(%eax) + return b.cnt; + 800a1a: 8b 45 f4 mov -0xc(%ebp),%eax +} + 800a1d: 89 ec mov %ebp,%esp + 800a1f: 5d pop %ebp + 800a20: c3 ret + +00800a21 : + * rand - returns a pseudo-random integer + * + * The rand() function return a value in the range [0, RAND_MAX]. + * */ +int +rand(void) { + 800a21: 55 push %ebp + 800a22: 89 e5 mov %esp,%ebp + 800a24: 57 push %edi + 800a25: 56 push %esi + 800a26: 53 push %ebx + 800a27: 83 ec 24 sub $0x24,%esp + next = (next * 0x5DEECE66DLL + 0xBLL) & ((1LL << 48) - 1); + 800a2a: a1 00 20 80 00 mov 0x802000,%eax + 800a2f: 8b 15 04 20 80 00 mov 0x802004,%edx + 800a35: 69 fa 6d e6 ec de imul $0xdeece66d,%edx,%edi + 800a3b: 6b f0 05 imul $0x5,%eax,%esi + 800a3e: 01 fe add %edi,%esi + 800a40: bf 6d e6 ec de mov $0xdeece66d,%edi + 800a45: f7 e7 mul %edi + 800a47: 01 d6 add %edx,%esi + 800a49: 89 f2 mov %esi,%edx + 800a4b: 83 c0 0b add $0xb,%eax + 800a4e: 83 d2 00 adc $0x0,%edx + 800a51: 89 c7 mov %eax,%edi + 800a53: 83 e7 ff and $0xffffffff,%edi + 800a56: 89 f9 mov %edi,%ecx + 800a58: 0f b7 da movzwl %dx,%ebx + 800a5b: 89 0d 00 20 80 00 mov %ecx,0x802000 + 800a61: 89 1d 04 20 80 00 mov %ebx,0x802004 + unsigned long long result = (next >> 12); + 800a67: a1 00 20 80 00 mov 0x802000,%eax + 800a6c: 8b 15 04 20 80 00 mov 0x802004,%edx + 800a72: 0f ac d0 0c shrd $0xc,%edx,%eax + 800a76: c1 ea 0c shr $0xc,%edx + 800a79: 89 45 e0 mov %eax,-0x20(%ebp) + 800a7c: 89 55 e4 mov %edx,-0x1c(%ebp) + return (int)do_div(result, RAND_MAX + 1); + 800a7f: c7 45 dc 00 00 00 80 movl $0x80000000,-0x24(%ebp) + 800a86: 8b 45 e0 mov -0x20(%ebp),%eax + 800a89: 8b 55 e4 mov -0x1c(%ebp),%edx + 800a8c: 89 45 d8 mov %eax,-0x28(%ebp) + 800a8f: 89 55 e8 mov %edx,-0x18(%ebp) + 800a92: 8b 45 e8 mov -0x18(%ebp),%eax + 800a95: 89 45 ec mov %eax,-0x14(%ebp) + 800a98: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 800a9c: 74 1c je 800aba + 800a9e: 8b 45 e8 mov -0x18(%ebp),%eax + 800aa1: ba 00 00 00 00 mov $0x0,%edx + 800aa6: f7 75 dc divl -0x24(%ebp) + 800aa9: 89 55 ec mov %edx,-0x14(%ebp) + 800aac: 8b 45 e8 mov -0x18(%ebp),%eax + 800aaf: ba 00 00 00 00 mov $0x0,%edx + 800ab4: f7 75 dc divl -0x24(%ebp) + 800ab7: 89 45 e8 mov %eax,-0x18(%ebp) + 800aba: 8b 45 d8 mov -0x28(%ebp),%eax + 800abd: 8b 55 ec mov -0x14(%ebp),%edx + 800ac0: f7 75 dc divl -0x24(%ebp) + 800ac3: 89 45 d8 mov %eax,-0x28(%ebp) + 800ac6: 89 55 d4 mov %edx,-0x2c(%ebp) + 800ac9: 8b 45 d8 mov -0x28(%ebp),%eax + 800acc: 8b 55 e8 mov -0x18(%ebp),%edx + 800acf: 89 45 e0 mov %eax,-0x20(%ebp) + 800ad2: 89 55 e4 mov %edx,-0x1c(%ebp) + 800ad5: 8b 45 d4 mov -0x2c(%ebp),%eax +} + 800ad8: 83 c4 24 add $0x24,%esp + 800adb: 5b pop %ebx + 800adc: 5e pop %esi + 800add: 5f pop %edi + 800ade: 5d pop %ebp + 800adf: c3 ret + +00800ae0 : +/* * + * srand - seed the random number generator with the given number + * @seed: the required seed number + * */ +void +srand(unsigned int seed) { + 800ae0: 55 push %ebp + 800ae1: 89 e5 mov %esp,%ebp + next = seed; + 800ae3: 8b 45 08 mov 0x8(%ebp),%eax + 800ae6: ba 00 00 00 00 mov $0x0,%edx + 800aeb: a3 00 20 80 00 mov %eax,0x802000 + 800af0: 89 15 04 20 80 00 mov %edx,0x802004 +} + 800af6: 90 nop + 800af7: 5d pop %ebp + 800af8: c3 ret + +00800af9 : + * @s: the input string + * + * The strlen() function returns the length of string @s. + * */ +size_t +strlen(const char *s) { + 800af9: 55 push %ebp + 800afa: 89 e5 mov %esp,%ebp + 800afc: 83 ec 10 sub $0x10,%esp + size_t cnt = 0; + 800aff: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + while (*s ++ != '\0') { + 800b06: eb 03 jmp 800b0b + cnt ++; + 800b08: ff 45 fc incl -0x4(%ebp) + while (*s ++ != '\0') { + 800b0b: 8b 45 08 mov 0x8(%ebp),%eax + 800b0e: 8d 50 01 lea 0x1(%eax),%edx + 800b11: 89 55 08 mov %edx,0x8(%ebp) + 800b14: 0f b6 00 movzbl (%eax),%eax + 800b17: 84 c0 test %al,%al + 800b19: 75 ed jne 800b08 + } + return cnt; + 800b1b: 8b 45 fc mov -0x4(%ebp),%eax +} + 800b1e: 89 ec mov %ebp,%esp + 800b20: 5d pop %ebp + 800b21: c3 ret + +00800b22 : + * The return value is strlen(s), if that is less than @len, or + * @len if there is no '\0' character among the first @len characters + * pointed by @s. + * */ +size_t +strnlen(const char *s, size_t len) { + 800b22: 55 push %ebp + 800b23: 89 e5 mov %esp,%ebp + 800b25: 83 ec 10 sub $0x10,%esp + size_t cnt = 0; + 800b28: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + while (cnt < len && *s ++ != '\0') { + 800b2f: eb 03 jmp 800b34 + cnt ++; + 800b31: ff 45 fc incl -0x4(%ebp) + while (cnt < len && *s ++ != '\0') { + 800b34: 8b 45 fc mov -0x4(%ebp),%eax + 800b37: 3b 45 0c cmp 0xc(%ebp),%eax + 800b3a: 73 10 jae 800b4c + 800b3c: 8b 45 08 mov 0x8(%ebp),%eax + 800b3f: 8d 50 01 lea 0x1(%eax),%edx + 800b42: 89 55 08 mov %edx,0x8(%ebp) + 800b45: 0f b6 00 movzbl (%eax),%eax + 800b48: 84 c0 test %al,%al + 800b4a: 75 e5 jne 800b31 + } + return cnt; + 800b4c: 8b 45 fc mov -0x4(%ebp),%eax +} + 800b4f: 89 ec mov %ebp,%esp + 800b51: 5d pop %ebp + 800b52: c3 ret + +00800b53 : + * To avoid overflows, the size of array pointed by @dst should be long enough to + * contain the same string as @src (including the terminating null character), and + * should not overlap in memory with @src. + * */ +char * +strcpy(char *dst, const char *src) { + 800b53: 55 push %ebp + 800b54: 89 e5 mov %esp,%ebp + 800b56: 57 push %edi + 800b57: 56 push %esi + 800b58: 83 ec 20 sub $0x20,%esp + 800b5b: 8b 45 08 mov 0x8(%ebp),%eax + 800b5e: 89 45 f4 mov %eax,-0xc(%ebp) + 800b61: 8b 45 0c mov 0xc(%ebp),%eax + 800b64: 89 45 f0 mov %eax,-0x10(%ebp) +#ifndef __HAVE_ARCH_STRCPY +#define __HAVE_ARCH_STRCPY +static inline char * +__strcpy(char *dst, const char *src) { + int d0, d1, d2; + asm volatile ( + 800b67: 8b 55 f0 mov -0x10(%ebp),%edx + 800b6a: 8b 45 f4 mov -0xc(%ebp),%eax + 800b6d: 89 d1 mov %edx,%ecx + 800b6f: 89 c2 mov %eax,%edx + 800b71: 89 ce mov %ecx,%esi + 800b73: 89 d7 mov %edx,%edi + 800b75: ac lods %ds:(%esi),%al + 800b76: aa stos %al,%es:(%edi) + 800b77: 84 c0 test %al,%al + 800b79: 75 fa jne 800b75 + 800b7b: 89 fa mov %edi,%edx + 800b7d: 89 f1 mov %esi,%ecx + 800b7f: 89 4d ec mov %ecx,-0x14(%ebp) + 800b82: 89 55 e8 mov %edx,-0x18(%ebp) + 800b85: 89 45 e4 mov %eax,-0x1c(%ebp) + "stosb;" + "testb %%al, %%al;" + "jne 1b;" + : "=&S" (d0), "=&D" (d1), "=&a" (d2) + : "0" (src), "1" (dst) : "memory"); + return dst; + 800b88: 8b 45 f4 mov -0xc(%ebp),%eax + char *p = dst; + while ((*p ++ = *src ++) != '\0') + /* nothing */; + return dst; +#endif /* __HAVE_ARCH_STRCPY */ +} + 800b8b: 83 c4 20 add $0x20,%esp + 800b8e: 5e pop %esi + 800b8f: 5f pop %edi + 800b90: 5d pop %ebp + 800b91: c3 ret + +00800b92 : + * @len: maximum number of characters to be copied from @src + * + * The return value is @dst + * */ +char * +strncpy(char *dst, const char *src, size_t len) { + 800b92: 55 push %ebp + 800b93: 89 e5 mov %esp,%ebp + 800b95: 83 ec 10 sub $0x10,%esp + char *p = dst; + 800b98: 8b 45 08 mov 0x8(%ebp),%eax + 800b9b: 89 45 fc mov %eax,-0x4(%ebp) + while (len > 0) { + 800b9e: eb 1e jmp 800bbe + if ((*p = *src) != '\0') { + 800ba0: 8b 45 0c mov 0xc(%ebp),%eax + 800ba3: 0f b6 10 movzbl (%eax),%edx + 800ba6: 8b 45 fc mov -0x4(%ebp),%eax + 800ba9: 88 10 mov %dl,(%eax) + 800bab: 8b 45 fc mov -0x4(%ebp),%eax + 800bae: 0f b6 00 movzbl (%eax),%eax + 800bb1: 84 c0 test %al,%al + 800bb3: 74 03 je 800bb8 + src ++; + 800bb5: ff 45 0c incl 0xc(%ebp) + } + p ++, len --; + 800bb8: ff 45 fc incl -0x4(%ebp) + 800bbb: ff 4d 10 decl 0x10(%ebp) + while (len > 0) { + 800bbe: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800bc2: 75 dc jne 800ba0 + } + return dst; + 800bc4: 8b 45 08 mov 0x8(%ebp),%eax +} + 800bc7: 89 ec mov %ebp,%esp + 800bc9: 5d pop %ebp + 800bca: c3 ret + +00800bcb : + * - A value greater than zero indicates that the first character that does + * not match has a greater value in @s1 than in @s2; + * - And a value less than zero indicates the opposite. + * */ +int +strcmp(const char *s1, const char *s2) { + 800bcb: 55 push %ebp + 800bcc: 89 e5 mov %esp,%ebp + 800bce: 57 push %edi + 800bcf: 56 push %esi + 800bd0: 83 ec 20 sub $0x20,%esp + 800bd3: 8b 45 08 mov 0x8(%ebp),%eax + 800bd6: 89 45 f4 mov %eax,-0xc(%ebp) + 800bd9: 8b 45 0c mov 0xc(%ebp),%eax + 800bdc: 89 45 f0 mov %eax,-0x10(%ebp) + asm volatile ( + 800bdf: 8b 55 f4 mov -0xc(%ebp),%edx + 800be2: 8b 45 f0 mov -0x10(%ebp),%eax + 800be5: 89 d1 mov %edx,%ecx + 800be7: 89 c2 mov %eax,%edx + 800be9: 89 ce mov %ecx,%esi + 800beb: 89 d7 mov %edx,%edi + 800bed: ac lods %ds:(%esi),%al + 800bee: ae scas %es:(%edi),%al + 800bef: 75 08 jne 800bf9 + 800bf1: 84 c0 test %al,%al + 800bf3: 75 f8 jne 800bed + 800bf5: 31 c0 xor %eax,%eax + 800bf7: eb 04 jmp 800bfd + 800bf9: 19 c0 sbb %eax,%eax + 800bfb: 0c 01 or $0x1,%al + 800bfd: 89 fa mov %edi,%edx + 800bff: 89 f1 mov %esi,%ecx + 800c01: 89 45 ec mov %eax,-0x14(%ebp) + 800c04: 89 4d e8 mov %ecx,-0x18(%ebp) + 800c07: 89 55 e4 mov %edx,-0x1c(%ebp) + return ret; + 800c0a: 8b 45 ec mov -0x14(%ebp),%eax + while (*s1 != '\0' && *s1 == *s2) { + s1 ++, s2 ++; + } + return (int)((unsigned char)*s1 - (unsigned char)*s2); +#endif /* __HAVE_ARCH_STRCMP */ +} + 800c0d: 83 c4 20 add $0x20,%esp + 800c10: 5e pop %esi + 800c11: 5f pop %edi + 800c12: 5d pop %ebp + 800c13: c3 ret + +00800c14 : + * they are equal to each other, it continues with the following pairs until + * the characters differ, until a terminating null-character is reached, or + * until @n characters match in both strings, whichever happens first. + * */ +int +strncmp(const char *s1, const char *s2, size_t n) { + 800c14: 55 push %ebp + 800c15: 89 e5 mov %esp,%ebp + while (n > 0 && *s1 != '\0' && *s1 == *s2) { + 800c17: eb 09 jmp 800c22 + n --, s1 ++, s2 ++; + 800c19: ff 4d 10 decl 0x10(%ebp) + 800c1c: ff 45 08 incl 0x8(%ebp) + 800c1f: ff 45 0c incl 0xc(%ebp) + while (n > 0 && *s1 != '\0' && *s1 == *s2) { + 800c22: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800c26: 74 1a je 800c42 + 800c28: 8b 45 08 mov 0x8(%ebp),%eax + 800c2b: 0f b6 00 movzbl (%eax),%eax + 800c2e: 84 c0 test %al,%al + 800c30: 74 10 je 800c42 + 800c32: 8b 45 08 mov 0x8(%ebp),%eax + 800c35: 0f b6 10 movzbl (%eax),%edx + 800c38: 8b 45 0c mov 0xc(%ebp),%eax + 800c3b: 0f b6 00 movzbl (%eax),%eax + 800c3e: 38 c2 cmp %al,%dl + 800c40: 74 d7 je 800c19 + } + return (n == 0) ? 0 : (int)((unsigned char)*s1 - (unsigned char)*s2); + 800c42: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800c46: 74 18 je 800c60 + 800c48: 8b 45 08 mov 0x8(%ebp),%eax + 800c4b: 0f b6 00 movzbl (%eax),%eax + 800c4e: 0f b6 d0 movzbl %al,%edx + 800c51: 8b 45 0c mov 0xc(%ebp),%eax + 800c54: 0f b6 00 movzbl (%eax),%eax + 800c57: 0f b6 c8 movzbl %al,%ecx + 800c5a: 89 d0 mov %edx,%eax + 800c5c: 29 c8 sub %ecx,%eax + 800c5e: eb 05 jmp 800c65 + 800c60: b8 00 00 00 00 mov $0x0,%eax +} + 800c65: 5d pop %ebp + 800c66: c3 ret + +00800c67 : + * + * The strchr() function returns a pointer to the first occurrence of + * character in @s. If the value is not found, the function returns 'NULL'. + * */ +char * +strchr(const char *s, char c) { + 800c67: 55 push %ebp + 800c68: 89 e5 mov %esp,%ebp + 800c6a: 83 ec 04 sub $0x4,%esp + 800c6d: 8b 45 0c mov 0xc(%ebp),%eax + 800c70: 88 45 fc mov %al,-0x4(%ebp) + while (*s != '\0') { + 800c73: eb 13 jmp 800c88 + if (*s == c) { + 800c75: 8b 45 08 mov 0x8(%ebp),%eax + 800c78: 0f b6 00 movzbl (%eax),%eax + 800c7b: 38 45 fc cmp %al,-0x4(%ebp) + 800c7e: 75 05 jne 800c85 + return (char *)s; + 800c80: 8b 45 08 mov 0x8(%ebp),%eax + 800c83: eb 12 jmp 800c97 + } + s ++; + 800c85: ff 45 08 incl 0x8(%ebp) + while (*s != '\0') { + 800c88: 8b 45 08 mov 0x8(%ebp),%eax + 800c8b: 0f b6 00 movzbl (%eax),%eax + 800c8e: 84 c0 test %al,%al + 800c90: 75 e3 jne 800c75 + } + return NULL; + 800c92: b8 00 00 00 00 mov $0x0,%eax +} + 800c97: 89 ec mov %ebp,%esp + 800c99: 5d pop %ebp + 800c9a: c3 ret + +00800c9b : + * The strfind() function is like strchr() except that if @c is + * not found in @s, then it returns a pointer to the null byte at the + * end of @s, rather than 'NULL'. + * */ +char * +strfind(const char *s, char c) { + 800c9b: 55 push %ebp + 800c9c: 89 e5 mov %esp,%ebp + 800c9e: 83 ec 04 sub $0x4,%esp + 800ca1: 8b 45 0c mov 0xc(%ebp),%eax + 800ca4: 88 45 fc mov %al,-0x4(%ebp) + while (*s != '\0') { + 800ca7: eb 0e jmp 800cb7 + if (*s == c) { + 800ca9: 8b 45 08 mov 0x8(%ebp),%eax + 800cac: 0f b6 00 movzbl (%eax),%eax + 800caf: 38 45 fc cmp %al,-0x4(%ebp) + 800cb2: 74 0f je 800cc3 + break; + } + s ++; + 800cb4: ff 45 08 incl 0x8(%ebp) + while (*s != '\0') { + 800cb7: 8b 45 08 mov 0x8(%ebp),%eax + 800cba: 0f b6 00 movzbl (%eax),%eax + 800cbd: 84 c0 test %al,%al + 800cbf: 75 e8 jne 800ca9 + 800cc1: eb 01 jmp 800cc4 + break; + 800cc3: 90 nop + } + return (char *)s; + 800cc4: 8b 45 08 mov 0x8(%ebp),%eax +} + 800cc7: 89 ec mov %ebp,%esp + 800cc9: 5d pop %ebp + 800cca: c3 ret + +00800ccb : + * an optional "0x" or "0X" prefix. + * + * The strtol() function returns the converted integral number as a long int value. + * */ +long +strtol(const char *s, char **endptr, int base) { + 800ccb: 55 push %ebp + 800ccc: 89 e5 mov %esp,%ebp + 800cce: 83 ec 10 sub $0x10,%esp + int neg = 0; + 800cd1: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + long val = 0; + 800cd8: c7 45 f8 00 00 00 00 movl $0x0,-0x8(%ebp) + + // gobble initial whitespace + while (*s == ' ' || *s == '\t') { + 800cdf: eb 03 jmp 800ce4 + s ++; + 800ce1: ff 45 08 incl 0x8(%ebp) + while (*s == ' ' || *s == '\t') { + 800ce4: 8b 45 08 mov 0x8(%ebp),%eax + 800ce7: 0f b6 00 movzbl (%eax),%eax + 800cea: 3c 20 cmp $0x20,%al + 800cec: 74 f3 je 800ce1 + 800cee: 8b 45 08 mov 0x8(%ebp),%eax + 800cf1: 0f b6 00 movzbl (%eax),%eax + 800cf4: 3c 09 cmp $0x9,%al + 800cf6: 74 e9 je 800ce1 + } + + // plus/minus sign + if (*s == '+') { + 800cf8: 8b 45 08 mov 0x8(%ebp),%eax + 800cfb: 0f b6 00 movzbl (%eax),%eax + 800cfe: 3c 2b cmp $0x2b,%al + 800d00: 75 05 jne 800d07 + s ++; + 800d02: ff 45 08 incl 0x8(%ebp) + 800d05: eb 14 jmp 800d1b + } + else if (*s == '-') { + 800d07: 8b 45 08 mov 0x8(%ebp),%eax + 800d0a: 0f b6 00 movzbl (%eax),%eax + 800d0d: 3c 2d cmp $0x2d,%al + 800d0f: 75 0a jne 800d1b + s ++, neg = 1; + 800d11: ff 45 08 incl 0x8(%ebp) + 800d14: c7 45 fc 01 00 00 00 movl $0x1,-0x4(%ebp) + } + + // hex or octal base prefix + if ((base == 0 || base == 16) && (s[0] == '0' && s[1] == 'x')) { + 800d1b: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800d1f: 74 06 je 800d27 + 800d21: 83 7d 10 10 cmpl $0x10,0x10(%ebp) + 800d25: 75 22 jne 800d49 + 800d27: 8b 45 08 mov 0x8(%ebp),%eax + 800d2a: 0f b6 00 movzbl (%eax),%eax + 800d2d: 3c 30 cmp $0x30,%al + 800d2f: 75 18 jne 800d49 + 800d31: 8b 45 08 mov 0x8(%ebp),%eax + 800d34: 40 inc %eax + 800d35: 0f b6 00 movzbl (%eax),%eax + 800d38: 3c 78 cmp $0x78,%al + 800d3a: 75 0d jne 800d49 + s += 2, base = 16; + 800d3c: 83 45 08 02 addl $0x2,0x8(%ebp) + 800d40: c7 45 10 10 00 00 00 movl $0x10,0x10(%ebp) + 800d47: eb 29 jmp 800d72 + } + else if (base == 0 && s[0] == '0') { + 800d49: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800d4d: 75 16 jne 800d65 + 800d4f: 8b 45 08 mov 0x8(%ebp),%eax + 800d52: 0f b6 00 movzbl (%eax),%eax + 800d55: 3c 30 cmp $0x30,%al + 800d57: 75 0c jne 800d65 + s ++, base = 8; + 800d59: ff 45 08 incl 0x8(%ebp) + 800d5c: c7 45 10 08 00 00 00 movl $0x8,0x10(%ebp) + 800d63: eb 0d jmp 800d72 + } + else if (base == 0) { + 800d65: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800d69: 75 07 jne 800d72 + base = 10; + 800d6b: c7 45 10 0a 00 00 00 movl $0xa,0x10(%ebp) + + // digits + while (1) { + int dig; + + if (*s >= '0' && *s <= '9') { + 800d72: 8b 45 08 mov 0x8(%ebp),%eax + 800d75: 0f b6 00 movzbl (%eax),%eax + 800d78: 3c 2f cmp $0x2f,%al + 800d7a: 7e 1b jle 800d97 + 800d7c: 8b 45 08 mov 0x8(%ebp),%eax + 800d7f: 0f b6 00 movzbl (%eax),%eax + 800d82: 3c 39 cmp $0x39,%al + 800d84: 7f 11 jg 800d97 + dig = *s - '0'; + 800d86: 8b 45 08 mov 0x8(%ebp),%eax + 800d89: 0f b6 00 movzbl (%eax),%eax + 800d8c: 0f be c0 movsbl %al,%eax + 800d8f: 83 e8 30 sub $0x30,%eax + 800d92: 89 45 f4 mov %eax,-0xc(%ebp) + 800d95: eb 48 jmp 800ddf + } + else if (*s >= 'a' && *s <= 'z') { + 800d97: 8b 45 08 mov 0x8(%ebp),%eax + 800d9a: 0f b6 00 movzbl (%eax),%eax + 800d9d: 3c 60 cmp $0x60,%al + 800d9f: 7e 1b jle 800dbc + 800da1: 8b 45 08 mov 0x8(%ebp),%eax + 800da4: 0f b6 00 movzbl (%eax),%eax + 800da7: 3c 7a cmp $0x7a,%al + 800da9: 7f 11 jg 800dbc + dig = *s - 'a' + 10; + 800dab: 8b 45 08 mov 0x8(%ebp),%eax + 800dae: 0f b6 00 movzbl (%eax),%eax + 800db1: 0f be c0 movsbl %al,%eax + 800db4: 83 e8 57 sub $0x57,%eax + 800db7: 89 45 f4 mov %eax,-0xc(%ebp) + 800dba: eb 23 jmp 800ddf + } + else if (*s >= 'A' && *s <= 'Z') { + 800dbc: 8b 45 08 mov 0x8(%ebp),%eax + 800dbf: 0f b6 00 movzbl (%eax),%eax + 800dc2: 3c 40 cmp $0x40,%al + 800dc4: 7e 3b jle 800e01 + 800dc6: 8b 45 08 mov 0x8(%ebp),%eax + 800dc9: 0f b6 00 movzbl (%eax),%eax + 800dcc: 3c 5a cmp $0x5a,%al + 800dce: 7f 31 jg 800e01 + dig = *s - 'A' + 10; + 800dd0: 8b 45 08 mov 0x8(%ebp),%eax + 800dd3: 0f b6 00 movzbl (%eax),%eax + 800dd6: 0f be c0 movsbl %al,%eax + 800dd9: 83 e8 37 sub $0x37,%eax + 800ddc: 89 45 f4 mov %eax,-0xc(%ebp) + } + else { + break; + } + if (dig >= base) { + 800ddf: 8b 45 f4 mov -0xc(%ebp),%eax + 800de2: 3b 45 10 cmp 0x10(%ebp),%eax + 800de5: 7d 19 jge 800e00 + break; + } + s ++, val = (val * base) + dig; + 800de7: ff 45 08 incl 0x8(%ebp) + 800dea: 8b 45 f8 mov -0x8(%ebp),%eax + 800ded: 0f af 45 10 imul 0x10(%ebp),%eax + 800df1: 89 c2 mov %eax,%edx + 800df3: 8b 45 f4 mov -0xc(%ebp),%eax + 800df6: 01 d0 add %edx,%eax + 800df8: 89 45 f8 mov %eax,-0x8(%ebp) + while (1) { + 800dfb: e9 72 ff ff ff jmp 800d72 + break; + 800e00: 90 nop + // we don't properly detect overflow! + } + + if (endptr) { + 800e01: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) + 800e05: 74 08 je 800e0f + *endptr = (char *) s; + 800e07: 8b 45 0c mov 0xc(%ebp),%eax + 800e0a: 8b 55 08 mov 0x8(%ebp),%edx + 800e0d: 89 10 mov %edx,(%eax) + } + return (neg ? -val : val); + 800e0f: 83 7d fc 00 cmpl $0x0,-0x4(%ebp) + 800e13: 74 07 je 800e1c + 800e15: 8b 45 f8 mov -0x8(%ebp),%eax + 800e18: f7 d8 neg %eax + 800e1a: eb 03 jmp 800e1f + 800e1c: 8b 45 f8 mov -0x8(%ebp),%eax +} + 800e1f: 89 ec mov %ebp,%esp + 800e21: 5d pop %ebp + 800e22: c3 ret + +00800e23 : + * @n: number of bytes to be set to the value + * + * The memset() function returns @s. + * */ +void * +memset(void *s, char c, size_t n) { + 800e23: 55 push %ebp + 800e24: 89 e5 mov %esp,%ebp + 800e26: 83 ec 28 sub $0x28,%esp + 800e29: 89 7d fc mov %edi,-0x4(%ebp) + 800e2c: 8b 45 0c mov 0xc(%ebp),%eax + 800e2f: 88 45 d8 mov %al,-0x28(%ebp) +#ifdef __HAVE_ARCH_MEMSET + return __memset(s, c, n); + 800e32: 0f be 55 d8 movsbl -0x28(%ebp),%edx + 800e36: 8b 45 08 mov 0x8(%ebp),%eax + 800e39: 89 45 f8 mov %eax,-0x8(%ebp) + 800e3c: 88 55 f7 mov %dl,-0x9(%ebp) + 800e3f: 8b 45 10 mov 0x10(%ebp),%eax + 800e42: 89 45 f0 mov %eax,-0x10(%ebp) +#ifndef __HAVE_ARCH_MEMSET +#define __HAVE_ARCH_MEMSET +static inline void * +__memset(void *s, char c, size_t n) { + int d0, d1; + asm volatile ( + 800e45: 8b 4d f0 mov -0x10(%ebp),%ecx + 800e48: 0f b6 45 f7 movzbl -0x9(%ebp),%eax + 800e4c: 8b 55 f8 mov -0x8(%ebp),%edx + 800e4f: 89 d7 mov %edx,%edi + 800e51: f3 aa rep stos %al,%es:(%edi) + 800e53: 89 fa mov %edi,%edx + 800e55: 89 4d ec mov %ecx,-0x14(%ebp) + 800e58: 89 55 e8 mov %edx,-0x18(%ebp) + "rep; stosb;" + : "=&c" (d0), "=&D" (d1) + : "0" (n), "a" (c), "1" (s) + : "memory"); + return s; + 800e5b: 8b 45 f8 mov -0x8(%ebp),%eax + while (n -- > 0) { + *p ++ = c; + } + return s; +#endif /* __HAVE_ARCH_MEMSET */ +} + 800e5e: 8b 7d fc mov -0x4(%ebp),%edi + 800e61: 89 ec mov %ebp,%esp + 800e63: 5d pop %ebp + 800e64: c3 ret + +00800e65 : + * @n: number of bytes to copy + * + * The memmove() function returns @dst. + * */ +void * +memmove(void *dst, const void *src, size_t n) { + 800e65: 55 push %ebp + 800e66: 89 e5 mov %esp,%ebp + 800e68: 57 push %edi + 800e69: 56 push %esi + 800e6a: 53 push %ebx + 800e6b: 83 ec 30 sub $0x30,%esp + 800e6e: 8b 45 08 mov 0x8(%ebp),%eax + 800e71: 89 45 f0 mov %eax,-0x10(%ebp) + 800e74: 8b 45 0c mov 0xc(%ebp),%eax + 800e77: 89 45 ec mov %eax,-0x14(%ebp) + 800e7a: 8b 45 10 mov 0x10(%ebp),%eax + 800e7d: 89 45 e8 mov %eax,-0x18(%ebp) + +#ifndef __HAVE_ARCH_MEMMOVE +#define __HAVE_ARCH_MEMMOVE +static inline void * +__memmove(void *dst, const void *src, size_t n) { + if (dst < src) { + 800e80: 8b 45 f0 mov -0x10(%ebp),%eax + 800e83: 3b 45 ec cmp -0x14(%ebp),%eax + 800e86: 73 42 jae 800eca + 800e88: 8b 45 f0 mov -0x10(%ebp),%eax + 800e8b: 89 45 e4 mov %eax,-0x1c(%ebp) + 800e8e: 8b 45 ec mov -0x14(%ebp),%eax + 800e91: 89 45 e0 mov %eax,-0x20(%ebp) + 800e94: 8b 45 e8 mov -0x18(%ebp),%eax + 800e97: 89 45 dc mov %eax,-0x24(%ebp) + "andl $3, %%ecx;" + "jz 1f;" + "rep; movsb;" + "1:" + : "=&c" (d0), "=&D" (d1), "=&S" (d2) + : "0" (n / 4), "g" (n), "1" (dst), "2" (src) + 800e9a: 8b 45 dc mov -0x24(%ebp),%eax + 800e9d: c1 e8 02 shr $0x2,%eax + 800ea0: 89 c1 mov %eax,%ecx + asm volatile ( + 800ea2: 8b 55 e4 mov -0x1c(%ebp),%edx + 800ea5: 8b 45 e0 mov -0x20(%ebp),%eax + 800ea8: 89 d7 mov %edx,%edi + 800eaa: 89 c6 mov %eax,%esi + 800eac: f3 a5 rep movsl %ds:(%esi),%es:(%edi) + 800eae: 8b 4d dc mov -0x24(%ebp),%ecx + 800eb1: 83 e1 03 and $0x3,%ecx + 800eb4: 74 02 je 800eb8 + 800eb6: f3 a4 rep movsb %ds:(%esi),%es:(%edi) + 800eb8: 89 f0 mov %esi,%eax + 800eba: 89 fa mov %edi,%edx + 800ebc: 89 4d d8 mov %ecx,-0x28(%ebp) + 800ebf: 89 55 d4 mov %edx,-0x2c(%ebp) + 800ec2: 89 45 d0 mov %eax,-0x30(%ebp) + : "memory"); + return dst; + 800ec5: 8b 45 e4 mov -0x1c(%ebp),%eax + return __memcpy(dst, src, n); + 800ec8: eb 36 jmp 800f00 + : "0" (n), "1" (n - 1 + src), "2" (n - 1 + dst) + 800eca: 8b 45 e8 mov -0x18(%ebp),%eax + 800ecd: 8d 50 ff lea -0x1(%eax),%edx + 800ed0: 8b 45 ec mov -0x14(%ebp),%eax + 800ed3: 01 c2 add %eax,%edx + 800ed5: 8b 45 e8 mov -0x18(%ebp),%eax + 800ed8: 8d 48 ff lea -0x1(%eax),%ecx + 800edb: 8b 45 f0 mov -0x10(%ebp),%eax + 800ede: 8d 1c 01 lea (%ecx,%eax,1),%ebx + asm volatile ( + 800ee1: 8b 45 e8 mov -0x18(%ebp),%eax + 800ee4: 89 c1 mov %eax,%ecx + 800ee6: 89 d8 mov %ebx,%eax + 800ee8: 89 d6 mov %edx,%esi + 800eea: 89 c7 mov %eax,%edi + 800eec: fd std + 800eed: f3 a4 rep movsb %ds:(%esi),%es:(%edi) + 800eef: fc cld + 800ef0: 89 f8 mov %edi,%eax + 800ef2: 89 f2 mov %esi,%edx + 800ef4: 89 4d cc mov %ecx,-0x34(%ebp) + 800ef7: 89 55 c8 mov %edx,-0x38(%ebp) + 800efa: 89 45 c4 mov %eax,-0x3c(%ebp) + return dst; + 800efd: 8b 45 f0 mov -0x10(%ebp),%eax + *d ++ = *s ++; + } + } + return dst; +#endif /* __HAVE_ARCH_MEMMOVE */ +} + 800f00: 83 c4 30 add $0x30,%esp + 800f03: 5b pop %ebx + 800f04: 5e pop %esi + 800f05: 5f pop %edi + 800f06: 5d pop %ebp + 800f07: c3 ret + +00800f08 : + * it always copies exactly @n bytes. To avoid overflows, the size of arrays pointed + * by both @src and @dst, should be at least @n bytes, and should not overlap + * (for overlapping memory area, memmove is a safer approach). + * */ +void * +memcpy(void *dst, const void *src, size_t n) { + 800f08: 55 push %ebp + 800f09: 89 e5 mov %esp,%ebp + 800f0b: 57 push %edi + 800f0c: 56 push %esi + 800f0d: 83 ec 20 sub $0x20,%esp + 800f10: 8b 45 08 mov 0x8(%ebp),%eax + 800f13: 89 45 f4 mov %eax,-0xc(%ebp) + 800f16: 8b 45 0c mov 0xc(%ebp),%eax + 800f19: 89 45 f0 mov %eax,-0x10(%ebp) + 800f1c: 8b 45 10 mov 0x10(%ebp),%eax + 800f1f: 89 45 ec mov %eax,-0x14(%ebp) + : "0" (n / 4), "g" (n), "1" (dst), "2" (src) + 800f22: 8b 45 ec mov -0x14(%ebp),%eax + 800f25: c1 e8 02 shr $0x2,%eax + 800f28: 89 c1 mov %eax,%ecx + asm volatile ( + 800f2a: 8b 55 f4 mov -0xc(%ebp),%edx + 800f2d: 8b 45 f0 mov -0x10(%ebp),%eax + 800f30: 89 d7 mov %edx,%edi + 800f32: 89 c6 mov %eax,%esi + 800f34: f3 a5 rep movsl %ds:(%esi),%es:(%edi) + 800f36: 8b 4d ec mov -0x14(%ebp),%ecx + 800f39: 83 e1 03 and $0x3,%ecx + 800f3c: 74 02 je 800f40 + 800f3e: f3 a4 rep movsb %ds:(%esi),%es:(%edi) + 800f40: 89 f0 mov %esi,%eax + 800f42: 89 fa mov %edi,%edx + 800f44: 89 4d e8 mov %ecx,-0x18(%ebp) + 800f47: 89 55 e4 mov %edx,-0x1c(%ebp) + 800f4a: 89 45 e0 mov %eax,-0x20(%ebp) + return dst; + 800f4d: 8b 45 f4 mov -0xc(%ebp),%eax + while (n -- > 0) { + *d ++ = *s ++; + } + return dst; +#endif /* __HAVE_ARCH_MEMCPY */ +} + 800f50: 83 c4 20 add $0x20,%esp + 800f53: 5e pop %esi + 800f54: 5f pop %edi + 800f55: 5d pop %ebp + 800f56: c3 ret + +00800f57 : + * match in both memory blocks has a greater value in @v1 than in @v2 + * as if evaluated as unsigned char values; + * - And a value less than zero indicates the opposite. + * */ +int +memcmp(const void *v1, const void *v2, size_t n) { + 800f57: 55 push %ebp + 800f58: 89 e5 mov %esp,%ebp + 800f5a: 83 ec 10 sub $0x10,%esp + const char *s1 = (const char *)v1; + 800f5d: 8b 45 08 mov 0x8(%ebp),%eax + 800f60: 89 45 fc mov %eax,-0x4(%ebp) + const char *s2 = (const char *)v2; + 800f63: 8b 45 0c mov 0xc(%ebp),%eax + 800f66: 89 45 f8 mov %eax,-0x8(%ebp) + while (n -- > 0) { + 800f69: eb 2e jmp 800f99 + if (*s1 != *s2) { + 800f6b: 8b 45 fc mov -0x4(%ebp),%eax + 800f6e: 0f b6 10 movzbl (%eax),%edx + 800f71: 8b 45 f8 mov -0x8(%ebp),%eax + 800f74: 0f b6 00 movzbl (%eax),%eax + 800f77: 38 c2 cmp %al,%dl + 800f79: 74 18 je 800f93 + return (int)((unsigned char)*s1 - (unsigned char)*s2); + 800f7b: 8b 45 fc mov -0x4(%ebp),%eax + 800f7e: 0f b6 00 movzbl (%eax),%eax + 800f81: 0f b6 d0 movzbl %al,%edx + 800f84: 8b 45 f8 mov -0x8(%ebp),%eax + 800f87: 0f b6 00 movzbl (%eax),%eax + 800f8a: 0f b6 c8 movzbl %al,%ecx + 800f8d: 89 d0 mov %edx,%eax + 800f8f: 29 c8 sub %ecx,%eax + 800f91: eb 18 jmp 800fab + } + s1 ++, s2 ++; + 800f93: ff 45 fc incl -0x4(%ebp) + 800f96: ff 45 f8 incl -0x8(%ebp) + while (n -- > 0) { + 800f99: 8b 45 10 mov 0x10(%ebp),%eax + 800f9c: 8d 50 ff lea -0x1(%eax),%edx + 800f9f: 89 55 10 mov %edx,0x10(%ebp) + 800fa2: 85 c0 test %eax,%eax + 800fa4: 75 c5 jne 800f6b + } + return 0; + 800fa6: b8 00 00 00 00 mov $0x0,%eax +} + 800fab: 89 ec mov %ebp,%esp + 800fad: 5d pop %ebp + 800fae: c3 ret + +00800faf
: +#include +#include + +int +main(void) { + 800faf: 55 push %ebp + 800fb0: 89 e5 mov %esp,%ebp + 800fb2: 83 e4 f0 and $0xfffffff0,%esp + 800fb5: 83 ec 10 sub $0x10,%esp + cprintf("I read %8x from 0.\n", *(unsigned int *)0); + 800fb8: b8 00 00 00 00 mov $0x0,%eax + 800fbd: 8b 00 mov (%eax),%eax + 800fbf: 89 44 24 04 mov %eax,0x4(%esp) + 800fc3: c7 04 24 e0 12 80 00 movl $0x8012e0,(%esp) + 800fca: e8 51 f1 ff ff call 800120 + panic("FAIL: T.T\n"); + 800fcf: c7 44 24 08 f4 12 80 movl $0x8012f4,0x8(%esp) + 800fd6: 00 + 800fd7: c7 44 24 04 07 00 00 movl $0x7,0x4(%esp) + 800fde: 00 + 800fdf: c7 04 24 ff 12 80 00 movl $0x8012ff,(%esp) + 800fe6: e8 44 f0 ff ff call 80002f <__panic> diff --git a/labcodes/lab5/obj/user/faultread.d b/labcodes/lab5/obj/user/faultread.d new file mode 100644 index 0000000000000000000000000000000000000000..7fb2e616b2edc49a893423d3d08d083f90693c9e --- /dev/null +++ b/labcodes/lab5/obj/user/faultread.d @@ -0,0 +1,2 @@ +obj/user/faultread.o obj/user/faultread.d: user/faultread.c libs/stdio.h \ + libs/defs.h libs/stdarg.h user/libs/ulib.h diff --git a/labcodes/lab5/obj/user/faultread.o b/labcodes/lab5/obj/user/faultread.o new file mode 100644 index 0000000000000000000000000000000000000000..deecbede07804d4a00a9bdb10c069a063ff02964 Binary files /dev/null and b/labcodes/lab5/obj/user/faultread.o differ diff --git a/labcodes/lab5/obj/user/faultread.sym b/labcodes/lab5/obj/user/faultread.sym new file mode 100644 index 0000000000000000000000000000000000000000..c3c264a0b200f5375b99557b65f6ea35edb4e770 --- /dev/null +++ b/labcodes/lab5/obj/user/faultread.sym @@ -0,0 +1,66 @@ +00000000 panic.c +00000000 stdio.c +008000c8 cputch +00000000 syscall.c +00800199 syscall +00000000 ulib.c +00000000 umain.c +00000000 hash.c +00000000 printfmt.c +00801100 error_string +008003ad printnum +008004af getuint +008004fe getint +0080094f sprintputch +00000000 rand.c +00802000 next +00000000 string.c +00000000 faultread.c +00800b53 strcpy +00800329 yield +0080030d waitpid +00800245 sys_yield +00800e65 memmove +00800985 snprintf +00800576 vprintfmt +0080020b sys_fork +00800120 cprintf +0080034e getpid +00800f08 memcpy +008009bb vsnprintf +0080036d umain +002026c8 __STAB_END__ +0080025b sys_kill +002026c9 __STABSTR_BEGIN__ +0080002f __panic +00800ccb strtol +00800b22 strnlen +0080035d print_pgdir +00800339 kill +00800c9b strfind +008002ef wait +00800020 _start +00800a21 rand +00800c14 strncmp +0080028e sys_putc +00800b92 strncpy +00800f57 memcmp +008002e0 fork +00800e23 memset +00800faf main +00800ae0 srand +00800386 hash32 +00800545 printfmt +00203603 __STABSTR_END__ +00800bcb strcmp +008000eb vcprintf +0080007f __warn +00800148 cputs +008002c1 exit +00800221 sys_wait +008001ee sys_exit +00200010 __STAB_BEGIN__ +00800af9 strlen +008002ab sys_pgdir +00800c67 strchr +00800278 sys_getpid diff --git a/labcodes/lab5/obj/user/faultreadkernel.asm b/labcodes/lab5/obj/user/faultreadkernel.asm new file mode 100644 index 0000000000000000000000000000000000000000..104bdcd65c68d86696ed4f4275601b335bac1ace --- /dev/null +++ b/labcodes/lab5/obj/user/faultreadkernel.asm @@ -0,0 +1,2323 @@ + +obj/__user_faultreadkernel.out: file format elf32-i386 + + +Disassembly of section .text: + +00800020 <_start>: +.text +.globl _start +_start: + # set ebp for backtrace + movl $0x0, %ebp + 800020: bd 00 00 00 00 mov $0x0,%ebp + + # move down the esp register + # since it may cause page fault in backtrace + subl $0x20, %esp + 800025: 83 ec 20 sub $0x20,%esp + + # call user-program function + call umain + 800028: e8 40 03 00 00 call 80036d +1: jmp 1b + 80002d: eb fe jmp 80002d <_start+0xd> + +0080002f <__panic>: +#include +#include +#include + +void +__panic(const char *file, int line, const char *fmt, ...) { + 80002f: 55 push %ebp + 800030: 89 e5 mov %esp,%ebp + 800032: 83 ec 28 sub $0x28,%esp + // print the 'message' + va_list ap; + va_start(ap, fmt); + 800035: 8d 45 14 lea 0x14(%ebp),%eax + 800038: 89 45 f4 mov %eax,-0xc(%ebp) + cprintf("user panic at %s:%d:\n ", file, line); + 80003b: 8b 45 0c mov 0xc(%ebp),%eax + 80003e: 89 44 24 08 mov %eax,0x8(%esp) + 800042: 8b 45 08 mov 0x8(%ebp),%eax + 800045: 89 44 24 04 mov %eax,0x4(%esp) + 800049: c7 04 24 00 10 80 00 movl $0x801000,(%esp) + 800050: e8 cb 00 00 00 call 800120 + vcprintf(fmt, ap); + 800055: 8b 45 f4 mov -0xc(%ebp),%eax + 800058: 89 44 24 04 mov %eax,0x4(%esp) + 80005c: 8b 45 10 mov 0x10(%ebp),%eax + 80005f: 89 04 24 mov %eax,(%esp) + 800062: e8 84 00 00 00 call 8000eb + cprintf("\n"); + 800067: c7 04 24 1a 10 80 00 movl $0x80101a,(%esp) + 80006e: e8 ad 00 00 00 call 800120 + va_end(ap); + exit(-E_PANIC); + 800073: c7 04 24 f6 ff ff ff movl $0xfffffff6,(%esp) + 80007a: e8 42 02 00 00 call 8002c1 + +0080007f <__warn>: +} + +void +__warn(const char *file, int line, const char *fmt, ...) { + 80007f: 55 push %ebp + 800080: 89 e5 mov %esp,%ebp + 800082: 83 ec 28 sub $0x28,%esp + va_list ap; + va_start(ap, fmt); + 800085: 8d 45 14 lea 0x14(%ebp),%eax + 800088: 89 45 f4 mov %eax,-0xc(%ebp) + cprintf("user warning at %s:%d:\n ", file, line); + 80008b: 8b 45 0c mov 0xc(%ebp),%eax + 80008e: 89 44 24 08 mov %eax,0x8(%esp) + 800092: 8b 45 08 mov 0x8(%ebp),%eax + 800095: 89 44 24 04 mov %eax,0x4(%esp) + 800099: c7 04 24 1c 10 80 00 movl $0x80101c,(%esp) + 8000a0: e8 7b 00 00 00 call 800120 + vcprintf(fmt, ap); + 8000a5: 8b 45 f4 mov -0xc(%ebp),%eax + 8000a8: 89 44 24 04 mov %eax,0x4(%esp) + 8000ac: 8b 45 10 mov 0x10(%ebp),%eax + 8000af: 89 04 24 mov %eax,(%esp) + 8000b2: e8 34 00 00 00 call 8000eb + cprintf("\n"); + 8000b7: c7 04 24 1a 10 80 00 movl $0x80101a,(%esp) + 8000be: e8 5d 00 00 00 call 800120 + va_end(ap); +} + 8000c3: 90 nop + 8000c4: 89 ec mov %ebp,%esp + 8000c6: 5d pop %ebp + 8000c7: c3 ret + +008000c8 : +/* * + * cputch - writes a single character @c to stdout, and it will + * increace the value of counter pointed by @cnt. + * */ +static void +cputch(int c, int *cnt) { + 8000c8: 55 push %ebp + 8000c9: 89 e5 mov %esp,%ebp + 8000cb: 83 ec 18 sub $0x18,%esp + sys_putc(c); + 8000ce: 8b 45 08 mov 0x8(%ebp),%eax + 8000d1: 89 04 24 mov %eax,(%esp) + 8000d4: e8 b5 01 00 00 call 80028e + (*cnt) ++; + 8000d9: 8b 45 0c mov 0xc(%ebp),%eax + 8000dc: 8b 00 mov (%eax),%eax + 8000de: 8d 50 01 lea 0x1(%eax),%edx + 8000e1: 8b 45 0c mov 0xc(%ebp),%eax + 8000e4: 89 10 mov %edx,(%eax) +} + 8000e6: 90 nop + 8000e7: 89 ec mov %ebp,%esp + 8000e9: 5d pop %ebp + 8000ea: c3 ret + +008000eb : + * + * Call this function if you are already dealing with a va_list. + * Or you probably want cprintf() instead. + * */ +int +vcprintf(const char *fmt, va_list ap) { + 8000eb: 55 push %ebp + 8000ec: 89 e5 mov %esp,%ebp + 8000ee: 83 ec 28 sub $0x28,%esp + int cnt = 0; + 8000f1: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + vprintfmt((void*)cputch, &cnt, fmt, ap); + 8000f8: 8b 45 0c mov 0xc(%ebp),%eax + 8000fb: 89 44 24 0c mov %eax,0xc(%esp) + 8000ff: 8b 45 08 mov 0x8(%ebp),%eax + 800102: 89 44 24 08 mov %eax,0x8(%esp) + 800106: 8d 45 f4 lea -0xc(%ebp),%eax + 800109: 89 44 24 04 mov %eax,0x4(%esp) + 80010d: c7 04 24 c8 00 80 00 movl $0x8000c8,(%esp) + 800114: e8 5d 04 00 00 call 800576 + return cnt; + 800119: 8b 45 f4 mov -0xc(%ebp),%eax +} + 80011c: 89 ec mov %ebp,%esp + 80011e: 5d pop %ebp + 80011f: c3 ret + +00800120 : + * + * The return value is the number of characters which would be + * written to stdout. + * */ +int +cprintf(const char *fmt, ...) { + 800120: 55 push %ebp + 800121: 89 e5 mov %esp,%ebp + 800123: 83 ec 28 sub $0x28,%esp + va_list ap; + + va_start(ap, fmt); + 800126: 8d 45 0c lea 0xc(%ebp),%eax + 800129: 89 45 f0 mov %eax,-0x10(%ebp) + int cnt = vcprintf(fmt, ap); + 80012c: 8b 45 f0 mov -0x10(%ebp),%eax + 80012f: 89 44 24 04 mov %eax,0x4(%esp) + 800133: 8b 45 08 mov 0x8(%ebp),%eax + 800136: 89 04 24 mov %eax,(%esp) + 800139: e8 ad ff ff ff call 8000eb + 80013e: 89 45 f4 mov %eax,-0xc(%ebp) + va_end(ap); + + return cnt; + 800141: 8b 45 f4 mov -0xc(%ebp),%eax +} + 800144: 89 ec mov %ebp,%esp + 800146: 5d pop %ebp + 800147: c3 ret + +00800148 : +/* * + * cputs- writes the string pointed by @str to stdout and + * appends a newline character. + * */ +int +cputs(const char *str) { + 800148: 55 push %ebp + 800149: 89 e5 mov %esp,%ebp + 80014b: 83 ec 28 sub $0x28,%esp + int cnt = 0; + 80014e: c7 45 f0 00 00 00 00 movl $0x0,-0x10(%ebp) + char c; + while ((c = *str ++) != '\0') { + 800155: eb 13 jmp 80016a + cputch(c, &cnt); + 800157: 0f be 45 f7 movsbl -0x9(%ebp),%eax + 80015b: 8d 55 f0 lea -0x10(%ebp),%edx + 80015e: 89 54 24 04 mov %edx,0x4(%esp) + 800162: 89 04 24 mov %eax,(%esp) + 800165: e8 5e ff ff ff call 8000c8 + while ((c = *str ++) != '\0') { + 80016a: 8b 45 08 mov 0x8(%ebp),%eax + 80016d: 8d 50 01 lea 0x1(%eax),%edx + 800170: 89 55 08 mov %edx,0x8(%ebp) + 800173: 0f b6 00 movzbl (%eax),%eax + 800176: 88 45 f7 mov %al,-0x9(%ebp) + 800179: 80 7d f7 00 cmpb $0x0,-0x9(%ebp) + 80017d: 75 d8 jne 800157 + } + cputch('\n', &cnt); + 80017f: 8d 45 f0 lea -0x10(%ebp),%eax + 800182: 89 44 24 04 mov %eax,0x4(%esp) + 800186: c7 04 24 0a 00 00 00 movl $0xa,(%esp) + 80018d: e8 36 ff ff ff call 8000c8 + return cnt; + 800192: 8b 45 f0 mov -0x10(%ebp),%eax +} + 800195: 89 ec mov %ebp,%esp + 800197: 5d pop %ebp + 800198: c3 ret + +00800199 : +#include + +#define MAX_ARGS 5 + +static inline int +syscall(int num, ...) { + 800199: 55 push %ebp + 80019a: 89 e5 mov %esp,%ebp + 80019c: 57 push %edi + 80019d: 56 push %esi + 80019e: 53 push %ebx + 80019f: 83 ec 20 sub $0x20,%esp + va_list ap; + va_start(ap, num); + 8001a2: 8d 45 0c lea 0xc(%ebp),%eax + 8001a5: 89 45 e8 mov %eax,-0x18(%ebp) + uint32_t a[MAX_ARGS]; + int i, ret; + for (i = 0; i < MAX_ARGS; i ++) { + 8001a8: c7 45 f0 00 00 00 00 movl $0x0,-0x10(%ebp) + 8001af: eb 15 jmp 8001c6 + a[i] = va_arg(ap, uint32_t); + 8001b1: 8b 45 e8 mov -0x18(%ebp),%eax + 8001b4: 8d 50 04 lea 0x4(%eax),%edx + 8001b7: 89 55 e8 mov %edx,-0x18(%ebp) + 8001ba: 8b 10 mov (%eax),%edx + 8001bc: 8b 45 f0 mov -0x10(%ebp),%eax + 8001bf: 89 54 85 d4 mov %edx,-0x2c(%ebp,%eax,4) + for (i = 0; i < MAX_ARGS; i ++) { + 8001c3: ff 45 f0 incl -0x10(%ebp) + 8001c6: 83 7d f0 04 cmpl $0x4,-0x10(%ebp) + 8001ca: 7e e5 jle 8001b1 + asm volatile ( + "int %1;" + : "=a" (ret) + : "i" (T_SYSCALL), + "a" (num), + "d" (a[0]), + 8001cc: 8b 55 d4 mov -0x2c(%ebp),%edx + "c" (a[1]), + 8001cf: 8b 4d d8 mov -0x28(%ebp),%ecx + "b" (a[2]), + 8001d2: 8b 5d dc mov -0x24(%ebp),%ebx + "D" (a[3]), + 8001d5: 8b 7d e0 mov -0x20(%ebp),%edi + "S" (a[4]) + 8001d8: 8b 75 e4 mov -0x1c(%ebp),%esi + asm volatile ( + 8001db: 8b 45 08 mov 0x8(%ebp),%eax + 8001de: cd 80 int $0x80 + 8001e0: 89 45 ec mov %eax,-0x14(%ebp) + : "cc", "memory"); + return ret; + 8001e3: 8b 45 ec mov -0x14(%ebp),%eax +} + 8001e6: 83 c4 20 add $0x20,%esp + 8001e9: 5b pop %ebx + 8001ea: 5e pop %esi + 8001eb: 5f pop %edi + 8001ec: 5d pop %ebp + 8001ed: c3 ret + +008001ee : + +int +sys_exit(int error_code) { + 8001ee: 55 push %ebp + 8001ef: 89 e5 mov %esp,%ebp + 8001f1: 83 ec 08 sub $0x8,%esp + return syscall(SYS_exit, error_code); + 8001f4: 8b 45 08 mov 0x8(%ebp),%eax + 8001f7: 89 44 24 04 mov %eax,0x4(%esp) + 8001fb: c7 04 24 01 00 00 00 movl $0x1,(%esp) + 800202: e8 92 ff ff ff call 800199 +} + 800207: 89 ec mov %ebp,%esp + 800209: 5d pop %ebp + 80020a: c3 ret + +0080020b : + +int +sys_fork(void) { + 80020b: 55 push %ebp + 80020c: 89 e5 mov %esp,%ebp + 80020e: 83 ec 04 sub $0x4,%esp + return syscall(SYS_fork); + 800211: c7 04 24 02 00 00 00 movl $0x2,(%esp) + 800218: e8 7c ff ff ff call 800199 +} + 80021d: 89 ec mov %ebp,%esp + 80021f: 5d pop %ebp + 800220: c3 ret + +00800221 : + +int +sys_wait(int pid, int *store) { + 800221: 55 push %ebp + 800222: 89 e5 mov %esp,%ebp + 800224: 83 ec 0c sub $0xc,%esp + return syscall(SYS_wait, pid, store); + 800227: 8b 45 0c mov 0xc(%ebp),%eax + 80022a: 89 44 24 08 mov %eax,0x8(%esp) + 80022e: 8b 45 08 mov 0x8(%ebp),%eax + 800231: 89 44 24 04 mov %eax,0x4(%esp) + 800235: c7 04 24 03 00 00 00 movl $0x3,(%esp) + 80023c: e8 58 ff ff ff call 800199 +} + 800241: 89 ec mov %ebp,%esp + 800243: 5d pop %ebp + 800244: c3 ret + +00800245 : + +int +sys_yield(void) { + 800245: 55 push %ebp + 800246: 89 e5 mov %esp,%ebp + 800248: 83 ec 04 sub $0x4,%esp + return syscall(SYS_yield); + 80024b: c7 04 24 0a 00 00 00 movl $0xa,(%esp) + 800252: e8 42 ff ff ff call 800199 +} + 800257: 89 ec mov %ebp,%esp + 800259: 5d pop %ebp + 80025a: c3 ret + +0080025b : + +int +sys_kill(int pid) { + 80025b: 55 push %ebp + 80025c: 89 e5 mov %esp,%ebp + 80025e: 83 ec 08 sub $0x8,%esp + return syscall(SYS_kill, pid); + 800261: 8b 45 08 mov 0x8(%ebp),%eax + 800264: 89 44 24 04 mov %eax,0x4(%esp) + 800268: c7 04 24 0c 00 00 00 movl $0xc,(%esp) + 80026f: e8 25 ff ff ff call 800199 +} + 800274: 89 ec mov %ebp,%esp + 800276: 5d pop %ebp + 800277: c3 ret + +00800278 : + +int +sys_getpid(void) { + 800278: 55 push %ebp + 800279: 89 e5 mov %esp,%ebp + 80027b: 83 ec 04 sub $0x4,%esp + return syscall(SYS_getpid); + 80027e: c7 04 24 12 00 00 00 movl $0x12,(%esp) + 800285: e8 0f ff ff ff call 800199 +} + 80028a: 89 ec mov %ebp,%esp + 80028c: 5d pop %ebp + 80028d: c3 ret + +0080028e : + +int +sys_putc(int c) { + 80028e: 55 push %ebp + 80028f: 89 e5 mov %esp,%ebp + 800291: 83 ec 08 sub $0x8,%esp + return syscall(SYS_putc, c); + 800294: 8b 45 08 mov 0x8(%ebp),%eax + 800297: 89 44 24 04 mov %eax,0x4(%esp) + 80029b: c7 04 24 1e 00 00 00 movl $0x1e,(%esp) + 8002a2: e8 f2 fe ff ff call 800199 +} + 8002a7: 89 ec mov %ebp,%esp + 8002a9: 5d pop %ebp + 8002aa: c3 ret + +008002ab : + +int +sys_pgdir(void) { + 8002ab: 55 push %ebp + 8002ac: 89 e5 mov %esp,%ebp + 8002ae: 83 ec 04 sub $0x4,%esp + return syscall(SYS_pgdir); + 8002b1: c7 04 24 1f 00 00 00 movl $0x1f,(%esp) + 8002b8: e8 dc fe ff ff call 800199 +} + 8002bd: 89 ec mov %ebp,%esp + 8002bf: 5d pop %ebp + 8002c0: c3 ret + +008002c1 : +#include +#include +#include + +void +exit(int error_code) { + 8002c1: 55 push %ebp + 8002c2: 89 e5 mov %esp,%ebp + 8002c4: 83 ec 18 sub $0x18,%esp + sys_exit(error_code); + 8002c7: 8b 45 08 mov 0x8(%ebp),%eax + 8002ca: 89 04 24 mov %eax,(%esp) + 8002cd: e8 1c ff ff ff call 8001ee + cprintf("BUG: exit failed.\n"); + 8002d2: c7 04 24 38 10 80 00 movl $0x801038,(%esp) + 8002d9: e8 42 fe ff ff call 800120 + while (1); + 8002de: eb fe jmp 8002de + +008002e0 : +} + +int +fork(void) { + 8002e0: 55 push %ebp + 8002e1: 89 e5 mov %esp,%ebp + 8002e3: 83 ec 08 sub $0x8,%esp + return sys_fork(); + 8002e6: e8 20 ff ff ff call 80020b +} + 8002eb: 89 ec mov %ebp,%esp + 8002ed: 5d pop %ebp + 8002ee: c3 ret + +008002ef : + +int +wait(void) { + 8002ef: 55 push %ebp + 8002f0: 89 e5 mov %esp,%ebp + 8002f2: 83 ec 18 sub $0x18,%esp + return sys_wait(0, NULL); + 8002f5: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) + 8002fc: 00 + 8002fd: c7 04 24 00 00 00 00 movl $0x0,(%esp) + 800304: e8 18 ff ff ff call 800221 +} + 800309: 89 ec mov %ebp,%esp + 80030b: 5d pop %ebp + 80030c: c3 ret + +0080030d : + +int +waitpid(int pid, int *store) { + 80030d: 55 push %ebp + 80030e: 89 e5 mov %esp,%ebp + 800310: 83 ec 18 sub $0x18,%esp + return sys_wait(pid, store); + 800313: 8b 45 0c mov 0xc(%ebp),%eax + 800316: 89 44 24 04 mov %eax,0x4(%esp) + 80031a: 8b 45 08 mov 0x8(%ebp),%eax + 80031d: 89 04 24 mov %eax,(%esp) + 800320: e8 fc fe ff ff call 800221 +} + 800325: 89 ec mov %ebp,%esp + 800327: 5d pop %ebp + 800328: c3 ret + +00800329 : + +void +yield(void) { + 800329: 55 push %ebp + 80032a: 89 e5 mov %esp,%ebp + 80032c: 83 ec 08 sub $0x8,%esp + sys_yield(); + 80032f: e8 11 ff ff ff call 800245 +} + 800334: 90 nop + 800335: 89 ec mov %ebp,%esp + 800337: 5d pop %ebp + 800338: c3 ret + +00800339 : + +int +kill(int pid) { + 800339: 55 push %ebp + 80033a: 89 e5 mov %esp,%ebp + 80033c: 83 ec 18 sub $0x18,%esp + return sys_kill(pid); + 80033f: 8b 45 08 mov 0x8(%ebp),%eax + 800342: 89 04 24 mov %eax,(%esp) + 800345: e8 11 ff ff ff call 80025b +} + 80034a: 89 ec mov %ebp,%esp + 80034c: 5d pop %ebp + 80034d: c3 ret + +0080034e : + +int +getpid(void) { + 80034e: 55 push %ebp + 80034f: 89 e5 mov %esp,%ebp + 800351: 83 ec 08 sub $0x8,%esp + return sys_getpid(); + 800354: e8 1f ff ff ff call 800278 +} + 800359: 89 ec mov %ebp,%esp + 80035b: 5d pop %ebp + 80035c: c3 ret + +0080035d : + +//print_pgdir - print the PDT&PT +void +print_pgdir(void) { + 80035d: 55 push %ebp + 80035e: 89 e5 mov %esp,%ebp + 800360: 83 ec 08 sub $0x8,%esp + sys_pgdir(); + 800363: e8 43 ff ff ff call 8002ab +} + 800368: 90 nop + 800369: 89 ec mov %ebp,%esp + 80036b: 5d pop %ebp + 80036c: c3 ret + +0080036d : +#include + +int main(void); + +void +umain(void) { + 80036d: 55 push %ebp + 80036e: 89 e5 mov %esp,%ebp + 800370: 83 ec 28 sub $0x28,%esp + int ret = main(); + 800373: e8 37 0c 00 00 call 800faf
+ 800378: 89 45 f4 mov %eax,-0xc(%ebp) + exit(ret); + 80037b: 8b 45 f4 mov -0xc(%ebp),%eax + 80037e: 89 04 24 mov %eax,(%esp) + 800381: e8 3b ff ff ff call 8002c1 + +00800386 : + * @bits: the number of bits in a return value + * + * High bits are more random, so we use them. + * */ +uint32_t +hash32(uint32_t val, unsigned int bits) { + 800386: 55 push %ebp + 800387: 89 e5 mov %esp,%ebp + 800389: 83 ec 10 sub $0x10,%esp + uint32_t hash = val * GOLDEN_RATIO_PRIME_32; + 80038c: 8b 45 08 mov 0x8(%ebp),%eax + 80038f: 69 c0 01 00 37 9e imul $0x9e370001,%eax,%eax + 800395: 89 45 fc mov %eax,-0x4(%ebp) + return (hash >> (32 - bits)); + 800398: b8 20 00 00 00 mov $0x20,%eax + 80039d: 2b 45 0c sub 0xc(%ebp),%eax + 8003a0: 8b 55 fc mov -0x4(%ebp),%edx + 8003a3: 88 c1 mov %al,%cl + 8003a5: d3 ea shr %cl,%edx + 8003a7: 89 d0 mov %edx,%eax +} + 8003a9: 89 ec mov %ebp,%esp + 8003ab: 5d pop %ebp + 8003ac: c3 ret + +008003ad : + * @width: maximum number of digits, if the actual width is less than @width, use @padc instead + * @padc: character that padded on the left if the actual width is less than @width + * */ +static void +printnum(void (*putch)(int, void*), void *putdat, + unsigned long long num, unsigned base, int width, int padc) { + 8003ad: 55 push %ebp + 8003ae: 89 e5 mov %esp,%ebp + 8003b0: 83 ec 58 sub $0x58,%esp + 8003b3: 8b 45 10 mov 0x10(%ebp),%eax + 8003b6: 89 45 d0 mov %eax,-0x30(%ebp) + 8003b9: 8b 45 14 mov 0x14(%ebp),%eax + 8003bc: 89 45 d4 mov %eax,-0x2c(%ebp) + unsigned long long result = num; + 8003bf: 8b 45 d0 mov -0x30(%ebp),%eax + 8003c2: 8b 55 d4 mov -0x2c(%ebp),%edx + 8003c5: 89 45 e8 mov %eax,-0x18(%ebp) + 8003c8: 89 55 ec mov %edx,-0x14(%ebp) + unsigned mod = do_div(result, base); + 8003cb: 8b 45 18 mov 0x18(%ebp),%eax + 8003ce: 89 45 e4 mov %eax,-0x1c(%ebp) + 8003d1: 8b 45 e8 mov -0x18(%ebp),%eax + 8003d4: 8b 55 ec mov -0x14(%ebp),%edx + 8003d7: 89 45 e0 mov %eax,-0x20(%ebp) + 8003da: 89 55 f0 mov %edx,-0x10(%ebp) + 8003dd: 8b 45 f0 mov -0x10(%ebp),%eax + 8003e0: 89 45 f4 mov %eax,-0xc(%ebp) + 8003e3: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) + 8003e7: 74 1c je 800405 + 8003e9: 8b 45 f0 mov -0x10(%ebp),%eax + 8003ec: ba 00 00 00 00 mov $0x0,%edx + 8003f1: f7 75 e4 divl -0x1c(%ebp) + 8003f4: 89 55 f4 mov %edx,-0xc(%ebp) + 8003f7: 8b 45 f0 mov -0x10(%ebp),%eax + 8003fa: ba 00 00 00 00 mov $0x0,%edx + 8003ff: f7 75 e4 divl -0x1c(%ebp) + 800402: 89 45 f0 mov %eax,-0x10(%ebp) + 800405: 8b 45 e0 mov -0x20(%ebp),%eax + 800408: 8b 55 f4 mov -0xc(%ebp),%edx + 80040b: f7 75 e4 divl -0x1c(%ebp) + 80040e: 89 45 e0 mov %eax,-0x20(%ebp) + 800411: 89 55 dc mov %edx,-0x24(%ebp) + 800414: 8b 45 e0 mov -0x20(%ebp),%eax + 800417: 8b 55 f0 mov -0x10(%ebp),%edx + 80041a: 89 45 e8 mov %eax,-0x18(%ebp) + 80041d: 89 55 ec mov %edx,-0x14(%ebp) + 800420: 8b 45 dc mov -0x24(%ebp),%eax + 800423: 89 45 d8 mov %eax,-0x28(%ebp) + + // first recursively print all preceding (more significant) digits + if (num >= base) { + 800426: 8b 45 18 mov 0x18(%ebp),%eax + 800429: ba 00 00 00 00 mov $0x0,%edx + 80042e: 8b 4d d4 mov -0x2c(%ebp),%ecx + 800431: 39 45 d0 cmp %eax,-0x30(%ebp) + 800434: 19 d1 sbb %edx,%ecx + 800436: 72 4c jb 800484 + printnum(putch, putdat, result, base, width - 1, padc); + 800438: 8b 45 1c mov 0x1c(%ebp),%eax + 80043b: 8d 50 ff lea -0x1(%eax),%edx + 80043e: 8b 45 20 mov 0x20(%ebp),%eax + 800441: 89 44 24 18 mov %eax,0x18(%esp) + 800445: 89 54 24 14 mov %edx,0x14(%esp) + 800449: 8b 45 18 mov 0x18(%ebp),%eax + 80044c: 89 44 24 10 mov %eax,0x10(%esp) + 800450: 8b 45 e8 mov -0x18(%ebp),%eax + 800453: 8b 55 ec mov -0x14(%ebp),%edx + 800456: 89 44 24 08 mov %eax,0x8(%esp) + 80045a: 89 54 24 0c mov %edx,0xc(%esp) + 80045e: 8b 45 0c mov 0xc(%ebp),%eax + 800461: 89 44 24 04 mov %eax,0x4(%esp) + 800465: 8b 45 08 mov 0x8(%ebp),%eax + 800468: 89 04 24 mov %eax,(%esp) + 80046b: e8 3d ff ff ff call 8003ad + 800470: eb 1b jmp 80048d + } else { + // print any needed pad characters before first digit + while (-- width > 0) + putch(padc, putdat); + 800472: 8b 45 0c mov 0xc(%ebp),%eax + 800475: 89 44 24 04 mov %eax,0x4(%esp) + 800479: 8b 45 20 mov 0x20(%ebp),%eax + 80047c: 89 04 24 mov %eax,(%esp) + 80047f: 8b 45 08 mov 0x8(%ebp),%eax + 800482: ff d0 call *%eax + while (-- width > 0) + 800484: ff 4d 1c decl 0x1c(%ebp) + 800487: 83 7d 1c 00 cmpl $0x0,0x1c(%ebp) + 80048b: 7f e5 jg 800472 + } + // then print this (the least significant) digit + putch("0123456789abcdef"[mod], putdat); + 80048d: 8b 45 d8 mov -0x28(%ebp),%eax + 800490: 05 64 11 80 00 add $0x801164,%eax + 800495: 0f b6 00 movzbl (%eax),%eax + 800498: 0f be c0 movsbl %al,%eax + 80049b: 8b 55 0c mov 0xc(%ebp),%edx + 80049e: 89 54 24 04 mov %edx,0x4(%esp) + 8004a2: 89 04 24 mov %eax,(%esp) + 8004a5: 8b 45 08 mov 0x8(%ebp),%eax + 8004a8: ff d0 call *%eax +} + 8004aa: 90 nop + 8004ab: 89 ec mov %ebp,%esp + 8004ad: 5d pop %ebp + 8004ae: c3 ret + +008004af : + * getuint - get an unsigned int of various possible sizes from a varargs list + * @ap: a varargs list pointer + * @lflag: determines the size of the vararg that @ap points to + * */ +static unsigned long long +getuint(va_list *ap, int lflag) { + 8004af: 55 push %ebp + 8004b0: 89 e5 mov %esp,%ebp + if (lflag >= 2) { + 8004b2: 83 7d 0c 01 cmpl $0x1,0xc(%ebp) + 8004b6: 7e 14 jle 8004cc + return va_arg(*ap, unsigned long long); + 8004b8: 8b 45 08 mov 0x8(%ebp),%eax + 8004bb: 8b 00 mov (%eax),%eax + 8004bd: 8d 48 08 lea 0x8(%eax),%ecx + 8004c0: 8b 55 08 mov 0x8(%ebp),%edx + 8004c3: 89 0a mov %ecx,(%edx) + 8004c5: 8b 50 04 mov 0x4(%eax),%edx + 8004c8: 8b 00 mov (%eax),%eax + 8004ca: eb 30 jmp 8004fc + } + else if (lflag) { + 8004cc: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) + 8004d0: 74 16 je 8004e8 + return va_arg(*ap, unsigned long); + 8004d2: 8b 45 08 mov 0x8(%ebp),%eax + 8004d5: 8b 00 mov (%eax),%eax + 8004d7: 8d 48 04 lea 0x4(%eax),%ecx + 8004da: 8b 55 08 mov 0x8(%ebp),%edx + 8004dd: 89 0a mov %ecx,(%edx) + 8004df: 8b 00 mov (%eax),%eax + 8004e1: ba 00 00 00 00 mov $0x0,%edx + 8004e6: eb 14 jmp 8004fc + } + else { + return va_arg(*ap, unsigned int); + 8004e8: 8b 45 08 mov 0x8(%ebp),%eax + 8004eb: 8b 00 mov (%eax),%eax + 8004ed: 8d 48 04 lea 0x4(%eax),%ecx + 8004f0: 8b 55 08 mov 0x8(%ebp),%edx + 8004f3: 89 0a mov %ecx,(%edx) + 8004f5: 8b 00 mov (%eax),%eax + 8004f7: ba 00 00 00 00 mov $0x0,%edx + } +} + 8004fc: 5d pop %ebp + 8004fd: c3 ret + +008004fe : + * getint - same as getuint but signed, we can't use getuint because of sign extension + * @ap: a varargs list pointer + * @lflag: determines the size of the vararg that @ap points to + * */ +static long long +getint(va_list *ap, int lflag) { + 8004fe: 55 push %ebp + 8004ff: 89 e5 mov %esp,%ebp + if (lflag >= 2) { + 800501: 83 7d 0c 01 cmpl $0x1,0xc(%ebp) + 800505: 7e 14 jle 80051b + return va_arg(*ap, long long); + 800507: 8b 45 08 mov 0x8(%ebp),%eax + 80050a: 8b 00 mov (%eax),%eax + 80050c: 8d 48 08 lea 0x8(%eax),%ecx + 80050f: 8b 55 08 mov 0x8(%ebp),%edx + 800512: 89 0a mov %ecx,(%edx) + 800514: 8b 50 04 mov 0x4(%eax),%edx + 800517: 8b 00 mov (%eax),%eax + 800519: eb 28 jmp 800543 + } + else if (lflag) { + 80051b: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) + 80051f: 74 12 je 800533 + return va_arg(*ap, long); + 800521: 8b 45 08 mov 0x8(%ebp),%eax + 800524: 8b 00 mov (%eax),%eax + 800526: 8d 48 04 lea 0x4(%eax),%ecx + 800529: 8b 55 08 mov 0x8(%ebp),%edx + 80052c: 89 0a mov %ecx,(%edx) + 80052e: 8b 00 mov (%eax),%eax + 800530: 99 cltd + 800531: eb 10 jmp 800543 + } + else { + return va_arg(*ap, int); + 800533: 8b 45 08 mov 0x8(%ebp),%eax + 800536: 8b 00 mov (%eax),%eax + 800538: 8d 48 04 lea 0x4(%eax),%ecx + 80053b: 8b 55 08 mov 0x8(%ebp),%edx + 80053e: 89 0a mov %ecx,(%edx) + 800540: 8b 00 mov (%eax),%eax + 800542: 99 cltd + } +} + 800543: 5d pop %ebp + 800544: c3 ret + +00800545 : + * @putch: specified putch function, print a single character + * @putdat: used by @putch function + * @fmt: the format string to use + * */ +void +printfmt(void (*putch)(int, void*), void *putdat, const char *fmt, ...) { + 800545: 55 push %ebp + 800546: 89 e5 mov %esp,%ebp + 800548: 83 ec 28 sub $0x28,%esp + va_list ap; + + va_start(ap, fmt); + 80054b: 8d 45 14 lea 0x14(%ebp),%eax + 80054e: 89 45 f4 mov %eax,-0xc(%ebp) + vprintfmt(putch, putdat, fmt, ap); + 800551: 8b 45 f4 mov -0xc(%ebp),%eax + 800554: 89 44 24 0c mov %eax,0xc(%esp) + 800558: 8b 45 10 mov 0x10(%ebp),%eax + 80055b: 89 44 24 08 mov %eax,0x8(%esp) + 80055f: 8b 45 0c mov 0xc(%ebp),%eax + 800562: 89 44 24 04 mov %eax,0x4(%esp) + 800566: 8b 45 08 mov 0x8(%ebp),%eax + 800569: 89 04 24 mov %eax,(%esp) + 80056c: e8 05 00 00 00 call 800576 + va_end(ap); +} + 800571: 90 nop + 800572: 89 ec mov %ebp,%esp + 800574: 5d pop %ebp + 800575: c3 ret + +00800576 : + * + * Call this function if you are already dealing with a va_list. + * Or you probably want printfmt() instead. + * */ +void +vprintfmt(void (*putch)(int, void*), void *putdat, const char *fmt, va_list ap) { + 800576: 55 push %ebp + 800577: 89 e5 mov %esp,%ebp + 800579: 56 push %esi + 80057a: 53 push %ebx + 80057b: 83 ec 40 sub $0x40,%esp + register int ch, err; + unsigned long long num; + int base, width, precision, lflag, altflag; + + while (1) { + while ((ch = *(unsigned char *)fmt ++) != '%') { + 80057e: eb 17 jmp 800597 + if (ch == '\0') { + 800580: 85 db test %ebx,%ebx + 800582: 0f 84 bf 03 00 00 je 800947 + return; + } + putch(ch, putdat); + 800588: 8b 45 0c mov 0xc(%ebp),%eax + 80058b: 89 44 24 04 mov %eax,0x4(%esp) + 80058f: 89 1c 24 mov %ebx,(%esp) + 800592: 8b 45 08 mov 0x8(%ebp),%eax + 800595: ff d0 call *%eax + while ((ch = *(unsigned char *)fmt ++) != '%') { + 800597: 8b 45 10 mov 0x10(%ebp),%eax + 80059a: 8d 50 01 lea 0x1(%eax),%edx + 80059d: 89 55 10 mov %edx,0x10(%ebp) + 8005a0: 0f b6 00 movzbl (%eax),%eax + 8005a3: 0f b6 d8 movzbl %al,%ebx + 8005a6: 83 fb 25 cmp $0x25,%ebx + 8005a9: 75 d5 jne 800580 + } + + // Process a %-escape sequence + char padc = ' '; + 8005ab: c6 45 db 20 movb $0x20,-0x25(%ebp) + width = precision = -1; + 8005af: c7 45 e4 ff ff ff ff movl $0xffffffff,-0x1c(%ebp) + 8005b6: 8b 45 e4 mov -0x1c(%ebp),%eax + 8005b9: 89 45 e8 mov %eax,-0x18(%ebp) + lflag = altflag = 0; + 8005bc: c7 45 dc 00 00 00 00 movl $0x0,-0x24(%ebp) + 8005c3: 8b 45 dc mov -0x24(%ebp),%eax + 8005c6: 89 45 e0 mov %eax,-0x20(%ebp) + + reswitch: + switch (ch = *(unsigned char *)fmt ++) { + 8005c9: 8b 45 10 mov 0x10(%ebp),%eax + 8005cc: 8d 50 01 lea 0x1(%eax),%edx + 8005cf: 89 55 10 mov %edx,0x10(%ebp) + 8005d2: 0f b6 00 movzbl (%eax),%eax + 8005d5: 0f b6 d8 movzbl %al,%ebx + 8005d8: 8d 43 dd lea -0x23(%ebx),%eax + 8005db: 83 f8 55 cmp $0x55,%eax + 8005de: 0f 87 37 03 00 00 ja 80091b + 8005e4: 8b 04 85 88 11 80 00 mov 0x801188(,%eax,4),%eax + 8005eb: ff e0 jmp *%eax + + // flag to pad on the right + case '-': + padc = '-'; + 8005ed: c6 45 db 2d movb $0x2d,-0x25(%ebp) + goto reswitch; + 8005f1: eb d6 jmp 8005c9 + + // flag to pad with 0's instead of spaces + case '0': + padc = '0'; + 8005f3: c6 45 db 30 movb $0x30,-0x25(%ebp) + goto reswitch; + 8005f7: eb d0 jmp 8005c9 + + // width field + case '1' ... '9': + for (precision = 0; ; ++ fmt) { + 8005f9: c7 45 e4 00 00 00 00 movl $0x0,-0x1c(%ebp) + precision = precision * 10 + ch - '0'; + 800600: 8b 55 e4 mov -0x1c(%ebp),%edx + 800603: 89 d0 mov %edx,%eax + 800605: c1 e0 02 shl $0x2,%eax + 800608: 01 d0 add %edx,%eax + 80060a: 01 c0 add %eax,%eax + 80060c: 01 d8 add %ebx,%eax + 80060e: 83 e8 30 sub $0x30,%eax + 800611: 89 45 e4 mov %eax,-0x1c(%ebp) + ch = *fmt; + 800614: 8b 45 10 mov 0x10(%ebp),%eax + 800617: 0f b6 00 movzbl (%eax),%eax + 80061a: 0f be d8 movsbl %al,%ebx + if (ch < '0' || ch > '9') { + 80061d: 83 fb 2f cmp $0x2f,%ebx + 800620: 7e 38 jle 80065a + 800622: 83 fb 39 cmp $0x39,%ebx + 800625: 7f 33 jg 80065a + for (precision = 0; ; ++ fmt) { + 800627: ff 45 10 incl 0x10(%ebp) + precision = precision * 10 + ch - '0'; + 80062a: eb d4 jmp 800600 + } + } + goto process_precision; + + case '*': + precision = va_arg(ap, int); + 80062c: 8b 45 14 mov 0x14(%ebp),%eax + 80062f: 8d 50 04 lea 0x4(%eax),%edx + 800632: 89 55 14 mov %edx,0x14(%ebp) + 800635: 8b 00 mov (%eax),%eax + 800637: 89 45 e4 mov %eax,-0x1c(%ebp) + goto process_precision; + 80063a: eb 1f jmp 80065b + + case '.': + if (width < 0) + 80063c: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 800640: 79 87 jns 8005c9 + width = 0; + 800642: c7 45 e8 00 00 00 00 movl $0x0,-0x18(%ebp) + goto reswitch; + 800649: e9 7b ff ff ff jmp 8005c9 + + case '#': + altflag = 1; + 80064e: c7 45 dc 01 00 00 00 movl $0x1,-0x24(%ebp) + goto reswitch; + 800655: e9 6f ff ff ff jmp 8005c9 + goto process_precision; + 80065a: 90 nop + + process_precision: + if (width < 0) + 80065b: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 80065f: 0f 89 64 ff ff ff jns 8005c9 + width = precision, precision = -1; + 800665: 8b 45 e4 mov -0x1c(%ebp),%eax + 800668: 89 45 e8 mov %eax,-0x18(%ebp) + 80066b: c7 45 e4 ff ff ff ff movl $0xffffffff,-0x1c(%ebp) + goto reswitch; + 800672: e9 52 ff ff ff jmp 8005c9 + + // long flag (doubled for long long) + case 'l': + lflag ++; + 800677: ff 45 e0 incl -0x20(%ebp) + goto reswitch; + 80067a: e9 4a ff ff ff jmp 8005c9 + + // character + case 'c': + putch(va_arg(ap, int), putdat); + 80067f: 8b 45 14 mov 0x14(%ebp),%eax + 800682: 8d 50 04 lea 0x4(%eax),%edx + 800685: 89 55 14 mov %edx,0x14(%ebp) + 800688: 8b 00 mov (%eax),%eax + 80068a: 8b 55 0c mov 0xc(%ebp),%edx + 80068d: 89 54 24 04 mov %edx,0x4(%esp) + 800691: 89 04 24 mov %eax,(%esp) + 800694: 8b 45 08 mov 0x8(%ebp),%eax + 800697: ff d0 call *%eax + break; + 800699: e9 a4 02 00 00 jmp 800942 + + // error message + case 'e': + err = va_arg(ap, int); + 80069e: 8b 45 14 mov 0x14(%ebp),%eax + 8006a1: 8d 50 04 lea 0x4(%eax),%edx + 8006a4: 89 55 14 mov %edx,0x14(%ebp) + 8006a7: 8b 18 mov (%eax),%ebx + if (err < 0) { + 8006a9: 85 db test %ebx,%ebx + 8006ab: 79 02 jns 8006af + err = -err; + 8006ad: f7 db neg %ebx + } + if (err > MAXERROR || (p = error_string[err]) == NULL) { + 8006af: 83 fb 18 cmp $0x18,%ebx + 8006b2: 7f 0b jg 8006bf + 8006b4: 8b 34 9d 00 11 80 00 mov 0x801100(,%ebx,4),%esi + 8006bb: 85 f6 test %esi,%esi + 8006bd: 75 23 jne 8006e2 + printfmt(putch, putdat, "error %d", err); + 8006bf: 89 5c 24 0c mov %ebx,0xc(%esp) + 8006c3: c7 44 24 08 75 11 80 movl $0x801175,0x8(%esp) + 8006ca: 00 + 8006cb: 8b 45 0c mov 0xc(%ebp),%eax + 8006ce: 89 44 24 04 mov %eax,0x4(%esp) + 8006d2: 8b 45 08 mov 0x8(%ebp),%eax + 8006d5: 89 04 24 mov %eax,(%esp) + 8006d8: e8 68 fe ff ff call 800545 + } + else { + printfmt(putch, putdat, "%s", p); + } + break; + 8006dd: e9 60 02 00 00 jmp 800942 + printfmt(putch, putdat, "%s", p); + 8006e2: 89 74 24 0c mov %esi,0xc(%esp) + 8006e6: c7 44 24 08 7e 11 80 movl $0x80117e,0x8(%esp) + 8006ed: 00 + 8006ee: 8b 45 0c mov 0xc(%ebp),%eax + 8006f1: 89 44 24 04 mov %eax,0x4(%esp) + 8006f5: 8b 45 08 mov 0x8(%ebp),%eax + 8006f8: 89 04 24 mov %eax,(%esp) + 8006fb: e8 45 fe ff ff call 800545 + break; + 800700: e9 3d 02 00 00 jmp 800942 + + // string + case 's': + if ((p = va_arg(ap, char *)) == NULL) { + 800705: 8b 45 14 mov 0x14(%ebp),%eax + 800708: 8d 50 04 lea 0x4(%eax),%edx + 80070b: 89 55 14 mov %edx,0x14(%ebp) + 80070e: 8b 30 mov (%eax),%esi + 800710: 85 f6 test %esi,%esi + 800712: 75 05 jne 800719 + p = "(null)"; + 800714: be 81 11 80 00 mov $0x801181,%esi + } + if (width > 0 && padc != '-') { + 800719: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 80071d: 7e 76 jle 800795 + 80071f: 80 7d db 2d cmpb $0x2d,-0x25(%ebp) + 800723: 74 70 je 800795 + for (width -= strnlen(p, precision); width > 0; width --) { + 800725: 8b 45 e4 mov -0x1c(%ebp),%eax + 800728: 89 44 24 04 mov %eax,0x4(%esp) + 80072c: 89 34 24 mov %esi,(%esp) + 80072f: e8 ee 03 00 00 call 800b22 + 800734: 89 c2 mov %eax,%edx + 800736: 8b 45 e8 mov -0x18(%ebp),%eax + 800739: 29 d0 sub %edx,%eax + 80073b: 89 45 e8 mov %eax,-0x18(%ebp) + 80073e: eb 16 jmp 800756 + putch(padc, putdat); + 800740: 0f be 45 db movsbl -0x25(%ebp),%eax + 800744: 8b 55 0c mov 0xc(%ebp),%edx + 800747: 89 54 24 04 mov %edx,0x4(%esp) + 80074b: 89 04 24 mov %eax,(%esp) + 80074e: 8b 45 08 mov 0x8(%ebp),%eax + 800751: ff d0 call *%eax + for (width -= strnlen(p, precision); width > 0; width --) { + 800753: ff 4d e8 decl -0x18(%ebp) + 800756: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 80075a: 7f e4 jg 800740 + } + } + for (; (ch = *p ++) != '\0' && (precision < 0 || -- precision >= 0); width --) { + 80075c: eb 37 jmp 800795 + if (altflag && (ch < ' ' || ch > '~')) { + 80075e: 83 7d dc 00 cmpl $0x0,-0x24(%ebp) + 800762: 74 1f je 800783 + 800764: 83 fb 1f cmp $0x1f,%ebx + 800767: 7e 05 jle 80076e + 800769: 83 fb 7e cmp $0x7e,%ebx + 80076c: 7e 15 jle 800783 + putch('?', putdat); + 80076e: 8b 45 0c mov 0xc(%ebp),%eax + 800771: 89 44 24 04 mov %eax,0x4(%esp) + 800775: c7 04 24 3f 00 00 00 movl $0x3f,(%esp) + 80077c: 8b 45 08 mov 0x8(%ebp),%eax + 80077f: ff d0 call *%eax + 800781: eb 0f jmp 800792 + } + else { + putch(ch, putdat); + 800783: 8b 45 0c mov 0xc(%ebp),%eax + 800786: 89 44 24 04 mov %eax,0x4(%esp) + 80078a: 89 1c 24 mov %ebx,(%esp) + 80078d: 8b 45 08 mov 0x8(%ebp),%eax + 800790: ff d0 call *%eax + for (; (ch = *p ++) != '\0' && (precision < 0 || -- precision >= 0); width --) { + 800792: ff 4d e8 decl -0x18(%ebp) + 800795: 89 f0 mov %esi,%eax + 800797: 8d 70 01 lea 0x1(%eax),%esi + 80079a: 0f b6 00 movzbl (%eax),%eax + 80079d: 0f be d8 movsbl %al,%ebx + 8007a0: 85 db test %ebx,%ebx + 8007a2: 74 27 je 8007cb + 8007a4: 83 7d e4 00 cmpl $0x0,-0x1c(%ebp) + 8007a8: 78 b4 js 80075e + 8007aa: ff 4d e4 decl -0x1c(%ebp) + 8007ad: 83 7d e4 00 cmpl $0x0,-0x1c(%ebp) + 8007b1: 79 ab jns 80075e + } + } + for (; width > 0; width --) { + 8007b3: eb 16 jmp 8007cb + putch(' ', putdat); + 8007b5: 8b 45 0c mov 0xc(%ebp),%eax + 8007b8: 89 44 24 04 mov %eax,0x4(%esp) + 8007bc: c7 04 24 20 00 00 00 movl $0x20,(%esp) + 8007c3: 8b 45 08 mov 0x8(%ebp),%eax + 8007c6: ff d0 call *%eax + for (; width > 0; width --) { + 8007c8: ff 4d e8 decl -0x18(%ebp) + 8007cb: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 8007cf: 7f e4 jg 8007b5 + } + break; + 8007d1: e9 6c 01 00 00 jmp 800942 + + // (signed) decimal + case 'd': + num = getint(&ap, lflag); + 8007d6: 8b 45 e0 mov -0x20(%ebp),%eax + 8007d9: 89 44 24 04 mov %eax,0x4(%esp) + 8007dd: 8d 45 14 lea 0x14(%ebp),%eax + 8007e0: 89 04 24 mov %eax,(%esp) + 8007e3: e8 16 fd ff ff call 8004fe + 8007e8: 89 45 f0 mov %eax,-0x10(%ebp) + 8007eb: 89 55 f4 mov %edx,-0xc(%ebp) + if ((long long)num < 0) { + 8007ee: 8b 45 f0 mov -0x10(%ebp),%eax + 8007f1: 8b 55 f4 mov -0xc(%ebp),%edx + 8007f4: 85 d2 test %edx,%edx + 8007f6: 79 26 jns 80081e + putch('-', putdat); + 8007f8: 8b 45 0c mov 0xc(%ebp),%eax + 8007fb: 89 44 24 04 mov %eax,0x4(%esp) + 8007ff: c7 04 24 2d 00 00 00 movl $0x2d,(%esp) + 800806: 8b 45 08 mov 0x8(%ebp),%eax + 800809: ff d0 call *%eax + num = -(long long)num; + 80080b: 8b 45 f0 mov -0x10(%ebp),%eax + 80080e: 8b 55 f4 mov -0xc(%ebp),%edx + 800811: f7 d8 neg %eax + 800813: 83 d2 00 adc $0x0,%edx + 800816: f7 da neg %edx + 800818: 89 45 f0 mov %eax,-0x10(%ebp) + 80081b: 89 55 f4 mov %edx,-0xc(%ebp) + } + base = 10; + 80081e: c7 45 ec 0a 00 00 00 movl $0xa,-0x14(%ebp) + goto number; + 800825: e9 a8 00 00 00 jmp 8008d2 + + // unsigned decimal + case 'u': + num = getuint(&ap, lflag); + 80082a: 8b 45 e0 mov -0x20(%ebp),%eax + 80082d: 89 44 24 04 mov %eax,0x4(%esp) + 800831: 8d 45 14 lea 0x14(%ebp),%eax + 800834: 89 04 24 mov %eax,(%esp) + 800837: e8 73 fc ff ff call 8004af + 80083c: 89 45 f0 mov %eax,-0x10(%ebp) + 80083f: 89 55 f4 mov %edx,-0xc(%ebp) + base = 10; + 800842: c7 45 ec 0a 00 00 00 movl $0xa,-0x14(%ebp) + goto number; + 800849: e9 84 00 00 00 jmp 8008d2 + + // (unsigned) octal + case 'o': + num = getuint(&ap, lflag); + 80084e: 8b 45 e0 mov -0x20(%ebp),%eax + 800851: 89 44 24 04 mov %eax,0x4(%esp) + 800855: 8d 45 14 lea 0x14(%ebp),%eax + 800858: 89 04 24 mov %eax,(%esp) + 80085b: e8 4f fc ff ff call 8004af + 800860: 89 45 f0 mov %eax,-0x10(%ebp) + 800863: 89 55 f4 mov %edx,-0xc(%ebp) + base = 8; + 800866: c7 45 ec 08 00 00 00 movl $0x8,-0x14(%ebp) + goto number; + 80086d: eb 63 jmp 8008d2 + + // pointer + case 'p': + putch('0', putdat); + 80086f: 8b 45 0c mov 0xc(%ebp),%eax + 800872: 89 44 24 04 mov %eax,0x4(%esp) + 800876: c7 04 24 30 00 00 00 movl $0x30,(%esp) + 80087d: 8b 45 08 mov 0x8(%ebp),%eax + 800880: ff d0 call *%eax + putch('x', putdat); + 800882: 8b 45 0c mov 0xc(%ebp),%eax + 800885: 89 44 24 04 mov %eax,0x4(%esp) + 800889: c7 04 24 78 00 00 00 movl $0x78,(%esp) + 800890: 8b 45 08 mov 0x8(%ebp),%eax + 800893: ff d0 call *%eax + num = (unsigned long long)(uintptr_t)va_arg(ap, void *); + 800895: 8b 45 14 mov 0x14(%ebp),%eax + 800898: 8d 50 04 lea 0x4(%eax),%edx + 80089b: 89 55 14 mov %edx,0x14(%ebp) + 80089e: 8b 00 mov (%eax),%eax + 8008a0: 89 45 f0 mov %eax,-0x10(%ebp) + 8008a3: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + base = 16; + 8008aa: c7 45 ec 10 00 00 00 movl $0x10,-0x14(%ebp) + goto number; + 8008b1: eb 1f jmp 8008d2 + + // (unsigned) hexadecimal + case 'x': + num = getuint(&ap, lflag); + 8008b3: 8b 45 e0 mov -0x20(%ebp),%eax + 8008b6: 89 44 24 04 mov %eax,0x4(%esp) + 8008ba: 8d 45 14 lea 0x14(%ebp),%eax + 8008bd: 89 04 24 mov %eax,(%esp) + 8008c0: e8 ea fb ff ff call 8004af + 8008c5: 89 45 f0 mov %eax,-0x10(%ebp) + 8008c8: 89 55 f4 mov %edx,-0xc(%ebp) + base = 16; + 8008cb: c7 45 ec 10 00 00 00 movl $0x10,-0x14(%ebp) + number: + printnum(putch, putdat, num, base, width, padc); + 8008d2: 0f be 55 db movsbl -0x25(%ebp),%edx + 8008d6: 8b 45 ec mov -0x14(%ebp),%eax + 8008d9: 89 54 24 18 mov %edx,0x18(%esp) + 8008dd: 8b 55 e8 mov -0x18(%ebp),%edx + 8008e0: 89 54 24 14 mov %edx,0x14(%esp) + 8008e4: 89 44 24 10 mov %eax,0x10(%esp) + 8008e8: 8b 45 f0 mov -0x10(%ebp),%eax + 8008eb: 8b 55 f4 mov -0xc(%ebp),%edx + 8008ee: 89 44 24 08 mov %eax,0x8(%esp) + 8008f2: 89 54 24 0c mov %edx,0xc(%esp) + 8008f6: 8b 45 0c mov 0xc(%ebp),%eax + 8008f9: 89 44 24 04 mov %eax,0x4(%esp) + 8008fd: 8b 45 08 mov 0x8(%ebp),%eax + 800900: 89 04 24 mov %eax,(%esp) + 800903: e8 a5 fa ff ff call 8003ad + break; + 800908: eb 38 jmp 800942 + + // escaped '%' character + case '%': + putch(ch, putdat); + 80090a: 8b 45 0c mov 0xc(%ebp),%eax + 80090d: 89 44 24 04 mov %eax,0x4(%esp) + 800911: 89 1c 24 mov %ebx,(%esp) + 800914: 8b 45 08 mov 0x8(%ebp),%eax + 800917: ff d0 call *%eax + break; + 800919: eb 27 jmp 800942 + + // unrecognized escape sequence - just print it literally + default: + putch('%', putdat); + 80091b: 8b 45 0c mov 0xc(%ebp),%eax + 80091e: 89 44 24 04 mov %eax,0x4(%esp) + 800922: c7 04 24 25 00 00 00 movl $0x25,(%esp) + 800929: 8b 45 08 mov 0x8(%ebp),%eax + 80092c: ff d0 call *%eax + for (fmt --; fmt[-1] != '%'; fmt --) + 80092e: ff 4d 10 decl 0x10(%ebp) + 800931: eb 03 jmp 800936 + 800933: ff 4d 10 decl 0x10(%ebp) + 800936: 8b 45 10 mov 0x10(%ebp),%eax + 800939: 48 dec %eax + 80093a: 0f b6 00 movzbl (%eax),%eax + 80093d: 3c 25 cmp $0x25,%al + 80093f: 75 f2 jne 800933 + /* do nothing */; + break; + 800941: 90 nop + while (1) { + 800942: e9 37 fc ff ff jmp 80057e + return; + 800947: 90 nop + } + } +} + 800948: 83 c4 40 add $0x40,%esp + 80094b: 5b pop %ebx + 80094c: 5e pop %esi + 80094d: 5d pop %ebp + 80094e: c3 ret + +0080094f : + * sprintputch - 'print' a single character in a buffer + * @ch: the character will be printed + * @b: the buffer to place the character @ch + * */ +static void +sprintputch(int ch, struct sprintbuf *b) { + 80094f: 55 push %ebp + 800950: 89 e5 mov %esp,%ebp + b->cnt ++; + 800952: 8b 45 0c mov 0xc(%ebp),%eax + 800955: 8b 40 08 mov 0x8(%eax),%eax + 800958: 8d 50 01 lea 0x1(%eax),%edx + 80095b: 8b 45 0c mov 0xc(%ebp),%eax + 80095e: 89 50 08 mov %edx,0x8(%eax) + if (b->buf < b->ebuf) { + 800961: 8b 45 0c mov 0xc(%ebp),%eax + 800964: 8b 10 mov (%eax),%edx + 800966: 8b 45 0c mov 0xc(%ebp),%eax + 800969: 8b 40 04 mov 0x4(%eax),%eax + 80096c: 39 c2 cmp %eax,%edx + 80096e: 73 12 jae 800982 + *b->buf ++ = ch; + 800970: 8b 45 0c mov 0xc(%ebp),%eax + 800973: 8b 00 mov (%eax),%eax + 800975: 8d 48 01 lea 0x1(%eax),%ecx + 800978: 8b 55 0c mov 0xc(%ebp),%edx + 80097b: 89 0a mov %ecx,(%edx) + 80097d: 8b 55 08 mov 0x8(%ebp),%edx + 800980: 88 10 mov %dl,(%eax) + } +} + 800982: 90 nop + 800983: 5d pop %ebp + 800984: c3 ret + +00800985 : + * @str: the buffer to place the result into + * @size: the size of buffer, including the trailing null space + * @fmt: the format string to use + * */ +int +snprintf(char *str, size_t size, const char *fmt, ...) { + 800985: 55 push %ebp + 800986: 89 e5 mov %esp,%ebp + 800988: 83 ec 28 sub $0x28,%esp + va_list ap; + int cnt; + va_start(ap, fmt); + 80098b: 8d 45 14 lea 0x14(%ebp),%eax + 80098e: 89 45 f0 mov %eax,-0x10(%ebp) + cnt = vsnprintf(str, size, fmt, ap); + 800991: 8b 45 f0 mov -0x10(%ebp),%eax + 800994: 89 44 24 0c mov %eax,0xc(%esp) + 800998: 8b 45 10 mov 0x10(%ebp),%eax + 80099b: 89 44 24 08 mov %eax,0x8(%esp) + 80099f: 8b 45 0c mov 0xc(%ebp),%eax + 8009a2: 89 44 24 04 mov %eax,0x4(%esp) + 8009a6: 8b 45 08 mov 0x8(%ebp),%eax + 8009a9: 89 04 24 mov %eax,(%esp) + 8009ac: e8 0a 00 00 00 call 8009bb + 8009b1: 89 45 f4 mov %eax,-0xc(%ebp) + va_end(ap); + return cnt; + 8009b4: 8b 45 f4 mov -0xc(%ebp),%eax +} + 8009b7: 89 ec mov %ebp,%esp + 8009b9: 5d pop %ebp + 8009ba: c3 ret + +008009bb : + * + * Call this function if you are already dealing with a va_list. + * Or you probably want snprintf() instead. + * */ +int +vsnprintf(char *str, size_t size, const char *fmt, va_list ap) { + 8009bb: 55 push %ebp + 8009bc: 89 e5 mov %esp,%ebp + 8009be: 83 ec 28 sub $0x28,%esp + struct sprintbuf b = {str, str + size - 1, 0}; + 8009c1: 8b 45 08 mov 0x8(%ebp),%eax + 8009c4: 89 45 ec mov %eax,-0x14(%ebp) + 8009c7: 8b 45 0c mov 0xc(%ebp),%eax + 8009ca: 8d 50 ff lea -0x1(%eax),%edx + 8009cd: 8b 45 08 mov 0x8(%ebp),%eax + 8009d0: 01 d0 add %edx,%eax + 8009d2: 89 45 f0 mov %eax,-0x10(%ebp) + 8009d5: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + if (str == NULL || b.buf > b.ebuf) { + 8009dc: 83 7d 08 00 cmpl $0x0,0x8(%ebp) + 8009e0: 74 0a je 8009ec + 8009e2: 8b 55 ec mov -0x14(%ebp),%edx + 8009e5: 8b 45 f0 mov -0x10(%ebp),%eax + 8009e8: 39 c2 cmp %eax,%edx + 8009ea: 76 07 jbe 8009f3 + return -E_INVAL; + 8009ec: b8 fd ff ff ff mov $0xfffffffd,%eax + 8009f1: eb 2a jmp 800a1d + } + // print the string to the buffer + vprintfmt((void*)sprintputch, &b, fmt, ap); + 8009f3: 8b 45 14 mov 0x14(%ebp),%eax + 8009f6: 89 44 24 0c mov %eax,0xc(%esp) + 8009fa: 8b 45 10 mov 0x10(%ebp),%eax + 8009fd: 89 44 24 08 mov %eax,0x8(%esp) + 800a01: 8d 45 ec lea -0x14(%ebp),%eax + 800a04: 89 44 24 04 mov %eax,0x4(%esp) + 800a08: c7 04 24 4f 09 80 00 movl $0x80094f,(%esp) + 800a0f: e8 62 fb ff ff call 800576 + // null terminate the buffer + *b.buf = '\0'; + 800a14: 8b 45 ec mov -0x14(%ebp),%eax + 800a17: c6 00 00 movb $0x0,(%eax) + return b.cnt; + 800a1a: 8b 45 f4 mov -0xc(%ebp),%eax +} + 800a1d: 89 ec mov %ebp,%esp + 800a1f: 5d pop %ebp + 800a20: c3 ret + +00800a21 : + * rand - returns a pseudo-random integer + * + * The rand() function return a value in the range [0, RAND_MAX]. + * */ +int +rand(void) { + 800a21: 55 push %ebp + 800a22: 89 e5 mov %esp,%ebp + 800a24: 57 push %edi + 800a25: 56 push %esi + 800a26: 53 push %ebx + 800a27: 83 ec 24 sub $0x24,%esp + next = (next * 0x5DEECE66DLL + 0xBLL) & ((1LL << 48) - 1); + 800a2a: a1 00 20 80 00 mov 0x802000,%eax + 800a2f: 8b 15 04 20 80 00 mov 0x802004,%edx + 800a35: 69 fa 6d e6 ec de imul $0xdeece66d,%edx,%edi + 800a3b: 6b f0 05 imul $0x5,%eax,%esi + 800a3e: 01 fe add %edi,%esi + 800a40: bf 6d e6 ec de mov $0xdeece66d,%edi + 800a45: f7 e7 mul %edi + 800a47: 01 d6 add %edx,%esi + 800a49: 89 f2 mov %esi,%edx + 800a4b: 83 c0 0b add $0xb,%eax + 800a4e: 83 d2 00 adc $0x0,%edx + 800a51: 89 c7 mov %eax,%edi + 800a53: 83 e7 ff and $0xffffffff,%edi + 800a56: 89 f9 mov %edi,%ecx + 800a58: 0f b7 da movzwl %dx,%ebx + 800a5b: 89 0d 00 20 80 00 mov %ecx,0x802000 + 800a61: 89 1d 04 20 80 00 mov %ebx,0x802004 + unsigned long long result = (next >> 12); + 800a67: a1 00 20 80 00 mov 0x802000,%eax + 800a6c: 8b 15 04 20 80 00 mov 0x802004,%edx + 800a72: 0f ac d0 0c shrd $0xc,%edx,%eax + 800a76: c1 ea 0c shr $0xc,%edx + 800a79: 89 45 e0 mov %eax,-0x20(%ebp) + 800a7c: 89 55 e4 mov %edx,-0x1c(%ebp) + return (int)do_div(result, RAND_MAX + 1); + 800a7f: c7 45 dc 00 00 00 80 movl $0x80000000,-0x24(%ebp) + 800a86: 8b 45 e0 mov -0x20(%ebp),%eax + 800a89: 8b 55 e4 mov -0x1c(%ebp),%edx + 800a8c: 89 45 d8 mov %eax,-0x28(%ebp) + 800a8f: 89 55 e8 mov %edx,-0x18(%ebp) + 800a92: 8b 45 e8 mov -0x18(%ebp),%eax + 800a95: 89 45 ec mov %eax,-0x14(%ebp) + 800a98: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 800a9c: 74 1c je 800aba + 800a9e: 8b 45 e8 mov -0x18(%ebp),%eax + 800aa1: ba 00 00 00 00 mov $0x0,%edx + 800aa6: f7 75 dc divl -0x24(%ebp) + 800aa9: 89 55 ec mov %edx,-0x14(%ebp) + 800aac: 8b 45 e8 mov -0x18(%ebp),%eax + 800aaf: ba 00 00 00 00 mov $0x0,%edx + 800ab4: f7 75 dc divl -0x24(%ebp) + 800ab7: 89 45 e8 mov %eax,-0x18(%ebp) + 800aba: 8b 45 d8 mov -0x28(%ebp),%eax + 800abd: 8b 55 ec mov -0x14(%ebp),%edx + 800ac0: f7 75 dc divl -0x24(%ebp) + 800ac3: 89 45 d8 mov %eax,-0x28(%ebp) + 800ac6: 89 55 d4 mov %edx,-0x2c(%ebp) + 800ac9: 8b 45 d8 mov -0x28(%ebp),%eax + 800acc: 8b 55 e8 mov -0x18(%ebp),%edx + 800acf: 89 45 e0 mov %eax,-0x20(%ebp) + 800ad2: 89 55 e4 mov %edx,-0x1c(%ebp) + 800ad5: 8b 45 d4 mov -0x2c(%ebp),%eax +} + 800ad8: 83 c4 24 add $0x24,%esp + 800adb: 5b pop %ebx + 800adc: 5e pop %esi + 800add: 5f pop %edi + 800ade: 5d pop %ebp + 800adf: c3 ret + +00800ae0 : +/* * + * srand - seed the random number generator with the given number + * @seed: the required seed number + * */ +void +srand(unsigned int seed) { + 800ae0: 55 push %ebp + 800ae1: 89 e5 mov %esp,%ebp + next = seed; + 800ae3: 8b 45 08 mov 0x8(%ebp),%eax + 800ae6: ba 00 00 00 00 mov $0x0,%edx + 800aeb: a3 00 20 80 00 mov %eax,0x802000 + 800af0: 89 15 04 20 80 00 mov %edx,0x802004 +} + 800af6: 90 nop + 800af7: 5d pop %ebp + 800af8: c3 ret + +00800af9 : + * @s: the input string + * + * The strlen() function returns the length of string @s. + * */ +size_t +strlen(const char *s) { + 800af9: 55 push %ebp + 800afa: 89 e5 mov %esp,%ebp + 800afc: 83 ec 10 sub $0x10,%esp + size_t cnt = 0; + 800aff: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + while (*s ++ != '\0') { + 800b06: eb 03 jmp 800b0b + cnt ++; + 800b08: ff 45 fc incl -0x4(%ebp) + while (*s ++ != '\0') { + 800b0b: 8b 45 08 mov 0x8(%ebp),%eax + 800b0e: 8d 50 01 lea 0x1(%eax),%edx + 800b11: 89 55 08 mov %edx,0x8(%ebp) + 800b14: 0f b6 00 movzbl (%eax),%eax + 800b17: 84 c0 test %al,%al + 800b19: 75 ed jne 800b08 + } + return cnt; + 800b1b: 8b 45 fc mov -0x4(%ebp),%eax +} + 800b1e: 89 ec mov %ebp,%esp + 800b20: 5d pop %ebp + 800b21: c3 ret + +00800b22 : + * The return value is strlen(s), if that is less than @len, or + * @len if there is no '\0' character among the first @len characters + * pointed by @s. + * */ +size_t +strnlen(const char *s, size_t len) { + 800b22: 55 push %ebp + 800b23: 89 e5 mov %esp,%ebp + 800b25: 83 ec 10 sub $0x10,%esp + size_t cnt = 0; + 800b28: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + while (cnt < len && *s ++ != '\0') { + 800b2f: eb 03 jmp 800b34 + cnt ++; + 800b31: ff 45 fc incl -0x4(%ebp) + while (cnt < len && *s ++ != '\0') { + 800b34: 8b 45 fc mov -0x4(%ebp),%eax + 800b37: 3b 45 0c cmp 0xc(%ebp),%eax + 800b3a: 73 10 jae 800b4c + 800b3c: 8b 45 08 mov 0x8(%ebp),%eax + 800b3f: 8d 50 01 lea 0x1(%eax),%edx + 800b42: 89 55 08 mov %edx,0x8(%ebp) + 800b45: 0f b6 00 movzbl (%eax),%eax + 800b48: 84 c0 test %al,%al + 800b4a: 75 e5 jne 800b31 + } + return cnt; + 800b4c: 8b 45 fc mov -0x4(%ebp),%eax +} + 800b4f: 89 ec mov %ebp,%esp + 800b51: 5d pop %ebp + 800b52: c3 ret + +00800b53 : + * To avoid overflows, the size of array pointed by @dst should be long enough to + * contain the same string as @src (including the terminating null character), and + * should not overlap in memory with @src. + * */ +char * +strcpy(char *dst, const char *src) { + 800b53: 55 push %ebp + 800b54: 89 e5 mov %esp,%ebp + 800b56: 57 push %edi + 800b57: 56 push %esi + 800b58: 83 ec 20 sub $0x20,%esp + 800b5b: 8b 45 08 mov 0x8(%ebp),%eax + 800b5e: 89 45 f4 mov %eax,-0xc(%ebp) + 800b61: 8b 45 0c mov 0xc(%ebp),%eax + 800b64: 89 45 f0 mov %eax,-0x10(%ebp) +#ifndef __HAVE_ARCH_STRCPY +#define __HAVE_ARCH_STRCPY +static inline char * +__strcpy(char *dst, const char *src) { + int d0, d1, d2; + asm volatile ( + 800b67: 8b 55 f0 mov -0x10(%ebp),%edx + 800b6a: 8b 45 f4 mov -0xc(%ebp),%eax + 800b6d: 89 d1 mov %edx,%ecx + 800b6f: 89 c2 mov %eax,%edx + 800b71: 89 ce mov %ecx,%esi + 800b73: 89 d7 mov %edx,%edi + 800b75: ac lods %ds:(%esi),%al + 800b76: aa stos %al,%es:(%edi) + 800b77: 84 c0 test %al,%al + 800b79: 75 fa jne 800b75 + 800b7b: 89 fa mov %edi,%edx + 800b7d: 89 f1 mov %esi,%ecx + 800b7f: 89 4d ec mov %ecx,-0x14(%ebp) + 800b82: 89 55 e8 mov %edx,-0x18(%ebp) + 800b85: 89 45 e4 mov %eax,-0x1c(%ebp) + "stosb;" + "testb %%al, %%al;" + "jne 1b;" + : "=&S" (d0), "=&D" (d1), "=&a" (d2) + : "0" (src), "1" (dst) : "memory"); + return dst; + 800b88: 8b 45 f4 mov -0xc(%ebp),%eax + char *p = dst; + while ((*p ++ = *src ++) != '\0') + /* nothing */; + return dst; +#endif /* __HAVE_ARCH_STRCPY */ +} + 800b8b: 83 c4 20 add $0x20,%esp + 800b8e: 5e pop %esi + 800b8f: 5f pop %edi + 800b90: 5d pop %ebp + 800b91: c3 ret + +00800b92 : + * @len: maximum number of characters to be copied from @src + * + * The return value is @dst + * */ +char * +strncpy(char *dst, const char *src, size_t len) { + 800b92: 55 push %ebp + 800b93: 89 e5 mov %esp,%ebp + 800b95: 83 ec 10 sub $0x10,%esp + char *p = dst; + 800b98: 8b 45 08 mov 0x8(%ebp),%eax + 800b9b: 89 45 fc mov %eax,-0x4(%ebp) + while (len > 0) { + 800b9e: eb 1e jmp 800bbe + if ((*p = *src) != '\0') { + 800ba0: 8b 45 0c mov 0xc(%ebp),%eax + 800ba3: 0f b6 10 movzbl (%eax),%edx + 800ba6: 8b 45 fc mov -0x4(%ebp),%eax + 800ba9: 88 10 mov %dl,(%eax) + 800bab: 8b 45 fc mov -0x4(%ebp),%eax + 800bae: 0f b6 00 movzbl (%eax),%eax + 800bb1: 84 c0 test %al,%al + 800bb3: 74 03 je 800bb8 + src ++; + 800bb5: ff 45 0c incl 0xc(%ebp) + } + p ++, len --; + 800bb8: ff 45 fc incl -0x4(%ebp) + 800bbb: ff 4d 10 decl 0x10(%ebp) + while (len > 0) { + 800bbe: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800bc2: 75 dc jne 800ba0 + } + return dst; + 800bc4: 8b 45 08 mov 0x8(%ebp),%eax +} + 800bc7: 89 ec mov %ebp,%esp + 800bc9: 5d pop %ebp + 800bca: c3 ret + +00800bcb : + * - A value greater than zero indicates that the first character that does + * not match has a greater value in @s1 than in @s2; + * - And a value less than zero indicates the opposite. + * */ +int +strcmp(const char *s1, const char *s2) { + 800bcb: 55 push %ebp + 800bcc: 89 e5 mov %esp,%ebp + 800bce: 57 push %edi + 800bcf: 56 push %esi + 800bd0: 83 ec 20 sub $0x20,%esp + 800bd3: 8b 45 08 mov 0x8(%ebp),%eax + 800bd6: 89 45 f4 mov %eax,-0xc(%ebp) + 800bd9: 8b 45 0c mov 0xc(%ebp),%eax + 800bdc: 89 45 f0 mov %eax,-0x10(%ebp) + asm volatile ( + 800bdf: 8b 55 f4 mov -0xc(%ebp),%edx + 800be2: 8b 45 f0 mov -0x10(%ebp),%eax + 800be5: 89 d1 mov %edx,%ecx + 800be7: 89 c2 mov %eax,%edx + 800be9: 89 ce mov %ecx,%esi + 800beb: 89 d7 mov %edx,%edi + 800bed: ac lods %ds:(%esi),%al + 800bee: ae scas %es:(%edi),%al + 800bef: 75 08 jne 800bf9 + 800bf1: 84 c0 test %al,%al + 800bf3: 75 f8 jne 800bed + 800bf5: 31 c0 xor %eax,%eax + 800bf7: eb 04 jmp 800bfd + 800bf9: 19 c0 sbb %eax,%eax + 800bfb: 0c 01 or $0x1,%al + 800bfd: 89 fa mov %edi,%edx + 800bff: 89 f1 mov %esi,%ecx + 800c01: 89 45 ec mov %eax,-0x14(%ebp) + 800c04: 89 4d e8 mov %ecx,-0x18(%ebp) + 800c07: 89 55 e4 mov %edx,-0x1c(%ebp) + return ret; + 800c0a: 8b 45 ec mov -0x14(%ebp),%eax + while (*s1 != '\0' && *s1 == *s2) { + s1 ++, s2 ++; + } + return (int)((unsigned char)*s1 - (unsigned char)*s2); +#endif /* __HAVE_ARCH_STRCMP */ +} + 800c0d: 83 c4 20 add $0x20,%esp + 800c10: 5e pop %esi + 800c11: 5f pop %edi + 800c12: 5d pop %ebp + 800c13: c3 ret + +00800c14 : + * they are equal to each other, it continues with the following pairs until + * the characters differ, until a terminating null-character is reached, or + * until @n characters match in both strings, whichever happens first. + * */ +int +strncmp(const char *s1, const char *s2, size_t n) { + 800c14: 55 push %ebp + 800c15: 89 e5 mov %esp,%ebp + while (n > 0 && *s1 != '\0' && *s1 == *s2) { + 800c17: eb 09 jmp 800c22 + n --, s1 ++, s2 ++; + 800c19: ff 4d 10 decl 0x10(%ebp) + 800c1c: ff 45 08 incl 0x8(%ebp) + 800c1f: ff 45 0c incl 0xc(%ebp) + while (n > 0 && *s1 != '\0' && *s1 == *s2) { + 800c22: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800c26: 74 1a je 800c42 + 800c28: 8b 45 08 mov 0x8(%ebp),%eax + 800c2b: 0f b6 00 movzbl (%eax),%eax + 800c2e: 84 c0 test %al,%al + 800c30: 74 10 je 800c42 + 800c32: 8b 45 08 mov 0x8(%ebp),%eax + 800c35: 0f b6 10 movzbl (%eax),%edx + 800c38: 8b 45 0c mov 0xc(%ebp),%eax + 800c3b: 0f b6 00 movzbl (%eax),%eax + 800c3e: 38 c2 cmp %al,%dl + 800c40: 74 d7 je 800c19 + } + return (n == 0) ? 0 : (int)((unsigned char)*s1 - (unsigned char)*s2); + 800c42: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800c46: 74 18 je 800c60 + 800c48: 8b 45 08 mov 0x8(%ebp),%eax + 800c4b: 0f b6 00 movzbl (%eax),%eax + 800c4e: 0f b6 d0 movzbl %al,%edx + 800c51: 8b 45 0c mov 0xc(%ebp),%eax + 800c54: 0f b6 00 movzbl (%eax),%eax + 800c57: 0f b6 c8 movzbl %al,%ecx + 800c5a: 89 d0 mov %edx,%eax + 800c5c: 29 c8 sub %ecx,%eax + 800c5e: eb 05 jmp 800c65 + 800c60: b8 00 00 00 00 mov $0x0,%eax +} + 800c65: 5d pop %ebp + 800c66: c3 ret + +00800c67 : + * + * The strchr() function returns a pointer to the first occurrence of + * character in @s. If the value is not found, the function returns 'NULL'. + * */ +char * +strchr(const char *s, char c) { + 800c67: 55 push %ebp + 800c68: 89 e5 mov %esp,%ebp + 800c6a: 83 ec 04 sub $0x4,%esp + 800c6d: 8b 45 0c mov 0xc(%ebp),%eax + 800c70: 88 45 fc mov %al,-0x4(%ebp) + while (*s != '\0') { + 800c73: eb 13 jmp 800c88 + if (*s == c) { + 800c75: 8b 45 08 mov 0x8(%ebp),%eax + 800c78: 0f b6 00 movzbl (%eax),%eax + 800c7b: 38 45 fc cmp %al,-0x4(%ebp) + 800c7e: 75 05 jne 800c85 + return (char *)s; + 800c80: 8b 45 08 mov 0x8(%ebp),%eax + 800c83: eb 12 jmp 800c97 + } + s ++; + 800c85: ff 45 08 incl 0x8(%ebp) + while (*s != '\0') { + 800c88: 8b 45 08 mov 0x8(%ebp),%eax + 800c8b: 0f b6 00 movzbl (%eax),%eax + 800c8e: 84 c0 test %al,%al + 800c90: 75 e3 jne 800c75 + } + return NULL; + 800c92: b8 00 00 00 00 mov $0x0,%eax +} + 800c97: 89 ec mov %ebp,%esp + 800c99: 5d pop %ebp + 800c9a: c3 ret + +00800c9b : + * The strfind() function is like strchr() except that if @c is + * not found in @s, then it returns a pointer to the null byte at the + * end of @s, rather than 'NULL'. + * */ +char * +strfind(const char *s, char c) { + 800c9b: 55 push %ebp + 800c9c: 89 e5 mov %esp,%ebp + 800c9e: 83 ec 04 sub $0x4,%esp + 800ca1: 8b 45 0c mov 0xc(%ebp),%eax + 800ca4: 88 45 fc mov %al,-0x4(%ebp) + while (*s != '\0') { + 800ca7: eb 0e jmp 800cb7 + if (*s == c) { + 800ca9: 8b 45 08 mov 0x8(%ebp),%eax + 800cac: 0f b6 00 movzbl (%eax),%eax + 800caf: 38 45 fc cmp %al,-0x4(%ebp) + 800cb2: 74 0f je 800cc3 + break; + } + s ++; + 800cb4: ff 45 08 incl 0x8(%ebp) + while (*s != '\0') { + 800cb7: 8b 45 08 mov 0x8(%ebp),%eax + 800cba: 0f b6 00 movzbl (%eax),%eax + 800cbd: 84 c0 test %al,%al + 800cbf: 75 e8 jne 800ca9 + 800cc1: eb 01 jmp 800cc4 + break; + 800cc3: 90 nop + } + return (char *)s; + 800cc4: 8b 45 08 mov 0x8(%ebp),%eax +} + 800cc7: 89 ec mov %ebp,%esp + 800cc9: 5d pop %ebp + 800cca: c3 ret + +00800ccb : + * an optional "0x" or "0X" prefix. + * + * The strtol() function returns the converted integral number as a long int value. + * */ +long +strtol(const char *s, char **endptr, int base) { + 800ccb: 55 push %ebp + 800ccc: 89 e5 mov %esp,%ebp + 800cce: 83 ec 10 sub $0x10,%esp + int neg = 0; + 800cd1: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + long val = 0; + 800cd8: c7 45 f8 00 00 00 00 movl $0x0,-0x8(%ebp) + + // gobble initial whitespace + while (*s == ' ' || *s == '\t') { + 800cdf: eb 03 jmp 800ce4 + s ++; + 800ce1: ff 45 08 incl 0x8(%ebp) + while (*s == ' ' || *s == '\t') { + 800ce4: 8b 45 08 mov 0x8(%ebp),%eax + 800ce7: 0f b6 00 movzbl (%eax),%eax + 800cea: 3c 20 cmp $0x20,%al + 800cec: 74 f3 je 800ce1 + 800cee: 8b 45 08 mov 0x8(%ebp),%eax + 800cf1: 0f b6 00 movzbl (%eax),%eax + 800cf4: 3c 09 cmp $0x9,%al + 800cf6: 74 e9 je 800ce1 + } + + // plus/minus sign + if (*s == '+') { + 800cf8: 8b 45 08 mov 0x8(%ebp),%eax + 800cfb: 0f b6 00 movzbl (%eax),%eax + 800cfe: 3c 2b cmp $0x2b,%al + 800d00: 75 05 jne 800d07 + s ++; + 800d02: ff 45 08 incl 0x8(%ebp) + 800d05: eb 14 jmp 800d1b + } + else if (*s == '-') { + 800d07: 8b 45 08 mov 0x8(%ebp),%eax + 800d0a: 0f b6 00 movzbl (%eax),%eax + 800d0d: 3c 2d cmp $0x2d,%al + 800d0f: 75 0a jne 800d1b + s ++, neg = 1; + 800d11: ff 45 08 incl 0x8(%ebp) + 800d14: c7 45 fc 01 00 00 00 movl $0x1,-0x4(%ebp) + } + + // hex or octal base prefix + if ((base == 0 || base == 16) && (s[0] == '0' && s[1] == 'x')) { + 800d1b: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800d1f: 74 06 je 800d27 + 800d21: 83 7d 10 10 cmpl $0x10,0x10(%ebp) + 800d25: 75 22 jne 800d49 + 800d27: 8b 45 08 mov 0x8(%ebp),%eax + 800d2a: 0f b6 00 movzbl (%eax),%eax + 800d2d: 3c 30 cmp $0x30,%al + 800d2f: 75 18 jne 800d49 + 800d31: 8b 45 08 mov 0x8(%ebp),%eax + 800d34: 40 inc %eax + 800d35: 0f b6 00 movzbl (%eax),%eax + 800d38: 3c 78 cmp $0x78,%al + 800d3a: 75 0d jne 800d49 + s += 2, base = 16; + 800d3c: 83 45 08 02 addl $0x2,0x8(%ebp) + 800d40: c7 45 10 10 00 00 00 movl $0x10,0x10(%ebp) + 800d47: eb 29 jmp 800d72 + } + else if (base == 0 && s[0] == '0') { + 800d49: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800d4d: 75 16 jne 800d65 + 800d4f: 8b 45 08 mov 0x8(%ebp),%eax + 800d52: 0f b6 00 movzbl (%eax),%eax + 800d55: 3c 30 cmp $0x30,%al + 800d57: 75 0c jne 800d65 + s ++, base = 8; + 800d59: ff 45 08 incl 0x8(%ebp) + 800d5c: c7 45 10 08 00 00 00 movl $0x8,0x10(%ebp) + 800d63: eb 0d jmp 800d72 + } + else if (base == 0) { + 800d65: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800d69: 75 07 jne 800d72 + base = 10; + 800d6b: c7 45 10 0a 00 00 00 movl $0xa,0x10(%ebp) + + // digits + while (1) { + int dig; + + if (*s >= '0' && *s <= '9') { + 800d72: 8b 45 08 mov 0x8(%ebp),%eax + 800d75: 0f b6 00 movzbl (%eax),%eax + 800d78: 3c 2f cmp $0x2f,%al + 800d7a: 7e 1b jle 800d97 + 800d7c: 8b 45 08 mov 0x8(%ebp),%eax + 800d7f: 0f b6 00 movzbl (%eax),%eax + 800d82: 3c 39 cmp $0x39,%al + 800d84: 7f 11 jg 800d97 + dig = *s - '0'; + 800d86: 8b 45 08 mov 0x8(%ebp),%eax + 800d89: 0f b6 00 movzbl (%eax),%eax + 800d8c: 0f be c0 movsbl %al,%eax + 800d8f: 83 e8 30 sub $0x30,%eax + 800d92: 89 45 f4 mov %eax,-0xc(%ebp) + 800d95: eb 48 jmp 800ddf + } + else if (*s >= 'a' && *s <= 'z') { + 800d97: 8b 45 08 mov 0x8(%ebp),%eax + 800d9a: 0f b6 00 movzbl (%eax),%eax + 800d9d: 3c 60 cmp $0x60,%al + 800d9f: 7e 1b jle 800dbc + 800da1: 8b 45 08 mov 0x8(%ebp),%eax + 800da4: 0f b6 00 movzbl (%eax),%eax + 800da7: 3c 7a cmp $0x7a,%al + 800da9: 7f 11 jg 800dbc + dig = *s - 'a' + 10; + 800dab: 8b 45 08 mov 0x8(%ebp),%eax + 800dae: 0f b6 00 movzbl (%eax),%eax + 800db1: 0f be c0 movsbl %al,%eax + 800db4: 83 e8 57 sub $0x57,%eax + 800db7: 89 45 f4 mov %eax,-0xc(%ebp) + 800dba: eb 23 jmp 800ddf + } + else if (*s >= 'A' && *s <= 'Z') { + 800dbc: 8b 45 08 mov 0x8(%ebp),%eax + 800dbf: 0f b6 00 movzbl (%eax),%eax + 800dc2: 3c 40 cmp $0x40,%al + 800dc4: 7e 3b jle 800e01 + 800dc6: 8b 45 08 mov 0x8(%ebp),%eax + 800dc9: 0f b6 00 movzbl (%eax),%eax + 800dcc: 3c 5a cmp $0x5a,%al + 800dce: 7f 31 jg 800e01 + dig = *s - 'A' + 10; + 800dd0: 8b 45 08 mov 0x8(%ebp),%eax + 800dd3: 0f b6 00 movzbl (%eax),%eax + 800dd6: 0f be c0 movsbl %al,%eax + 800dd9: 83 e8 37 sub $0x37,%eax + 800ddc: 89 45 f4 mov %eax,-0xc(%ebp) + } + else { + break; + } + if (dig >= base) { + 800ddf: 8b 45 f4 mov -0xc(%ebp),%eax + 800de2: 3b 45 10 cmp 0x10(%ebp),%eax + 800de5: 7d 19 jge 800e00 + break; + } + s ++, val = (val * base) + dig; + 800de7: ff 45 08 incl 0x8(%ebp) + 800dea: 8b 45 f8 mov -0x8(%ebp),%eax + 800ded: 0f af 45 10 imul 0x10(%ebp),%eax + 800df1: 89 c2 mov %eax,%edx + 800df3: 8b 45 f4 mov -0xc(%ebp),%eax + 800df6: 01 d0 add %edx,%eax + 800df8: 89 45 f8 mov %eax,-0x8(%ebp) + while (1) { + 800dfb: e9 72 ff ff ff jmp 800d72 + break; + 800e00: 90 nop + // we don't properly detect overflow! + } + + if (endptr) { + 800e01: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) + 800e05: 74 08 je 800e0f + *endptr = (char *) s; + 800e07: 8b 45 0c mov 0xc(%ebp),%eax + 800e0a: 8b 55 08 mov 0x8(%ebp),%edx + 800e0d: 89 10 mov %edx,(%eax) + } + return (neg ? -val : val); + 800e0f: 83 7d fc 00 cmpl $0x0,-0x4(%ebp) + 800e13: 74 07 je 800e1c + 800e15: 8b 45 f8 mov -0x8(%ebp),%eax + 800e18: f7 d8 neg %eax + 800e1a: eb 03 jmp 800e1f + 800e1c: 8b 45 f8 mov -0x8(%ebp),%eax +} + 800e1f: 89 ec mov %ebp,%esp + 800e21: 5d pop %ebp + 800e22: c3 ret + +00800e23 : + * @n: number of bytes to be set to the value + * + * The memset() function returns @s. + * */ +void * +memset(void *s, char c, size_t n) { + 800e23: 55 push %ebp + 800e24: 89 e5 mov %esp,%ebp + 800e26: 83 ec 28 sub $0x28,%esp + 800e29: 89 7d fc mov %edi,-0x4(%ebp) + 800e2c: 8b 45 0c mov 0xc(%ebp),%eax + 800e2f: 88 45 d8 mov %al,-0x28(%ebp) +#ifdef __HAVE_ARCH_MEMSET + return __memset(s, c, n); + 800e32: 0f be 55 d8 movsbl -0x28(%ebp),%edx + 800e36: 8b 45 08 mov 0x8(%ebp),%eax + 800e39: 89 45 f8 mov %eax,-0x8(%ebp) + 800e3c: 88 55 f7 mov %dl,-0x9(%ebp) + 800e3f: 8b 45 10 mov 0x10(%ebp),%eax + 800e42: 89 45 f0 mov %eax,-0x10(%ebp) +#ifndef __HAVE_ARCH_MEMSET +#define __HAVE_ARCH_MEMSET +static inline void * +__memset(void *s, char c, size_t n) { + int d0, d1; + asm volatile ( + 800e45: 8b 4d f0 mov -0x10(%ebp),%ecx + 800e48: 0f b6 45 f7 movzbl -0x9(%ebp),%eax + 800e4c: 8b 55 f8 mov -0x8(%ebp),%edx + 800e4f: 89 d7 mov %edx,%edi + 800e51: f3 aa rep stos %al,%es:(%edi) + 800e53: 89 fa mov %edi,%edx + 800e55: 89 4d ec mov %ecx,-0x14(%ebp) + 800e58: 89 55 e8 mov %edx,-0x18(%ebp) + "rep; stosb;" + : "=&c" (d0), "=&D" (d1) + : "0" (n), "a" (c), "1" (s) + : "memory"); + return s; + 800e5b: 8b 45 f8 mov -0x8(%ebp),%eax + while (n -- > 0) { + *p ++ = c; + } + return s; +#endif /* __HAVE_ARCH_MEMSET */ +} + 800e5e: 8b 7d fc mov -0x4(%ebp),%edi + 800e61: 89 ec mov %ebp,%esp + 800e63: 5d pop %ebp + 800e64: c3 ret + +00800e65 : + * @n: number of bytes to copy + * + * The memmove() function returns @dst. + * */ +void * +memmove(void *dst, const void *src, size_t n) { + 800e65: 55 push %ebp + 800e66: 89 e5 mov %esp,%ebp + 800e68: 57 push %edi + 800e69: 56 push %esi + 800e6a: 53 push %ebx + 800e6b: 83 ec 30 sub $0x30,%esp + 800e6e: 8b 45 08 mov 0x8(%ebp),%eax + 800e71: 89 45 f0 mov %eax,-0x10(%ebp) + 800e74: 8b 45 0c mov 0xc(%ebp),%eax + 800e77: 89 45 ec mov %eax,-0x14(%ebp) + 800e7a: 8b 45 10 mov 0x10(%ebp),%eax + 800e7d: 89 45 e8 mov %eax,-0x18(%ebp) + +#ifndef __HAVE_ARCH_MEMMOVE +#define __HAVE_ARCH_MEMMOVE +static inline void * +__memmove(void *dst, const void *src, size_t n) { + if (dst < src) { + 800e80: 8b 45 f0 mov -0x10(%ebp),%eax + 800e83: 3b 45 ec cmp -0x14(%ebp),%eax + 800e86: 73 42 jae 800eca + 800e88: 8b 45 f0 mov -0x10(%ebp),%eax + 800e8b: 89 45 e4 mov %eax,-0x1c(%ebp) + 800e8e: 8b 45 ec mov -0x14(%ebp),%eax + 800e91: 89 45 e0 mov %eax,-0x20(%ebp) + 800e94: 8b 45 e8 mov -0x18(%ebp),%eax + 800e97: 89 45 dc mov %eax,-0x24(%ebp) + "andl $3, %%ecx;" + "jz 1f;" + "rep; movsb;" + "1:" + : "=&c" (d0), "=&D" (d1), "=&S" (d2) + : "0" (n / 4), "g" (n), "1" (dst), "2" (src) + 800e9a: 8b 45 dc mov -0x24(%ebp),%eax + 800e9d: c1 e8 02 shr $0x2,%eax + 800ea0: 89 c1 mov %eax,%ecx + asm volatile ( + 800ea2: 8b 55 e4 mov -0x1c(%ebp),%edx + 800ea5: 8b 45 e0 mov -0x20(%ebp),%eax + 800ea8: 89 d7 mov %edx,%edi + 800eaa: 89 c6 mov %eax,%esi + 800eac: f3 a5 rep movsl %ds:(%esi),%es:(%edi) + 800eae: 8b 4d dc mov -0x24(%ebp),%ecx + 800eb1: 83 e1 03 and $0x3,%ecx + 800eb4: 74 02 je 800eb8 + 800eb6: f3 a4 rep movsb %ds:(%esi),%es:(%edi) + 800eb8: 89 f0 mov %esi,%eax + 800eba: 89 fa mov %edi,%edx + 800ebc: 89 4d d8 mov %ecx,-0x28(%ebp) + 800ebf: 89 55 d4 mov %edx,-0x2c(%ebp) + 800ec2: 89 45 d0 mov %eax,-0x30(%ebp) + : "memory"); + return dst; + 800ec5: 8b 45 e4 mov -0x1c(%ebp),%eax + return __memcpy(dst, src, n); + 800ec8: eb 36 jmp 800f00 + : "0" (n), "1" (n - 1 + src), "2" (n - 1 + dst) + 800eca: 8b 45 e8 mov -0x18(%ebp),%eax + 800ecd: 8d 50 ff lea -0x1(%eax),%edx + 800ed0: 8b 45 ec mov -0x14(%ebp),%eax + 800ed3: 01 c2 add %eax,%edx + 800ed5: 8b 45 e8 mov -0x18(%ebp),%eax + 800ed8: 8d 48 ff lea -0x1(%eax),%ecx + 800edb: 8b 45 f0 mov -0x10(%ebp),%eax + 800ede: 8d 1c 01 lea (%ecx,%eax,1),%ebx + asm volatile ( + 800ee1: 8b 45 e8 mov -0x18(%ebp),%eax + 800ee4: 89 c1 mov %eax,%ecx + 800ee6: 89 d8 mov %ebx,%eax + 800ee8: 89 d6 mov %edx,%esi + 800eea: 89 c7 mov %eax,%edi + 800eec: fd std + 800eed: f3 a4 rep movsb %ds:(%esi),%es:(%edi) + 800eef: fc cld + 800ef0: 89 f8 mov %edi,%eax + 800ef2: 89 f2 mov %esi,%edx + 800ef4: 89 4d cc mov %ecx,-0x34(%ebp) + 800ef7: 89 55 c8 mov %edx,-0x38(%ebp) + 800efa: 89 45 c4 mov %eax,-0x3c(%ebp) + return dst; + 800efd: 8b 45 f0 mov -0x10(%ebp),%eax + *d ++ = *s ++; + } + } + return dst; +#endif /* __HAVE_ARCH_MEMMOVE */ +} + 800f00: 83 c4 30 add $0x30,%esp + 800f03: 5b pop %ebx + 800f04: 5e pop %esi + 800f05: 5f pop %edi + 800f06: 5d pop %ebp + 800f07: c3 ret + +00800f08 : + * it always copies exactly @n bytes. To avoid overflows, the size of arrays pointed + * by both @src and @dst, should be at least @n bytes, and should not overlap + * (for overlapping memory area, memmove is a safer approach). + * */ +void * +memcpy(void *dst, const void *src, size_t n) { + 800f08: 55 push %ebp + 800f09: 89 e5 mov %esp,%ebp + 800f0b: 57 push %edi + 800f0c: 56 push %esi + 800f0d: 83 ec 20 sub $0x20,%esp + 800f10: 8b 45 08 mov 0x8(%ebp),%eax + 800f13: 89 45 f4 mov %eax,-0xc(%ebp) + 800f16: 8b 45 0c mov 0xc(%ebp),%eax + 800f19: 89 45 f0 mov %eax,-0x10(%ebp) + 800f1c: 8b 45 10 mov 0x10(%ebp),%eax + 800f1f: 89 45 ec mov %eax,-0x14(%ebp) + : "0" (n / 4), "g" (n), "1" (dst), "2" (src) + 800f22: 8b 45 ec mov -0x14(%ebp),%eax + 800f25: c1 e8 02 shr $0x2,%eax + 800f28: 89 c1 mov %eax,%ecx + asm volatile ( + 800f2a: 8b 55 f4 mov -0xc(%ebp),%edx + 800f2d: 8b 45 f0 mov -0x10(%ebp),%eax + 800f30: 89 d7 mov %edx,%edi + 800f32: 89 c6 mov %eax,%esi + 800f34: f3 a5 rep movsl %ds:(%esi),%es:(%edi) + 800f36: 8b 4d ec mov -0x14(%ebp),%ecx + 800f39: 83 e1 03 and $0x3,%ecx + 800f3c: 74 02 je 800f40 + 800f3e: f3 a4 rep movsb %ds:(%esi),%es:(%edi) + 800f40: 89 f0 mov %esi,%eax + 800f42: 89 fa mov %edi,%edx + 800f44: 89 4d e8 mov %ecx,-0x18(%ebp) + 800f47: 89 55 e4 mov %edx,-0x1c(%ebp) + 800f4a: 89 45 e0 mov %eax,-0x20(%ebp) + return dst; + 800f4d: 8b 45 f4 mov -0xc(%ebp),%eax + while (n -- > 0) { + *d ++ = *s ++; + } + return dst; +#endif /* __HAVE_ARCH_MEMCPY */ +} + 800f50: 83 c4 20 add $0x20,%esp + 800f53: 5e pop %esi + 800f54: 5f pop %edi + 800f55: 5d pop %ebp + 800f56: c3 ret + +00800f57 : + * match in both memory blocks has a greater value in @v1 than in @v2 + * as if evaluated as unsigned char values; + * - And a value less than zero indicates the opposite. + * */ +int +memcmp(const void *v1, const void *v2, size_t n) { + 800f57: 55 push %ebp + 800f58: 89 e5 mov %esp,%ebp + 800f5a: 83 ec 10 sub $0x10,%esp + const char *s1 = (const char *)v1; + 800f5d: 8b 45 08 mov 0x8(%ebp),%eax + 800f60: 89 45 fc mov %eax,-0x4(%ebp) + const char *s2 = (const char *)v2; + 800f63: 8b 45 0c mov 0xc(%ebp),%eax + 800f66: 89 45 f8 mov %eax,-0x8(%ebp) + while (n -- > 0) { + 800f69: eb 2e jmp 800f99 + if (*s1 != *s2) { + 800f6b: 8b 45 fc mov -0x4(%ebp),%eax + 800f6e: 0f b6 10 movzbl (%eax),%edx + 800f71: 8b 45 f8 mov -0x8(%ebp),%eax + 800f74: 0f b6 00 movzbl (%eax),%eax + 800f77: 38 c2 cmp %al,%dl + 800f79: 74 18 je 800f93 + return (int)((unsigned char)*s1 - (unsigned char)*s2); + 800f7b: 8b 45 fc mov -0x4(%ebp),%eax + 800f7e: 0f b6 00 movzbl (%eax),%eax + 800f81: 0f b6 d0 movzbl %al,%edx + 800f84: 8b 45 f8 mov -0x8(%ebp),%eax + 800f87: 0f b6 00 movzbl (%eax),%eax + 800f8a: 0f b6 c8 movzbl %al,%ecx + 800f8d: 89 d0 mov %edx,%eax + 800f8f: 29 c8 sub %ecx,%eax + 800f91: eb 18 jmp 800fab + } + s1 ++, s2 ++; + 800f93: ff 45 fc incl -0x4(%ebp) + 800f96: ff 45 f8 incl -0x8(%ebp) + while (n -- > 0) { + 800f99: 8b 45 10 mov 0x10(%ebp),%eax + 800f9c: 8d 50 ff lea -0x1(%eax),%edx + 800f9f: 89 55 10 mov %edx,0x10(%ebp) + 800fa2: 85 c0 test %eax,%eax + 800fa4: 75 c5 jne 800f6b + } + return 0; + 800fa6: b8 00 00 00 00 mov $0x0,%eax +} + 800fab: 89 ec mov %ebp,%esp + 800fad: 5d pop %ebp + 800fae: c3 ret + +00800faf
: +#include +#include + +int +main(void) { + 800faf: 55 push %ebp + 800fb0: 89 e5 mov %esp,%ebp + 800fb2: 83 e4 f0 and $0xfffffff0,%esp + 800fb5: 83 ec 10 sub $0x10,%esp + cprintf("I read %08x from 0xfac00000!\n", *(unsigned *)0xfac00000); + 800fb8: b8 00 00 c0 fa mov $0xfac00000,%eax + 800fbd: 8b 00 mov (%eax),%eax + 800fbf: 89 44 24 04 mov %eax,0x4(%esp) + 800fc3: c7 04 24 e0 12 80 00 movl $0x8012e0,(%esp) + 800fca: e8 51 f1 ff ff call 800120 + panic("FAIL: T.T\n"); + 800fcf: c7 44 24 08 fe 12 80 movl $0x8012fe,0x8(%esp) + 800fd6: 00 + 800fd7: c7 44 24 04 07 00 00 movl $0x7,0x4(%esp) + 800fde: 00 + 800fdf: c7 04 24 09 13 80 00 movl $0x801309,(%esp) + 800fe6: e8 44 f0 ff ff call 80002f <__panic> diff --git a/labcodes/lab5/obj/user/faultreadkernel.d b/labcodes/lab5/obj/user/faultreadkernel.d new file mode 100644 index 0000000000000000000000000000000000000000..485d066028746483bb161469cf3e4b6d8c5d9b17 --- /dev/null +++ b/labcodes/lab5/obj/user/faultreadkernel.d @@ -0,0 +1,3 @@ +obj/user/faultreadkernel.o obj/user/faultreadkernel.d: \ + user/faultreadkernel.c libs/stdio.h libs/defs.h libs/stdarg.h \ + user/libs/ulib.h diff --git a/labcodes/lab5/obj/user/faultreadkernel.o b/labcodes/lab5/obj/user/faultreadkernel.o new file mode 100644 index 0000000000000000000000000000000000000000..b14385f484fae81c0832aa6c877735e66aa2e960 Binary files /dev/null and b/labcodes/lab5/obj/user/faultreadkernel.o differ diff --git a/labcodes/lab5/obj/user/faultreadkernel.sym b/labcodes/lab5/obj/user/faultreadkernel.sym new file mode 100644 index 0000000000000000000000000000000000000000..4dd956434c324a45adf189f164a550ab051f7c93 --- /dev/null +++ b/labcodes/lab5/obj/user/faultreadkernel.sym @@ -0,0 +1,66 @@ +00000000 panic.c +00000000 stdio.c +008000c8 cputch +00000000 syscall.c +00800199 syscall +00000000 ulib.c +00000000 umain.c +00000000 hash.c +00000000 printfmt.c +00801100 error_string +008003ad printnum +008004af getuint +008004fe getint +0080094f sprintputch +00000000 rand.c +00802000 next +00000000 string.c +00000000 faultreadkernel.c +00800b53 strcpy +00800329 yield +0080030d waitpid +00800245 sys_yield +00800e65 memmove +00800985 snprintf +00800576 vprintfmt +0080020b sys_fork +00800120 cprintf +0080034e getpid +00800f08 memcpy +008009bb vsnprintf +0080036d umain +002026c8 __STAB_END__ +0080025b sys_kill +002026c9 __STABSTR_BEGIN__ +0080002f __panic +00800ccb strtol +00800b22 strnlen +0080035d print_pgdir +00800339 kill +00800c9b strfind +008002ef wait +00800020 _start +00800a21 rand +00800c14 strncmp +0080028e sys_putc +00800b92 strncpy +00800f57 memcmp +008002e0 fork +00800e23 memset +00800faf main +00800ae0 srand +00800386 hash32 +00800545 printfmt +00203609 __STABSTR_END__ +00800bcb strcmp +008000eb vcprintf +0080007f __warn +00800148 cputs +008002c1 exit +00800221 sys_wait +008001ee sys_exit +00200010 __STAB_BEGIN__ +00800af9 strlen +008002ab sys_pgdir +00800c67 strchr +00800278 sys_getpid diff --git a/labcodes/lab5/obj/user/forktest.asm b/labcodes/lab5/obj/user/forktest.asm new file mode 100644 index 0000000000000000000000000000000000000000..08f43345d92d21be607484195175cf33c34195fa --- /dev/null +++ b/labcodes/lab5/obj/user/forktest.asm @@ -0,0 +1,2404 @@ + +obj/__user_forktest.out: file format elf32-i386 + + +Disassembly of section .text: + +00800020 <_start>: +.text +.globl _start +_start: + # set ebp for backtrace + movl $0x0, %ebp + 800020: bd 00 00 00 00 mov $0x0,%ebp + + # move down the esp register + # since it may cause page fault in backtrace + subl $0x20, %esp + 800025: 83 ec 20 sub $0x20,%esp + + # call user-program function + call umain + 800028: e8 40 03 00 00 call 80036d +1: jmp 1b + 80002d: eb fe jmp 80002d <_start+0xd> + +0080002f <__panic>: +#include +#include +#include + +void +__panic(const char *file, int line, const char *fmt, ...) { + 80002f: 55 push %ebp + 800030: 89 e5 mov %esp,%ebp + 800032: 83 ec 28 sub $0x28,%esp + // print the 'message' + va_list ap; + va_start(ap, fmt); + 800035: 8d 45 14 lea 0x14(%ebp),%eax + 800038: 89 45 f4 mov %eax,-0xc(%ebp) + cprintf("user panic at %s:%d:\n ", file, line); + 80003b: 8b 45 0c mov 0xc(%ebp),%eax + 80003e: 89 44 24 08 mov %eax,0x8(%esp) + 800042: 8b 45 08 mov 0x8(%ebp),%eax + 800045: 89 44 24 04 mov %eax,0x4(%esp) + 800049: c7 04 24 e0 10 80 00 movl $0x8010e0,(%esp) + 800050: e8 cb 00 00 00 call 800120 + vcprintf(fmt, ap); + 800055: 8b 45 f4 mov -0xc(%ebp),%eax + 800058: 89 44 24 04 mov %eax,0x4(%esp) + 80005c: 8b 45 10 mov 0x10(%ebp),%eax + 80005f: 89 04 24 mov %eax,(%esp) + 800062: e8 84 00 00 00 call 8000eb + cprintf("\n"); + 800067: c7 04 24 fa 10 80 00 movl $0x8010fa,(%esp) + 80006e: e8 ad 00 00 00 call 800120 + va_end(ap); + exit(-E_PANIC); + 800073: c7 04 24 f6 ff ff ff movl $0xfffffff6,(%esp) + 80007a: e8 42 02 00 00 call 8002c1 + +0080007f <__warn>: +} + +void +__warn(const char *file, int line, const char *fmt, ...) { + 80007f: 55 push %ebp + 800080: 89 e5 mov %esp,%ebp + 800082: 83 ec 28 sub $0x28,%esp + va_list ap; + va_start(ap, fmt); + 800085: 8d 45 14 lea 0x14(%ebp),%eax + 800088: 89 45 f4 mov %eax,-0xc(%ebp) + cprintf("user warning at %s:%d:\n ", file, line); + 80008b: 8b 45 0c mov 0xc(%ebp),%eax + 80008e: 89 44 24 08 mov %eax,0x8(%esp) + 800092: 8b 45 08 mov 0x8(%ebp),%eax + 800095: 89 44 24 04 mov %eax,0x4(%esp) + 800099: c7 04 24 fc 10 80 00 movl $0x8010fc,(%esp) + 8000a0: e8 7b 00 00 00 call 800120 + vcprintf(fmt, ap); + 8000a5: 8b 45 f4 mov -0xc(%ebp),%eax + 8000a8: 89 44 24 04 mov %eax,0x4(%esp) + 8000ac: 8b 45 10 mov 0x10(%ebp),%eax + 8000af: 89 04 24 mov %eax,(%esp) + 8000b2: e8 34 00 00 00 call 8000eb + cprintf("\n"); + 8000b7: c7 04 24 fa 10 80 00 movl $0x8010fa,(%esp) + 8000be: e8 5d 00 00 00 call 800120 + va_end(ap); +} + 8000c3: 90 nop + 8000c4: 89 ec mov %ebp,%esp + 8000c6: 5d pop %ebp + 8000c7: c3 ret + +008000c8 : +/* * + * cputch - writes a single character @c to stdout, and it will + * increace the value of counter pointed by @cnt. + * */ +static void +cputch(int c, int *cnt) { + 8000c8: 55 push %ebp + 8000c9: 89 e5 mov %esp,%ebp + 8000cb: 83 ec 18 sub $0x18,%esp + sys_putc(c); + 8000ce: 8b 45 08 mov 0x8(%ebp),%eax + 8000d1: 89 04 24 mov %eax,(%esp) + 8000d4: e8 b5 01 00 00 call 80028e + (*cnt) ++; + 8000d9: 8b 45 0c mov 0xc(%ebp),%eax + 8000dc: 8b 00 mov (%eax),%eax + 8000de: 8d 50 01 lea 0x1(%eax),%edx + 8000e1: 8b 45 0c mov 0xc(%ebp),%eax + 8000e4: 89 10 mov %edx,(%eax) +} + 8000e6: 90 nop + 8000e7: 89 ec mov %ebp,%esp + 8000e9: 5d pop %ebp + 8000ea: c3 ret + +008000eb : + * + * Call this function if you are already dealing with a va_list. + * Or you probably want cprintf() instead. + * */ +int +vcprintf(const char *fmt, va_list ap) { + 8000eb: 55 push %ebp + 8000ec: 89 e5 mov %esp,%ebp + 8000ee: 83 ec 28 sub $0x28,%esp + int cnt = 0; + 8000f1: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + vprintfmt((void*)cputch, &cnt, fmt, ap); + 8000f8: 8b 45 0c mov 0xc(%ebp),%eax + 8000fb: 89 44 24 0c mov %eax,0xc(%esp) + 8000ff: 8b 45 08 mov 0x8(%ebp),%eax + 800102: 89 44 24 08 mov %eax,0x8(%esp) + 800106: 8d 45 f4 lea -0xc(%ebp),%eax + 800109: 89 44 24 04 mov %eax,0x4(%esp) + 80010d: c7 04 24 c8 00 80 00 movl $0x8000c8,(%esp) + 800114: e8 5d 04 00 00 call 800576 + return cnt; + 800119: 8b 45 f4 mov -0xc(%ebp),%eax +} + 80011c: 89 ec mov %ebp,%esp + 80011e: 5d pop %ebp + 80011f: c3 ret + +00800120 : + * + * The return value is the number of characters which would be + * written to stdout. + * */ +int +cprintf(const char *fmt, ...) { + 800120: 55 push %ebp + 800121: 89 e5 mov %esp,%ebp + 800123: 83 ec 28 sub $0x28,%esp + va_list ap; + + va_start(ap, fmt); + 800126: 8d 45 0c lea 0xc(%ebp),%eax + 800129: 89 45 f0 mov %eax,-0x10(%ebp) + int cnt = vcprintf(fmt, ap); + 80012c: 8b 45 f0 mov -0x10(%ebp),%eax + 80012f: 89 44 24 04 mov %eax,0x4(%esp) + 800133: 8b 45 08 mov 0x8(%ebp),%eax + 800136: 89 04 24 mov %eax,(%esp) + 800139: e8 ad ff ff ff call 8000eb + 80013e: 89 45 f4 mov %eax,-0xc(%ebp) + va_end(ap); + + return cnt; + 800141: 8b 45 f4 mov -0xc(%ebp),%eax +} + 800144: 89 ec mov %ebp,%esp + 800146: 5d pop %ebp + 800147: c3 ret + +00800148 : +/* * + * cputs- writes the string pointed by @str to stdout and + * appends a newline character. + * */ +int +cputs(const char *str) { + 800148: 55 push %ebp + 800149: 89 e5 mov %esp,%ebp + 80014b: 83 ec 28 sub $0x28,%esp + int cnt = 0; + 80014e: c7 45 f0 00 00 00 00 movl $0x0,-0x10(%ebp) + char c; + while ((c = *str ++) != '\0') { + 800155: eb 13 jmp 80016a + cputch(c, &cnt); + 800157: 0f be 45 f7 movsbl -0x9(%ebp),%eax + 80015b: 8d 55 f0 lea -0x10(%ebp),%edx + 80015e: 89 54 24 04 mov %edx,0x4(%esp) + 800162: 89 04 24 mov %eax,(%esp) + 800165: e8 5e ff ff ff call 8000c8 + while ((c = *str ++) != '\0') { + 80016a: 8b 45 08 mov 0x8(%ebp),%eax + 80016d: 8d 50 01 lea 0x1(%eax),%edx + 800170: 89 55 08 mov %edx,0x8(%ebp) + 800173: 0f b6 00 movzbl (%eax),%eax + 800176: 88 45 f7 mov %al,-0x9(%ebp) + 800179: 80 7d f7 00 cmpb $0x0,-0x9(%ebp) + 80017d: 75 d8 jne 800157 + } + cputch('\n', &cnt); + 80017f: 8d 45 f0 lea -0x10(%ebp),%eax + 800182: 89 44 24 04 mov %eax,0x4(%esp) + 800186: c7 04 24 0a 00 00 00 movl $0xa,(%esp) + 80018d: e8 36 ff ff ff call 8000c8 + return cnt; + 800192: 8b 45 f0 mov -0x10(%ebp),%eax +} + 800195: 89 ec mov %ebp,%esp + 800197: 5d pop %ebp + 800198: c3 ret + +00800199 : +#include + +#define MAX_ARGS 5 + +static inline int +syscall(int num, ...) { + 800199: 55 push %ebp + 80019a: 89 e5 mov %esp,%ebp + 80019c: 57 push %edi + 80019d: 56 push %esi + 80019e: 53 push %ebx + 80019f: 83 ec 20 sub $0x20,%esp + va_list ap; + va_start(ap, num); + 8001a2: 8d 45 0c lea 0xc(%ebp),%eax + 8001a5: 89 45 e8 mov %eax,-0x18(%ebp) + uint32_t a[MAX_ARGS]; + int i, ret; + for (i = 0; i < MAX_ARGS; i ++) { + 8001a8: c7 45 f0 00 00 00 00 movl $0x0,-0x10(%ebp) + 8001af: eb 15 jmp 8001c6 + a[i] = va_arg(ap, uint32_t); + 8001b1: 8b 45 e8 mov -0x18(%ebp),%eax + 8001b4: 8d 50 04 lea 0x4(%eax),%edx + 8001b7: 89 55 e8 mov %edx,-0x18(%ebp) + 8001ba: 8b 10 mov (%eax),%edx + 8001bc: 8b 45 f0 mov -0x10(%ebp),%eax + 8001bf: 89 54 85 d4 mov %edx,-0x2c(%ebp,%eax,4) + for (i = 0; i < MAX_ARGS; i ++) { + 8001c3: ff 45 f0 incl -0x10(%ebp) + 8001c6: 83 7d f0 04 cmpl $0x4,-0x10(%ebp) + 8001ca: 7e e5 jle 8001b1 + asm volatile ( + "int %1;" + : "=a" (ret) + : "i" (T_SYSCALL), + "a" (num), + "d" (a[0]), + 8001cc: 8b 55 d4 mov -0x2c(%ebp),%edx + "c" (a[1]), + 8001cf: 8b 4d d8 mov -0x28(%ebp),%ecx + "b" (a[2]), + 8001d2: 8b 5d dc mov -0x24(%ebp),%ebx + "D" (a[3]), + 8001d5: 8b 7d e0 mov -0x20(%ebp),%edi + "S" (a[4]) + 8001d8: 8b 75 e4 mov -0x1c(%ebp),%esi + asm volatile ( + 8001db: 8b 45 08 mov 0x8(%ebp),%eax + 8001de: cd 80 int $0x80 + 8001e0: 89 45 ec mov %eax,-0x14(%ebp) + : "cc", "memory"); + return ret; + 8001e3: 8b 45 ec mov -0x14(%ebp),%eax +} + 8001e6: 83 c4 20 add $0x20,%esp + 8001e9: 5b pop %ebx + 8001ea: 5e pop %esi + 8001eb: 5f pop %edi + 8001ec: 5d pop %ebp + 8001ed: c3 ret + +008001ee : + +int +sys_exit(int error_code) { + 8001ee: 55 push %ebp + 8001ef: 89 e5 mov %esp,%ebp + 8001f1: 83 ec 08 sub $0x8,%esp + return syscall(SYS_exit, error_code); + 8001f4: 8b 45 08 mov 0x8(%ebp),%eax + 8001f7: 89 44 24 04 mov %eax,0x4(%esp) + 8001fb: c7 04 24 01 00 00 00 movl $0x1,(%esp) + 800202: e8 92 ff ff ff call 800199 +} + 800207: 89 ec mov %ebp,%esp + 800209: 5d pop %ebp + 80020a: c3 ret + +0080020b : + +int +sys_fork(void) { + 80020b: 55 push %ebp + 80020c: 89 e5 mov %esp,%ebp + 80020e: 83 ec 04 sub $0x4,%esp + return syscall(SYS_fork); + 800211: c7 04 24 02 00 00 00 movl $0x2,(%esp) + 800218: e8 7c ff ff ff call 800199 +} + 80021d: 89 ec mov %ebp,%esp + 80021f: 5d pop %ebp + 800220: c3 ret + +00800221 : + +int +sys_wait(int pid, int *store) { + 800221: 55 push %ebp + 800222: 89 e5 mov %esp,%ebp + 800224: 83 ec 0c sub $0xc,%esp + return syscall(SYS_wait, pid, store); + 800227: 8b 45 0c mov 0xc(%ebp),%eax + 80022a: 89 44 24 08 mov %eax,0x8(%esp) + 80022e: 8b 45 08 mov 0x8(%ebp),%eax + 800231: 89 44 24 04 mov %eax,0x4(%esp) + 800235: c7 04 24 03 00 00 00 movl $0x3,(%esp) + 80023c: e8 58 ff ff ff call 800199 +} + 800241: 89 ec mov %ebp,%esp + 800243: 5d pop %ebp + 800244: c3 ret + +00800245 : + +int +sys_yield(void) { + 800245: 55 push %ebp + 800246: 89 e5 mov %esp,%ebp + 800248: 83 ec 04 sub $0x4,%esp + return syscall(SYS_yield); + 80024b: c7 04 24 0a 00 00 00 movl $0xa,(%esp) + 800252: e8 42 ff ff ff call 800199 +} + 800257: 89 ec mov %ebp,%esp + 800259: 5d pop %ebp + 80025a: c3 ret + +0080025b : + +int +sys_kill(int pid) { + 80025b: 55 push %ebp + 80025c: 89 e5 mov %esp,%ebp + 80025e: 83 ec 08 sub $0x8,%esp + return syscall(SYS_kill, pid); + 800261: 8b 45 08 mov 0x8(%ebp),%eax + 800264: 89 44 24 04 mov %eax,0x4(%esp) + 800268: c7 04 24 0c 00 00 00 movl $0xc,(%esp) + 80026f: e8 25 ff ff ff call 800199 +} + 800274: 89 ec mov %ebp,%esp + 800276: 5d pop %ebp + 800277: c3 ret + +00800278 : + +int +sys_getpid(void) { + 800278: 55 push %ebp + 800279: 89 e5 mov %esp,%ebp + 80027b: 83 ec 04 sub $0x4,%esp + return syscall(SYS_getpid); + 80027e: c7 04 24 12 00 00 00 movl $0x12,(%esp) + 800285: e8 0f ff ff ff call 800199 +} + 80028a: 89 ec mov %ebp,%esp + 80028c: 5d pop %ebp + 80028d: c3 ret + +0080028e : + +int +sys_putc(int c) { + 80028e: 55 push %ebp + 80028f: 89 e5 mov %esp,%ebp + 800291: 83 ec 08 sub $0x8,%esp + return syscall(SYS_putc, c); + 800294: 8b 45 08 mov 0x8(%ebp),%eax + 800297: 89 44 24 04 mov %eax,0x4(%esp) + 80029b: c7 04 24 1e 00 00 00 movl $0x1e,(%esp) + 8002a2: e8 f2 fe ff ff call 800199 +} + 8002a7: 89 ec mov %ebp,%esp + 8002a9: 5d pop %ebp + 8002aa: c3 ret + +008002ab : + +int +sys_pgdir(void) { + 8002ab: 55 push %ebp + 8002ac: 89 e5 mov %esp,%ebp + 8002ae: 83 ec 04 sub $0x4,%esp + return syscall(SYS_pgdir); + 8002b1: c7 04 24 1f 00 00 00 movl $0x1f,(%esp) + 8002b8: e8 dc fe ff ff call 800199 +} + 8002bd: 89 ec mov %ebp,%esp + 8002bf: 5d pop %ebp + 8002c0: c3 ret + +008002c1 : +#include +#include +#include + +void +exit(int error_code) { + 8002c1: 55 push %ebp + 8002c2: 89 e5 mov %esp,%ebp + 8002c4: 83 ec 18 sub $0x18,%esp + sys_exit(error_code); + 8002c7: 8b 45 08 mov 0x8(%ebp),%eax + 8002ca: 89 04 24 mov %eax,(%esp) + 8002cd: e8 1c ff ff ff call 8001ee + cprintf("BUG: exit failed.\n"); + 8002d2: c7 04 24 18 11 80 00 movl $0x801118,(%esp) + 8002d9: e8 42 fe ff ff call 800120 + while (1); + 8002de: eb fe jmp 8002de + +008002e0 : +} + +int +fork(void) { + 8002e0: 55 push %ebp + 8002e1: 89 e5 mov %esp,%ebp + 8002e3: 83 ec 08 sub $0x8,%esp + return sys_fork(); + 8002e6: e8 20 ff ff ff call 80020b +} + 8002eb: 89 ec mov %ebp,%esp + 8002ed: 5d pop %ebp + 8002ee: c3 ret + +008002ef : + +int +wait(void) { + 8002ef: 55 push %ebp + 8002f0: 89 e5 mov %esp,%ebp + 8002f2: 83 ec 18 sub $0x18,%esp + return sys_wait(0, NULL); + 8002f5: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) + 8002fc: 00 + 8002fd: c7 04 24 00 00 00 00 movl $0x0,(%esp) + 800304: e8 18 ff ff ff call 800221 +} + 800309: 89 ec mov %ebp,%esp + 80030b: 5d pop %ebp + 80030c: c3 ret + +0080030d : + +int +waitpid(int pid, int *store) { + 80030d: 55 push %ebp + 80030e: 89 e5 mov %esp,%ebp + 800310: 83 ec 18 sub $0x18,%esp + return sys_wait(pid, store); + 800313: 8b 45 0c mov 0xc(%ebp),%eax + 800316: 89 44 24 04 mov %eax,0x4(%esp) + 80031a: 8b 45 08 mov 0x8(%ebp),%eax + 80031d: 89 04 24 mov %eax,(%esp) + 800320: e8 fc fe ff ff call 800221 +} + 800325: 89 ec mov %ebp,%esp + 800327: 5d pop %ebp + 800328: c3 ret + +00800329 : + +void +yield(void) { + 800329: 55 push %ebp + 80032a: 89 e5 mov %esp,%ebp + 80032c: 83 ec 08 sub $0x8,%esp + sys_yield(); + 80032f: e8 11 ff ff ff call 800245 +} + 800334: 90 nop + 800335: 89 ec mov %ebp,%esp + 800337: 5d pop %ebp + 800338: c3 ret + +00800339 : + +int +kill(int pid) { + 800339: 55 push %ebp + 80033a: 89 e5 mov %esp,%ebp + 80033c: 83 ec 18 sub $0x18,%esp + return sys_kill(pid); + 80033f: 8b 45 08 mov 0x8(%ebp),%eax + 800342: 89 04 24 mov %eax,(%esp) + 800345: e8 11 ff ff ff call 80025b +} + 80034a: 89 ec mov %ebp,%esp + 80034c: 5d pop %ebp + 80034d: c3 ret + +0080034e : + +int +getpid(void) { + 80034e: 55 push %ebp + 80034f: 89 e5 mov %esp,%ebp + 800351: 83 ec 08 sub $0x8,%esp + return sys_getpid(); + 800354: e8 1f ff ff ff call 800278 +} + 800359: 89 ec mov %ebp,%esp + 80035b: 5d pop %ebp + 80035c: c3 ret + +0080035d : + +//print_pgdir - print the PDT&PT +void +print_pgdir(void) { + 80035d: 55 push %ebp + 80035e: 89 e5 mov %esp,%ebp + 800360: 83 ec 08 sub $0x8,%esp + sys_pgdir(); + 800363: e8 43 ff ff ff call 8002ab +} + 800368: 90 nop + 800369: 89 ec mov %ebp,%esp + 80036b: 5d pop %ebp + 80036c: c3 ret + +0080036d : +#include + +int main(void); + +void +umain(void) { + 80036d: 55 push %ebp + 80036e: 89 e5 mov %esp,%ebp + 800370: 83 ec 28 sub $0x28,%esp + int ret = main(); + 800373: e8 37 0c 00 00 call 800faf
+ 800378: 89 45 f4 mov %eax,-0xc(%ebp) + exit(ret); + 80037b: 8b 45 f4 mov -0xc(%ebp),%eax + 80037e: 89 04 24 mov %eax,(%esp) + 800381: e8 3b ff ff ff call 8002c1 + +00800386 : + * @bits: the number of bits in a return value + * + * High bits are more random, so we use them. + * */ +uint32_t +hash32(uint32_t val, unsigned int bits) { + 800386: 55 push %ebp + 800387: 89 e5 mov %esp,%ebp + 800389: 83 ec 10 sub $0x10,%esp + uint32_t hash = val * GOLDEN_RATIO_PRIME_32; + 80038c: 8b 45 08 mov 0x8(%ebp),%eax + 80038f: 69 c0 01 00 37 9e imul $0x9e370001,%eax,%eax + 800395: 89 45 fc mov %eax,-0x4(%ebp) + return (hash >> (32 - bits)); + 800398: b8 20 00 00 00 mov $0x20,%eax + 80039d: 2b 45 0c sub 0xc(%ebp),%eax + 8003a0: 8b 55 fc mov -0x4(%ebp),%edx + 8003a3: 88 c1 mov %al,%cl + 8003a5: d3 ea shr %cl,%edx + 8003a7: 89 d0 mov %edx,%eax +} + 8003a9: 89 ec mov %ebp,%esp + 8003ab: 5d pop %ebp + 8003ac: c3 ret + +008003ad : + * @width: maximum number of digits, if the actual width is less than @width, use @padc instead + * @padc: character that padded on the left if the actual width is less than @width + * */ +static void +printnum(void (*putch)(int, void*), void *putdat, + unsigned long long num, unsigned base, int width, int padc) { + 8003ad: 55 push %ebp + 8003ae: 89 e5 mov %esp,%ebp + 8003b0: 83 ec 58 sub $0x58,%esp + 8003b3: 8b 45 10 mov 0x10(%ebp),%eax + 8003b6: 89 45 d0 mov %eax,-0x30(%ebp) + 8003b9: 8b 45 14 mov 0x14(%ebp),%eax + 8003bc: 89 45 d4 mov %eax,-0x2c(%ebp) + unsigned long long result = num; + 8003bf: 8b 45 d0 mov -0x30(%ebp),%eax + 8003c2: 8b 55 d4 mov -0x2c(%ebp),%edx + 8003c5: 89 45 e8 mov %eax,-0x18(%ebp) + 8003c8: 89 55 ec mov %edx,-0x14(%ebp) + unsigned mod = do_div(result, base); + 8003cb: 8b 45 18 mov 0x18(%ebp),%eax + 8003ce: 89 45 e4 mov %eax,-0x1c(%ebp) + 8003d1: 8b 45 e8 mov -0x18(%ebp),%eax + 8003d4: 8b 55 ec mov -0x14(%ebp),%edx + 8003d7: 89 45 e0 mov %eax,-0x20(%ebp) + 8003da: 89 55 f0 mov %edx,-0x10(%ebp) + 8003dd: 8b 45 f0 mov -0x10(%ebp),%eax + 8003e0: 89 45 f4 mov %eax,-0xc(%ebp) + 8003e3: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) + 8003e7: 74 1c je 800405 + 8003e9: 8b 45 f0 mov -0x10(%ebp),%eax + 8003ec: ba 00 00 00 00 mov $0x0,%edx + 8003f1: f7 75 e4 divl -0x1c(%ebp) + 8003f4: 89 55 f4 mov %edx,-0xc(%ebp) + 8003f7: 8b 45 f0 mov -0x10(%ebp),%eax + 8003fa: ba 00 00 00 00 mov $0x0,%edx + 8003ff: f7 75 e4 divl -0x1c(%ebp) + 800402: 89 45 f0 mov %eax,-0x10(%ebp) + 800405: 8b 45 e0 mov -0x20(%ebp),%eax + 800408: 8b 55 f4 mov -0xc(%ebp),%edx + 80040b: f7 75 e4 divl -0x1c(%ebp) + 80040e: 89 45 e0 mov %eax,-0x20(%ebp) + 800411: 89 55 dc mov %edx,-0x24(%ebp) + 800414: 8b 45 e0 mov -0x20(%ebp),%eax + 800417: 8b 55 f0 mov -0x10(%ebp),%edx + 80041a: 89 45 e8 mov %eax,-0x18(%ebp) + 80041d: 89 55 ec mov %edx,-0x14(%ebp) + 800420: 8b 45 dc mov -0x24(%ebp),%eax + 800423: 89 45 d8 mov %eax,-0x28(%ebp) + + // first recursively print all preceding (more significant) digits + if (num >= base) { + 800426: 8b 45 18 mov 0x18(%ebp),%eax + 800429: ba 00 00 00 00 mov $0x0,%edx + 80042e: 8b 4d d4 mov -0x2c(%ebp),%ecx + 800431: 39 45 d0 cmp %eax,-0x30(%ebp) + 800434: 19 d1 sbb %edx,%ecx + 800436: 72 4c jb 800484 + printnum(putch, putdat, result, base, width - 1, padc); + 800438: 8b 45 1c mov 0x1c(%ebp),%eax + 80043b: 8d 50 ff lea -0x1(%eax),%edx + 80043e: 8b 45 20 mov 0x20(%ebp),%eax + 800441: 89 44 24 18 mov %eax,0x18(%esp) + 800445: 89 54 24 14 mov %edx,0x14(%esp) + 800449: 8b 45 18 mov 0x18(%ebp),%eax + 80044c: 89 44 24 10 mov %eax,0x10(%esp) + 800450: 8b 45 e8 mov -0x18(%ebp),%eax + 800453: 8b 55 ec mov -0x14(%ebp),%edx + 800456: 89 44 24 08 mov %eax,0x8(%esp) + 80045a: 89 54 24 0c mov %edx,0xc(%esp) + 80045e: 8b 45 0c mov 0xc(%ebp),%eax + 800461: 89 44 24 04 mov %eax,0x4(%esp) + 800465: 8b 45 08 mov 0x8(%ebp),%eax + 800468: 89 04 24 mov %eax,(%esp) + 80046b: e8 3d ff ff ff call 8003ad + 800470: eb 1b jmp 80048d + } else { + // print any needed pad characters before first digit + while (-- width > 0) + putch(padc, putdat); + 800472: 8b 45 0c mov 0xc(%ebp),%eax + 800475: 89 44 24 04 mov %eax,0x4(%esp) + 800479: 8b 45 20 mov 0x20(%ebp),%eax + 80047c: 89 04 24 mov %eax,(%esp) + 80047f: 8b 45 08 mov 0x8(%ebp),%eax + 800482: ff d0 call *%eax + while (-- width > 0) + 800484: ff 4d 1c decl 0x1c(%ebp) + 800487: 83 7d 1c 00 cmpl $0x0,0x1c(%ebp) + 80048b: 7f e5 jg 800472 + } + // then print this (the least significant) digit + putch("0123456789abcdef"[mod], putdat); + 80048d: 8b 45 d8 mov -0x28(%ebp),%eax + 800490: 05 44 12 80 00 add $0x801244,%eax + 800495: 0f b6 00 movzbl (%eax),%eax + 800498: 0f be c0 movsbl %al,%eax + 80049b: 8b 55 0c mov 0xc(%ebp),%edx + 80049e: 89 54 24 04 mov %edx,0x4(%esp) + 8004a2: 89 04 24 mov %eax,(%esp) + 8004a5: 8b 45 08 mov 0x8(%ebp),%eax + 8004a8: ff d0 call *%eax +} + 8004aa: 90 nop + 8004ab: 89 ec mov %ebp,%esp + 8004ad: 5d pop %ebp + 8004ae: c3 ret + +008004af : + * getuint - get an unsigned int of various possible sizes from a varargs list + * @ap: a varargs list pointer + * @lflag: determines the size of the vararg that @ap points to + * */ +static unsigned long long +getuint(va_list *ap, int lflag) { + 8004af: 55 push %ebp + 8004b0: 89 e5 mov %esp,%ebp + if (lflag >= 2) { + 8004b2: 83 7d 0c 01 cmpl $0x1,0xc(%ebp) + 8004b6: 7e 14 jle 8004cc + return va_arg(*ap, unsigned long long); + 8004b8: 8b 45 08 mov 0x8(%ebp),%eax + 8004bb: 8b 00 mov (%eax),%eax + 8004bd: 8d 48 08 lea 0x8(%eax),%ecx + 8004c0: 8b 55 08 mov 0x8(%ebp),%edx + 8004c3: 89 0a mov %ecx,(%edx) + 8004c5: 8b 50 04 mov 0x4(%eax),%edx + 8004c8: 8b 00 mov (%eax),%eax + 8004ca: eb 30 jmp 8004fc + } + else if (lflag) { + 8004cc: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) + 8004d0: 74 16 je 8004e8 + return va_arg(*ap, unsigned long); + 8004d2: 8b 45 08 mov 0x8(%ebp),%eax + 8004d5: 8b 00 mov (%eax),%eax + 8004d7: 8d 48 04 lea 0x4(%eax),%ecx + 8004da: 8b 55 08 mov 0x8(%ebp),%edx + 8004dd: 89 0a mov %ecx,(%edx) + 8004df: 8b 00 mov (%eax),%eax + 8004e1: ba 00 00 00 00 mov $0x0,%edx + 8004e6: eb 14 jmp 8004fc + } + else { + return va_arg(*ap, unsigned int); + 8004e8: 8b 45 08 mov 0x8(%ebp),%eax + 8004eb: 8b 00 mov (%eax),%eax + 8004ed: 8d 48 04 lea 0x4(%eax),%ecx + 8004f0: 8b 55 08 mov 0x8(%ebp),%edx + 8004f3: 89 0a mov %ecx,(%edx) + 8004f5: 8b 00 mov (%eax),%eax + 8004f7: ba 00 00 00 00 mov $0x0,%edx + } +} + 8004fc: 5d pop %ebp + 8004fd: c3 ret + +008004fe : + * getint - same as getuint but signed, we can't use getuint because of sign extension + * @ap: a varargs list pointer + * @lflag: determines the size of the vararg that @ap points to + * */ +static long long +getint(va_list *ap, int lflag) { + 8004fe: 55 push %ebp + 8004ff: 89 e5 mov %esp,%ebp + if (lflag >= 2) { + 800501: 83 7d 0c 01 cmpl $0x1,0xc(%ebp) + 800505: 7e 14 jle 80051b + return va_arg(*ap, long long); + 800507: 8b 45 08 mov 0x8(%ebp),%eax + 80050a: 8b 00 mov (%eax),%eax + 80050c: 8d 48 08 lea 0x8(%eax),%ecx + 80050f: 8b 55 08 mov 0x8(%ebp),%edx + 800512: 89 0a mov %ecx,(%edx) + 800514: 8b 50 04 mov 0x4(%eax),%edx + 800517: 8b 00 mov (%eax),%eax + 800519: eb 28 jmp 800543 + } + else if (lflag) { + 80051b: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) + 80051f: 74 12 je 800533 + return va_arg(*ap, long); + 800521: 8b 45 08 mov 0x8(%ebp),%eax + 800524: 8b 00 mov (%eax),%eax + 800526: 8d 48 04 lea 0x4(%eax),%ecx + 800529: 8b 55 08 mov 0x8(%ebp),%edx + 80052c: 89 0a mov %ecx,(%edx) + 80052e: 8b 00 mov (%eax),%eax + 800530: 99 cltd + 800531: eb 10 jmp 800543 + } + else { + return va_arg(*ap, int); + 800533: 8b 45 08 mov 0x8(%ebp),%eax + 800536: 8b 00 mov (%eax),%eax + 800538: 8d 48 04 lea 0x4(%eax),%ecx + 80053b: 8b 55 08 mov 0x8(%ebp),%edx + 80053e: 89 0a mov %ecx,(%edx) + 800540: 8b 00 mov (%eax),%eax + 800542: 99 cltd + } +} + 800543: 5d pop %ebp + 800544: c3 ret + +00800545 : + * @putch: specified putch function, print a single character + * @putdat: used by @putch function + * @fmt: the format string to use + * */ +void +printfmt(void (*putch)(int, void*), void *putdat, const char *fmt, ...) { + 800545: 55 push %ebp + 800546: 89 e5 mov %esp,%ebp + 800548: 83 ec 28 sub $0x28,%esp + va_list ap; + + va_start(ap, fmt); + 80054b: 8d 45 14 lea 0x14(%ebp),%eax + 80054e: 89 45 f4 mov %eax,-0xc(%ebp) + vprintfmt(putch, putdat, fmt, ap); + 800551: 8b 45 f4 mov -0xc(%ebp),%eax + 800554: 89 44 24 0c mov %eax,0xc(%esp) + 800558: 8b 45 10 mov 0x10(%ebp),%eax + 80055b: 89 44 24 08 mov %eax,0x8(%esp) + 80055f: 8b 45 0c mov 0xc(%ebp),%eax + 800562: 89 44 24 04 mov %eax,0x4(%esp) + 800566: 8b 45 08 mov 0x8(%ebp),%eax + 800569: 89 04 24 mov %eax,(%esp) + 80056c: e8 05 00 00 00 call 800576 + va_end(ap); +} + 800571: 90 nop + 800572: 89 ec mov %ebp,%esp + 800574: 5d pop %ebp + 800575: c3 ret + +00800576 : + * + * Call this function if you are already dealing with a va_list. + * Or you probably want printfmt() instead. + * */ +void +vprintfmt(void (*putch)(int, void*), void *putdat, const char *fmt, va_list ap) { + 800576: 55 push %ebp + 800577: 89 e5 mov %esp,%ebp + 800579: 56 push %esi + 80057a: 53 push %ebx + 80057b: 83 ec 40 sub $0x40,%esp + register int ch, err; + unsigned long long num; + int base, width, precision, lflag, altflag; + + while (1) { + while ((ch = *(unsigned char *)fmt ++) != '%') { + 80057e: eb 17 jmp 800597 + if (ch == '\0') { + 800580: 85 db test %ebx,%ebx + 800582: 0f 84 bf 03 00 00 je 800947 + return; + } + putch(ch, putdat); + 800588: 8b 45 0c mov 0xc(%ebp),%eax + 80058b: 89 44 24 04 mov %eax,0x4(%esp) + 80058f: 89 1c 24 mov %ebx,(%esp) + 800592: 8b 45 08 mov 0x8(%ebp),%eax + 800595: ff d0 call *%eax + while ((ch = *(unsigned char *)fmt ++) != '%') { + 800597: 8b 45 10 mov 0x10(%ebp),%eax + 80059a: 8d 50 01 lea 0x1(%eax),%edx + 80059d: 89 55 10 mov %edx,0x10(%ebp) + 8005a0: 0f b6 00 movzbl (%eax),%eax + 8005a3: 0f b6 d8 movzbl %al,%ebx + 8005a6: 83 fb 25 cmp $0x25,%ebx + 8005a9: 75 d5 jne 800580 + } + + // Process a %-escape sequence + char padc = ' '; + 8005ab: c6 45 db 20 movb $0x20,-0x25(%ebp) + width = precision = -1; + 8005af: c7 45 e4 ff ff ff ff movl $0xffffffff,-0x1c(%ebp) + 8005b6: 8b 45 e4 mov -0x1c(%ebp),%eax + 8005b9: 89 45 e8 mov %eax,-0x18(%ebp) + lflag = altflag = 0; + 8005bc: c7 45 dc 00 00 00 00 movl $0x0,-0x24(%ebp) + 8005c3: 8b 45 dc mov -0x24(%ebp),%eax + 8005c6: 89 45 e0 mov %eax,-0x20(%ebp) + + reswitch: + switch (ch = *(unsigned char *)fmt ++) { + 8005c9: 8b 45 10 mov 0x10(%ebp),%eax + 8005cc: 8d 50 01 lea 0x1(%eax),%edx + 8005cf: 89 55 10 mov %edx,0x10(%ebp) + 8005d2: 0f b6 00 movzbl (%eax),%eax + 8005d5: 0f b6 d8 movzbl %al,%ebx + 8005d8: 8d 43 dd lea -0x23(%ebx),%eax + 8005db: 83 f8 55 cmp $0x55,%eax + 8005de: 0f 87 37 03 00 00 ja 80091b + 8005e4: 8b 04 85 68 12 80 00 mov 0x801268(,%eax,4),%eax + 8005eb: ff e0 jmp *%eax + + // flag to pad on the right + case '-': + padc = '-'; + 8005ed: c6 45 db 2d movb $0x2d,-0x25(%ebp) + goto reswitch; + 8005f1: eb d6 jmp 8005c9 + + // flag to pad with 0's instead of spaces + case '0': + padc = '0'; + 8005f3: c6 45 db 30 movb $0x30,-0x25(%ebp) + goto reswitch; + 8005f7: eb d0 jmp 8005c9 + + // width field + case '1' ... '9': + for (precision = 0; ; ++ fmt) { + 8005f9: c7 45 e4 00 00 00 00 movl $0x0,-0x1c(%ebp) + precision = precision * 10 + ch - '0'; + 800600: 8b 55 e4 mov -0x1c(%ebp),%edx + 800603: 89 d0 mov %edx,%eax + 800605: c1 e0 02 shl $0x2,%eax + 800608: 01 d0 add %edx,%eax + 80060a: 01 c0 add %eax,%eax + 80060c: 01 d8 add %ebx,%eax + 80060e: 83 e8 30 sub $0x30,%eax + 800611: 89 45 e4 mov %eax,-0x1c(%ebp) + ch = *fmt; + 800614: 8b 45 10 mov 0x10(%ebp),%eax + 800617: 0f b6 00 movzbl (%eax),%eax + 80061a: 0f be d8 movsbl %al,%ebx + if (ch < '0' || ch > '9') { + 80061d: 83 fb 2f cmp $0x2f,%ebx + 800620: 7e 38 jle 80065a + 800622: 83 fb 39 cmp $0x39,%ebx + 800625: 7f 33 jg 80065a + for (precision = 0; ; ++ fmt) { + 800627: ff 45 10 incl 0x10(%ebp) + precision = precision * 10 + ch - '0'; + 80062a: eb d4 jmp 800600 + } + } + goto process_precision; + + case '*': + precision = va_arg(ap, int); + 80062c: 8b 45 14 mov 0x14(%ebp),%eax + 80062f: 8d 50 04 lea 0x4(%eax),%edx + 800632: 89 55 14 mov %edx,0x14(%ebp) + 800635: 8b 00 mov (%eax),%eax + 800637: 89 45 e4 mov %eax,-0x1c(%ebp) + goto process_precision; + 80063a: eb 1f jmp 80065b + + case '.': + if (width < 0) + 80063c: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 800640: 79 87 jns 8005c9 + width = 0; + 800642: c7 45 e8 00 00 00 00 movl $0x0,-0x18(%ebp) + goto reswitch; + 800649: e9 7b ff ff ff jmp 8005c9 + + case '#': + altflag = 1; + 80064e: c7 45 dc 01 00 00 00 movl $0x1,-0x24(%ebp) + goto reswitch; + 800655: e9 6f ff ff ff jmp 8005c9 + goto process_precision; + 80065a: 90 nop + + process_precision: + if (width < 0) + 80065b: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 80065f: 0f 89 64 ff ff ff jns 8005c9 + width = precision, precision = -1; + 800665: 8b 45 e4 mov -0x1c(%ebp),%eax + 800668: 89 45 e8 mov %eax,-0x18(%ebp) + 80066b: c7 45 e4 ff ff ff ff movl $0xffffffff,-0x1c(%ebp) + goto reswitch; + 800672: e9 52 ff ff ff jmp 8005c9 + + // long flag (doubled for long long) + case 'l': + lflag ++; + 800677: ff 45 e0 incl -0x20(%ebp) + goto reswitch; + 80067a: e9 4a ff ff ff jmp 8005c9 + + // character + case 'c': + putch(va_arg(ap, int), putdat); + 80067f: 8b 45 14 mov 0x14(%ebp),%eax + 800682: 8d 50 04 lea 0x4(%eax),%edx + 800685: 89 55 14 mov %edx,0x14(%ebp) + 800688: 8b 00 mov (%eax),%eax + 80068a: 8b 55 0c mov 0xc(%ebp),%edx + 80068d: 89 54 24 04 mov %edx,0x4(%esp) + 800691: 89 04 24 mov %eax,(%esp) + 800694: 8b 45 08 mov 0x8(%ebp),%eax + 800697: ff d0 call *%eax + break; + 800699: e9 a4 02 00 00 jmp 800942 + + // error message + case 'e': + err = va_arg(ap, int); + 80069e: 8b 45 14 mov 0x14(%ebp),%eax + 8006a1: 8d 50 04 lea 0x4(%eax),%edx + 8006a4: 89 55 14 mov %edx,0x14(%ebp) + 8006a7: 8b 18 mov (%eax),%ebx + if (err < 0) { + 8006a9: 85 db test %ebx,%ebx + 8006ab: 79 02 jns 8006af + err = -err; + 8006ad: f7 db neg %ebx + } + if (err > MAXERROR || (p = error_string[err]) == NULL) { + 8006af: 83 fb 18 cmp $0x18,%ebx + 8006b2: 7f 0b jg 8006bf + 8006b4: 8b 34 9d e0 11 80 00 mov 0x8011e0(,%ebx,4),%esi + 8006bb: 85 f6 test %esi,%esi + 8006bd: 75 23 jne 8006e2 + printfmt(putch, putdat, "error %d", err); + 8006bf: 89 5c 24 0c mov %ebx,0xc(%esp) + 8006c3: c7 44 24 08 55 12 80 movl $0x801255,0x8(%esp) + 8006ca: 00 + 8006cb: 8b 45 0c mov 0xc(%ebp),%eax + 8006ce: 89 44 24 04 mov %eax,0x4(%esp) + 8006d2: 8b 45 08 mov 0x8(%ebp),%eax + 8006d5: 89 04 24 mov %eax,(%esp) + 8006d8: e8 68 fe ff ff call 800545 + } + else { + printfmt(putch, putdat, "%s", p); + } + break; + 8006dd: e9 60 02 00 00 jmp 800942 + printfmt(putch, putdat, "%s", p); + 8006e2: 89 74 24 0c mov %esi,0xc(%esp) + 8006e6: c7 44 24 08 5e 12 80 movl $0x80125e,0x8(%esp) + 8006ed: 00 + 8006ee: 8b 45 0c mov 0xc(%ebp),%eax + 8006f1: 89 44 24 04 mov %eax,0x4(%esp) + 8006f5: 8b 45 08 mov 0x8(%ebp),%eax + 8006f8: 89 04 24 mov %eax,(%esp) + 8006fb: e8 45 fe ff ff call 800545 + break; + 800700: e9 3d 02 00 00 jmp 800942 + + // string + case 's': + if ((p = va_arg(ap, char *)) == NULL) { + 800705: 8b 45 14 mov 0x14(%ebp),%eax + 800708: 8d 50 04 lea 0x4(%eax),%edx + 80070b: 89 55 14 mov %edx,0x14(%ebp) + 80070e: 8b 30 mov (%eax),%esi + 800710: 85 f6 test %esi,%esi + 800712: 75 05 jne 800719 + p = "(null)"; + 800714: be 61 12 80 00 mov $0x801261,%esi + } + if (width > 0 && padc != '-') { + 800719: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 80071d: 7e 76 jle 800795 + 80071f: 80 7d db 2d cmpb $0x2d,-0x25(%ebp) + 800723: 74 70 je 800795 + for (width -= strnlen(p, precision); width > 0; width --) { + 800725: 8b 45 e4 mov -0x1c(%ebp),%eax + 800728: 89 44 24 04 mov %eax,0x4(%esp) + 80072c: 89 34 24 mov %esi,(%esp) + 80072f: e8 ee 03 00 00 call 800b22 + 800734: 89 c2 mov %eax,%edx + 800736: 8b 45 e8 mov -0x18(%ebp),%eax + 800739: 29 d0 sub %edx,%eax + 80073b: 89 45 e8 mov %eax,-0x18(%ebp) + 80073e: eb 16 jmp 800756 + putch(padc, putdat); + 800740: 0f be 45 db movsbl -0x25(%ebp),%eax + 800744: 8b 55 0c mov 0xc(%ebp),%edx + 800747: 89 54 24 04 mov %edx,0x4(%esp) + 80074b: 89 04 24 mov %eax,(%esp) + 80074e: 8b 45 08 mov 0x8(%ebp),%eax + 800751: ff d0 call *%eax + for (width -= strnlen(p, precision); width > 0; width --) { + 800753: ff 4d e8 decl -0x18(%ebp) + 800756: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 80075a: 7f e4 jg 800740 + } + } + for (; (ch = *p ++) != '\0' && (precision < 0 || -- precision >= 0); width --) { + 80075c: eb 37 jmp 800795 + if (altflag && (ch < ' ' || ch > '~')) { + 80075e: 83 7d dc 00 cmpl $0x0,-0x24(%ebp) + 800762: 74 1f je 800783 + 800764: 83 fb 1f cmp $0x1f,%ebx + 800767: 7e 05 jle 80076e + 800769: 83 fb 7e cmp $0x7e,%ebx + 80076c: 7e 15 jle 800783 + putch('?', putdat); + 80076e: 8b 45 0c mov 0xc(%ebp),%eax + 800771: 89 44 24 04 mov %eax,0x4(%esp) + 800775: c7 04 24 3f 00 00 00 movl $0x3f,(%esp) + 80077c: 8b 45 08 mov 0x8(%ebp),%eax + 80077f: ff d0 call *%eax + 800781: eb 0f jmp 800792 + } + else { + putch(ch, putdat); + 800783: 8b 45 0c mov 0xc(%ebp),%eax + 800786: 89 44 24 04 mov %eax,0x4(%esp) + 80078a: 89 1c 24 mov %ebx,(%esp) + 80078d: 8b 45 08 mov 0x8(%ebp),%eax + 800790: ff d0 call *%eax + for (; (ch = *p ++) != '\0' && (precision < 0 || -- precision >= 0); width --) { + 800792: ff 4d e8 decl -0x18(%ebp) + 800795: 89 f0 mov %esi,%eax + 800797: 8d 70 01 lea 0x1(%eax),%esi + 80079a: 0f b6 00 movzbl (%eax),%eax + 80079d: 0f be d8 movsbl %al,%ebx + 8007a0: 85 db test %ebx,%ebx + 8007a2: 74 27 je 8007cb + 8007a4: 83 7d e4 00 cmpl $0x0,-0x1c(%ebp) + 8007a8: 78 b4 js 80075e + 8007aa: ff 4d e4 decl -0x1c(%ebp) + 8007ad: 83 7d e4 00 cmpl $0x0,-0x1c(%ebp) + 8007b1: 79 ab jns 80075e + } + } + for (; width > 0; width --) { + 8007b3: eb 16 jmp 8007cb + putch(' ', putdat); + 8007b5: 8b 45 0c mov 0xc(%ebp),%eax + 8007b8: 89 44 24 04 mov %eax,0x4(%esp) + 8007bc: c7 04 24 20 00 00 00 movl $0x20,(%esp) + 8007c3: 8b 45 08 mov 0x8(%ebp),%eax + 8007c6: ff d0 call *%eax + for (; width > 0; width --) { + 8007c8: ff 4d e8 decl -0x18(%ebp) + 8007cb: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 8007cf: 7f e4 jg 8007b5 + } + break; + 8007d1: e9 6c 01 00 00 jmp 800942 + + // (signed) decimal + case 'd': + num = getint(&ap, lflag); + 8007d6: 8b 45 e0 mov -0x20(%ebp),%eax + 8007d9: 89 44 24 04 mov %eax,0x4(%esp) + 8007dd: 8d 45 14 lea 0x14(%ebp),%eax + 8007e0: 89 04 24 mov %eax,(%esp) + 8007e3: e8 16 fd ff ff call 8004fe + 8007e8: 89 45 f0 mov %eax,-0x10(%ebp) + 8007eb: 89 55 f4 mov %edx,-0xc(%ebp) + if ((long long)num < 0) { + 8007ee: 8b 45 f0 mov -0x10(%ebp),%eax + 8007f1: 8b 55 f4 mov -0xc(%ebp),%edx + 8007f4: 85 d2 test %edx,%edx + 8007f6: 79 26 jns 80081e + putch('-', putdat); + 8007f8: 8b 45 0c mov 0xc(%ebp),%eax + 8007fb: 89 44 24 04 mov %eax,0x4(%esp) + 8007ff: c7 04 24 2d 00 00 00 movl $0x2d,(%esp) + 800806: 8b 45 08 mov 0x8(%ebp),%eax + 800809: ff d0 call *%eax + num = -(long long)num; + 80080b: 8b 45 f0 mov -0x10(%ebp),%eax + 80080e: 8b 55 f4 mov -0xc(%ebp),%edx + 800811: f7 d8 neg %eax + 800813: 83 d2 00 adc $0x0,%edx + 800816: f7 da neg %edx + 800818: 89 45 f0 mov %eax,-0x10(%ebp) + 80081b: 89 55 f4 mov %edx,-0xc(%ebp) + } + base = 10; + 80081e: c7 45 ec 0a 00 00 00 movl $0xa,-0x14(%ebp) + goto number; + 800825: e9 a8 00 00 00 jmp 8008d2 + + // unsigned decimal + case 'u': + num = getuint(&ap, lflag); + 80082a: 8b 45 e0 mov -0x20(%ebp),%eax + 80082d: 89 44 24 04 mov %eax,0x4(%esp) + 800831: 8d 45 14 lea 0x14(%ebp),%eax + 800834: 89 04 24 mov %eax,(%esp) + 800837: e8 73 fc ff ff call 8004af + 80083c: 89 45 f0 mov %eax,-0x10(%ebp) + 80083f: 89 55 f4 mov %edx,-0xc(%ebp) + base = 10; + 800842: c7 45 ec 0a 00 00 00 movl $0xa,-0x14(%ebp) + goto number; + 800849: e9 84 00 00 00 jmp 8008d2 + + // (unsigned) octal + case 'o': + num = getuint(&ap, lflag); + 80084e: 8b 45 e0 mov -0x20(%ebp),%eax + 800851: 89 44 24 04 mov %eax,0x4(%esp) + 800855: 8d 45 14 lea 0x14(%ebp),%eax + 800858: 89 04 24 mov %eax,(%esp) + 80085b: e8 4f fc ff ff call 8004af + 800860: 89 45 f0 mov %eax,-0x10(%ebp) + 800863: 89 55 f4 mov %edx,-0xc(%ebp) + base = 8; + 800866: c7 45 ec 08 00 00 00 movl $0x8,-0x14(%ebp) + goto number; + 80086d: eb 63 jmp 8008d2 + + // pointer + case 'p': + putch('0', putdat); + 80086f: 8b 45 0c mov 0xc(%ebp),%eax + 800872: 89 44 24 04 mov %eax,0x4(%esp) + 800876: c7 04 24 30 00 00 00 movl $0x30,(%esp) + 80087d: 8b 45 08 mov 0x8(%ebp),%eax + 800880: ff d0 call *%eax + putch('x', putdat); + 800882: 8b 45 0c mov 0xc(%ebp),%eax + 800885: 89 44 24 04 mov %eax,0x4(%esp) + 800889: c7 04 24 78 00 00 00 movl $0x78,(%esp) + 800890: 8b 45 08 mov 0x8(%ebp),%eax + 800893: ff d0 call *%eax + num = (unsigned long long)(uintptr_t)va_arg(ap, void *); + 800895: 8b 45 14 mov 0x14(%ebp),%eax + 800898: 8d 50 04 lea 0x4(%eax),%edx + 80089b: 89 55 14 mov %edx,0x14(%ebp) + 80089e: 8b 00 mov (%eax),%eax + 8008a0: 89 45 f0 mov %eax,-0x10(%ebp) + 8008a3: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + base = 16; + 8008aa: c7 45 ec 10 00 00 00 movl $0x10,-0x14(%ebp) + goto number; + 8008b1: eb 1f jmp 8008d2 + + // (unsigned) hexadecimal + case 'x': + num = getuint(&ap, lflag); + 8008b3: 8b 45 e0 mov -0x20(%ebp),%eax + 8008b6: 89 44 24 04 mov %eax,0x4(%esp) + 8008ba: 8d 45 14 lea 0x14(%ebp),%eax + 8008bd: 89 04 24 mov %eax,(%esp) + 8008c0: e8 ea fb ff ff call 8004af + 8008c5: 89 45 f0 mov %eax,-0x10(%ebp) + 8008c8: 89 55 f4 mov %edx,-0xc(%ebp) + base = 16; + 8008cb: c7 45 ec 10 00 00 00 movl $0x10,-0x14(%ebp) + number: + printnum(putch, putdat, num, base, width, padc); + 8008d2: 0f be 55 db movsbl -0x25(%ebp),%edx + 8008d6: 8b 45 ec mov -0x14(%ebp),%eax + 8008d9: 89 54 24 18 mov %edx,0x18(%esp) + 8008dd: 8b 55 e8 mov -0x18(%ebp),%edx + 8008e0: 89 54 24 14 mov %edx,0x14(%esp) + 8008e4: 89 44 24 10 mov %eax,0x10(%esp) + 8008e8: 8b 45 f0 mov -0x10(%ebp),%eax + 8008eb: 8b 55 f4 mov -0xc(%ebp),%edx + 8008ee: 89 44 24 08 mov %eax,0x8(%esp) + 8008f2: 89 54 24 0c mov %edx,0xc(%esp) + 8008f6: 8b 45 0c mov 0xc(%ebp),%eax + 8008f9: 89 44 24 04 mov %eax,0x4(%esp) + 8008fd: 8b 45 08 mov 0x8(%ebp),%eax + 800900: 89 04 24 mov %eax,(%esp) + 800903: e8 a5 fa ff ff call 8003ad + break; + 800908: eb 38 jmp 800942 + + // escaped '%' character + case '%': + putch(ch, putdat); + 80090a: 8b 45 0c mov 0xc(%ebp),%eax + 80090d: 89 44 24 04 mov %eax,0x4(%esp) + 800911: 89 1c 24 mov %ebx,(%esp) + 800914: 8b 45 08 mov 0x8(%ebp),%eax + 800917: ff d0 call *%eax + break; + 800919: eb 27 jmp 800942 + + // unrecognized escape sequence - just print it literally + default: + putch('%', putdat); + 80091b: 8b 45 0c mov 0xc(%ebp),%eax + 80091e: 89 44 24 04 mov %eax,0x4(%esp) + 800922: c7 04 24 25 00 00 00 movl $0x25,(%esp) + 800929: 8b 45 08 mov 0x8(%ebp),%eax + 80092c: ff d0 call *%eax + for (fmt --; fmt[-1] != '%'; fmt --) + 80092e: ff 4d 10 decl 0x10(%ebp) + 800931: eb 03 jmp 800936 + 800933: ff 4d 10 decl 0x10(%ebp) + 800936: 8b 45 10 mov 0x10(%ebp),%eax + 800939: 48 dec %eax + 80093a: 0f b6 00 movzbl (%eax),%eax + 80093d: 3c 25 cmp $0x25,%al + 80093f: 75 f2 jne 800933 + /* do nothing */; + break; + 800941: 90 nop + while (1) { + 800942: e9 37 fc ff ff jmp 80057e + return; + 800947: 90 nop + } + } +} + 800948: 83 c4 40 add $0x40,%esp + 80094b: 5b pop %ebx + 80094c: 5e pop %esi + 80094d: 5d pop %ebp + 80094e: c3 ret + +0080094f : + * sprintputch - 'print' a single character in a buffer + * @ch: the character will be printed + * @b: the buffer to place the character @ch + * */ +static void +sprintputch(int ch, struct sprintbuf *b) { + 80094f: 55 push %ebp + 800950: 89 e5 mov %esp,%ebp + b->cnt ++; + 800952: 8b 45 0c mov 0xc(%ebp),%eax + 800955: 8b 40 08 mov 0x8(%eax),%eax + 800958: 8d 50 01 lea 0x1(%eax),%edx + 80095b: 8b 45 0c mov 0xc(%ebp),%eax + 80095e: 89 50 08 mov %edx,0x8(%eax) + if (b->buf < b->ebuf) { + 800961: 8b 45 0c mov 0xc(%ebp),%eax + 800964: 8b 10 mov (%eax),%edx + 800966: 8b 45 0c mov 0xc(%ebp),%eax + 800969: 8b 40 04 mov 0x4(%eax),%eax + 80096c: 39 c2 cmp %eax,%edx + 80096e: 73 12 jae 800982 + *b->buf ++ = ch; + 800970: 8b 45 0c mov 0xc(%ebp),%eax + 800973: 8b 00 mov (%eax),%eax + 800975: 8d 48 01 lea 0x1(%eax),%ecx + 800978: 8b 55 0c mov 0xc(%ebp),%edx + 80097b: 89 0a mov %ecx,(%edx) + 80097d: 8b 55 08 mov 0x8(%ebp),%edx + 800980: 88 10 mov %dl,(%eax) + } +} + 800982: 90 nop + 800983: 5d pop %ebp + 800984: c3 ret + +00800985 : + * @str: the buffer to place the result into + * @size: the size of buffer, including the trailing null space + * @fmt: the format string to use + * */ +int +snprintf(char *str, size_t size, const char *fmt, ...) { + 800985: 55 push %ebp + 800986: 89 e5 mov %esp,%ebp + 800988: 83 ec 28 sub $0x28,%esp + va_list ap; + int cnt; + va_start(ap, fmt); + 80098b: 8d 45 14 lea 0x14(%ebp),%eax + 80098e: 89 45 f0 mov %eax,-0x10(%ebp) + cnt = vsnprintf(str, size, fmt, ap); + 800991: 8b 45 f0 mov -0x10(%ebp),%eax + 800994: 89 44 24 0c mov %eax,0xc(%esp) + 800998: 8b 45 10 mov 0x10(%ebp),%eax + 80099b: 89 44 24 08 mov %eax,0x8(%esp) + 80099f: 8b 45 0c mov 0xc(%ebp),%eax + 8009a2: 89 44 24 04 mov %eax,0x4(%esp) + 8009a6: 8b 45 08 mov 0x8(%ebp),%eax + 8009a9: 89 04 24 mov %eax,(%esp) + 8009ac: e8 0a 00 00 00 call 8009bb + 8009b1: 89 45 f4 mov %eax,-0xc(%ebp) + va_end(ap); + return cnt; + 8009b4: 8b 45 f4 mov -0xc(%ebp),%eax +} + 8009b7: 89 ec mov %ebp,%esp + 8009b9: 5d pop %ebp + 8009ba: c3 ret + +008009bb : + * + * Call this function if you are already dealing with a va_list. + * Or you probably want snprintf() instead. + * */ +int +vsnprintf(char *str, size_t size, const char *fmt, va_list ap) { + 8009bb: 55 push %ebp + 8009bc: 89 e5 mov %esp,%ebp + 8009be: 83 ec 28 sub $0x28,%esp + struct sprintbuf b = {str, str + size - 1, 0}; + 8009c1: 8b 45 08 mov 0x8(%ebp),%eax + 8009c4: 89 45 ec mov %eax,-0x14(%ebp) + 8009c7: 8b 45 0c mov 0xc(%ebp),%eax + 8009ca: 8d 50 ff lea -0x1(%eax),%edx + 8009cd: 8b 45 08 mov 0x8(%ebp),%eax + 8009d0: 01 d0 add %edx,%eax + 8009d2: 89 45 f0 mov %eax,-0x10(%ebp) + 8009d5: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + if (str == NULL || b.buf > b.ebuf) { + 8009dc: 83 7d 08 00 cmpl $0x0,0x8(%ebp) + 8009e0: 74 0a je 8009ec + 8009e2: 8b 55 ec mov -0x14(%ebp),%edx + 8009e5: 8b 45 f0 mov -0x10(%ebp),%eax + 8009e8: 39 c2 cmp %eax,%edx + 8009ea: 76 07 jbe 8009f3 + return -E_INVAL; + 8009ec: b8 fd ff ff ff mov $0xfffffffd,%eax + 8009f1: eb 2a jmp 800a1d + } + // print the string to the buffer + vprintfmt((void*)sprintputch, &b, fmt, ap); + 8009f3: 8b 45 14 mov 0x14(%ebp),%eax + 8009f6: 89 44 24 0c mov %eax,0xc(%esp) + 8009fa: 8b 45 10 mov 0x10(%ebp),%eax + 8009fd: 89 44 24 08 mov %eax,0x8(%esp) + 800a01: 8d 45 ec lea -0x14(%ebp),%eax + 800a04: 89 44 24 04 mov %eax,0x4(%esp) + 800a08: c7 04 24 4f 09 80 00 movl $0x80094f,(%esp) + 800a0f: e8 62 fb ff ff call 800576 + // null terminate the buffer + *b.buf = '\0'; + 800a14: 8b 45 ec mov -0x14(%ebp),%eax + 800a17: c6 00 00 movb $0x0,(%eax) + return b.cnt; + 800a1a: 8b 45 f4 mov -0xc(%ebp),%eax +} + 800a1d: 89 ec mov %ebp,%esp + 800a1f: 5d pop %ebp + 800a20: c3 ret + +00800a21 : + * rand - returns a pseudo-random integer + * + * The rand() function return a value in the range [0, RAND_MAX]. + * */ +int +rand(void) { + 800a21: 55 push %ebp + 800a22: 89 e5 mov %esp,%ebp + 800a24: 57 push %edi + 800a25: 56 push %esi + 800a26: 53 push %ebx + 800a27: 83 ec 24 sub $0x24,%esp + next = (next * 0x5DEECE66DLL + 0xBLL) & ((1LL << 48) - 1); + 800a2a: a1 00 20 80 00 mov 0x802000,%eax + 800a2f: 8b 15 04 20 80 00 mov 0x802004,%edx + 800a35: 69 fa 6d e6 ec de imul $0xdeece66d,%edx,%edi + 800a3b: 6b f0 05 imul $0x5,%eax,%esi + 800a3e: 01 fe add %edi,%esi + 800a40: bf 6d e6 ec de mov $0xdeece66d,%edi + 800a45: f7 e7 mul %edi + 800a47: 01 d6 add %edx,%esi + 800a49: 89 f2 mov %esi,%edx + 800a4b: 83 c0 0b add $0xb,%eax + 800a4e: 83 d2 00 adc $0x0,%edx + 800a51: 89 c7 mov %eax,%edi + 800a53: 83 e7 ff and $0xffffffff,%edi + 800a56: 89 f9 mov %edi,%ecx + 800a58: 0f b7 da movzwl %dx,%ebx + 800a5b: 89 0d 00 20 80 00 mov %ecx,0x802000 + 800a61: 89 1d 04 20 80 00 mov %ebx,0x802004 + unsigned long long result = (next >> 12); + 800a67: a1 00 20 80 00 mov 0x802000,%eax + 800a6c: 8b 15 04 20 80 00 mov 0x802004,%edx + 800a72: 0f ac d0 0c shrd $0xc,%edx,%eax + 800a76: c1 ea 0c shr $0xc,%edx + 800a79: 89 45 e0 mov %eax,-0x20(%ebp) + 800a7c: 89 55 e4 mov %edx,-0x1c(%ebp) + return (int)do_div(result, RAND_MAX + 1); + 800a7f: c7 45 dc 00 00 00 80 movl $0x80000000,-0x24(%ebp) + 800a86: 8b 45 e0 mov -0x20(%ebp),%eax + 800a89: 8b 55 e4 mov -0x1c(%ebp),%edx + 800a8c: 89 45 d8 mov %eax,-0x28(%ebp) + 800a8f: 89 55 e8 mov %edx,-0x18(%ebp) + 800a92: 8b 45 e8 mov -0x18(%ebp),%eax + 800a95: 89 45 ec mov %eax,-0x14(%ebp) + 800a98: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 800a9c: 74 1c je 800aba + 800a9e: 8b 45 e8 mov -0x18(%ebp),%eax + 800aa1: ba 00 00 00 00 mov $0x0,%edx + 800aa6: f7 75 dc divl -0x24(%ebp) + 800aa9: 89 55 ec mov %edx,-0x14(%ebp) + 800aac: 8b 45 e8 mov -0x18(%ebp),%eax + 800aaf: ba 00 00 00 00 mov $0x0,%edx + 800ab4: f7 75 dc divl -0x24(%ebp) + 800ab7: 89 45 e8 mov %eax,-0x18(%ebp) + 800aba: 8b 45 d8 mov -0x28(%ebp),%eax + 800abd: 8b 55 ec mov -0x14(%ebp),%edx + 800ac0: f7 75 dc divl -0x24(%ebp) + 800ac3: 89 45 d8 mov %eax,-0x28(%ebp) + 800ac6: 89 55 d4 mov %edx,-0x2c(%ebp) + 800ac9: 8b 45 d8 mov -0x28(%ebp),%eax + 800acc: 8b 55 e8 mov -0x18(%ebp),%edx + 800acf: 89 45 e0 mov %eax,-0x20(%ebp) + 800ad2: 89 55 e4 mov %edx,-0x1c(%ebp) + 800ad5: 8b 45 d4 mov -0x2c(%ebp),%eax +} + 800ad8: 83 c4 24 add $0x24,%esp + 800adb: 5b pop %ebx + 800adc: 5e pop %esi + 800add: 5f pop %edi + 800ade: 5d pop %ebp + 800adf: c3 ret + +00800ae0 : +/* * + * srand - seed the random number generator with the given number + * @seed: the required seed number + * */ +void +srand(unsigned int seed) { + 800ae0: 55 push %ebp + 800ae1: 89 e5 mov %esp,%ebp + next = seed; + 800ae3: 8b 45 08 mov 0x8(%ebp),%eax + 800ae6: ba 00 00 00 00 mov $0x0,%edx + 800aeb: a3 00 20 80 00 mov %eax,0x802000 + 800af0: 89 15 04 20 80 00 mov %edx,0x802004 +} + 800af6: 90 nop + 800af7: 5d pop %ebp + 800af8: c3 ret + +00800af9 : + * @s: the input string + * + * The strlen() function returns the length of string @s. + * */ +size_t +strlen(const char *s) { + 800af9: 55 push %ebp + 800afa: 89 e5 mov %esp,%ebp + 800afc: 83 ec 10 sub $0x10,%esp + size_t cnt = 0; + 800aff: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + while (*s ++ != '\0') { + 800b06: eb 03 jmp 800b0b + cnt ++; + 800b08: ff 45 fc incl -0x4(%ebp) + while (*s ++ != '\0') { + 800b0b: 8b 45 08 mov 0x8(%ebp),%eax + 800b0e: 8d 50 01 lea 0x1(%eax),%edx + 800b11: 89 55 08 mov %edx,0x8(%ebp) + 800b14: 0f b6 00 movzbl (%eax),%eax + 800b17: 84 c0 test %al,%al + 800b19: 75 ed jne 800b08 + } + return cnt; + 800b1b: 8b 45 fc mov -0x4(%ebp),%eax +} + 800b1e: 89 ec mov %ebp,%esp + 800b20: 5d pop %ebp + 800b21: c3 ret + +00800b22 : + * The return value is strlen(s), if that is less than @len, or + * @len if there is no '\0' character among the first @len characters + * pointed by @s. + * */ +size_t +strnlen(const char *s, size_t len) { + 800b22: 55 push %ebp + 800b23: 89 e5 mov %esp,%ebp + 800b25: 83 ec 10 sub $0x10,%esp + size_t cnt = 0; + 800b28: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + while (cnt < len && *s ++ != '\0') { + 800b2f: eb 03 jmp 800b34 + cnt ++; + 800b31: ff 45 fc incl -0x4(%ebp) + while (cnt < len && *s ++ != '\0') { + 800b34: 8b 45 fc mov -0x4(%ebp),%eax + 800b37: 3b 45 0c cmp 0xc(%ebp),%eax + 800b3a: 73 10 jae 800b4c + 800b3c: 8b 45 08 mov 0x8(%ebp),%eax + 800b3f: 8d 50 01 lea 0x1(%eax),%edx + 800b42: 89 55 08 mov %edx,0x8(%ebp) + 800b45: 0f b6 00 movzbl (%eax),%eax + 800b48: 84 c0 test %al,%al + 800b4a: 75 e5 jne 800b31 + } + return cnt; + 800b4c: 8b 45 fc mov -0x4(%ebp),%eax +} + 800b4f: 89 ec mov %ebp,%esp + 800b51: 5d pop %ebp + 800b52: c3 ret + +00800b53 : + * To avoid overflows, the size of array pointed by @dst should be long enough to + * contain the same string as @src (including the terminating null character), and + * should not overlap in memory with @src. + * */ +char * +strcpy(char *dst, const char *src) { + 800b53: 55 push %ebp + 800b54: 89 e5 mov %esp,%ebp + 800b56: 57 push %edi + 800b57: 56 push %esi + 800b58: 83 ec 20 sub $0x20,%esp + 800b5b: 8b 45 08 mov 0x8(%ebp),%eax + 800b5e: 89 45 f4 mov %eax,-0xc(%ebp) + 800b61: 8b 45 0c mov 0xc(%ebp),%eax + 800b64: 89 45 f0 mov %eax,-0x10(%ebp) +#ifndef __HAVE_ARCH_STRCPY +#define __HAVE_ARCH_STRCPY +static inline char * +__strcpy(char *dst, const char *src) { + int d0, d1, d2; + asm volatile ( + 800b67: 8b 55 f0 mov -0x10(%ebp),%edx + 800b6a: 8b 45 f4 mov -0xc(%ebp),%eax + 800b6d: 89 d1 mov %edx,%ecx + 800b6f: 89 c2 mov %eax,%edx + 800b71: 89 ce mov %ecx,%esi + 800b73: 89 d7 mov %edx,%edi + 800b75: ac lods %ds:(%esi),%al + 800b76: aa stos %al,%es:(%edi) + 800b77: 84 c0 test %al,%al + 800b79: 75 fa jne 800b75 + 800b7b: 89 fa mov %edi,%edx + 800b7d: 89 f1 mov %esi,%ecx + 800b7f: 89 4d ec mov %ecx,-0x14(%ebp) + 800b82: 89 55 e8 mov %edx,-0x18(%ebp) + 800b85: 89 45 e4 mov %eax,-0x1c(%ebp) + "stosb;" + "testb %%al, %%al;" + "jne 1b;" + : "=&S" (d0), "=&D" (d1), "=&a" (d2) + : "0" (src), "1" (dst) : "memory"); + return dst; + 800b88: 8b 45 f4 mov -0xc(%ebp),%eax + char *p = dst; + while ((*p ++ = *src ++) != '\0') + /* nothing */; + return dst; +#endif /* __HAVE_ARCH_STRCPY */ +} + 800b8b: 83 c4 20 add $0x20,%esp + 800b8e: 5e pop %esi + 800b8f: 5f pop %edi + 800b90: 5d pop %ebp + 800b91: c3 ret + +00800b92 : + * @len: maximum number of characters to be copied from @src + * + * The return value is @dst + * */ +char * +strncpy(char *dst, const char *src, size_t len) { + 800b92: 55 push %ebp + 800b93: 89 e5 mov %esp,%ebp + 800b95: 83 ec 10 sub $0x10,%esp + char *p = dst; + 800b98: 8b 45 08 mov 0x8(%ebp),%eax + 800b9b: 89 45 fc mov %eax,-0x4(%ebp) + while (len > 0) { + 800b9e: eb 1e jmp 800bbe + if ((*p = *src) != '\0') { + 800ba0: 8b 45 0c mov 0xc(%ebp),%eax + 800ba3: 0f b6 10 movzbl (%eax),%edx + 800ba6: 8b 45 fc mov -0x4(%ebp),%eax + 800ba9: 88 10 mov %dl,(%eax) + 800bab: 8b 45 fc mov -0x4(%ebp),%eax + 800bae: 0f b6 00 movzbl (%eax),%eax + 800bb1: 84 c0 test %al,%al + 800bb3: 74 03 je 800bb8 + src ++; + 800bb5: ff 45 0c incl 0xc(%ebp) + } + p ++, len --; + 800bb8: ff 45 fc incl -0x4(%ebp) + 800bbb: ff 4d 10 decl 0x10(%ebp) + while (len > 0) { + 800bbe: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800bc2: 75 dc jne 800ba0 + } + return dst; + 800bc4: 8b 45 08 mov 0x8(%ebp),%eax +} + 800bc7: 89 ec mov %ebp,%esp + 800bc9: 5d pop %ebp + 800bca: c3 ret + +00800bcb : + * - A value greater than zero indicates that the first character that does + * not match has a greater value in @s1 than in @s2; + * - And a value less than zero indicates the opposite. + * */ +int +strcmp(const char *s1, const char *s2) { + 800bcb: 55 push %ebp + 800bcc: 89 e5 mov %esp,%ebp + 800bce: 57 push %edi + 800bcf: 56 push %esi + 800bd0: 83 ec 20 sub $0x20,%esp + 800bd3: 8b 45 08 mov 0x8(%ebp),%eax + 800bd6: 89 45 f4 mov %eax,-0xc(%ebp) + 800bd9: 8b 45 0c mov 0xc(%ebp),%eax + 800bdc: 89 45 f0 mov %eax,-0x10(%ebp) + asm volatile ( + 800bdf: 8b 55 f4 mov -0xc(%ebp),%edx + 800be2: 8b 45 f0 mov -0x10(%ebp),%eax + 800be5: 89 d1 mov %edx,%ecx + 800be7: 89 c2 mov %eax,%edx + 800be9: 89 ce mov %ecx,%esi + 800beb: 89 d7 mov %edx,%edi + 800bed: ac lods %ds:(%esi),%al + 800bee: ae scas %es:(%edi),%al + 800bef: 75 08 jne 800bf9 + 800bf1: 84 c0 test %al,%al + 800bf3: 75 f8 jne 800bed + 800bf5: 31 c0 xor %eax,%eax + 800bf7: eb 04 jmp 800bfd + 800bf9: 19 c0 sbb %eax,%eax + 800bfb: 0c 01 or $0x1,%al + 800bfd: 89 fa mov %edi,%edx + 800bff: 89 f1 mov %esi,%ecx + 800c01: 89 45 ec mov %eax,-0x14(%ebp) + 800c04: 89 4d e8 mov %ecx,-0x18(%ebp) + 800c07: 89 55 e4 mov %edx,-0x1c(%ebp) + return ret; + 800c0a: 8b 45 ec mov -0x14(%ebp),%eax + while (*s1 != '\0' && *s1 == *s2) { + s1 ++, s2 ++; + } + return (int)((unsigned char)*s1 - (unsigned char)*s2); +#endif /* __HAVE_ARCH_STRCMP */ +} + 800c0d: 83 c4 20 add $0x20,%esp + 800c10: 5e pop %esi + 800c11: 5f pop %edi + 800c12: 5d pop %ebp + 800c13: c3 ret + +00800c14 : + * they are equal to each other, it continues with the following pairs until + * the characters differ, until a terminating null-character is reached, or + * until @n characters match in both strings, whichever happens first. + * */ +int +strncmp(const char *s1, const char *s2, size_t n) { + 800c14: 55 push %ebp + 800c15: 89 e5 mov %esp,%ebp + while (n > 0 && *s1 != '\0' && *s1 == *s2) { + 800c17: eb 09 jmp 800c22 + n --, s1 ++, s2 ++; + 800c19: ff 4d 10 decl 0x10(%ebp) + 800c1c: ff 45 08 incl 0x8(%ebp) + 800c1f: ff 45 0c incl 0xc(%ebp) + while (n > 0 && *s1 != '\0' && *s1 == *s2) { + 800c22: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800c26: 74 1a je 800c42 + 800c28: 8b 45 08 mov 0x8(%ebp),%eax + 800c2b: 0f b6 00 movzbl (%eax),%eax + 800c2e: 84 c0 test %al,%al + 800c30: 74 10 je 800c42 + 800c32: 8b 45 08 mov 0x8(%ebp),%eax + 800c35: 0f b6 10 movzbl (%eax),%edx + 800c38: 8b 45 0c mov 0xc(%ebp),%eax + 800c3b: 0f b6 00 movzbl (%eax),%eax + 800c3e: 38 c2 cmp %al,%dl + 800c40: 74 d7 je 800c19 + } + return (n == 0) ? 0 : (int)((unsigned char)*s1 - (unsigned char)*s2); + 800c42: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800c46: 74 18 je 800c60 + 800c48: 8b 45 08 mov 0x8(%ebp),%eax + 800c4b: 0f b6 00 movzbl (%eax),%eax + 800c4e: 0f b6 d0 movzbl %al,%edx + 800c51: 8b 45 0c mov 0xc(%ebp),%eax + 800c54: 0f b6 00 movzbl (%eax),%eax + 800c57: 0f b6 c8 movzbl %al,%ecx + 800c5a: 89 d0 mov %edx,%eax + 800c5c: 29 c8 sub %ecx,%eax + 800c5e: eb 05 jmp 800c65 + 800c60: b8 00 00 00 00 mov $0x0,%eax +} + 800c65: 5d pop %ebp + 800c66: c3 ret + +00800c67 : + * + * The strchr() function returns a pointer to the first occurrence of + * character in @s. If the value is not found, the function returns 'NULL'. + * */ +char * +strchr(const char *s, char c) { + 800c67: 55 push %ebp + 800c68: 89 e5 mov %esp,%ebp + 800c6a: 83 ec 04 sub $0x4,%esp + 800c6d: 8b 45 0c mov 0xc(%ebp),%eax + 800c70: 88 45 fc mov %al,-0x4(%ebp) + while (*s != '\0') { + 800c73: eb 13 jmp 800c88 + if (*s == c) { + 800c75: 8b 45 08 mov 0x8(%ebp),%eax + 800c78: 0f b6 00 movzbl (%eax),%eax + 800c7b: 38 45 fc cmp %al,-0x4(%ebp) + 800c7e: 75 05 jne 800c85 + return (char *)s; + 800c80: 8b 45 08 mov 0x8(%ebp),%eax + 800c83: eb 12 jmp 800c97 + } + s ++; + 800c85: ff 45 08 incl 0x8(%ebp) + while (*s != '\0') { + 800c88: 8b 45 08 mov 0x8(%ebp),%eax + 800c8b: 0f b6 00 movzbl (%eax),%eax + 800c8e: 84 c0 test %al,%al + 800c90: 75 e3 jne 800c75 + } + return NULL; + 800c92: b8 00 00 00 00 mov $0x0,%eax +} + 800c97: 89 ec mov %ebp,%esp + 800c99: 5d pop %ebp + 800c9a: c3 ret + +00800c9b : + * The strfind() function is like strchr() except that if @c is + * not found in @s, then it returns a pointer to the null byte at the + * end of @s, rather than 'NULL'. + * */ +char * +strfind(const char *s, char c) { + 800c9b: 55 push %ebp + 800c9c: 89 e5 mov %esp,%ebp + 800c9e: 83 ec 04 sub $0x4,%esp + 800ca1: 8b 45 0c mov 0xc(%ebp),%eax + 800ca4: 88 45 fc mov %al,-0x4(%ebp) + while (*s != '\0') { + 800ca7: eb 0e jmp 800cb7 + if (*s == c) { + 800ca9: 8b 45 08 mov 0x8(%ebp),%eax + 800cac: 0f b6 00 movzbl (%eax),%eax + 800caf: 38 45 fc cmp %al,-0x4(%ebp) + 800cb2: 74 0f je 800cc3 + break; + } + s ++; + 800cb4: ff 45 08 incl 0x8(%ebp) + while (*s != '\0') { + 800cb7: 8b 45 08 mov 0x8(%ebp),%eax + 800cba: 0f b6 00 movzbl (%eax),%eax + 800cbd: 84 c0 test %al,%al + 800cbf: 75 e8 jne 800ca9 + 800cc1: eb 01 jmp 800cc4 + break; + 800cc3: 90 nop + } + return (char *)s; + 800cc4: 8b 45 08 mov 0x8(%ebp),%eax +} + 800cc7: 89 ec mov %ebp,%esp + 800cc9: 5d pop %ebp + 800cca: c3 ret + +00800ccb : + * an optional "0x" or "0X" prefix. + * + * The strtol() function returns the converted integral number as a long int value. + * */ +long +strtol(const char *s, char **endptr, int base) { + 800ccb: 55 push %ebp + 800ccc: 89 e5 mov %esp,%ebp + 800cce: 83 ec 10 sub $0x10,%esp + int neg = 0; + 800cd1: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + long val = 0; + 800cd8: c7 45 f8 00 00 00 00 movl $0x0,-0x8(%ebp) + + // gobble initial whitespace + while (*s == ' ' || *s == '\t') { + 800cdf: eb 03 jmp 800ce4 + s ++; + 800ce1: ff 45 08 incl 0x8(%ebp) + while (*s == ' ' || *s == '\t') { + 800ce4: 8b 45 08 mov 0x8(%ebp),%eax + 800ce7: 0f b6 00 movzbl (%eax),%eax + 800cea: 3c 20 cmp $0x20,%al + 800cec: 74 f3 je 800ce1 + 800cee: 8b 45 08 mov 0x8(%ebp),%eax + 800cf1: 0f b6 00 movzbl (%eax),%eax + 800cf4: 3c 09 cmp $0x9,%al + 800cf6: 74 e9 je 800ce1 + } + + // plus/minus sign + if (*s == '+') { + 800cf8: 8b 45 08 mov 0x8(%ebp),%eax + 800cfb: 0f b6 00 movzbl (%eax),%eax + 800cfe: 3c 2b cmp $0x2b,%al + 800d00: 75 05 jne 800d07 + s ++; + 800d02: ff 45 08 incl 0x8(%ebp) + 800d05: eb 14 jmp 800d1b + } + else if (*s == '-') { + 800d07: 8b 45 08 mov 0x8(%ebp),%eax + 800d0a: 0f b6 00 movzbl (%eax),%eax + 800d0d: 3c 2d cmp $0x2d,%al + 800d0f: 75 0a jne 800d1b + s ++, neg = 1; + 800d11: ff 45 08 incl 0x8(%ebp) + 800d14: c7 45 fc 01 00 00 00 movl $0x1,-0x4(%ebp) + } + + // hex or octal base prefix + if ((base == 0 || base == 16) && (s[0] == '0' && s[1] == 'x')) { + 800d1b: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800d1f: 74 06 je 800d27 + 800d21: 83 7d 10 10 cmpl $0x10,0x10(%ebp) + 800d25: 75 22 jne 800d49 + 800d27: 8b 45 08 mov 0x8(%ebp),%eax + 800d2a: 0f b6 00 movzbl (%eax),%eax + 800d2d: 3c 30 cmp $0x30,%al + 800d2f: 75 18 jne 800d49 + 800d31: 8b 45 08 mov 0x8(%ebp),%eax + 800d34: 40 inc %eax + 800d35: 0f b6 00 movzbl (%eax),%eax + 800d38: 3c 78 cmp $0x78,%al + 800d3a: 75 0d jne 800d49 + s += 2, base = 16; + 800d3c: 83 45 08 02 addl $0x2,0x8(%ebp) + 800d40: c7 45 10 10 00 00 00 movl $0x10,0x10(%ebp) + 800d47: eb 29 jmp 800d72 + } + else if (base == 0 && s[0] == '0') { + 800d49: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800d4d: 75 16 jne 800d65 + 800d4f: 8b 45 08 mov 0x8(%ebp),%eax + 800d52: 0f b6 00 movzbl (%eax),%eax + 800d55: 3c 30 cmp $0x30,%al + 800d57: 75 0c jne 800d65 + s ++, base = 8; + 800d59: ff 45 08 incl 0x8(%ebp) + 800d5c: c7 45 10 08 00 00 00 movl $0x8,0x10(%ebp) + 800d63: eb 0d jmp 800d72 + } + else if (base == 0) { + 800d65: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800d69: 75 07 jne 800d72 + base = 10; + 800d6b: c7 45 10 0a 00 00 00 movl $0xa,0x10(%ebp) + + // digits + while (1) { + int dig; + + if (*s >= '0' && *s <= '9') { + 800d72: 8b 45 08 mov 0x8(%ebp),%eax + 800d75: 0f b6 00 movzbl (%eax),%eax + 800d78: 3c 2f cmp $0x2f,%al + 800d7a: 7e 1b jle 800d97 + 800d7c: 8b 45 08 mov 0x8(%ebp),%eax + 800d7f: 0f b6 00 movzbl (%eax),%eax + 800d82: 3c 39 cmp $0x39,%al + 800d84: 7f 11 jg 800d97 + dig = *s - '0'; + 800d86: 8b 45 08 mov 0x8(%ebp),%eax + 800d89: 0f b6 00 movzbl (%eax),%eax + 800d8c: 0f be c0 movsbl %al,%eax + 800d8f: 83 e8 30 sub $0x30,%eax + 800d92: 89 45 f4 mov %eax,-0xc(%ebp) + 800d95: eb 48 jmp 800ddf + } + else if (*s >= 'a' && *s <= 'z') { + 800d97: 8b 45 08 mov 0x8(%ebp),%eax + 800d9a: 0f b6 00 movzbl (%eax),%eax + 800d9d: 3c 60 cmp $0x60,%al + 800d9f: 7e 1b jle 800dbc + 800da1: 8b 45 08 mov 0x8(%ebp),%eax + 800da4: 0f b6 00 movzbl (%eax),%eax + 800da7: 3c 7a cmp $0x7a,%al + 800da9: 7f 11 jg 800dbc + dig = *s - 'a' + 10; + 800dab: 8b 45 08 mov 0x8(%ebp),%eax + 800dae: 0f b6 00 movzbl (%eax),%eax + 800db1: 0f be c0 movsbl %al,%eax + 800db4: 83 e8 57 sub $0x57,%eax + 800db7: 89 45 f4 mov %eax,-0xc(%ebp) + 800dba: eb 23 jmp 800ddf + } + else if (*s >= 'A' && *s <= 'Z') { + 800dbc: 8b 45 08 mov 0x8(%ebp),%eax + 800dbf: 0f b6 00 movzbl (%eax),%eax + 800dc2: 3c 40 cmp $0x40,%al + 800dc4: 7e 3b jle 800e01 + 800dc6: 8b 45 08 mov 0x8(%ebp),%eax + 800dc9: 0f b6 00 movzbl (%eax),%eax + 800dcc: 3c 5a cmp $0x5a,%al + 800dce: 7f 31 jg 800e01 + dig = *s - 'A' + 10; + 800dd0: 8b 45 08 mov 0x8(%ebp),%eax + 800dd3: 0f b6 00 movzbl (%eax),%eax + 800dd6: 0f be c0 movsbl %al,%eax + 800dd9: 83 e8 37 sub $0x37,%eax + 800ddc: 89 45 f4 mov %eax,-0xc(%ebp) + } + else { + break; + } + if (dig >= base) { + 800ddf: 8b 45 f4 mov -0xc(%ebp),%eax + 800de2: 3b 45 10 cmp 0x10(%ebp),%eax + 800de5: 7d 19 jge 800e00 + break; + } + s ++, val = (val * base) + dig; + 800de7: ff 45 08 incl 0x8(%ebp) + 800dea: 8b 45 f8 mov -0x8(%ebp),%eax + 800ded: 0f af 45 10 imul 0x10(%ebp),%eax + 800df1: 89 c2 mov %eax,%edx + 800df3: 8b 45 f4 mov -0xc(%ebp),%eax + 800df6: 01 d0 add %edx,%eax + 800df8: 89 45 f8 mov %eax,-0x8(%ebp) + while (1) { + 800dfb: e9 72 ff ff ff jmp 800d72 + break; + 800e00: 90 nop + // we don't properly detect overflow! + } + + if (endptr) { + 800e01: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) + 800e05: 74 08 je 800e0f + *endptr = (char *) s; + 800e07: 8b 45 0c mov 0xc(%ebp),%eax + 800e0a: 8b 55 08 mov 0x8(%ebp),%edx + 800e0d: 89 10 mov %edx,(%eax) + } + return (neg ? -val : val); + 800e0f: 83 7d fc 00 cmpl $0x0,-0x4(%ebp) + 800e13: 74 07 je 800e1c + 800e15: 8b 45 f8 mov -0x8(%ebp),%eax + 800e18: f7 d8 neg %eax + 800e1a: eb 03 jmp 800e1f + 800e1c: 8b 45 f8 mov -0x8(%ebp),%eax +} + 800e1f: 89 ec mov %ebp,%esp + 800e21: 5d pop %ebp + 800e22: c3 ret + +00800e23 : + * @n: number of bytes to be set to the value + * + * The memset() function returns @s. + * */ +void * +memset(void *s, char c, size_t n) { + 800e23: 55 push %ebp + 800e24: 89 e5 mov %esp,%ebp + 800e26: 83 ec 28 sub $0x28,%esp + 800e29: 89 7d fc mov %edi,-0x4(%ebp) + 800e2c: 8b 45 0c mov 0xc(%ebp),%eax + 800e2f: 88 45 d8 mov %al,-0x28(%ebp) +#ifdef __HAVE_ARCH_MEMSET + return __memset(s, c, n); + 800e32: 0f be 55 d8 movsbl -0x28(%ebp),%edx + 800e36: 8b 45 08 mov 0x8(%ebp),%eax + 800e39: 89 45 f8 mov %eax,-0x8(%ebp) + 800e3c: 88 55 f7 mov %dl,-0x9(%ebp) + 800e3f: 8b 45 10 mov 0x10(%ebp),%eax + 800e42: 89 45 f0 mov %eax,-0x10(%ebp) +#ifndef __HAVE_ARCH_MEMSET +#define __HAVE_ARCH_MEMSET +static inline void * +__memset(void *s, char c, size_t n) { + int d0, d1; + asm volatile ( + 800e45: 8b 4d f0 mov -0x10(%ebp),%ecx + 800e48: 0f b6 45 f7 movzbl -0x9(%ebp),%eax + 800e4c: 8b 55 f8 mov -0x8(%ebp),%edx + 800e4f: 89 d7 mov %edx,%edi + 800e51: f3 aa rep stos %al,%es:(%edi) + 800e53: 89 fa mov %edi,%edx + 800e55: 89 4d ec mov %ecx,-0x14(%ebp) + 800e58: 89 55 e8 mov %edx,-0x18(%ebp) + "rep; stosb;" + : "=&c" (d0), "=&D" (d1) + : "0" (n), "a" (c), "1" (s) + : "memory"); + return s; + 800e5b: 8b 45 f8 mov -0x8(%ebp),%eax + while (n -- > 0) { + *p ++ = c; + } + return s; +#endif /* __HAVE_ARCH_MEMSET */ +} + 800e5e: 8b 7d fc mov -0x4(%ebp),%edi + 800e61: 89 ec mov %ebp,%esp + 800e63: 5d pop %ebp + 800e64: c3 ret + +00800e65 : + * @n: number of bytes to copy + * + * The memmove() function returns @dst. + * */ +void * +memmove(void *dst, const void *src, size_t n) { + 800e65: 55 push %ebp + 800e66: 89 e5 mov %esp,%ebp + 800e68: 57 push %edi + 800e69: 56 push %esi + 800e6a: 53 push %ebx + 800e6b: 83 ec 30 sub $0x30,%esp + 800e6e: 8b 45 08 mov 0x8(%ebp),%eax + 800e71: 89 45 f0 mov %eax,-0x10(%ebp) + 800e74: 8b 45 0c mov 0xc(%ebp),%eax + 800e77: 89 45 ec mov %eax,-0x14(%ebp) + 800e7a: 8b 45 10 mov 0x10(%ebp),%eax + 800e7d: 89 45 e8 mov %eax,-0x18(%ebp) + +#ifndef __HAVE_ARCH_MEMMOVE +#define __HAVE_ARCH_MEMMOVE +static inline void * +__memmove(void *dst, const void *src, size_t n) { + if (dst < src) { + 800e80: 8b 45 f0 mov -0x10(%ebp),%eax + 800e83: 3b 45 ec cmp -0x14(%ebp),%eax + 800e86: 73 42 jae 800eca + 800e88: 8b 45 f0 mov -0x10(%ebp),%eax + 800e8b: 89 45 e4 mov %eax,-0x1c(%ebp) + 800e8e: 8b 45 ec mov -0x14(%ebp),%eax + 800e91: 89 45 e0 mov %eax,-0x20(%ebp) + 800e94: 8b 45 e8 mov -0x18(%ebp),%eax + 800e97: 89 45 dc mov %eax,-0x24(%ebp) + "andl $3, %%ecx;" + "jz 1f;" + "rep; movsb;" + "1:" + : "=&c" (d0), "=&D" (d1), "=&S" (d2) + : "0" (n / 4), "g" (n), "1" (dst), "2" (src) + 800e9a: 8b 45 dc mov -0x24(%ebp),%eax + 800e9d: c1 e8 02 shr $0x2,%eax + 800ea0: 89 c1 mov %eax,%ecx + asm volatile ( + 800ea2: 8b 55 e4 mov -0x1c(%ebp),%edx + 800ea5: 8b 45 e0 mov -0x20(%ebp),%eax + 800ea8: 89 d7 mov %edx,%edi + 800eaa: 89 c6 mov %eax,%esi + 800eac: f3 a5 rep movsl %ds:(%esi),%es:(%edi) + 800eae: 8b 4d dc mov -0x24(%ebp),%ecx + 800eb1: 83 e1 03 and $0x3,%ecx + 800eb4: 74 02 je 800eb8 + 800eb6: f3 a4 rep movsb %ds:(%esi),%es:(%edi) + 800eb8: 89 f0 mov %esi,%eax + 800eba: 89 fa mov %edi,%edx + 800ebc: 89 4d d8 mov %ecx,-0x28(%ebp) + 800ebf: 89 55 d4 mov %edx,-0x2c(%ebp) + 800ec2: 89 45 d0 mov %eax,-0x30(%ebp) + : "memory"); + return dst; + 800ec5: 8b 45 e4 mov -0x1c(%ebp),%eax + return __memcpy(dst, src, n); + 800ec8: eb 36 jmp 800f00 + : "0" (n), "1" (n - 1 + src), "2" (n - 1 + dst) + 800eca: 8b 45 e8 mov -0x18(%ebp),%eax + 800ecd: 8d 50 ff lea -0x1(%eax),%edx + 800ed0: 8b 45 ec mov -0x14(%ebp),%eax + 800ed3: 01 c2 add %eax,%edx + 800ed5: 8b 45 e8 mov -0x18(%ebp),%eax + 800ed8: 8d 48 ff lea -0x1(%eax),%ecx + 800edb: 8b 45 f0 mov -0x10(%ebp),%eax + 800ede: 8d 1c 01 lea (%ecx,%eax,1),%ebx + asm volatile ( + 800ee1: 8b 45 e8 mov -0x18(%ebp),%eax + 800ee4: 89 c1 mov %eax,%ecx + 800ee6: 89 d8 mov %ebx,%eax + 800ee8: 89 d6 mov %edx,%esi + 800eea: 89 c7 mov %eax,%edi + 800eec: fd std + 800eed: f3 a4 rep movsb %ds:(%esi),%es:(%edi) + 800eef: fc cld + 800ef0: 89 f8 mov %edi,%eax + 800ef2: 89 f2 mov %esi,%edx + 800ef4: 89 4d cc mov %ecx,-0x34(%ebp) + 800ef7: 89 55 c8 mov %edx,-0x38(%ebp) + 800efa: 89 45 c4 mov %eax,-0x3c(%ebp) + return dst; + 800efd: 8b 45 f0 mov -0x10(%ebp),%eax + *d ++ = *s ++; + } + } + return dst; +#endif /* __HAVE_ARCH_MEMMOVE */ +} + 800f00: 83 c4 30 add $0x30,%esp + 800f03: 5b pop %ebx + 800f04: 5e pop %esi + 800f05: 5f pop %edi + 800f06: 5d pop %ebp + 800f07: c3 ret + +00800f08 : + * it always copies exactly @n bytes. To avoid overflows, the size of arrays pointed + * by both @src and @dst, should be at least @n bytes, and should not overlap + * (for overlapping memory area, memmove is a safer approach). + * */ +void * +memcpy(void *dst, const void *src, size_t n) { + 800f08: 55 push %ebp + 800f09: 89 e5 mov %esp,%ebp + 800f0b: 57 push %edi + 800f0c: 56 push %esi + 800f0d: 83 ec 20 sub $0x20,%esp + 800f10: 8b 45 08 mov 0x8(%ebp),%eax + 800f13: 89 45 f4 mov %eax,-0xc(%ebp) + 800f16: 8b 45 0c mov 0xc(%ebp),%eax + 800f19: 89 45 f0 mov %eax,-0x10(%ebp) + 800f1c: 8b 45 10 mov 0x10(%ebp),%eax + 800f1f: 89 45 ec mov %eax,-0x14(%ebp) + : "0" (n / 4), "g" (n), "1" (dst), "2" (src) + 800f22: 8b 45 ec mov -0x14(%ebp),%eax + 800f25: c1 e8 02 shr $0x2,%eax + 800f28: 89 c1 mov %eax,%ecx + asm volatile ( + 800f2a: 8b 55 f4 mov -0xc(%ebp),%edx + 800f2d: 8b 45 f0 mov -0x10(%ebp),%eax + 800f30: 89 d7 mov %edx,%edi + 800f32: 89 c6 mov %eax,%esi + 800f34: f3 a5 rep movsl %ds:(%esi),%es:(%edi) + 800f36: 8b 4d ec mov -0x14(%ebp),%ecx + 800f39: 83 e1 03 and $0x3,%ecx + 800f3c: 74 02 je 800f40 + 800f3e: f3 a4 rep movsb %ds:(%esi),%es:(%edi) + 800f40: 89 f0 mov %esi,%eax + 800f42: 89 fa mov %edi,%edx + 800f44: 89 4d e8 mov %ecx,-0x18(%ebp) + 800f47: 89 55 e4 mov %edx,-0x1c(%ebp) + 800f4a: 89 45 e0 mov %eax,-0x20(%ebp) + return dst; + 800f4d: 8b 45 f4 mov -0xc(%ebp),%eax + while (n -- > 0) { + *d ++ = *s ++; + } + return dst; +#endif /* __HAVE_ARCH_MEMCPY */ +} + 800f50: 83 c4 20 add $0x20,%esp + 800f53: 5e pop %esi + 800f54: 5f pop %edi + 800f55: 5d pop %ebp + 800f56: c3 ret + +00800f57 : + * match in both memory blocks has a greater value in @v1 than in @v2 + * as if evaluated as unsigned char values; + * - And a value less than zero indicates the opposite. + * */ +int +memcmp(const void *v1, const void *v2, size_t n) { + 800f57: 55 push %ebp + 800f58: 89 e5 mov %esp,%ebp + 800f5a: 83 ec 10 sub $0x10,%esp + const char *s1 = (const char *)v1; + 800f5d: 8b 45 08 mov 0x8(%ebp),%eax + 800f60: 89 45 fc mov %eax,-0x4(%ebp) + const char *s2 = (const char *)v2; + 800f63: 8b 45 0c mov 0xc(%ebp),%eax + 800f66: 89 45 f8 mov %eax,-0x8(%ebp) + while (n -- > 0) { + 800f69: eb 2e jmp 800f99 + if (*s1 != *s2) { + 800f6b: 8b 45 fc mov -0x4(%ebp),%eax + 800f6e: 0f b6 10 movzbl (%eax),%edx + 800f71: 8b 45 f8 mov -0x8(%ebp),%eax + 800f74: 0f b6 00 movzbl (%eax),%eax + 800f77: 38 c2 cmp %al,%dl + 800f79: 74 18 je 800f93 + return (int)((unsigned char)*s1 - (unsigned char)*s2); + 800f7b: 8b 45 fc mov -0x4(%ebp),%eax + 800f7e: 0f b6 00 movzbl (%eax),%eax + 800f81: 0f b6 d0 movzbl %al,%edx + 800f84: 8b 45 f8 mov -0x8(%ebp),%eax + 800f87: 0f b6 00 movzbl (%eax),%eax + 800f8a: 0f b6 c8 movzbl %al,%ecx + 800f8d: 89 d0 mov %edx,%eax + 800f8f: 29 c8 sub %ecx,%eax + 800f91: eb 18 jmp 800fab + } + s1 ++, s2 ++; + 800f93: ff 45 fc incl -0x4(%ebp) + 800f96: ff 45 f8 incl -0x8(%ebp) + while (n -- > 0) { + 800f99: 8b 45 10 mov 0x10(%ebp),%eax + 800f9c: 8d 50 ff lea -0x1(%eax),%edx + 800f9f: 89 55 10 mov %edx,0x10(%ebp) + 800fa2: 85 c0 test %eax,%eax + 800fa4: 75 c5 jne 800f6b + } + return 0; + 800fa6: b8 00 00 00 00 mov $0x0,%eax +} + 800fab: 89 ec mov %ebp,%esp + 800fad: 5d pop %ebp + 800fae: c3 ret + +00800faf
: +#include + +const int max_child = 32; + +int +main(void) { + 800faf: 55 push %ebp + 800fb0: 89 e5 mov %esp,%ebp + 800fb2: 83 e4 f0 and $0xfffffff0,%esp + 800fb5: 83 ec 20 sub $0x20,%esp + int n, pid; + for (n = 0; n < max_child; n ++) { + 800fb8: c7 44 24 1c 00 00 00 movl $0x0,0x1c(%esp) + 800fbf: 00 + 800fc0: eb 5f jmp 801021 + if ((pid = fork()) == 0) { + 800fc2: e8 19 f3 ff ff call 8002e0 + 800fc7: 89 44 24 18 mov %eax,0x18(%esp) + 800fcb: 83 7c 24 18 00 cmpl $0x0,0x18(%esp) + 800fd0: 75 20 jne 800ff2 + cprintf("I am child %d\n", n); + 800fd2: 8b 44 24 1c mov 0x1c(%esp),%eax + 800fd6: 89 44 24 04 mov %eax,0x4(%esp) + 800fda: c7 04 24 c4 13 80 00 movl $0x8013c4,(%esp) + 800fe1: e8 3a f1 ff ff call 800120 + exit(0); + 800fe6: c7 04 24 00 00 00 00 movl $0x0,(%esp) + 800fed: e8 cf f2 ff ff call 8002c1 + } + assert(pid > 0); + 800ff2: 83 7c 24 18 00 cmpl $0x0,0x18(%esp) + 800ff7: 7f 24 jg 80101d + 800ff9: c7 44 24 0c d3 13 80 movl $0x8013d3,0xc(%esp) + 801000: 00 + 801001: c7 44 24 08 db 13 80 movl $0x8013db,0x8(%esp) + 801008: 00 + 801009: c7 44 24 04 0e 00 00 movl $0xe,0x4(%esp) + 801010: 00 + 801011: c7 04 24 f0 13 80 00 movl $0x8013f0,(%esp) + 801018: e8 12 f0 ff ff call 80002f <__panic> + for (n = 0; n < max_child; n ++) { + 80101d: ff 44 24 1c incl 0x1c(%esp) + 801021: b8 20 00 00 00 mov $0x20,%eax + 801026: 39 44 24 1c cmp %eax,0x1c(%esp) + 80102a: 7c 96 jl 800fc2 + } + + if (n > max_child) { + 80102c: b8 20 00 00 00 mov $0x20,%eax + 801031: 39 44 24 1c cmp %eax,0x1c(%esp) + 801035: 7e 4d jle 801084 + panic("fork claimed to work %d times!\n", n); + 801037: 8b 44 24 1c mov 0x1c(%esp),%eax + 80103b: 89 44 24 0c mov %eax,0xc(%esp) + 80103f: c7 44 24 08 00 14 80 movl $0x801400,0x8(%esp) + 801046: 00 + 801047: c7 44 24 04 12 00 00 movl $0x12,0x4(%esp) + 80104e: 00 + 80104f: c7 04 24 f0 13 80 00 movl $0x8013f0,(%esp) + 801056: e8 d4 ef ff ff call 80002f <__panic> + } + + for (; n > 0; n --) { + if (wait() != 0) { + 80105b: e8 8f f2 ff ff call 8002ef + 801060: 85 c0 test %eax,%eax + 801062: 74 1c je 801080 + panic("wait stopped early\n"); + 801064: c7 44 24 08 20 14 80 movl $0x801420,0x8(%esp) + 80106b: 00 + 80106c: c7 44 24 04 17 00 00 movl $0x17,0x4(%esp) + 801073: 00 + 801074: c7 04 24 f0 13 80 00 movl $0x8013f0,(%esp) + 80107b: e8 af ef ff ff call 80002f <__panic> + for (; n > 0; n --) { + 801080: ff 4c 24 1c decl 0x1c(%esp) + 801084: 83 7c 24 1c 00 cmpl $0x0,0x1c(%esp) + 801089: 7f d0 jg 80105b + } + } + + if (wait() == 0) { + 80108b: e8 5f f2 ff ff call 8002ef + 801090: 85 c0 test %eax,%eax + 801092: 75 1c jne 8010b0 + panic("wait got too many\n"); + 801094: c7 44 24 08 34 14 80 movl $0x801434,0x8(%esp) + 80109b: 00 + 80109c: c7 44 24 04 1c 00 00 movl $0x1c,0x4(%esp) + 8010a3: 00 + 8010a4: c7 04 24 f0 13 80 00 movl $0x8013f0,(%esp) + 8010ab: e8 7f ef ff ff call 80002f <__panic> + } + + cprintf("forktest pass.\n"); + 8010b0: c7 04 24 47 14 80 00 movl $0x801447,(%esp) + 8010b7: e8 64 f0 ff ff call 800120 + return 0; + 8010bc: b8 00 00 00 00 mov $0x0,%eax +} + 8010c1: 89 ec mov %ebp,%esp + 8010c3: 5d pop %ebp + 8010c4: c3 ret diff --git a/labcodes/lab5/obj/user/forktest.d b/labcodes/lab5/obj/user/forktest.d new file mode 100644 index 0000000000000000000000000000000000000000..84980a320b04f78a3b13338b9464d1b333d6f695 --- /dev/null +++ b/labcodes/lab5/obj/user/forktest.d @@ -0,0 +1,2 @@ +obj/user/forktest.o obj/user/forktest.d: user/forktest.c user/libs/ulib.h \ + libs/defs.h libs/stdio.h libs/stdarg.h diff --git a/labcodes/lab5/obj/user/forktest.o b/labcodes/lab5/obj/user/forktest.o new file mode 100644 index 0000000000000000000000000000000000000000..75c365f29ef54d57a0c7e35ba14802ad1638e223 Binary files /dev/null and b/labcodes/lab5/obj/user/forktest.o differ diff --git a/labcodes/lab5/obj/user/forktest.sym b/labcodes/lab5/obj/user/forktest.sym new file mode 100644 index 0000000000000000000000000000000000000000..641bfda0cfa040b18a112320a6427fbf575e6c12 --- /dev/null +++ b/labcodes/lab5/obj/user/forktest.sym @@ -0,0 +1,67 @@ +00000000 panic.c +00000000 stdio.c +008000c8 cputch +00000000 syscall.c +00800199 syscall +00000000 ulib.c +00000000 umain.c +00000000 hash.c +00000000 printfmt.c +008011e0 error_string +008003ad printnum +008004af getuint +008004fe getint +0080094f sprintputch +00000000 rand.c +00802000 next +00000000 string.c +00000000 forktest.c +00800b53 strcpy +00800329 yield +0080030d waitpid +00800245 sys_yield +00800e65 memmove +00800985 snprintf +00800576 vprintfmt +0080020b sys_fork +00800120 cprintf +0080034e getpid +00800f08 memcpy +008009bb vsnprintf +0080036d umain +00202800 __STAB_END__ +0080025b sys_kill +00202801 __STABSTR_BEGIN__ +0080002f __panic +008013c0 max_child +00800ccb strtol +00800b22 strnlen +0080035d print_pgdir +00800339 kill +00800c9b strfind +008002ef wait +00800020 _start +00800a21 rand +00800c14 strncmp +0080028e sys_putc +00800b92 strncpy +00800f57 memcmp +008002e0 fork +00800e23 memset +00800faf main +00800ae0 srand +00800386 hash32 +00800545 printfmt +00203734 __STABSTR_END__ +00800bcb strcmp +008000eb vcprintf +0080007f __warn +00800148 cputs +008002c1 exit +00800221 sys_wait +008001ee sys_exit +00200010 __STAB_BEGIN__ +00800af9 strlen +008002ab sys_pgdir +00800c67 strchr +00800278 sys_getpid diff --git a/labcodes/lab5/obj/user/forktree.asm b/labcodes/lab5/obj/user/forktree.asm new file mode 100644 index 0000000000000000000000000000000000000000..ea7d6d5e0ec8b3de71f721cd97bda86cca08fd38 --- /dev/null +++ b/labcodes/lab5/obj/user/forktree.asm @@ -0,0 +1,2405 @@ + +obj/__user_forktree.out: file format elf32-i386 + + +Disassembly of section .text: + +00800020 <_start>: +.text +.globl _start +_start: + # set ebp for backtrace + movl $0x0, %ebp + 800020: bd 00 00 00 00 mov $0x0,%ebp + + # move down the esp register + # since it may cause page fault in backtrace + subl $0x20, %esp + 800025: 83 ec 20 sub $0x20,%esp + + # call user-program function + call umain + 800028: e8 40 03 00 00 call 80036d +1: jmp 1b + 80002d: eb fe jmp 80002d <_start+0xd> + +0080002f <__panic>: +#include +#include +#include + +void +__panic(const char *file, int line, const char *fmt, ...) { + 80002f: 55 push %ebp + 800030: 89 e5 mov %esp,%ebp + 800032: 83 ec 28 sub $0x28,%esp + // print the 'message' + va_list ap; + va_start(ap, fmt); + 800035: 8d 45 14 lea 0x14(%ebp),%eax + 800038: 89 45 f4 mov %eax,-0xc(%ebp) + cprintf("user panic at %s:%d:\n ", file, line); + 80003b: 8b 45 0c mov 0xc(%ebp),%eax + 80003e: 89 44 24 08 mov %eax,0x8(%esp) + 800042: 8b 45 08 mov 0x8(%ebp),%eax + 800045: 89 44 24 04 mov %eax,0x4(%esp) + 800049: c7 04 24 a0 10 80 00 movl $0x8010a0,(%esp) + 800050: e8 cb 00 00 00 call 800120 + vcprintf(fmt, ap); + 800055: 8b 45 f4 mov -0xc(%ebp),%eax + 800058: 89 44 24 04 mov %eax,0x4(%esp) + 80005c: 8b 45 10 mov 0x10(%ebp),%eax + 80005f: 89 04 24 mov %eax,(%esp) + 800062: e8 84 00 00 00 call 8000eb + cprintf("\n"); + 800067: c7 04 24 ba 10 80 00 movl $0x8010ba,(%esp) + 80006e: e8 ad 00 00 00 call 800120 + va_end(ap); + exit(-E_PANIC); + 800073: c7 04 24 f6 ff ff ff movl $0xfffffff6,(%esp) + 80007a: e8 42 02 00 00 call 8002c1 + +0080007f <__warn>: +} + +void +__warn(const char *file, int line, const char *fmt, ...) { + 80007f: 55 push %ebp + 800080: 89 e5 mov %esp,%ebp + 800082: 83 ec 28 sub $0x28,%esp + va_list ap; + va_start(ap, fmt); + 800085: 8d 45 14 lea 0x14(%ebp),%eax + 800088: 89 45 f4 mov %eax,-0xc(%ebp) + cprintf("user warning at %s:%d:\n ", file, line); + 80008b: 8b 45 0c mov 0xc(%ebp),%eax + 80008e: 89 44 24 08 mov %eax,0x8(%esp) + 800092: 8b 45 08 mov 0x8(%ebp),%eax + 800095: 89 44 24 04 mov %eax,0x4(%esp) + 800099: c7 04 24 bc 10 80 00 movl $0x8010bc,(%esp) + 8000a0: e8 7b 00 00 00 call 800120 + vcprintf(fmt, ap); + 8000a5: 8b 45 f4 mov -0xc(%ebp),%eax + 8000a8: 89 44 24 04 mov %eax,0x4(%esp) + 8000ac: 8b 45 10 mov 0x10(%ebp),%eax + 8000af: 89 04 24 mov %eax,(%esp) + 8000b2: e8 34 00 00 00 call 8000eb + cprintf("\n"); + 8000b7: c7 04 24 ba 10 80 00 movl $0x8010ba,(%esp) + 8000be: e8 5d 00 00 00 call 800120 + va_end(ap); +} + 8000c3: 90 nop + 8000c4: 89 ec mov %ebp,%esp + 8000c6: 5d pop %ebp + 8000c7: c3 ret + +008000c8 : +/* * + * cputch - writes a single character @c to stdout, and it will + * increace the value of counter pointed by @cnt. + * */ +static void +cputch(int c, int *cnt) { + 8000c8: 55 push %ebp + 8000c9: 89 e5 mov %esp,%ebp + 8000cb: 83 ec 18 sub $0x18,%esp + sys_putc(c); + 8000ce: 8b 45 08 mov 0x8(%ebp),%eax + 8000d1: 89 04 24 mov %eax,(%esp) + 8000d4: e8 b5 01 00 00 call 80028e + (*cnt) ++; + 8000d9: 8b 45 0c mov 0xc(%ebp),%eax + 8000dc: 8b 00 mov (%eax),%eax + 8000de: 8d 50 01 lea 0x1(%eax),%edx + 8000e1: 8b 45 0c mov 0xc(%ebp),%eax + 8000e4: 89 10 mov %edx,(%eax) +} + 8000e6: 90 nop + 8000e7: 89 ec mov %ebp,%esp + 8000e9: 5d pop %ebp + 8000ea: c3 ret + +008000eb : + * + * Call this function if you are already dealing with a va_list. + * Or you probably want cprintf() instead. + * */ +int +vcprintf(const char *fmt, va_list ap) { + 8000eb: 55 push %ebp + 8000ec: 89 e5 mov %esp,%ebp + 8000ee: 83 ec 28 sub $0x28,%esp + int cnt = 0; + 8000f1: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + vprintfmt((void*)cputch, &cnt, fmt, ap); + 8000f8: 8b 45 0c mov 0xc(%ebp),%eax + 8000fb: 89 44 24 0c mov %eax,0xc(%esp) + 8000ff: 8b 45 08 mov 0x8(%ebp),%eax + 800102: 89 44 24 08 mov %eax,0x8(%esp) + 800106: 8d 45 f4 lea -0xc(%ebp),%eax + 800109: 89 44 24 04 mov %eax,0x4(%esp) + 80010d: c7 04 24 c8 00 80 00 movl $0x8000c8,(%esp) + 800114: e8 5d 04 00 00 call 800576 + return cnt; + 800119: 8b 45 f4 mov -0xc(%ebp),%eax +} + 80011c: 89 ec mov %ebp,%esp + 80011e: 5d pop %ebp + 80011f: c3 ret + +00800120 : + * + * The return value is the number of characters which would be + * written to stdout. + * */ +int +cprintf(const char *fmt, ...) { + 800120: 55 push %ebp + 800121: 89 e5 mov %esp,%ebp + 800123: 83 ec 28 sub $0x28,%esp + va_list ap; + + va_start(ap, fmt); + 800126: 8d 45 0c lea 0xc(%ebp),%eax + 800129: 89 45 f0 mov %eax,-0x10(%ebp) + int cnt = vcprintf(fmt, ap); + 80012c: 8b 45 f0 mov -0x10(%ebp),%eax + 80012f: 89 44 24 04 mov %eax,0x4(%esp) + 800133: 8b 45 08 mov 0x8(%ebp),%eax + 800136: 89 04 24 mov %eax,(%esp) + 800139: e8 ad ff ff ff call 8000eb + 80013e: 89 45 f4 mov %eax,-0xc(%ebp) + va_end(ap); + + return cnt; + 800141: 8b 45 f4 mov -0xc(%ebp),%eax +} + 800144: 89 ec mov %ebp,%esp + 800146: 5d pop %ebp + 800147: c3 ret + +00800148 : +/* * + * cputs- writes the string pointed by @str to stdout and + * appends a newline character. + * */ +int +cputs(const char *str) { + 800148: 55 push %ebp + 800149: 89 e5 mov %esp,%ebp + 80014b: 83 ec 28 sub $0x28,%esp + int cnt = 0; + 80014e: c7 45 f0 00 00 00 00 movl $0x0,-0x10(%ebp) + char c; + while ((c = *str ++) != '\0') { + 800155: eb 13 jmp 80016a + cputch(c, &cnt); + 800157: 0f be 45 f7 movsbl -0x9(%ebp),%eax + 80015b: 8d 55 f0 lea -0x10(%ebp),%edx + 80015e: 89 54 24 04 mov %edx,0x4(%esp) + 800162: 89 04 24 mov %eax,(%esp) + 800165: e8 5e ff ff ff call 8000c8 + while ((c = *str ++) != '\0') { + 80016a: 8b 45 08 mov 0x8(%ebp),%eax + 80016d: 8d 50 01 lea 0x1(%eax),%edx + 800170: 89 55 08 mov %edx,0x8(%ebp) + 800173: 0f b6 00 movzbl (%eax),%eax + 800176: 88 45 f7 mov %al,-0x9(%ebp) + 800179: 80 7d f7 00 cmpb $0x0,-0x9(%ebp) + 80017d: 75 d8 jne 800157 + } + cputch('\n', &cnt); + 80017f: 8d 45 f0 lea -0x10(%ebp),%eax + 800182: 89 44 24 04 mov %eax,0x4(%esp) + 800186: c7 04 24 0a 00 00 00 movl $0xa,(%esp) + 80018d: e8 36 ff ff ff call 8000c8 + return cnt; + 800192: 8b 45 f0 mov -0x10(%ebp),%eax +} + 800195: 89 ec mov %ebp,%esp + 800197: 5d pop %ebp + 800198: c3 ret + +00800199 : +#include + +#define MAX_ARGS 5 + +static inline int +syscall(int num, ...) { + 800199: 55 push %ebp + 80019a: 89 e5 mov %esp,%ebp + 80019c: 57 push %edi + 80019d: 56 push %esi + 80019e: 53 push %ebx + 80019f: 83 ec 20 sub $0x20,%esp + va_list ap; + va_start(ap, num); + 8001a2: 8d 45 0c lea 0xc(%ebp),%eax + 8001a5: 89 45 e8 mov %eax,-0x18(%ebp) + uint32_t a[MAX_ARGS]; + int i, ret; + for (i = 0; i < MAX_ARGS; i ++) { + 8001a8: c7 45 f0 00 00 00 00 movl $0x0,-0x10(%ebp) + 8001af: eb 15 jmp 8001c6 + a[i] = va_arg(ap, uint32_t); + 8001b1: 8b 45 e8 mov -0x18(%ebp),%eax + 8001b4: 8d 50 04 lea 0x4(%eax),%edx + 8001b7: 89 55 e8 mov %edx,-0x18(%ebp) + 8001ba: 8b 10 mov (%eax),%edx + 8001bc: 8b 45 f0 mov -0x10(%ebp),%eax + 8001bf: 89 54 85 d4 mov %edx,-0x2c(%ebp,%eax,4) + for (i = 0; i < MAX_ARGS; i ++) { + 8001c3: ff 45 f0 incl -0x10(%ebp) + 8001c6: 83 7d f0 04 cmpl $0x4,-0x10(%ebp) + 8001ca: 7e e5 jle 8001b1 + asm volatile ( + "int %1;" + : "=a" (ret) + : "i" (T_SYSCALL), + "a" (num), + "d" (a[0]), + 8001cc: 8b 55 d4 mov -0x2c(%ebp),%edx + "c" (a[1]), + 8001cf: 8b 4d d8 mov -0x28(%ebp),%ecx + "b" (a[2]), + 8001d2: 8b 5d dc mov -0x24(%ebp),%ebx + "D" (a[3]), + 8001d5: 8b 7d e0 mov -0x20(%ebp),%edi + "S" (a[4]) + 8001d8: 8b 75 e4 mov -0x1c(%ebp),%esi + asm volatile ( + 8001db: 8b 45 08 mov 0x8(%ebp),%eax + 8001de: cd 80 int $0x80 + 8001e0: 89 45 ec mov %eax,-0x14(%ebp) + : "cc", "memory"); + return ret; + 8001e3: 8b 45 ec mov -0x14(%ebp),%eax +} + 8001e6: 83 c4 20 add $0x20,%esp + 8001e9: 5b pop %ebx + 8001ea: 5e pop %esi + 8001eb: 5f pop %edi + 8001ec: 5d pop %ebp + 8001ed: c3 ret + +008001ee : + +int +sys_exit(int error_code) { + 8001ee: 55 push %ebp + 8001ef: 89 e5 mov %esp,%ebp + 8001f1: 83 ec 08 sub $0x8,%esp + return syscall(SYS_exit, error_code); + 8001f4: 8b 45 08 mov 0x8(%ebp),%eax + 8001f7: 89 44 24 04 mov %eax,0x4(%esp) + 8001fb: c7 04 24 01 00 00 00 movl $0x1,(%esp) + 800202: e8 92 ff ff ff call 800199 +} + 800207: 89 ec mov %ebp,%esp + 800209: 5d pop %ebp + 80020a: c3 ret + +0080020b : + +int +sys_fork(void) { + 80020b: 55 push %ebp + 80020c: 89 e5 mov %esp,%ebp + 80020e: 83 ec 04 sub $0x4,%esp + return syscall(SYS_fork); + 800211: c7 04 24 02 00 00 00 movl $0x2,(%esp) + 800218: e8 7c ff ff ff call 800199 +} + 80021d: 89 ec mov %ebp,%esp + 80021f: 5d pop %ebp + 800220: c3 ret + +00800221 : + +int +sys_wait(int pid, int *store) { + 800221: 55 push %ebp + 800222: 89 e5 mov %esp,%ebp + 800224: 83 ec 0c sub $0xc,%esp + return syscall(SYS_wait, pid, store); + 800227: 8b 45 0c mov 0xc(%ebp),%eax + 80022a: 89 44 24 08 mov %eax,0x8(%esp) + 80022e: 8b 45 08 mov 0x8(%ebp),%eax + 800231: 89 44 24 04 mov %eax,0x4(%esp) + 800235: c7 04 24 03 00 00 00 movl $0x3,(%esp) + 80023c: e8 58 ff ff ff call 800199 +} + 800241: 89 ec mov %ebp,%esp + 800243: 5d pop %ebp + 800244: c3 ret + +00800245 : + +int +sys_yield(void) { + 800245: 55 push %ebp + 800246: 89 e5 mov %esp,%ebp + 800248: 83 ec 04 sub $0x4,%esp + return syscall(SYS_yield); + 80024b: c7 04 24 0a 00 00 00 movl $0xa,(%esp) + 800252: e8 42 ff ff ff call 800199 +} + 800257: 89 ec mov %ebp,%esp + 800259: 5d pop %ebp + 80025a: c3 ret + +0080025b : + +int +sys_kill(int pid) { + 80025b: 55 push %ebp + 80025c: 89 e5 mov %esp,%ebp + 80025e: 83 ec 08 sub $0x8,%esp + return syscall(SYS_kill, pid); + 800261: 8b 45 08 mov 0x8(%ebp),%eax + 800264: 89 44 24 04 mov %eax,0x4(%esp) + 800268: c7 04 24 0c 00 00 00 movl $0xc,(%esp) + 80026f: e8 25 ff ff ff call 800199 +} + 800274: 89 ec mov %ebp,%esp + 800276: 5d pop %ebp + 800277: c3 ret + +00800278 : + +int +sys_getpid(void) { + 800278: 55 push %ebp + 800279: 89 e5 mov %esp,%ebp + 80027b: 83 ec 04 sub $0x4,%esp + return syscall(SYS_getpid); + 80027e: c7 04 24 12 00 00 00 movl $0x12,(%esp) + 800285: e8 0f ff ff ff call 800199 +} + 80028a: 89 ec mov %ebp,%esp + 80028c: 5d pop %ebp + 80028d: c3 ret + +0080028e : + +int +sys_putc(int c) { + 80028e: 55 push %ebp + 80028f: 89 e5 mov %esp,%ebp + 800291: 83 ec 08 sub $0x8,%esp + return syscall(SYS_putc, c); + 800294: 8b 45 08 mov 0x8(%ebp),%eax + 800297: 89 44 24 04 mov %eax,0x4(%esp) + 80029b: c7 04 24 1e 00 00 00 movl $0x1e,(%esp) + 8002a2: e8 f2 fe ff ff call 800199 +} + 8002a7: 89 ec mov %ebp,%esp + 8002a9: 5d pop %ebp + 8002aa: c3 ret + +008002ab : + +int +sys_pgdir(void) { + 8002ab: 55 push %ebp + 8002ac: 89 e5 mov %esp,%ebp + 8002ae: 83 ec 04 sub $0x4,%esp + return syscall(SYS_pgdir); + 8002b1: c7 04 24 1f 00 00 00 movl $0x1f,(%esp) + 8002b8: e8 dc fe ff ff call 800199 +} + 8002bd: 89 ec mov %ebp,%esp + 8002bf: 5d pop %ebp + 8002c0: c3 ret + +008002c1 : +#include +#include +#include + +void +exit(int error_code) { + 8002c1: 55 push %ebp + 8002c2: 89 e5 mov %esp,%ebp + 8002c4: 83 ec 18 sub $0x18,%esp + sys_exit(error_code); + 8002c7: 8b 45 08 mov 0x8(%ebp),%eax + 8002ca: 89 04 24 mov %eax,(%esp) + 8002cd: e8 1c ff ff ff call 8001ee + cprintf("BUG: exit failed.\n"); + 8002d2: c7 04 24 d8 10 80 00 movl $0x8010d8,(%esp) + 8002d9: e8 42 fe ff ff call 800120 + while (1); + 8002de: eb fe jmp 8002de + +008002e0 : +} + +int +fork(void) { + 8002e0: 55 push %ebp + 8002e1: 89 e5 mov %esp,%ebp + 8002e3: 83 ec 08 sub $0x8,%esp + return sys_fork(); + 8002e6: e8 20 ff ff ff call 80020b +} + 8002eb: 89 ec mov %ebp,%esp + 8002ed: 5d pop %ebp + 8002ee: c3 ret + +008002ef : + +int +wait(void) { + 8002ef: 55 push %ebp + 8002f0: 89 e5 mov %esp,%ebp + 8002f2: 83 ec 18 sub $0x18,%esp + return sys_wait(0, NULL); + 8002f5: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) + 8002fc: 00 + 8002fd: c7 04 24 00 00 00 00 movl $0x0,(%esp) + 800304: e8 18 ff ff ff call 800221 +} + 800309: 89 ec mov %ebp,%esp + 80030b: 5d pop %ebp + 80030c: c3 ret + +0080030d : + +int +waitpid(int pid, int *store) { + 80030d: 55 push %ebp + 80030e: 89 e5 mov %esp,%ebp + 800310: 83 ec 18 sub $0x18,%esp + return sys_wait(pid, store); + 800313: 8b 45 0c mov 0xc(%ebp),%eax + 800316: 89 44 24 04 mov %eax,0x4(%esp) + 80031a: 8b 45 08 mov 0x8(%ebp),%eax + 80031d: 89 04 24 mov %eax,(%esp) + 800320: e8 fc fe ff ff call 800221 +} + 800325: 89 ec mov %ebp,%esp + 800327: 5d pop %ebp + 800328: c3 ret + +00800329 : + +void +yield(void) { + 800329: 55 push %ebp + 80032a: 89 e5 mov %esp,%ebp + 80032c: 83 ec 08 sub $0x8,%esp + sys_yield(); + 80032f: e8 11 ff ff ff call 800245 +} + 800334: 90 nop + 800335: 89 ec mov %ebp,%esp + 800337: 5d pop %ebp + 800338: c3 ret + +00800339 : + +int +kill(int pid) { + 800339: 55 push %ebp + 80033a: 89 e5 mov %esp,%ebp + 80033c: 83 ec 18 sub $0x18,%esp + return sys_kill(pid); + 80033f: 8b 45 08 mov 0x8(%ebp),%eax + 800342: 89 04 24 mov %eax,(%esp) + 800345: e8 11 ff ff ff call 80025b +} + 80034a: 89 ec mov %ebp,%esp + 80034c: 5d pop %ebp + 80034d: c3 ret + +0080034e : + +int +getpid(void) { + 80034e: 55 push %ebp + 80034f: 89 e5 mov %esp,%ebp + 800351: 83 ec 08 sub $0x8,%esp + return sys_getpid(); + 800354: e8 1f ff ff ff call 800278 +} + 800359: 89 ec mov %ebp,%esp + 80035b: 5d pop %ebp + 80035c: c3 ret + +0080035d : + +//print_pgdir - print the PDT&PT +void +print_pgdir(void) { + 80035d: 55 push %ebp + 80035e: 89 e5 mov %esp,%ebp + 800360: 83 ec 08 sub $0x8,%esp + sys_pgdir(); + 800363: e8 43 ff ff ff call 8002ab +} + 800368: 90 nop + 800369: 89 ec mov %ebp,%esp + 80036b: 5d pop %ebp + 80036c: c3 ret + +0080036d : +#include + +int main(void); + +void +umain(void) { + 80036d: 55 push %ebp + 80036e: 89 e5 mov %esp,%ebp + 800370: 83 ec 28 sub $0x28,%esp + int ret = main(); + 800373: e8 f4 0c 00 00 call 80106c
+ 800378: 89 45 f4 mov %eax,-0xc(%ebp) + exit(ret); + 80037b: 8b 45 f4 mov -0xc(%ebp),%eax + 80037e: 89 04 24 mov %eax,(%esp) + 800381: e8 3b ff ff ff call 8002c1 + +00800386 : + * @bits: the number of bits in a return value + * + * High bits are more random, so we use them. + * */ +uint32_t +hash32(uint32_t val, unsigned int bits) { + 800386: 55 push %ebp + 800387: 89 e5 mov %esp,%ebp + 800389: 83 ec 10 sub $0x10,%esp + uint32_t hash = val * GOLDEN_RATIO_PRIME_32; + 80038c: 8b 45 08 mov 0x8(%ebp),%eax + 80038f: 69 c0 01 00 37 9e imul $0x9e370001,%eax,%eax + 800395: 89 45 fc mov %eax,-0x4(%ebp) + return (hash >> (32 - bits)); + 800398: b8 20 00 00 00 mov $0x20,%eax + 80039d: 2b 45 0c sub 0xc(%ebp),%eax + 8003a0: 8b 55 fc mov -0x4(%ebp),%edx + 8003a3: 88 c1 mov %al,%cl + 8003a5: d3 ea shr %cl,%edx + 8003a7: 89 d0 mov %edx,%eax +} + 8003a9: 89 ec mov %ebp,%esp + 8003ab: 5d pop %ebp + 8003ac: c3 ret + +008003ad : + * @width: maximum number of digits, if the actual width is less than @width, use @padc instead + * @padc: character that padded on the left if the actual width is less than @width + * */ +static void +printnum(void (*putch)(int, void*), void *putdat, + unsigned long long num, unsigned base, int width, int padc) { + 8003ad: 55 push %ebp + 8003ae: 89 e5 mov %esp,%ebp + 8003b0: 83 ec 58 sub $0x58,%esp + 8003b3: 8b 45 10 mov 0x10(%ebp),%eax + 8003b6: 89 45 d0 mov %eax,-0x30(%ebp) + 8003b9: 8b 45 14 mov 0x14(%ebp),%eax + 8003bc: 89 45 d4 mov %eax,-0x2c(%ebp) + unsigned long long result = num; + 8003bf: 8b 45 d0 mov -0x30(%ebp),%eax + 8003c2: 8b 55 d4 mov -0x2c(%ebp),%edx + 8003c5: 89 45 e8 mov %eax,-0x18(%ebp) + 8003c8: 89 55 ec mov %edx,-0x14(%ebp) + unsigned mod = do_div(result, base); + 8003cb: 8b 45 18 mov 0x18(%ebp),%eax + 8003ce: 89 45 e4 mov %eax,-0x1c(%ebp) + 8003d1: 8b 45 e8 mov -0x18(%ebp),%eax + 8003d4: 8b 55 ec mov -0x14(%ebp),%edx + 8003d7: 89 45 e0 mov %eax,-0x20(%ebp) + 8003da: 89 55 f0 mov %edx,-0x10(%ebp) + 8003dd: 8b 45 f0 mov -0x10(%ebp),%eax + 8003e0: 89 45 f4 mov %eax,-0xc(%ebp) + 8003e3: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) + 8003e7: 74 1c je 800405 + 8003e9: 8b 45 f0 mov -0x10(%ebp),%eax + 8003ec: ba 00 00 00 00 mov $0x0,%edx + 8003f1: f7 75 e4 divl -0x1c(%ebp) + 8003f4: 89 55 f4 mov %edx,-0xc(%ebp) + 8003f7: 8b 45 f0 mov -0x10(%ebp),%eax + 8003fa: ba 00 00 00 00 mov $0x0,%edx + 8003ff: f7 75 e4 divl -0x1c(%ebp) + 800402: 89 45 f0 mov %eax,-0x10(%ebp) + 800405: 8b 45 e0 mov -0x20(%ebp),%eax + 800408: 8b 55 f4 mov -0xc(%ebp),%edx + 80040b: f7 75 e4 divl -0x1c(%ebp) + 80040e: 89 45 e0 mov %eax,-0x20(%ebp) + 800411: 89 55 dc mov %edx,-0x24(%ebp) + 800414: 8b 45 e0 mov -0x20(%ebp),%eax + 800417: 8b 55 f0 mov -0x10(%ebp),%edx + 80041a: 89 45 e8 mov %eax,-0x18(%ebp) + 80041d: 89 55 ec mov %edx,-0x14(%ebp) + 800420: 8b 45 dc mov -0x24(%ebp),%eax + 800423: 89 45 d8 mov %eax,-0x28(%ebp) + + // first recursively print all preceding (more significant) digits + if (num >= base) { + 800426: 8b 45 18 mov 0x18(%ebp),%eax + 800429: ba 00 00 00 00 mov $0x0,%edx + 80042e: 8b 4d d4 mov -0x2c(%ebp),%ecx + 800431: 39 45 d0 cmp %eax,-0x30(%ebp) + 800434: 19 d1 sbb %edx,%ecx + 800436: 72 4c jb 800484 + printnum(putch, putdat, result, base, width - 1, padc); + 800438: 8b 45 1c mov 0x1c(%ebp),%eax + 80043b: 8d 50 ff lea -0x1(%eax),%edx + 80043e: 8b 45 20 mov 0x20(%ebp),%eax + 800441: 89 44 24 18 mov %eax,0x18(%esp) + 800445: 89 54 24 14 mov %edx,0x14(%esp) + 800449: 8b 45 18 mov 0x18(%ebp),%eax + 80044c: 89 44 24 10 mov %eax,0x10(%esp) + 800450: 8b 45 e8 mov -0x18(%ebp),%eax + 800453: 8b 55 ec mov -0x14(%ebp),%edx + 800456: 89 44 24 08 mov %eax,0x8(%esp) + 80045a: 89 54 24 0c mov %edx,0xc(%esp) + 80045e: 8b 45 0c mov 0xc(%ebp),%eax + 800461: 89 44 24 04 mov %eax,0x4(%esp) + 800465: 8b 45 08 mov 0x8(%ebp),%eax + 800468: 89 04 24 mov %eax,(%esp) + 80046b: e8 3d ff ff ff call 8003ad + 800470: eb 1b jmp 80048d + } else { + // print any needed pad characters before first digit + while (-- width > 0) + putch(padc, putdat); + 800472: 8b 45 0c mov 0xc(%ebp),%eax + 800475: 89 44 24 04 mov %eax,0x4(%esp) + 800479: 8b 45 20 mov 0x20(%ebp),%eax + 80047c: 89 04 24 mov %eax,(%esp) + 80047f: 8b 45 08 mov 0x8(%ebp),%eax + 800482: ff d0 call *%eax + while (-- width > 0) + 800484: ff 4d 1c decl 0x1c(%ebp) + 800487: 83 7d 1c 00 cmpl $0x0,0x1c(%ebp) + 80048b: 7f e5 jg 800472 + } + // then print this (the least significant) digit + putch("0123456789abcdef"[mod], putdat); + 80048d: 8b 45 d8 mov -0x28(%ebp),%eax + 800490: 05 04 12 80 00 add $0x801204,%eax + 800495: 0f b6 00 movzbl (%eax),%eax + 800498: 0f be c0 movsbl %al,%eax + 80049b: 8b 55 0c mov 0xc(%ebp),%edx + 80049e: 89 54 24 04 mov %edx,0x4(%esp) + 8004a2: 89 04 24 mov %eax,(%esp) + 8004a5: 8b 45 08 mov 0x8(%ebp),%eax + 8004a8: ff d0 call *%eax +} + 8004aa: 90 nop + 8004ab: 89 ec mov %ebp,%esp + 8004ad: 5d pop %ebp + 8004ae: c3 ret + +008004af : + * getuint - get an unsigned int of various possible sizes from a varargs list + * @ap: a varargs list pointer + * @lflag: determines the size of the vararg that @ap points to + * */ +static unsigned long long +getuint(va_list *ap, int lflag) { + 8004af: 55 push %ebp + 8004b0: 89 e5 mov %esp,%ebp + if (lflag >= 2) { + 8004b2: 83 7d 0c 01 cmpl $0x1,0xc(%ebp) + 8004b6: 7e 14 jle 8004cc + return va_arg(*ap, unsigned long long); + 8004b8: 8b 45 08 mov 0x8(%ebp),%eax + 8004bb: 8b 00 mov (%eax),%eax + 8004bd: 8d 48 08 lea 0x8(%eax),%ecx + 8004c0: 8b 55 08 mov 0x8(%ebp),%edx + 8004c3: 89 0a mov %ecx,(%edx) + 8004c5: 8b 50 04 mov 0x4(%eax),%edx + 8004c8: 8b 00 mov (%eax),%eax + 8004ca: eb 30 jmp 8004fc + } + else if (lflag) { + 8004cc: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) + 8004d0: 74 16 je 8004e8 + return va_arg(*ap, unsigned long); + 8004d2: 8b 45 08 mov 0x8(%ebp),%eax + 8004d5: 8b 00 mov (%eax),%eax + 8004d7: 8d 48 04 lea 0x4(%eax),%ecx + 8004da: 8b 55 08 mov 0x8(%ebp),%edx + 8004dd: 89 0a mov %ecx,(%edx) + 8004df: 8b 00 mov (%eax),%eax + 8004e1: ba 00 00 00 00 mov $0x0,%edx + 8004e6: eb 14 jmp 8004fc + } + else { + return va_arg(*ap, unsigned int); + 8004e8: 8b 45 08 mov 0x8(%ebp),%eax + 8004eb: 8b 00 mov (%eax),%eax + 8004ed: 8d 48 04 lea 0x4(%eax),%ecx + 8004f0: 8b 55 08 mov 0x8(%ebp),%edx + 8004f3: 89 0a mov %ecx,(%edx) + 8004f5: 8b 00 mov (%eax),%eax + 8004f7: ba 00 00 00 00 mov $0x0,%edx + } +} + 8004fc: 5d pop %ebp + 8004fd: c3 ret + +008004fe : + * getint - same as getuint but signed, we can't use getuint because of sign extension + * @ap: a varargs list pointer + * @lflag: determines the size of the vararg that @ap points to + * */ +static long long +getint(va_list *ap, int lflag) { + 8004fe: 55 push %ebp + 8004ff: 89 e5 mov %esp,%ebp + if (lflag >= 2) { + 800501: 83 7d 0c 01 cmpl $0x1,0xc(%ebp) + 800505: 7e 14 jle 80051b + return va_arg(*ap, long long); + 800507: 8b 45 08 mov 0x8(%ebp),%eax + 80050a: 8b 00 mov (%eax),%eax + 80050c: 8d 48 08 lea 0x8(%eax),%ecx + 80050f: 8b 55 08 mov 0x8(%ebp),%edx + 800512: 89 0a mov %ecx,(%edx) + 800514: 8b 50 04 mov 0x4(%eax),%edx + 800517: 8b 00 mov (%eax),%eax + 800519: eb 28 jmp 800543 + } + else if (lflag) { + 80051b: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) + 80051f: 74 12 je 800533 + return va_arg(*ap, long); + 800521: 8b 45 08 mov 0x8(%ebp),%eax + 800524: 8b 00 mov (%eax),%eax + 800526: 8d 48 04 lea 0x4(%eax),%ecx + 800529: 8b 55 08 mov 0x8(%ebp),%edx + 80052c: 89 0a mov %ecx,(%edx) + 80052e: 8b 00 mov (%eax),%eax + 800530: 99 cltd + 800531: eb 10 jmp 800543 + } + else { + return va_arg(*ap, int); + 800533: 8b 45 08 mov 0x8(%ebp),%eax + 800536: 8b 00 mov (%eax),%eax + 800538: 8d 48 04 lea 0x4(%eax),%ecx + 80053b: 8b 55 08 mov 0x8(%ebp),%edx + 80053e: 89 0a mov %ecx,(%edx) + 800540: 8b 00 mov (%eax),%eax + 800542: 99 cltd + } +} + 800543: 5d pop %ebp + 800544: c3 ret + +00800545 : + * @putch: specified putch function, print a single character + * @putdat: used by @putch function + * @fmt: the format string to use + * */ +void +printfmt(void (*putch)(int, void*), void *putdat, const char *fmt, ...) { + 800545: 55 push %ebp + 800546: 89 e5 mov %esp,%ebp + 800548: 83 ec 28 sub $0x28,%esp + va_list ap; + + va_start(ap, fmt); + 80054b: 8d 45 14 lea 0x14(%ebp),%eax + 80054e: 89 45 f4 mov %eax,-0xc(%ebp) + vprintfmt(putch, putdat, fmt, ap); + 800551: 8b 45 f4 mov -0xc(%ebp),%eax + 800554: 89 44 24 0c mov %eax,0xc(%esp) + 800558: 8b 45 10 mov 0x10(%ebp),%eax + 80055b: 89 44 24 08 mov %eax,0x8(%esp) + 80055f: 8b 45 0c mov 0xc(%ebp),%eax + 800562: 89 44 24 04 mov %eax,0x4(%esp) + 800566: 8b 45 08 mov 0x8(%ebp),%eax + 800569: 89 04 24 mov %eax,(%esp) + 80056c: e8 05 00 00 00 call 800576 + va_end(ap); +} + 800571: 90 nop + 800572: 89 ec mov %ebp,%esp + 800574: 5d pop %ebp + 800575: c3 ret + +00800576 : + * + * Call this function if you are already dealing with a va_list. + * Or you probably want printfmt() instead. + * */ +void +vprintfmt(void (*putch)(int, void*), void *putdat, const char *fmt, va_list ap) { + 800576: 55 push %ebp + 800577: 89 e5 mov %esp,%ebp + 800579: 56 push %esi + 80057a: 53 push %ebx + 80057b: 83 ec 40 sub $0x40,%esp + register int ch, err; + unsigned long long num; + int base, width, precision, lflag, altflag; + + while (1) { + while ((ch = *(unsigned char *)fmt ++) != '%') { + 80057e: eb 17 jmp 800597 + if (ch == '\0') { + 800580: 85 db test %ebx,%ebx + 800582: 0f 84 bf 03 00 00 je 800947 + return; + } + putch(ch, putdat); + 800588: 8b 45 0c mov 0xc(%ebp),%eax + 80058b: 89 44 24 04 mov %eax,0x4(%esp) + 80058f: 89 1c 24 mov %ebx,(%esp) + 800592: 8b 45 08 mov 0x8(%ebp),%eax + 800595: ff d0 call *%eax + while ((ch = *(unsigned char *)fmt ++) != '%') { + 800597: 8b 45 10 mov 0x10(%ebp),%eax + 80059a: 8d 50 01 lea 0x1(%eax),%edx + 80059d: 89 55 10 mov %edx,0x10(%ebp) + 8005a0: 0f b6 00 movzbl (%eax),%eax + 8005a3: 0f b6 d8 movzbl %al,%ebx + 8005a6: 83 fb 25 cmp $0x25,%ebx + 8005a9: 75 d5 jne 800580 + } + + // Process a %-escape sequence + char padc = ' '; + 8005ab: c6 45 db 20 movb $0x20,-0x25(%ebp) + width = precision = -1; + 8005af: c7 45 e4 ff ff ff ff movl $0xffffffff,-0x1c(%ebp) + 8005b6: 8b 45 e4 mov -0x1c(%ebp),%eax + 8005b9: 89 45 e8 mov %eax,-0x18(%ebp) + lflag = altflag = 0; + 8005bc: c7 45 dc 00 00 00 00 movl $0x0,-0x24(%ebp) + 8005c3: 8b 45 dc mov -0x24(%ebp),%eax + 8005c6: 89 45 e0 mov %eax,-0x20(%ebp) + + reswitch: + switch (ch = *(unsigned char *)fmt ++) { + 8005c9: 8b 45 10 mov 0x10(%ebp),%eax + 8005cc: 8d 50 01 lea 0x1(%eax),%edx + 8005cf: 89 55 10 mov %edx,0x10(%ebp) + 8005d2: 0f b6 00 movzbl (%eax),%eax + 8005d5: 0f b6 d8 movzbl %al,%ebx + 8005d8: 8d 43 dd lea -0x23(%ebx),%eax + 8005db: 83 f8 55 cmp $0x55,%eax + 8005de: 0f 87 37 03 00 00 ja 80091b + 8005e4: 8b 04 85 28 12 80 00 mov 0x801228(,%eax,4),%eax + 8005eb: ff e0 jmp *%eax + + // flag to pad on the right + case '-': + padc = '-'; + 8005ed: c6 45 db 2d movb $0x2d,-0x25(%ebp) + goto reswitch; + 8005f1: eb d6 jmp 8005c9 + + // flag to pad with 0's instead of spaces + case '0': + padc = '0'; + 8005f3: c6 45 db 30 movb $0x30,-0x25(%ebp) + goto reswitch; + 8005f7: eb d0 jmp 8005c9 + + // width field + case '1' ... '9': + for (precision = 0; ; ++ fmt) { + 8005f9: c7 45 e4 00 00 00 00 movl $0x0,-0x1c(%ebp) + precision = precision * 10 + ch - '0'; + 800600: 8b 55 e4 mov -0x1c(%ebp),%edx + 800603: 89 d0 mov %edx,%eax + 800605: c1 e0 02 shl $0x2,%eax + 800608: 01 d0 add %edx,%eax + 80060a: 01 c0 add %eax,%eax + 80060c: 01 d8 add %ebx,%eax + 80060e: 83 e8 30 sub $0x30,%eax + 800611: 89 45 e4 mov %eax,-0x1c(%ebp) + ch = *fmt; + 800614: 8b 45 10 mov 0x10(%ebp),%eax + 800617: 0f b6 00 movzbl (%eax),%eax + 80061a: 0f be d8 movsbl %al,%ebx + if (ch < '0' || ch > '9') { + 80061d: 83 fb 2f cmp $0x2f,%ebx + 800620: 7e 38 jle 80065a + 800622: 83 fb 39 cmp $0x39,%ebx + 800625: 7f 33 jg 80065a + for (precision = 0; ; ++ fmt) { + 800627: ff 45 10 incl 0x10(%ebp) + precision = precision * 10 + ch - '0'; + 80062a: eb d4 jmp 800600 + } + } + goto process_precision; + + case '*': + precision = va_arg(ap, int); + 80062c: 8b 45 14 mov 0x14(%ebp),%eax + 80062f: 8d 50 04 lea 0x4(%eax),%edx + 800632: 89 55 14 mov %edx,0x14(%ebp) + 800635: 8b 00 mov (%eax),%eax + 800637: 89 45 e4 mov %eax,-0x1c(%ebp) + goto process_precision; + 80063a: eb 1f jmp 80065b + + case '.': + if (width < 0) + 80063c: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 800640: 79 87 jns 8005c9 + width = 0; + 800642: c7 45 e8 00 00 00 00 movl $0x0,-0x18(%ebp) + goto reswitch; + 800649: e9 7b ff ff ff jmp 8005c9 + + case '#': + altflag = 1; + 80064e: c7 45 dc 01 00 00 00 movl $0x1,-0x24(%ebp) + goto reswitch; + 800655: e9 6f ff ff ff jmp 8005c9 + goto process_precision; + 80065a: 90 nop + + process_precision: + if (width < 0) + 80065b: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 80065f: 0f 89 64 ff ff ff jns 8005c9 + width = precision, precision = -1; + 800665: 8b 45 e4 mov -0x1c(%ebp),%eax + 800668: 89 45 e8 mov %eax,-0x18(%ebp) + 80066b: c7 45 e4 ff ff ff ff movl $0xffffffff,-0x1c(%ebp) + goto reswitch; + 800672: e9 52 ff ff ff jmp 8005c9 + + // long flag (doubled for long long) + case 'l': + lflag ++; + 800677: ff 45 e0 incl -0x20(%ebp) + goto reswitch; + 80067a: e9 4a ff ff ff jmp 8005c9 + + // character + case 'c': + putch(va_arg(ap, int), putdat); + 80067f: 8b 45 14 mov 0x14(%ebp),%eax + 800682: 8d 50 04 lea 0x4(%eax),%edx + 800685: 89 55 14 mov %edx,0x14(%ebp) + 800688: 8b 00 mov (%eax),%eax + 80068a: 8b 55 0c mov 0xc(%ebp),%edx + 80068d: 89 54 24 04 mov %edx,0x4(%esp) + 800691: 89 04 24 mov %eax,(%esp) + 800694: 8b 45 08 mov 0x8(%ebp),%eax + 800697: ff d0 call *%eax + break; + 800699: e9 a4 02 00 00 jmp 800942 + + // error message + case 'e': + err = va_arg(ap, int); + 80069e: 8b 45 14 mov 0x14(%ebp),%eax + 8006a1: 8d 50 04 lea 0x4(%eax),%edx + 8006a4: 89 55 14 mov %edx,0x14(%ebp) + 8006a7: 8b 18 mov (%eax),%ebx + if (err < 0) { + 8006a9: 85 db test %ebx,%ebx + 8006ab: 79 02 jns 8006af + err = -err; + 8006ad: f7 db neg %ebx + } + if (err > MAXERROR || (p = error_string[err]) == NULL) { + 8006af: 83 fb 18 cmp $0x18,%ebx + 8006b2: 7f 0b jg 8006bf + 8006b4: 8b 34 9d a0 11 80 00 mov 0x8011a0(,%ebx,4),%esi + 8006bb: 85 f6 test %esi,%esi + 8006bd: 75 23 jne 8006e2 + printfmt(putch, putdat, "error %d", err); + 8006bf: 89 5c 24 0c mov %ebx,0xc(%esp) + 8006c3: c7 44 24 08 15 12 80 movl $0x801215,0x8(%esp) + 8006ca: 00 + 8006cb: 8b 45 0c mov 0xc(%ebp),%eax + 8006ce: 89 44 24 04 mov %eax,0x4(%esp) + 8006d2: 8b 45 08 mov 0x8(%ebp),%eax + 8006d5: 89 04 24 mov %eax,(%esp) + 8006d8: e8 68 fe ff ff call 800545 + } + else { + printfmt(putch, putdat, "%s", p); + } + break; + 8006dd: e9 60 02 00 00 jmp 800942 + printfmt(putch, putdat, "%s", p); + 8006e2: 89 74 24 0c mov %esi,0xc(%esp) + 8006e6: c7 44 24 08 1e 12 80 movl $0x80121e,0x8(%esp) + 8006ed: 00 + 8006ee: 8b 45 0c mov 0xc(%ebp),%eax + 8006f1: 89 44 24 04 mov %eax,0x4(%esp) + 8006f5: 8b 45 08 mov 0x8(%ebp),%eax + 8006f8: 89 04 24 mov %eax,(%esp) + 8006fb: e8 45 fe ff ff call 800545 + break; + 800700: e9 3d 02 00 00 jmp 800942 + + // string + case 's': + if ((p = va_arg(ap, char *)) == NULL) { + 800705: 8b 45 14 mov 0x14(%ebp),%eax + 800708: 8d 50 04 lea 0x4(%eax),%edx + 80070b: 89 55 14 mov %edx,0x14(%ebp) + 80070e: 8b 30 mov (%eax),%esi + 800710: 85 f6 test %esi,%esi + 800712: 75 05 jne 800719 + p = "(null)"; + 800714: be 21 12 80 00 mov $0x801221,%esi + } + if (width > 0 && padc != '-') { + 800719: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 80071d: 7e 76 jle 800795 + 80071f: 80 7d db 2d cmpb $0x2d,-0x25(%ebp) + 800723: 74 70 je 800795 + for (width -= strnlen(p, precision); width > 0; width --) { + 800725: 8b 45 e4 mov -0x1c(%ebp),%eax + 800728: 89 44 24 04 mov %eax,0x4(%esp) + 80072c: 89 34 24 mov %esi,(%esp) + 80072f: e8 ee 03 00 00 call 800b22 + 800734: 89 c2 mov %eax,%edx + 800736: 8b 45 e8 mov -0x18(%ebp),%eax + 800739: 29 d0 sub %edx,%eax + 80073b: 89 45 e8 mov %eax,-0x18(%ebp) + 80073e: eb 16 jmp 800756 + putch(padc, putdat); + 800740: 0f be 45 db movsbl -0x25(%ebp),%eax + 800744: 8b 55 0c mov 0xc(%ebp),%edx + 800747: 89 54 24 04 mov %edx,0x4(%esp) + 80074b: 89 04 24 mov %eax,(%esp) + 80074e: 8b 45 08 mov 0x8(%ebp),%eax + 800751: ff d0 call *%eax + for (width -= strnlen(p, precision); width > 0; width --) { + 800753: ff 4d e8 decl -0x18(%ebp) + 800756: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 80075a: 7f e4 jg 800740 + } + } + for (; (ch = *p ++) != '\0' && (precision < 0 || -- precision >= 0); width --) { + 80075c: eb 37 jmp 800795 + if (altflag && (ch < ' ' || ch > '~')) { + 80075e: 83 7d dc 00 cmpl $0x0,-0x24(%ebp) + 800762: 74 1f je 800783 + 800764: 83 fb 1f cmp $0x1f,%ebx + 800767: 7e 05 jle 80076e + 800769: 83 fb 7e cmp $0x7e,%ebx + 80076c: 7e 15 jle 800783 + putch('?', putdat); + 80076e: 8b 45 0c mov 0xc(%ebp),%eax + 800771: 89 44 24 04 mov %eax,0x4(%esp) + 800775: c7 04 24 3f 00 00 00 movl $0x3f,(%esp) + 80077c: 8b 45 08 mov 0x8(%ebp),%eax + 80077f: ff d0 call *%eax + 800781: eb 0f jmp 800792 + } + else { + putch(ch, putdat); + 800783: 8b 45 0c mov 0xc(%ebp),%eax + 800786: 89 44 24 04 mov %eax,0x4(%esp) + 80078a: 89 1c 24 mov %ebx,(%esp) + 80078d: 8b 45 08 mov 0x8(%ebp),%eax + 800790: ff d0 call *%eax + for (; (ch = *p ++) != '\0' && (precision < 0 || -- precision >= 0); width --) { + 800792: ff 4d e8 decl -0x18(%ebp) + 800795: 89 f0 mov %esi,%eax + 800797: 8d 70 01 lea 0x1(%eax),%esi + 80079a: 0f b6 00 movzbl (%eax),%eax + 80079d: 0f be d8 movsbl %al,%ebx + 8007a0: 85 db test %ebx,%ebx + 8007a2: 74 27 je 8007cb + 8007a4: 83 7d e4 00 cmpl $0x0,-0x1c(%ebp) + 8007a8: 78 b4 js 80075e + 8007aa: ff 4d e4 decl -0x1c(%ebp) + 8007ad: 83 7d e4 00 cmpl $0x0,-0x1c(%ebp) + 8007b1: 79 ab jns 80075e + } + } + for (; width > 0; width --) { + 8007b3: eb 16 jmp 8007cb + putch(' ', putdat); + 8007b5: 8b 45 0c mov 0xc(%ebp),%eax + 8007b8: 89 44 24 04 mov %eax,0x4(%esp) + 8007bc: c7 04 24 20 00 00 00 movl $0x20,(%esp) + 8007c3: 8b 45 08 mov 0x8(%ebp),%eax + 8007c6: ff d0 call *%eax + for (; width > 0; width --) { + 8007c8: ff 4d e8 decl -0x18(%ebp) + 8007cb: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 8007cf: 7f e4 jg 8007b5 + } + break; + 8007d1: e9 6c 01 00 00 jmp 800942 + + // (signed) decimal + case 'd': + num = getint(&ap, lflag); + 8007d6: 8b 45 e0 mov -0x20(%ebp),%eax + 8007d9: 89 44 24 04 mov %eax,0x4(%esp) + 8007dd: 8d 45 14 lea 0x14(%ebp),%eax + 8007e0: 89 04 24 mov %eax,(%esp) + 8007e3: e8 16 fd ff ff call 8004fe + 8007e8: 89 45 f0 mov %eax,-0x10(%ebp) + 8007eb: 89 55 f4 mov %edx,-0xc(%ebp) + if ((long long)num < 0) { + 8007ee: 8b 45 f0 mov -0x10(%ebp),%eax + 8007f1: 8b 55 f4 mov -0xc(%ebp),%edx + 8007f4: 85 d2 test %edx,%edx + 8007f6: 79 26 jns 80081e + putch('-', putdat); + 8007f8: 8b 45 0c mov 0xc(%ebp),%eax + 8007fb: 89 44 24 04 mov %eax,0x4(%esp) + 8007ff: c7 04 24 2d 00 00 00 movl $0x2d,(%esp) + 800806: 8b 45 08 mov 0x8(%ebp),%eax + 800809: ff d0 call *%eax + num = -(long long)num; + 80080b: 8b 45 f0 mov -0x10(%ebp),%eax + 80080e: 8b 55 f4 mov -0xc(%ebp),%edx + 800811: f7 d8 neg %eax + 800813: 83 d2 00 adc $0x0,%edx + 800816: f7 da neg %edx + 800818: 89 45 f0 mov %eax,-0x10(%ebp) + 80081b: 89 55 f4 mov %edx,-0xc(%ebp) + } + base = 10; + 80081e: c7 45 ec 0a 00 00 00 movl $0xa,-0x14(%ebp) + goto number; + 800825: e9 a8 00 00 00 jmp 8008d2 + + // unsigned decimal + case 'u': + num = getuint(&ap, lflag); + 80082a: 8b 45 e0 mov -0x20(%ebp),%eax + 80082d: 89 44 24 04 mov %eax,0x4(%esp) + 800831: 8d 45 14 lea 0x14(%ebp),%eax + 800834: 89 04 24 mov %eax,(%esp) + 800837: e8 73 fc ff ff call 8004af + 80083c: 89 45 f0 mov %eax,-0x10(%ebp) + 80083f: 89 55 f4 mov %edx,-0xc(%ebp) + base = 10; + 800842: c7 45 ec 0a 00 00 00 movl $0xa,-0x14(%ebp) + goto number; + 800849: e9 84 00 00 00 jmp 8008d2 + + // (unsigned) octal + case 'o': + num = getuint(&ap, lflag); + 80084e: 8b 45 e0 mov -0x20(%ebp),%eax + 800851: 89 44 24 04 mov %eax,0x4(%esp) + 800855: 8d 45 14 lea 0x14(%ebp),%eax + 800858: 89 04 24 mov %eax,(%esp) + 80085b: e8 4f fc ff ff call 8004af + 800860: 89 45 f0 mov %eax,-0x10(%ebp) + 800863: 89 55 f4 mov %edx,-0xc(%ebp) + base = 8; + 800866: c7 45 ec 08 00 00 00 movl $0x8,-0x14(%ebp) + goto number; + 80086d: eb 63 jmp 8008d2 + + // pointer + case 'p': + putch('0', putdat); + 80086f: 8b 45 0c mov 0xc(%ebp),%eax + 800872: 89 44 24 04 mov %eax,0x4(%esp) + 800876: c7 04 24 30 00 00 00 movl $0x30,(%esp) + 80087d: 8b 45 08 mov 0x8(%ebp),%eax + 800880: ff d0 call *%eax + putch('x', putdat); + 800882: 8b 45 0c mov 0xc(%ebp),%eax + 800885: 89 44 24 04 mov %eax,0x4(%esp) + 800889: c7 04 24 78 00 00 00 movl $0x78,(%esp) + 800890: 8b 45 08 mov 0x8(%ebp),%eax + 800893: ff d0 call *%eax + num = (unsigned long long)(uintptr_t)va_arg(ap, void *); + 800895: 8b 45 14 mov 0x14(%ebp),%eax + 800898: 8d 50 04 lea 0x4(%eax),%edx + 80089b: 89 55 14 mov %edx,0x14(%ebp) + 80089e: 8b 00 mov (%eax),%eax + 8008a0: 89 45 f0 mov %eax,-0x10(%ebp) + 8008a3: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + base = 16; + 8008aa: c7 45 ec 10 00 00 00 movl $0x10,-0x14(%ebp) + goto number; + 8008b1: eb 1f jmp 8008d2 + + // (unsigned) hexadecimal + case 'x': + num = getuint(&ap, lflag); + 8008b3: 8b 45 e0 mov -0x20(%ebp),%eax + 8008b6: 89 44 24 04 mov %eax,0x4(%esp) + 8008ba: 8d 45 14 lea 0x14(%ebp),%eax + 8008bd: 89 04 24 mov %eax,(%esp) + 8008c0: e8 ea fb ff ff call 8004af + 8008c5: 89 45 f0 mov %eax,-0x10(%ebp) + 8008c8: 89 55 f4 mov %edx,-0xc(%ebp) + base = 16; + 8008cb: c7 45 ec 10 00 00 00 movl $0x10,-0x14(%ebp) + number: + printnum(putch, putdat, num, base, width, padc); + 8008d2: 0f be 55 db movsbl -0x25(%ebp),%edx + 8008d6: 8b 45 ec mov -0x14(%ebp),%eax + 8008d9: 89 54 24 18 mov %edx,0x18(%esp) + 8008dd: 8b 55 e8 mov -0x18(%ebp),%edx + 8008e0: 89 54 24 14 mov %edx,0x14(%esp) + 8008e4: 89 44 24 10 mov %eax,0x10(%esp) + 8008e8: 8b 45 f0 mov -0x10(%ebp),%eax + 8008eb: 8b 55 f4 mov -0xc(%ebp),%edx + 8008ee: 89 44 24 08 mov %eax,0x8(%esp) + 8008f2: 89 54 24 0c mov %edx,0xc(%esp) + 8008f6: 8b 45 0c mov 0xc(%ebp),%eax + 8008f9: 89 44 24 04 mov %eax,0x4(%esp) + 8008fd: 8b 45 08 mov 0x8(%ebp),%eax + 800900: 89 04 24 mov %eax,(%esp) + 800903: e8 a5 fa ff ff call 8003ad + break; + 800908: eb 38 jmp 800942 + + // escaped '%' character + case '%': + putch(ch, putdat); + 80090a: 8b 45 0c mov 0xc(%ebp),%eax + 80090d: 89 44 24 04 mov %eax,0x4(%esp) + 800911: 89 1c 24 mov %ebx,(%esp) + 800914: 8b 45 08 mov 0x8(%ebp),%eax + 800917: ff d0 call *%eax + break; + 800919: eb 27 jmp 800942 + + // unrecognized escape sequence - just print it literally + default: + putch('%', putdat); + 80091b: 8b 45 0c mov 0xc(%ebp),%eax + 80091e: 89 44 24 04 mov %eax,0x4(%esp) + 800922: c7 04 24 25 00 00 00 movl $0x25,(%esp) + 800929: 8b 45 08 mov 0x8(%ebp),%eax + 80092c: ff d0 call *%eax + for (fmt --; fmt[-1] != '%'; fmt --) + 80092e: ff 4d 10 decl 0x10(%ebp) + 800931: eb 03 jmp 800936 + 800933: ff 4d 10 decl 0x10(%ebp) + 800936: 8b 45 10 mov 0x10(%ebp),%eax + 800939: 48 dec %eax + 80093a: 0f b6 00 movzbl (%eax),%eax + 80093d: 3c 25 cmp $0x25,%al + 80093f: 75 f2 jne 800933 + /* do nothing */; + break; + 800941: 90 nop + while (1) { + 800942: e9 37 fc ff ff jmp 80057e + return; + 800947: 90 nop + } + } +} + 800948: 83 c4 40 add $0x40,%esp + 80094b: 5b pop %ebx + 80094c: 5e pop %esi + 80094d: 5d pop %ebp + 80094e: c3 ret + +0080094f : + * sprintputch - 'print' a single character in a buffer + * @ch: the character will be printed + * @b: the buffer to place the character @ch + * */ +static void +sprintputch(int ch, struct sprintbuf *b) { + 80094f: 55 push %ebp + 800950: 89 e5 mov %esp,%ebp + b->cnt ++; + 800952: 8b 45 0c mov 0xc(%ebp),%eax + 800955: 8b 40 08 mov 0x8(%eax),%eax + 800958: 8d 50 01 lea 0x1(%eax),%edx + 80095b: 8b 45 0c mov 0xc(%ebp),%eax + 80095e: 89 50 08 mov %edx,0x8(%eax) + if (b->buf < b->ebuf) { + 800961: 8b 45 0c mov 0xc(%ebp),%eax + 800964: 8b 10 mov (%eax),%edx + 800966: 8b 45 0c mov 0xc(%ebp),%eax + 800969: 8b 40 04 mov 0x4(%eax),%eax + 80096c: 39 c2 cmp %eax,%edx + 80096e: 73 12 jae 800982 + *b->buf ++ = ch; + 800970: 8b 45 0c mov 0xc(%ebp),%eax + 800973: 8b 00 mov (%eax),%eax + 800975: 8d 48 01 lea 0x1(%eax),%ecx + 800978: 8b 55 0c mov 0xc(%ebp),%edx + 80097b: 89 0a mov %ecx,(%edx) + 80097d: 8b 55 08 mov 0x8(%ebp),%edx + 800980: 88 10 mov %dl,(%eax) + } +} + 800982: 90 nop + 800983: 5d pop %ebp + 800984: c3 ret + +00800985 : + * @str: the buffer to place the result into + * @size: the size of buffer, including the trailing null space + * @fmt: the format string to use + * */ +int +snprintf(char *str, size_t size, const char *fmt, ...) { + 800985: 55 push %ebp + 800986: 89 e5 mov %esp,%ebp + 800988: 83 ec 28 sub $0x28,%esp + va_list ap; + int cnt; + va_start(ap, fmt); + 80098b: 8d 45 14 lea 0x14(%ebp),%eax + 80098e: 89 45 f0 mov %eax,-0x10(%ebp) + cnt = vsnprintf(str, size, fmt, ap); + 800991: 8b 45 f0 mov -0x10(%ebp),%eax + 800994: 89 44 24 0c mov %eax,0xc(%esp) + 800998: 8b 45 10 mov 0x10(%ebp),%eax + 80099b: 89 44 24 08 mov %eax,0x8(%esp) + 80099f: 8b 45 0c mov 0xc(%ebp),%eax + 8009a2: 89 44 24 04 mov %eax,0x4(%esp) + 8009a6: 8b 45 08 mov 0x8(%ebp),%eax + 8009a9: 89 04 24 mov %eax,(%esp) + 8009ac: e8 0a 00 00 00 call 8009bb + 8009b1: 89 45 f4 mov %eax,-0xc(%ebp) + va_end(ap); + return cnt; + 8009b4: 8b 45 f4 mov -0xc(%ebp),%eax +} + 8009b7: 89 ec mov %ebp,%esp + 8009b9: 5d pop %ebp + 8009ba: c3 ret + +008009bb : + * + * Call this function if you are already dealing with a va_list. + * Or you probably want snprintf() instead. + * */ +int +vsnprintf(char *str, size_t size, const char *fmt, va_list ap) { + 8009bb: 55 push %ebp + 8009bc: 89 e5 mov %esp,%ebp + 8009be: 83 ec 28 sub $0x28,%esp + struct sprintbuf b = {str, str + size - 1, 0}; + 8009c1: 8b 45 08 mov 0x8(%ebp),%eax + 8009c4: 89 45 ec mov %eax,-0x14(%ebp) + 8009c7: 8b 45 0c mov 0xc(%ebp),%eax + 8009ca: 8d 50 ff lea -0x1(%eax),%edx + 8009cd: 8b 45 08 mov 0x8(%ebp),%eax + 8009d0: 01 d0 add %edx,%eax + 8009d2: 89 45 f0 mov %eax,-0x10(%ebp) + 8009d5: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + if (str == NULL || b.buf > b.ebuf) { + 8009dc: 83 7d 08 00 cmpl $0x0,0x8(%ebp) + 8009e0: 74 0a je 8009ec + 8009e2: 8b 55 ec mov -0x14(%ebp),%edx + 8009e5: 8b 45 f0 mov -0x10(%ebp),%eax + 8009e8: 39 c2 cmp %eax,%edx + 8009ea: 76 07 jbe 8009f3 + return -E_INVAL; + 8009ec: b8 fd ff ff ff mov $0xfffffffd,%eax + 8009f1: eb 2a jmp 800a1d + } + // print the string to the buffer + vprintfmt((void*)sprintputch, &b, fmt, ap); + 8009f3: 8b 45 14 mov 0x14(%ebp),%eax + 8009f6: 89 44 24 0c mov %eax,0xc(%esp) + 8009fa: 8b 45 10 mov 0x10(%ebp),%eax + 8009fd: 89 44 24 08 mov %eax,0x8(%esp) + 800a01: 8d 45 ec lea -0x14(%ebp),%eax + 800a04: 89 44 24 04 mov %eax,0x4(%esp) + 800a08: c7 04 24 4f 09 80 00 movl $0x80094f,(%esp) + 800a0f: e8 62 fb ff ff call 800576 + // null terminate the buffer + *b.buf = '\0'; + 800a14: 8b 45 ec mov -0x14(%ebp),%eax + 800a17: c6 00 00 movb $0x0,(%eax) + return b.cnt; + 800a1a: 8b 45 f4 mov -0xc(%ebp),%eax +} + 800a1d: 89 ec mov %ebp,%esp + 800a1f: 5d pop %ebp + 800a20: c3 ret + +00800a21 : + * rand - returns a pseudo-random integer + * + * The rand() function return a value in the range [0, RAND_MAX]. + * */ +int +rand(void) { + 800a21: 55 push %ebp + 800a22: 89 e5 mov %esp,%ebp + 800a24: 57 push %edi + 800a25: 56 push %esi + 800a26: 53 push %ebx + 800a27: 83 ec 24 sub $0x24,%esp + next = (next * 0x5DEECE66DLL + 0xBLL) & ((1LL << 48) - 1); + 800a2a: a1 00 20 80 00 mov 0x802000,%eax + 800a2f: 8b 15 04 20 80 00 mov 0x802004,%edx + 800a35: 69 fa 6d e6 ec de imul $0xdeece66d,%edx,%edi + 800a3b: 6b f0 05 imul $0x5,%eax,%esi + 800a3e: 01 fe add %edi,%esi + 800a40: bf 6d e6 ec de mov $0xdeece66d,%edi + 800a45: f7 e7 mul %edi + 800a47: 01 d6 add %edx,%esi + 800a49: 89 f2 mov %esi,%edx + 800a4b: 83 c0 0b add $0xb,%eax + 800a4e: 83 d2 00 adc $0x0,%edx + 800a51: 89 c7 mov %eax,%edi + 800a53: 83 e7 ff and $0xffffffff,%edi + 800a56: 89 f9 mov %edi,%ecx + 800a58: 0f b7 da movzwl %dx,%ebx + 800a5b: 89 0d 00 20 80 00 mov %ecx,0x802000 + 800a61: 89 1d 04 20 80 00 mov %ebx,0x802004 + unsigned long long result = (next >> 12); + 800a67: a1 00 20 80 00 mov 0x802000,%eax + 800a6c: 8b 15 04 20 80 00 mov 0x802004,%edx + 800a72: 0f ac d0 0c shrd $0xc,%edx,%eax + 800a76: c1 ea 0c shr $0xc,%edx + 800a79: 89 45 e0 mov %eax,-0x20(%ebp) + 800a7c: 89 55 e4 mov %edx,-0x1c(%ebp) + return (int)do_div(result, RAND_MAX + 1); + 800a7f: c7 45 dc 00 00 00 80 movl $0x80000000,-0x24(%ebp) + 800a86: 8b 45 e0 mov -0x20(%ebp),%eax + 800a89: 8b 55 e4 mov -0x1c(%ebp),%edx + 800a8c: 89 45 d8 mov %eax,-0x28(%ebp) + 800a8f: 89 55 e8 mov %edx,-0x18(%ebp) + 800a92: 8b 45 e8 mov -0x18(%ebp),%eax + 800a95: 89 45 ec mov %eax,-0x14(%ebp) + 800a98: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 800a9c: 74 1c je 800aba + 800a9e: 8b 45 e8 mov -0x18(%ebp),%eax + 800aa1: ba 00 00 00 00 mov $0x0,%edx + 800aa6: f7 75 dc divl -0x24(%ebp) + 800aa9: 89 55 ec mov %edx,-0x14(%ebp) + 800aac: 8b 45 e8 mov -0x18(%ebp),%eax + 800aaf: ba 00 00 00 00 mov $0x0,%edx + 800ab4: f7 75 dc divl -0x24(%ebp) + 800ab7: 89 45 e8 mov %eax,-0x18(%ebp) + 800aba: 8b 45 d8 mov -0x28(%ebp),%eax + 800abd: 8b 55 ec mov -0x14(%ebp),%edx + 800ac0: f7 75 dc divl -0x24(%ebp) + 800ac3: 89 45 d8 mov %eax,-0x28(%ebp) + 800ac6: 89 55 d4 mov %edx,-0x2c(%ebp) + 800ac9: 8b 45 d8 mov -0x28(%ebp),%eax + 800acc: 8b 55 e8 mov -0x18(%ebp),%edx + 800acf: 89 45 e0 mov %eax,-0x20(%ebp) + 800ad2: 89 55 e4 mov %edx,-0x1c(%ebp) + 800ad5: 8b 45 d4 mov -0x2c(%ebp),%eax +} + 800ad8: 83 c4 24 add $0x24,%esp + 800adb: 5b pop %ebx + 800adc: 5e pop %esi + 800add: 5f pop %edi + 800ade: 5d pop %ebp + 800adf: c3 ret + +00800ae0 : +/* * + * srand - seed the random number generator with the given number + * @seed: the required seed number + * */ +void +srand(unsigned int seed) { + 800ae0: 55 push %ebp + 800ae1: 89 e5 mov %esp,%ebp + next = seed; + 800ae3: 8b 45 08 mov 0x8(%ebp),%eax + 800ae6: ba 00 00 00 00 mov $0x0,%edx + 800aeb: a3 00 20 80 00 mov %eax,0x802000 + 800af0: 89 15 04 20 80 00 mov %edx,0x802004 +} + 800af6: 90 nop + 800af7: 5d pop %ebp + 800af8: c3 ret + +00800af9 : + * @s: the input string + * + * The strlen() function returns the length of string @s. + * */ +size_t +strlen(const char *s) { + 800af9: 55 push %ebp + 800afa: 89 e5 mov %esp,%ebp + 800afc: 83 ec 10 sub $0x10,%esp + size_t cnt = 0; + 800aff: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + while (*s ++ != '\0') { + 800b06: eb 03 jmp 800b0b + cnt ++; + 800b08: ff 45 fc incl -0x4(%ebp) + while (*s ++ != '\0') { + 800b0b: 8b 45 08 mov 0x8(%ebp),%eax + 800b0e: 8d 50 01 lea 0x1(%eax),%edx + 800b11: 89 55 08 mov %edx,0x8(%ebp) + 800b14: 0f b6 00 movzbl (%eax),%eax + 800b17: 84 c0 test %al,%al + 800b19: 75 ed jne 800b08 + } + return cnt; + 800b1b: 8b 45 fc mov -0x4(%ebp),%eax +} + 800b1e: 89 ec mov %ebp,%esp + 800b20: 5d pop %ebp + 800b21: c3 ret + +00800b22 : + * The return value is strlen(s), if that is less than @len, or + * @len if there is no '\0' character among the first @len characters + * pointed by @s. + * */ +size_t +strnlen(const char *s, size_t len) { + 800b22: 55 push %ebp + 800b23: 89 e5 mov %esp,%ebp + 800b25: 83 ec 10 sub $0x10,%esp + size_t cnt = 0; + 800b28: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + while (cnt < len && *s ++ != '\0') { + 800b2f: eb 03 jmp 800b34 + cnt ++; + 800b31: ff 45 fc incl -0x4(%ebp) + while (cnt < len && *s ++ != '\0') { + 800b34: 8b 45 fc mov -0x4(%ebp),%eax + 800b37: 3b 45 0c cmp 0xc(%ebp),%eax + 800b3a: 73 10 jae 800b4c + 800b3c: 8b 45 08 mov 0x8(%ebp),%eax + 800b3f: 8d 50 01 lea 0x1(%eax),%edx + 800b42: 89 55 08 mov %edx,0x8(%ebp) + 800b45: 0f b6 00 movzbl (%eax),%eax + 800b48: 84 c0 test %al,%al + 800b4a: 75 e5 jne 800b31 + } + return cnt; + 800b4c: 8b 45 fc mov -0x4(%ebp),%eax +} + 800b4f: 89 ec mov %ebp,%esp + 800b51: 5d pop %ebp + 800b52: c3 ret + +00800b53 : + * To avoid overflows, the size of array pointed by @dst should be long enough to + * contain the same string as @src (including the terminating null character), and + * should not overlap in memory with @src. + * */ +char * +strcpy(char *dst, const char *src) { + 800b53: 55 push %ebp + 800b54: 89 e5 mov %esp,%ebp + 800b56: 57 push %edi + 800b57: 56 push %esi + 800b58: 83 ec 20 sub $0x20,%esp + 800b5b: 8b 45 08 mov 0x8(%ebp),%eax + 800b5e: 89 45 f4 mov %eax,-0xc(%ebp) + 800b61: 8b 45 0c mov 0xc(%ebp),%eax + 800b64: 89 45 f0 mov %eax,-0x10(%ebp) +#ifndef __HAVE_ARCH_STRCPY +#define __HAVE_ARCH_STRCPY +static inline char * +__strcpy(char *dst, const char *src) { + int d0, d1, d2; + asm volatile ( + 800b67: 8b 55 f0 mov -0x10(%ebp),%edx + 800b6a: 8b 45 f4 mov -0xc(%ebp),%eax + 800b6d: 89 d1 mov %edx,%ecx + 800b6f: 89 c2 mov %eax,%edx + 800b71: 89 ce mov %ecx,%esi + 800b73: 89 d7 mov %edx,%edi + 800b75: ac lods %ds:(%esi),%al + 800b76: aa stos %al,%es:(%edi) + 800b77: 84 c0 test %al,%al + 800b79: 75 fa jne 800b75 + 800b7b: 89 fa mov %edi,%edx + 800b7d: 89 f1 mov %esi,%ecx + 800b7f: 89 4d ec mov %ecx,-0x14(%ebp) + 800b82: 89 55 e8 mov %edx,-0x18(%ebp) + 800b85: 89 45 e4 mov %eax,-0x1c(%ebp) + "stosb;" + "testb %%al, %%al;" + "jne 1b;" + : "=&S" (d0), "=&D" (d1), "=&a" (d2) + : "0" (src), "1" (dst) : "memory"); + return dst; + 800b88: 8b 45 f4 mov -0xc(%ebp),%eax + char *p = dst; + while ((*p ++ = *src ++) != '\0') + /* nothing */; + return dst; +#endif /* __HAVE_ARCH_STRCPY */ +} + 800b8b: 83 c4 20 add $0x20,%esp + 800b8e: 5e pop %esi + 800b8f: 5f pop %edi + 800b90: 5d pop %ebp + 800b91: c3 ret + +00800b92 : + * @len: maximum number of characters to be copied from @src + * + * The return value is @dst + * */ +char * +strncpy(char *dst, const char *src, size_t len) { + 800b92: 55 push %ebp + 800b93: 89 e5 mov %esp,%ebp + 800b95: 83 ec 10 sub $0x10,%esp + char *p = dst; + 800b98: 8b 45 08 mov 0x8(%ebp),%eax + 800b9b: 89 45 fc mov %eax,-0x4(%ebp) + while (len > 0) { + 800b9e: eb 1e jmp 800bbe + if ((*p = *src) != '\0') { + 800ba0: 8b 45 0c mov 0xc(%ebp),%eax + 800ba3: 0f b6 10 movzbl (%eax),%edx + 800ba6: 8b 45 fc mov -0x4(%ebp),%eax + 800ba9: 88 10 mov %dl,(%eax) + 800bab: 8b 45 fc mov -0x4(%ebp),%eax + 800bae: 0f b6 00 movzbl (%eax),%eax + 800bb1: 84 c0 test %al,%al + 800bb3: 74 03 je 800bb8 + src ++; + 800bb5: ff 45 0c incl 0xc(%ebp) + } + p ++, len --; + 800bb8: ff 45 fc incl -0x4(%ebp) + 800bbb: ff 4d 10 decl 0x10(%ebp) + while (len > 0) { + 800bbe: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800bc2: 75 dc jne 800ba0 + } + return dst; + 800bc4: 8b 45 08 mov 0x8(%ebp),%eax +} + 800bc7: 89 ec mov %ebp,%esp + 800bc9: 5d pop %ebp + 800bca: c3 ret + +00800bcb : + * - A value greater than zero indicates that the first character that does + * not match has a greater value in @s1 than in @s2; + * - And a value less than zero indicates the opposite. + * */ +int +strcmp(const char *s1, const char *s2) { + 800bcb: 55 push %ebp + 800bcc: 89 e5 mov %esp,%ebp + 800bce: 57 push %edi + 800bcf: 56 push %esi + 800bd0: 83 ec 20 sub $0x20,%esp + 800bd3: 8b 45 08 mov 0x8(%ebp),%eax + 800bd6: 89 45 f4 mov %eax,-0xc(%ebp) + 800bd9: 8b 45 0c mov 0xc(%ebp),%eax + 800bdc: 89 45 f0 mov %eax,-0x10(%ebp) + asm volatile ( + 800bdf: 8b 55 f4 mov -0xc(%ebp),%edx + 800be2: 8b 45 f0 mov -0x10(%ebp),%eax + 800be5: 89 d1 mov %edx,%ecx + 800be7: 89 c2 mov %eax,%edx + 800be9: 89 ce mov %ecx,%esi + 800beb: 89 d7 mov %edx,%edi + 800bed: ac lods %ds:(%esi),%al + 800bee: ae scas %es:(%edi),%al + 800bef: 75 08 jne 800bf9 + 800bf1: 84 c0 test %al,%al + 800bf3: 75 f8 jne 800bed + 800bf5: 31 c0 xor %eax,%eax + 800bf7: eb 04 jmp 800bfd + 800bf9: 19 c0 sbb %eax,%eax + 800bfb: 0c 01 or $0x1,%al + 800bfd: 89 fa mov %edi,%edx + 800bff: 89 f1 mov %esi,%ecx + 800c01: 89 45 ec mov %eax,-0x14(%ebp) + 800c04: 89 4d e8 mov %ecx,-0x18(%ebp) + 800c07: 89 55 e4 mov %edx,-0x1c(%ebp) + return ret; + 800c0a: 8b 45 ec mov -0x14(%ebp),%eax + while (*s1 != '\0' && *s1 == *s2) { + s1 ++, s2 ++; + } + return (int)((unsigned char)*s1 - (unsigned char)*s2); +#endif /* __HAVE_ARCH_STRCMP */ +} + 800c0d: 83 c4 20 add $0x20,%esp + 800c10: 5e pop %esi + 800c11: 5f pop %edi + 800c12: 5d pop %ebp + 800c13: c3 ret + +00800c14 : + * they are equal to each other, it continues with the following pairs until + * the characters differ, until a terminating null-character is reached, or + * until @n characters match in both strings, whichever happens first. + * */ +int +strncmp(const char *s1, const char *s2, size_t n) { + 800c14: 55 push %ebp + 800c15: 89 e5 mov %esp,%ebp + while (n > 0 && *s1 != '\0' && *s1 == *s2) { + 800c17: eb 09 jmp 800c22 + n --, s1 ++, s2 ++; + 800c19: ff 4d 10 decl 0x10(%ebp) + 800c1c: ff 45 08 incl 0x8(%ebp) + 800c1f: ff 45 0c incl 0xc(%ebp) + while (n > 0 && *s1 != '\0' && *s1 == *s2) { + 800c22: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800c26: 74 1a je 800c42 + 800c28: 8b 45 08 mov 0x8(%ebp),%eax + 800c2b: 0f b6 00 movzbl (%eax),%eax + 800c2e: 84 c0 test %al,%al + 800c30: 74 10 je 800c42 + 800c32: 8b 45 08 mov 0x8(%ebp),%eax + 800c35: 0f b6 10 movzbl (%eax),%edx + 800c38: 8b 45 0c mov 0xc(%ebp),%eax + 800c3b: 0f b6 00 movzbl (%eax),%eax + 800c3e: 38 c2 cmp %al,%dl + 800c40: 74 d7 je 800c19 + } + return (n == 0) ? 0 : (int)((unsigned char)*s1 - (unsigned char)*s2); + 800c42: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800c46: 74 18 je 800c60 + 800c48: 8b 45 08 mov 0x8(%ebp),%eax + 800c4b: 0f b6 00 movzbl (%eax),%eax + 800c4e: 0f b6 d0 movzbl %al,%edx + 800c51: 8b 45 0c mov 0xc(%ebp),%eax + 800c54: 0f b6 00 movzbl (%eax),%eax + 800c57: 0f b6 c8 movzbl %al,%ecx + 800c5a: 89 d0 mov %edx,%eax + 800c5c: 29 c8 sub %ecx,%eax + 800c5e: eb 05 jmp 800c65 + 800c60: b8 00 00 00 00 mov $0x0,%eax +} + 800c65: 5d pop %ebp + 800c66: c3 ret + +00800c67 : + * + * The strchr() function returns a pointer to the first occurrence of + * character in @s. If the value is not found, the function returns 'NULL'. + * */ +char * +strchr(const char *s, char c) { + 800c67: 55 push %ebp + 800c68: 89 e5 mov %esp,%ebp + 800c6a: 83 ec 04 sub $0x4,%esp + 800c6d: 8b 45 0c mov 0xc(%ebp),%eax + 800c70: 88 45 fc mov %al,-0x4(%ebp) + while (*s != '\0') { + 800c73: eb 13 jmp 800c88 + if (*s == c) { + 800c75: 8b 45 08 mov 0x8(%ebp),%eax + 800c78: 0f b6 00 movzbl (%eax),%eax + 800c7b: 38 45 fc cmp %al,-0x4(%ebp) + 800c7e: 75 05 jne 800c85 + return (char *)s; + 800c80: 8b 45 08 mov 0x8(%ebp),%eax + 800c83: eb 12 jmp 800c97 + } + s ++; + 800c85: ff 45 08 incl 0x8(%ebp) + while (*s != '\0') { + 800c88: 8b 45 08 mov 0x8(%ebp),%eax + 800c8b: 0f b6 00 movzbl (%eax),%eax + 800c8e: 84 c0 test %al,%al + 800c90: 75 e3 jne 800c75 + } + return NULL; + 800c92: b8 00 00 00 00 mov $0x0,%eax +} + 800c97: 89 ec mov %ebp,%esp + 800c99: 5d pop %ebp + 800c9a: c3 ret + +00800c9b : + * The strfind() function is like strchr() except that if @c is + * not found in @s, then it returns a pointer to the null byte at the + * end of @s, rather than 'NULL'. + * */ +char * +strfind(const char *s, char c) { + 800c9b: 55 push %ebp + 800c9c: 89 e5 mov %esp,%ebp + 800c9e: 83 ec 04 sub $0x4,%esp + 800ca1: 8b 45 0c mov 0xc(%ebp),%eax + 800ca4: 88 45 fc mov %al,-0x4(%ebp) + while (*s != '\0') { + 800ca7: eb 0e jmp 800cb7 + if (*s == c) { + 800ca9: 8b 45 08 mov 0x8(%ebp),%eax + 800cac: 0f b6 00 movzbl (%eax),%eax + 800caf: 38 45 fc cmp %al,-0x4(%ebp) + 800cb2: 74 0f je 800cc3 + break; + } + s ++; + 800cb4: ff 45 08 incl 0x8(%ebp) + while (*s != '\0') { + 800cb7: 8b 45 08 mov 0x8(%ebp),%eax + 800cba: 0f b6 00 movzbl (%eax),%eax + 800cbd: 84 c0 test %al,%al + 800cbf: 75 e8 jne 800ca9 + 800cc1: eb 01 jmp 800cc4 + break; + 800cc3: 90 nop + } + return (char *)s; + 800cc4: 8b 45 08 mov 0x8(%ebp),%eax +} + 800cc7: 89 ec mov %ebp,%esp + 800cc9: 5d pop %ebp + 800cca: c3 ret + +00800ccb : + * an optional "0x" or "0X" prefix. + * + * The strtol() function returns the converted integral number as a long int value. + * */ +long +strtol(const char *s, char **endptr, int base) { + 800ccb: 55 push %ebp + 800ccc: 89 e5 mov %esp,%ebp + 800cce: 83 ec 10 sub $0x10,%esp + int neg = 0; + 800cd1: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + long val = 0; + 800cd8: c7 45 f8 00 00 00 00 movl $0x0,-0x8(%ebp) + + // gobble initial whitespace + while (*s == ' ' || *s == '\t') { + 800cdf: eb 03 jmp 800ce4 + s ++; + 800ce1: ff 45 08 incl 0x8(%ebp) + while (*s == ' ' || *s == '\t') { + 800ce4: 8b 45 08 mov 0x8(%ebp),%eax + 800ce7: 0f b6 00 movzbl (%eax),%eax + 800cea: 3c 20 cmp $0x20,%al + 800cec: 74 f3 je 800ce1 + 800cee: 8b 45 08 mov 0x8(%ebp),%eax + 800cf1: 0f b6 00 movzbl (%eax),%eax + 800cf4: 3c 09 cmp $0x9,%al + 800cf6: 74 e9 je 800ce1 + } + + // plus/minus sign + if (*s == '+') { + 800cf8: 8b 45 08 mov 0x8(%ebp),%eax + 800cfb: 0f b6 00 movzbl (%eax),%eax + 800cfe: 3c 2b cmp $0x2b,%al + 800d00: 75 05 jne 800d07 + s ++; + 800d02: ff 45 08 incl 0x8(%ebp) + 800d05: eb 14 jmp 800d1b + } + else if (*s == '-') { + 800d07: 8b 45 08 mov 0x8(%ebp),%eax + 800d0a: 0f b6 00 movzbl (%eax),%eax + 800d0d: 3c 2d cmp $0x2d,%al + 800d0f: 75 0a jne 800d1b + s ++, neg = 1; + 800d11: ff 45 08 incl 0x8(%ebp) + 800d14: c7 45 fc 01 00 00 00 movl $0x1,-0x4(%ebp) + } + + // hex or octal base prefix + if ((base == 0 || base == 16) && (s[0] == '0' && s[1] == 'x')) { + 800d1b: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800d1f: 74 06 je 800d27 + 800d21: 83 7d 10 10 cmpl $0x10,0x10(%ebp) + 800d25: 75 22 jne 800d49 + 800d27: 8b 45 08 mov 0x8(%ebp),%eax + 800d2a: 0f b6 00 movzbl (%eax),%eax + 800d2d: 3c 30 cmp $0x30,%al + 800d2f: 75 18 jne 800d49 + 800d31: 8b 45 08 mov 0x8(%ebp),%eax + 800d34: 40 inc %eax + 800d35: 0f b6 00 movzbl (%eax),%eax + 800d38: 3c 78 cmp $0x78,%al + 800d3a: 75 0d jne 800d49 + s += 2, base = 16; + 800d3c: 83 45 08 02 addl $0x2,0x8(%ebp) + 800d40: c7 45 10 10 00 00 00 movl $0x10,0x10(%ebp) + 800d47: eb 29 jmp 800d72 + } + else if (base == 0 && s[0] == '0') { + 800d49: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800d4d: 75 16 jne 800d65 + 800d4f: 8b 45 08 mov 0x8(%ebp),%eax + 800d52: 0f b6 00 movzbl (%eax),%eax + 800d55: 3c 30 cmp $0x30,%al + 800d57: 75 0c jne 800d65 + s ++, base = 8; + 800d59: ff 45 08 incl 0x8(%ebp) + 800d5c: c7 45 10 08 00 00 00 movl $0x8,0x10(%ebp) + 800d63: eb 0d jmp 800d72 + } + else if (base == 0) { + 800d65: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800d69: 75 07 jne 800d72 + base = 10; + 800d6b: c7 45 10 0a 00 00 00 movl $0xa,0x10(%ebp) + + // digits + while (1) { + int dig; + + if (*s >= '0' && *s <= '9') { + 800d72: 8b 45 08 mov 0x8(%ebp),%eax + 800d75: 0f b6 00 movzbl (%eax),%eax + 800d78: 3c 2f cmp $0x2f,%al + 800d7a: 7e 1b jle 800d97 + 800d7c: 8b 45 08 mov 0x8(%ebp),%eax + 800d7f: 0f b6 00 movzbl (%eax),%eax + 800d82: 3c 39 cmp $0x39,%al + 800d84: 7f 11 jg 800d97 + dig = *s - '0'; + 800d86: 8b 45 08 mov 0x8(%ebp),%eax + 800d89: 0f b6 00 movzbl (%eax),%eax + 800d8c: 0f be c0 movsbl %al,%eax + 800d8f: 83 e8 30 sub $0x30,%eax + 800d92: 89 45 f4 mov %eax,-0xc(%ebp) + 800d95: eb 48 jmp 800ddf + } + else if (*s >= 'a' && *s <= 'z') { + 800d97: 8b 45 08 mov 0x8(%ebp),%eax + 800d9a: 0f b6 00 movzbl (%eax),%eax + 800d9d: 3c 60 cmp $0x60,%al + 800d9f: 7e 1b jle 800dbc + 800da1: 8b 45 08 mov 0x8(%ebp),%eax + 800da4: 0f b6 00 movzbl (%eax),%eax + 800da7: 3c 7a cmp $0x7a,%al + 800da9: 7f 11 jg 800dbc + dig = *s - 'a' + 10; + 800dab: 8b 45 08 mov 0x8(%ebp),%eax + 800dae: 0f b6 00 movzbl (%eax),%eax + 800db1: 0f be c0 movsbl %al,%eax + 800db4: 83 e8 57 sub $0x57,%eax + 800db7: 89 45 f4 mov %eax,-0xc(%ebp) + 800dba: eb 23 jmp 800ddf + } + else if (*s >= 'A' && *s <= 'Z') { + 800dbc: 8b 45 08 mov 0x8(%ebp),%eax + 800dbf: 0f b6 00 movzbl (%eax),%eax + 800dc2: 3c 40 cmp $0x40,%al + 800dc4: 7e 3b jle 800e01 + 800dc6: 8b 45 08 mov 0x8(%ebp),%eax + 800dc9: 0f b6 00 movzbl (%eax),%eax + 800dcc: 3c 5a cmp $0x5a,%al + 800dce: 7f 31 jg 800e01 + dig = *s - 'A' + 10; + 800dd0: 8b 45 08 mov 0x8(%ebp),%eax + 800dd3: 0f b6 00 movzbl (%eax),%eax + 800dd6: 0f be c0 movsbl %al,%eax + 800dd9: 83 e8 37 sub $0x37,%eax + 800ddc: 89 45 f4 mov %eax,-0xc(%ebp) + } + else { + break; + } + if (dig >= base) { + 800ddf: 8b 45 f4 mov -0xc(%ebp),%eax + 800de2: 3b 45 10 cmp 0x10(%ebp),%eax + 800de5: 7d 19 jge 800e00 + break; + } + s ++, val = (val * base) + dig; + 800de7: ff 45 08 incl 0x8(%ebp) + 800dea: 8b 45 f8 mov -0x8(%ebp),%eax + 800ded: 0f af 45 10 imul 0x10(%ebp),%eax + 800df1: 89 c2 mov %eax,%edx + 800df3: 8b 45 f4 mov -0xc(%ebp),%eax + 800df6: 01 d0 add %edx,%eax + 800df8: 89 45 f8 mov %eax,-0x8(%ebp) + while (1) { + 800dfb: e9 72 ff ff ff jmp 800d72 + break; + 800e00: 90 nop + // we don't properly detect overflow! + } + + if (endptr) { + 800e01: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) + 800e05: 74 08 je 800e0f + *endptr = (char *) s; + 800e07: 8b 45 0c mov 0xc(%ebp),%eax + 800e0a: 8b 55 08 mov 0x8(%ebp),%edx + 800e0d: 89 10 mov %edx,(%eax) + } + return (neg ? -val : val); + 800e0f: 83 7d fc 00 cmpl $0x0,-0x4(%ebp) + 800e13: 74 07 je 800e1c + 800e15: 8b 45 f8 mov -0x8(%ebp),%eax + 800e18: f7 d8 neg %eax + 800e1a: eb 03 jmp 800e1f + 800e1c: 8b 45 f8 mov -0x8(%ebp),%eax +} + 800e1f: 89 ec mov %ebp,%esp + 800e21: 5d pop %ebp + 800e22: c3 ret + +00800e23 : + * @n: number of bytes to be set to the value + * + * The memset() function returns @s. + * */ +void * +memset(void *s, char c, size_t n) { + 800e23: 55 push %ebp + 800e24: 89 e5 mov %esp,%ebp + 800e26: 83 ec 28 sub $0x28,%esp + 800e29: 89 7d fc mov %edi,-0x4(%ebp) + 800e2c: 8b 45 0c mov 0xc(%ebp),%eax + 800e2f: 88 45 d8 mov %al,-0x28(%ebp) +#ifdef __HAVE_ARCH_MEMSET + return __memset(s, c, n); + 800e32: 0f be 55 d8 movsbl -0x28(%ebp),%edx + 800e36: 8b 45 08 mov 0x8(%ebp),%eax + 800e39: 89 45 f8 mov %eax,-0x8(%ebp) + 800e3c: 88 55 f7 mov %dl,-0x9(%ebp) + 800e3f: 8b 45 10 mov 0x10(%ebp),%eax + 800e42: 89 45 f0 mov %eax,-0x10(%ebp) +#ifndef __HAVE_ARCH_MEMSET +#define __HAVE_ARCH_MEMSET +static inline void * +__memset(void *s, char c, size_t n) { + int d0, d1; + asm volatile ( + 800e45: 8b 4d f0 mov -0x10(%ebp),%ecx + 800e48: 0f b6 45 f7 movzbl -0x9(%ebp),%eax + 800e4c: 8b 55 f8 mov -0x8(%ebp),%edx + 800e4f: 89 d7 mov %edx,%edi + 800e51: f3 aa rep stos %al,%es:(%edi) + 800e53: 89 fa mov %edi,%edx + 800e55: 89 4d ec mov %ecx,-0x14(%ebp) + 800e58: 89 55 e8 mov %edx,-0x18(%ebp) + "rep; stosb;" + : "=&c" (d0), "=&D" (d1) + : "0" (n), "a" (c), "1" (s) + : "memory"); + return s; + 800e5b: 8b 45 f8 mov -0x8(%ebp),%eax + while (n -- > 0) { + *p ++ = c; + } + return s; +#endif /* __HAVE_ARCH_MEMSET */ +} + 800e5e: 8b 7d fc mov -0x4(%ebp),%edi + 800e61: 89 ec mov %ebp,%esp + 800e63: 5d pop %ebp + 800e64: c3 ret + +00800e65 : + * @n: number of bytes to copy + * + * The memmove() function returns @dst. + * */ +void * +memmove(void *dst, const void *src, size_t n) { + 800e65: 55 push %ebp + 800e66: 89 e5 mov %esp,%ebp + 800e68: 57 push %edi + 800e69: 56 push %esi + 800e6a: 53 push %ebx + 800e6b: 83 ec 30 sub $0x30,%esp + 800e6e: 8b 45 08 mov 0x8(%ebp),%eax + 800e71: 89 45 f0 mov %eax,-0x10(%ebp) + 800e74: 8b 45 0c mov 0xc(%ebp),%eax + 800e77: 89 45 ec mov %eax,-0x14(%ebp) + 800e7a: 8b 45 10 mov 0x10(%ebp),%eax + 800e7d: 89 45 e8 mov %eax,-0x18(%ebp) + +#ifndef __HAVE_ARCH_MEMMOVE +#define __HAVE_ARCH_MEMMOVE +static inline void * +__memmove(void *dst, const void *src, size_t n) { + if (dst < src) { + 800e80: 8b 45 f0 mov -0x10(%ebp),%eax + 800e83: 3b 45 ec cmp -0x14(%ebp),%eax + 800e86: 73 42 jae 800eca + 800e88: 8b 45 f0 mov -0x10(%ebp),%eax + 800e8b: 89 45 e4 mov %eax,-0x1c(%ebp) + 800e8e: 8b 45 ec mov -0x14(%ebp),%eax + 800e91: 89 45 e0 mov %eax,-0x20(%ebp) + 800e94: 8b 45 e8 mov -0x18(%ebp),%eax + 800e97: 89 45 dc mov %eax,-0x24(%ebp) + "andl $3, %%ecx;" + "jz 1f;" + "rep; movsb;" + "1:" + : "=&c" (d0), "=&D" (d1), "=&S" (d2) + : "0" (n / 4), "g" (n), "1" (dst), "2" (src) + 800e9a: 8b 45 dc mov -0x24(%ebp),%eax + 800e9d: c1 e8 02 shr $0x2,%eax + 800ea0: 89 c1 mov %eax,%ecx + asm volatile ( + 800ea2: 8b 55 e4 mov -0x1c(%ebp),%edx + 800ea5: 8b 45 e0 mov -0x20(%ebp),%eax + 800ea8: 89 d7 mov %edx,%edi + 800eaa: 89 c6 mov %eax,%esi + 800eac: f3 a5 rep movsl %ds:(%esi),%es:(%edi) + 800eae: 8b 4d dc mov -0x24(%ebp),%ecx + 800eb1: 83 e1 03 and $0x3,%ecx + 800eb4: 74 02 je 800eb8 + 800eb6: f3 a4 rep movsb %ds:(%esi),%es:(%edi) + 800eb8: 89 f0 mov %esi,%eax + 800eba: 89 fa mov %edi,%edx + 800ebc: 89 4d d8 mov %ecx,-0x28(%ebp) + 800ebf: 89 55 d4 mov %edx,-0x2c(%ebp) + 800ec2: 89 45 d0 mov %eax,-0x30(%ebp) + : "memory"); + return dst; + 800ec5: 8b 45 e4 mov -0x1c(%ebp),%eax + return __memcpy(dst, src, n); + 800ec8: eb 36 jmp 800f00 + : "0" (n), "1" (n - 1 + src), "2" (n - 1 + dst) + 800eca: 8b 45 e8 mov -0x18(%ebp),%eax + 800ecd: 8d 50 ff lea -0x1(%eax),%edx + 800ed0: 8b 45 ec mov -0x14(%ebp),%eax + 800ed3: 01 c2 add %eax,%edx + 800ed5: 8b 45 e8 mov -0x18(%ebp),%eax + 800ed8: 8d 48 ff lea -0x1(%eax),%ecx + 800edb: 8b 45 f0 mov -0x10(%ebp),%eax + 800ede: 8d 1c 01 lea (%ecx,%eax,1),%ebx + asm volatile ( + 800ee1: 8b 45 e8 mov -0x18(%ebp),%eax + 800ee4: 89 c1 mov %eax,%ecx + 800ee6: 89 d8 mov %ebx,%eax + 800ee8: 89 d6 mov %edx,%esi + 800eea: 89 c7 mov %eax,%edi + 800eec: fd std + 800eed: f3 a4 rep movsb %ds:(%esi),%es:(%edi) + 800eef: fc cld + 800ef0: 89 f8 mov %edi,%eax + 800ef2: 89 f2 mov %esi,%edx + 800ef4: 89 4d cc mov %ecx,-0x34(%ebp) + 800ef7: 89 55 c8 mov %edx,-0x38(%ebp) + 800efa: 89 45 c4 mov %eax,-0x3c(%ebp) + return dst; + 800efd: 8b 45 f0 mov -0x10(%ebp),%eax + *d ++ = *s ++; + } + } + return dst; +#endif /* __HAVE_ARCH_MEMMOVE */ +} + 800f00: 83 c4 30 add $0x30,%esp + 800f03: 5b pop %ebx + 800f04: 5e pop %esi + 800f05: 5f pop %edi + 800f06: 5d pop %ebp + 800f07: c3 ret + +00800f08 : + * it always copies exactly @n bytes. To avoid overflows, the size of arrays pointed + * by both @src and @dst, should be at least @n bytes, and should not overlap + * (for overlapping memory area, memmove is a safer approach). + * */ +void * +memcpy(void *dst, const void *src, size_t n) { + 800f08: 55 push %ebp + 800f09: 89 e5 mov %esp,%ebp + 800f0b: 57 push %edi + 800f0c: 56 push %esi + 800f0d: 83 ec 20 sub $0x20,%esp + 800f10: 8b 45 08 mov 0x8(%ebp),%eax + 800f13: 89 45 f4 mov %eax,-0xc(%ebp) + 800f16: 8b 45 0c mov 0xc(%ebp),%eax + 800f19: 89 45 f0 mov %eax,-0x10(%ebp) + 800f1c: 8b 45 10 mov 0x10(%ebp),%eax + 800f1f: 89 45 ec mov %eax,-0x14(%ebp) + : "0" (n / 4), "g" (n), "1" (dst), "2" (src) + 800f22: 8b 45 ec mov -0x14(%ebp),%eax + 800f25: c1 e8 02 shr $0x2,%eax + 800f28: 89 c1 mov %eax,%ecx + asm volatile ( + 800f2a: 8b 55 f4 mov -0xc(%ebp),%edx + 800f2d: 8b 45 f0 mov -0x10(%ebp),%eax + 800f30: 89 d7 mov %edx,%edi + 800f32: 89 c6 mov %eax,%esi + 800f34: f3 a5 rep movsl %ds:(%esi),%es:(%edi) + 800f36: 8b 4d ec mov -0x14(%ebp),%ecx + 800f39: 83 e1 03 and $0x3,%ecx + 800f3c: 74 02 je 800f40 + 800f3e: f3 a4 rep movsb %ds:(%esi),%es:(%edi) + 800f40: 89 f0 mov %esi,%eax + 800f42: 89 fa mov %edi,%edx + 800f44: 89 4d e8 mov %ecx,-0x18(%ebp) + 800f47: 89 55 e4 mov %edx,-0x1c(%ebp) + 800f4a: 89 45 e0 mov %eax,-0x20(%ebp) + return dst; + 800f4d: 8b 45 f4 mov -0xc(%ebp),%eax + while (n -- > 0) { + *d ++ = *s ++; + } + return dst; +#endif /* __HAVE_ARCH_MEMCPY */ +} + 800f50: 83 c4 20 add $0x20,%esp + 800f53: 5e pop %esi + 800f54: 5f pop %edi + 800f55: 5d pop %ebp + 800f56: c3 ret + +00800f57 : + * match in both memory blocks has a greater value in @v1 than in @v2 + * as if evaluated as unsigned char values; + * - And a value less than zero indicates the opposite. + * */ +int +memcmp(const void *v1, const void *v2, size_t n) { + 800f57: 55 push %ebp + 800f58: 89 e5 mov %esp,%ebp + 800f5a: 83 ec 10 sub $0x10,%esp + const char *s1 = (const char *)v1; + 800f5d: 8b 45 08 mov 0x8(%ebp),%eax + 800f60: 89 45 fc mov %eax,-0x4(%ebp) + const char *s2 = (const char *)v2; + 800f63: 8b 45 0c mov 0xc(%ebp),%eax + 800f66: 89 45 f8 mov %eax,-0x8(%ebp) + while (n -- > 0) { + 800f69: eb 2e jmp 800f99 + if (*s1 != *s2) { + 800f6b: 8b 45 fc mov -0x4(%ebp),%eax + 800f6e: 0f b6 10 movzbl (%eax),%edx + 800f71: 8b 45 f8 mov -0x8(%ebp),%eax + 800f74: 0f b6 00 movzbl (%eax),%eax + 800f77: 38 c2 cmp %al,%dl + 800f79: 74 18 je 800f93 + return (int)((unsigned char)*s1 - (unsigned char)*s2); + 800f7b: 8b 45 fc mov -0x4(%ebp),%eax + 800f7e: 0f b6 00 movzbl (%eax),%eax + 800f81: 0f b6 d0 movzbl %al,%edx + 800f84: 8b 45 f8 mov -0x8(%ebp),%eax + 800f87: 0f b6 00 movzbl (%eax),%eax + 800f8a: 0f b6 c8 movzbl %al,%ecx + 800f8d: 89 d0 mov %edx,%eax + 800f8f: 29 c8 sub %ecx,%eax + 800f91: eb 18 jmp 800fab + } + s1 ++, s2 ++; + 800f93: ff 45 fc incl -0x4(%ebp) + 800f96: ff 45 f8 incl -0x8(%ebp) + while (n -- > 0) { + 800f99: 8b 45 10 mov 0x10(%ebp),%eax + 800f9c: 8d 50 ff lea -0x1(%eax),%edx + 800f9f: 89 55 10 mov %edx,0x10(%ebp) + 800fa2: 85 c0 test %eax,%eax + 800fa4: 75 c5 jne 800f6b + } + return 0; + 800fa6: b8 00 00 00 00 mov $0x0,%eax +} + 800fab: 89 ec mov %ebp,%esp + 800fad: 5d pop %ebp + 800fae: c3 ret + +00800faf : +#define DEPTH 4 + +void forktree(const char *cur); + +void +forkchild(const char *cur, char branch) { + 800faf: 55 push %ebp + 800fb0: 89 e5 mov %esp,%ebp + 800fb2: 83 ec 48 sub $0x48,%esp + 800fb5: 8b 45 0c mov 0xc(%ebp),%eax + 800fb8: 88 45 e4 mov %al,-0x1c(%ebp) + char nxt[DEPTH + 1]; + + if (strlen(cur) >= DEPTH) + 800fbb: 8b 45 08 mov 0x8(%ebp),%eax + 800fbe: 89 04 24 mov %eax,(%esp) + 800fc1: e8 33 fb ff ff call 800af9 + 800fc6: 83 f8 03 cmp $0x3,%eax + 800fc9: 77 4f ja 80101a + return; + + snprintf(nxt, DEPTH + 1, "%s%c", cur, branch); + 800fcb: 0f be 45 e4 movsbl -0x1c(%ebp),%eax + 800fcf: 89 44 24 10 mov %eax,0x10(%esp) + 800fd3: 8b 45 08 mov 0x8(%ebp),%eax + 800fd6: 89 44 24 0c mov %eax,0xc(%esp) + 800fda: c7 44 24 08 80 13 80 movl $0x801380,0x8(%esp) + 800fe1: 00 + 800fe2: c7 44 24 04 05 00 00 movl $0x5,0x4(%esp) + 800fe9: 00 + 800fea: 8d 45 f3 lea -0xd(%ebp),%eax + 800fed: 89 04 24 mov %eax,(%esp) + 800ff0: e8 90 f9 ff ff call 800985 + if (fork() == 0) { + 800ff5: e8 e6 f2 ff ff call 8002e0 + 800ffa: 85 c0 test %eax,%eax + 800ffc: 75 1d jne 80101b + forktree(nxt); + 800ffe: 8d 45 f3 lea -0xd(%ebp),%eax + 801001: 89 04 24 mov %eax,(%esp) + 801004: e8 16 00 00 00 call 80101f + yield(); + 801009: e8 1b f3 ff ff call 800329 + exit(0); + 80100e: c7 04 24 00 00 00 00 movl $0x0,(%esp) + 801015: e8 a7 f2 ff ff call 8002c1 + return; + 80101a: 90 nop + } +} + 80101b: 89 ec mov %ebp,%esp + 80101d: 5d pop %ebp + 80101e: c3 ret + +0080101f : + +void +forktree(const char *cur) { + 80101f: 55 push %ebp + 801020: 89 e5 mov %esp,%ebp + 801022: 83 ec 18 sub $0x18,%esp + cprintf("%04x: I am '%s'\n", getpid(), cur); + 801025: e8 24 f3 ff ff call 80034e + 80102a: 8b 55 08 mov 0x8(%ebp),%edx + 80102d: 89 54 24 08 mov %edx,0x8(%esp) + 801031: 89 44 24 04 mov %eax,0x4(%esp) + 801035: c7 04 24 85 13 80 00 movl $0x801385,(%esp) + 80103c: e8 df f0 ff ff call 800120 + + forkchild(cur, '0'); + 801041: c7 44 24 04 30 00 00 movl $0x30,0x4(%esp) + 801048: 00 + 801049: 8b 45 08 mov 0x8(%ebp),%eax + 80104c: 89 04 24 mov %eax,(%esp) + 80104f: e8 5b ff ff ff call 800faf + forkchild(cur, '1'); + 801054: c7 44 24 04 31 00 00 movl $0x31,0x4(%esp) + 80105b: 00 + 80105c: 8b 45 08 mov 0x8(%ebp),%eax + 80105f: 89 04 24 mov %eax,(%esp) + 801062: e8 48 ff ff ff call 800faf +} + 801067: 90 nop + 801068: 89 ec mov %ebp,%esp + 80106a: 5d pop %ebp + 80106b: c3 ret + +0080106c
: + +int +main(void) { + 80106c: 55 push %ebp + 80106d: 89 e5 mov %esp,%ebp + 80106f: 83 e4 f0 and $0xfffffff0,%esp + 801072: 83 ec 10 sub $0x10,%esp + forktree(""); + 801075: c7 04 24 96 13 80 00 movl $0x801396,(%esp) + 80107c: e8 9e ff ff ff call 80101f + return 0; + 801081: b8 00 00 00 00 mov $0x0,%eax +} + 801086: 89 ec mov %ebp,%esp + 801088: 5d pop %ebp + 801089: c3 ret diff --git a/labcodes/lab5/obj/user/forktree.d b/labcodes/lab5/obj/user/forktree.d new file mode 100644 index 0000000000000000000000000000000000000000..04773a632b614c6e4b61bf95d6d98e9419085290 --- /dev/null +++ b/labcodes/lab5/obj/user/forktree.d @@ -0,0 +1,2 @@ +obj/user/forktree.o obj/user/forktree.d: user/forktree.c user/libs/ulib.h \ + libs/defs.h libs/stdio.h libs/stdarg.h libs/string.h diff --git a/labcodes/lab5/obj/user/forktree.o b/labcodes/lab5/obj/user/forktree.o new file mode 100644 index 0000000000000000000000000000000000000000..5a0d26e092a7870ba20641189a6555246cb49606 Binary files /dev/null and b/labcodes/lab5/obj/user/forktree.o differ diff --git a/labcodes/lab5/obj/user/forktree.sym b/labcodes/lab5/obj/user/forktree.sym new file mode 100644 index 0000000000000000000000000000000000000000..f65c9fea7911806cc6d47a61807f7b3f248646b5 --- /dev/null +++ b/labcodes/lab5/obj/user/forktree.sym @@ -0,0 +1,68 @@ +00000000 panic.c +00000000 stdio.c +008000c8 cputch +00000000 syscall.c +00800199 syscall +00000000 ulib.c +00000000 umain.c +00000000 hash.c +00000000 printfmt.c +008011a0 error_string +008003ad printnum +008004af getuint +008004fe getint +0080094f sprintputch +00000000 rand.c +00802000 next +00000000 string.c +00000000 forktree.c +00800b53 strcpy +00800329 yield +0080030d waitpid +00800245 sys_yield +00800e65 memmove +00800985 snprintf +00800576 vprintfmt +0080020b sys_fork +00800120 cprintf +0080034e getpid +00800f08 memcpy +008009bb vsnprintf +0080036d umain +0020280c __STAB_END__ +0080025b sys_kill +0020280d __STABSTR_BEGIN__ +0080002f __panic +00800ccb strtol +00800b22 strnlen +0080101f forktree +0080035d print_pgdir +00800339 kill +00800c9b strfind +008002ef wait +00800020 _start +00800a21 rand +00800c14 strncmp +0080028e sys_putc +00800b92 strncpy +00800f57 memcmp +008002e0 fork +00800e23 memset +0080106c main +00800ae0 srand +00800386 hash32 +00800545 printfmt +002037bb __STABSTR_END__ +00800bcb strcmp +008000eb vcprintf +0080007f __warn +00800148 cputs +008002c1 exit +00800221 sys_wait +008001ee sys_exit +00200010 __STAB_BEGIN__ +00800af9 strlen +008002ab sys_pgdir +00800c67 strchr +00800278 sys_getpid +00800faf forkchild diff --git a/labcodes/lab5/obj/user/hello.asm b/labcodes/lab5/obj/user/hello.asm new file mode 100644 index 0000000000000000000000000000000000000000..745d55af8c8436e68961aba4aec531a12a590602 --- /dev/null +++ b/labcodes/lab5/obj/user/hello.asm @@ -0,0 +1,2327 @@ + +obj/__user_hello.out: file format elf32-i386 + + +Disassembly of section .text: + +00800020 <_start>: +.text +.globl _start +_start: + # set ebp for backtrace + movl $0x0, %ebp + 800020: bd 00 00 00 00 mov $0x0,%ebp + + # move down the esp register + # since it may cause page fault in backtrace + subl $0x20, %esp + 800025: 83 ec 20 sub $0x20,%esp + + # call user-program function + call umain + 800028: e8 40 03 00 00 call 80036d +1: jmp 1b + 80002d: eb fe jmp 80002d <_start+0xd> + +0080002f <__panic>: +#include +#include +#include + +void +__panic(const char *file, int line, const char *fmt, ...) { + 80002f: 55 push %ebp + 800030: 89 e5 mov %esp,%ebp + 800032: 83 ec 28 sub $0x28,%esp + // print the 'message' + va_list ap; + va_start(ap, fmt); + 800035: 8d 45 14 lea 0x14(%ebp),%eax + 800038: 89 45 f4 mov %eax,-0xc(%ebp) + cprintf("user panic at %s:%d:\n ", file, line); + 80003b: 8b 45 0c mov 0xc(%ebp),%eax + 80003e: 89 44 24 08 mov %eax,0x8(%esp) + 800042: 8b 45 08 mov 0x8(%ebp),%eax + 800045: 89 44 24 04 mov %eax,0x4(%esp) + 800049: c7 04 24 00 10 80 00 movl $0x801000,(%esp) + 800050: e8 cb 00 00 00 call 800120 + vcprintf(fmt, ap); + 800055: 8b 45 f4 mov -0xc(%ebp),%eax + 800058: 89 44 24 04 mov %eax,0x4(%esp) + 80005c: 8b 45 10 mov 0x10(%ebp),%eax + 80005f: 89 04 24 mov %eax,(%esp) + 800062: e8 84 00 00 00 call 8000eb + cprintf("\n"); + 800067: c7 04 24 1a 10 80 00 movl $0x80101a,(%esp) + 80006e: e8 ad 00 00 00 call 800120 + va_end(ap); + exit(-E_PANIC); + 800073: c7 04 24 f6 ff ff ff movl $0xfffffff6,(%esp) + 80007a: e8 42 02 00 00 call 8002c1 + +0080007f <__warn>: +} + +void +__warn(const char *file, int line, const char *fmt, ...) { + 80007f: 55 push %ebp + 800080: 89 e5 mov %esp,%ebp + 800082: 83 ec 28 sub $0x28,%esp + va_list ap; + va_start(ap, fmt); + 800085: 8d 45 14 lea 0x14(%ebp),%eax + 800088: 89 45 f4 mov %eax,-0xc(%ebp) + cprintf("user warning at %s:%d:\n ", file, line); + 80008b: 8b 45 0c mov 0xc(%ebp),%eax + 80008e: 89 44 24 08 mov %eax,0x8(%esp) + 800092: 8b 45 08 mov 0x8(%ebp),%eax + 800095: 89 44 24 04 mov %eax,0x4(%esp) + 800099: c7 04 24 1c 10 80 00 movl $0x80101c,(%esp) + 8000a0: e8 7b 00 00 00 call 800120 + vcprintf(fmt, ap); + 8000a5: 8b 45 f4 mov -0xc(%ebp),%eax + 8000a8: 89 44 24 04 mov %eax,0x4(%esp) + 8000ac: 8b 45 10 mov 0x10(%ebp),%eax + 8000af: 89 04 24 mov %eax,(%esp) + 8000b2: e8 34 00 00 00 call 8000eb + cprintf("\n"); + 8000b7: c7 04 24 1a 10 80 00 movl $0x80101a,(%esp) + 8000be: e8 5d 00 00 00 call 800120 + va_end(ap); +} + 8000c3: 90 nop + 8000c4: 89 ec mov %ebp,%esp + 8000c6: 5d pop %ebp + 8000c7: c3 ret + +008000c8 : +/* * + * cputch - writes a single character @c to stdout, and it will + * increace the value of counter pointed by @cnt. + * */ +static void +cputch(int c, int *cnt) { + 8000c8: 55 push %ebp + 8000c9: 89 e5 mov %esp,%ebp + 8000cb: 83 ec 18 sub $0x18,%esp + sys_putc(c); + 8000ce: 8b 45 08 mov 0x8(%ebp),%eax + 8000d1: 89 04 24 mov %eax,(%esp) + 8000d4: e8 b5 01 00 00 call 80028e + (*cnt) ++; + 8000d9: 8b 45 0c mov 0xc(%ebp),%eax + 8000dc: 8b 00 mov (%eax),%eax + 8000de: 8d 50 01 lea 0x1(%eax),%edx + 8000e1: 8b 45 0c mov 0xc(%ebp),%eax + 8000e4: 89 10 mov %edx,(%eax) +} + 8000e6: 90 nop + 8000e7: 89 ec mov %ebp,%esp + 8000e9: 5d pop %ebp + 8000ea: c3 ret + +008000eb : + * + * Call this function if you are already dealing with a va_list. + * Or you probably want cprintf() instead. + * */ +int +vcprintf(const char *fmt, va_list ap) { + 8000eb: 55 push %ebp + 8000ec: 89 e5 mov %esp,%ebp + 8000ee: 83 ec 28 sub $0x28,%esp + int cnt = 0; + 8000f1: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + vprintfmt((void*)cputch, &cnt, fmt, ap); + 8000f8: 8b 45 0c mov 0xc(%ebp),%eax + 8000fb: 89 44 24 0c mov %eax,0xc(%esp) + 8000ff: 8b 45 08 mov 0x8(%ebp),%eax + 800102: 89 44 24 08 mov %eax,0x8(%esp) + 800106: 8d 45 f4 lea -0xc(%ebp),%eax + 800109: 89 44 24 04 mov %eax,0x4(%esp) + 80010d: c7 04 24 c8 00 80 00 movl $0x8000c8,(%esp) + 800114: e8 5d 04 00 00 call 800576 + return cnt; + 800119: 8b 45 f4 mov -0xc(%ebp),%eax +} + 80011c: 89 ec mov %ebp,%esp + 80011e: 5d pop %ebp + 80011f: c3 ret + +00800120 : + * + * The return value is the number of characters which would be + * written to stdout. + * */ +int +cprintf(const char *fmt, ...) { + 800120: 55 push %ebp + 800121: 89 e5 mov %esp,%ebp + 800123: 83 ec 28 sub $0x28,%esp + va_list ap; + + va_start(ap, fmt); + 800126: 8d 45 0c lea 0xc(%ebp),%eax + 800129: 89 45 f0 mov %eax,-0x10(%ebp) + int cnt = vcprintf(fmt, ap); + 80012c: 8b 45 f0 mov -0x10(%ebp),%eax + 80012f: 89 44 24 04 mov %eax,0x4(%esp) + 800133: 8b 45 08 mov 0x8(%ebp),%eax + 800136: 89 04 24 mov %eax,(%esp) + 800139: e8 ad ff ff ff call 8000eb + 80013e: 89 45 f4 mov %eax,-0xc(%ebp) + va_end(ap); + + return cnt; + 800141: 8b 45 f4 mov -0xc(%ebp),%eax +} + 800144: 89 ec mov %ebp,%esp + 800146: 5d pop %ebp + 800147: c3 ret + +00800148 : +/* * + * cputs- writes the string pointed by @str to stdout and + * appends a newline character. + * */ +int +cputs(const char *str) { + 800148: 55 push %ebp + 800149: 89 e5 mov %esp,%ebp + 80014b: 83 ec 28 sub $0x28,%esp + int cnt = 0; + 80014e: c7 45 f0 00 00 00 00 movl $0x0,-0x10(%ebp) + char c; + while ((c = *str ++) != '\0') { + 800155: eb 13 jmp 80016a + cputch(c, &cnt); + 800157: 0f be 45 f7 movsbl -0x9(%ebp),%eax + 80015b: 8d 55 f0 lea -0x10(%ebp),%edx + 80015e: 89 54 24 04 mov %edx,0x4(%esp) + 800162: 89 04 24 mov %eax,(%esp) + 800165: e8 5e ff ff ff call 8000c8 + while ((c = *str ++) != '\0') { + 80016a: 8b 45 08 mov 0x8(%ebp),%eax + 80016d: 8d 50 01 lea 0x1(%eax),%edx + 800170: 89 55 08 mov %edx,0x8(%ebp) + 800173: 0f b6 00 movzbl (%eax),%eax + 800176: 88 45 f7 mov %al,-0x9(%ebp) + 800179: 80 7d f7 00 cmpb $0x0,-0x9(%ebp) + 80017d: 75 d8 jne 800157 + } + cputch('\n', &cnt); + 80017f: 8d 45 f0 lea -0x10(%ebp),%eax + 800182: 89 44 24 04 mov %eax,0x4(%esp) + 800186: c7 04 24 0a 00 00 00 movl $0xa,(%esp) + 80018d: e8 36 ff ff ff call 8000c8 + return cnt; + 800192: 8b 45 f0 mov -0x10(%ebp),%eax +} + 800195: 89 ec mov %ebp,%esp + 800197: 5d pop %ebp + 800198: c3 ret + +00800199 : +#include + +#define MAX_ARGS 5 + +static inline int +syscall(int num, ...) { + 800199: 55 push %ebp + 80019a: 89 e5 mov %esp,%ebp + 80019c: 57 push %edi + 80019d: 56 push %esi + 80019e: 53 push %ebx + 80019f: 83 ec 20 sub $0x20,%esp + va_list ap; + va_start(ap, num); + 8001a2: 8d 45 0c lea 0xc(%ebp),%eax + 8001a5: 89 45 e8 mov %eax,-0x18(%ebp) + uint32_t a[MAX_ARGS]; + int i, ret; + for (i = 0; i < MAX_ARGS; i ++) { + 8001a8: c7 45 f0 00 00 00 00 movl $0x0,-0x10(%ebp) + 8001af: eb 15 jmp 8001c6 + a[i] = va_arg(ap, uint32_t); + 8001b1: 8b 45 e8 mov -0x18(%ebp),%eax + 8001b4: 8d 50 04 lea 0x4(%eax),%edx + 8001b7: 89 55 e8 mov %edx,-0x18(%ebp) + 8001ba: 8b 10 mov (%eax),%edx + 8001bc: 8b 45 f0 mov -0x10(%ebp),%eax + 8001bf: 89 54 85 d4 mov %edx,-0x2c(%ebp,%eax,4) + for (i = 0; i < MAX_ARGS; i ++) { + 8001c3: ff 45 f0 incl -0x10(%ebp) + 8001c6: 83 7d f0 04 cmpl $0x4,-0x10(%ebp) + 8001ca: 7e e5 jle 8001b1 + asm volatile ( + "int %1;" + : "=a" (ret) + : "i" (T_SYSCALL), + "a" (num), + "d" (a[0]), + 8001cc: 8b 55 d4 mov -0x2c(%ebp),%edx + "c" (a[1]), + 8001cf: 8b 4d d8 mov -0x28(%ebp),%ecx + "b" (a[2]), + 8001d2: 8b 5d dc mov -0x24(%ebp),%ebx + "D" (a[3]), + 8001d5: 8b 7d e0 mov -0x20(%ebp),%edi + "S" (a[4]) + 8001d8: 8b 75 e4 mov -0x1c(%ebp),%esi + asm volatile ( + 8001db: 8b 45 08 mov 0x8(%ebp),%eax + 8001de: cd 80 int $0x80 + 8001e0: 89 45 ec mov %eax,-0x14(%ebp) + : "cc", "memory"); + return ret; + 8001e3: 8b 45 ec mov -0x14(%ebp),%eax +} + 8001e6: 83 c4 20 add $0x20,%esp + 8001e9: 5b pop %ebx + 8001ea: 5e pop %esi + 8001eb: 5f pop %edi + 8001ec: 5d pop %ebp + 8001ed: c3 ret + +008001ee : + +int +sys_exit(int error_code) { + 8001ee: 55 push %ebp + 8001ef: 89 e5 mov %esp,%ebp + 8001f1: 83 ec 08 sub $0x8,%esp + return syscall(SYS_exit, error_code); + 8001f4: 8b 45 08 mov 0x8(%ebp),%eax + 8001f7: 89 44 24 04 mov %eax,0x4(%esp) + 8001fb: c7 04 24 01 00 00 00 movl $0x1,(%esp) + 800202: e8 92 ff ff ff call 800199 +} + 800207: 89 ec mov %ebp,%esp + 800209: 5d pop %ebp + 80020a: c3 ret + +0080020b : + +int +sys_fork(void) { + 80020b: 55 push %ebp + 80020c: 89 e5 mov %esp,%ebp + 80020e: 83 ec 04 sub $0x4,%esp + return syscall(SYS_fork); + 800211: c7 04 24 02 00 00 00 movl $0x2,(%esp) + 800218: e8 7c ff ff ff call 800199 +} + 80021d: 89 ec mov %ebp,%esp + 80021f: 5d pop %ebp + 800220: c3 ret + +00800221 : + +int +sys_wait(int pid, int *store) { + 800221: 55 push %ebp + 800222: 89 e5 mov %esp,%ebp + 800224: 83 ec 0c sub $0xc,%esp + return syscall(SYS_wait, pid, store); + 800227: 8b 45 0c mov 0xc(%ebp),%eax + 80022a: 89 44 24 08 mov %eax,0x8(%esp) + 80022e: 8b 45 08 mov 0x8(%ebp),%eax + 800231: 89 44 24 04 mov %eax,0x4(%esp) + 800235: c7 04 24 03 00 00 00 movl $0x3,(%esp) + 80023c: e8 58 ff ff ff call 800199 +} + 800241: 89 ec mov %ebp,%esp + 800243: 5d pop %ebp + 800244: c3 ret + +00800245 : + +int +sys_yield(void) { + 800245: 55 push %ebp + 800246: 89 e5 mov %esp,%ebp + 800248: 83 ec 04 sub $0x4,%esp + return syscall(SYS_yield); + 80024b: c7 04 24 0a 00 00 00 movl $0xa,(%esp) + 800252: e8 42 ff ff ff call 800199 +} + 800257: 89 ec mov %ebp,%esp + 800259: 5d pop %ebp + 80025a: c3 ret + +0080025b : + +int +sys_kill(int pid) { + 80025b: 55 push %ebp + 80025c: 89 e5 mov %esp,%ebp + 80025e: 83 ec 08 sub $0x8,%esp + return syscall(SYS_kill, pid); + 800261: 8b 45 08 mov 0x8(%ebp),%eax + 800264: 89 44 24 04 mov %eax,0x4(%esp) + 800268: c7 04 24 0c 00 00 00 movl $0xc,(%esp) + 80026f: e8 25 ff ff ff call 800199 +} + 800274: 89 ec mov %ebp,%esp + 800276: 5d pop %ebp + 800277: c3 ret + +00800278 : + +int +sys_getpid(void) { + 800278: 55 push %ebp + 800279: 89 e5 mov %esp,%ebp + 80027b: 83 ec 04 sub $0x4,%esp + return syscall(SYS_getpid); + 80027e: c7 04 24 12 00 00 00 movl $0x12,(%esp) + 800285: e8 0f ff ff ff call 800199 +} + 80028a: 89 ec mov %ebp,%esp + 80028c: 5d pop %ebp + 80028d: c3 ret + +0080028e : + +int +sys_putc(int c) { + 80028e: 55 push %ebp + 80028f: 89 e5 mov %esp,%ebp + 800291: 83 ec 08 sub $0x8,%esp + return syscall(SYS_putc, c); + 800294: 8b 45 08 mov 0x8(%ebp),%eax + 800297: 89 44 24 04 mov %eax,0x4(%esp) + 80029b: c7 04 24 1e 00 00 00 movl $0x1e,(%esp) + 8002a2: e8 f2 fe ff ff call 800199 +} + 8002a7: 89 ec mov %ebp,%esp + 8002a9: 5d pop %ebp + 8002aa: c3 ret + +008002ab : + +int +sys_pgdir(void) { + 8002ab: 55 push %ebp + 8002ac: 89 e5 mov %esp,%ebp + 8002ae: 83 ec 04 sub $0x4,%esp + return syscall(SYS_pgdir); + 8002b1: c7 04 24 1f 00 00 00 movl $0x1f,(%esp) + 8002b8: e8 dc fe ff ff call 800199 +} + 8002bd: 89 ec mov %ebp,%esp + 8002bf: 5d pop %ebp + 8002c0: c3 ret + +008002c1 : +#include +#include +#include + +void +exit(int error_code) { + 8002c1: 55 push %ebp + 8002c2: 89 e5 mov %esp,%ebp + 8002c4: 83 ec 18 sub $0x18,%esp + sys_exit(error_code); + 8002c7: 8b 45 08 mov 0x8(%ebp),%eax + 8002ca: 89 04 24 mov %eax,(%esp) + 8002cd: e8 1c ff ff ff call 8001ee + cprintf("BUG: exit failed.\n"); + 8002d2: c7 04 24 38 10 80 00 movl $0x801038,(%esp) + 8002d9: e8 42 fe ff ff call 800120 + while (1); + 8002de: eb fe jmp 8002de + +008002e0 : +} + +int +fork(void) { + 8002e0: 55 push %ebp + 8002e1: 89 e5 mov %esp,%ebp + 8002e3: 83 ec 08 sub $0x8,%esp + return sys_fork(); + 8002e6: e8 20 ff ff ff call 80020b +} + 8002eb: 89 ec mov %ebp,%esp + 8002ed: 5d pop %ebp + 8002ee: c3 ret + +008002ef : + +int +wait(void) { + 8002ef: 55 push %ebp + 8002f0: 89 e5 mov %esp,%ebp + 8002f2: 83 ec 18 sub $0x18,%esp + return sys_wait(0, NULL); + 8002f5: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) + 8002fc: 00 + 8002fd: c7 04 24 00 00 00 00 movl $0x0,(%esp) + 800304: e8 18 ff ff ff call 800221 +} + 800309: 89 ec mov %ebp,%esp + 80030b: 5d pop %ebp + 80030c: c3 ret + +0080030d : + +int +waitpid(int pid, int *store) { + 80030d: 55 push %ebp + 80030e: 89 e5 mov %esp,%ebp + 800310: 83 ec 18 sub $0x18,%esp + return sys_wait(pid, store); + 800313: 8b 45 0c mov 0xc(%ebp),%eax + 800316: 89 44 24 04 mov %eax,0x4(%esp) + 80031a: 8b 45 08 mov 0x8(%ebp),%eax + 80031d: 89 04 24 mov %eax,(%esp) + 800320: e8 fc fe ff ff call 800221 +} + 800325: 89 ec mov %ebp,%esp + 800327: 5d pop %ebp + 800328: c3 ret + +00800329 : + +void +yield(void) { + 800329: 55 push %ebp + 80032a: 89 e5 mov %esp,%ebp + 80032c: 83 ec 08 sub $0x8,%esp + sys_yield(); + 80032f: e8 11 ff ff ff call 800245 +} + 800334: 90 nop + 800335: 89 ec mov %ebp,%esp + 800337: 5d pop %ebp + 800338: c3 ret + +00800339 : + +int +kill(int pid) { + 800339: 55 push %ebp + 80033a: 89 e5 mov %esp,%ebp + 80033c: 83 ec 18 sub $0x18,%esp + return sys_kill(pid); + 80033f: 8b 45 08 mov 0x8(%ebp),%eax + 800342: 89 04 24 mov %eax,(%esp) + 800345: e8 11 ff ff ff call 80025b +} + 80034a: 89 ec mov %ebp,%esp + 80034c: 5d pop %ebp + 80034d: c3 ret + +0080034e : + +int +getpid(void) { + 80034e: 55 push %ebp + 80034f: 89 e5 mov %esp,%ebp + 800351: 83 ec 08 sub $0x8,%esp + return sys_getpid(); + 800354: e8 1f ff ff ff call 800278 +} + 800359: 89 ec mov %ebp,%esp + 80035b: 5d pop %ebp + 80035c: c3 ret + +0080035d : + +//print_pgdir - print the PDT&PT +void +print_pgdir(void) { + 80035d: 55 push %ebp + 80035e: 89 e5 mov %esp,%ebp + 800360: 83 ec 08 sub $0x8,%esp + sys_pgdir(); + 800363: e8 43 ff ff ff call 8002ab +} + 800368: 90 nop + 800369: 89 ec mov %ebp,%esp + 80036b: 5d pop %ebp + 80036c: c3 ret + +0080036d : +#include + +int main(void); + +void +umain(void) { + 80036d: 55 push %ebp + 80036e: 89 e5 mov %esp,%ebp + 800370: 83 ec 28 sub $0x28,%esp + int ret = main(); + 800373: e8 37 0c 00 00 call 800faf
+ 800378: 89 45 f4 mov %eax,-0xc(%ebp) + exit(ret); + 80037b: 8b 45 f4 mov -0xc(%ebp),%eax + 80037e: 89 04 24 mov %eax,(%esp) + 800381: e8 3b ff ff ff call 8002c1 + +00800386 : + * @bits: the number of bits in a return value + * + * High bits are more random, so we use them. + * */ +uint32_t +hash32(uint32_t val, unsigned int bits) { + 800386: 55 push %ebp + 800387: 89 e5 mov %esp,%ebp + 800389: 83 ec 10 sub $0x10,%esp + uint32_t hash = val * GOLDEN_RATIO_PRIME_32; + 80038c: 8b 45 08 mov 0x8(%ebp),%eax + 80038f: 69 c0 01 00 37 9e imul $0x9e370001,%eax,%eax + 800395: 89 45 fc mov %eax,-0x4(%ebp) + return (hash >> (32 - bits)); + 800398: b8 20 00 00 00 mov $0x20,%eax + 80039d: 2b 45 0c sub 0xc(%ebp),%eax + 8003a0: 8b 55 fc mov -0x4(%ebp),%edx + 8003a3: 88 c1 mov %al,%cl + 8003a5: d3 ea shr %cl,%edx + 8003a7: 89 d0 mov %edx,%eax +} + 8003a9: 89 ec mov %ebp,%esp + 8003ab: 5d pop %ebp + 8003ac: c3 ret + +008003ad : + * @width: maximum number of digits, if the actual width is less than @width, use @padc instead + * @padc: character that padded on the left if the actual width is less than @width + * */ +static void +printnum(void (*putch)(int, void*), void *putdat, + unsigned long long num, unsigned base, int width, int padc) { + 8003ad: 55 push %ebp + 8003ae: 89 e5 mov %esp,%ebp + 8003b0: 83 ec 58 sub $0x58,%esp + 8003b3: 8b 45 10 mov 0x10(%ebp),%eax + 8003b6: 89 45 d0 mov %eax,-0x30(%ebp) + 8003b9: 8b 45 14 mov 0x14(%ebp),%eax + 8003bc: 89 45 d4 mov %eax,-0x2c(%ebp) + unsigned long long result = num; + 8003bf: 8b 45 d0 mov -0x30(%ebp),%eax + 8003c2: 8b 55 d4 mov -0x2c(%ebp),%edx + 8003c5: 89 45 e8 mov %eax,-0x18(%ebp) + 8003c8: 89 55 ec mov %edx,-0x14(%ebp) + unsigned mod = do_div(result, base); + 8003cb: 8b 45 18 mov 0x18(%ebp),%eax + 8003ce: 89 45 e4 mov %eax,-0x1c(%ebp) + 8003d1: 8b 45 e8 mov -0x18(%ebp),%eax + 8003d4: 8b 55 ec mov -0x14(%ebp),%edx + 8003d7: 89 45 e0 mov %eax,-0x20(%ebp) + 8003da: 89 55 f0 mov %edx,-0x10(%ebp) + 8003dd: 8b 45 f0 mov -0x10(%ebp),%eax + 8003e0: 89 45 f4 mov %eax,-0xc(%ebp) + 8003e3: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) + 8003e7: 74 1c je 800405 + 8003e9: 8b 45 f0 mov -0x10(%ebp),%eax + 8003ec: ba 00 00 00 00 mov $0x0,%edx + 8003f1: f7 75 e4 divl -0x1c(%ebp) + 8003f4: 89 55 f4 mov %edx,-0xc(%ebp) + 8003f7: 8b 45 f0 mov -0x10(%ebp),%eax + 8003fa: ba 00 00 00 00 mov $0x0,%edx + 8003ff: f7 75 e4 divl -0x1c(%ebp) + 800402: 89 45 f0 mov %eax,-0x10(%ebp) + 800405: 8b 45 e0 mov -0x20(%ebp),%eax + 800408: 8b 55 f4 mov -0xc(%ebp),%edx + 80040b: f7 75 e4 divl -0x1c(%ebp) + 80040e: 89 45 e0 mov %eax,-0x20(%ebp) + 800411: 89 55 dc mov %edx,-0x24(%ebp) + 800414: 8b 45 e0 mov -0x20(%ebp),%eax + 800417: 8b 55 f0 mov -0x10(%ebp),%edx + 80041a: 89 45 e8 mov %eax,-0x18(%ebp) + 80041d: 89 55 ec mov %edx,-0x14(%ebp) + 800420: 8b 45 dc mov -0x24(%ebp),%eax + 800423: 89 45 d8 mov %eax,-0x28(%ebp) + + // first recursively print all preceding (more significant) digits + if (num >= base) { + 800426: 8b 45 18 mov 0x18(%ebp),%eax + 800429: ba 00 00 00 00 mov $0x0,%edx + 80042e: 8b 4d d4 mov -0x2c(%ebp),%ecx + 800431: 39 45 d0 cmp %eax,-0x30(%ebp) + 800434: 19 d1 sbb %edx,%ecx + 800436: 72 4c jb 800484 + printnum(putch, putdat, result, base, width - 1, padc); + 800438: 8b 45 1c mov 0x1c(%ebp),%eax + 80043b: 8d 50 ff lea -0x1(%eax),%edx + 80043e: 8b 45 20 mov 0x20(%ebp),%eax + 800441: 89 44 24 18 mov %eax,0x18(%esp) + 800445: 89 54 24 14 mov %edx,0x14(%esp) + 800449: 8b 45 18 mov 0x18(%ebp),%eax + 80044c: 89 44 24 10 mov %eax,0x10(%esp) + 800450: 8b 45 e8 mov -0x18(%ebp),%eax + 800453: 8b 55 ec mov -0x14(%ebp),%edx + 800456: 89 44 24 08 mov %eax,0x8(%esp) + 80045a: 89 54 24 0c mov %edx,0xc(%esp) + 80045e: 8b 45 0c mov 0xc(%ebp),%eax + 800461: 89 44 24 04 mov %eax,0x4(%esp) + 800465: 8b 45 08 mov 0x8(%ebp),%eax + 800468: 89 04 24 mov %eax,(%esp) + 80046b: e8 3d ff ff ff call 8003ad + 800470: eb 1b jmp 80048d + } else { + // print any needed pad characters before first digit + while (-- width > 0) + putch(padc, putdat); + 800472: 8b 45 0c mov 0xc(%ebp),%eax + 800475: 89 44 24 04 mov %eax,0x4(%esp) + 800479: 8b 45 20 mov 0x20(%ebp),%eax + 80047c: 89 04 24 mov %eax,(%esp) + 80047f: 8b 45 08 mov 0x8(%ebp),%eax + 800482: ff d0 call *%eax + while (-- width > 0) + 800484: ff 4d 1c decl 0x1c(%ebp) + 800487: 83 7d 1c 00 cmpl $0x0,0x1c(%ebp) + 80048b: 7f e5 jg 800472 + } + // then print this (the least significant) digit + putch("0123456789abcdef"[mod], putdat); + 80048d: 8b 45 d8 mov -0x28(%ebp),%eax + 800490: 05 64 11 80 00 add $0x801164,%eax + 800495: 0f b6 00 movzbl (%eax),%eax + 800498: 0f be c0 movsbl %al,%eax + 80049b: 8b 55 0c mov 0xc(%ebp),%edx + 80049e: 89 54 24 04 mov %edx,0x4(%esp) + 8004a2: 89 04 24 mov %eax,(%esp) + 8004a5: 8b 45 08 mov 0x8(%ebp),%eax + 8004a8: ff d0 call *%eax +} + 8004aa: 90 nop + 8004ab: 89 ec mov %ebp,%esp + 8004ad: 5d pop %ebp + 8004ae: c3 ret + +008004af : + * getuint - get an unsigned int of various possible sizes from a varargs list + * @ap: a varargs list pointer + * @lflag: determines the size of the vararg that @ap points to + * */ +static unsigned long long +getuint(va_list *ap, int lflag) { + 8004af: 55 push %ebp + 8004b0: 89 e5 mov %esp,%ebp + if (lflag >= 2) { + 8004b2: 83 7d 0c 01 cmpl $0x1,0xc(%ebp) + 8004b6: 7e 14 jle 8004cc + return va_arg(*ap, unsigned long long); + 8004b8: 8b 45 08 mov 0x8(%ebp),%eax + 8004bb: 8b 00 mov (%eax),%eax + 8004bd: 8d 48 08 lea 0x8(%eax),%ecx + 8004c0: 8b 55 08 mov 0x8(%ebp),%edx + 8004c3: 89 0a mov %ecx,(%edx) + 8004c5: 8b 50 04 mov 0x4(%eax),%edx + 8004c8: 8b 00 mov (%eax),%eax + 8004ca: eb 30 jmp 8004fc + } + else if (lflag) { + 8004cc: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) + 8004d0: 74 16 je 8004e8 + return va_arg(*ap, unsigned long); + 8004d2: 8b 45 08 mov 0x8(%ebp),%eax + 8004d5: 8b 00 mov (%eax),%eax + 8004d7: 8d 48 04 lea 0x4(%eax),%ecx + 8004da: 8b 55 08 mov 0x8(%ebp),%edx + 8004dd: 89 0a mov %ecx,(%edx) + 8004df: 8b 00 mov (%eax),%eax + 8004e1: ba 00 00 00 00 mov $0x0,%edx + 8004e6: eb 14 jmp 8004fc + } + else { + return va_arg(*ap, unsigned int); + 8004e8: 8b 45 08 mov 0x8(%ebp),%eax + 8004eb: 8b 00 mov (%eax),%eax + 8004ed: 8d 48 04 lea 0x4(%eax),%ecx + 8004f0: 8b 55 08 mov 0x8(%ebp),%edx + 8004f3: 89 0a mov %ecx,(%edx) + 8004f5: 8b 00 mov (%eax),%eax + 8004f7: ba 00 00 00 00 mov $0x0,%edx + } +} + 8004fc: 5d pop %ebp + 8004fd: c3 ret + +008004fe : + * getint - same as getuint but signed, we can't use getuint because of sign extension + * @ap: a varargs list pointer + * @lflag: determines the size of the vararg that @ap points to + * */ +static long long +getint(va_list *ap, int lflag) { + 8004fe: 55 push %ebp + 8004ff: 89 e5 mov %esp,%ebp + if (lflag >= 2) { + 800501: 83 7d 0c 01 cmpl $0x1,0xc(%ebp) + 800505: 7e 14 jle 80051b + return va_arg(*ap, long long); + 800507: 8b 45 08 mov 0x8(%ebp),%eax + 80050a: 8b 00 mov (%eax),%eax + 80050c: 8d 48 08 lea 0x8(%eax),%ecx + 80050f: 8b 55 08 mov 0x8(%ebp),%edx + 800512: 89 0a mov %ecx,(%edx) + 800514: 8b 50 04 mov 0x4(%eax),%edx + 800517: 8b 00 mov (%eax),%eax + 800519: eb 28 jmp 800543 + } + else if (lflag) { + 80051b: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) + 80051f: 74 12 je 800533 + return va_arg(*ap, long); + 800521: 8b 45 08 mov 0x8(%ebp),%eax + 800524: 8b 00 mov (%eax),%eax + 800526: 8d 48 04 lea 0x4(%eax),%ecx + 800529: 8b 55 08 mov 0x8(%ebp),%edx + 80052c: 89 0a mov %ecx,(%edx) + 80052e: 8b 00 mov (%eax),%eax + 800530: 99 cltd + 800531: eb 10 jmp 800543 + } + else { + return va_arg(*ap, int); + 800533: 8b 45 08 mov 0x8(%ebp),%eax + 800536: 8b 00 mov (%eax),%eax + 800538: 8d 48 04 lea 0x4(%eax),%ecx + 80053b: 8b 55 08 mov 0x8(%ebp),%edx + 80053e: 89 0a mov %ecx,(%edx) + 800540: 8b 00 mov (%eax),%eax + 800542: 99 cltd + } +} + 800543: 5d pop %ebp + 800544: c3 ret + +00800545 : + * @putch: specified putch function, print a single character + * @putdat: used by @putch function + * @fmt: the format string to use + * */ +void +printfmt(void (*putch)(int, void*), void *putdat, const char *fmt, ...) { + 800545: 55 push %ebp + 800546: 89 e5 mov %esp,%ebp + 800548: 83 ec 28 sub $0x28,%esp + va_list ap; + + va_start(ap, fmt); + 80054b: 8d 45 14 lea 0x14(%ebp),%eax + 80054e: 89 45 f4 mov %eax,-0xc(%ebp) + vprintfmt(putch, putdat, fmt, ap); + 800551: 8b 45 f4 mov -0xc(%ebp),%eax + 800554: 89 44 24 0c mov %eax,0xc(%esp) + 800558: 8b 45 10 mov 0x10(%ebp),%eax + 80055b: 89 44 24 08 mov %eax,0x8(%esp) + 80055f: 8b 45 0c mov 0xc(%ebp),%eax + 800562: 89 44 24 04 mov %eax,0x4(%esp) + 800566: 8b 45 08 mov 0x8(%ebp),%eax + 800569: 89 04 24 mov %eax,(%esp) + 80056c: e8 05 00 00 00 call 800576 + va_end(ap); +} + 800571: 90 nop + 800572: 89 ec mov %ebp,%esp + 800574: 5d pop %ebp + 800575: c3 ret + +00800576 : + * + * Call this function if you are already dealing with a va_list. + * Or you probably want printfmt() instead. + * */ +void +vprintfmt(void (*putch)(int, void*), void *putdat, const char *fmt, va_list ap) { + 800576: 55 push %ebp + 800577: 89 e5 mov %esp,%ebp + 800579: 56 push %esi + 80057a: 53 push %ebx + 80057b: 83 ec 40 sub $0x40,%esp + register int ch, err; + unsigned long long num; + int base, width, precision, lflag, altflag; + + while (1) { + while ((ch = *(unsigned char *)fmt ++) != '%') { + 80057e: eb 17 jmp 800597 + if (ch == '\0') { + 800580: 85 db test %ebx,%ebx + 800582: 0f 84 bf 03 00 00 je 800947 + return; + } + putch(ch, putdat); + 800588: 8b 45 0c mov 0xc(%ebp),%eax + 80058b: 89 44 24 04 mov %eax,0x4(%esp) + 80058f: 89 1c 24 mov %ebx,(%esp) + 800592: 8b 45 08 mov 0x8(%ebp),%eax + 800595: ff d0 call *%eax + while ((ch = *(unsigned char *)fmt ++) != '%') { + 800597: 8b 45 10 mov 0x10(%ebp),%eax + 80059a: 8d 50 01 lea 0x1(%eax),%edx + 80059d: 89 55 10 mov %edx,0x10(%ebp) + 8005a0: 0f b6 00 movzbl (%eax),%eax + 8005a3: 0f b6 d8 movzbl %al,%ebx + 8005a6: 83 fb 25 cmp $0x25,%ebx + 8005a9: 75 d5 jne 800580 + } + + // Process a %-escape sequence + char padc = ' '; + 8005ab: c6 45 db 20 movb $0x20,-0x25(%ebp) + width = precision = -1; + 8005af: c7 45 e4 ff ff ff ff movl $0xffffffff,-0x1c(%ebp) + 8005b6: 8b 45 e4 mov -0x1c(%ebp),%eax + 8005b9: 89 45 e8 mov %eax,-0x18(%ebp) + lflag = altflag = 0; + 8005bc: c7 45 dc 00 00 00 00 movl $0x0,-0x24(%ebp) + 8005c3: 8b 45 dc mov -0x24(%ebp),%eax + 8005c6: 89 45 e0 mov %eax,-0x20(%ebp) + + reswitch: + switch (ch = *(unsigned char *)fmt ++) { + 8005c9: 8b 45 10 mov 0x10(%ebp),%eax + 8005cc: 8d 50 01 lea 0x1(%eax),%edx + 8005cf: 89 55 10 mov %edx,0x10(%ebp) + 8005d2: 0f b6 00 movzbl (%eax),%eax + 8005d5: 0f b6 d8 movzbl %al,%ebx + 8005d8: 8d 43 dd lea -0x23(%ebx),%eax + 8005db: 83 f8 55 cmp $0x55,%eax + 8005de: 0f 87 37 03 00 00 ja 80091b + 8005e4: 8b 04 85 88 11 80 00 mov 0x801188(,%eax,4),%eax + 8005eb: ff e0 jmp *%eax + + // flag to pad on the right + case '-': + padc = '-'; + 8005ed: c6 45 db 2d movb $0x2d,-0x25(%ebp) + goto reswitch; + 8005f1: eb d6 jmp 8005c9 + + // flag to pad with 0's instead of spaces + case '0': + padc = '0'; + 8005f3: c6 45 db 30 movb $0x30,-0x25(%ebp) + goto reswitch; + 8005f7: eb d0 jmp 8005c9 + + // width field + case '1' ... '9': + for (precision = 0; ; ++ fmt) { + 8005f9: c7 45 e4 00 00 00 00 movl $0x0,-0x1c(%ebp) + precision = precision * 10 + ch - '0'; + 800600: 8b 55 e4 mov -0x1c(%ebp),%edx + 800603: 89 d0 mov %edx,%eax + 800605: c1 e0 02 shl $0x2,%eax + 800608: 01 d0 add %edx,%eax + 80060a: 01 c0 add %eax,%eax + 80060c: 01 d8 add %ebx,%eax + 80060e: 83 e8 30 sub $0x30,%eax + 800611: 89 45 e4 mov %eax,-0x1c(%ebp) + ch = *fmt; + 800614: 8b 45 10 mov 0x10(%ebp),%eax + 800617: 0f b6 00 movzbl (%eax),%eax + 80061a: 0f be d8 movsbl %al,%ebx + if (ch < '0' || ch > '9') { + 80061d: 83 fb 2f cmp $0x2f,%ebx + 800620: 7e 38 jle 80065a + 800622: 83 fb 39 cmp $0x39,%ebx + 800625: 7f 33 jg 80065a + for (precision = 0; ; ++ fmt) { + 800627: ff 45 10 incl 0x10(%ebp) + precision = precision * 10 + ch - '0'; + 80062a: eb d4 jmp 800600 + } + } + goto process_precision; + + case '*': + precision = va_arg(ap, int); + 80062c: 8b 45 14 mov 0x14(%ebp),%eax + 80062f: 8d 50 04 lea 0x4(%eax),%edx + 800632: 89 55 14 mov %edx,0x14(%ebp) + 800635: 8b 00 mov (%eax),%eax + 800637: 89 45 e4 mov %eax,-0x1c(%ebp) + goto process_precision; + 80063a: eb 1f jmp 80065b + + case '.': + if (width < 0) + 80063c: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 800640: 79 87 jns 8005c9 + width = 0; + 800642: c7 45 e8 00 00 00 00 movl $0x0,-0x18(%ebp) + goto reswitch; + 800649: e9 7b ff ff ff jmp 8005c9 + + case '#': + altflag = 1; + 80064e: c7 45 dc 01 00 00 00 movl $0x1,-0x24(%ebp) + goto reswitch; + 800655: e9 6f ff ff ff jmp 8005c9 + goto process_precision; + 80065a: 90 nop + + process_precision: + if (width < 0) + 80065b: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 80065f: 0f 89 64 ff ff ff jns 8005c9 + width = precision, precision = -1; + 800665: 8b 45 e4 mov -0x1c(%ebp),%eax + 800668: 89 45 e8 mov %eax,-0x18(%ebp) + 80066b: c7 45 e4 ff ff ff ff movl $0xffffffff,-0x1c(%ebp) + goto reswitch; + 800672: e9 52 ff ff ff jmp 8005c9 + + // long flag (doubled for long long) + case 'l': + lflag ++; + 800677: ff 45 e0 incl -0x20(%ebp) + goto reswitch; + 80067a: e9 4a ff ff ff jmp 8005c9 + + // character + case 'c': + putch(va_arg(ap, int), putdat); + 80067f: 8b 45 14 mov 0x14(%ebp),%eax + 800682: 8d 50 04 lea 0x4(%eax),%edx + 800685: 89 55 14 mov %edx,0x14(%ebp) + 800688: 8b 00 mov (%eax),%eax + 80068a: 8b 55 0c mov 0xc(%ebp),%edx + 80068d: 89 54 24 04 mov %edx,0x4(%esp) + 800691: 89 04 24 mov %eax,(%esp) + 800694: 8b 45 08 mov 0x8(%ebp),%eax + 800697: ff d0 call *%eax + break; + 800699: e9 a4 02 00 00 jmp 800942 + + // error message + case 'e': + err = va_arg(ap, int); + 80069e: 8b 45 14 mov 0x14(%ebp),%eax + 8006a1: 8d 50 04 lea 0x4(%eax),%edx + 8006a4: 89 55 14 mov %edx,0x14(%ebp) + 8006a7: 8b 18 mov (%eax),%ebx + if (err < 0) { + 8006a9: 85 db test %ebx,%ebx + 8006ab: 79 02 jns 8006af + err = -err; + 8006ad: f7 db neg %ebx + } + if (err > MAXERROR || (p = error_string[err]) == NULL) { + 8006af: 83 fb 18 cmp $0x18,%ebx + 8006b2: 7f 0b jg 8006bf + 8006b4: 8b 34 9d 00 11 80 00 mov 0x801100(,%ebx,4),%esi + 8006bb: 85 f6 test %esi,%esi + 8006bd: 75 23 jne 8006e2 + printfmt(putch, putdat, "error %d", err); + 8006bf: 89 5c 24 0c mov %ebx,0xc(%esp) + 8006c3: c7 44 24 08 75 11 80 movl $0x801175,0x8(%esp) + 8006ca: 00 + 8006cb: 8b 45 0c mov 0xc(%ebp),%eax + 8006ce: 89 44 24 04 mov %eax,0x4(%esp) + 8006d2: 8b 45 08 mov 0x8(%ebp),%eax + 8006d5: 89 04 24 mov %eax,(%esp) + 8006d8: e8 68 fe ff ff call 800545 + } + else { + printfmt(putch, putdat, "%s", p); + } + break; + 8006dd: e9 60 02 00 00 jmp 800942 + printfmt(putch, putdat, "%s", p); + 8006e2: 89 74 24 0c mov %esi,0xc(%esp) + 8006e6: c7 44 24 08 7e 11 80 movl $0x80117e,0x8(%esp) + 8006ed: 00 + 8006ee: 8b 45 0c mov 0xc(%ebp),%eax + 8006f1: 89 44 24 04 mov %eax,0x4(%esp) + 8006f5: 8b 45 08 mov 0x8(%ebp),%eax + 8006f8: 89 04 24 mov %eax,(%esp) + 8006fb: e8 45 fe ff ff call 800545 + break; + 800700: e9 3d 02 00 00 jmp 800942 + + // string + case 's': + if ((p = va_arg(ap, char *)) == NULL) { + 800705: 8b 45 14 mov 0x14(%ebp),%eax + 800708: 8d 50 04 lea 0x4(%eax),%edx + 80070b: 89 55 14 mov %edx,0x14(%ebp) + 80070e: 8b 30 mov (%eax),%esi + 800710: 85 f6 test %esi,%esi + 800712: 75 05 jne 800719 + p = "(null)"; + 800714: be 81 11 80 00 mov $0x801181,%esi + } + if (width > 0 && padc != '-') { + 800719: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 80071d: 7e 76 jle 800795 + 80071f: 80 7d db 2d cmpb $0x2d,-0x25(%ebp) + 800723: 74 70 je 800795 + for (width -= strnlen(p, precision); width > 0; width --) { + 800725: 8b 45 e4 mov -0x1c(%ebp),%eax + 800728: 89 44 24 04 mov %eax,0x4(%esp) + 80072c: 89 34 24 mov %esi,(%esp) + 80072f: e8 ee 03 00 00 call 800b22 + 800734: 89 c2 mov %eax,%edx + 800736: 8b 45 e8 mov -0x18(%ebp),%eax + 800739: 29 d0 sub %edx,%eax + 80073b: 89 45 e8 mov %eax,-0x18(%ebp) + 80073e: eb 16 jmp 800756 + putch(padc, putdat); + 800740: 0f be 45 db movsbl -0x25(%ebp),%eax + 800744: 8b 55 0c mov 0xc(%ebp),%edx + 800747: 89 54 24 04 mov %edx,0x4(%esp) + 80074b: 89 04 24 mov %eax,(%esp) + 80074e: 8b 45 08 mov 0x8(%ebp),%eax + 800751: ff d0 call *%eax + for (width -= strnlen(p, precision); width > 0; width --) { + 800753: ff 4d e8 decl -0x18(%ebp) + 800756: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 80075a: 7f e4 jg 800740 + } + } + for (; (ch = *p ++) != '\0' && (precision < 0 || -- precision >= 0); width --) { + 80075c: eb 37 jmp 800795 + if (altflag && (ch < ' ' || ch > '~')) { + 80075e: 83 7d dc 00 cmpl $0x0,-0x24(%ebp) + 800762: 74 1f je 800783 + 800764: 83 fb 1f cmp $0x1f,%ebx + 800767: 7e 05 jle 80076e + 800769: 83 fb 7e cmp $0x7e,%ebx + 80076c: 7e 15 jle 800783 + putch('?', putdat); + 80076e: 8b 45 0c mov 0xc(%ebp),%eax + 800771: 89 44 24 04 mov %eax,0x4(%esp) + 800775: c7 04 24 3f 00 00 00 movl $0x3f,(%esp) + 80077c: 8b 45 08 mov 0x8(%ebp),%eax + 80077f: ff d0 call *%eax + 800781: eb 0f jmp 800792 + } + else { + putch(ch, putdat); + 800783: 8b 45 0c mov 0xc(%ebp),%eax + 800786: 89 44 24 04 mov %eax,0x4(%esp) + 80078a: 89 1c 24 mov %ebx,(%esp) + 80078d: 8b 45 08 mov 0x8(%ebp),%eax + 800790: ff d0 call *%eax + for (; (ch = *p ++) != '\0' && (precision < 0 || -- precision >= 0); width --) { + 800792: ff 4d e8 decl -0x18(%ebp) + 800795: 89 f0 mov %esi,%eax + 800797: 8d 70 01 lea 0x1(%eax),%esi + 80079a: 0f b6 00 movzbl (%eax),%eax + 80079d: 0f be d8 movsbl %al,%ebx + 8007a0: 85 db test %ebx,%ebx + 8007a2: 74 27 je 8007cb + 8007a4: 83 7d e4 00 cmpl $0x0,-0x1c(%ebp) + 8007a8: 78 b4 js 80075e + 8007aa: ff 4d e4 decl -0x1c(%ebp) + 8007ad: 83 7d e4 00 cmpl $0x0,-0x1c(%ebp) + 8007b1: 79 ab jns 80075e + } + } + for (; width > 0; width --) { + 8007b3: eb 16 jmp 8007cb + putch(' ', putdat); + 8007b5: 8b 45 0c mov 0xc(%ebp),%eax + 8007b8: 89 44 24 04 mov %eax,0x4(%esp) + 8007bc: c7 04 24 20 00 00 00 movl $0x20,(%esp) + 8007c3: 8b 45 08 mov 0x8(%ebp),%eax + 8007c6: ff d0 call *%eax + for (; width > 0; width --) { + 8007c8: ff 4d e8 decl -0x18(%ebp) + 8007cb: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 8007cf: 7f e4 jg 8007b5 + } + break; + 8007d1: e9 6c 01 00 00 jmp 800942 + + // (signed) decimal + case 'd': + num = getint(&ap, lflag); + 8007d6: 8b 45 e0 mov -0x20(%ebp),%eax + 8007d9: 89 44 24 04 mov %eax,0x4(%esp) + 8007dd: 8d 45 14 lea 0x14(%ebp),%eax + 8007e0: 89 04 24 mov %eax,(%esp) + 8007e3: e8 16 fd ff ff call 8004fe + 8007e8: 89 45 f0 mov %eax,-0x10(%ebp) + 8007eb: 89 55 f4 mov %edx,-0xc(%ebp) + if ((long long)num < 0) { + 8007ee: 8b 45 f0 mov -0x10(%ebp),%eax + 8007f1: 8b 55 f4 mov -0xc(%ebp),%edx + 8007f4: 85 d2 test %edx,%edx + 8007f6: 79 26 jns 80081e + putch('-', putdat); + 8007f8: 8b 45 0c mov 0xc(%ebp),%eax + 8007fb: 89 44 24 04 mov %eax,0x4(%esp) + 8007ff: c7 04 24 2d 00 00 00 movl $0x2d,(%esp) + 800806: 8b 45 08 mov 0x8(%ebp),%eax + 800809: ff d0 call *%eax + num = -(long long)num; + 80080b: 8b 45 f0 mov -0x10(%ebp),%eax + 80080e: 8b 55 f4 mov -0xc(%ebp),%edx + 800811: f7 d8 neg %eax + 800813: 83 d2 00 adc $0x0,%edx + 800816: f7 da neg %edx + 800818: 89 45 f0 mov %eax,-0x10(%ebp) + 80081b: 89 55 f4 mov %edx,-0xc(%ebp) + } + base = 10; + 80081e: c7 45 ec 0a 00 00 00 movl $0xa,-0x14(%ebp) + goto number; + 800825: e9 a8 00 00 00 jmp 8008d2 + + // unsigned decimal + case 'u': + num = getuint(&ap, lflag); + 80082a: 8b 45 e0 mov -0x20(%ebp),%eax + 80082d: 89 44 24 04 mov %eax,0x4(%esp) + 800831: 8d 45 14 lea 0x14(%ebp),%eax + 800834: 89 04 24 mov %eax,(%esp) + 800837: e8 73 fc ff ff call 8004af + 80083c: 89 45 f0 mov %eax,-0x10(%ebp) + 80083f: 89 55 f4 mov %edx,-0xc(%ebp) + base = 10; + 800842: c7 45 ec 0a 00 00 00 movl $0xa,-0x14(%ebp) + goto number; + 800849: e9 84 00 00 00 jmp 8008d2 + + // (unsigned) octal + case 'o': + num = getuint(&ap, lflag); + 80084e: 8b 45 e0 mov -0x20(%ebp),%eax + 800851: 89 44 24 04 mov %eax,0x4(%esp) + 800855: 8d 45 14 lea 0x14(%ebp),%eax + 800858: 89 04 24 mov %eax,(%esp) + 80085b: e8 4f fc ff ff call 8004af + 800860: 89 45 f0 mov %eax,-0x10(%ebp) + 800863: 89 55 f4 mov %edx,-0xc(%ebp) + base = 8; + 800866: c7 45 ec 08 00 00 00 movl $0x8,-0x14(%ebp) + goto number; + 80086d: eb 63 jmp 8008d2 + + // pointer + case 'p': + putch('0', putdat); + 80086f: 8b 45 0c mov 0xc(%ebp),%eax + 800872: 89 44 24 04 mov %eax,0x4(%esp) + 800876: c7 04 24 30 00 00 00 movl $0x30,(%esp) + 80087d: 8b 45 08 mov 0x8(%ebp),%eax + 800880: ff d0 call *%eax + putch('x', putdat); + 800882: 8b 45 0c mov 0xc(%ebp),%eax + 800885: 89 44 24 04 mov %eax,0x4(%esp) + 800889: c7 04 24 78 00 00 00 movl $0x78,(%esp) + 800890: 8b 45 08 mov 0x8(%ebp),%eax + 800893: ff d0 call *%eax + num = (unsigned long long)(uintptr_t)va_arg(ap, void *); + 800895: 8b 45 14 mov 0x14(%ebp),%eax + 800898: 8d 50 04 lea 0x4(%eax),%edx + 80089b: 89 55 14 mov %edx,0x14(%ebp) + 80089e: 8b 00 mov (%eax),%eax + 8008a0: 89 45 f0 mov %eax,-0x10(%ebp) + 8008a3: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + base = 16; + 8008aa: c7 45 ec 10 00 00 00 movl $0x10,-0x14(%ebp) + goto number; + 8008b1: eb 1f jmp 8008d2 + + // (unsigned) hexadecimal + case 'x': + num = getuint(&ap, lflag); + 8008b3: 8b 45 e0 mov -0x20(%ebp),%eax + 8008b6: 89 44 24 04 mov %eax,0x4(%esp) + 8008ba: 8d 45 14 lea 0x14(%ebp),%eax + 8008bd: 89 04 24 mov %eax,(%esp) + 8008c0: e8 ea fb ff ff call 8004af + 8008c5: 89 45 f0 mov %eax,-0x10(%ebp) + 8008c8: 89 55 f4 mov %edx,-0xc(%ebp) + base = 16; + 8008cb: c7 45 ec 10 00 00 00 movl $0x10,-0x14(%ebp) + number: + printnum(putch, putdat, num, base, width, padc); + 8008d2: 0f be 55 db movsbl -0x25(%ebp),%edx + 8008d6: 8b 45 ec mov -0x14(%ebp),%eax + 8008d9: 89 54 24 18 mov %edx,0x18(%esp) + 8008dd: 8b 55 e8 mov -0x18(%ebp),%edx + 8008e0: 89 54 24 14 mov %edx,0x14(%esp) + 8008e4: 89 44 24 10 mov %eax,0x10(%esp) + 8008e8: 8b 45 f0 mov -0x10(%ebp),%eax + 8008eb: 8b 55 f4 mov -0xc(%ebp),%edx + 8008ee: 89 44 24 08 mov %eax,0x8(%esp) + 8008f2: 89 54 24 0c mov %edx,0xc(%esp) + 8008f6: 8b 45 0c mov 0xc(%ebp),%eax + 8008f9: 89 44 24 04 mov %eax,0x4(%esp) + 8008fd: 8b 45 08 mov 0x8(%ebp),%eax + 800900: 89 04 24 mov %eax,(%esp) + 800903: e8 a5 fa ff ff call 8003ad + break; + 800908: eb 38 jmp 800942 + + // escaped '%' character + case '%': + putch(ch, putdat); + 80090a: 8b 45 0c mov 0xc(%ebp),%eax + 80090d: 89 44 24 04 mov %eax,0x4(%esp) + 800911: 89 1c 24 mov %ebx,(%esp) + 800914: 8b 45 08 mov 0x8(%ebp),%eax + 800917: ff d0 call *%eax + break; + 800919: eb 27 jmp 800942 + + // unrecognized escape sequence - just print it literally + default: + putch('%', putdat); + 80091b: 8b 45 0c mov 0xc(%ebp),%eax + 80091e: 89 44 24 04 mov %eax,0x4(%esp) + 800922: c7 04 24 25 00 00 00 movl $0x25,(%esp) + 800929: 8b 45 08 mov 0x8(%ebp),%eax + 80092c: ff d0 call *%eax + for (fmt --; fmt[-1] != '%'; fmt --) + 80092e: ff 4d 10 decl 0x10(%ebp) + 800931: eb 03 jmp 800936 + 800933: ff 4d 10 decl 0x10(%ebp) + 800936: 8b 45 10 mov 0x10(%ebp),%eax + 800939: 48 dec %eax + 80093a: 0f b6 00 movzbl (%eax),%eax + 80093d: 3c 25 cmp $0x25,%al + 80093f: 75 f2 jne 800933 + /* do nothing */; + break; + 800941: 90 nop + while (1) { + 800942: e9 37 fc ff ff jmp 80057e + return; + 800947: 90 nop + } + } +} + 800948: 83 c4 40 add $0x40,%esp + 80094b: 5b pop %ebx + 80094c: 5e pop %esi + 80094d: 5d pop %ebp + 80094e: c3 ret + +0080094f : + * sprintputch - 'print' a single character in a buffer + * @ch: the character will be printed + * @b: the buffer to place the character @ch + * */ +static void +sprintputch(int ch, struct sprintbuf *b) { + 80094f: 55 push %ebp + 800950: 89 e5 mov %esp,%ebp + b->cnt ++; + 800952: 8b 45 0c mov 0xc(%ebp),%eax + 800955: 8b 40 08 mov 0x8(%eax),%eax + 800958: 8d 50 01 lea 0x1(%eax),%edx + 80095b: 8b 45 0c mov 0xc(%ebp),%eax + 80095e: 89 50 08 mov %edx,0x8(%eax) + if (b->buf < b->ebuf) { + 800961: 8b 45 0c mov 0xc(%ebp),%eax + 800964: 8b 10 mov (%eax),%edx + 800966: 8b 45 0c mov 0xc(%ebp),%eax + 800969: 8b 40 04 mov 0x4(%eax),%eax + 80096c: 39 c2 cmp %eax,%edx + 80096e: 73 12 jae 800982 + *b->buf ++ = ch; + 800970: 8b 45 0c mov 0xc(%ebp),%eax + 800973: 8b 00 mov (%eax),%eax + 800975: 8d 48 01 lea 0x1(%eax),%ecx + 800978: 8b 55 0c mov 0xc(%ebp),%edx + 80097b: 89 0a mov %ecx,(%edx) + 80097d: 8b 55 08 mov 0x8(%ebp),%edx + 800980: 88 10 mov %dl,(%eax) + } +} + 800982: 90 nop + 800983: 5d pop %ebp + 800984: c3 ret + +00800985 : + * @str: the buffer to place the result into + * @size: the size of buffer, including the trailing null space + * @fmt: the format string to use + * */ +int +snprintf(char *str, size_t size, const char *fmt, ...) { + 800985: 55 push %ebp + 800986: 89 e5 mov %esp,%ebp + 800988: 83 ec 28 sub $0x28,%esp + va_list ap; + int cnt; + va_start(ap, fmt); + 80098b: 8d 45 14 lea 0x14(%ebp),%eax + 80098e: 89 45 f0 mov %eax,-0x10(%ebp) + cnt = vsnprintf(str, size, fmt, ap); + 800991: 8b 45 f0 mov -0x10(%ebp),%eax + 800994: 89 44 24 0c mov %eax,0xc(%esp) + 800998: 8b 45 10 mov 0x10(%ebp),%eax + 80099b: 89 44 24 08 mov %eax,0x8(%esp) + 80099f: 8b 45 0c mov 0xc(%ebp),%eax + 8009a2: 89 44 24 04 mov %eax,0x4(%esp) + 8009a6: 8b 45 08 mov 0x8(%ebp),%eax + 8009a9: 89 04 24 mov %eax,(%esp) + 8009ac: e8 0a 00 00 00 call 8009bb + 8009b1: 89 45 f4 mov %eax,-0xc(%ebp) + va_end(ap); + return cnt; + 8009b4: 8b 45 f4 mov -0xc(%ebp),%eax +} + 8009b7: 89 ec mov %ebp,%esp + 8009b9: 5d pop %ebp + 8009ba: c3 ret + +008009bb : + * + * Call this function if you are already dealing with a va_list. + * Or you probably want snprintf() instead. + * */ +int +vsnprintf(char *str, size_t size, const char *fmt, va_list ap) { + 8009bb: 55 push %ebp + 8009bc: 89 e5 mov %esp,%ebp + 8009be: 83 ec 28 sub $0x28,%esp + struct sprintbuf b = {str, str + size - 1, 0}; + 8009c1: 8b 45 08 mov 0x8(%ebp),%eax + 8009c4: 89 45 ec mov %eax,-0x14(%ebp) + 8009c7: 8b 45 0c mov 0xc(%ebp),%eax + 8009ca: 8d 50 ff lea -0x1(%eax),%edx + 8009cd: 8b 45 08 mov 0x8(%ebp),%eax + 8009d0: 01 d0 add %edx,%eax + 8009d2: 89 45 f0 mov %eax,-0x10(%ebp) + 8009d5: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + if (str == NULL || b.buf > b.ebuf) { + 8009dc: 83 7d 08 00 cmpl $0x0,0x8(%ebp) + 8009e0: 74 0a je 8009ec + 8009e2: 8b 55 ec mov -0x14(%ebp),%edx + 8009e5: 8b 45 f0 mov -0x10(%ebp),%eax + 8009e8: 39 c2 cmp %eax,%edx + 8009ea: 76 07 jbe 8009f3 + return -E_INVAL; + 8009ec: b8 fd ff ff ff mov $0xfffffffd,%eax + 8009f1: eb 2a jmp 800a1d + } + // print the string to the buffer + vprintfmt((void*)sprintputch, &b, fmt, ap); + 8009f3: 8b 45 14 mov 0x14(%ebp),%eax + 8009f6: 89 44 24 0c mov %eax,0xc(%esp) + 8009fa: 8b 45 10 mov 0x10(%ebp),%eax + 8009fd: 89 44 24 08 mov %eax,0x8(%esp) + 800a01: 8d 45 ec lea -0x14(%ebp),%eax + 800a04: 89 44 24 04 mov %eax,0x4(%esp) + 800a08: c7 04 24 4f 09 80 00 movl $0x80094f,(%esp) + 800a0f: e8 62 fb ff ff call 800576 + // null terminate the buffer + *b.buf = '\0'; + 800a14: 8b 45 ec mov -0x14(%ebp),%eax + 800a17: c6 00 00 movb $0x0,(%eax) + return b.cnt; + 800a1a: 8b 45 f4 mov -0xc(%ebp),%eax +} + 800a1d: 89 ec mov %ebp,%esp + 800a1f: 5d pop %ebp + 800a20: c3 ret + +00800a21 : + * rand - returns a pseudo-random integer + * + * The rand() function return a value in the range [0, RAND_MAX]. + * */ +int +rand(void) { + 800a21: 55 push %ebp + 800a22: 89 e5 mov %esp,%ebp + 800a24: 57 push %edi + 800a25: 56 push %esi + 800a26: 53 push %ebx + 800a27: 83 ec 24 sub $0x24,%esp + next = (next * 0x5DEECE66DLL + 0xBLL) & ((1LL << 48) - 1); + 800a2a: a1 00 20 80 00 mov 0x802000,%eax + 800a2f: 8b 15 04 20 80 00 mov 0x802004,%edx + 800a35: 69 fa 6d e6 ec de imul $0xdeece66d,%edx,%edi + 800a3b: 6b f0 05 imul $0x5,%eax,%esi + 800a3e: 01 fe add %edi,%esi + 800a40: bf 6d e6 ec de mov $0xdeece66d,%edi + 800a45: f7 e7 mul %edi + 800a47: 01 d6 add %edx,%esi + 800a49: 89 f2 mov %esi,%edx + 800a4b: 83 c0 0b add $0xb,%eax + 800a4e: 83 d2 00 adc $0x0,%edx + 800a51: 89 c7 mov %eax,%edi + 800a53: 83 e7 ff and $0xffffffff,%edi + 800a56: 89 f9 mov %edi,%ecx + 800a58: 0f b7 da movzwl %dx,%ebx + 800a5b: 89 0d 00 20 80 00 mov %ecx,0x802000 + 800a61: 89 1d 04 20 80 00 mov %ebx,0x802004 + unsigned long long result = (next >> 12); + 800a67: a1 00 20 80 00 mov 0x802000,%eax + 800a6c: 8b 15 04 20 80 00 mov 0x802004,%edx + 800a72: 0f ac d0 0c shrd $0xc,%edx,%eax + 800a76: c1 ea 0c shr $0xc,%edx + 800a79: 89 45 e0 mov %eax,-0x20(%ebp) + 800a7c: 89 55 e4 mov %edx,-0x1c(%ebp) + return (int)do_div(result, RAND_MAX + 1); + 800a7f: c7 45 dc 00 00 00 80 movl $0x80000000,-0x24(%ebp) + 800a86: 8b 45 e0 mov -0x20(%ebp),%eax + 800a89: 8b 55 e4 mov -0x1c(%ebp),%edx + 800a8c: 89 45 d8 mov %eax,-0x28(%ebp) + 800a8f: 89 55 e8 mov %edx,-0x18(%ebp) + 800a92: 8b 45 e8 mov -0x18(%ebp),%eax + 800a95: 89 45 ec mov %eax,-0x14(%ebp) + 800a98: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 800a9c: 74 1c je 800aba + 800a9e: 8b 45 e8 mov -0x18(%ebp),%eax + 800aa1: ba 00 00 00 00 mov $0x0,%edx + 800aa6: f7 75 dc divl -0x24(%ebp) + 800aa9: 89 55 ec mov %edx,-0x14(%ebp) + 800aac: 8b 45 e8 mov -0x18(%ebp),%eax + 800aaf: ba 00 00 00 00 mov $0x0,%edx + 800ab4: f7 75 dc divl -0x24(%ebp) + 800ab7: 89 45 e8 mov %eax,-0x18(%ebp) + 800aba: 8b 45 d8 mov -0x28(%ebp),%eax + 800abd: 8b 55 ec mov -0x14(%ebp),%edx + 800ac0: f7 75 dc divl -0x24(%ebp) + 800ac3: 89 45 d8 mov %eax,-0x28(%ebp) + 800ac6: 89 55 d4 mov %edx,-0x2c(%ebp) + 800ac9: 8b 45 d8 mov -0x28(%ebp),%eax + 800acc: 8b 55 e8 mov -0x18(%ebp),%edx + 800acf: 89 45 e0 mov %eax,-0x20(%ebp) + 800ad2: 89 55 e4 mov %edx,-0x1c(%ebp) + 800ad5: 8b 45 d4 mov -0x2c(%ebp),%eax +} + 800ad8: 83 c4 24 add $0x24,%esp + 800adb: 5b pop %ebx + 800adc: 5e pop %esi + 800add: 5f pop %edi + 800ade: 5d pop %ebp + 800adf: c3 ret + +00800ae0 : +/* * + * srand - seed the random number generator with the given number + * @seed: the required seed number + * */ +void +srand(unsigned int seed) { + 800ae0: 55 push %ebp + 800ae1: 89 e5 mov %esp,%ebp + next = seed; + 800ae3: 8b 45 08 mov 0x8(%ebp),%eax + 800ae6: ba 00 00 00 00 mov $0x0,%edx + 800aeb: a3 00 20 80 00 mov %eax,0x802000 + 800af0: 89 15 04 20 80 00 mov %edx,0x802004 +} + 800af6: 90 nop + 800af7: 5d pop %ebp + 800af8: c3 ret + +00800af9 : + * @s: the input string + * + * The strlen() function returns the length of string @s. + * */ +size_t +strlen(const char *s) { + 800af9: 55 push %ebp + 800afa: 89 e5 mov %esp,%ebp + 800afc: 83 ec 10 sub $0x10,%esp + size_t cnt = 0; + 800aff: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + while (*s ++ != '\0') { + 800b06: eb 03 jmp 800b0b + cnt ++; + 800b08: ff 45 fc incl -0x4(%ebp) + while (*s ++ != '\0') { + 800b0b: 8b 45 08 mov 0x8(%ebp),%eax + 800b0e: 8d 50 01 lea 0x1(%eax),%edx + 800b11: 89 55 08 mov %edx,0x8(%ebp) + 800b14: 0f b6 00 movzbl (%eax),%eax + 800b17: 84 c0 test %al,%al + 800b19: 75 ed jne 800b08 + } + return cnt; + 800b1b: 8b 45 fc mov -0x4(%ebp),%eax +} + 800b1e: 89 ec mov %ebp,%esp + 800b20: 5d pop %ebp + 800b21: c3 ret + +00800b22 : + * The return value is strlen(s), if that is less than @len, or + * @len if there is no '\0' character among the first @len characters + * pointed by @s. + * */ +size_t +strnlen(const char *s, size_t len) { + 800b22: 55 push %ebp + 800b23: 89 e5 mov %esp,%ebp + 800b25: 83 ec 10 sub $0x10,%esp + size_t cnt = 0; + 800b28: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + while (cnt < len && *s ++ != '\0') { + 800b2f: eb 03 jmp 800b34 + cnt ++; + 800b31: ff 45 fc incl -0x4(%ebp) + while (cnt < len && *s ++ != '\0') { + 800b34: 8b 45 fc mov -0x4(%ebp),%eax + 800b37: 3b 45 0c cmp 0xc(%ebp),%eax + 800b3a: 73 10 jae 800b4c + 800b3c: 8b 45 08 mov 0x8(%ebp),%eax + 800b3f: 8d 50 01 lea 0x1(%eax),%edx + 800b42: 89 55 08 mov %edx,0x8(%ebp) + 800b45: 0f b6 00 movzbl (%eax),%eax + 800b48: 84 c0 test %al,%al + 800b4a: 75 e5 jne 800b31 + } + return cnt; + 800b4c: 8b 45 fc mov -0x4(%ebp),%eax +} + 800b4f: 89 ec mov %ebp,%esp + 800b51: 5d pop %ebp + 800b52: c3 ret + +00800b53 : + * To avoid overflows, the size of array pointed by @dst should be long enough to + * contain the same string as @src (including the terminating null character), and + * should not overlap in memory with @src. + * */ +char * +strcpy(char *dst, const char *src) { + 800b53: 55 push %ebp + 800b54: 89 e5 mov %esp,%ebp + 800b56: 57 push %edi + 800b57: 56 push %esi + 800b58: 83 ec 20 sub $0x20,%esp + 800b5b: 8b 45 08 mov 0x8(%ebp),%eax + 800b5e: 89 45 f4 mov %eax,-0xc(%ebp) + 800b61: 8b 45 0c mov 0xc(%ebp),%eax + 800b64: 89 45 f0 mov %eax,-0x10(%ebp) +#ifndef __HAVE_ARCH_STRCPY +#define __HAVE_ARCH_STRCPY +static inline char * +__strcpy(char *dst, const char *src) { + int d0, d1, d2; + asm volatile ( + 800b67: 8b 55 f0 mov -0x10(%ebp),%edx + 800b6a: 8b 45 f4 mov -0xc(%ebp),%eax + 800b6d: 89 d1 mov %edx,%ecx + 800b6f: 89 c2 mov %eax,%edx + 800b71: 89 ce mov %ecx,%esi + 800b73: 89 d7 mov %edx,%edi + 800b75: ac lods %ds:(%esi),%al + 800b76: aa stos %al,%es:(%edi) + 800b77: 84 c0 test %al,%al + 800b79: 75 fa jne 800b75 + 800b7b: 89 fa mov %edi,%edx + 800b7d: 89 f1 mov %esi,%ecx + 800b7f: 89 4d ec mov %ecx,-0x14(%ebp) + 800b82: 89 55 e8 mov %edx,-0x18(%ebp) + 800b85: 89 45 e4 mov %eax,-0x1c(%ebp) + "stosb;" + "testb %%al, %%al;" + "jne 1b;" + : "=&S" (d0), "=&D" (d1), "=&a" (d2) + : "0" (src), "1" (dst) : "memory"); + return dst; + 800b88: 8b 45 f4 mov -0xc(%ebp),%eax + char *p = dst; + while ((*p ++ = *src ++) != '\0') + /* nothing */; + return dst; +#endif /* __HAVE_ARCH_STRCPY */ +} + 800b8b: 83 c4 20 add $0x20,%esp + 800b8e: 5e pop %esi + 800b8f: 5f pop %edi + 800b90: 5d pop %ebp + 800b91: c3 ret + +00800b92 : + * @len: maximum number of characters to be copied from @src + * + * The return value is @dst + * */ +char * +strncpy(char *dst, const char *src, size_t len) { + 800b92: 55 push %ebp + 800b93: 89 e5 mov %esp,%ebp + 800b95: 83 ec 10 sub $0x10,%esp + char *p = dst; + 800b98: 8b 45 08 mov 0x8(%ebp),%eax + 800b9b: 89 45 fc mov %eax,-0x4(%ebp) + while (len > 0) { + 800b9e: eb 1e jmp 800bbe + if ((*p = *src) != '\0') { + 800ba0: 8b 45 0c mov 0xc(%ebp),%eax + 800ba3: 0f b6 10 movzbl (%eax),%edx + 800ba6: 8b 45 fc mov -0x4(%ebp),%eax + 800ba9: 88 10 mov %dl,(%eax) + 800bab: 8b 45 fc mov -0x4(%ebp),%eax + 800bae: 0f b6 00 movzbl (%eax),%eax + 800bb1: 84 c0 test %al,%al + 800bb3: 74 03 je 800bb8 + src ++; + 800bb5: ff 45 0c incl 0xc(%ebp) + } + p ++, len --; + 800bb8: ff 45 fc incl -0x4(%ebp) + 800bbb: ff 4d 10 decl 0x10(%ebp) + while (len > 0) { + 800bbe: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800bc2: 75 dc jne 800ba0 + } + return dst; + 800bc4: 8b 45 08 mov 0x8(%ebp),%eax +} + 800bc7: 89 ec mov %ebp,%esp + 800bc9: 5d pop %ebp + 800bca: c3 ret + +00800bcb : + * - A value greater than zero indicates that the first character that does + * not match has a greater value in @s1 than in @s2; + * - And a value less than zero indicates the opposite. + * */ +int +strcmp(const char *s1, const char *s2) { + 800bcb: 55 push %ebp + 800bcc: 89 e5 mov %esp,%ebp + 800bce: 57 push %edi + 800bcf: 56 push %esi + 800bd0: 83 ec 20 sub $0x20,%esp + 800bd3: 8b 45 08 mov 0x8(%ebp),%eax + 800bd6: 89 45 f4 mov %eax,-0xc(%ebp) + 800bd9: 8b 45 0c mov 0xc(%ebp),%eax + 800bdc: 89 45 f0 mov %eax,-0x10(%ebp) + asm volatile ( + 800bdf: 8b 55 f4 mov -0xc(%ebp),%edx + 800be2: 8b 45 f0 mov -0x10(%ebp),%eax + 800be5: 89 d1 mov %edx,%ecx + 800be7: 89 c2 mov %eax,%edx + 800be9: 89 ce mov %ecx,%esi + 800beb: 89 d7 mov %edx,%edi + 800bed: ac lods %ds:(%esi),%al + 800bee: ae scas %es:(%edi),%al + 800bef: 75 08 jne 800bf9 + 800bf1: 84 c0 test %al,%al + 800bf3: 75 f8 jne 800bed + 800bf5: 31 c0 xor %eax,%eax + 800bf7: eb 04 jmp 800bfd + 800bf9: 19 c0 sbb %eax,%eax + 800bfb: 0c 01 or $0x1,%al + 800bfd: 89 fa mov %edi,%edx + 800bff: 89 f1 mov %esi,%ecx + 800c01: 89 45 ec mov %eax,-0x14(%ebp) + 800c04: 89 4d e8 mov %ecx,-0x18(%ebp) + 800c07: 89 55 e4 mov %edx,-0x1c(%ebp) + return ret; + 800c0a: 8b 45 ec mov -0x14(%ebp),%eax + while (*s1 != '\0' && *s1 == *s2) { + s1 ++, s2 ++; + } + return (int)((unsigned char)*s1 - (unsigned char)*s2); +#endif /* __HAVE_ARCH_STRCMP */ +} + 800c0d: 83 c4 20 add $0x20,%esp + 800c10: 5e pop %esi + 800c11: 5f pop %edi + 800c12: 5d pop %ebp + 800c13: c3 ret + +00800c14 : + * they are equal to each other, it continues with the following pairs until + * the characters differ, until a terminating null-character is reached, or + * until @n characters match in both strings, whichever happens first. + * */ +int +strncmp(const char *s1, const char *s2, size_t n) { + 800c14: 55 push %ebp + 800c15: 89 e5 mov %esp,%ebp + while (n > 0 && *s1 != '\0' && *s1 == *s2) { + 800c17: eb 09 jmp 800c22 + n --, s1 ++, s2 ++; + 800c19: ff 4d 10 decl 0x10(%ebp) + 800c1c: ff 45 08 incl 0x8(%ebp) + 800c1f: ff 45 0c incl 0xc(%ebp) + while (n > 0 && *s1 != '\0' && *s1 == *s2) { + 800c22: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800c26: 74 1a je 800c42 + 800c28: 8b 45 08 mov 0x8(%ebp),%eax + 800c2b: 0f b6 00 movzbl (%eax),%eax + 800c2e: 84 c0 test %al,%al + 800c30: 74 10 je 800c42 + 800c32: 8b 45 08 mov 0x8(%ebp),%eax + 800c35: 0f b6 10 movzbl (%eax),%edx + 800c38: 8b 45 0c mov 0xc(%ebp),%eax + 800c3b: 0f b6 00 movzbl (%eax),%eax + 800c3e: 38 c2 cmp %al,%dl + 800c40: 74 d7 je 800c19 + } + return (n == 0) ? 0 : (int)((unsigned char)*s1 - (unsigned char)*s2); + 800c42: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800c46: 74 18 je 800c60 + 800c48: 8b 45 08 mov 0x8(%ebp),%eax + 800c4b: 0f b6 00 movzbl (%eax),%eax + 800c4e: 0f b6 d0 movzbl %al,%edx + 800c51: 8b 45 0c mov 0xc(%ebp),%eax + 800c54: 0f b6 00 movzbl (%eax),%eax + 800c57: 0f b6 c8 movzbl %al,%ecx + 800c5a: 89 d0 mov %edx,%eax + 800c5c: 29 c8 sub %ecx,%eax + 800c5e: eb 05 jmp 800c65 + 800c60: b8 00 00 00 00 mov $0x0,%eax +} + 800c65: 5d pop %ebp + 800c66: c3 ret + +00800c67 : + * + * The strchr() function returns a pointer to the first occurrence of + * character in @s. If the value is not found, the function returns 'NULL'. + * */ +char * +strchr(const char *s, char c) { + 800c67: 55 push %ebp + 800c68: 89 e5 mov %esp,%ebp + 800c6a: 83 ec 04 sub $0x4,%esp + 800c6d: 8b 45 0c mov 0xc(%ebp),%eax + 800c70: 88 45 fc mov %al,-0x4(%ebp) + while (*s != '\0') { + 800c73: eb 13 jmp 800c88 + if (*s == c) { + 800c75: 8b 45 08 mov 0x8(%ebp),%eax + 800c78: 0f b6 00 movzbl (%eax),%eax + 800c7b: 38 45 fc cmp %al,-0x4(%ebp) + 800c7e: 75 05 jne 800c85 + return (char *)s; + 800c80: 8b 45 08 mov 0x8(%ebp),%eax + 800c83: eb 12 jmp 800c97 + } + s ++; + 800c85: ff 45 08 incl 0x8(%ebp) + while (*s != '\0') { + 800c88: 8b 45 08 mov 0x8(%ebp),%eax + 800c8b: 0f b6 00 movzbl (%eax),%eax + 800c8e: 84 c0 test %al,%al + 800c90: 75 e3 jne 800c75 + } + return NULL; + 800c92: b8 00 00 00 00 mov $0x0,%eax +} + 800c97: 89 ec mov %ebp,%esp + 800c99: 5d pop %ebp + 800c9a: c3 ret + +00800c9b : + * The strfind() function is like strchr() except that if @c is + * not found in @s, then it returns a pointer to the null byte at the + * end of @s, rather than 'NULL'. + * */ +char * +strfind(const char *s, char c) { + 800c9b: 55 push %ebp + 800c9c: 89 e5 mov %esp,%ebp + 800c9e: 83 ec 04 sub $0x4,%esp + 800ca1: 8b 45 0c mov 0xc(%ebp),%eax + 800ca4: 88 45 fc mov %al,-0x4(%ebp) + while (*s != '\0') { + 800ca7: eb 0e jmp 800cb7 + if (*s == c) { + 800ca9: 8b 45 08 mov 0x8(%ebp),%eax + 800cac: 0f b6 00 movzbl (%eax),%eax + 800caf: 38 45 fc cmp %al,-0x4(%ebp) + 800cb2: 74 0f je 800cc3 + break; + } + s ++; + 800cb4: ff 45 08 incl 0x8(%ebp) + while (*s != '\0') { + 800cb7: 8b 45 08 mov 0x8(%ebp),%eax + 800cba: 0f b6 00 movzbl (%eax),%eax + 800cbd: 84 c0 test %al,%al + 800cbf: 75 e8 jne 800ca9 + 800cc1: eb 01 jmp 800cc4 + break; + 800cc3: 90 nop + } + return (char *)s; + 800cc4: 8b 45 08 mov 0x8(%ebp),%eax +} + 800cc7: 89 ec mov %ebp,%esp + 800cc9: 5d pop %ebp + 800cca: c3 ret + +00800ccb : + * an optional "0x" or "0X" prefix. + * + * The strtol() function returns the converted integral number as a long int value. + * */ +long +strtol(const char *s, char **endptr, int base) { + 800ccb: 55 push %ebp + 800ccc: 89 e5 mov %esp,%ebp + 800cce: 83 ec 10 sub $0x10,%esp + int neg = 0; + 800cd1: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + long val = 0; + 800cd8: c7 45 f8 00 00 00 00 movl $0x0,-0x8(%ebp) + + // gobble initial whitespace + while (*s == ' ' || *s == '\t') { + 800cdf: eb 03 jmp 800ce4 + s ++; + 800ce1: ff 45 08 incl 0x8(%ebp) + while (*s == ' ' || *s == '\t') { + 800ce4: 8b 45 08 mov 0x8(%ebp),%eax + 800ce7: 0f b6 00 movzbl (%eax),%eax + 800cea: 3c 20 cmp $0x20,%al + 800cec: 74 f3 je 800ce1 + 800cee: 8b 45 08 mov 0x8(%ebp),%eax + 800cf1: 0f b6 00 movzbl (%eax),%eax + 800cf4: 3c 09 cmp $0x9,%al + 800cf6: 74 e9 je 800ce1 + } + + // plus/minus sign + if (*s == '+') { + 800cf8: 8b 45 08 mov 0x8(%ebp),%eax + 800cfb: 0f b6 00 movzbl (%eax),%eax + 800cfe: 3c 2b cmp $0x2b,%al + 800d00: 75 05 jne 800d07 + s ++; + 800d02: ff 45 08 incl 0x8(%ebp) + 800d05: eb 14 jmp 800d1b + } + else if (*s == '-') { + 800d07: 8b 45 08 mov 0x8(%ebp),%eax + 800d0a: 0f b6 00 movzbl (%eax),%eax + 800d0d: 3c 2d cmp $0x2d,%al + 800d0f: 75 0a jne 800d1b + s ++, neg = 1; + 800d11: ff 45 08 incl 0x8(%ebp) + 800d14: c7 45 fc 01 00 00 00 movl $0x1,-0x4(%ebp) + } + + // hex or octal base prefix + if ((base == 0 || base == 16) && (s[0] == '0' && s[1] == 'x')) { + 800d1b: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800d1f: 74 06 je 800d27 + 800d21: 83 7d 10 10 cmpl $0x10,0x10(%ebp) + 800d25: 75 22 jne 800d49 + 800d27: 8b 45 08 mov 0x8(%ebp),%eax + 800d2a: 0f b6 00 movzbl (%eax),%eax + 800d2d: 3c 30 cmp $0x30,%al + 800d2f: 75 18 jne 800d49 + 800d31: 8b 45 08 mov 0x8(%ebp),%eax + 800d34: 40 inc %eax + 800d35: 0f b6 00 movzbl (%eax),%eax + 800d38: 3c 78 cmp $0x78,%al + 800d3a: 75 0d jne 800d49 + s += 2, base = 16; + 800d3c: 83 45 08 02 addl $0x2,0x8(%ebp) + 800d40: c7 45 10 10 00 00 00 movl $0x10,0x10(%ebp) + 800d47: eb 29 jmp 800d72 + } + else if (base == 0 && s[0] == '0') { + 800d49: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800d4d: 75 16 jne 800d65 + 800d4f: 8b 45 08 mov 0x8(%ebp),%eax + 800d52: 0f b6 00 movzbl (%eax),%eax + 800d55: 3c 30 cmp $0x30,%al + 800d57: 75 0c jne 800d65 + s ++, base = 8; + 800d59: ff 45 08 incl 0x8(%ebp) + 800d5c: c7 45 10 08 00 00 00 movl $0x8,0x10(%ebp) + 800d63: eb 0d jmp 800d72 + } + else if (base == 0) { + 800d65: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800d69: 75 07 jne 800d72 + base = 10; + 800d6b: c7 45 10 0a 00 00 00 movl $0xa,0x10(%ebp) + + // digits + while (1) { + int dig; + + if (*s >= '0' && *s <= '9') { + 800d72: 8b 45 08 mov 0x8(%ebp),%eax + 800d75: 0f b6 00 movzbl (%eax),%eax + 800d78: 3c 2f cmp $0x2f,%al + 800d7a: 7e 1b jle 800d97 + 800d7c: 8b 45 08 mov 0x8(%ebp),%eax + 800d7f: 0f b6 00 movzbl (%eax),%eax + 800d82: 3c 39 cmp $0x39,%al + 800d84: 7f 11 jg 800d97 + dig = *s - '0'; + 800d86: 8b 45 08 mov 0x8(%ebp),%eax + 800d89: 0f b6 00 movzbl (%eax),%eax + 800d8c: 0f be c0 movsbl %al,%eax + 800d8f: 83 e8 30 sub $0x30,%eax + 800d92: 89 45 f4 mov %eax,-0xc(%ebp) + 800d95: eb 48 jmp 800ddf + } + else if (*s >= 'a' && *s <= 'z') { + 800d97: 8b 45 08 mov 0x8(%ebp),%eax + 800d9a: 0f b6 00 movzbl (%eax),%eax + 800d9d: 3c 60 cmp $0x60,%al + 800d9f: 7e 1b jle 800dbc + 800da1: 8b 45 08 mov 0x8(%ebp),%eax + 800da4: 0f b6 00 movzbl (%eax),%eax + 800da7: 3c 7a cmp $0x7a,%al + 800da9: 7f 11 jg 800dbc + dig = *s - 'a' + 10; + 800dab: 8b 45 08 mov 0x8(%ebp),%eax + 800dae: 0f b6 00 movzbl (%eax),%eax + 800db1: 0f be c0 movsbl %al,%eax + 800db4: 83 e8 57 sub $0x57,%eax + 800db7: 89 45 f4 mov %eax,-0xc(%ebp) + 800dba: eb 23 jmp 800ddf + } + else if (*s >= 'A' && *s <= 'Z') { + 800dbc: 8b 45 08 mov 0x8(%ebp),%eax + 800dbf: 0f b6 00 movzbl (%eax),%eax + 800dc2: 3c 40 cmp $0x40,%al + 800dc4: 7e 3b jle 800e01 + 800dc6: 8b 45 08 mov 0x8(%ebp),%eax + 800dc9: 0f b6 00 movzbl (%eax),%eax + 800dcc: 3c 5a cmp $0x5a,%al + 800dce: 7f 31 jg 800e01 + dig = *s - 'A' + 10; + 800dd0: 8b 45 08 mov 0x8(%ebp),%eax + 800dd3: 0f b6 00 movzbl (%eax),%eax + 800dd6: 0f be c0 movsbl %al,%eax + 800dd9: 83 e8 37 sub $0x37,%eax + 800ddc: 89 45 f4 mov %eax,-0xc(%ebp) + } + else { + break; + } + if (dig >= base) { + 800ddf: 8b 45 f4 mov -0xc(%ebp),%eax + 800de2: 3b 45 10 cmp 0x10(%ebp),%eax + 800de5: 7d 19 jge 800e00 + break; + } + s ++, val = (val * base) + dig; + 800de7: ff 45 08 incl 0x8(%ebp) + 800dea: 8b 45 f8 mov -0x8(%ebp),%eax + 800ded: 0f af 45 10 imul 0x10(%ebp),%eax + 800df1: 89 c2 mov %eax,%edx + 800df3: 8b 45 f4 mov -0xc(%ebp),%eax + 800df6: 01 d0 add %edx,%eax + 800df8: 89 45 f8 mov %eax,-0x8(%ebp) + while (1) { + 800dfb: e9 72 ff ff ff jmp 800d72 + break; + 800e00: 90 nop + // we don't properly detect overflow! + } + + if (endptr) { + 800e01: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) + 800e05: 74 08 je 800e0f + *endptr = (char *) s; + 800e07: 8b 45 0c mov 0xc(%ebp),%eax + 800e0a: 8b 55 08 mov 0x8(%ebp),%edx + 800e0d: 89 10 mov %edx,(%eax) + } + return (neg ? -val : val); + 800e0f: 83 7d fc 00 cmpl $0x0,-0x4(%ebp) + 800e13: 74 07 je 800e1c + 800e15: 8b 45 f8 mov -0x8(%ebp),%eax + 800e18: f7 d8 neg %eax + 800e1a: eb 03 jmp 800e1f + 800e1c: 8b 45 f8 mov -0x8(%ebp),%eax +} + 800e1f: 89 ec mov %ebp,%esp + 800e21: 5d pop %ebp + 800e22: c3 ret + +00800e23 : + * @n: number of bytes to be set to the value + * + * The memset() function returns @s. + * */ +void * +memset(void *s, char c, size_t n) { + 800e23: 55 push %ebp + 800e24: 89 e5 mov %esp,%ebp + 800e26: 83 ec 28 sub $0x28,%esp + 800e29: 89 7d fc mov %edi,-0x4(%ebp) + 800e2c: 8b 45 0c mov 0xc(%ebp),%eax + 800e2f: 88 45 d8 mov %al,-0x28(%ebp) +#ifdef __HAVE_ARCH_MEMSET + return __memset(s, c, n); + 800e32: 0f be 55 d8 movsbl -0x28(%ebp),%edx + 800e36: 8b 45 08 mov 0x8(%ebp),%eax + 800e39: 89 45 f8 mov %eax,-0x8(%ebp) + 800e3c: 88 55 f7 mov %dl,-0x9(%ebp) + 800e3f: 8b 45 10 mov 0x10(%ebp),%eax + 800e42: 89 45 f0 mov %eax,-0x10(%ebp) +#ifndef __HAVE_ARCH_MEMSET +#define __HAVE_ARCH_MEMSET +static inline void * +__memset(void *s, char c, size_t n) { + int d0, d1; + asm volatile ( + 800e45: 8b 4d f0 mov -0x10(%ebp),%ecx + 800e48: 0f b6 45 f7 movzbl -0x9(%ebp),%eax + 800e4c: 8b 55 f8 mov -0x8(%ebp),%edx + 800e4f: 89 d7 mov %edx,%edi + 800e51: f3 aa rep stos %al,%es:(%edi) + 800e53: 89 fa mov %edi,%edx + 800e55: 89 4d ec mov %ecx,-0x14(%ebp) + 800e58: 89 55 e8 mov %edx,-0x18(%ebp) + "rep; stosb;" + : "=&c" (d0), "=&D" (d1) + : "0" (n), "a" (c), "1" (s) + : "memory"); + return s; + 800e5b: 8b 45 f8 mov -0x8(%ebp),%eax + while (n -- > 0) { + *p ++ = c; + } + return s; +#endif /* __HAVE_ARCH_MEMSET */ +} + 800e5e: 8b 7d fc mov -0x4(%ebp),%edi + 800e61: 89 ec mov %ebp,%esp + 800e63: 5d pop %ebp + 800e64: c3 ret + +00800e65 : + * @n: number of bytes to copy + * + * The memmove() function returns @dst. + * */ +void * +memmove(void *dst, const void *src, size_t n) { + 800e65: 55 push %ebp + 800e66: 89 e5 mov %esp,%ebp + 800e68: 57 push %edi + 800e69: 56 push %esi + 800e6a: 53 push %ebx + 800e6b: 83 ec 30 sub $0x30,%esp + 800e6e: 8b 45 08 mov 0x8(%ebp),%eax + 800e71: 89 45 f0 mov %eax,-0x10(%ebp) + 800e74: 8b 45 0c mov 0xc(%ebp),%eax + 800e77: 89 45 ec mov %eax,-0x14(%ebp) + 800e7a: 8b 45 10 mov 0x10(%ebp),%eax + 800e7d: 89 45 e8 mov %eax,-0x18(%ebp) + +#ifndef __HAVE_ARCH_MEMMOVE +#define __HAVE_ARCH_MEMMOVE +static inline void * +__memmove(void *dst, const void *src, size_t n) { + if (dst < src) { + 800e80: 8b 45 f0 mov -0x10(%ebp),%eax + 800e83: 3b 45 ec cmp -0x14(%ebp),%eax + 800e86: 73 42 jae 800eca + 800e88: 8b 45 f0 mov -0x10(%ebp),%eax + 800e8b: 89 45 e4 mov %eax,-0x1c(%ebp) + 800e8e: 8b 45 ec mov -0x14(%ebp),%eax + 800e91: 89 45 e0 mov %eax,-0x20(%ebp) + 800e94: 8b 45 e8 mov -0x18(%ebp),%eax + 800e97: 89 45 dc mov %eax,-0x24(%ebp) + "andl $3, %%ecx;" + "jz 1f;" + "rep; movsb;" + "1:" + : "=&c" (d0), "=&D" (d1), "=&S" (d2) + : "0" (n / 4), "g" (n), "1" (dst), "2" (src) + 800e9a: 8b 45 dc mov -0x24(%ebp),%eax + 800e9d: c1 e8 02 shr $0x2,%eax + 800ea0: 89 c1 mov %eax,%ecx + asm volatile ( + 800ea2: 8b 55 e4 mov -0x1c(%ebp),%edx + 800ea5: 8b 45 e0 mov -0x20(%ebp),%eax + 800ea8: 89 d7 mov %edx,%edi + 800eaa: 89 c6 mov %eax,%esi + 800eac: f3 a5 rep movsl %ds:(%esi),%es:(%edi) + 800eae: 8b 4d dc mov -0x24(%ebp),%ecx + 800eb1: 83 e1 03 and $0x3,%ecx + 800eb4: 74 02 je 800eb8 + 800eb6: f3 a4 rep movsb %ds:(%esi),%es:(%edi) + 800eb8: 89 f0 mov %esi,%eax + 800eba: 89 fa mov %edi,%edx + 800ebc: 89 4d d8 mov %ecx,-0x28(%ebp) + 800ebf: 89 55 d4 mov %edx,-0x2c(%ebp) + 800ec2: 89 45 d0 mov %eax,-0x30(%ebp) + : "memory"); + return dst; + 800ec5: 8b 45 e4 mov -0x1c(%ebp),%eax + return __memcpy(dst, src, n); + 800ec8: eb 36 jmp 800f00 + : "0" (n), "1" (n - 1 + src), "2" (n - 1 + dst) + 800eca: 8b 45 e8 mov -0x18(%ebp),%eax + 800ecd: 8d 50 ff lea -0x1(%eax),%edx + 800ed0: 8b 45 ec mov -0x14(%ebp),%eax + 800ed3: 01 c2 add %eax,%edx + 800ed5: 8b 45 e8 mov -0x18(%ebp),%eax + 800ed8: 8d 48 ff lea -0x1(%eax),%ecx + 800edb: 8b 45 f0 mov -0x10(%ebp),%eax + 800ede: 8d 1c 01 lea (%ecx,%eax,1),%ebx + asm volatile ( + 800ee1: 8b 45 e8 mov -0x18(%ebp),%eax + 800ee4: 89 c1 mov %eax,%ecx + 800ee6: 89 d8 mov %ebx,%eax + 800ee8: 89 d6 mov %edx,%esi + 800eea: 89 c7 mov %eax,%edi + 800eec: fd std + 800eed: f3 a4 rep movsb %ds:(%esi),%es:(%edi) + 800eef: fc cld + 800ef0: 89 f8 mov %edi,%eax + 800ef2: 89 f2 mov %esi,%edx + 800ef4: 89 4d cc mov %ecx,-0x34(%ebp) + 800ef7: 89 55 c8 mov %edx,-0x38(%ebp) + 800efa: 89 45 c4 mov %eax,-0x3c(%ebp) + return dst; + 800efd: 8b 45 f0 mov -0x10(%ebp),%eax + *d ++ = *s ++; + } + } + return dst; +#endif /* __HAVE_ARCH_MEMMOVE */ +} + 800f00: 83 c4 30 add $0x30,%esp + 800f03: 5b pop %ebx + 800f04: 5e pop %esi + 800f05: 5f pop %edi + 800f06: 5d pop %ebp + 800f07: c3 ret + +00800f08 : + * it always copies exactly @n bytes. To avoid overflows, the size of arrays pointed + * by both @src and @dst, should be at least @n bytes, and should not overlap + * (for overlapping memory area, memmove is a safer approach). + * */ +void * +memcpy(void *dst, const void *src, size_t n) { + 800f08: 55 push %ebp + 800f09: 89 e5 mov %esp,%ebp + 800f0b: 57 push %edi + 800f0c: 56 push %esi + 800f0d: 83 ec 20 sub $0x20,%esp + 800f10: 8b 45 08 mov 0x8(%ebp),%eax + 800f13: 89 45 f4 mov %eax,-0xc(%ebp) + 800f16: 8b 45 0c mov 0xc(%ebp),%eax + 800f19: 89 45 f0 mov %eax,-0x10(%ebp) + 800f1c: 8b 45 10 mov 0x10(%ebp),%eax + 800f1f: 89 45 ec mov %eax,-0x14(%ebp) + : "0" (n / 4), "g" (n), "1" (dst), "2" (src) + 800f22: 8b 45 ec mov -0x14(%ebp),%eax + 800f25: c1 e8 02 shr $0x2,%eax + 800f28: 89 c1 mov %eax,%ecx + asm volatile ( + 800f2a: 8b 55 f4 mov -0xc(%ebp),%edx + 800f2d: 8b 45 f0 mov -0x10(%ebp),%eax + 800f30: 89 d7 mov %edx,%edi + 800f32: 89 c6 mov %eax,%esi + 800f34: f3 a5 rep movsl %ds:(%esi),%es:(%edi) + 800f36: 8b 4d ec mov -0x14(%ebp),%ecx + 800f39: 83 e1 03 and $0x3,%ecx + 800f3c: 74 02 je 800f40 + 800f3e: f3 a4 rep movsb %ds:(%esi),%es:(%edi) + 800f40: 89 f0 mov %esi,%eax + 800f42: 89 fa mov %edi,%edx + 800f44: 89 4d e8 mov %ecx,-0x18(%ebp) + 800f47: 89 55 e4 mov %edx,-0x1c(%ebp) + 800f4a: 89 45 e0 mov %eax,-0x20(%ebp) + return dst; + 800f4d: 8b 45 f4 mov -0xc(%ebp),%eax + while (n -- > 0) { + *d ++ = *s ++; + } + return dst; +#endif /* __HAVE_ARCH_MEMCPY */ +} + 800f50: 83 c4 20 add $0x20,%esp + 800f53: 5e pop %esi + 800f54: 5f pop %edi + 800f55: 5d pop %ebp + 800f56: c3 ret + +00800f57 : + * match in both memory blocks has a greater value in @v1 than in @v2 + * as if evaluated as unsigned char values; + * - And a value less than zero indicates the opposite. + * */ +int +memcmp(const void *v1, const void *v2, size_t n) { + 800f57: 55 push %ebp + 800f58: 89 e5 mov %esp,%ebp + 800f5a: 83 ec 10 sub $0x10,%esp + const char *s1 = (const char *)v1; + 800f5d: 8b 45 08 mov 0x8(%ebp),%eax + 800f60: 89 45 fc mov %eax,-0x4(%ebp) + const char *s2 = (const char *)v2; + 800f63: 8b 45 0c mov 0xc(%ebp),%eax + 800f66: 89 45 f8 mov %eax,-0x8(%ebp) + while (n -- > 0) { + 800f69: eb 2e jmp 800f99 + if (*s1 != *s2) { + 800f6b: 8b 45 fc mov -0x4(%ebp),%eax + 800f6e: 0f b6 10 movzbl (%eax),%edx + 800f71: 8b 45 f8 mov -0x8(%ebp),%eax + 800f74: 0f b6 00 movzbl (%eax),%eax + 800f77: 38 c2 cmp %al,%dl + 800f79: 74 18 je 800f93 + return (int)((unsigned char)*s1 - (unsigned char)*s2); + 800f7b: 8b 45 fc mov -0x4(%ebp),%eax + 800f7e: 0f b6 00 movzbl (%eax),%eax + 800f81: 0f b6 d0 movzbl %al,%edx + 800f84: 8b 45 f8 mov -0x8(%ebp),%eax + 800f87: 0f b6 00 movzbl (%eax),%eax + 800f8a: 0f b6 c8 movzbl %al,%ecx + 800f8d: 89 d0 mov %edx,%eax + 800f8f: 29 c8 sub %ecx,%eax + 800f91: eb 18 jmp 800fab + } + s1 ++, s2 ++; + 800f93: ff 45 fc incl -0x4(%ebp) + 800f96: ff 45 f8 incl -0x8(%ebp) + while (n -- > 0) { + 800f99: 8b 45 10 mov 0x10(%ebp),%eax + 800f9c: 8d 50 ff lea -0x1(%eax),%edx + 800f9f: 89 55 10 mov %edx,0x10(%ebp) + 800fa2: 85 c0 test %eax,%eax + 800fa4: 75 c5 jne 800f6b + } + return 0; + 800fa6: b8 00 00 00 00 mov $0x0,%eax +} + 800fab: 89 ec mov %ebp,%esp + 800fad: 5d pop %ebp + 800fae: c3 ret + +00800faf
: +#include +#include + +int +main(void) { + 800faf: 55 push %ebp + 800fb0: 89 e5 mov %esp,%ebp + 800fb2: 83 e4 f0 and $0xfffffff0,%esp + 800fb5: 83 ec 10 sub $0x10,%esp + cprintf("Hello world!!.\n"); + 800fb8: c7 04 24 e0 12 80 00 movl $0x8012e0,(%esp) + 800fbf: e8 5c f1 ff ff call 800120 + cprintf("I am process %d.\n", getpid()); + 800fc4: e8 85 f3 ff ff call 80034e + 800fc9: 89 44 24 04 mov %eax,0x4(%esp) + 800fcd: c7 04 24 f0 12 80 00 movl $0x8012f0,(%esp) + 800fd4: e8 47 f1 ff ff call 800120 + cprintf("hello pass.\n"); + 800fd9: c7 04 24 02 13 80 00 movl $0x801302,(%esp) + 800fe0: e8 3b f1 ff ff call 800120 + return 0; + 800fe5: b8 00 00 00 00 mov $0x0,%eax +} + 800fea: 89 ec mov %ebp,%esp + 800fec: 5d pop %ebp + 800fed: c3 ret diff --git a/labcodes/lab5/obj/user/hello.d b/labcodes/lab5/obj/user/hello.d new file mode 100644 index 0000000000000000000000000000000000000000..3fb0f6ae27c708f9750f7083ff3fed19ca30d2b4 --- /dev/null +++ b/labcodes/lab5/obj/user/hello.d @@ -0,0 +1,2 @@ +obj/user/hello.o obj/user/hello.d: user/hello.c libs/stdio.h libs/defs.h \ + libs/stdarg.h user/libs/ulib.h diff --git a/labcodes/lab5/obj/user/hello.o b/labcodes/lab5/obj/user/hello.o new file mode 100644 index 0000000000000000000000000000000000000000..699bb438c5ebde03b85bd0e4b19e27585fcd75f6 Binary files /dev/null and b/labcodes/lab5/obj/user/hello.o differ diff --git a/labcodes/lab5/obj/user/hello.sym b/labcodes/lab5/obj/user/hello.sym new file mode 100644 index 0000000000000000000000000000000000000000..66b839f539721367098da37fec8886ac692cbd4a --- /dev/null +++ b/labcodes/lab5/obj/user/hello.sym @@ -0,0 +1,66 @@ +00000000 panic.c +00000000 stdio.c +008000c8 cputch +00000000 syscall.c +00800199 syscall +00000000 ulib.c +00000000 umain.c +00000000 hash.c +00000000 printfmt.c +00801100 error_string +008003ad printnum +008004af getuint +008004fe getint +0080094f sprintputch +00000000 rand.c +00802000 next +00000000 string.c +00000000 hello.c +00800b53 strcpy +00800329 yield +0080030d waitpid +00800245 sys_yield +00800e65 memmove +00800985 snprintf +00800576 vprintfmt +0080020b sys_fork +00800120 cprintf +0080034e getpid +00800f08 memcpy +008009bb vsnprintf +0080036d umain +002026e0 __STAB_END__ +0080025b sys_kill +002026e1 __STABSTR_BEGIN__ +0080002f __panic +00800ccb strtol +00800b22 strnlen +0080035d print_pgdir +00800339 kill +00800c9b strfind +008002ef wait +00800020 _start +00800a21 rand +00800c14 strncmp +0080028e sys_putc +00800b92 strncpy +00800f57 memcmp +008002e0 fork +00800e23 memset +00800faf main +00800ae0 srand +00800386 hash32 +00800545 printfmt +002035ee __STABSTR_END__ +00800bcb strcmp +008000eb vcprintf +0080007f __warn +00800148 cputs +008002c1 exit +00800221 sys_wait +008001ee sys_exit +00200010 __STAB_BEGIN__ +00800af9 strlen +008002ab sys_pgdir +00800c67 strchr +00800278 sys_getpid diff --git a/labcodes/lab5/obj/user/libs/initcode.d b/labcodes/lab5/obj/user/libs/initcode.d new file mode 100644 index 0000000000000000000000000000000000000000..7e1af031d996ffd863802f672f9a843ec62df357 --- /dev/null +++ b/labcodes/lab5/obj/user/libs/initcode.d @@ -0,0 +1 @@ +obj/user/libs/initcode.o obj/user/libs/initcode.d: user/libs/initcode.S diff --git a/labcodes/lab5/obj/user/libs/initcode.o b/labcodes/lab5/obj/user/libs/initcode.o new file mode 100644 index 0000000000000000000000000000000000000000..84e5fc8c99572ba3f52855ea8fde4de9768431d8 Binary files /dev/null and b/labcodes/lab5/obj/user/libs/initcode.o differ diff --git a/labcodes/lab5/obj/user/libs/panic.d b/labcodes/lab5/obj/user/libs/panic.d new file mode 100644 index 0000000000000000000000000000000000000000..e64caf8e27c3e35068c529d6f3df4c935ef50c9a --- /dev/null +++ b/labcodes/lab5/obj/user/libs/panic.d @@ -0,0 +1,2 @@ +obj/user/libs/panic.o obj/user/libs/panic.d: user/libs/panic.c \ + libs/defs.h libs/stdarg.h libs/stdio.h user/libs/ulib.h libs/error.h diff --git a/labcodes/lab5/obj/user/libs/panic.o b/labcodes/lab5/obj/user/libs/panic.o new file mode 100644 index 0000000000000000000000000000000000000000..ae38bf996069e706dd3fae30ca4471fc4b13c2c8 Binary files /dev/null and b/labcodes/lab5/obj/user/libs/panic.o differ diff --git a/labcodes/lab5/obj/user/libs/stdio.d b/labcodes/lab5/obj/user/libs/stdio.d new file mode 100644 index 0000000000000000000000000000000000000000..66d43cc133b881314cb039030faccf4325ff6f8a --- /dev/null +++ b/labcodes/lab5/obj/user/libs/stdio.d @@ -0,0 +1,2 @@ +obj/user/libs/stdio.o obj/user/libs/stdio.d: user/libs/stdio.c \ + libs/defs.h libs/stdio.h libs/stdarg.h user/libs/syscall.h diff --git a/labcodes/lab5/obj/user/libs/stdio.o b/labcodes/lab5/obj/user/libs/stdio.o new file mode 100644 index 0000000000000000000000000000000000000000..592b0dc5ab53aee245cfb3e485c52d0132edc496 Binary files /dev/null and b/labcodes/lab5/obj/user/libs/stdio.o differ diff --git a/labcodes/lab5/obj/user/libs/syscall.d b/labcodes/lab5/obj/user/libs/syscall.d new file mode 100644 index 0000000000000000000000000000000000000000..205f032b3626bb07b96c90ab192ed3b44e2f665f --- /dev/null +++ b/labcodes/lab5/obj/user/libs/syscall.d @@ -0,0 +1,2 @@ +obj/user/libs/syscall.o obj/user/libs/syscall.d: user/libs/syscall.c \ + libs/defs.h libs/unistd.h libs/stdarg.h user/libs/syscall.h diff --git a/labcodes/lab5/obj/user/libs/syscall.o b/labcodes/lab5/obj/user/libs/syscall.o new file mode 100644 index 0000000000000000000000000000000000000000..03c1b6bb46b5d4107ba6fe6373ef7e31667e2b22 Binary files /dev/null and b/labcodes/lab5/obj/user/libs/syscall.o differ diff --git a/labcodes/lab5/obj/user/libs/ulib.d b/labcodes/lab5/obj/user/libs/ulib.d new file mode 100644 index 0000000000000000000000000000000000000000..6a57e5bf3406697743322aa8be3274f4d7ebfd05 --- /dev/null +++ b/labcodes/lab5/obj/user/libs/ulib.d @@ -0,0 +1,2 @@ +obj/user/libs/ulib.o obj/user/libs/ulib.d: user/libs/ulib.c libs/defs.h \ + user/libs/syscall.h libs/stdio.h libs/stdarg.h user/libs/ulib.h diff --git a/labcodes/lab5/obj/user/libs/ulib.o b/labcodes/lab5/obj/user/libs/ulib.o new file mode 100644 index 0000000000000000000000000000000000000000..5d9f973a31ddef76cb5b9b46514acd35f22b1dc3 Binary files /dev/null and b/labcodes/lab5/obj/user/libs/ulib.o differ diff --git a/labcodes/lab5/obj/user/libs/umain.d b/labcodes/lab5/obj/user/libs/umain.d new file mode 100644 index 0000000000000000000000000000000000000000..aad2151be213344cb82c61ccfd16f4d7f4cfb922 --- /dev/null +++ b/labcodes/lab5/obj/user/libs/umain.d @@ -0,0 +1,2 @@ +obj/user/libs/umain.o obj/user/libs/umain.d: user/libs/umain.c \ + user/libs/ulib.h libs/defs.h diff --git a/labcodes/lab5/obj/user/libs/umain.o b/labcodes/lab5/obj/user/libs/umain.o new file mode 100644 index 0000000000000000000000000000000000000000..33ded2a07810f0886b0e1788ff0b21a3835ea367 Binary files /dev/null and b/labcodes/lab5/obj/user/libs/umain.o differ diff --git a/labcodes/lab5/obj/user/pgdir.asm b/labcodes/lab5/obj/user/pgdir.asm new file mode 100644 index 0000000000000000000000000000000000000000..e71add813d308b97b9ae99433c725f88cb880e05 --- /dev/null +++ b/labcodes/lab5/obj/user/pgdir.asm @@ -0,0 +1,2326 @@ + +obj/__user_pgdir.out: file format elf32-i386 + + +Disassembly of section .text: + +00800020 <_start>: +.text +.globl _start +_start: + # set ebp for backtrace + movl $0x0, %ebp + 800020: bd 00 00 00 00 mov $0x0,%ebp + + # move down the esp register + # since it may cause page fault in backtrace + subl $0x20, %esp + 800025: 83 ec 20 sub $0x20,%esp + + # call user-program function + call umain + 800028: e8 40 03 00 00 call 80036d +1: jmp 1b + 80002d: eb fe jmp 80002d <_start+0xd> + +0080002f <__panic>: +#include +#include +#include + +void +__panic(const char *file, int line, const char *fmt, ...) { + 80002f: 55 push %ebp + 800030: 89 e5 mov %esp,%ebp + 800032: 83 ec 28 sub $0x28,%esp + // print the 'message' + va_list ap; + va_start(ap, fmt); + 800035: 8d 45 14 lea 0x14(%ebp),%eax + 800038: 89 45 f4 mov %eax,-0xc(%ebp) + cprintf("user panic at %s:%d:\n ", file, line); + 80003b: 8b 45 0c mov 0xc(%ebp),%eax + 80003e: 89 44 24 08 mov %eax,0x8(%esp) + 800042: 8b 45 08 mov 0x8(%ebp),%eax + 800045: 89 44 24 04 mov %eax,0x4(%esp) + 800049: c7 04 24 00 10 80 00 movl $0x801000,(%esp) + 800050: e8 cb 00 00 00 call 800120 + vcprintf(fmt, ap); + 800055: 8b 45 f4 mov -0xc(%ebp),%eax + 800058: 89 44 24 04 mov %eax,0x4(%esp) + 80005c: 8b 45 10 mov 0x10(%ebp),%eax + 80005f: 89 04 24 mov %eax,(%esp) + 800062: e8 84 00 00 00 call 8000eb + cprintf("\n"); + 800067: c7 04 24 1a 10 80 00 movl $0x80101a,(%esp) + 80006e: e8 ad 00 00 00 call 800120 + va_end(ap); + exit(-E_PANIC); + 800073: c7 04 24 f6 ff ff ff movl $0xfffffff6,(%esp) + 80007a: e8 42 02 00 00 call 8002c1 + +0080007f <__warn>: +} + +void +__warn(const char *file, int line, const char *fmt, ...) { + 80007f: 55 push %ebp + 800080: 89 e5 mov %esp,%ebp + 800082: 83 ec 28 sub $0x28,%esp + va_list ap; + va_start(ap, fmt); + 800085: 8d 45 14 lea 0x14(%ebp),%eax + 800088: 89 45 f4 mov %eax,-0xc(%ebp) + cprintf("user warning at %s:%d:\n ", file, line); + 80008b: 8b 45 0c mov 0xc(%ebp),%eax + 80008e: 89 44 24 08 mov %eax,0x8(%esp) + 800092: 8b 45 08 mov 0x8(%ebp),%eax + 800095: 89 44 24 04 mov %eax,0x4(%esp) + 800099: c7 04 24 1c 10 80 00 movl $0x80101c,(%esp) + 8000a0: e8 7b 00 00 00 call 800120 + vcprintf(fmt, ap); + 8000a5: 8b 45 f4 mov -0xc(%ebp),%eax + 8000a8: 89 44 24 04 mov %eax,0x4(%esp) + 8000ac: 8b 45 10 mov 0x10(%ebp),%eax + 8000af: 89 04 24 mov %eax,(%esp) + 8000b2: e8 34 00 00 00 call 8000eb + cprintf("\n"); + 8000b7: c7 04 24 1a 10 80 00 movl $0x80101a,(%esp) + 8000be: e8 5d 00 00 00 call 800120 + va_end(ap); +} + 8000c3: 90 nop + 8000c4: 89 ec mov %ebp,%esp + 8000c6: 5d pop %ebp + 8000c7: c3 ret + +008000c8 : +/* * + * cputch - writes a single character @c to stdout, and it will + * increace the value of counter pointed by @cnt. + * */ +static void +cputch(int c, int *cnt) { + 8000c8: 55 push %ebp + 8000c9: 89 e5 mov %esp,%ebp + 8000cb: 83 ec 18 sub $0x18,%esp + sys_putc(c); + 8000ce: 8b 45 08 mov 0x8(%ebp),%eax + 8000d1: 89 04 24 mov %eax,(%esp) + 8000d4: e8 b5 01 00 00 call 80028e + (*cnt) ++; + 8000d9: 8b 45 0c mov 0xc(%ebp),%eax + 8000dc: 8b 00 mov (%eax),%eax + 8000de: 8d 50 01 lea 0x1(%eax),%edx + 8000e1: 8b 45 0c mov 0xc(%ebp),%eax + 8000e4: 89 10 mov %edx,(%eax) +} + 8000e6: 90 nop + 8000e7: 89 ec mov %ebp,%esp + 8000e9: 5d pop %ebp + 8000ea: c3 ret + +008000eb : + * + * Call this function if you are already dealing with a va_list. + * Or you probably want cprintf() instead. + * */ +int +vcprintf(const char *fmt, va_list ap) { + 8000eb: 55 push %ebp + 8000ec: 89 e5 mov %esp,%ebp + 8000ee: 83 ec 28 sub $0x28,%esp + int cnt = 0; + 8000f1: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + vprintfmt((void*)cputch, &cnt, fmt, ap); + 8000f8: 8b 45 0c mov 0xc(%ebp),%eax + 8000fb: 89 44 24 0c mov %eax,0xc(%esp) + 8000ff: 8b 45 08 mov 0x8(%ebp),%eax + 800102: 89 44 24 08 mov %eax,0x8(%esp) + 800106: 8d 45 f4 lea -0xc(%ebp),%eax + 800109: 89 44 24 04 mov %eax,0x4(%esp) + 80010d: c7 04 24 c8 00 80 00 movl $0x8000c8,(%esp) + 800114: e8 5d 04 00 00 call 800576 + return cnt; + 800119: 8b 45 f4 mov -0xc(%ebp),%eax +} + 80011c: 89 ec mov %ebp,%esp + 80011e: 5d pop %ebp + 80011f: c3 ret + +00800120 : + * + * The return value is the number of characters which would be + * written to stdout. + * */ +int +cprintf(const char *fmt, ...) { + 800120: 55 push %ebp + 800121: 89 e5 mov %esp,%ebp + 800123: 83 ec 28 sub $0x28,%esp + va_list ap; + + va_start(ap, fmt); + 800126: 8d 45 0c lea 0xc(%ebp),%eax + 800129: 89 45 f0 mov %eax,-0x10(%ebp) + int cnt = vcprintf(fmt, ap); + 80012c: 8b 45 f0 mov -0x10(%ebp),%eax + 80012f: 89 44 24 04 mov %eax,0x4(%esp) + 800133: 8b 45 08 mov 0x8(%ebp),%eax + 800136: 89 04 24 mov %eax,(%esp) + 800139: e8 ad ff ff ff call 8000eb + 80013e: 89 45 f4 mov %eax,-0xc(%ebp) + va_end(ap); + + return cnt; + 800141: 8b 45 f4 mov -0xc(%ebp),%eax +} + 800144: 89 ec mov %ebp,%esp + 800146: 5d pop %ebp + 800147: c3 ret + +00800148 : +/* * + * cputs- writes the string pointed by @str to stdout and + * appends a newline character. + * */ +int +cputs(const char *str) { + 800148: 55 push %ebp + 800149: 89 e5 mov %esp,%ebp + 80014b: 83 ec 28 sub $0x28,%esp + int cnt = 0; + 80014e: c7 45 f0 00 00 00 00 movl $0x0,-0x10(%ebp) + char c; + while ((c = *str ++) != '\0') { + 800155: eb 13 jmp 80016a + cputch(c, &cnt); + 800157: 0f be 45 f7 movsbl -0x9(%ebp),%eax + 80015b: 8d 55 f0 lea -0x10(%ebp),%edx + 80015e: 89 54 24 04 mov %edx,0x4(%esp) + 800162: 89 04 24 mov %eax,(%esp) + 800165: e8 5e ff ff ff call 8000c8 + while ((c = *str ++) != '\0') { + 80016a: 8b 45 08 mov 0x8(%ebp),%eax + 80016d: 8d 50 01 lea 0x1(%eax),%edx + 800170: 89 55 08 mov %edx,0x8(%ebp) + 800173: 0f b6 00 movzbl (%eax),%eax + 800176: 88 45 f7 mov %al,-0x9(%ebp) + 800179: 80 7d f7 00 cmpb $0x0,-0x9(%ebp) + 80017d: 75 d8 jne 800157 + } + cputch('\n', &cnt); + 80017f: 8d 45 f0 lea -0x10(%ebp),%eax + 800182: 89 44 24 04 mov %eax,0x4(%esp) + 800186: c7 04 24 0a 00 00 00 movl $0xa,(%esp) + 80018d: e8 36 ff ff ff call 8000c8 + return cnt; + 800192: 8b 45 f0 mov -0x10(%ebp),%eax +} + 800195: 89 ec mov %ebp,%esp + 800197: 5d pop %ebp + 800198: c3 ret + +00800199 : +#include + +#define MAX_ARGS 5 + +static inline int +syscall(int num, ...) { + 800199: 55 push %ebp + 80019a: 89 e5 mov %esp,%ebp + 80019c: 57 push %edi + 80019d: 56 push %esi + 80019e: 53 push %ebx + 80019f: 83 ec 20 sub $0x20,%esp + va_list ap; + va_start(ap, num); + 8001a2: 8d 45 0c lea 0xc(%ebp),%eax + 8001a5: 89 45 e8 mov %eax,-0x18(%ebp) + uint32_t a[MAX_ARGS]; + int i, ret; + for (i = 0; i < MAX_ARGS; i ++) { + 8001a8: c7 45 f0 00 00 00 00 movl $0x0,-0x10(%ebp) + 8001af: eb 15 jmp 8001c6 + a[i] = va_arg(ap, uint32_t); + 8001b1: 8b 45 e8 mov -0x18(%ebp),%eax + 8001b4: 8d 50 04 lea 0x4(%eax),%edx + 8001b7: 89 55 e8 mov %edx,-0x18(%ebp) + 8001ba: 8b 10 mov (%eax),%edx + 8001bc: 8b 45 f0 mov -0x10(%ebp),%eax + 8001bf: 89 54 85 d4 mov %edx,-0x2c(%ebp,%eax,4) + for (i = 0; i < MAX_ARGS; i ++) { + 8001c3: ff 45 f0 incl -0x10(%ebp) + 8001c6: 83 7d f0 04 cmpl $0x4,-0x10(%ebp) + 8001ca: 7e e5 jle 8001b1 + asm volatile ( + "int %1;" + : "=a" (ret) + : "i" (T_SYSCALL), + "a" (num), + "d" (a[0]), + 8001cc: 8b 55 d4 mov -0x2c(%ebp),%edx + "c" (a[1]), + 8001cf: 8b 4d d8 mov -0x28(%ebp),%ecx + "b" (a[2]), + 8001d2: 8b 5d dc mov -0x24(%ebp),%ebx + "D" (a[3]), + 8001d5: 8b 7d e0 mov -0x20(%ebp),%edi + "S" (a[4]) + 8001d8: 8b 75 e4 mov -0x1c(%ebp),%esi + asm volatile ( + 8001db: 8b 45 08 mov 0x8(%ebp),%eax + 8001de: cd 80 int $0x80 + 8001e0: 89 45 ec mov %eax,-0x14(%ebp) + : "cc", "memory"); + return ret; + 8001e3: 8b 45 ec mov -0x14(%ebp),%eax +} + 8001e6: 83 c4 20 add $0x20,%esp + 8001e9: 5b pop %ebx + 8001ea: 5e pop %esi + 8001eb: 5f pop %edi + 8001ec: 5d pop %ebp + 8001ed: c3 ret + +008001ee : + +int +sys_exit(int error_code) { + 8001ee: 55 push %ebp + 8001ef: 89 e5 mov %esp,%ebp + 8001f1: 83 ec 08 sub $0x8,%esp + return syscall(SYS_exit, error_code); + 8001f4: 8b 45 08 mov 0x8(%ebp),%eax + 8001f7: 89 44 24 04 mov %eax,0x4(%esp) + 8001fb: c7 04 24 01 00 00 00 movl $0x1,(%esp) + 800202: e8 92 ff ff ff call 800199 +} + 800207: 89 ec mov %ebp,%esp + 800209: 5d pop %ebp + 80020a: c3 ret + +0080020b : + +int +sys_fork(void) { + 80020b: 55 push %ebp + 80020c: 89 e5 mov %esp,%ebp + 80020e: 83 ec 04 sub $0x4,%esp + return syscall(SYS_fork); + 800211: c7 04 24 02 00 00 00 movl $0x2,(%esp) + 800218: e8 7c ff ff ff call 800199 +} + 80021d: 89 ec mov %ebp,%esp + 80021f: 5d pop %ebp + 800220: c3 ret + +00800221 : + +int +sys_wait(int pid, int *store) { + 800221: 55 push %ebp + 800222: 89 e5 mov %esp,%ebp + 800224: 83 ec 0c sub $0xc,%esp + return syscall(SYS_wait, pid, store); + 800227: 8b 45 0c mov 0xc(%ebp),%eax + 80022a: 89 44 24 08 mov %eax,0x8(%esp) + 80022e: 8b 45 08 mov 0x8(%ebp),%eax + 800231: 89 44 24 04 mov %eax,0x4(%esp) + 800235: c7 04 24 03 00 00 00 movl $0x3,(%esp) + 80023c: e8 58 ff ff ff call 800199 +} + 800241: 89 ec mov %ebp,%esp + 800243: 5d pop %ebp + 800244: c3 ret + +00800245 : + +int +sys_yield(void) { + 800245: 55 push %ebp + 800246: 89 e5 mov %esp,%ebp + 800248: 83 ec 04 sub $0x4,%esp + return syscall(SYS_yield); + 80024b: c7 04 24 0a 00 00 00 movl $0xa,(%esp) + 800252: e8 42 ff ff ff call 800199 +} + 800257: 89 ec mov %ebp,%esp + 800259: 5d pop %ebp + 80025a: c3 ret + +0080025b : + +int +sys_kill(int pid) { + 80025b: 55 push %ebp + 80025c: 89 e5 mov %esp,%ebp + 80025e: 83 ec 08 sub $0x8,%esp + return syscall(SYS_kill, pid); + 800261: 8b 45 08 mov 0x8(%ebp),%eax + 800264: 89 44 24 04 mov %eax,0x4(%esp) + 800268: c7 04 24 0c 00 00 00 movl $0xc,(%esp) + 80026f: e8 25 ff ff ff call 800199 +} + 800274: 89 ec mov %ebp,%esp + 800276: 5d pop %ebp + 800277: c3 ret + +00800278 : + +int +sys_getpid(void) { + 800278: 55 push %ebp + 800279: 89 e5 mov %esp,%ebp + 80027b: 83 ec 04 sub $0x4,%esp + return syscall(SYS_getpid); + 80027e: c7 04 24 12 00 00 00 movl $0x12,(%esp) + 800285: e8 0f ff ff ff call 800199 +} + 80028a: 89 ec mov %ebp,%esp + 80028c: 5d pop %ebp + 80028d: c3 ret + +0080028e : + +int +sys_putc(int c) { + 80028e: 55 push %ebp + 80028f: 89 e5 mov %esp,%ebp + 800291: 83 ec 08 sub $0x8,%esp + return syscall(SYS_putc, c); + 800294: 8b 45 08 mov 0x8(%ebp),%eax + 800297: 89 44 24 04 mov %eax,0x4(%esp) + 80029b: c7 04 24 1e 00 00 00 movl $0x1e,(%esp) + 8002a2: e8 f2 fe ff ff call 800199 +} + 8002a7: 89 ec mov %ebp,%esp + 8002a9: 5d pop %ebp + 8002aa: c3 ret + +008002ab : + +int +sys_pgdir(void) { + 8002ab: 55 push %ebp + 8002ac: 89 e5 mov %esp,%ebp + 8002ae: 83 ec 04 sub $0x4,%esp + return syscall(SYS_pgdir); + 8002b1: c7 04 24 1f 00 00 00 movl $0x1f,(%esp) + 8002b8: e8 dc fe ff ff call 800199 +} + 8002bd: 89 ec mov %ebp,%esp + 8002bf: 5d pop %ebp + 8002c0: c3 ret + +008002c1 : +#include +#include +#include + +void +exit(int error_code) { + 8002c1: 55 push %ebp + 8002c2: 89 e5 mov %esp,%ebp + 8002c4: 83 ec 18 sub $0x18,%esp + sys_exit(error_code); + 8002c7: 8b 45 08 mov 0x8(%ebp),%eax + 8002ca: 89 04 24 mov %eax,(%esp) + 8002cd: e8 1c ff ff ff call 8001ee + cprintf("BUG: exit failed.\n"); + 8002d2: c7 04 24 38 10 80 00 movl $0x801038,(%esp) + 8002d9: e8 42 fe ff ff call 800120 + while (1); + 8002de: eb fe jmp 8002de + +008002e0 : +} + +int +fork(void) { + 8002e0: 55 push %ebp + 8002e1: 89 e5 mov %esp,%ebp + 8002e3: 83 ec 08 sub $0x8,%esp + return sys_fork(); + 8002e6: e8 20 ff ff ff call 80020b +} + 8002eb: 89 ec mov %ebp,%esp + 8002ed: 5d pop %ebp + 8002ee: c3 ret + +008002ef : + +int +wait(void) { + 8002ef: 55 push %ebp + 8002f0: 89 e5 mov %esp,%ebp + 8002f2: 83 ec 18 sub $0x18,%esp + return sys_wait(0, NULL); + 8002f5: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) + 8002fc: 00 + 8002fd: c7 04 24 00 00 00 00 movl $0x0,(%esp) + 800304: e8 18 ff ff ff call 800221 +} + 800309: 89 ec mov %ebp,%esp + 80030b: 5d pop %ebp + 80030c: c3 ret + +0080030d : + +int +waitpid(int pid, int *store) { + 80030d: 55 push %ebp + 80030e: 89 e5 mov %esp,%ebp + 800310: 83 ec 18 sub $0x18,%esp + return sys_wait(pid, store); + 800313: 8b 45 0c mov 0xc(%ebp),%eax + 800316: 89 44 24 04 mov %eax,0x4(%esp) + 80031a: 8b 45 08 mov 0x8(%ebp),%eax + 80031d: 89 04 24 mov %eax,(%esp) + 800320: e8 fc fe ff ff call 800221 +} + 800325: 89 ec mov %ebp,%esp + 800327: 5d pop %ebp + 800328: c3 ret + +00800329 : + +void +yield(void) { + 800329: 55 push %ebp + 80032a: 89 e5 mov %esp,%ebp + 80032c: 83 ec 08 sub $0x8,%esp + sys_yield(); + 80032f: e8 11 ff ff ff call 800245 +} + 800334: 90 nop + 800335: 89 ec mov %ebp,%esp + 800337: 5d pop %ebp + 800338: c3 ret + +00800339 : + +int +kill(int pid) { + 800339: 55 push %ebp + 80033a: 89 e5 mov %esp,%ebp + 80033c: 83 ec 18 sub $0x18,%esp + return sys_kill(pid); + 80033f: 8b 45 08 mov 0x8(%ebp),%eax + 800342: 89 04 24 mov %eax,(%esp) + 800345: e8 11 ff ff ff call 80025b +} + 80034a: 89 ec mov %ebp,%esp + 80034c: 5d pop %ebp + 80034d: c3 ret + +0080034e : + +int +getpid(void) { + 80034e: 55 push %ebp + 80034f: 89 e5 mov %esp,%ebp + 800351: 83 ec 08 sub $0x8,%esp + return sys_getpid(); + 800354: e8 1f ff ff ff call 800278 +} + 800359: 89 ec mov %ebp,%esp + 80035b: 5d pop %ebp + 80035c: c3 ret + +0080035d : + +//print_pgdir - print the PDT&PT +void +print_pgdir(void) { + 80035d: 55 push %ebp + 80035e: 89 e5 mov %esp,%ebp + 800360: 83 ec 08 sub $0x8,%esp + sys_pgdir(); + 800363: e8 43 ff ff ff call 8002ab +} + 800368: 90 nop + 800369: 89 ec mov %ebp,%esp + 80036b: 5d pop %ebp + 80036c: c3 ret + +0080036d : +#include + +int main(void); + +void +umain(void) { + 80036d: 55 push %ebp + 80036e: 89 e5 mov %esp,%ebp + 800370: 83 ec 28 sub $0x28,%esp + int ret = main(); + 800373: e8 37 0c 00 00 call 800faf
+ 800378: 89 45 f4 mov %eax,-0xc(%ebp) + exit(ret); + 80037b: 8b 45 f4 mov -0xc(%ebp),%eax + 80037e: 89 04 24 mov %eax,(%esp) + 800381: e8 3b ff ff ff call 8002c1 + +00800386 : + * @bits: the number of bits in a return value + * + * High bits are more random, so we use them. + * */ +uint32_t +hash32(uint32_t val, unsigned int bits) { + 800386: 55 push %ebp + 800387: 89 e5 mov %esp,%ebp + 800389: 83 ec 10 sub $0x10,%esp + uint32_t hash = val * GOLDEN_RATIO_PRIME_32; + 80038c: 8b 45 08 mov 0x8(%ebp),%eax + 80038f: 69 c0 01 00 37 9e imul $0x9e370001,%eax,%eax + 800395: 89 45 fc mov %eax,-0x4(%ebp) + return (hash >> (32 - bits)); + 800398: b8 20 00 00 00 mov $0x20,%eax + 80039d: 2b 45 0c sub 0xc(%ebp),%eax + 8003a0: 8b 55 fc mov -0x4(%ebp),%edx + 8003a3: 88 c1 mov %al,%cl + 8003a5: d3 ea shr %cl,%edx + 8003a7: 89 d0 mov %edx,%eax +} + 8003a9: 89 ec mov %ebp,%esp + 8003ab: 5d pop %ebp + 8003ac: c3 ret + +008003ad : + * @width: maximum number of digits, if the actual width is less than @width, use @padc instead + * @padc: character that padded on the left if the actual width is less than @width + * */ +static void +printnum(void (*putch)(int, void*), void *putdat, + unsigned long long num, unsigned base, int width, int padc) { + 8003ad: 55 push %ebp + 8003ae: 89 e5 mov %esp,%ebp + 8003b0: 83 ec 58 sub $0x58,%esp + 8003b3: 8b 45 10 mov 0x10(%ebp),%eax + 8003b6: 89 45 d0 mov %eax,-0x30(%ebp) + 8003b9: 8b 45 14 mov 0x14(%ebp),%eax + 8003bc: 89 45 d4 mov %eax,-0x2c(%ebp) + unsigned long long result = num; + 8003bf: 8b 45 d0 mov -0x30(%ebp),%eax + 8003c2: 8b 55 d4 mov -0x2c(%ebp),%edx + 8003c5: 89 45 e8 mov %eax,-0x18(%ebp) + 8003c8: 89 55 ec mov %edx,-0x14(%ebp) + unsigned mod = do_div(result, base); + 8003cb: 8b 45 18 mov 0x18(%ebp),%eax + 8003ce: 89 45 e4 mov %eax,-0x1c(%ebp) + 8003d1: 8b 45 e8 mov -0x18(%ebp),%eax + 8003d4: 8b 55 ec mov -0x14(%ebp),%edx + 8003d7: 89 45 e0 mov %eax,-0x20(%ebp) + 8003da: 89 55 f0 mov %edx,-0x10(%ebp) + 8003dd: 8b 45 f0 mov -0x10(%ebp),%eax + 8003e0: 89 45 f4 mov %eax,-0xc(%ebp) + 8003e3: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) + 8003e7: 74 1c je 800405 + 8003e9: 8b 45 f0 mov -0x10(%ebp),%eax + 8003ec: ba 00 00 00 00 mov $0x0,%edx + 8003f1: f7 75 e4 divl -0x1c(%ebp) + 8003f4: 89 55 f4 mov %edx,-0xc(%ebp) + 8003f7: 8b 45 f0 mov -0x10(%ebp),%eax + 8003fa: ba 00 00 00 00 mov $0x0,%edx + 8003ff: f7 75 e4 divl -0x1c(%ebp) + 800402: 89 45 f0 mov %eax,-0x10(%ebp) + 800405: 8b 45 e0 mov -0x20(%ebp),%eax + 800408: 8b 55 f4 mov -0xc(%ebp),%edx + 80040b: f7 75 e4 divl -0x1c(%ebp) + 80040e: 89 45 e0 mov %eax,-0x20(%ebp) + 800411: 89 55 dc mov %edx,-0x24(%ebp) + 800414: 8b 45 e0 mov -0x20(%ebp),%eax + 800417: 8b 55 f0 mov -0x10(%ebp),%edx + 80041a: 89 45 e8 mov %eax,-0x18(%ebp) + 80041d: 89 55 ec mov %edx,-0x14(%ebp) + 800420: 8b 45 dc mov -0x24(%ebp),%eax + 800423: 89 45 d8 mov %eax,-0x28(%ebp) + + // first recursively print all preceding (more significant) digits + if (num >= base) { + 800426: 8b 45 18 mov 0x18(%ebp),%eax + 800429: ba 00 00 00 00 mov $0x0,%edx + 80042e: 8b 4d d4 mov -0x2c(%ebp),%ecx + 800431: 39 45 d0 cmp %eax,-0x30(%ebp) + 800434: 19 d1 sbb %edx,%ecx + 800436: 72 4c jb 800484 + printnum(putch, putdat, result, base, width - 1, padc); + 800438: 8b 45 1c mov 0x1c(%ebp),%eax + 80043b: 8d 50 ff lea -0x1(%eax),%edx + 80043e: 8b 45 20 mov 0x20(%ebp),%eax + 800441: 89 44 24 18 mov %eax,0x18(%esp) + 800445: 89 54 24 14 mov %edx,0x14(%esp) + 800449: 8b 45 18 mov 0x18(%ebp),%eax + 80044c: 89 44 24 10 mov %eax,0x10(%esp) + 800450: 8b 45 e8 mov -0x18(%ebp),%eax + 800453: 8b 55 ec mov -0x14(%ebp),%edx + 800456: 89 44 24 08 mov %eax,0x8(%esp) + 80045a: 89 54 24 0c mov %edx,0xc(%esp) + 80045e: 8b 45 0c mov 0xc(%ebp),%eax + 800461: 89 44 24 04 mov %eax,0x4(%esp) + 800465: 8b 45 08 mov 0x8(%ebp),%eax + 800468: 89 04 24 mov %eax,(%esp) + 80046b: e8 3d ff ff ff call 8003ad + 800470: eb 1b jmp 80048d + } else { + // print any needed pad characters before first digit + while (-- width > 0) + putch(padc, putdat); + 800472: 8b 45 0c mov 0xc(%ebp),%eax + 800475: 89 44 24 04 mov %eax,0x4(%esp) + 800479: 8b 45 20 mov 0x20(%ebp),%eax + 80047c: 89 04 24 mov %eax,(%esp) + 80047f: 8b 45 08 mov 0x8(%ebp),%eax + 800482: ff d0 call *%eax + while (-- width > 0) + 800484: ff 4d 1c decl 0x1c(%ebp) + 800487: 83 7d 1c 00 cmpl $0x0,0x1c(%ebp) + 80048b: 7f e5 jg 800472 + } + // then print this (the least significant) digit + putch("0123456789abcdef"[mod], putdat); + 80048d: 8b 45 d8 mov -0x28(%ebp),%eax + 800490: 05 64 11 80 00 add $0x801164,%eax + 800495: 0f b6 00 movzbl (%eax),%eax + 800498: 0f be c0 movsbl %al,%eax + 80049b: 8b 55 0c mov 0xc(%ebp),%edx + 80049e: 89 54 24 04 mov %edx,0x4(%esp) + 8004a2: 89 04 24 mov %eax,(%esp) + 8004a5: 8b 45 08 mov 0x8(%ebp),%eax + 8004a8: ff d0 call *%eax +} + 8004aa: 90 nop + 8004ab: 89 ec mov %ebp,%esp + 8004ad: 5d pop %ebp + 8004ae: c3 ret + +008004af : + * getuint - get an unsigned int of various possible sizes from a varargs list + * @ap: a varargs list pointer + * @lflag: determines the size of the vararg that @ap points to + * */ +static unsigned long long +getuint(va_list *ap, int lflag) { + 8004af: 55 push %ebp + 8004b0: 89 e5 mov %esp,%ebp + if (lflag >= 2) { + 8004b2: 83 7d 0c 01 cmpl $0x1,0xc(%ebp) + 8004b6: 7e 14 jle 8004cc + return va_arg(*ap, unsigned long long); + 8004b8: 8b 45 08 mov 0x8(%ebp),%eax + 8004bb: 8b 00 mov (%eax),%eax + 8004bd: 8d 48 08 lea 0x8(%eax),%ecx + 8004c0: 8b 55 08 mov 0x8(%ebp),%edx + 8004c3: 89 0a mov %ecx,(%edx) + 8004c5: 8b 50 04 mov 0x4(%eax),%edx + 8004c8: 8b 00 mov (%eax),%eax + 8004ca: eb 30 jmp 8004fc + } + else if (lflag) { + 8004cc: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) + 8004d0: 74 16 je 8004e8 + return va_arg(*ap, unsigned long); + 8004d2: 8b 45 08 mov 0x8(%ebp),%eax + 8004d5: 8b 00 mov (%eax),%eax + 8004d7: 8d 48 04 lea 0x4(%eax),%ecx + 8004da: 8b 55 08 mov 0x8(%ebp),%edx + 8004dd: 89 0a mov %ecx,(%edx) + 8004df: 8b 00 mov (%eax),%eax + 8004e1: ba 00 00 00 00 mov $0x0,%edx + 8004e6: eb 14 jmp 8004fc + } + else { + return va_arg(*ap, unsigned int); + 8004e8: 8b 45 08 mov 0x8(%ebp),%eax + 8004eb: 8b 00 mov (%eax),%eax + 8004ed: 8d 48 04 lea 0x4(%eax),%ecx + 8004f0: 8b 55 08 mov 0x8(%ebp),%edx + 8004f3: 89 0a mov %ecx,(%edx) + 8004f5: 8b 00 mov (%eax),%eax + 8004f7: ba 00 00 00 00 mov $0x0,%edx + } +} + 8004fc: 5d pop %ebp + 8004fd: c3 ret + +008004fe : + * getint - same as getuint but signed, we can't use getuint because of sign extension + * @ap: a varargs list pointer + * @lflag: determines the size of the vararg that @ap points to + * */ +static long long +getint(va_list *ap, int lflag) { + 8004fe: 55 push %ebp + 8004ff: 89 e5 mov %esp,%ebp + if (lflag >= 2) { + 800501: 83 7d 0c 01 cmpl $0x1,0xc(%ebp) + 800505: 7e 14 jle 80051b + return va_arg(*ap, long long); + 800507: 8b 45 08 mov 0x8(%ebp),%eax + 80050a: 8b 00 mov (%eax),%eax + 80050c: 8d 48 08 lea 0x8(%eax),%ecx + 80050f: 8b 55 08 mov 0x8(%ebp),%edx + 800512: 89 0a mov %ecx,(%edx) + 800514: 8b 50 04 mov 0x4(%eax),%edx + 800517: 8b 00 mov (%eax),%eax + 800519: eb 28 jmp 800543 + } + else if (lflag) { + 80051b: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) + 80051f: 74 12 je 800533 + return va_arg(*ap, long); + 800521: 8b 45 08 mov 0x8(%ebp),%eax + 800524: 8b 00 mov (%eax),%eax + 800526: 8d 48 04 lea 0x4(%eax),%ecx + 800529: 8b 55 08 mov 0x8(%ebp),%edx + 80052c: 89 0a mov %ecx,(%edx) + 80052e: 8b 00 mov (%eax),%eax + 800530: 99 cltd + 800531: eb 10 jmp 800543 + } + else { + return va_arg(*ap, int); + 800533: 8b 45 08 mov 0x8(%ebp),%eax + 800536: 8b 00 mov (%eax),%eax + 800538: 8d 48 04 lea 0x4(%eax),%ecx + 80053b: 8b 55 08 mov 0x8(%ebp),%edx + 80053e: 89 0a mov %ecx,(%edx) + 800540: 8b 00 mov (%eax),%eax + 800542: 99 cltd + } +} + 800543: 5d pop %ebp + 800544: c3 ret + +00800545 : + * @putch: specified putch function, print a single character + * @putdat: used by @putch function + * @fmt: the format string to use + * */ +void +printfmt(void (*putch)(int, void*), void *putdat, const char *fmt, ...) { + 800545: 55 push %ebp + 800546: 89 e5 mov %esp,%ebp + 800548: 83 ec 28 sub $0x28,%esp + va_list ap; + + va_start(ap, fmt); + 80054b: 8d 45 14 lea 0x14(%ebp),%eax + 80054e: 89 45 f4 mov %eax,-0xc(%ebp) + vprintfmt(putch, putdat, fmt, ap); + 800551: 8b 45 f4 mov -0xc(%ebp),%eax + 800554: 89 44 24 0c mov %eax,0xc(%esp) + 800558: 8b 45 10 mov 0x10(%ebp),%eax + 80055b: 89 44 24 08 mov %eax,0x8(%esp) + 80055f: 8b 45 0c mov 0xc(%ebp),%eax + 800562: 89 44 24 04 mov %eax,0x4(%esp) + 800566: 8b 45 08 mov 0x8(%ebp),%eax + 800569: 89 04 24 mov %eax,(%esp) + 80056c: e8 05 00 00 00 call 800576 + va_end(ap); +} + 800571: 90 nop + 800572: 89 ec mov %ebp,%esp + 800574: 5d pop %ebp + 800575: c3 ret + +00800576 : + * + * Call this function if you are already dealing with a va_list. + * Or you probably want printfmt() instead. + * */ +void +vprintfmt(void (*putch)(int, void*), void *putdat, const char *fmt, va_list ap) { + 800576: 55 push %ebp + 800577: 89 e5 mov %esp,%ebp + 800579: 56 push %esi + 80057a: 53 push %ebx + 80057b: 83 ec 40 sub $0x40,%esp + register int ch, err; + unsigned long long num; + int base, width, precision, lflag, altflag; + + while (1) { + while ((ch = *(unsigned char *)fmt ++) != '%') { + 80057e: eb 17 jmp 800597 + if (ch == '\0') { + 800580: 85 db test %ebx,%ebx + 800582: 0f 84 bf 03 00 00 je 800947 + return; + } + putch(ch, putdat); + 800588: 8b 45 0c mov 0xc(%ebp),%eax + 80058b: 89 44 24 04 mov %eax,0x4(%esp) + 80058f: 89 1c 24 mov %ebx,(%esp) + 800592: 8b 45 08 mov 0x8(%ebp),%eax + 800595: ff d0 call *%eax + while ((ch = *(unsigned char *)fmt ++) != '%') { + 800597: 8b 45 10 mov 0x10(%ebp),%eax + 80059a: 8d 50 01 lea 0x1(%eax),%edx + 80059d: 89 55 10 mov %edx,0x10(%ebp) + 8005a0: 0f b6 00 movzbl (%eax),%eax + 8005a3: 0f b6 d8 movzbl %al,%ebx + 8005a6: 83 fb 25 cmp $0x25,%ebx + 8005a9: 75 d5 jne 800580 + } + + // Process a %-escape sequence + char padc = ' '; + 8005ab: c6 45 db 20 movb $0x20,-0x25(%ebp) + width = precision = -1; + 8005af: c7 45 e4 ff ff ff ff movl $0xffffffff,-0x1c(%ebp) + 8005b6: 8b 45 e4 mov -0x1c(%ebp),%eax + 8005b9: 89 45 e8 mov %eax,-0x18(%ebp) + lflag = altflag = 0; + 8005bc: c7 45 dc 00 00 00 00 movl $0x0,-0x24(%ebp) + 8005c3: 8b 45 dc mov -0x24(%ebp),%eax + 8005c6: 89 45 e0 mov %eax,-0x20(%ebp) + + reswitch: + switch (ch = *(unsigned char *)fmt ++) { + 8005c9: 8b 45 10 mov 0x10(%ebp),%eax + 8005cc: 8d 50 01 lea 0x1(%eax),%edx + 8005cf: 89 55 10 mov %edx,0x10(%ebp) + 8005d2: 0f b6 00 movzbl (%eax),%eax + 8005d5: 0f b6 d8 movzbl %al,%ebx + 8005d8: 8d 43 dd lea -0x23(%ebx),%eax + 8005db: 83 f8 55 cmp $0x55,%eax + 8005de: 0f 87 37 03 00 00 ja 80091b + 8005e4: 8b 04 85 88 11 80 00 mov 0x801188(,%eax,4),%eax + 8005eb: ff e0 jmp *%eax + + // flag to pad on the right + case '-': + padc = '-'; + 8005ed: c6 45 db 2d movb $0x2d,-0x25(%ebp) + goto reswitch; + 8005f1: eb d6 jmp 8005c9 + + // flag to pad with 0's instead of spaces + case '0': + padc = '0'; + 8005f3: c6 45 db 30 movb $0x30,-0x25(%ebp) + goto reswitch; + 8005f7: eb d0 jmp 8005c9 + + // width field + case '1' ... '9': + for (precision = 0; ; ++ fmt) { + 8005f9: c7 45 e4 00 00 00 00 movl $0x0,-0x1c(%ebp) + precision = precision * 10 + ch - '0'; + 800600: 8b 55 e4 mov -0x1c(%ebp),%edx + 800603: 89 d0 mov %edx,%eax + 800605: c1 e0 02 shl $0x2,%eax + 800608: 01 d0 add %edx,%eax + 80060a: 01 c0 add %eax,%eax + 80060c: 01 d8 add %ebx,%eax + 80060e: 83 e8 30 sub $0x30,%eax + 800611: 89 45 e4 mov %eax,-0x1c(%ebp) + ch = *fmt; + 800614: 8b 45 10 mov 0x10(%ebp),%eax + 800617: 0f b6 00 movzbl (%eax),%eax + 80061a: 0f be d8 movsbl %al,%ebx + if (ch < '0' || ch > '9') { + 80061d: 83 fb 2f cmp $0x2f,%ebx + 800620: 7e 38 jle 80065a + 800622: 83 fb 39 cmp $0x39,%ebx + 800625: 7f 33 jg 80065a + for (precision = 0; ; ++ fmt) { + 800627: ff 45 10 incl 0x10(%ebp) + precision = precision * 10 + ch - '0'; + 80062a: eb d4 jmp 800600 + } + } + goto process_precision; + + case '*': + precision = va_arg(ap, int); + 80062c: 8b 45 14 mov 0x14(%ebp),%eax + 80062f: 8d 50 04 lea 0x4(%eax),%edx + 800632: 89 55 14 mov %edx,0x14(%ebp) + 800635: 8b 00 mov (%eax),%eax + 800637: 89 45 e4 mov %eax,-0x1c(%ebp) + goto process_precision; + 80063a: eb 1f jmp 80065b + + case '.': + if (width < 0) + 80063c: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 800640: 79 87 jns 8005c9 + width = 0; + 800642: c7 45 e8 00 00 00 00 movl $0x0,-0x18(%ebp) + goto reswitch; + 800649: e9 7b ff ff ff jmp 8005c9 + + case '#': + altflag = 1; + 80064e: c7 45 dc 01 00 00 00 movl $0x1,-0x24(%ebp) + goto reswitch; + 800655: e9 6f ff ff ff jmp 8005c9 + goto process_precision; + 80065a: 90 nop + + process_precision: + if (width < 0) + 80065b: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 80065f: 0f 89 64 ff ff ff jns 8005c9 + width = precision, precision = -1; + 800665: 8b 45 e4 mov -0x1c(%ebp),%eax + 800668: 89 45 e8 mov %eax,-0x18(%ebp) + 80066b: c7 45 e4 ff ff ff ff movl $0xffffffff,-0x1c(%ebp) + goto reswitch; + 800672: e9 52 ff ff ff jmp 8005c9 + + // long flag (doubled for long long) + case 'l': + lflag ++; + 800677: ff 45 e0 incl -0x20(%ebp) + goto reswitch; + 80067a: e9 4a ff ff ff jmp 8005c9 + + // character + case 'c': + putch(va_arg(ap, int), putdat); + 80067f: 8b 45 14 mov 0x14(%ebp),%eax + 800682: 8d 50 04 lea 0x4(%eax),%edx + 800685: 89 55 14 mov %edx,0x14(%ebp) + 800688: 8b 00 mov (%eax),%eax + 80068a: 8b 55 0c mov 0xc(%ebp),%edx + 80068d: 89 54 24 04 mov %edx,0x4(%esp) + 800691: 89 04 24 mov %eax,(%esp) + 800694: 8b 45 08 mov 0x8(%ebp),%eax + 800697: ff d0 call *%eax + break; + 800699: e9 a4 02 00 00 jmp 800942 + + // error message + case 'e': + err = va_arg(ap, int); + 80069e: 8b 45 14 mov 0x14(%ebp),%eax + 8006a1: 8d 50 04 lea 0x4(%eax),%edx + 8006a4: 89 55 14 mov %edx,0x14(%ebp) + 8006a7: 8b 18 mov (%eax),%ebx + if (err < 0) { + 8006a9: 85 db test %ebx,%ebx + 8006ab: 79 02 jns 8006af + err = -err; + 8006ad: f7 db neg %ebx + } + if (err > MAXERROR || (p = error_string[err]) == NULL) { + 8006af: 83 fb 18 cmp $0x18,%ebx + 8006b2: 7f 0b jg 8006bf + 8006b4: 8b 34 9d 00 11 80 00 mov 0x801100(,%ebx,4),%esi + 8006bb: 85 f6 test %esi,%esi + 8006bd: 75 23 jne 8006e2 + printfmt(putch, putdat, "error %d", err); + 8006bf: 89 5c 24 0c mov %ebx,0xc(%esp) + 8006c3: c7 44 24 08 75 11 80 movl $0x801175,0x8(%esp) + 8006ca: 00 + 8006cb: 8b 45 0c mov 0xc(%ebp),%eax + 8006ce: 89 44 24 04 mov %eax,0x4(%esp) + 8006d2: 8b 45 08 mov 0x8(%ebp),%eax + 8006d5: 89 04 24 mov %eax,(%esp) + 8006d8: e8 68 fe ff ff call 800545 + } + else { + printfmt(putch, putdat, "%s", p); + } + break; + 8006dd: e9 60 02 00 00 jmp 800942 + printfmt(putch, putdat, "%s", p); + 8006e2: 89 74 24 0c mov %esi,0xc(%esp) + 8006e6: c7 44 24 08 7e 11 80 movl $0x80117e,0x8(%esp) + 8006ed: 00 + 8006ee: 8b 45 0c mov 0xc(%ebp),%eax + 8006f1: 89 44 24 04 mov %eax,0x4(%esp) + 8006f5: 8b 45 08 mov 0x8(%ebp),%eax + 8006f8: 89 04 24 mov %eax,(%esp) + 8006fb: e8 45 fe ff ff call 800545 + break; + 800700: e9 3d 02 00 00 jmp 800942 + + // string + case 's': + if ((p = va_arg(ap, char *)) == NULL) { + 800705: 8b 45 14 mov 0x14(%ebp),%eax + 800708: 8d 50 04 lea 0x4(%eax),%edx + 80070b: 89 55 14 mov %edx,0x14(%ebp) + 80070e: 8b 30 mov (%eax),%esi + 800710: 85 f6 test %esi,%esi + 800712: 75 05 jne 800719 + p = "(null)"; + 800714: be 81 11 80 00 mov $0x801181,%esi + } + if (width > 0 && padc != '-') { + 800719: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 80071d: 7e 76 jle 800795 + 80071f: 80 7d db 2d cmpb $0x2d,-0x25(%ebp) + 800723: 74 70 je 800795 + for (width -= strnlen(p, precision); width > 0; width --) { + 800725: 8b 45 e4 mov -0x1c(%ebp),%eax + 800728: 89 44 24 04 mov %eax,0x4(%esp) + 80072c: 89 34 24 mov %esi,(%esp) + 80072f: e8 ee 03 00 00 call 800b22 + 800734: 89 c2 mov %eax,%edx + 800736: 8b 45 e8 mov -0x18(%ebp),%eax + 800739: 29 d0 sub %edx,%eax + 80073b: 89 45 e8 mov %eax,-0x18(%ebp) + 80073e: eb 16 jmp 800756 + putch(padc, putdat); + 800740: 0f be 45 db movsbl -0x25(%ebp),%eax + 800744: 8b 55 0c mov 0xc(%ebp),%edx + 800747: 89 54 24 04 mov %edx,0x4(%esp) + 80074b: 89 04 24 mov %eax,(%esp) + 80074e: 8b 45 08 mov 0x8(%ebp),%eax + 800751: ff d0 call *%eax + for (width -= strnlen(p, precision); width > 0; width --) { + 800753: ff 4d e8 decl -0x18(%ebp) + 800756: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 80075a: 7f e4 jg 800740 + } + } + for (; (ch = *p ++) != '\0' && (precision < 0 || -- precision >= 0); width --) { + 80075c: eb 37 jmp 800795 + if (altflag && (ch < ' ' || ch > '~')) { + 80075e: 83 7d dc 00 cmpl $0x0,-0x24(%ebp) + 800762: 74 1f je 800783 + 800764: 83 fb 1f cmp $0x1f,%ebx + 800767: 7e 05 jle 80076e + 800769: 83 fb 7e cmp $0x7e,%ebx + 80076c: 7e 15 jle 800783 + putch('?', putdat); + 80076e: 8b 45 0c mov 0xc(%ebp),%eax + 800771: 89 44 24 04 mov %eax,0x4(%esp) + 800775: c7 04 24 3f 00 00 00 movl $0x3f,(%esp) + 80077c: 8b 45 08 mov 0x8(%ebp),%eax + 80077f: ff d0 call *%eax + 800781: eb 0f jmp 800792 + } + else { + putch(ch, putdat); + 800783: 8b 45 0c mov 0xc(%ebp),%eax + 800786: 89 44 24 04 mov %eax,0x4(%esp) + 80078a: 89 1c 24 mov %ebx,(%esp) + 80078d: 8b 45 08 mov 0x8(%ebp),%eax + 800790: ff d0 call *%eax + for (; (ch = *p ++) != '\0' && (precision < 0 || -- precision >= 0); width --) { + 800792: ff 4d e8 decl -0x18(%ebp) + 800795: 89 f0 mov %esi,%eax + 800797: 8d 70 01 lea 0x1(%eax),%esi + 80079a: 0f b6 00 movzbl (%eax),%eax + 80079d: 0f be d8 movsbl %al,%ebx + 8007a0: 85 db test %ebx,%ebx + 8007a2: 74 27 je 8007cb + 8007a4: 83 7d e4 00 cmpl $0x0,-0x1c(%ebp) + 8007a8: 78 b4 js 80075e + 8007aa: ff 4d e4 decl -0x1c(%ebp) + 8007ad: 83 7d e4 00 cmpl $0x0,-0x1c(%ebp) + 8007b1: 79 ab jns 80075e + } + } + for (; width > 0; width --) { + 8007b3: eb 16 jmp 8007cb + putch(' ', putdat); + 8007b5: 8b 45 0c mov 0xc(%ebp),%eax + 8007b8: 89 44 24 04 mov %eax,0x4(%esp) + 8007bc: c7 04 24 20 00 00 00 movl $0x20,(%esp) + 8007c3: 8b 45 08 mov 0x8(%ebp),%eax + 8007c6: ff d0 call *%eax + for (; width > 0; width --) { + 8007c8: ff 4d e8 decl -0x18(%ebp) + 8007cb: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 8007cf: 7f e4 jg 8007b5 + } + break; + 8007d1: e9 6c 01 00 00 jmp 800942 + + // (signed) decimal + case 'd': + num = getint(&ap, lflag); + 8007d6: 8b 45 e0 mov -0x20(%ebp),%eax + 8007d9: 89 44 24 04 mov %eax,0x4(%esp) + 8007dd: 8d 45 14 lea 0x14(%ebp),%eax + 8007e0: 89 04 24 mov %eax,(%esp) + 8007e3: e8 16 fd ff ff call 8004fe + 8007e8: 89 45 f0 mov %eax,-0x10(%ebp) + 8007eb: 89 55 f4 mov %edx,-0xc(%ebp) + if ((long long)num < 0) { + 8007ee: 8b 45 f0 mov -0x10(%ebp),%eax + 8007f1: 8b 55 f4 mov -0xc(%ebp),%edx + 8007f4: 85 d2 test %edx,%edx + 8007f6: 79 26 jns 80081e + putch('-', putdat); + 8007f8: 8b 45 0c mov 0xc(%ebp),%eax + 8007fb: 89 44 24 04 mov %eax,0x4(%esp) + 8007ff: c7 04 24 2d 00 00 00 movl $0x2d,(%esp) + 800806: 8b 45 08 mov 0x8(%ebp),%eax + 800809: ff d0 call *%eax + num = -(long long)num; + 80080b: 8b 45 f0 mov -0x10(%ebp),%eax + 80080e: 8b 55 f4 mov -0xc(%ebp),%edx + 800811: f7 d8 neg %eax + 800813: 83 d2 00 adc $0x0,%edx + 800816: f7 da neg %edx + 800818: 89 45 f0 mov %eax,-0x10(%ebp) + 80081b: 89 55 f4 mov %edx,-0xc(%ebp) + } + base = 10; + 80081e: c7 45 ec 0a 00 00 00 movl $0xa,-0x14(%ebp) + goto number; + 800825: e9 a8 00 00 00 jmp 8008d2 + + // unsigned decimal + case 'u': + num = getuint(&ap, lflag); + 80082a: 8b 45 e0 mov -0x20(%ebp),%eax + 80082d: 89 44 24 04 mov %eax,0x4(%esp) + 800831: 8d 45 14 lea 0x14(%ebp),%eax + 800834: 89 04 24 mov %eax,(%esp) + 800837: e8 73 fc ff ff call 8004af + 80083c: 89 45 f0 mov %eax,-0x10(%ebp) + 80083f: 89 55 f4 mov %edx,-0xc(%ebp) + base = 10; + 800842: c7 45 ec 0a 00 00 00 movl $0xa,-0x14(%ebp) + goto number; + 800849: e9 84 00 00 00 jmp 8008d2 + + // (unsigned) octal + case 'o': + num = getuint(&ap, lflag); + 80084e: 8b 45 e0 mov -0x20(%ebp),%eax + 800851: 89 44 24 04 mov %eax,0x4(%esp) + 800855: 8d 45 14 lea 0x14(%ebp),%eax + 800858: 89 04 24 mov %eax,(%esp) + 80085b: e8 4f fc ff ff call 8004af + 800860: 89 45 f0 mov %eax,-0x10(%ebp) + 800863: 89 55 f4 mov %edx,-0xc(%ebp) + base = 8; + 800866: c7 45 ec 08 00 00 00 movl $0x8,-0x14(%ebp) + goto number; + 80086d: eb 63 jmp 8008d2 + + // pointer + case 'p': + putch('0', putdat); + 80086f: 8b 45 0c mov 0xc(%ebp),%eax + 800872: 89 44 24 04 mov %eax,0x4(%esp) + 800876: c7 04 24 30 00 00 00 movl $0x30,(%esp) + 80087d: 8b 45 08 mov 0x8(%ebp),%eax + 800880: ff d0 call *%eax + putch('x', putdat); + 800882: 8b 45 0c mov 0xc(%ebp),%eax + 800885: 89 44 24 04 mov %eax,0x4(%esp) + 800889: c7 04 24 78 00 00 00 movl $0x78,(%esp) + 800890: 8b 45 08 mov 0x8(%ebp),%eax + 800893: ff d0 call *%eax + num = (unsigned long long)(uintptr_t)va_arg(ap, void *); + 800895: 8b 45 14 mov 0x14(%ebp),%eax + 800898: 8d 50 04 lea 0x4(%eax),%edx + 80089b: 89 55 14 mov %edx,0x14(%ebp) + 80089e: 8b 00 mov (%eax),%eax + 8008a0: 89 45 f0 mov %eax,-0x10(%ebp) + 8008a3: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + base = 16; + 8008aa: c7 45 ec 10 00 00 00 movl $0x10,-0x14(%ebp) + goto number; + 8008b1: eb 1f jmp 8008d2 + + // (unsigned) hexadecimal + case 'x': + num = getuint(&ap, lflag); + 8008b3: 8b 45 e0 mov -0x20(%ebp),%eax + 8008b6: 89 44 24 04 mov %eax,0x4(%esp) + 8008ba: 8d 45 14 lea 0x14(%ebp),%eax + 8008bd: 89 04 24 mov %eax,(%esp) + 8008c0: e8 ea fb ff ff call 8004af + 8008c5: 89 45 f0 mov %eax,-0x10(%ebp) + 8008c8: 89 55 f4 mov %edx,-0xc(%ebp) + base = 16; + 8008cb: c7 45 ec 10 00 00 00 movl $0x10,-0x14(%ebp) + number: + printnum(putch, putdat, num, base, width, padc); + 8008d2: 0f be 55 db movsbl -0x25(%ebp),%edx + 8008d6: 8b 45 ec mov -0x14(%ebp),%eax + 8008d9: 89 54 24 18 mov %edx,0x18(%esp) + 8008dd: 8b 55 e8 mov -0x18(%ebp),%edx + 8008e0: 89 54 24 14 mov %edx,0x14(%esp) + 8008e4: 89 44 24 10 mov %eax,0x10(%esp) + 8008e8: 8b 45 f0 mov -0x10(%ebp),%eax + 8008eb: 8b 55 f4 mov -0xc(%ebp),%edx + 8008ee: 89 44 24 08 mov %eax,0x8(%esp) + 8008f2: 89 54 24 0c mov %edx,0xc(%esp) + 8008f6: 8b 45 0c mov 0xc(%ebp),%eax + 8008f9: 89 44 24 04 mov %eax,0x4(%esp) + 8008fd: 8b 45 08 mov 0x8(%ebp),%eax + 800900: 89 04 24 mov %eax,(%esp) + 800903: e8 a5 fa ff ff call 8003ad + break; + 800908: eb 38 jmp 800942 + + // escaped '%' character + case '%': + putch(ch, putdat); + 80090a: 8b 45 0c mov 0xc(%ebp),%eax + 80090d: 89 44 24 04 mov %eax,0x4(%esp) + 800911: 89 1c 24 mov %ebx,(%esp) + 800914: 8b 45 08 mov 0x8(%ebp),%eax + 800917: ff d0 call *%eax + break; + 800919: eb 27 jmp 800942 + + // unrecognized escape sequence - just print it literally + default: + putch('%', putdat); + 80091b: 8b 45 0c mov 0xc(%ebp),%eax + 80091e: 89 44 24 04 mov %eax,0x4(%esp) + 800922: c7 04 24 25 00 00 00 movl $0x25,(%esp) + 800929: 8b 45 08 mov 0x8(%ebp),%eax + 80092c: ff d0 call *%eax + for (fmt --; fmt[-1] != '%'; fmt --) + 80092e: ff 4d 10 decl 0x10(%ebp) + 800931: eb 03 jmp 800936 + 800933: ff 4d 10 decl 0x10(%ebp) + 800936: 8b 45 10 mov 0x10(%ebp),%eax + 800939: 48 dec %eax + 80093a: 0f b6 00 movzbl (%eax),%eax + 80093d: 3c 25 cmp $0x25,%al + 80093f: 75 f2 jne 800933 + /* do nothing */; + break; + 800941: 90 nop + while (1) { + 800942: e9 37 fc ff ff jmp 80057e + return; + 800947: 90 nop + } + } +} + 800948: 83 c4 40 add $0x40,%esp + 80094b: 5b pop %ebx + 80094c: 5e pop %esi + 80094d: 5d pop %ebp + 80094e: c3 ret + +0080094f : + * sprintputch - 'print' a single character in a buffer + * @ch: the character will be printed + * @b: the buffer to place the character @ch + * */ +static void +sprintputch(int ch, struct sprintbuf *b) { + 80094f: 55 push %ebp + 800950: 89 e5 mov %esp,%ebp + b->cnt ++; + 800952: 8b 45 0c mov 0xc(%ebp),%eax + 800955: 8b 40 08 mov 0x8(%eax),%eax + 800958: 8d 50 01 lea 0x1(%eax),%edx + 80095b: 8b 45 0c mov 0xc(%ebp),%eax + 80095e: 89 50 08 mov %edx,0x8(%eax) + if (b->buf < b->ebuf) { + 800961: 8b 45 0c mov 0xc(%ebp),%eax + 800964: 8b 10 mov (%eax),%edx + 800966: 8b 45 0c mov 0xc(%ebp),%eax + 800969: 8b 40 04 mov 0x4(%eax),%eax + 80096c: 39 c2 cmp %eax,%edx + 80096e: 73 12 jae 800982 + *b->buf ++ = ch; + 800970: 8b 45 0c mov 0xc(%ebp),%eax + 800973: 8b 00 mov (%eax),%eax + 800975: 8d 48 01 lea 0x1(%eax),%ecx + 800978: 8b 55 0c mov 0xc(%ebp),%edx + 80097b: 89 0a mov %ecx,(%edx) + 80097d: 8b 55 08 mov 0x8(%ebp),%edx + 800980: 88 10 mov %dl,(%eax) + } +} + 800982: 90 nop + 800983: 5d pop %ebp + 800984: c3 ret + +00800985 : + * @str: the buffer to place the result into + * @size: the size of buffer, including the trailing null space + * @fmt: the format string to use + * */ +int +snprintf(char *str, size_t size, const char *fmt, ...) { + 800985: 55 push %ebp + 800986: 89 e5 mov %esp,%ebp + 800988: 83 ec 28 sub $0x28,%esp + va_list ap; + int cnt; + va_start(ap, fmt); + 80098b: 8d 45 14 lea 0x14(%ebp),%eax + 80098e: 89 45 f0 mov %eax,-0x10(%ebp) + cnt = vsnprintf(str, size, fmt, ap); + 800991: 8b 45 f0 mov -0x10(%ebp),%eax + 800994: 89 44 24 0c mov %eax,0xc(%esp) + 800998: 8b 45 10 mov 0x10(%ebp),%eax + 80099b: 89 44 24 08 mov %eax,0x8(%esp) + 80099f: 8b 45 0c mov 0xc(%ebp),%eax + 8009a2: 89 44 24 04 mov %eax,0x4(%esp) + 8009a6: 8b 45 08 mov 0x8(%ebp),%eax + 8009a9: 89 04 24 mov %eax,(%esp) + 8009ac: e8 0a 00 00 00 call 8009bb + 8009b1: 89 45 f4 mov %eax,-0xc(%ebp) + va_end(ap); + return cnt; + 8009b4: 8b 45 f4 mov -0xc(%ebp),%eax +} + 8009b7: 89 ec mov %ebp,%esp + 8009b9: 5d pop %ebp + 8009ba: c3 ret + +008009bb : + * + * Call this function if you are already dealing with a va_list. + * Or you probably want snprintf() instead. + * */ +int +vsnprintf(char *str, size_t size, const char *fmt, va_list ap) { + 8009bb: 55 push %ebp + 8009bc: 89 e5 mov %esp,%ebp + 8009be: 83 ec 28 sub $0x28,%esp + struct sprintbuf b = {str, str + size - 1, 0}; + 8009c1: 8b 45 08 mov 0x8(%ebp),%eax + 8009c4: 89 45 ec mov %eax,-0x14(%ebp) + 8009c7: 8b 45 0c mov 0xc(%ebp),%eax + 8009ca: 8d 50 ff lea -0x1(%eax),%edx + 8009cd: 8b 45 08 mov 0x8(%ebp),%eax + 8009d0: 01 d0 add %edx,%eax + 8009d2: 89 45 f0 mov %eax,-0x10(%ebp) + 8009d5: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + if (str == NULL || b.buf > b.ebuf) { + 8009dc: 83 7d 08 00 cmpl $0x0,0x8(%ebp) + 8009e0: 74 0a je 8009ec + 8009e2: 8b 55 ec mov -0x14(%ebp),%edx + 8009e5: 8b 45 f0 mov -0x10(%ebp),%eax + 8009e8: 39 c2 cmp %eax,%edx + 8009ea: 76 07 jbe 8009f3 + return -E_INVAL; + 8009ec: b8 fd ff ff ff mov $0xfffffffd,%eax + 8009f1: eb 2a jmp 800a1d + } + // print the string to the buffer + vprintfmt((void*)sprintputch, &b, fmt, ap); + 8009f3: 8b 45 14 mov 0x14(%ebp),%eax + 8009f6: 89 44 24 0c mov %eax,0xc(%esp) + 8009fa: 8b 45 10 mov 0x10(%ebp),%eax + 8009fd: 89 44 24 08 mov %eax,0x8(%esp) + 800a01: 8d 45 ec lea -0x14(%ebp),%eax + 800a04: 89 44 24 04 mov %eax,0x4(%esp) + 800a08: c7 04 24 4f 09 80 00 movl $0x80094f,(%esp) + 800a0f: e8 62 fb ff ff call 800576 + // null terminate the buffer + *b.buf = '\0'; + 800a14: 8b 45 ec mov -0x14(%ebp),%eax + 800a17: c6 00 00 movb $0x0,(%eax) + return b.cnt; + 800a1a: 8b 45 f4 mov -0xc(%ebp),%eax +} + 800a1d: 89 ec mov %ebp,%esp + 800a1f: 5d pop %ebp + 800a20: c3 ret + +00800a21 : + * rand - returns a pseudo-random integer + * + * The rand() function return a value in the range [0, RAND_MAX]. + * */ +int +rand(void) { + 800a21: 55 push %ebp + 800a22: 89 e5 mov %esp,%ebp + 800a24: 57 push %edi + 800a25: 56 push %esi + 800a26: 53 push %ebx + 800a27: 83 ec 24 sub $0x24,%esp + next = (next * 0x5DEECE66DLL + 0xBLL) & ((1LL << 48) - 1); + 800a2a: a1 00 20 80 00 mov 0x802000,%eax + 800a2f: 8b 15 04 20 80 00 mov 0x802004,%edx + 800a35: 69 fa 6d e6 ec de imul $0xdeece66d,%edx,%edi + 800a3b: 6b f0 05 imul $0x5,%eax,%esi + 800a3e: 01 fe add %edi,%esi + 800a40: bf 6d e6 ec de mov $0xdeece66d,%edi + 800a45: f7 e7 mul %edi + 800a47: 01 d6 add %edx,%esi + 800a49: 89 f2 mov %esi,%edx + 800a4b: 83 c0 0b add $0xb,%eax + 800a4e: 83 d2 00 adc $0x0,%edx + 800a51: 89 c7 mov %eax,%edi + 800a53: 83 e7 ff and $0xffffffff,%edi + 800a56: 89 f9 mov %edi,%ecx + 800a58: 0f b7 da movzwl %dx,%ebx + 800a5b: 89 0d 00 20 80 00 mov %ecx,0x802000 + 800a61: 89 1d 04 20 80 00 mov %ebx,0x802004 + unsigned long long result = (next >> 12); + 800a67: a1 00 20 80 00 mov 0x802000,%eax + 800a6c: 8b 15 04 20 80 00 mov 0x802004,%edx + 800a72: 0f ac d0 0c shrd $0xc,%edx,%eax + 800a76: c1 ea 0c shr $0xc,%edx + 800a79: 89 45 e0 mov %eax,-0x20(%ebp) + 800a7c: 89 55 e4 mov %edx,-0x1c(%ebp) + return (int)do_div(result, RAND_MAX + 1); + 800a7f: c7 45 dc 00 00 00 80 movl $0x80000000,-0x24(%ebp) + 800a86: 8b 45 e0 mov -0x20(%ebp),%eax + 800a89: 8b 55 e4 mov -0x1c(%ebp),%edx + 800a8c: 89 45 d8 mov %eax,-0x28(%ebp) + 800a8f: 89 55 e8 mov %edx,-0x18(%ebp) + 800a92: 8b 45 e8 mov -0x18(%ebp),%eax + 800a95: 89 45 ec mov %eax,-0x14(%ebp) + 800a98: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 800a9c: 74 1c je 800aba + 800a9e: 8b 45 e8 mov -0x18(%ebp),%eax + 800aa1: ba 00 00 00 00 mov $0x0,%edx + 800aa6: f7 75 dc divl -0x24(%ebp) + 800aa9: 89 55 ec mov %edx,-0x14(%ebp) + 800aac: 8b 45 e8 mov -0x18(%ebp),%eax + 800aaf: ba 00 00 00 00 mov $0x0,%edx + 800ab4: f7 75 dc divl -0x24(%ebp) + 800ab7: 89 45 e8 mov %eax,-0x18(%ebp) + 800aba: 8b 45 d8 mov -0x28(%ebp),%eax + 800abd: 8b 55 ec mov -0x14(%ebp),%edx + 800ac0: f7 75 dc divl -0x24(%ebp) + 800ac3: 89 45 d8 mov %eax,-0x28(%ebp) + 800ac6: 89 55 d4 mov %edx,-0x2c(%ebp) + 800ac9: 8b 45 d8 mov -0x28(%ebp),%eax + 800acc: 8b 55 e8 mov -0x18(%ebp),%edx + 800acf: 89 45 e0 mov %eax,-0x20(%ebp) + 800ad2: 89 55 e4 mov %edx,-0x1c(%ebp) + 800ad5: 8b 45 d4 mov -0x2c(%ebp),%eax +} + 800ad8: 83 c4 24 add $0x24,%esp + 800adb: 5b pop %ebx + 800adc: 5e pop %esi + 800add: 5f pop %edi + 800ade: 5d pop %ebp + 800adf: c3 ret + +00800ae0 : +/* * + * srand - seed the random number generator with the given number + * @seed: the required seed number + * */ +void +srand(unsigned int seed) { + 800ae0: 55 push %ebp + 800ae1: 89 e5 mov %esp,%ebp + next = seed; + 800ae3: 8b 45 08 mov 0x8(%ebp),%eax + 800ae6: ba 00 00 00 00 mov $0x0,%edx + 800aeb: a3 00 20 80 00 mov %eax,0x802000 + 800af0: 89 15 04 20 80 00 mov %edx,0x802004 +} + 800af6: 90 nop + 800af7: 5d pop %ebp + 800af8: c3 ret + +00800af9 : + * @s: the input string + * + * The strlen() function returns the length of string @s. + * */ +size_t +strlen(const char *s) { + 800af9: 55 push %ebp + 800afa: 89 e5 mov %esp,%ebp + 800afc: 83 ec 10 sub $0x10,%esp + size_t cnt = 0; + 800aff: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + while (*s ++ != '\0') { + 800b06: eb 03 jmp 800b0b + cnt ++; + 800b08: ff 45 fc incl -0x4(%ebp) + while (*s ++ != '\0') { + 800b0b: 8b 45 08 mov 0x8(%ebp),%eax + 800b0e: 8d 50 01 lea 0x1(%eax),%edx + 800b11: 89 55 08 mov %edx,0x8(%ebp) + 800b14: 0f b6 00 movzbl (%eax),%eax + 800b17: 84 c0 test %al,%al + 800b19: 75 ed jne 800b08 + } + return cnt; + 800b1b: 8b 45 fc mov -0x4(%ebp),%eax +} + 800b1e: 89 ec mov %ebp,%esp + 800b20: 5d pop %ebp + 800b21: c3 ret + +00800b22 : + * The return value is strlen(s), if that is less than @len, or + * @len if there is no '\0' character among the first @len characters + * pointed by @s. + * */ +size_t +strnlen(const char *s, size_t len) { + 800b22: 55 push %ebp + 800b23: 89 e5 mov %esp,%ebp + 800b25: 83 ec 10 sub $0x10,%esp + size_t cnt = 0; + 800b28: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + while (cnt < len && *s ++ != '\0') { + 800b2f: eb 03 jmp 800b34 + cnt ++; + 800b31: ff 45 fc incl -0x4(%ebp) + while (cnt < len && *s ++ != '\0') { + 800b34: 8b 45 fc mov -0x4(%ebp),%eax + 800b37: 3b 45 0c cmp 0xc(%ebp),%eax + 800b3a: 73 10 jae 800b4c + 800b3c: 8b 45 08 mov 0x8(%ebp),%eax + 800b3f: 8d 50 01 lea 0x1(%eax),%edx + 800b42: 89 55 08 mov %edx,0x8(%ebp) + 800b45: 0f b6 00 movzbl (%eax),%eax + 800b48: 84 c0 test %al,%al + 800b4a: 75 e5 jne 800b31 + } + return cnt; + 800b4c: 8b 45 fc mov -0x4(%ebp),%eax +} + 800b4f: 89 ec mov %ebp,%esp + 800b51: 5d pop %ebp + 800b52: c3 ret + +00800b53 : + * To avoid overflows, the size of array pointed by @dst should be long enough to + * contain the same string as @src (including the terminating null character), and + * should not overlap in memory with @src. + * */ +char * +strcpy(char *dst, const char *src) { + 800b53: 55 push %ebp + 800b54: 89 e5 mov %esp,%ebp + 800b56: 57 push %edi + 800b57: 56 push %esi + 800b58: 83 ec 20 sub $0x20,%esp + 800b5b: 8b 45 08 mov 0x8(%ebp),%eax + 800b5e: 89 45 f4 mov %eax,-0xc(%ebp) + 800b61: 8b 45 0c mov 0xc(%ebp),%eax + 800b64: 89 45 f0 mov %eax,-0x10(%ebp) +#ifndef __HAVE_ARCH_STRCPY +#define __HAVE_ARCH_STRCPY +static inline char * +__strcpy(char *dst, const char *src) { + int d0, d1, d2; + asm volatile ( + 800b67: 8b 55 f0 mov -0x10(%ebp),%edx + 800b6a: 8b 45 f4 mov -0xc(%ebp),%eax + 800b6d: 89 d1 mov %edx,%ecx + 800b6f: 89 c2 mov %eax,%edx + 800b71: 89 ce mov %ecx,%esi + 800b73: 89 d7 mov %edx,%edi + 800b75: ac lods %ds:(%esi),%al + 800b76: aa stos %al,%es:(%edi) + 800b77: 84 c0 test %al,%al + 800b79: 75 fa jne 800b75 + 800b7b: 89 fa mov %edi,%edx + 800b7d: 89 f1 mov %esi,%ecx + 800b7f: 89 4d ec mov %ecx,-0x14(%ebp) + 800b82: 89 55 e8 mov %edx,-0x18(%ebp) + 800b85: 89 45 e4 mov %eax,-0x1c(%ebp) + "stosb;" + "testb %%al, %%al;" + "jne 1b;" + : "=&S" (d0), "=&D" (d1), "=&a" (d2) + : "0" (src), "1" (dst) : "memory"); + return dst; + 800b88: 8b 45 f4 mov -0xc(%ebp),%eax + char *p = dst; + while ((*p ++ = *src ++) != '\0') + /* nothing */; + return dst; +#endif /* __HAVE_ARCH_STRCPY */ +} + 800b8b: 83 c4 20 add $0x20,%esp + 800b8e: 5e pop %esi + 800b8f: 5f pop %edi + 800b90: 5d pop %ebp + 800b91: c3 ret + +00800b92 : + * @len: maximum number of characters to be copied from @src + * + * The return value is @dst + * */ +char * +strncpy(char *dst, const char *src, size_t len) { + 800b92: 55 push %ebp + 800b93: 89 e5 mov %esp,%ebp + 800b95: 83 ec 10 sub $0x10,%esp + char *p = dst; + 800b98: 8b 45 08 mov 0x8(%ebp),%eax + 800b9b: 89 45 fc mov %eax,-0x4(%ebp) + while (len > 0) { + 800b9e: eb 1e jmp 800bbe + if ((*p = *src) != '\0') { + 800ba0: 8b 45 0c mov 0xc(%ebp),%eax + 800ba3: 0f b6 10 movzbl (%eax),%edx + 800ba6: 8b 45 fc mov -0x4(%ebp),%eax + 800ba9: 88 10 mov %dl,(%eax) + 800bab: 8b 45 fc mov -0x4(%ebp),%eax + 800bae: 0f b6 00 movzbl (%eax),%eax + 800bb1: 84 c0 test %al,%al + 800bb3: 74 03 je 800bb8 + src ++; + 800bb5: ff 45 0c incl 0xc(%ebp) + } + p ++, len --; + 800bb8: ff 45 fc incl -0x4(%ebp) + 800bbb: ff 4d 10 decl 0x10(%ebp) + while (len > 0) { + 800bbe: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800bc2: 75 dc jne 800ba0 + } + return dst; + 800bc4: 8b 45 08 mov 0x8(%ebp),%eax +} + 800bc7: 89 ec mov %ebp,%esp + 800bc9: 5d pop %ebp + 800bca: c3 ret + +00800bcb : + * - A value greater than zero indicates that the first character that does + * not match has a greater value in @s1 than in @s2; + * - And a value less than zero indicates the opposite. + * */ +int +strcmp(const char *s1, const char *s2) { + 800bcb: 55 push %ebp + 800bcc: 89 e5 mov %esp,%ebp + 800bce: 57 push %edi + 800bcf: 56 push %esi + 800bd0: 83 ec 20 sub $0x20,%esp + 800bd3: 8b 45 08 mov 0x8(%ebp),%eax + 800bd6: 89 45 f4 mov %eax,-0xc(%ebp) + 800bd9: 8b 45 0c mov 0xc(%ebp),%eax + 800bdc: 89 45 f0 mov %eax,-0x10(%ebp) + asm volatile ( + 800bdf: 8b 55 f4 mov -0xc(%ebp),%edx + 800be2: 8b 45 f0 mov -0x10(%ebp),%eax + 800be5: 89 d1 mov %edx,%ecx + 800be7: 89 c2 mov %eax,%edx + 800be9: 89 ce mov %ecx,%esi + 800beb: 89 d7 mov %edx,%edi + 800bed: ac lods %ds:(%esi),%al + 800bee: ae scas %es:(%edi),%al + 800bef: 75 08 jne 800bf9 + 800bf1: 84 c0 test %al,%al + 800bf3: 75 f8 jne 800bed + 800bf5: 31 c0 xor %eax,%eax + 800bf7: eb 04 jmp 800bfd + 800bf9: 19 c0 sbb %eax,%eax + 800bfb: 0c 01 or $0x1,%al + 800bfd: 89 fa mov %edi,%edx + 800bff: 89 f1 mov %esi,%ecx + 800c01: 89 45 ec mov %eax,-0x14(%ebp) + 800c04: 89 4d e8 mov %ecx,-0x18(%ebp) + 800c07: 89 55 e4 mov %edx,-0x1c(%ebp) + return ret; + 800c0a: 8b 45 ec mov -0x14(%ebp),%eax + while (*s1 != '\0' && *s1 == *s2) { + s1 ++, s2 ++; + } + return (int)((unsigned char)*s1 - (unsigned char)*s2); +#endif /* __HAVE_ARCH_STRCMP */ +} + 800c0d: 83 c4 20 add $0x20,%esp + 800c10: 5e pop %esi + 800c11: 5f pop %edi + 800c12: 5d pop %ebp + 800c13: c3 ret + +00800c14 : + * they are equal to each other, it continues with the following pairs until + * the characters differ, until a terminating null-character is reached, or + * until @n characters match in both strings, whichever happens first. + * */ +int +strncmp(const char *s1, const char *s2, size_t n) { + 800c14: 55 push %ebp + 800c15: 89 e5 mov %esp,%ebp + while (n > 0 && *s1 != '\0' && *s1 == *s2) { + 800c17: eb 09 jmp 800c22 + n --, s1 ++, s2 ++; + 800c19: ff 4d 10 decl 0x10(%ebp) + 800c1c: ff 45 08 incl 0x8(%ebp) + 800c1f: ff 45 0c incl 0xc(%ebp) + while (n > 0 && *s1 != '\0' && *s1 == *s2) { + 800c22: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800c26: 74 1a je 800c42 + 800c28: 8b 45 08 mov 0x8(%ebp),%eax + 800c2b: 0f b6 00 movzbl (%eax),%eax + 800c2e: 84 c0 test %al,%al + 800c30: 74 10 je 800c42 + 800c32: 8b 45 08 mov 0x8(%ebp),%eax + 800c35: 0f b6 10 movzbl (%eax),%edx + 800c38: 8b 45 0c mov 0xc(%ebp),%eax + 800c3b: 0f b6 00 movzbl (%eax),%eax + 800c3e: 38 c2 cmp %al,%dl + 800c40: 74 d7 je 800c19 + } + return (n == 0) ? 0 : (int)((unsigned char)*s1 - (unsigned char)*s2); + 800c42: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800c46: 74 18 je 800c60 + 800c48: 8b 45 08 mov 0x8(%ebp),%eax + 800c4b: 0f b6 00 movzbl (%eax),%eax + 800c4e: 0f b6 d0 movzbl %al,%edx + 800c51: 8b 45 0c mov 0xc(%ebp),%eax + 800c54: 0f b6 00 movzbl (%eax),%eax + 800c57: 0f b6 c8 movzbl %al,%ecx + 800c5a: 89 d0 mov %edx,%eax + 800c5c: 29 c8 sub %ecx,%eax + 800c5e: eb 05 jmp 800c65 + 800c60: b8 00 00 00 00 mov $0x0,%eax +} + 800c65: 5d pop %ebp + 800c66: c3 ret + +00800c67 : + * + * The strchr() function returns a pointer to the first occurrence of + * character in @s. If the value is not found, the function returns 'NULL'. + * */ +char * +strchr(const char *s, char c) { + 800c67: 55 push %ebp + 800c68: 89 e5 mov %esp,%ebp + 800c6a: 83 ec 04 sub $0x4,%esp + 800c6d: 8b 45 0c mov 0xc(%ebp),%eax + 800c70: 88 45 fc mov %al,-0x4(%ebp) + while (*s != '\0') { + 800c73: eb 13 jmp 800c88 + if (*s == c) { + 800c75: 8b 45 08 mov 0x8(%ebp),%eax + 800c78: 0f b6 00 movzbl (%eax),%eax + 800c7b: 38 45 fc cmp %al,-0x4(%ebp) + 800c7e: 75 05 jne 800c85 + return (char *)s; + 800c80: 8b 45 08 mov 0x8(%ebp),%eax + 800c83: eb 12 jmp 800c97 + } + s ++; + 800c85: ff 45 08 incl 0x8(%ebp) + while (*s != '\0') { + 800c88: 8b 45 08 mov 0x8(%ebp),%eax + 800c8b: 0f b6 00 movzbl (%eax),%eax + 800c8e: 84 c0 test %al,%al + 800c90: 75 e3 jne 800c75 + } + return NULL; + 800c92: b8 00 00 00 00 mov $0x0,%eax +} + 800c97: 89 ec mov %ebp,%esp + 800c99: 5d pop %ebp + 800c9a: c3 ret + +00800c9b : + * The strfind() function is like strchr() except that if @c is + * not found in @s, then it returns a pointer to the null byte at the + * end of @s, rather than 'NULL'. + * */ +char * +strfind(const char *s, char c) { + 800c9b: 55 push %ebp + 800c9c: 89 e5 mov %esp,%ebp + 800c9e: 83 ec 04 sub $0x4,%esp + 800ca1: 8b 45 0c mov 0xc(%ebp),%eax + 800ca4: 88 45 fc mov %al,-0x4(%ebp) + while (*s != '\0') { + 800ca7: eb 0e jmp 800cb7 + if (*s == c) { + 800ca9: 8b 45 08 mov 0x8(%ebp),%eax + 800cac: 0f b6 00 movzbl (%eax),%eax + 800caf: 38 45 fc cmp %al,-0x4(%ebp) + 800cb2: 74 0f je 800cc3 + break; + } + s ++; + 800cb4: ff 45 08 incl 0x8(%ebp) + while (*s != '\0') { + 800cb7: 8b 45 08 mov 0x8(%ebp),%eax + 800cba: 0f b6 00 movzbl (%eax),%eax + 800cbd: 84 c0 test %al,%al + 800cbf: 75 e8 jne 800ca9 + 800cc1: eb 01 jmp 800cc4 + break; + 800cc3: 90 nop + } + return (char *)s; + 800cc4: 8b 45 08 mov 0x8(%ebp),%eax +} + 800cc7: 89 ec mov %ebp,%esp + 800cc9: 5d pop %ebp + 800cca: c3 ret + +00800ccb : + * an optional "0x" or "0X" prefix. + * + * The strtol() function returns the converted integral number as a long int value. + * */ +long +strtol(const char *s, char **endptr, int base) { + 800ccb: 55 push %ebp + 800ccc: 89 e5 mov %esp,%ebp + 800cce: 83 ec 10 sub $0x10,%esp + int neg = 0; + 800cd1: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + long val = 0; + 800cd8: c7 45 f8 00 00 00 00 movl $0x0,-0x8(%ebp) + + // gobble initial whitespace + while (*s == ' ' || *s == '\t') { + 800cdf: eb 03 jmp 800ce4 + s ++; + 800ce1: ff 45 08 incl 0x8(%ebp) + while (*s == ' ' || *s == '\t') { + 800ce4: 8b 45 08 mov 0x8(%ebp),%eax + 800ce7: 0f b6 00 movzbl (%eax),%eax + 800cea: 3c 20 cmp $0x20,%al + 800cec: 74 f3 je 800ce1 + 800cee: 8b 45 08 mov 0x8(%ebp),%eax + 800cf1: 0f b6 00 movzbl (%eax),%eax + 800cf4: 3c 09 cmp $0x9,%al + 800cf6: 74 e9 je 800ce1 + } + + // plus/minus sign + if (*s == '+') { + 800cf8: 8b 45 08 mov 0x8(%ebp),%eax + 800cfb: 0f b6 00 movzbl (%eax),%eax + 800cfe: 3c 2b cmp $0x2b,%al + 800d00: 75 05 jne 800d07 + s ++; + 800d02: ff 45 08 incl 0x8(%ebp) + 800d05: eb 14 jmp 800d1b + } + else if (*s == '-') { + 800d07: 8b 45 08 mov 0x8(%ebp),%eax + 800d0a: 0f b6 00 movzbl (%eax),%eax + 800d0d: 3c 2d cmp $0x2d,%al + 800d0f: 75 0a jne 800d1b + s ++, neg = 1; + 800d11: ff 45 08 incl 0x8(%ebp) + 800d14: c7 45 fc 01 00 00 00 movl $0x1,-0x4(%ebp) + } + + // hex or octal base prefix + if ((base == 0 || base == 16) && (s[0] == '0' && s[1] == 'x')) { + 800d1b: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800d1f: 74 06 je 800d27 + 800d21: 83 7d 10 10 cmpl $0x10,0x10(%ebp) + 800d25: 75 22 jne 800d49 + 800d27: 8b 45 08 mov 0x8(%ebp),%eax + 800d2a: 0f b6 00 movzbl (%eax),%eax + 800d2d: 3c 30 cmp $0x30,%al + 800d2f: 75 18 jne 800d49 + 800d31: 8b 45 08 mov 0x8(%ebp),%eax + 800d34: 40 inc %eax + 800d35: 0f b6 00 movzbl (%eax),%eax + 800d38: 3c 78 cmp $0x78,%al + 800d3a: 75 0d jne 800d49 + s += 2, base = 16; + 800d3c: 83 45 08 02 addl $0x2,0x8(%ebp) + 800d40: c7 45 10 10 00 00 00 movl $0x10,0x10(%ebp) + 800d47: eb 29 jmp 800d72 + } + else if (base == 0 && s[0] == '0') { + 800d49: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800d4d: 75 16 jne 800d65 + 800d4f: 8b 45 08 mov 0x8(%ebp),%eax + 800d52: 0f b6 00 movzbl (%eax),%eax + 800d55: 3c 30 cmp $0x30,%al + 800d57: 75 0c jne 800d65 + s ++, base = 8; + 800d59: ff 45 08 incl 0x8(%ebp) + 800d5c: c7 45 10 08 00 00 00 movl $0x8,0x10(%ebp) + 800d63: eb 0d jmp 800d72 + } + else if (base == 0) { + 800d65: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800d69: 75 07 jne 800d72 + base = 10; + 800d6b: c7 45 10 0a 00 00 00 movl $0xa,0x10(%ebp) + + // digits + while (1) { + int dig; + + if (*s >= '0' && *s <= '9') { + 800d72: 8b 45 08 mov 0x8(%ebp),%eax + 800d75: 0f b6 00 movzbl (%eax),%eax + 800d78: 3c 2f cmp $0x2f,%al + 800d7a: 7e 1b jle 800d97 + 800d7c: 8b 45 08 mov 0x8(%ebp),%eax + 800d7f: 0f b6 00 movzbl (%eax),%eax + 800d82: 3c 39 cmp $0x39,%al + 800d84: 7f 11 jg 800d97 + dig = *s - '0'; + 800d86: 8b 45 08 mov 0x8(%ebp),%eax + 800d89: 0f b6 00 movzbl (%eax),%eax + 800d8c: 0f be c0 movsbl %al,%eax + 800d8f: 83 e8 30 sub $0x30,%eax + 800d92: 89 45 f4 mov %eax,-0xc(%ebp) + 800d95: eb 48 jmp 800ddf + } + else if (*s >= 'a' && *s <= 'z') { + 800d97: 8b 45 08 mov 0x8(%ebp),%eax + 800d9a: 0f b6 00 movzbl (%eax),%eax + 800d9d: 3c 60 cmp $0x60,%al + 800d9f: 7e 1b jle 800dbc + 800da1: 8b 45 08 mov 0x8(%ebp),%eax + 800da4: 0f b6 00 movzbl (%eax),%eax + 800da7: 3c 7a cmp $0x7a,%al + 800da9: 7f 11 jg 800dbc + dig = *s - 'a' + 10; + 800dab: 8b 45 08 mov 0x8(%ebp),%eax + 800dae: 0f b6 00 movzbl (%eax),%eax + 800db1: 0f be c0 movsbl %al,%eax + 800db4: 83 e8 57 sub $0x57,%eax + 800db7: 89 45 f4 mov %eax,-0xc(%ebp) + 800dba: eb 23 jmp 800ddf + } + else if (*s >= 'A' && *s <= 'Z') { + 800dbc: 8b 45 08 mov 0x8(%ebp),%eax + 800dbf: 0f b6 00 movzbl (%eax),%eax + 800dc2: 3c 40 cmp $0x40,%al + 800dc4: 7e 3b jle 800e01 + 800dc6: 8b 45 08 mov 0x8(%ebp),%eax + 800dc9: 0f b6 00 movzbl (%eax),%eax + 800dcc: 3c 5a cmp $0x5a,%al + 800dce: 7f 31 jg 800e01 + dig = *s - 'A' + 10; + 800dd0: 8b 45 08 mov 0x8(%ebp),%eax + 800dd3: 0f b6 00 movzbl (%eax),%eax + 800dd6: 0f be c0 movsbl %al,%eax + 800dd9: 83 e8 37 sub $0x37,%eax + 800ddc: 89 45 f4 mov %eax,-0xc(%ebp) + } + else { + break; + } + if (dig >= base) { + 800ddf: 8b 45 f4 mov -0xc(%ebp),%eax + 800de2: 3b 45 10 cmp 0x10(%ebp),%eax + 800de5: 7d 19 jge 800e00 + break; + } + s ++, val = (val * base) + dig; + 800de7: ff 45 08 incl 0x8(%ebp) + 800dea: 8b 45 f8 mov -0x8(%ebp),%eax + 800ded: 0f af 45 10 imul 0x10(%ebp),%eax + 800df1: 89 c2 mov %eax,%edx + 800df3: 8b 45 f4 mov -0xc(%ebp),%eax + 800df6: 01 d0 add %edx,%eax + 800df8: 89 45 f8 mov %eax,-0x8(%ebp) + while (1) { + 800dfb: e9 72 ff ff ff jmp 800d72 + break; + 800e00: 90 nop + // we don't properly detect overflow! + } + + if (endptr) { + 800e01: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) + 800e05: 74 08 je 800e0f + *endptr = (char *) s; + 800e07: 8b 45 0c mov 0xc(%ebp),%eax + 800e0a: 8b 55 08 mov 0x8(%ebp),%edx + 800e0d: 89 10 mov %edx,(%eax) + } + return (neg ? -val : val); + 800e0f: 83 7d fc 00 cmpl $0x0,-0x4(%ebp) + 800e13: 74 07 je 800e1c + 800e15: 8b 45 f8 mov -0x8(%ebp),%eax + 800e18: f7 d8 neg %eax + 800e1a: eb 03 jmp 800e1f + 800e1c: 8b 45 f8 mov -0x8(%ebp),%eax +} + 800e1f: 89 ec mov %ebp,%esp + 800e21: 5d pop %ebp + 800e22: c3 ret + +00800e23 : + * @n: number of bytes to be set to the value + * + * The memset() function returns @s. + * */ +void * +memset(void *s, char c, size_t n) { + 800e23: 55 push %ebp + 800e24: 89 e5 mov %esp,%ebp + 800e26: 83 ec 28 sub $0x28,%esp + 800e29: 89 7d fc mov %edi,-0x4(%ebp) + 800e2c: 8b 45 0c mov 0xc(%ebp),%eax + 800e2f: 88 45 d8 mov %al,-0x28(%ebp) +#ifdef __HAVE_ARCH_MEMSET + return __memset(s, c, n); + 800e32: 0f be 55 d8 movsbl -0x28(%ebp),%edx + 800e36: 8b 45 08 mov 0x8(%ebp),%eax + 800e39: 89 45 f8 mov %eax,-0x8(%ebp) + 800e3c: 88 55 f7 mov %dl,-0x9(%ebp) + 800e3f: 8b 45 10 mov 0x10(%ebp),%eax + 800e42: 89 45 f0 mov %eax,-0x10(%ebp) +#ifndef __HAVE_ARCH_MEMSET +#define __HAVE_ARCH_MEMSET +static inline void * +__memset(void *s, char c, size_t n) { + int d0, d1; + asm volatile ( + 800e45: 8b 4d f0 mov -0x10(%ebp),%ecx + 800e48: 0f b6 45 f7 movzbl -0x9(%ebp),%eax + 800e4c: 8b 55 f8 mov -0x8(%ebp),%edx + 800e4f: 89 d7 mov %edx,%edi + 800e51: f3 aa rep stos %al,%es:(%edi) + 800e53: 89 fa mov %edi,%edx + 800e55: 89 4d ec mov %ecx,-0x14(%ebp) + 800e58: 89 55 e8 mov %edx,-0x18(%ebp) + "rep; stosb;" + : "=&c" (d0), "=&D" (d1) + : "0" (n), "a" (c), "1" (s) + : "memory"); + return s; + 800e5b: 8b 45 f8 mov -0x8(%ebp),%eax + while (n -- > 0) { + *p ++ = c; + } + return s; +#endif /* __HAVE_ARCH_MEMSET */ +} + 800e5e: 8b 7d fc mov -0x4(%ebp),%edi + 800e61: 89 ec mov %ebp,%esp + 800e63: 5d pop %ebp + 800e64: c3 ret + +00800e65 : + * @n: number of bytes to copy + * + * The memmove() function returns @dst. + * */ +void * +memmove(void *dst, const void *src, size_t n) { + 800e65: 55 push %ebp + 800e66: 89 e5 mov %esp,%ebp + 800e68: 57 push %edi + 800e69: 56 push %esi + 800e6a: 53 push %ebx + 800e6b: 83 ec 30 sub $0x30,%esp + 800e6e: 8b 45 08 mov 0x8(%ebp),%eax + 800e71: 89 45 f0 mov %eax,-0x10(%ebp) + 800e74: 8b 45 0c mov 0xc(%ebp),%eax + 800e77: 89 45 ec mov %eax,-0x14(%ebp) + 800e7a: 8b 45 10 mov 0x10(%ebp),%eax + 800e7d: 89 45 e8 mov %eax,-0x18(%ebp) + +#ifndef __HAVE_ARCH_MEMMOVE +#define __HAVE_ARCH_MEMMOVE +static inline void * +__memmove(void *dst, const void *src, size_t n) { + if (dst < src) { + 800e80: 8b 45 f0 mov -0x10(%ebp),%eax + 800e83: 3b 45 ec cmp -0x14(%ebp),%eax + 800e86: 73 42 jae 800eca + 800e88: 8b 45 f0 mov -0x10(%ebp),%eax + 800e8b: 89 45 e4 mov %eax,-0x1c(%ebp) + 800e8e: 8b 45 ec mov -0x14(%ebp),%eax + 800e91: 89 45 e0 mov %eax,-0x20(%ebp) + 800e94: 8b 45 e8 mov -0x18(%ebp),%eax + 800e97: 89 45 dc mov %eax,-0x24(%ebp) + "andl $3, %%ecx;" + "jz 1f;" + "rep; movsb;" + "1:" + : "=&c" (d0), "=&D" (d1), "=&S" (d2) + : "0" (n / 4), "g" (n), "1" (dst), "2" (src) + 800e9a: 8b 45 dc mov -0x24(%ebp),%eax + 800e9d: c1 e8 02 shr $0x2,%eax + 800ea0: 89 c1 mov %eax,%ecx + asm volatile ( + 800ea2: 8b 55 e4 mov -0x1c(%ebp),%edx + 800ea5: 8b 45 e0 mov -0x20(%ebp),%eax + 800ea8: 89 d7 mov %edx,%edi + 800eaa: 89 c6 mov %eax,%esi + 800eac: f3 a5 rep movsl %ds:(%esi),%es:(%edi) + 800eae: 8b 4d dc mov -0x24(%ebp),%ecx + 800eb1: 83 e1 03 and $0x3,%ecx + 800eb4: 74 02 je 800eb8 + 800eb6: f3 a4 rep movsb %ds:(%esi),%es:(%edi) + 800eb8: 89 f0 mov %esi,%eax + 800eba: 89 fa mov %edi,%edx + 800ebc: 89 4d d8 mov %ecx,-0x28(%ebp) + 800ebf: 89 55 d4 mov %edx,-0x2c(%ebp) + 800ec2: 89 45 d0 mov %eax,-0x30(%ebp) + : "memory"); + return dst; + 800ec5: 8b 45 e4 mov -0x1c(%ebp),%eax + return __memcpy(dst, src, n); + 800ec8: eb 36 jmp 800f00 + : "0" (n), "1" (n - 1 + src), "2" (n - 1 + dst) + 800eca: 8b 45 e8 mov -0x18(%ebp),%eax + 800ecd: 8d 50 ff lea -0x1(%eax),%edx + 800ed0: 8b 45 ec mov -0x14(%ebp),%eax + 800ed3: 01 c2 add %eax,%edx + 800ed5: 8b 45 e8 mov -0x18(%ebp),%eax + 800ed8: 8d 48 ff lea -0x1(%eax),%ecx + 800edb: 8b 45 f0 mov -0x10(%ebp),%eax + 800ede: 8d 1c 01 lea (%ecx,%eax,1),%ebx + asm volatile ( + 800ee1: 8b 45 e8 mov -0x18(%ebp),%eax + 800ee4: 89 c1 mov %eax,%ecx + 800ee6: 89 d8 mov %ebx,%eax + 800ee8: 89 d6 mov %edx,%esi + 800eea: 89 c7 mov %eax,%edi + 800eec: fd std + 800eed: f3 a4 rep movsb %ds:(%esi),%es:(%edi) + 800eef: fc cld + 800ef0: 89 f8 mov %edi,%eax + 800ef2: 89 f2 mov %esi,%edx + 800ef4: 89 4d cc mov %ecx,-0x34(%ebp) + 800ef7: 89 55 c8 mov %edx,-0x38(%ebp) + 800efa: 89 45 c4 mov %eax,-0x3c(%ebp) + return dst; + 800efd: 8b 45 f0 mov -0x10(%ebp),%eax + *d ++ = *s ++; + } + } + return dst; +#endif /* __HAVE_ARCH_MEMMOVE */ +} + 800f00: 83 c4 30 add $0x30,%esp + 800f03: 5b pop %ebx + 800f04: 5e pop %esi + 800f05: 5f pop %edi + 800f06: 5d pop %ebp + 800f07: c3 ret + +00800f08 : + * it always copies exactly @n bytes. To avoid overflows, the size of arrays pointed + * by both @src and @dst, should be at least @n bytes, and should not overlap + * (for overlapping memory area, memmove is a safer approach). + * */ +void * +memcpy(void *dst, const void *src, size_t n) { + 800f08: 55 push %ebp + 800f09: 89 e5 mov %esp,%ebp + 800f0b: 57 push %edi + 800f0c: 56 push %esi + 800f0d: 83 ec 20 sub $0x20,%esp + 800f10: 8b 45 08 mov 0x8(%ebp),%eax + 800f13: 89 45 f4 mov %eax,-0xc(%ebp) + 800f16: 8b 45 0c mov 0xc(%ebp),%eax + 800f19: 89 45 f0 mov %eax,-0x10(%ebp) + 800f1c: 8b 45 10 mov 0x10(%ebp),%eax + 800f1f: 89 45 ec mov %eax,-0x14(%ebp) + : "0" (n / 4), "g" (n), "1" (dst), "2" (src) + 800f22: 8b 45 ec mov -0x14(%ebp),%eax + 800f25: c1 e8 02 shr $0x2,%eax + 800f28: 89 c1 mov %eax,%ecx + asm volatile ( + 800f2a: 8b 55 f4 mov -0xc(%ebp),%edx + 800f2d: 8b 45 f0 mov -0x10(%ebp),%eax + 800f30: 89 d7 mov %edx,%edi + 800f32: 89 c6 mov %eax,%esi + 800f34: f3 a5 rep movsl %ds:(%esi),%es:(%edi) + 800f36: 8b 4d ec mov -0x14(%ebp),%ecx + 800f39: 83 e1 03 and $0x3,%ecx + 800f3c: 74 02 je 800f40 + 800f3e: f3 a4 rep movsb %ds:(%esi),%es:(%edi) + 800f40: 89 f0 mov %esi,%eax + 800f42: 89 fa mov %edi,%edx + 800f44: 89 4d e8 mov %ecx,-0x18(%ebp) + 800f47: 89 55 e4 mov %edx,-0x1c(%ebp) + 800f4a: 89 45 e0 mov %eax,-0x20(%ebp) + return dst; + 800f4d: 8b 45 f4 mov -0xc(%ebp),%eax + while (n -- > 0) { + *d ++ = *s ++; + } + return dst; +#endif /* __HAVE_ARCH_MEMCPY */ +} + 800f50: 83 c4 20 add $0x20,%esp + 800f53: 5e pop %esi + 800f54: 5f pop %edi + 800f55: 5d pop %ebp + 800f56: c3 ret + +00800f57 : + * match in both memory blocks has a greater value in @v1 than in @v2 + * as if evaluated as unsigned char values; + * - And a value less than zero indicates the opposite. + * */ +int +memcmp(const void *v1, const void *v2, size_t n) { + 800f57: 55 push %ebp + 800f58: 89 e5 mov %esp,%ebp + 800f5a: 83 ec 10 sub $0x10,%esp + const char *s1 = (const char *)v1; + 800f5d: 8b 45 08 mov 0x8(%ebp),%eax + 800f60: 89 45 fc mov %eax,-0x4(%ebp) + const char *s2 = (const char *)v2; + 800f63: 8b 45 0c mov 0xc(%ebp),%eax + 800f66: 89 45 f8 mov %eax,-0x8(%ebp) + while (n -- > 0) { + 800f69: eb 2e jmp 800f99 + if (*s1 != *s2) { + 800f6b: 8b 45 fc mov -0x4(%ebp),%eax + 800f6e: 0f b6 10 movzbl (%eax),%edx + 800f71: 8b 45 f8 mov -0x8(%ebp),%eax + 800f74: 0f b6 00 movzbl (%eax),%eax + 800f77: 38 c2 cmp %al,%dl + 800f79: 74 18 je 800f93 + return (int)((unsigned char)*s1 - (unsigned char)*s2); + 800f7b: 8b 45 fc mov -0x4(%ebp),%eax + 800f7e: 0f b6 00 movzbl (%eax),%eax + 800f81: 0f b6 d0 movzbl %al,%edx + 800f84: 8b 45 f8 mov -0x8(%ebp),%eax + 800f87: 0f b6 00 movzbl (%eax),%eax + 800f8a: 0f b6 c8 movzbl %al,%ecx + 800f8d: 89 d0 mov %edx,%eax + 800f8f: 29 c8 sub %ecx,%eax + 800f91: eb 18 jmp 800fab + } + s1 ++, s2 ++; + 800f93: ff 45 fc incl -0x4(%ebp) + 800f96: ff 45 f8 incl -0x8(%ebp) + while (n -- > 0) { + 800f99: 8b 45 10 mov 0x10(%ebp),%eax + 800f9c: 8d 50 ff lea -0x1(%eax),%edx + 800f9f: 89 55 10 mov %edx,0x10(%ebp) + 800fa2: 85 c0 test %eax,%eax + 800fa4: 75 c5 jne 800f6b + } + return 0; + 800fa6: b8 00 00 00 00 mov $0x0,%eax +} + 800fab: 89 ec mov %ebp,%esp + 800fad: 5d pop %ebp + 800fae: c3 ret + +00800faf
: +#include +#include + +int +main(void) { + 800faf: 55 push %ebp + 800fb0: 89 e5 mov %esp,%ebp + 800fb2: 83 e4 f0 and $0xfffffff0,%esp + 800fb5: 83 ec 10 sub $0x10,%esp + cprintf("I am %d, print pgdir.\n", getpid()); + 800fb8: e8 91 f3 ff ff call 80034e + 800fbd: 89 44 24 04 mov %eax,0x4(%esp) + 800fc1: c7 04 24 e0 12 80 00 movl $0x8012e0,(%esp) + 800fc8: e8 53 f1 ff ff call 800120 + print_pgdir(); + 800fcd: e8 8b f3 ff ff call 80035d + cprintf("pgdir pass.\n"); + 800fd2: c7 04 24 f7 12 80 00 movl $0x8012f7,(%esp) + 800fd9: e8 42 f1 ff ff call 800120 + return 0; + 800fde: b8 00 00 00 00 mov $0x0,%eax +} + 800fe3: 89 ec mov %ebp,%esp + 800fe5: 5d pop %ebp + 800fe6: c3 ret diff --git a/labcodes/lab5/obj/user/pgdir.d b/labcodes/lab5/obj/user/pgdir.d new file mode 100644 index 0000000000000000000000000000000000000000..2c84c3bc55b5f39c393b82e1227df99103b0d729 --- /dev/null +++ b/labcodes/lab5/obj/user/pgdir.d @@ -0,0 +1,2 @@ +obj/user/pgdir.o obj/user/pgdir.d: user/pgdir.c libs/stdio.h libs/defs.h \ + libs/stdarg.h user/libs/ulib.h diff --git a/labcodes/lab5/obj/user/pgdir.o b/labcodes/lab5/obj/user/pgdir.o new file mode 100644 index 0000000000000000000000000000000000000000..695e8642dd77688b8a5955f09311ec82f798a417 Binary files /dev/null and b/labcodes/lab5/obj/user/pgdir.o differ diff --git a/labcodes/lab5/obj/user/pgdir.sym b/labcodes/lab5/obj/user/pgdir.sym new file mode 100644 index 0000000000000000000000000000000000000000..ae6b8d6310dbfc5803222f24cb8d991d5dfd3e05 --- /dev/null +++ b/labcodes/lab5/obj/user/pgdir.sym @@ -0,0 +1,66 @@ +00000000 panic.c +00000000 stdio.c +008000c8 cputch +00000000 syscall.c +00800199 syscall +00000000 ulib.c +00000000 umain.c +00000000 hash.c +00000000 printfmt.c +00801100 error_string +008003ad printnum +008004af getuint +008004fe getint +0080094f sprintputch +00000000 rand.c +00802000 next +00000000 string.c +00000000 pgdir.c +00800b53 strcpy +00800329 yield +0080030d waitpid +00800245 sys_yield +00800e65 memmove +00800985 snprintf +00800576 vprintfmt +0080020b sys_fork +00800120 cprintf +0080034e getpid +00800f08 memcpy +008009bb vsnprintf +0080036d umain +002026e0 __STAB_END__ +0080025b sys_kill +002026e1 __STABSTR_BEGIN__ +0080002f __panic +00800ccb strtol +00800b22 strnlen +0080035d print_pgdir +00800339 kill +00800c9b strfind +008002ef wait +00800020 _start +00800a21 rand +00800c14 strncmp +0080028e sys_putc +00800b92 strncpy +00800f57 memcmp +008002e0 fork +00800e23 memset +00800faf main +00800ae0 srand +00800386 hash32 +00800545 printfmt +002035ee __STABSTR_END__ +00800bcb strcmp +008000eb vcprintf +0080007f __warn +00800148 cputs +008002c1 exit +00800221 sys_wait +008001ee sys_exit +00200010 __STAB_BEGIN__ +00800af9 strlen +008002ab sys_pgdir +00800c67 strchr +00800278 sys_getpid diff --git a/labcodes/lab5/obj/user/softint.asm b/labcodes/lab5/obj/user/softint.asm new file mode 100644 index 0000000000000000000000000000000000000000..febfeb0e5302ef4553dd44606f1dec9331fc7014 --- /dev/null +++ b/labcodes/lab5/obj/user/softint.asm @@ -0,0 +1,2319 @@ + +obj/__user_softint.out: file format elf32-i386 + + +Disassembly of section .text: + +00800020 <_start>: +.text +.globl _start +_start: + # set ebp for backtrace + movl $0x0, %ebp + 800020: bd 00 00 00 00 mov $0x0,%ebp + + # move down the esp register + # since it may cause page fault in backtrace + subl $0x20, %esp + 800025: 83 ec 20 sub $0x20,%esp + + # call user-program function + call umain + 800028: e8 40 03 00 00 call 80036d +1: jmp 1b + 80002d: eb fe jmp 80002d <_start+0xd> + +0080002f <__panic>: +#include +#include +#include + +void +__panic(const char *file, int line, const char *fmt, ...) { + 80002f: 55 push %ebp + 800030: 89 e5 mov %esp,%ebp + 800032: 83 ec 28 sub $0x28,%esp + // print the 'message' + va_list ap; + va_start(ap, fmt); + 800035: 8d 45 14 lea 0x14(%ebp),%eax + 800038: 89 45 f4 mov %eax,-0xc(%ebp) + cprintf("user panic at %s:%d:\n ", file, line); + 80003b: 8b 45 0c mov 0xc(%ebp),%eax + 80003e: 89 44 24 08 mov %eax,0x8(%esp) + 800042: 8b 45 08 mov 0x8(%ebp),%eax + 800045: 89 44 24 04 mov %eax,0x4(%esp) + 800049: c7 04 24 e0 0f 80 00 movl $0x800fe0,(%esp) + 800050: e8 cb 00 00 00 call 800120 + vcprintf(fmt, ap); + 800055: 8b 45 f4 mov -0xc(%ebp),%eax + 800058: 89 44 24 04 mov %eax,0x4(%esp) + 80005c: 8b 45 10 mov 0x10(%ebp),%eax + 80005f: 89 04 24 mov %eax,(%esp) + 800062: e8 84 00 00 00 call 8000eb + cprintf("\n"); + 800067: c7 04 24 fa 0f 80 00 movl $0x800ffa,(%esp) + 80006e: e8 ad 00 00 00 call 800120 + va_end(ap); + exit(-E_PANIC); + 800073: c7 04 24 f6 ff ff ff movl $0xfffffff6,(%esp) + 80007a: e8 42 02 00 00 call 8002c1 + +0080007f <__warn>: +} + +void +__warn(const char *file, int line, const char *fmt, ...) { + 80007f: 55 push %ebp + 800080: 89 e5 mov %esp,%ebp + 800082: 83 ec 28 sub $0x28,%esp + va_list ap; + va_start(ap, fmt); + 800085: 8d 45 14 lea 0x14(%ebp),%eax + 800088: 89 45 f4 mov %eax,-0xc(%ebp) + cprintf("user warning at %s:%d:\n ", file, line); + 80008b: 8b 45 0c mov 0xc(%ebp),%eax + 80008e: 89 44 24 08 mov %eax,0x8(%esp) + 800092: 8b 45 08 mov 0x8(%ebp),%eax + 800095: 89 44 24 04 mov %eax,0x4(%esp) + 800099: c7 04 24 fc 0f 80 00 movl $0x800ffc,(%esp) + 8000a0: e8 7b 00 00 00 call 800120 + vcprintf(fmt, ap); + 8000a5: 8b 45 f4 mov -0xc(%ebp),%eax + 8000a8: 89 44 24 04 mov %eax,0x4(%esp) + 8000ac: 8b 45 10 mov 0x10(%ebp),%eax + 8000af: 89 04 24 mov %eax,(%esp) + 8000b2: e8 34 00 00 00 call 8000eb + cprintf("\n"); + 8000b7: c7 04 24 fa 0f 80 00 movl $0x800ffa,(%esp) + 8000be: e8 5d 00 00 00 call 800120 + va_end(ap); +} + 8000c3: 90 nop + 8000c4: 89 ec mov %ebp,%esp + 8000c6: 5d pop %ebp + 8000c7: c3 ret + +008000c8 : +/* * + * cputch - writes a single character @c to stdout, and it will + * increace the value of counter pointed by @cnt. + * */ +static void +cputch(int c, int *cnt) { + 8000c8: 55 push %ebp + 8000c9: 89 e5 mov %esp,%ebp + 8000cb: 83 ec 18 sub $0x18,%esp + sys_putc(c); + 8000ce: 8b 45 08 mov 0x8(%ebp),%eax + 8000d1: 89 04 24 mov %eax,(%esp) + 8000d4: e8 b5 01 00 00 call 80028e + (*cnt) ++; + 8000d9: 8b 45 0c mov 0xc(%ebp),%eax + 8000dc: 8b 00 mov (%eax),%eax + 8000de: 8d 50 01 lea 0x1(%eax),%edx + 8000e1: 8b 45 0c mov 0xc(%ebp),%eax + 8000e4: 89 10 mov %edx,(%eax) +} + 8000e6: 90 nop + 8000e7: 89 ec mov %ebp,%esp + 8000e9: 5d pop %ebp + 8000ea: c3 ret + +008000eb : + * + * Call this function if you are already dealing with a va_list. + * Or you probably want cprintf() instead. + * */ +int +vcprintf(const char *fmt, va_list ap) { + 8000eb: 55 push %ebp + 8000ec: 89 e5 mov %esp,%ebp + 8000ee: 83 ec 28 sub $0x28,%esp + int cnt = 0; + 8000f1: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + vprintfmt((void*)cputch, &cnt, fmt, ap); + 8000f8: 8b 45 0c mov 0xc(%ebp),%eax + 8000fb: 89 44 24 0c mov %eax,0xc(%esp) + 8000ff: 8b 45 08 mov 0x8(%ebp),%eax + 800102: 89 44 24 08 mov %eax,0x8(%esp) + 800106: 8d 45 f4 lea -0xc(%ebp),%eax + 800109: 89 44 24 04 mov %eax,0x4(%esp) + 80010d: c7 04 24 c8 00 80 00 movl $0x8000c8,(%esp) + 800114: e8 5d 04 00 00 call 800576 + return cnt; + 800119: 8b 45 f4 mov -0xc(%ebp),%eax +} + 80011c: 89 ec mov %ebp,%esp + 80011e: 5d pop %ebp + 80011f: c3 ret + +00800120 : + * + * The return value is the number of characters which would be + * written to stdout. + * */ +int +cprintf(const char *fmt, ...) { + 800120: 55 push %ebp + 800121: 89 e5 mov %esp,%ebp + 800123: 83 ec 28 sub $0x28,%esp + va_list ap; + + va_start(ap, fmt); + 800126: 8d 45 0c lea 0xc(%ebp),%eax + 800129: 89 45 f0 mov %eax,-0x10(%ebp) + int cnt = vcprintf(fmt, ap); + 80012c: 8b 45 f0 mov -0x10(%ebp),%eax + 80012f: 89 44 24 04 mov %eax,0x4(%esp) + 800133: 8b 45 08 mov 0x8(%ebp),%eax + 800136: 89 04 24 mov %eax,(%esp) + 800139: e8 ad ff ff ff call 8000eb + 80013e: 89 45 f4 mov %eax,-0xc(%ebp) + va_end(ap); + + return cnt; + 800141: 8b 45 f4 mov -0xc(%ebp),%eax +} + 800144: 89 ec mov %ebp,%esp + 800146: 5d pop %ebp + 800147: c3 ret + +00800148 : +/* * + * cputs- writes the string pointed by @str to stdout and + * appends a newline character. + * */ +int +cputs(const char *str) { + 800148: 55 push %ebp + 800149: 89 e5 mov %esp,%ebp + 80014b: 83 ec 28 sub $0x28,%esp + int cnt = 0; + 80014e: c7 45 f0 00 00 00 00 movl $0x0,-0x10(%ebp) + char c; + while ((c = *str ++) != '\0') { + 800155: eb 13 jmp 80016a + cputch(c, &cnt); + 800157: 0f be 45 f7 movsbl -0x9(%ebp),%eax + 80015b: 8d 55 f0 lea -0x10(%ebp),%edx + 80015e: 89 54 24 04 mov %edx,0x4(%esp) + 800162: 89 04 24 mov %eax,(%esp) + 800165: e8 5e ff ff ff call 8000c8 + while ((c = *str ++) != '\0') { + 80016a: 8b 45 08 mov 0x8(%ebp),%eax + 80016d: 8d 50 01 lea 0x1(%eax),%edx + 800170: 89 55 08 mov %edx,0x8(%ebp) + 800173: 0f b6 00 movzbl (%eax),%eax + 800176: 88 45 f7 mov %al,-0x9(%ebp) + 800179: 80 7d f7 00 cmpb $0x0,-0x9(%ebp) + 80017d: 75 d8 jne 800157 + } + cputch('\n', &cnt); + 80017f: 8d 45 f0 lea -0x10(%ebp),%eax + 800182: 89 44 24 04 mov %eax,0x4(%esp) + 800186: c7 04 24 0a 00 00 00 movl $0xa,(%esp) + 80018d: e8 36 ff ff ff call 8000c8 + return cnt; + 800192: 8b 45 f0 mov -0x10(%ebp),%eax +} + 800195: 89 ec mov %ebp,%esp + 800197: 5d pop %ebp + 800198: c3 ret + +00800199 : +#include + +#define MAX_ARGS 5 + +static inline int +syscall(int num, ...) { + 800199: 55 push %ebp + 80019a: 89 e5 mov %esp,%ebp + 80019c: 57 push %edi + 80019d: 56 push %esi + 80019e: 53 push %ebx + 80019f: 83 ec 20 sub $0x20,%esp + va_list ap; + va_start(ap, num); + 8001a2: 8d 45 0c lea 0xc(%ebp),%eax + 8001a5: 89 45 e8 mov %eax,-0x18(%ebp) + uint32_t a[MAX_ARGS]; + int i, ret; + for (i = 0; i < MAX_ARGS; i ++) { + 8001a8: c7 45 f0 00 00 00 00 movl $0x0,-0x10(%ebp) + 8001af: eb 15 jmp 8001c6 + a[i] = va_arg(ap, uint32_t); + 8001b1: 8b 45 e8 mov -0x18(%ebp),%eax + 8001b4: 8d 50 04 lea 0x4(%eax),%edx + 8001b7: 89 55 e8 mov %edx,-0x18(%ebp) + 8001ba: 8b 10 mov (%eax),%edx + 8001bc: 8b 45 f0 mov -0x10(%ebp),%eax + 8001bf: 89 54 85 d4 mov %edx,-0x2c(%ebp,%eax,4) + for (i = 0; i < MAX_ARGS; i ++) { + 8001c3: ff 45 f0 incl -0x10(%ebp) + 8001c6: 83 7d f0 04 cmpl $0x4,-0x10(%ebp) + 8001ca: 7e e5 jle 8001b1 + asm volatile ( + "int %1;" + : "=a" (ret) + : "i" (T_SYSCALL), + "a" (num), + "d" (a[0]), + 8001cc: 8b 55 d4 mov -0x2c(%ebp),%edx + "c" (a[1]), + 8001cf: 8b 4d d8 mov -0x28(%ebp),%ecx + "b" (a[2]), + 8001d2: 8b 5d dc mov -0x24(%ebp),%ebx + "D" (a[3]), + 8001d5: 8b 7d e0 mov -0x20(%ebp),%edi + "S" (a[4]) + 8001d8: 8b 75 e4 mov -0x1c(%ebp),%esi + asm volatile ( + 8001db: 8b 45 08 mov 0x8(%ebp),%eax + 8001de: cd 80 int $0x80 + 8001e0: 89 45 ec mov %eax,-0x14(%ebp) + : "cc", "memory"); + return ret; + 8001e3: 8b 45 ec mov -0x14(%ebp),%eax +} + 8001e6: 83 c4 20 add $0x20,%esp + 8001e9: 5b pop %ebx + 8001ea: 5e pop %esi + 8001eb: 5f pop %edi + 8001ec: 5d pop %ebp + 8001ed: c3 ret + +008001ee : + +int +sys_exit(int error_code) { + 8001ee: 55 push %ebp + 8001ef: 89 e5 mov %esp,%ebp + 8001f1: 83 ec 08 sub $0x8,%esp + return syscall(SYS_exit, error_code); + 8001f4: 8b 45 08 mov 0x8(%ebp),%eax + 8001f7: 89 44 24 04 mov %eax,0x4(%esp) + 8001fb: c7 04 24 01 00 00 00 movl $0x1,(%esp) + 800202: e8 92 ff ff ff call 800199 +} + 800207: 89 ec mov %ebp,%esp + 800209: 5d pop %ebp + 80020a: c3 ret + +0080020b : + +int +sys_fork(void) { + 80020b: 55 push %ebp + 80020c: 89 e5 mov %esp,%ebp + 80020e: 83 ec 04 sub $0x4,%esp + return syscall(SYS_fork); + 800211: c7 04 24 02 00 00 00 movl $0x2,(%esp) + 800218: e8 7c ff ff ff call 800199 +} + 80021d: 89 ec mov %ebp,%esp + 80021f: 5d pop %ebp + 800220: c3 ret + +00800221 : + +int +sys_wait(int pid, int *store) { + 800221: 55 push %ebp + 800222: 89 e5 mov %esp,%ebp + 800224: 83 ec 0c sub $0xc,%esp + return syscall(SYS_wait, pid, store); + 800227: 8b 45 0c mov 0xc(%ebp),%eax + 80022a: 89 44 24 08 mov %eax,0x8(%esp) + 80022e: 8b 45 08 mov 0x8(%ebp),%eax + 800231: 89 44 24 04 mov %eax,0x4(%esp) + 800235: c7 04 24 03 00 00 00 movl $0x3,(%esp) + 80023c: e8 58 ff ff ff call 800199 +} + 800241: 89 ec mov %ebp,%esp + 800243: 5d pop %ebp + 800244: c3 ret + +00800245 : + +int +sys_yield(void) { + 800245: 55 push %ebp + 800246: 89 e5 mov %esp,%ebp + 800248: 83 ec 04 sub $0x4,%esp + return syscall(SYS_yield); + 80024b: c7 04 24 0a 00 00 00 movl $0xa,(%esp) + 800252: e8 42 ff ff ff call 800199 +} + 800257: 89 ec mov %ebp,%esp + 800259: 5d pop %ebp + 80025a: c3 ret + +0080025b : + +int +sys_kill(int pid) { + 80025b: 55 push %ebp + 80025c: 89 e5 mov %esp,%ebp + 80025e: 83 ec 08 sub $0x8,%esp + return syscall(SYS_kill, pid); + 800261: 8b 45 08 mov 0x8(%ebp),%eax + 800264: 89 44 24 04 mov %eax,0x4(%esp) + 800268: c7 04 24 0c 00 00 00 movl $0xc,(%esp) + 80026f: e8 25 ff ff ff call 800199 +} + 800274: 89 ec mov %ebp,%esp + 800276: 5d pop %ebp + 800277: c3 ret + +00800278 : + +int +sys_getpid(void) { + 800278: 55 push %ebp + 800279: 89 e5 mov %esp,%ebp + 80027b: 83 ec 04 sub $0x4,%esp + return syscall(SYS_getpid); + 80027e: c7 04 24 12 00 00 00 movl $0x12,(%esp) + 800285: e8 0f ff ff ff call 800199 +} + 80028a: 89 ec mov %ebp,%esp + 80028c: 5d pop %ebp + 80028d: c3 ret + +0080028e : + +int +sys_putc(int c) { + 80028e: 55 push %ebp + 80028f: 89 e5 mov %esp,%ebp + 800291: 83 ec 08 sub $0x8,%esp + return syscall(SYS_putc, c); + 800294: 8b 45 08 mov 0x8(%ebp),%eax + 800297: 89 44 24 04 mov %eax,0x4(%esp) + 80029b: c7 04 24 1e 00 00 00 movl $0x1e,(%esp) + 8002a2: e8 f2 fe ff ff call 800199 +} + 8002a7: 89 ec mov %ebp,%esp + 8002a9: 5d pop %ebp + 8002aa: c3 ret + +008002ab : + +int +sys_pgdir(void) { + 8002ab: 55 push %ebp + 8002ac: 89 e5 mov %esp,%ebp + 8002ae: 83 ec 04 sub $0x4,%esp + return syscall(SYS_pgdir); + 8002b1: c7 04 24 1f 00 00 00 movl $0x1f,(%esp) + 8002b8: e8 dc fe ff ff call 800199 +} + 8002bd: 89 ec mov %ebp,%esp + 8002bf: 5d pop %ebp + 8002c0: c3 ret + +008002c1 : +#include +#include +#include + +void +exit(int error_code) { + 8002c1: 55 push %ebp + 8002c2: 89 e5 mov %esp,%ebp + 8002c4: 83 ec 18 sub $0x18,%esp + sys_exit(error_code); + 8002c7: 8b 45 08 mov 0x8(%ebp),%eax + 8002ca: 89 04 24 mov %eax,(%esp) + 8002cd: e8 1c ff ff ff call 8001ee + cprintf("BUG: exit failed.\n"); + 8002d2: c7 04 24 18 10 80 00 movl $0x801018,(%esp) + 8002d9: e8 42 fe ff ff call 800120 + while (1); + 8002de: eb fe jmp 8002de + +008002e0 : +} + +int +fork(void) { + 8002e0: 55 push %ebp + 8002e1: 89 e5 mov %esp,%ebp + 8002e3: 83 ec 08 sub $0x8,%esp + return sys_fork(); + 8002e6: e8 20 ff ff ff call 80020b +} + 8002eb: 89 ec mov %ebp,%esp + 8002ed: 5d pop %ebp + 8002ee: c3 ret + +008002ef : + +int +wait(void) { + 8002ef: 55 push %ebp + 8002f0: 89 e5 mov %esp,%ebp + 8002f2: 83 ec 18 sub $0x18,%esp + return sys_wait(0, NULL); + 8002f5: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) + 8002fc: 00 + 8002fd: c7 04 24 00 00 00 00 movl $0x0,(%esp) + 800304: e8 18 ff ff ff call 800221 +} + 800309: 89 ec mov %ebp,%esp + 80030b: 5d pop %ebp + 80030c: c3 ret + +0080030d : + +int +waitpid(int pid, int *store) { + 80030d: 55 push %ebp + 80030e: 89 e5 mov %esp,%ebp + 800310: 83 ec 18 sub $0x18,%esp + return sys_wait(pid, store); + 800313: 8b 45 0c mov 0xc(%ebp),%eax + 800316: 89 44 24 04 mov %eax,0x4(%esp) + 80031a: 8b 45 08 mov 0x8(%ebp),%eax + 80031d: 89 04 24 mov %eax,(%esp) + 800320: e8 fc fe ff ff call 800221 +} + 800325: 89 ec mov %ebp,%esp + 800327: 5d pop %ebp + 800328: c3 ret + +00800329 : + +void +yield(void) { + 800329: 55 push %ebp + 80032a: 89 e5 mov %esp,%ebp + 80032c: 83 ec 08 sub $0x8,%esp + sys_yield(); + 80032f: e8 11 ff ff ff call 800245 +} + 800334: 90 nop + 800335: 89 ec mov %ebp,%esp + 800337: 5d pop %ebp + 800338: c3 ret + +00800339 : + +int +kill(int pid) { + 800339: 55 push %ebp + 80033a: 89 e5 mov %esp,%ebp + 80033c: 83 ec 18 sub $0x18,%esp + return sys_kill(pid); + 80033f: 8b 45 08 mov 0x8(%ebp),%eax + 800342: 89 04 24 mov %eax,(%esp) + 800345: e8 11 ff ff ff call 80025b +} + 80034a: 89 ec mov %ebp,%esp + 80034c: 5d pop %ebp + 80034d: c3 ret + +0080034e : + +int +getpid(void) { + 80034e: 55 push %ebp + 80034f: 89 e5 mov %esp,%ebp + 800351: 83 ec 08 sub $0x8,%esp + return sys_getpid(); + 800354: e8 1f ff ff ff call 800278 +} + 800359: 89 ec mov %ebp,%esp + 80035b: 5d pop %ebp + 80035c: c3 ret + +0080035d : + +//print_pgdir - print the PDT&PT +void +print_pgdir(void) { + 80035d: 55 push %ebp + 80035e: 89 e5 mov %esp,%ebp + 800360: 83 ec 08 sub $0x8,%esp + sys_pgdir(); + 800363: e8 43 ff ff ff call 8002ab +} + 800368: 90 nop + 800369: 89 ec mov %ebp,%esp + 80036b: 5d pop %ebp + 80036c: c3 ret + +0080036d : +#include + +int main(void); + +void +umain(void) { + 80036d: 55 push %ebp + 80036e: 89 e5 mov %esp,%ebp + 800370: 83 ec 28 sub $0x28,%esp + int ret = main(); + 800373: e8 37 0c 00 00 call 800faf
+ 800378: 89 45 f4 mov %eax,-0xc(%ebp) + exit(ret); + 80037b: 8b 45 f4 mov -0xc(%ebp),%eax + 80037e: 89 04 24 mov %eax,(%esp) + 800381: e8 3b ff ff ff call 8002c1 + +00800386 : + * @bits: the number of bits in a return value + * + * High bits are more random, so we use them. + * */ +uint32_t +hash32(uint32_t val, unsigned int bits) { + 800386: 55 push %ebp + 800387: 89 e5 mov %esp,%ebp + 800389: 83 ec 10 sub $0x10,%esp + uint32_t hash = val * GOLDEN_RATIO_PRIME_32; + 80038c: 8b 45 08 mov 0x8(%ebp),%eax + 80038f: 69 c0 01 00 37 9e imul $0x9e370001,%eax,%eax + 800395: 89 45 fc mov %eax,-0x4(%ebp) + return (hash >> (32 - bits)); + 800398: b8 20 00 00 00 mov $0x20,%eax + 80039d: 2b 45 0c sub 0xc(%ebp),%eax + 8003a0: 8b 55 fc mov -0x4(%ebp),%edx + 8003a3: 88 c1 mov %al,%cl + 8003a5: d3 ea shr %cl,%edx + 8003a7: 89 d0 mov %edx,%eax +} + 8003a9: 89 ec mov %ebp,%esp + 8003ab: 5d pop %ebp + 8003ac: c3 ret + +008003ad : + * @width: maximum number of digits, if the actual width is less than @width, use @padc instead + * @padc: character that padded on the left if the actual width is less than @width + * */ +static void +printnum(void (*putch)(int, void*), void *putdat, + unsigned long long num, unsigned base, int width, int padc) { + 8003ad: 55 push %ebp + 8003ae: 89 e5 mov %esp,%ebp + 8003b0: 83 ec 58 sub $0x58,%esp + 8003b3: 8b 45 10 mov 0x10(%ebp),%eax + 8003b6: 89 45 d0 mov %eax,-0x30(%ebp) + 8003b9: 8b 45 14 mov 0x14(%ebp),%eax + 8003bc: 89 45 d4 mov %eax,-0x2c(%ebp) + unsigned long long result = num; + 8003bf: 8b 45 d0 mov -0x30(%ebp),%eax + 8003c2: 8b 55 d4 mov -0x2c(%ebp),%edx + 8003c5: 89 45 e8 mov %eax,-0x18(%ebp) + 8003c8: 89 55 ec mov %edx,-0x14(%ebp) + unsigned mod = do_div(result, base); + 8003cb: 8b 45 18 mov 0x18(%ebp),%eax + 8003ce: 89 45 e4 mov %eax,-0x1c(%ebp) + 8003d1: 8b 45 e8 mov -0x18(%ebp),%eax + 8003d4: 8b 55 ec mov -0x14(%ebp),%edx + 8003d7: 89 45 e0 mov %eax,-0x20(%ebp) + 8003da: 89 55 f0 mov %edx,-0x10(%ebp) + 8003dd: 8b 45 f0 mov -0x10(%ebp),%eax + 8003e0: 89 45 f4 mov %eax,-0xc(%ebp) + 8003e3: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) + 8003e7: 74 1c je 800405 + 8003e9: 8b 45 f0 mov -0x10(%ebp),%eax + 8003ec: ba 00 00 00 00 mov $0x0,%edx + 8003f1: f7 75 e4 divl -0x1c(%ebp) + 8003f4: 89 55 f4 mov %edx,-0xc(%ebp) + 8003f7: 8b 45 f0 mov -0x10(%ebp),%eax + 8003fa: ba 00 00 00 00 mov $0x0,%edx + 8003ff: f7 75 e4 divl -0x1c(%ebp) + 800402: 89 45 f0 mov %eax,-0x10(%ebp) + 800405: 8b 45 e0 mov -0x20(%ebp),%eax + 800408: 8b 55 f4 mov -0xc(%ebp),%edx + 80040b: f7 75 e4 divl -0x1c(%ebp) + 80040e: 89 45 e0 mov %eax,-0x20(%ebp) + 800411: 89 55 dc mov %edx,-0x24(%ebp) + 800414: 8b 45 e0 mov -0x20(%ebp),%eax + 800417: 8b 55 f0 mov -0x10(%ebp),%edx + 80041a: 89 45 e8 mov %eax,-0x18(%ebp) + 80041d: 89 55 ec mov %edx,-0x14(%ebp) + 800420: 8b 45 dc mov -0x24(%ebp),%eax + 800423: 89 45 d8 mov %eax,-0x28(%ebp) + + // first recursively print all preceding (more significant) digits + if (num >= base) { + 800426: 8b 45 18 mov 0x18(%ebp),%eax + 800429: ba 00 00 00 00 mov $0x0,%edx + 80042e: 8b 4d d4 mov -0x2c(%ebp),%ecx + 800431: 39 45 d0 cmp %eax,-0x30(%ebp) + 800434: 19 d1 sbb %edx,%ecx + 800436: 72 4c jb 800484 + printnum(putch, putdat, result, base, width - 1, padc); + 800438: 8b 45 1c mov 0x1c(%ebp),%eax + 80043b: 8d 50 ff lea -0x1(%eax),%edx + 80043e: 8b 45 20 mov 0x20(%ebp),%eax + 800441: 89 44 24 18 mov %eax,0x18(%esp) + 800445: 89 54 24 14 mov %edx,0x14(%esp) + 800449: 8b 45 18 mov 0x18(%ebp),%eax + 80044c: 89 44 24 10 mov %eax,0x10(%esp) + 800450: 8b 45 e8 mov -0x18(%ebp),%eax + 800453: 8b 55 ec mov -0x14(%ebp),%edx + 800456: 89 44 24 08 mov %eax,0x8(%esp) + 80045a: 89 54 24 0c mov %edx,0xc(%esp) + 80045e: 8b 45 0c mov 0xc(%ebp),%eax + 800461: 89 44 24 04 mov %eax,0x4(%esp) + 800465: 8b 45 08 mov 0x8(%ebp),%eax + 800468: 89 04 24 mov %eax,(%esp) + 80046b: e8 3d ff ff ff call 8003ad + 800470: eb 1b jmp 80048d + } else { + // print any needed pad characters before first digit + while (-- width > 0) + putch(padc, putdat); + 800472: 8b 45 0c mov 0xc(%ebp),%eax + 800475: 89 44 24 04 mov %eax,0x4(%esp) + 800479: 8b 45 20 mov 0x20(%ebp),%eax + 80047c: 89 04 24 mov %eax,(%esp) + 80047f: 8b 45 08 mov 0x8(%ebp),%eax + 800482: ff d0 call *%eax + while (-- width > 0) + 800484: ff 4d 1c decl 0x1c(%ebp) + 800487: 83 7d 1c 00 cmpl $0x0,0x1c(%ebp) + 80048b: 7f e5 jg 800472 + } + // then print this (the least significant) digit + putch("0123456789abcdef"[mod], putdat); + 80048d: 8b 45 d8 mov -0x28(%ebp),%eax + 800490: 05 44 11 80 00 add $0x801144,%eax + 800495: 0f b6 00 movzbl (%eax),%eax + 800498: 0f be c0 movsbl %al,%eax + 80049b: 8b 55 0c mov 0xc(%ebp),%edx + 80049e: 89 54 24 04 mov %edx,0x4(%esp) + 8004a2: 89 04 24 mov %eax,(%esp) + 8004a5: 8b 45 08 mov 0x8(%ebp),%eax + 8004a8: ff d0 call *%eax +} + 8004aa: 90 nop + 8004ab: 89 ec mov %ebp,%esp + 8004ad: 5d pop %ebp + 8004ae: c3 ret + +008004af : + * getuint - get an unsigned int of various possible sizes from a varargs list + * @ap: a varargs list pointer + * @lflag: determines the size of the vararg that @ap points to + * */ +static unsigned long long +getuint(va_list *ap, int lflag) { + 8004af: 55 push %ebp + 8004b0: 89 e5 mov %esp,%ebp + if (lflag >= 2) { + 8004b2: 83 7d 0c 01 cmpl $0x1,0xc(%ebp) + 8004b6: 7e 14 jle 8004cc + return va_arg(*ap, unsigned long long); + 8004b8: 8b 45 08 mov 0x8(%ebp),%eax + 8004bb: 8b 00 mov (%eax),%eax + 8004bd: 8d 48 08 lea 0x8(%eax),%ecx + 8004c0: 8b 55 08 mov 0x8(%ebp),%edx + 8004c3: 89 0a mov %ecx,(%edx) + 8004c5: 8b 50 04 mov 0x4(%eax),%edx + 8004c8: 8b 00 mov (%eax),%eax + 8004ca: eb 30 jmp 8004fc + } + else if (lflag) { + 8004cc: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) + 8004d0: 74 16 je 8004e8 + return va_arg(*ap, unsigned long); + 8004d2: 8b 45 08 mov 0x8(%ebp),%eax + 8004d5: 8b 00 mov (%eax),%eax + 8004d7: 8d 48 04 lea 0x4(%eax),%ecx + 8004da: 8b 55 08 mov 0x8(%ebp),%edx + 8004dd: 89 0a mov %ecx,(%edx) + 8004df: 8b 00 mov (%eax),%eax + 8004e1: ba 00 00 00 00 mov $0x0,%edx + 8004e6: eb 14 jmp 8004fc + } + else { + return va_arg(*ap, unsigned int); + 8004e8: 8b 45 08 mov 0x8(%ebp),%eax + 8004eb: 8b 00 mov (%eax),%eax + 8004ed: 8d 48 04 lea 0x4(%eax),%ecx + 8004f0: 8b 55 08 mov 0x8(%ebp),%edx + 8004f3: 89 0a mov %ecx,(%edx) + 8004f5: 8b 00 mov (%eax),%eax + 8004f7: ba 00 00 00 00 mov $0x0,%edx + } +} + 8004fc: 5d pop %ebp + 8004fd: c3 ret + +008004fe : + * getint - same as getuint but signed, we can't use getuint because of sign extension + * @ap: a varargs list pointer + * @lflag: determines the size of the vararg that @ap points to + * */ +static long long +getint(va_list *ap, int lflag) { + 8004fe: 55 push %ebp + 8004ff: 89 e5 mov %esp,%ebp + if (lflag >= 2) { + 800501: 83 7d 0c 01 cmpl $0x1,0xc(%ebp) + 800505: 7e 14 jle 80051b + return va_arg(*ap, long long); + 800507: 8b 45 08 mov 0x8(%ebp),%eax + 80050a: 8b 00 mov (%eax),%eax + 80050c: 8d 48 08 lea 0x8(%eax),%ecx + 80050f: 8b 55 08 mov 0x8(%ebp),%edx + 800512: 89 0a mov %ecx,(%edx) + 800514: 8b 50 04 mov 0x4(%eax),%edx + 800517: 8b 00 mov (%eax),%eax + 800519: eb 28 jmp 800543 + } + else if (lflag) { + 80051b: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) + 80051f: 74 12 je 800533 + return va_arg(*ap, long); + 800521: 8b 45 08 mov 0x8(%ebp),%eax + 800524: 8b 00 mov (%eax),%eax + 800526: 8d 48 04 lea 0x4(%eax),%ecx + 800529: 8b 55 08 mov 0x8(%ebp),%edx + 80052c: 89 0a mov %ecx,(%edx) + 80052e: 8b 00 mov (%eax),%eax + 800530: 99 cltd + 800531: eb 10 jmp 800543 + } + else { + return va_arg(*ap, int); + 800533: 8b 45 08 mov 0x8(%ebp),%eax + 800536: 8b 00 mov (%eax),%eax + 800538: 8d 48 04 lea 0x4(%eax),%ecx + 80053b: 8b 55 08 mov 0x8(%ebp),%edx + 80053e: 89 0a mov %ecx,(%edx) + 800540: 8b 00 mov (%eax),%eax + 800542: 99 cltd + } +} + 800543: 5d pop %ebp + 800544: c3 ret + +00800545 : + * @putch: specified putch function, print a single character + * @putdat: used by @putch function + * @fmt: the format string to use + * */ +void +printfmt(void (*putch)(int, void*), void *putdat, const char *fmt, ...) { + 800545: 55 push %ebp + 800546: 89 e5 mov %esp,%ebp + 800548: 83 ec 28 sub $0x28,%esp + va_list ap; + + va_start(ap, fmt); + 80054b: 8d 45 14 lea 0x14(%ebp),%eax + 80054e: 89 45 f4 mov %eax,-0xc(%ebp) + vprintfmt(putch, putdat, fmt, ap); + 800551: 8b 45 f4 mov -0xc(%ebp),%eax + 800554: 89 44 24 0c mov %eax,0xc(%esp) + 800558: 8b 45 10 mov 0x10(%ebp),%eax + 80055b: 89 44 24 08 mov %eax,0x8(%esp) + 80055f: 8b 45 0c mov 0xc(%ebp),%eax + 800562: 89 44 24 04 mov %eax,0x4(%esp) + 800566: 8b 45 08 mov 0x8(%ebp),%eax + 800569: 89 04 24 mov %eax,(%esp) + 80056c: e8 05 00 00 00 call 800576 + va_end(ap); +} + 800571: 90 nop + 800572: 89 ec mov %ebp,%esp + 800574: 5d pop %ebp + 800575: c3 ret + +00800576 : + * + * Call this function if you are already dealing with a va_list. + * Or you probably want printfmt() instead. + * */ +void +vprintfmt(void (*putch)(int, void*), void *putdat, const char *fmt, va_list ap) { + 800576: 55 push %ebp + 800577: 89 e5 mov %esp,%ebp + 800579: 56 push %esi + 80057a: 53 push %ebx + 80057b: 83 ec 40 sub $0x40,%esp + register int ch, err; + unsigned long long num; + int base, width, precision, lflag, altflag; + + while (1) { + while ((ch = *(unsigned char *)fmt ++) != '%') { + 80057e: eb 17 jmp 800597 + if (ch == '\0') { + 800580: 85 db test %ebx,%ebx + 800582: 0f 84 bf 03 00 00 je 800947 + return; + } + putch(ch, putdat); + 800588: 8b 45 0c mov 0xc(%ebp),%eax + 80058b: 89 44 24 04 mov %eax,0x4(%esp) + 80058f: 89 1c 24 mov %ebx,(%esp) + 800592: 8b 45 08 mov 0x8(%ebp),%eax + 800595: ff d0 call *%eax + while ((ch = *(unsigned char *)fmt ++) != '%') { + 800597: 8b 45 10 mov 0x10(%ebp),%eax + 80059a: 8d 50 01 lea 0x1(%eax),%edx + 80059d: 89 55 10 mov %edx,0x10(%ebp) + 8005a0: 0f b6 00 movzbl (%eax),%eax + 8005a3: 0f b6 d8 movzbl %al,%ebx + 8005a6: 83 fb 25 cmp $0x25,%ebx + 8005a9: 75 d5 jne 800580 + } + + // Process a %-escape sequence + char padc = ' '; + 8005ab: c6 45 db 20 movb $0x20,-0x25(%ebp) + width = precision = -1; + 8005af: c7 45 e4 ff ff ff ff movl $0xffffffff,-0x1c(%ebp) + 8005b6: 8b 45 e4 mov -0x1c(%ebp),%eax + 8005b9: 89 45 e8 mov %eax,-0x18(%ebp) + lflag = altflag = 0; + 8005bc: c7 45 dc 00 00 00 00 movl $0x0,-0x24(%ebp) + 8005c3: 8b 45 dc mov -0x24(%ebp),%eax + 8005c6: 89 45 e0 mov %eax,-0x20(%ebp) + + reswitch: + switch (ch = *(unsigned char *)fmt ++) { + 8005c9: 8b 45 10 mov 0x10(%ebp),%eax + 8005cc: 8d 50 01 lea 0x1(%eax),%edx + 8005cf: 89 55 10 mov %edx,0x10(%ebp) + 8005d2: 0f b6 00 movzbl (%eax),%eax + 8005d5: 0f b6 d8 movzbl %al,%ebx + 8005d8: 8d 43 dd lea -0x23(%ebx),%eax + 8005db: 83 f8 55 cmp $0x55,%eax + 8005de: 0f 87 37 03 00 00 ja 80091b + 8005e4: 8b 04 85 68 11 80 00 mov 0x801168(,%eax,4),%eax + 8005eb: ff e0 jmp *%eax + + // flag to pad on the right + case '-': + padc = '-'; + 8005ed: c6 45 db 2d movb $0x2d,-0x25(%ebp) + goto reswitch; + 8005f1: eb d6 jmp 8005c9 + + // flag to pad with 0's instead of spaces + case '0': + padc = '0'; + 8005f3: c6 45 db 30 movb $0x30,-0x25(%ebp) + goto reswitch; + 8005f7: eb d0 jmp 8005c9 + + // width field + case '1' ... '9': + for (precision = 0; ; ++ fmt) { + 8005f9: c7 45 e4 00 00 00 00 movl $0x0,-0x1c(%ebp) + precision = precision * 10 + ch - '0'; + 800600: 8b 55 e4 mov -0x1c(%ebp),%edx + 800603: 89 d0 mov %edx,%eax + 800605: c1 e0 02 shl $0x2,%eax + 800608: 01 d0 add %edx,%eax + 80060a: 01 c0 add %eax,%eax + 80060c: 01 d8 add %ebx,%eax + 80060e: 83 e8 30 sub $0x30,%eax + 800611: 89 45 e4 mov %eax,-0x1c(%ebp) + ch = *fmt; + 800614: 8b 45 10 mov 0x10(%ebp),%eax + 800617: 0f b6 00 movzbl (%eax),%eax + 80061a: 0f be d8 movsbl %al,%ebx + if (ch < '0' || ch > '9') { + 80061d: 83 fb 2f cmp $0x2f,%ebx + 800620: 7e 38 jle 80065a + 800622: 83 fb 39 cmp $0x39,%ebx + 800625: 7f 33 jg 80065a + for (precision = 0; ; ++ fmt) { + 800627: ff 45 10 incl 0x10(%ebp) + precision = precision * 10 + ch - '0'; + 80062a: eb d4 jmp 800600 + } + } + goto process_precision; + + case '*': + precision = va_arg(ap, int); + 80062c: 8b 45 14 mov 0x14(%ebp),%eax + 80062f: 8d 50 04 lea 0x4(%eax),%edx + 800632: 89 55 14 mov %edx,0x14(%ebp) + 800635: 8b 00 mov (%eax),%eax + 800637: 89 45 e4 mov %eax,-0x1c(%ebp) + goto process_precision; + 80063a: eb 1f jmp 80065b + + case '.': + if (width < 0) + 80063c: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 800640: 79 87 jns 8005c9 + width = 0; + 800642: c7 45 e8 00 00 00 00 movl $0x0,-0x18(%ebp) + goto reswitch; + 800649: e9 7b ff ff ff jmp 8005c9 + + case '#': + altflag = 1; + 80064e: c7 45 dc 01 00 00 00 movl $0x1,-0x24(%ebp) + goto reswitch; + 800655: e9 6f ff ff ff jmp 8005c9 + goto process_precision; + 80065a: 90 nop + + process_precision: + if (width < 0) + 80065b: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 80065f: 0f 89 64 ff ff ff jns 8005c9 + width = precision, precision = -1; + 800665: 8b 45 e4 mov -0x1c(%ebp),%eax + 800668: 89 45 e8 mov %eax,-0x18(%ebp) + 80066b: c7 45 e4 ff ff ff ff movl $0xffffffff,-0x1c(%ebp) + goto reswitch; + 800672: e9 52 ff ff ff jmp 8005c9 + + // long flag (doubled for long long) + case 'l': + lflag ++; + 800677: ff 45 e0 incl -0x20(%ebp) + goto reswitch; + 80067a: e9 4a ff ff ff jmp 8005c9 + + // character + case 'c': + putch(va_arg(ap, int), putdat); + 80067f: 8b 45 14 mov 0x14(%ebp),%eax + 800682: 8d 50 04 lea 0x4(%eax),%edx + 800685: 89 55 14 mov %edx,0x14(%ebp) + 800688: 8b 00 mov (%eax),%eax + 80068a: 8b 55 0c mov 0xc(%ebp),%edx + 80068d: 89 54 24 04 mov %edx,0x4(%esp) + 800691: 89 04 24 mov %eax,(%esp) + 800694: 8b 45 08 mov 0x8(%ebp),%eax + 800697: ff d0 call *%eax + break; + 800699: e9 a4 02 00 00 jmp 800942 + + // error message + case 'e': + err = va_arg(ap, int); + 80069e: 8b 45 14 mov 0x14(%ebp),%eax + 8006a1: 8d 50 04 lea 0x4(%eax),%edx + 8006a4: 89 55 14 mov %edx,0x14(%ebp) + 8006a7: 8b 18 mov (%eax),%ebx + if (err < 0) { + 8006a9: 85 db test %ebx,%ebx + 8006ab: 79 02 jns 8006af + err = -err; + 8006ad: f7 db neg %ebx + } + if (err > MAXERROR || (p = error_string[err]) == NULL) { + 8006af: 83 fb 18 cmp $0x18,%ebx + 8006b2: 7f 0b jg 8006bf + 8006b4: 8b 34 9d e0 10 80 00 mov 0x8010e0(,%ebx,4),%esi + 8006bb: 85 f6 test %esi,%esi + 8006bd: 75 23 jne 8006e2 + printfmt(putch, putdat, "error %d", err); + 8006bf: 89 5c 24 0c mov %ebx,0xc(%esp) + 8006c3: c7 44 24 08 55 11 80 movl $0x801155,0x8(%esp) + 8006ca: 00 + 8006cb: 8b 45 0c mov 0xc(%ebp),%eax + 8006ce: 89 44 24 04 mov %eax,0x4(%esp) + 8006d2: 8b 45 08 mov 0x8(%ebp),%eax + 8006d5: 89 04 24 mov %eax,(%esp) + 8006d8: e8 68 fe ff ff call 800545 + } + else { + printfmt(putch, putdat, "%s", p); + } + break; + 8006dd: e9 60 02 00 00 jmp 800942 + printfmt(putch, putdat, "%s", p); + 8006e2: 89 74 24 0c mov %esi,0xc(%esp) + 8006e6: c7 44 24 08 5e 11 80 movl $0x80115e,0x8(%esp) + 8006ed: 00 + 8006ee: 8b 45 0c mov 0xc(%ebp),%eax + 8006f1: 89 44 24 04 mov %eax,0x4(%esp) + 8006f5: 8b 45 08 mov 0x8(%ebp),%eax + 8006f8: 89 04 24 mov %eax,(%esp) + 8006fb: e8 45 fe ff ff call 800545 + break; + 800700: e9 3d 02 00 00 jmp 800942 + + // string + case 's': + if ((p = va_arg(ap, char *)) == NULL) { + 800705: 8b 45 14 mov 0x14(%ebp),%eax + 800708: 8d 50 04 lea 0x4(%eax),%edx + 80070b: 89 55 14 mov %edx,0x14(%ebp) + 80070e: 8b 30 mov (%eax),%esi + 800710: 85 f6 test %esi,%esi + 800712: 75 05 jne 800719 + p = "(null)"; + 800714: be 61 11 80 00 mov $0x801161,%esi + } + if (width > 0 && padc != '-') { + 800719: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 80071d: 7e 76 jle 800795 + 80071f: 80 7d db 2d cmpb $0x2d,-0x25(%ebp) + 800723: 74 70 je 800795 + for (width -= strnlen(p, precision); width > 0; width --) { + 800725: 8b 45 e4 mov -0x1c(%ebp),%eax + 800728: 89 44 24 04 mov %eax,0x4(%esp) + 80072c: 89 34 24 mov %esi,(%esp) + 80072f: e8 ee 03 00 00 call 800b22 + 800734: 89 c2 mov %eax,%edx + 800736: 8b 45 e8 mov -0x18(%ebp),%eax + 800739: 29 d0 sub %edx,%eax + 80073b: 89 45 e8 mov %eax,-0x18(%ebp) + 80073e: eb 16 jmp 800756 + putch(padc, putdat); + 800740: 0f be 45 db movsbl -0x25(%ebp),%eax + 800744: 8b 55 0c mov 0xc(%ebp),%edx + 800747: 89 54 24 04 mov %edx,0x4(%esp) + 80074b: 89 04 24 mov %eax,(%esp) + 80074e: 8b 45 08 mov 0x8(%ebp),%eax + 800751: ff d0 call *%eax + for (width -= strnlen(p, precision); width > 0; width --) { + 800753: ff 4d e8 decl -0x18(%ebp) + 800756: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 80075a: 7f e4 jg 800740 + } + } + for (; (ch = *p ++) != '\0' && (precision < 0 || -- precision >= 0); width --) { + 80075c: eb 37 jmp 800795 + if (altflag && (ch < ' ' || ch > '~')) { + 80075e: 83 7d dc 00 cmpl $0x0,-0x24(%ebp) + 800762: 74 1f je 800783 + 800764: 83 fb 1f cmp $0x1f,%ebx + 800767: 7e 05 jle 80076e + 800769: 83 fb 7e cmp $0x7e,%ebx + 80076c: 7e 15 jle 800783 + putch('?', putdat); + 80076e: 8b 45 0c mov 0xc(%ebp),%eax + 800771: 89 44 24 04 mov %eax,0x4(%esp) + 800775: c7 04 24 3f 00 00 00 movl $0x3f,(%esp) + 80077c: 8b 45 08 mov 0x8(%ebp),%eax + 80077f: ff d0 call *%eax + 800781: eb 0f jmp 800792 + } + else { + putch(ch, putdat); + 800783: 8b 45 0c mov 0xc(%ebp),%eax + 800786: 89 44 24 04 mov %eax,0x4(%esp) + 80078a: 89 1c 24 mov %ebx,(%esp) + 80078d: 8b 45 08 mov 0x8(%ebp),%eax + 800790: ff d0 call *%eax + for (; (ch = *p ++) != '\0' && (precision < 0 || -- precision >= 0); width --) { + 800792: ff 4d e8 decl -0x18(%ebp) + 800795: 89 f0 mov %esi,%eax + 800797: 8d 70 01 lea 0x1(%eax),%esi + 80079a: 0f b6 00 movzbl (%eax),%eax + 80079d: 0f be d8 movsbl %al,%ebx + 8007a0: 85 db test %ebx,%ebx + 8007a2: 74 27 je 8007cb + 8007a4: 83 7d e4 00 cmpl $0x0,-0x1c(%ebp) + 8007a8: 78 b4 js 80075e + 8007aa: ff 4d e4 decl -0x1c(%ebp) + 8007ad: 83 7d e4 00 cmpl $0x0,-0x1c(%ebp) + 8007b1: 79 ab jns 80075e + } + } + for (; width > 0; width --) { + 8007b3: eb 16 jmp 8007cb + putch(' ', putdat); + 8007b5: 8b 45 0c mov 0xc(%ebp),%eax + 8007b8: 89 44 24 04 mov %eax,0x4(%esp) + 8007bc: c7 04 24 20 00 00 00 movl $0x20,(%esp) + 8007c3: 8b 45 08 mov 0x8(%ebp),%eax + 8007c6: ff d0 call *%eax + for (; width > 0; width --) { + 8007c8: ff 4d e8 decl -0x18(%ebp) + 8007cb: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 8007cf: 7f e4 jg 8007b5 + } + break; + 8007d1: e9 6c 01 00 00 jmp 800942 + + // (signed) decimal + case 'd': + num = getint(&ap, lflag); + 8007d6: 8b 45 e0 mov -0x20(%ebp),%eax + 8007d9: 89 44 24 04 mov %eax,0x4(%esp) + 8007dd: 8d 45 14 lea 0x14(%ebp),%eax + 8007e0: 89 04 24 mov %eax,(%esp) + 8007e3: e8 16 fd ff ff call 8004fe + 8007e8: 89 45 f0 mov %eax,-0x10(%ebp) + 8007eb: 89 55 f4 mov %edx,-0xc(%ebp) + if ((long long)num < 0) { + 8007ee: 8b 45 f0 mov -0x10(%ebp),%eax + 8007f1: 8b 55 f4 mov -0xc(%ebp),%edx + 8007f4: 85 d2 test %edx,%edx + 8007f6: 79 26 jns 80081e + putch('-', putdat); + 8007f8: 8b 45 0c mov 0xc(%ebp),%eax + 8007fb: 89 44 24 04 mov %eax,0x4(%esp) + 8007ff: c7 04 24 2d 00 00 00 movl $0x2d,(%esp) + 800806: 8b 45 08 mov 0x8(%ebp),%eax + 800809: ff d0 call *%eax + num = -(long long)num; + 80080b: 8b 45 f0 mov -0x10(%ebp),%eax + 80080e: 8b 55 f4 mov -0xc(%ebp),%edx + 800811: f7 d8 neg %eax + 800813: 83 d2 00 adc $0x0,%edx + 800816: f7 da neg %edx + 800818: 89 45 f0 mov %eax,-0x10(%ebp) + 80081b: 89 55 f4 mov %edx,-0xc(%ebp) + } + base = 10; + 80081e: c7 45 ec 0a 00 00 00 movl $0xa,-0x14(%ebp) + goto number; + 800825: e9 a8 00 00 00 jmp 8008d2 + + // unsigned decimal + case 'u': + num = getuint(&ap, lflag); + 80082a: 8b 45 e0 mov -0x20(%ebp),%eax + 80082d: 89 44 24 04 mov %eax,0x4(%esp) + 800831: 8d 45 14 lea 0x14(%ebp),%eax + 800834: 89 04 24 mov %eax,(%esp) + 800837: e8 73 fc ff ff call 8004af + 80083c: 89 45 f0 mov %eax,-0x10(%ebp) + 80083f: 89 55 f4 mov %edx,-0xc(%ebp) + base = 10; + 800842: c7 45 ec 0a 00 00 00 movl $0xa,-0x14(%ebp) + goto number; + 800849: e9 84 00 00 00 jmp 8008d2 + + // (unsigned) octal + case 'o': + num = getuint(&ap, lflag); + 80084e: 8b 45 e0 mov -0x20(%ebp),%eax + 800851: 89 44 24 04 mov %eax,0x4(%esp) + 800855: 8d 45 14 lea 0x14(%ebp),%eax + 800858: 89 04 24 mov %eax,(%esp) + 80085b: e8 4f fc ff ff call 8004af + 800860: 89 45 f0 mov %eax,-0x10(%ebp) + 800863: 89 55 f4 mov %edx,-0xc(%ebp) + base = 8; + 800866: c7 45 ec 08 00 00 00 movl $0x8,-0x14(%ebp) + goto number; + 80086d: eb 63 jmp 8008d2 + + // pointer + case 'p': + putch('0', putdat); + 80086f: 8b 45 0c mov 0xc(%ebp),%eax + 800872: 89 44 24 04 mov %eax,0x4(%esp) + 800876: c7 04 24 30 00 00 00 movl $0x30,(%esp) + 80087d: 8b 45 08 mov 0x8(%ebp),%eax + 800880: ff d0 call *%eax + putch('x', putdat); + 800882: 8b 45 0c mov 0xc(%ebp),%eax + 800885: 89 44 24 04 mov %eax,0x4(%esp) + 800889: c7 04 24 78 00 00 00 movl $0x78,(%esp) + 800890: 8b 45 08 mov 0x8(%ebp),%eax + 800893: ff d0 call *%eax + num = (unsigned long long)(uintptr_t)va_arg(ap, void *); + 800895: 8b 45 14 mov 0x14(%ebp),%eax + 800898: 8d 50 04 lea 0x4(%eax),%edx + 80089b: 89 55 14 mov %edx,0x14(%ebp) + 80089e: 8b 00 mov (%eax),%eax + 8008a0: 89 45 f0 mov %eax,-0x10(%ebp) + 8008a3: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + base = 16; + 8008aa: c7 45 ec 10 00 00 00 movl $0x10,-0x14(%ebp) + goto number; + 8008b1: eb 1f jmp 8008d2 + + // (unsigned) hexadecimal + case 'x': + num = getuint(&ap, lflag); + 8008b3: 8b 45 e0 mov -0x20(%ebp),%eax + 8008b6: 89 44 24 04 mov %eax,0x4(%esp) + 8008ba: 8d 45 14 lea 0x14(%ebp),%eax + 8008bd: 89 04 24 mov %eax,(%esp) + 8008c0: e8 ea fb ff ff call 8004af + 8008c5: 89 45 f0 mov %eax,-0x10(%ebp) + 8008c8: 89 55 f4 mov %edx,-0xc(%ebp) + base = 16; + 8008cb: c7 45 ec 10 00 00 00 movl $0x10,-0x14(%ebp) + number: + printnum(putch, putdat, num, base, width, padc); + 8008d2: 0f be 55 db movsbl -0x25(%ebp),%edx + 8008d6: 8b 45 ec mov -0x14(%ebp),%eax + 8008d9: 89 54 24 18 mov %edx,0x18(%esp) + 8008dd: 8b 55 e8 mov -0x18(%ebp),%edx + 8008e0: 89 54 24 14 mov %edx,0x14(%esp) + 8008e4: 89 44 24 10 mov %eax,0x10(%esp) + 8008e8: 8b 45 f0 mov -0x10(%ebp),%eax + 8008eb: 8b 55 f4 mov -0xc(%ebp),%edx + 8008ee: 89 44 24 08 mov %eax,0x8(%esp) + 8008f2: 89 54 24 0c mov %edx,0xc(%esp) + 8008f6: 8b 45 0c mov 0xc(%ebp),%eax + 8008f9: 89 44 24 04 mov %eax,0x4(%esp) + 8008fd: 8b 45 08 mov 0x8(%ebp),%eax + 800900: 89 04 24 mov %eax,(%esp) + 800903: e8 a5 fa ff ff call 8003ad + break; + 800908: eb 38 jmp 800942 + + // escaped '%' character + case '%': + putch(ch, putdat); + 80090a: 8b 45 0c mov 0xc(%ebp),%eax + 80090d: 89 44 24 04 mov %eax,0x4(%esp) + 800911: 89 1c 24 mov %ebx,(%esp) + 800914: 8b 45 08 mov 0x8(%ebp),%eax + 800917: ff d0 call *%eax + break; + 800919: eb 27 jmp 800942 + + // unrecognized escape sequence - just print it literally + default: + putch('%', putdat); + 80091b: 8b 45 0c mov 0xc(%ebp),%eax + 80091e: 89 44 24 04 mov %eax,0x4(%esp) + 800922: c7 04 24 25 00 00 00 movl $0x25,(%esp) + 800929: 8b 45 08 mov 0x8(%ebp),%eax + 80092c: ff d0 call *%eax + for (fmt --; fmt[-1] != '%'; fmt --) + 80092e: ff 4d 10 decl 0x10(%ebp) + 800931: eb 03 jmp 800936 + 800933: ff 4d 10 decl 0x10(%ebp) + 800936: 8b 45 10 mov 0x10(%ebp),%eax + 800939: 48 dec %eax + 80093a: 0f b6 00 movzbl (%eax),%eax + 80093d: 3c 25 cmp $0x25,%al + 80093f: 75 f2 jne 800933 + /* do nothing */; + break; + 800941: 90 nop + while (1) { + 800942: e9 37 fc ff ff jmp 80057e + return; + 800947: 90 nop + } + } +} + 800948: 83 c4 40 add $0x40,%esp + 80094b: 5b pop %ebx + 80094c: 5e pop %esi + 80094d: 5d pop %ebp + 80094e: c3 ret + +0080094f : + * sprintputch - 'print' a single character in a buffer + * @ch: the character will be printed + * @b: the buffer to place the character @ch + * */ +static void +sprintputch(int ch, struct sprintbuf *b) { + 80094f: 55 push %ebp + 800950: 89 e5 mov %esp,%ebp + b->cnt ++; + 800952: 8b 45 0c mov 0xc(%ebp),%eax + 800955: 8b 40 08 mov 0x8(%eax),%eax + 800958: 8d 50 01 lea 0x1(%eax),%edx + 80095b: 8b 45 0c mov 0xc(%ebp),%eax + 80095e: 89 50 08 mov %edx,0x8(%eax) + if (b->buf < b->ebuf) { + 800961: 8b 45 0c mov 0xc(%ebp),%eax + 800964: 8b 10 mov (%eax),%edx + 800966: 8b 45 0c mov 0xc(%ebp),%eax + 800969: 8b 40 04 mov 0x4(%eax),%eax + 80096c: 39 c2 cmp %eax,%edx + 80096e: 73 12 jae 800982 + *b->buf ++ = ch; + 800970: 8b 45 0c mov 0xc(%ebp),%eax + 800973: 8b 00 mov (%eax),%eax + 800975: 8d 48 01 lea 0x1(%eax),%ecx + 800978: 8b 55 0c mov 0xc(%ebp),%edx + 80097b: 89 0a mov %ecx,(%edx) + 80097d: 8b 55 08 mov 0x8(%ebp),%edx + 800980: 88 10 mov %dl,(%eax) + } +} + 800982: 90 nop + 800983: 5d pop %ebp + 800984: c3 ret + +00800985 : + * @str: the buffer to place the result into + * @size: the size of buffer, including the trailing null space + * @fmt: the format string to use + * */ +int +snprintf(char *str, size_t size, const char *fmt, ...) { + 800985: 55 push %ebp + 800986: 89 e5 mov %esp,%ebp + 800988: 83 ec 28 sub $0x28,%esp + va_list ap; + int cnt; + va_start(ap, fmt); + 80098b: 8d 45 14 lea 0x14(%ebp),%eax + 80098e: 89 45 f0 mov %eax,-0x10(%ebp) + cnt = vsnprintf(str, size, fmt, ap); + 800991: 8b 45 f0 mov -0x10(%ebp),%eax + 800994: 89 44 24 0c mov %eax,0xc(%esp) + 800998: 8b 45 10 mov 0x10(%ebp),%eax + 80099b: 89 44 24 08 mov %eax,0x8(%esp) + 80099f: 8b 45 0c mov 0xc(%ebp),%eax + 8009a2: 89 44 24 04 mov %eax,0x4(%esp) + 8009a6: 8b 45 08 mov 0x8(%ebp),%eax + 8009a9: 89 04 24 mov %eax,(%esp) + 8009ac: e8 0a 00 00 00 call 8009bb + 8009b1: 89 45 f4 mov %eax,-0xc(%ebp) + va_end(ap); + return cnt; + 8009b4: 8b 45 f4 mov -0xc(%ebp),%eax +} + 8009b7: 89 ec mov %ebp,%esp + 8009b9: 5d pop %ebp + 8009ba: c3 ret + +008009bb : + * + * Call this function if you are already dealing with a va_list. + * Or you probably want snprintf() instead. + * */ +int +vsnprintf(char *str, size_t size, const char *fmt, va_list ap) { + 8009bb: 55 push %ebp + 8009bc: 89 e5 mov %esp,%ebp + 8009be: 83 ec 28 sub $0x28,%esp + struct sprintbuf b = {str, str + size - 1, 0}; + 8009c1: 8b 45 08 mov 0x8(%ebp),%eax + 8009c4: 89 45 ec mov %eax,-0x14(%ebp) + 8009c7: 8b 45 0c mov 0xc(%ebp),%eax + 8009ca: 8d 50 ff lea -0x1(%eax),%edx + 8009cd: 8b 45 08 mov 0x8(%ebp),%eax + 8009d0: 01 d0 add %edx,%eax + 8009d2: 89 45 f0 mov %eax,-0x10(%ebp) + 8009d5: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + if (str == NULL || b.buf > b.ebuf) { + 8009dc: 83 7d 08 00 cmpl $0x0,0x8(%ebp) + 8009e0: 74 0a je 8009ec + 8009e2: 8b 55 ec mov -0x14(%ebp),%edx + 8009e5: 8b 45 f0 mov -0x10(%ebp),%eax + 8009e8: 39 c2 cmp %eax,%edx + 8009ea: 76 07 jbe 8009f3 + return -E_INVAL; + 8009ec: b8 fd ff ff ff mov $0xfffffffd,%eax + 8009f1: eb 2a jmp 800a1d + } + // print the string to the buffer + vprintfmt((void*)sprintputch, &b, fmt, ap); + 8009f3: 8b 45 14 mov 0x14(%ebp),%eax + 8009f6: 89 44 24 0c mov %eax,0xc(%esp) + 8009fa: 8b 45 10 mov 0x10(%ebp),%eax + 8009fd: 89 44 24 08 mov %eax,0x8(%esp) + 800a01: 8d 45 ec lea -0x14(%ebp),%eax + 800a04: 89 44 24 04 mov %eax,0x4(%esp) + 800a08: c7 04 24 4f 09 80 00 movl $0x80094f,(%esp) + 800a0f: e8 62 fb ff ff call 800576 + // null terminate the buffer + *b.buf = '\0'; + 800a14: 8b 45 ec mov -0x14(%ebp),%eax + 800a17: c6 00 00 movb $0x0,(%eax) + return b.cnt; + 800a1a: 8b 45 f4 mov -0xc(%ebp),%eax +} + 800a1d: 89 ec mov %ebp,%esp + 800a1f: 5d pop %ebp + 800a20: c3 ret + +00800a21 : + * rand - returns a pseudo-random integer + * + * The rand() function return a value in the range [0, RAND_MAX]. + * */ +int +rand(void) { + 800a21: 55 push %ebp + 800a22: 89 e5 mov %esp,%ebp + 800a24: 57 push %edi + 800a25: 56 push %esi + 800a26: 53 push %ebx + 800a27: 83 ec 24 sub $0x24,%esp + next = (next * 0x5DEECE66DLL + 0xBLL) & ((1LL << 48) - 1); + 800a2a: a1 00 20 80 00 mov 0x802000,%eax + 800a2f: 8b 15 04 20 80 00 mov 0x802004,%edx + 800a35: 69 fa 6d e6 ec de imul $0xdeece66d,%edx,%edi + 800a3b: 6b f0 05 imul $0x5,%eax,%esi + 800a3e: 01 fe add %edi,%esi + 800a40: bf 6d e6 ec de mov $0xdeece66d,%edi + 800a45: f7 e7 mul %edi + 800a47: 01 d6 add %edx,%esi + 800a49: 89 f2 mov %esi,%edx + 800a4b: 83 c0 0b add $0xb,%eax + 800a4e: 83 d2 00 adc $0x0,%edx + 800a51: 89 c7 mov %eax,%edi + 800a53: 83 e7 ff and $0xffffffff,%edi + 800a56: 89 f9 mov %edi,%ecx + 800a58: 0f b7 da movzwl %dx,%ebx + 800a5b: 89 0d 00 20 80 00 mov %ecx,0x802000 + 800a61: 89 1d 04 20 80 00 mov %ebx,0x802004 + unsigned long long result = (next >> 12); + 800a67: a1 00 20 80 00 mov 0x802000,%eax + 800a6c: 8b 15 04 20 80 00 mov 0x802004,%edx + 800a72: 0f ac d0 0c shrd $0xc,%edx,%eax + 800a76: c1 ea 0c shr $0xc,%edx + 800a79: 89 45 e0 mov %eax,-0x20(%ebp) + 800a7c: 89 55 e4 mov %edx,-0x1c(%ebp) + return (int)do_div(result, RAND_MAX + 1); + 800a7f: c7 45 dc 00 00 00 80 movl $0x80000000,-0x24(%ebp) + 800a86: 8b 45 e0 mov -0x20(%ebp),%eax + 800a89: 8b 55 e4 mov -0x1c(%ebp),%edx + 800a8c: 89 45 d8 mov %eax,-0x28(%ebp) + 800a8f: 89 55 e8 mov %edx,-0x18(%ebp) + 800a92: 8b 45 e8 mov -0x18(%ebp),%eax + 800a95: 89 45 ec mov %eax,-0x14(%ebp) + 800a98: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 800a9c: 74 1c je 800aba + 800a9e: 8b 45 e8 mov -0x18(%ebp),%eax + 800aa1: ba 00 00 00 00 mov $0x0,%edx + 800aa6: f7 75 dc divl -0x24(%ebp) + 800aa9: 89 55 ec mov %edx,-0x14(%ebp) + 800aac: 8b 45 e8 mov -0x18(%ebp),%eax + 800aaf: ba 00 00 00 00 mov $0x0,%edx + 800ab4: f7 75 dc divl -0x24(%ebp) + 800ab7: 89 45 e8 mov %eax,-0x18(%ebp) + 800aba: 8b 45 d8 mov -0x28(%ebp),%eax + 800abd: 8b 55 ec mov -0x14(%ebp),%edx + 800ac0: f7 75 dc divl -0x24(%ebp) + 800ac3: 89 45 d8 mov %eax,-0x28(%ebp) + 800ac6: 89 55 d4 mov %edx,-0x2c(%ebp) + 800ac9: 8b 45 d8 mov -0x28(%ebp),%eax + 800acc: 8b 55 e8 mov -0x18(%ebp),%edx + 800acf: 89 45 e0 mov %eax,-0x20(%ebp) + 800ad2: 89 55 e4 mov %edx,-0x1c(%ebp) + 800ad5: 8b 45 d4 mov -0x2c(%ebp),%eax +} + 800ad8: 83 c4 24 add $0x24,%esp + 800adb: 5b pop %ebx + 800adc: 5e pop %esi + 800add: 5f pop %edi + 800ade: 5d pop %ebp + 800adf: c3 ret + +00800ae0 : +/* * + * srand - seed the random number generator with the given number + * @seed: the required seed number + * */ +void +srand(unsigned int seed) { + 800ae0: 55 push %ebp + 800ae1: 89 e5 mov %esp,%ebp + next = seed; + 800ae3: 8b 45 08 mov 0x8(%ebp),%eax + 800ae6: ba 00 00 00 00 mov $0x0,%edx + 800aeb: a3 00 20 80 00 mov %eax,0x802000 + 800af0: 89 15 04 20 80 00 mov %edx,0x802004 +} + 800af6: 90 nop + 800af7: 5d pop %ebp + 800af8: c3 ret + +00800af9 : + * @s: the input string + * + * The strlen() function returns the length of string @s. + * */ +size_t +strlen(const char *s) { + 800af9: 55 push %ebp + 800afa: 89 e5 mov %esp,%ebp + 800afc: 83 ec 10 sub $0x10,%esp + size_t cnt = 0; + 800aff: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + while (*s ++ != '\0') { + 800b06: eb 03 jmp 800b0b + cnt ++; + 800b08: ff 45 fc incl -0x4(%ebp) + while (*s ++ != '\0') { + 800b0b: 8b 45 08 mov 0x8(%ebp),%eax + 800b0e: 8d 50 01 lea 0x1(%eax),%edx + 800b11: 89 55 08 mov %edx,0x8(%ebp) + 800b14: 0f b6 00 movzbl (%eax),%eax + 800b17: 84 c0 test %al,%al + 800b19: 75 ed jne 800b08 + } + return cnt; + 800b1b: 8b 45 fc mov -0x4(%ebp),%eax +} + 800b1e: 89 ec mov %ebp,%esp + 800b20: 5d pop %ebp + 800b21: c3 ret + +00800b22 : + * The return value is strlen(s), if that is less than @len, or + * @len if there is no '\0' character among the first @len characters + * pointed by @s. + * */ +size_t +strnlen(const char *s, size_t len) { + 800b22: 55 push %ebp + 800b23: 89 e5 mov %esp,%ebp + 800b25: 83 ec 10 sub $0x10,%esp + size_t cnt = 0; + 800b28: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + while (cnt < len && *s ++ != '\0') { + 800b2f: eb 03 jmp 800b34 + cnt ++; + 800b31: ff 45 fc incl -0x4(%ebp) + while (cnt < len && *s ++ != '\0') { + 800b34: 8b 45 fc mov -0x4(%ebp),%eax + 800b37: 3b 45 0c cmp 0xc(%ebp),%eax + 800b3a: 73 10 jae 800b4c + 800b3c: 8b 45 08 mov 0x8(%ebp),%eax + 800b3f: 8d 50 01 lea 0x1(%eax),%edx + 800b42: 89 55 08 mov %edx,0x8(%ebp) + 800b45: 0f b6 00 movzbl (%eax),%eax + 800b48: 84 c0 test %al,%al + 800b4a: 75 e5 jne 800b31 + } + return cnt; + 800b4c: 8b 45 fc mov -0x4(%ebp),%eax +} + 800b4f: 89 ec mov %ebp,%esp + 800b51: 5d pop %ebp + 800b52: c3 ret + +00800b53 : + * To avoid overflows, the size of array pointed by @dst should be long enough to + * contain the same string as @src (including the terminating null character), and + * should not overlap in memory with @src. + * */ +char * +strcpy(char *dst, const char *src) { + 800b53: 55 push %ebp + 800b54: 89 e5 mov %esp,%ebp + 800b56: 57 push %edi + 800b57: 56 push %esi + 800b58: 83 ec 20 sub $0x20,%esp + 800b5b: 8b 45 08 mov 0x8(%ebp),%eax + 800b5e: 89 45 f4 mov %eax,-0xc(%ebp) + 800b61: 8b 45 0c mov 0xc(%ebp),%eax + 800b64: 89 45 f0 mov %eax,-0x10(%ebp) +#ifndef __HAVE_ARCH_STRCPY +#define __HAVE_ARCH_STRCPY +static inline char * +__strcpy(char *dst, const char *src) { + int d0, d1, d2; + asm volatile ( + 800b67: 8b 55 f0 mov -0x10(%ebp),%edx + 800b6a: 8b 45 f4 mov -0xc(%ebp),%eax + 800b6d: 89 d1 mov %edx,%ecx + 800b6f: 89 c2 mov %eax,%edx + 800b71: 89 ce mov %ecx,%esi + 800b73: 89 d7 mov %edx,%edi + 800b75: ac lods %ds:(%esi),%al + 800b76: aa stos %al,%es:(%edi) + 800b77: 84 c0 test %al,%al + 800b79: 75 fa jne 800b75 + 800b7b: 89 fa mov %edi,%edx + 800b7d: 89 f1 mov %esi,%ecx + 800b7f: 89 4d ec mov %ecx,-0x14(%ebp) + 800b82: 89 55 e8 mov %edx,-0x18(%ebp) + 800b85: 89 45 e4 mov %eax,-0x1c(%ebp) + "stosb;" + "testb %%al, %%al;" + "jne 1b;" + : "=&S" (d0), "=&D" (d1), "=&a" (d2) + : "0" (src), "1" (dst) : "memory"); + return dst; + 800b88: 8b 45 f4 mov -0xc(%ebp),%eax + char *p = dst; + while ((*p ++ = *src ++) != '\0') + /* nothing */; + return dst; +#endif /* __HAVE_ARCH_STRCPY */ +} + 800b8b: 83 c4 20 add $0x20,%esp + 800b8e: 5e pop %esi + 800b8f: 5f pop %edi + 800b90: 5d pop %ebp + 800b91: c3 ret + +00800b92 : + * @len: maximum number of characters to be copied from @src + * + * The return value is @dst + * */ +char * +strncpy(char *dst, const char *src, size_t len) { + 800b92: 55 push %ebp + 800b93: 89 e5 mov %esp,%ebp + 800b95: 83 ec 10 sub $0x10,%esp + char *p = dst; + 800b98: 8b 45 08 mov 0x8(%ebp),%eax + 800b9b: 89 45 fc mov %eax,-0x4(%ebp) + while (len > 0) { + 800b9e: eb 1e jmp 800bbe + if ((*p = *src) != '\0') { + 800ba0: 8b 45 0c mov 0xc(%ebp),%eax + 800ba3: 0f b6 10 movzbl (%eax),%edx + 800ba6: 8b 45 fc mov -0x4(%ebp),%eax + 800ba9: 88 10 mov %dl,(%eax) + 800bab: 8b 45 fc mov -0x4(%ebp),%eax + 800bae: 0f b6 00 movzbl (%eax),%eax + 800bb1: 84 c0 test %al,%al + 800bb3: 74 03 je 800bb8 + src ++; + 800bb5: ff 45 0c incl 0xc(%ebp) + } + p ++, len --; + 800bb8: ff 45 fc incl -0x4(%ebp) + 800bbb: ff 4d 10 decl 0x10(%ebp) + while (len > 0) { + 800bbe: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800bc2: 75 dc jne 800ba0 + } + return dst; + 800bc4: 8b 45 08 mov 0x8(%ebp),%eax +} + 800bc7: 89 ec mov %ebp,%esp + 800bc9: 5d pop %ebp + 800bca: c3 ret + +00800bcb : + * - A value greater than zero indicates that the first character that does + * not match has a greater value in @s1 than in @s2; + * - And a value less than zero indicates the opposite. + * */ +int +strcmp(const char *s1, const char *s2) { + 800bcb: 55 push %ebp + 800bcc: 89 e5 mov %esp,%ebp + 800bce: 57 push %edi + 800bcf: 56 push %esi + 800bd0: 83 ec 20 sub $0x20,%esp + 800bd3: 8b 45 08 mov 0x8(%ebp),%eax + 800bd6: 89 45 f4 mov %eax,-0xc(%ebp) + 800bd9: 8b 45 0c mov 0xc(%ebp),%eax + 800bdc: 89 45 f0 mov %eax,-0x10(%ebp) + asm volatile ( + 800bdf: 8b 55 f4 mov -0xc(%ebp),%edx + 800be2: 8b 45 f0 mov -0x10(%ebp),%eax + 800be5: 89 d1 mov %edx,%ecx + 800be7: 89 c2 mov %eax,%edx + 800be9: 89 ce mov %ecx,%esi + 800beb: 89 d7 mov %edx,%edi + 800bed: ac lods %ds:(%esi),%al + 800bee: ae scas %es:(%edi),%al + 800bef: 75 08 jne 800bf9 + 800bf1: 84 c0 test %al,%al + 800bf3: 75 f8 jne 800bed + 800bf5: 31 c0 xor %eax,%eax + 800bf7: eb 04 jmp 800bfd + 800bf9: 19 c0 sbb %eax,%eax + 800bfb: 0c 01 or $0x1,%al + 800bfd: 89 fa mov %edi,%edx + 800bff: 89 f1 mov %esi,%ecx + 800c01: 89 45 ec mov %eax,-0x14(%ebp) + 800c04: 89 4d e8 mov %ecx,-0x18(%ebp) + 800c07: 89 55 e4 mov %edx,-0x1c(%ebp) + return ret; + 800c0a: 8b 45 ec mov -0x14(%ebp),%eax + while (*s1 != '\0' && *s1 == *s2) { + s1 ++, s2 ++; + } + return (int)((unsigned char)*s1 - (unsigned char)*s2); +#endif /* __HAVE_ARCH_STRCMP */ +} + 800c0d: 83 c4 20 add $0x20,%esp + 800c10: 5e pop %esi + 800c11: 5f pop %edi + 800c12: 5d pop %ebp + 800c13: c3 ret + +00800c14 : + * they are equal to each other, it continues with the following pairs until + * the characters differ, until a terminating null-character is reached, or + * until @n characters match in both strings, whichever happens first. + * */ +int +strncmp(const char *s1, const char *s2, size_t n) { + 800c14: 55 push %ebp + 800c15: 89 e5 mov %esp,%ebp + while (n > 0 && *s1 != '\0' && *s1 == *s2) { + 800c17: eb 09 jmp 800c22 + n --, s1 ++, s2 ++; + 800c19: ff 4d 10 decl 0x10(%ebp) + 800c1c: ff 45 08 incl 0x8(%ebp) + 800c1f: ff 45 0c incl 0xc(%ebp) + while (n > 0 && *s1 != '\0' && *s1 == *s2) { + 800c22: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800c26: 74 1a je 800c42 + 800c28: 8b 45 08 mov 0x8(%ebp),%eax + 800c2b: 0f b6 00 movzbl (%eax),%eax + 800c2e: 84 c0 test %al,%al + 800c30: 74 10 je 800c42 + 800c32: 8b 45 08 mov 0x8(%ebp),%eax + 800c35: 0f b6 10 movzbl (%eax),%edx + 800c38: 8b 45 0c mov 0xc(%ebp),%eax + 800c3b: 0f b6 00 movzbl (%eax),%eax + 800c3e: 38 c2 cmp %al,%dl + 800c40: 74 d7 je 800c19 + } + return (n == 0) ? 0 : (int)((unsigned char)*s1 - (unsigned char)*s2); + 800c42: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800c46: 74 18 je 800c60 + 800c48: 8b 45 08 mov 0x8(%ebp),%eax + 800c4b: 0f b6 00 movzbl (%eax),%eax + 800c4e: 0f b6 d0 movzbl %al,%edx + 800c51: 8b 45 0c mov 0xc(%ebp),%eax + 800c54: 0f b6 00 movzbl (%eax),%eax + 800c57: 0f b6 c8 movzbl %al,%ecx + 800c5a: 89 d0 mov %edx,%eax + 800c5c: 29 c8 sub %ecx,%eax + 800c5e: eb 05 jmp 800c65 + 800c60: b8 00 00 00 00 mov $0x0,%eax +} + 800c65: 5d pop %ebp + 800c66: c3 ret + +00800c67 : + * + * The strchr() function returns a pointer to the first occurrence of + * character in @s. If the value is not found, the function returns 'NULL'. + * */ +char * +strchr(const char *s, char c) { + 800c67: 55 push %ebp + 800c68: 89 e5 mov %esp,%ebp + 800c6a: 83 ec 04 sub $0x4,%esp + 800c6d: 8b 45 0c mov 0xc(%ebp),%eax + 800c70: 88 45 fc mov %al,-0x4(%ebp) + while (*s != '\0') { + 800c73: eb 13 jmp 800c88 + if (*s == c) { + 800c75: 8b 45 08 mov 0x8(%ebp),%eax + 800c78: 0f b6 00 movzbl (%eax),%eax + 800c7b: 38 45 fc cmp %al,-0x4(%ebp) + 800c7e: 75 05 jne 800c85 + return (char *)s; + 800c80: 8b 45 08 mov 0x8(%ebp),%eax + 800c83: eb 12 jmp 800c97 + } + s ++; + 800c85: ff 45 08 incl 0x8(%ebp) + while (*s != '\0') { + 800c88: 8b 45 08 mov 0x8(%ebp),%eax + 800c8b: 0f b6 00 movzbl (%eax),%eax + 800c8e: 84 c0 test %al,%al + 800c90: 75 e3 jne 800c75 + } + return NULL; + 800c92: b8 00 00 00 00 mov $0x0,%eax +} + 800c97: 89 ec mov %ebp,%esp + 800c99: 5d pop %ebp + 800c9a: c3 ret + +00800c9b : + * The strfind() function is like strchr() except that if @c is + * not found in @s, then it returns a pointer to the null byte at the + * end of @s, rather than 'NULL'. + * */ +char * +strfind(const char *s, char c) { + 800c9b: 55 push %ebp + 800c9c: 89 e5 mov %esp,%ebp + 800c9e: 83 ec 04 sub $0x4,%esp + 800ca1: 8b 45 0c mov 0xc(%ebp),%eax + 800ca4: 88 45 fc mov %al,-0x4(%ebp) + while (*s != '\0') { + 800ca7: eb 0e jmp 800cb7 + if (*s == c) { + 800ca9: 8b 45 08 mov 0x8(%ebp),%eax + 800cac: 0f b6 00 movzbl (%eax),%eax + 800caf: 38 45 fc cmp %al,-0x4(%ebp) + 800cb2: 74 0f je 800cc3 + break; + } + s ++; + 800cb4: ff 45 08 incl 0x8(%ebp) + while (*s != '\0') { + 800cb7: 8b 45 08 mov 0x8(%ebp),%eax + 800cba: 0f b6 00 movzbl (%eax),%eax + 800cbd: 84 c0 test %al,%al + 800cbf: 75 e8 jne 800ca9 + 800cc1: eb 01 jmp 800cc4 + break; + 800cc3: 90 nop + } + return (char *)s; + 800cc4: 8b 45 08 mov 0x8(%ebp),%eax +} + 800cc7: 89 ec mov %ebp,%esp + 800cc9: 5d pop %ebp + 800cca: c3 ret + +00800ccb : + * an optional "0x" or "0X" prefix. + * + * The strtol() function returns the converted integral number as a long int value. + * */ +long +strtol(const char *s, char **endptr, int base) { + 800ccb: 55 push %ebp + 800ccc: 89 e5 mov %esp,%ebp + 800cce: 83 ec 10 sub $0x10,%esp + int neg = 0; + 800cd1: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + long val = 0; + 800cd8: c7 45 f8 00 00 00 00 movl $0x0,-0x8(%ebp) + + // gobble initial whitespace + while (*s == ' ' || *s == '\t') { + 800cdf: eb 03 jmp 800ce4 + s ++; + 800ce1: ff 45 08 incl 0x8(%ebp) + while (*s == ' ' || *s == '\t') { + 800ce4: 8b 45 08 mov 0x8(%ebp),%eax + 800ce7: 0f b6 00 movzbl (%eax),%eax + 800cea: 3c 20 cmp $0x20,%al + 800cec: 74 f3 je 800ce1 + 800cee: 8b 45 08 mov 0x8(%ebp),%eax + 800cf1: 0f b6 00 movzbl (%eax),%eax + 800cf4: 3c 09 cmp $0x9,%al + 800cf6: 74 e9 je 800ce1 + } + + // plus/minus sign + if (*s == '+') { + 800cf8: 8b 45 08 mov 0x8(%ebp),%eax + 800cfb: 0f b6 00 movzbl (%eax),%eax + 800cfe: 3c 2b cmp $0x2b,%al + 800d00: 75 05 jne 800d07 + s ++; + 800d02: ff 45 08 incl 0x8(%ebp) + 800d05: eb 14 jmp 800d1b + } + else if (*s == '-') { + 800d07: 8b 45 08 mov 0x8(%ebp),%eax + 800d0a: 0f b6 00 movzbl (%eax),%eax + 800d0d: 3c 2d cmp $0x2d,%al + 800d0f: 75 0a jne 800d1b + s ++, neg = 1; + 800d11: ff 45 08 incl 0x8(%ebp) + 800d14: c7 45 fc 01 00 00 00 movl $0x1,-0x4(%ebp) + } + + // hex or octal base prefix + if ((base == 0 || base == 16) && (s[0] == '0' && s[1] == 'x')) { + 800d1b: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800d1f: 74 06 je 800d27 + 800d21: 83 7d 10 10 cmpl $0x10,0x10(%ebp) + 800d25: 75 22 jne 800d49 + 800d27: 8b 45 08 mov 0x8(%ebp),%eax + 800d2a: 0f b6 00 movzbl (%eax),%eax + 800d2d: 3c 30 cmp $0x30,%al + 800d2f: 75 18 jne 800d49 + 800d31: 8b 45 08 mov 0x8(%ebp),%eax + 800d34: 40 inc %eax + 800d35: 0f b6 00 movzbl (%eax),%eax + 800d38: 3c 78 cmp $0x78,%al + 800d3a: 75 0d jne 800d49 + s += 2, base = 16; + 800d3c: 83 45 08 02 addl $0x2,0x8(%ebp) + 800d40: c7 45 10 10 00 00 00 movl $0x10,0x10(%ebp) + 800d47: eb 29 jmp 800d72 + } + else if (base == 0 && s[0] == '0') { + 800d49: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800d4d: 75 16 jne 800d65 + 800d4f: 8b 45 08 mov 0x8(%ebp),%eax + 800d52: 0f b6 00 movzbl (%eax),%eax + 800d55: 3c 30 cmp $0x30,%al + 800d57: 75 0c jne 800d65 + s ++, base = 8; + 800d59: ff 45 08 incl 0x8(%ebp) + 800d5c: c7 45 10 08 00 00 00 movl $0x8,0x10(%ebp) + 800d63: eb 0d jmp 800d72 + } + else if (base == 0) { + 800d65: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800d69: 75 07 jne 800d72 + base = 10; + 800d6b: c7 45 10 0a 00 00 00 movl $0xa,0x10(%ebp) + + // digits + while (1) { + int dig; + + if (*s >= '0' && *s <= '9') { + 800d72: 8b 45 08 mov 0x8(%ebp),%eax + 800d75: 0f b6 00 movzbl (%eax),%eax + 800d78: 3c 2f cmp $0x2f,%al + 800d7a: 7e 1b jle 800d97 + 800d7c: 8b 45 08 mov 0x8(%ebp),%eax + 800d7f: 0f b6 00 movzbl (%eax),%eax + 800d82: 3c 39 cmp $0x39,%al + 800d84: 7f 11 jg 800d97 + dig = *s - '0'; + 800d86: 8b 45 08 mov 0x8(%ebp),%eax + 800d89: 0f b6 00 movzbl (%eax),%eax + 800d8c: 0f be c0 movsbl %al,%eax + 800d8f: 83 e8 30 sub $0x30,%eax + 800d92: 89 45 f4 mov %eax,-0xc(%ebp) + 800d95: eb 48 jmp 800ddf + } + else if (*s >= 'a' && *s <= 'z') { + 800d97: 8b 45 08 mov 0x8(%ebp),%eax + 800d9a: 0f b6 00 movzbl (%eax),%eax + 800d9d: 3c 60 cmp $0x60,%al + 800d9f: 7e 1b jle 800dbc + 800da1: 8b 45 08 mov 0x8(%ebp),%eax + 800da4: 0f b6 00 movzbl (%eax),%eax + 800da7: 3c 7a cmp $0x7a,%al + 800da9: 7f 11 jg 800dbc + dig = *s - 'a' + 10; + 800dab: 8b 45 08 mov 0x8(%ebp),%eax + 800dae: 0f b6 00 movzbl (%eax),%eax + 800db1: 0f be c0 movsbl %al,%eax + 800db4: 83 e8 57 sub $0x57,%eax + 800db7: 89 45 f4 mov %eax,-0xc(%ebp) + 800dba: eb 23 jmp 800ddf + } + else if (*s >= 'A' && *s <= 'Z') { + 800dbc: 8b 45 08 mov 0x8(%ebp),%eax + 800dbf: 0f b6 00 movzbl (%eax),%eax + 800dc2: 3c 40 cmp $0x40,%al + 800dc4: 7e 3b jle 800e01 + 800dc6: 8b 45 08 mov 0x8(%ebp),%eax + 800dc9: 0f b6 00 movzbl (%eax),%eax + 800dcc: 3c 5a cmp $0x5a,%al + 800dce: 7f 31 jg 800e01 + dig = *s - 'A' + 10; + 800dd0: 8b 45 08 mov 0x8(%ebp),%eax + 800dd3: 0f b6 00 movzbl (%eax),%eax + 800dd6: 0f be c0 movsbl %al,%eax + 800dd9: 83 e8 37 sub $0x37,%eax + 800ddc: 89 45 f4 mov %eax,-0xc(%ebp) + } + else { + break; + } + if (dig >= base) { + 800ddf: 8b 45 f4 mov -0xc(%ebp),%eax + 800de2: 3b 45 10 cmp 0x10(%ebp),%eax + 800de5: 7d 19 jge 800e00 + break; + } + s ++, val = (val * base) + dig; + 800de7: ff 45 08 incl 0x8(%ebp) + 800dea: 8b 45 f8 mov -0x8(%ebp),%eax + 800ded: 0f af 45 10 imul 0x10(%ebp),%eax + 800df1: 89 c2 mov %eax,%edx + 800df3: 8b 45 f4 mov -0xc(%ebp),%eax + 800df6: 01 d0 add %edx,%eax + 800df8: 89 45 f8 mov %eax,-0x8(%ebp) + while (1) { + 800dfb: e9 72 ff ff ff jmp 800d72 + break; + 800e00: 90 nop + // we don't properly detect overflow! + } + + if (endptr) { + 800e01: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) + 800e05: 74 08 je 800e0f + *endptr = (char *) s; + 800e07: 8b 45 0c mov 0xc(%ebp),%eax + 800e0a: 8b 55 08 mov 0x8(%ebp),%edx + 800e0d: 89 10 mov %edx,(%eax) + } + return (neg ? -val : val); + 800e0f: 83 7d fc 00 cmpl $0x0,-0x4(%ebp) + 800e13: 74 07 je 800e1c + 800e15: 8b 45 f8 mov -0x8(%ebp),%eax + 800e18: f7 d8 neg %eax + 800e1a: eb 03 jmp 800e1f + 800e1c: 8b 45 f8 mov -0x8(%ebp),%eax +} + 800e1f: 89 ec mov %ebp,%esp + 800e21: 5d pop %ebp + 800e22: c3 ret + +00800e23 : + * @n: number of bytes to be set to the value + * + * The memset() function returns @s. + * */ +void * +memset(void *s, char c, size_t n) { + 800e23: 55 push %ebp + 800e24: 89 e5 mov %esp,%ebp + 800e26: 83 ec 28 sub $0x28,%esp + 800e29: 89 7d fc mov %edi,-0x4(%ebp) + 800e2c: 8b 45 0c mov 0xc(%ebp),%eax + 800e2f: 88 45 d8 mov %al,-0x28(%ebp) +#ifdef __HAVE_ARCH_MEMSET + return __memset(s, c, n); + 800e32: 0f be 55 d8 movsbl -0x28(%ebp),%edx + 800e36: 8b 45 08 mov 0x8(%ebp),%eax + 800e39: 89 45 f8 mov %eax,-0x8(%ebp) + 800e3c: 88 55 f7 mov %dl,-0x9(%ebp) + 800e3f: 8b 45 10 mov 0x10(%ebp),%eax + 800e42: 89 45 f0 mov %eax,-0x10(%ebp) +#ifndef __HAVE_ARCH_MEMSET +#define __HAVE_ARCH_MEMSET +static inline void * +__memset(void *s, char c, size_t n) { + int d0, d1; + asm volatile ( + 800e45: 8b 4d f0 mov -0x10(%ebp),%ecx + 800e48: 0f b6 45 f7 movzbl -0x9(%ebp),%eax + 800e4c: 8b 55 f8 mov -0x8(%ebp),%edx + 800e4f: 89 d7 mov %edx,%edi + 800e51: f3 aa rep stos %al,%es:(%edi) + 800e53: 89 fa mov %edi,%edx + 800e55: 89 4d ec mov %ecx,-0x14(%ebp) + 800e58: 89 55 e8 mov %edx,-0x18(%ebp) + "rep; stosb;" + : "=&c" (d0), "=&D" (d1) + : "0" (n), "a" (c), "1" (s) + : "memory"); + return s; + 800e5b: 8b 45 f8 mov -0x8(%ebp),%eax + while (n -- > 0) { + *p ++ = c; + } + return s; +#endif /* __HAVE_ARCH_MEMSET */ +} + 800e5e: 8b 7d fc mov -0x4(%ebp),%edi + 800e61: 89 ec mov %ebp,%esp + 800e63: 5d pop %ebp + 800e64: c3 ret + +00800e65 : + * @n: number of bytes to copy + * + * The memmove() function returns @dst. + * */ +void * +memmove(void *dst, const void *src, size_t n) { + 800e65: 55 push %ebp + 800e66: 89 e5 mov %esp,%ebp + 800e68: 57 push %edi + 800e69: 56 push %esi + 800e6a: 53 push %ebx + 800e6b: 83 ec 30 sub $0x30,%esp + 800e6e: 8b 45 08 mov 0x8(%ebp),%eax + 800e71: 89 45 f0 mov %eax,-0x10(%ebp) + 800e74: 8b 45 0c mov 0xc(%ebp),%eax + 800e77: 89 45 ec mov %eax,-0x14(%ebp) + 800e7a: 8b 45 10 mov 0x10(%ebp),%eax + 800e7d: 89 45 e8 mov %eax,-0x18(%ebp) + +#ifndef __HAVE_ARCH_MEMMOVE +#define __HAVE_ARCH_MEMMOVE +static inline void * +__memmove(void *dst, const void *src, size_t n) { + if (dst < src) { + 800e80: 8b 45 f0 mov -0x10(%ebp),%eax + 800e83: 3b 45 ec cmp -0x14(%ebp),%eax + 800e86: 73 42 jae 800eca + 800e88: 8b 45 f0 mov -0x10(%ebp),%eax + 800e8b: 89 45 e4 mov %eax,-0x1c(%ebp) + 800e8e: 8b 45 ec mov -0x14(%ebp),%eax + 800e91: 89 45 e0 mov %eax,-0x20(%ebp) + 800e94: 8b 45 e8 mov -0x18(%ebp),%eax + 800e97: 89 45 dc mov %eax,-0x24(%ebp) + "andl $3, %%ecx;" + "jz 1f;" + "rep; movsb;" + "1:" + : "=&c" (d0), "=&D" (d1), "=&S" (d2) + : "0" (n / 4), "g" (n), "1" (dst), "2" (src) + 800e9a: 8b 45 dc mov -0x24(%ebp),%eax + 800e9d: c1 e8 02 shr $0x2,%eax + 800ea0: 89 c1 mov %eax,%ecx + asm volatile ( + 800ea2: 8b 55 e4 mov -0x1c(%ebp),%edx + 800ea5: 8b 45 e0 mov -0x20(%ebp),%eax + 800ea8: 89 d7 mov %edx,%edi + 800eaa: 89 c6 mov %eax,%esi + 800eac: f3 a5 rep movsl %ds:(%esi),%es:(%edi) + 800eae: 8b 4d dc mov -0x24(%ebp),%ecx + 800eb1: 83 e1 03 and $0x3,%ecx + 800eb4: 74 02 je 800eb8 + 800eb6: f3 a4 rep movsb %ds:(%esi),%es:(%edi) + 800eb8: 89 f0 mov %esi,%eax + 800eba: 89 fa mov %edi,%edx + 800ebc: 89 4d d8 mov %ecx,-0x28(%ebp) + 800ebf: 89 55 d4 mov %edx,-0x2c(%ebp) + 800ec2: 89 45 d0 mov %eax,-0x30(%ebp) + : "memory"); + return dst; + 800ec5: 8b 45 e4 mov -0x1c(%ebp),%eax + return __memcpy(dst, src, n); + 800ec8: eb 36 jmp 800f00 + : "0" (n), "1" (n - 1 + src), "2" (n - 1 + dst) + 800eca: 8b 45 e8 mov -0x18(%ebp),%eax + 800ecd: 8d 50 ff lea -0x1(%eax),%edx + 800ed0: 8b 45 ec mov -0x14(%ebp),%eax + 800ed3: 01 c2 add %eax,%edx + 800ed5: 8b 45 e8 mov -0x18(%ebp),%eax + 800ed8: 8d 48 ff lea -0x1(%eax),%ecx + 800edb: 8b 45 f0 mov -0x10(%ebp),%eax + 800ede: 8d 1c 01 lea (%ecx,%eax,1),%ebx + asm volatile ( + 800ee1: 8b 45 e8 mov -0x18(%ebp),%eax + 800ee4: 89 c1 mov %eax,%ecx + 800ee6: 89 d8 mov %ebx,%eax + 800ee8: 89 d6 mov %edx,%esi + 800eea: 89 c7 mov %eax,%edi + 800eec: fd std + 800eed: f3 a4 rep movsb %ds:(%esi),%es:(%edi) + 800eef: fc cld + 800ef0: 89 f8 mov %edi,%eax + 800ef2: 89 f2 mov %esi,%edx + 800ef4: 89 4d cc mov %ecx,-0x34(%ebp) + 800ef7: 89 55 c8 mov %edx,-0x38(%ebp) + 800efa: 89 45 c4 mov %eax,-0x3c(%ebp) + return dst; + 800efd: 8b 45 f0 mov -0x10(%ebp),%eax + *d ++ = *s ++; + } + } + return dst; +#endif /* __HAVE_ARCH_MEMMOVE */ +} + 800f00: 83 c4 30 add $0x30,%esp + 800f03: 5b pop %ebx + 800f04: 5e pop %esi + 800f05: 5f pop %edi + 800f06: 5d pop %ebp + 800f07: c3 ret + +00800f08 : + * it always copies exactly @n bytes. To avoid overflows, the size of arrays pointed + * by both @src and @dst, should be at least @n bytes, and should not overlap + * (for overlapping memory area, memmove is a safer approach). + * */ +void * +memcpy(void *dst, const void *src, size_t n) { + 800f08: 55 push %ebp + 800f09: 89 e5 mov %esp,%ebp + 800f0b: 57 push %edi + 800f0c: 56 push %esi + 800f0d: 83 ec 20 sub $0x20,%esp + 800f10: 8b 45 08 mov 0x8(%ebp),%eax + 800f13: 89 45 f4 mov %eax,-0xc(%ebp) + 800f16: 8b 45 0c mov 0xc(%ebp),%eax + 800f19: 89 45 f0 mov %eax,-0x10(%ebp) + 800f1c: 8b 45 10 mov 0x10(%ebp),%eax + 800f1f: 89 45 ec mov %eax,-0x14(%ebp) + : "0" (n / 4), "g" (n), "1" (dst), "2" (src) + 800f22: 8b 45 ec mov -0x14(%ebp),%eax + 800f25: c1 e8 02 shr $0x2,%eax + 800f28: 89 c1 mov %eax,%ecx + asm volatile ( + 800f2a: 8b 55 f4 mov -0xc(%ebp),%edx + 800f2d: 8b 45 f0 mov -0x10(%ebp),%eax + 800f30: 89 d7 mov %edx,%edi + 800f32: 89 c6 mov %eax,%esi + 800f34: f3 a5 rep movsl %ds:(%esi),%es:(%edi) + 800f36: 8b 4d ec mov -0x14(%ebp),%ecx + 800f39: 83 e1 03 and $0x3,%ecx + 800f3c: 74 02 je 800f40 + 800f3e: f3 a4 rep movsb %ds:(%esi),%es:(%edi) + 800f40: 89 f0 mov %esi,%eax + 800f42: 89 fa mov %edi,%edx + 800f44: 89 4d e8 mov %ecx,-0x18(%ebp) + 800f47: 89 55 e4 mov %edx,-0x1c(%ebp) + 800f4a: 89 45 e0 mov %eax,-0x20(%ebp) + return dst; + 800f4d: 8b 45 f4 mov -0xc(%ebp),%eax + while (n -- > 0) { + *d ++ = *s ++; + } + return dst; +#endif /* __HAVE_ARCH_MEMCPY */ +} + 800f50: 83 c4 20 add $0x20,%esp + 800f53: 5e pop %esi + 800f54: 5f pop %edi + 800f55: 5d pop %ebp + 800f56: c3 ret + +00800f57 : + * match in both memory blocks has a greater value in @v1 than in @v2 + * as if evaluated as unsigned char values; + * - And a value less than zero indicates the opposite. + * */ +int +memcmp(const void *v1, const void *v2, size_t n) { + 800f57: 55 push %ebp + 800f58: 89 e5 mov %esp,%ebp + 800f5a: 83 ec 10 sub $0x10,%esp + const char *s1 = (const char *)v1; + 800f5d: 8b 45 08 mov 0x8(%ebp),%eax + 800f60: 89 45 fc mov %eax,-0x4(%ebp) + const char *s2 = (const char *)v2; + 800f63: 8b 45 0c mov 0xc(%ebp),%eax + 800f66: 89 45 f8 mov %eax,-0x8(%ebp) + while (n -- > 0) { + 800f69: eb 2e jmp 800f99 + if (*s1 != *s2) { + 800f6b: 8b 45 fc mov -0x4(%ebp),%eax + 800f6e: 0f b6 10 movzbl (%eax),%edx + 800f71: 8b 45 f8 mov -0x8(%ebp),%eax + 800f74: 0f b6 00 movzbl (%eax),%eax + 800f77: 38 c2 cmp %al,%dl + 800f79: 74 18 je 800f93 + return (int)((unsigned char)*s1 - (unsigned char)*s2); + 800f7b: 8b 45 fc mov -0x4(%ebp),%eax + 800f7e: 0f b6 00 movzbl (%eax),%eax + 800f81: 0f b6 d0 movzbl %al,%edx + 800f84: 8b 45 f8 mov -0x8(%ebp),%eax + 800f87: 0f b6 00 movzbl (%eax),%eax + 800f8a: 0f b6 c8 movzbl %al,%ecx + 800f8d: 89 d0 mov %edx,%eax + 800f8f: 29 c8 sub %ecx,%eax + 800f91: eb 18 jmp 800fab + } + s1 ++, s2 ++; + 800f93: ff 45 fc incl -0x4(%ebp) + 800f96: ff 45 f8 incl -0x8(%ebp) + while (n -- > 0) { + 800f99: 8b 45 10 mov 0x10(%ebp),%eax + 800f9c: 8d 50 ff lea -0x1(%eax),%edx + 800f9f: 89 55 10 mov %edx,0x10(%ebp) + 800fa2: 85 c0 test %eax,%eax + 800fa4: 75 c5 jne 800f6b + } + return 0; + 800fa6: b8 00 00 00 00 mov $0x0,%eax +} + 800fab: 89 ec mov %ebp,%esp + 800fad: 5d pop %ebp + 800fae: c3 ret + +00800faf
: +#include +#include + +int +main(void) { + 800faf: 55 push %ebp + 800fb0: 89 e5 mov %esp,%ebp + 800fb2: 83 e4 f0 and $0xfffffff0,%esp + 800fb5: 83 ec 10 sub $0x10,%esp + asm volatile("int $14"); + 800fb8: cd 0e int $0xe + panic("FAIL: T.T\n"); + 800fba: c7 44 24 08 c0 12 80 movl $0x8012c0,0x8(%esp) + 800fc1: 00 + 800fc2: c7 44 24 04 07 00 00 movl $0x7,0x4(%esp) + 800fc9: 00 + 800fca: c7 04 24 cb 12 80 00 movl $0x8012cb,(%esp) + 800fd1: e8 59 f0 ff ff call 80002f <__panic> diff --git a/labcodes/lab5/obj/user/softint.d b/labcodes/lab5/obj/user/softint.d new file mode 100644 index 0000000000000000000000000000000000000000..22c1094e407456fa92b2da8d32132f81817ce90b --- /dev/null +++ b/labcodes/lab5/obj/user/softint.d @@ -0,0 +1,2 @@ +obj/user/softint.o obj/user/softint.d: user/softint.c libs/stdio.h \ + libs/defs.h libs/stdarg.h user/libs/ulib.h diff --git a/labcodes/lab5/obj/user/softint.o b/labcodes/lab5/obj/user/softint.o new file mode 100644 index 0000000000000000000000000000000000000000..0196214e77a831b6d439238b32b25d42d14fc98b Binary files /dev/null and b/labcodes/lab5/obj/user/softint.o differ diff --git a/labcodes/lab5/obj/user/softint.sym b/labcodes/lab5/obj/user/softint.sym new file mode 100644 index 0000000000000000000000000000000000000000..6da511d852aa0efbf42c20484150dacd3ea1f98a --- /dev/null +++ b/labcodes/lab5/obj/user/softint.sym @@ -0,0 +1,66 @@ +00000000 panic.c +00000000 stdio.c +008000c8 cputch +00000000 syscall.c +00800199 syscall +00000000 ulib.c +00000000 umain.c +00000000 hash.c +00000000 printfmt.c +008010e0 error_string +008003ad printnum +008004af getuint +008004fe getint +0080094f sprintputch +00000000 rand.c +00802000 next +00000000 string.c +00000000 softint.c +00800b53 strcpy +00800329 yield +0080030d waitpid +00800245 sys_yield +00800e65 memmove +00800985 snprintf +00800576 vprintfmt +0080020b sys_fork +00800120 cprintf +0080034e getpid +00800f08 memcpy +008009bb vsnprintf +0080036d umain +002026bc __STAB_END__ +0080025b sys_kill +002026bd __STABSTR_BEGIN__ +0080002f __panic +00800ccb strtol +00800b22 strnlen +0080035d print_pgdir +00800339 kill +00800c9b strfind +008002ef wait +00800020 _start +00800a21 rand +00800c14 strncmp +0080028e sys_putc +00800b92 strncpy +00800f57 memcmp +008002e0 fork +00800e23 memset +00800faf main +00800ae0 srand +00800386 hash32 +00800545 printfmt +002035cc __STABSTR_END__ +00800bcb strcmp +008000eb vcprintf +0080007f __warn +00800148 cputs +008002c1 exit +00800221 sys_wait +008001ee sys_exit +00200010 __STAB_BEGIN__ +00800af9 strlen +008002ab sys_pgdir +00800c67 strchr +00800278 sys_getpid diff --git a/labcodes/lab5/obj/user/spin.asm b/labcodes/lab5/obj/user/spin.asm new file mode 100644 index 0000000000000000000000000000000000000000..f46f1b2aef6ce2b1439a1369fe16158cf6f4ae3a --- /dev/null +++ b/labcodes/lab5/obj/user/spin.asm @@ -0,0 +1,2393 @@ + +obj/__user_spin.out: file format elf32-i386 + + +Disassembly of section .text: + +00800020 <_start>: +.text +.globl _start +_start: + # set ebp for backtrace + movl $0x0, %ebp + 800020: bd 00 00 00 00 mov $0x0,%ebp + + # move down the esp register + # since it may cause page fault in backtrace + subl $0x20, %esp + 800025: 83 ec 20 sub $0x20,%esp + + # call user-program function + call umain + 800028: e8 40 03 00 00 call 80036d +1: jmp 1b + 80002d: eb fe jmp 80002d <_start+0xd> + +0080002f <__panic>: +#include +#include +#include + +void +__panic(const char *file, int line, const char *fmt, ...) { + 80002f: 55 push %ebp + 800030: 89 e5 mov %esp,%ebp + 800032: 83 ec 28 sub $0x28,%esp + // print the 'message' + va_list ap; + va_start(ap, fmt); + 800035: 8d 45 14 lea 0x14(%ebp),%eax + 800038: 89 45 f4 mov %eax,-0xc(%ebp) + cprintf("user panic at %s:%d:\n ", file, line); + 80003b: 8b 45 0c mov 0xc(%ebp),%eax + 80003e: 89 44 24 08 mov %eax,0x8(%esp) + 800042: 8b 45 08 mov 0x8(%ebp),%eax + 800045: 89 44 24 04 mov %eax,0x4(%esp) + 800049: c7 04 24 e0 10 80 00 movl $0x8010e0,(%esp) + 800050: e8 cb 00 00 00 call 800120 + vcprintf(fmt, ap); + 800055: 8b 45 f4 mov -0xc(%ebp),%eax + 800058: 89 44 24 04 mov %eax,0x4(%esp) + 80005c: 8b 45 10 mov 0x10(%ebp),%eax + 80005f: 89 04 24 mov %eax,(%esp) + 800062: e8 84 00 00 00 call 8000eb + cprintf("\n"); + 800067: c7 04 24 fa 10 80 00 movl $0x8010fa,(%esp) + 80006e: e8 ad 00 00 00 call 800120 + va_end(ap); + exit(-E_PANIC); + 800073: c7 04 24 f6 ff ff ff movl $0xfffffff6,(%esp) + 80007a: e8 42 02 00 00 call 8002c1 + +0080007f <__warn>: +} + +void +__warn(const char *file, int line, const char *fmt, ...) { + 80007f: 55 push %ebp + 800080: 89 e5 mov %esp,%ebp + 800082: 83 ec 28 sub $0x28,%esp + va_list ap; + va_start(ap, fmt); + 800085: 8d 45 14 lea 0x14(%ebp),%eax + 800088: 89 45 f4 mov %eax,-0xc(%ebp) + cprintf("user warning at %s:%d:\n ", file, line); + 80008b: 8b 45 0c mov 0xc(%ebp),%eax + 80008e: 89 44 24 08 mov %eax,0x8(%esp) + 800092: 8b 45 08 mov 0x8(%ebp),%eax + 800095: 89 44 24 04 mov %eax,0x4(%esp) + 800099: c7 04 24 fc 10 80 00 movl $0x8010fc,(%esp) + 8000a0: e8 7b 00 00 00 call 800120 + vcprintf(fmt, ap); + 8000a5: 8b 45 f4 mov -0xc(%ebp),%eax + 8000a8: 89 44 24 04 mov %eax,0x4(%esp) + 8000ac: 8b 45 10 mov 0x10(%ebp),%eax + 8000af: 89 04 24 mov %eax,(%esp) + 8000b2: e8 34 00 00 00 call 8000eb + cprintf("\n"); + 8000b7: c7 04 24 fa 10 80 00 movl $0x8010fa,(%esp) + 8000be: e8 5d 00 00 00 call 800120 + va_end(ap); +} + 8000c3: 90 nop + 8000c4: 89 ec mov %ebp,%esp + 8000c6: 5d pop %ebp + 8000c7: c3 ret + +008000c8 : +/* * + * cputch - writes a single character @c to stdout, and it will + * increace the value of counter pointed by @cnt. + * */ +static void +cputch(int c, int *cnt) { + 8000c8: 55 push %ebp + 8000c9: 89 e5 mov %esp,%ebp + 8000cb: 83 ec 18 sub $0x18,%esp + sys_putc(c); + 8000ce: 8b 45 08 mov 0x8(%ebp),%eax + 8000d1: 89 04 24 mov %eax,(%esp) + 8000d4: e8 b5 01 00 00 call 80028e + (*cnt) ++; + 8000d9: 8b 45 0c mov 0xc(%ebp),%eax + 8000dc: 8b 00 mov (%eax),%eax + 8000de: 8d 50 01 lea 0x1(%eax),%edx + 8000e1: 8b 45 0c mov 0xc(%ebp),%eax + 8000e4: 89 10 mov %edx,(%eax) +} + 8000e6: 90 nop + 8000e7: 89 ec mov %ebp,%esp + 8000e9: 5d pop %ebp + 8000ea: c3 ret + +008000eb : + * + * Call this function if you are already dealing with a va_list. + * Or you probably want cprintf() instead. + * */ +int +vcprintf(const char *fmt, va_list ap) { + 8000eb: 55 push %ebp + 8000ec: 89 e5 mov %esp,%ebp + 8000ee: 83 ec 28 sub $0x28,%esp + int cnt = 0; + 8000f1: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + vprintfmt((void*)cputch, &cnt, fmt, ap); + 8000f8: 8b 45 0c mov 0xc(%ebp),%eax + 8000fb: 89 44 24 0c mov %eax,0xc(%esp) + 8000ff: 8b 45 08 mov 0x8(%ebp),%eax + 800102: 89 44 24 08 mov %eax,0x8(%esp) + 800106: 8d 45 f4 lea -0xc(%ebp),%eax + 800109: 89 44 24 04 mov %eax,0x4(%esp) + 80010d: c7 04 24 c8 00 80 00 movl $0x8000c8,(%esp) + 800114: e8 5d 04 00 00 call 800576 + return cnt; + 800119: 8b 45 f4 mov -0xc(%ebp),%eax +} + 80011c: 89 ec mov %ebp,%esp + 80011e: 5d pop %ebp + 80011f: c3 ret + +00800120 : + * + * The return value is the number of characters which would be + * written to stdout. + * */ +int +cprintf(const char *fmt, ...) { + 800120: 55 push %ebp + 800121: 89 e5 mov %esp,%ebp + 800123: 83 ec 28 sub $0x28,%esp + va_list ap; + + va_start(ap, fmt); + 800126: 8d 45 0c lea 0xc(%ebp),%eax + 800129: 89 45 f0 mov %eax,-0x10(%ebp) + int cnt = vcprintf(fmt, ap); + 80012c: 8b 45 f0 mov -0x10(%ebp),%eax + 80012f: 89 44 24 04 mov %eax,0x4(%esp) + 800133: 8b 45 08 mov 0x8(%ebp),%eax + 800136: 89 04 24 mov %eax,(%esp) + 800139: e8 ad ff ff ff call 8000eb + 80013e: 89 45 f4 mov %eax,-0xc(%ebp) + va_end(ap); + + return cnt; + 800141: 8b 45 f4 mov -0xc(%ebp),%eax +} + 800144: 89 ec mov %ebp,%esp + 800146: 5d pop %ebp + 800147: c3 ret + +00800148 : +/* * + * cputs- writes the string pointed by @str to stdout and + * appends a newline character. + * */ +int +cputs(const char *str) { + 800148: 55 push %ebp + 800149: 89 e5 mov %esp,%ebp + 80014b: 83 ec 28 sub $0x28,%esp + int cnt = 0; + 80014e: c7 45 f0 00 00 00 00 movl $0x0,-0x10(%ebp) + char c; + while ((c = *str ++) != '\0') { + 800155: eb 13 jmp 80016a + cputch(c, &cnt); + 800157: 0f be 45 f7 movsbl -0x9(%ebp),%eax + 80015b: 8d 55 f0 lea -0x10(%ebp),%edx + 80015e: 89 54 24 04 mov %edx,0x4(%esp) + 800162: 89 04 24 mov %eax,(%esp) + 800165: e8 5e ff ff ff call 8000c8 + while ((c = *str ++) != '\0') { + 80016a: 8b 45 08 mov 0x8(%ebp),%eax + 80016d: 8d 50 01 lea 0x1(%eax),%edx + 800170: 89 55 08 mov %edx,0x8(%ebp) + 800173: 0f b6 00 movzbl (%eax),%eax + 800176: 88 45 f7 mov %al,-0x9(%ebp) + 800179: 80 7d f7 00 cmpb $0x0,-0x9(%ebp) + 80017d: 75 d8 jne 800157 + } + cputch('\n', &cnt); + 80017f: 8d 45 f0 lea -0x10(%ebp),%eax + 800182: 89 44 24 04 mov %eax,0x4(%esp) + 800186: c7 04 24 0a 00 00 00 movl $0xa,(%esp) + 80018d: e8 36 ff ff ff call 8000c8 + return cnt; + 800192: 8b 45 f0 mov -0x10(%ebp),%eax +} + 800195: 89 ec mov %ebp,%esp + 800197: 5d pop %ebp + 800198: c3 ret + +00800199 : +#include + +#define MAX_ARGS 5 + +static inline int +syscall(int num, ...) { + 800199: 55 push %ebp + 80019a: 89 e5 mov %esp,%ebp + 80019c: 57 push %edi + 80019d: 56 push %esi + 80019e: 53 push %ebx + 80019f: 83 ec 20 sub $0x20,%esp + va_list ap; + va_start(ap, num); + 8001a2: 8d 45 0c lea 0xc(%ebp),%eax + 8001a5: 89 45 e8 mov %eax,-0x18(%ebp) + uint32_t a[MAX_ARGS]; + int i, ret; + for (i = 0; i < MAX_ARGS; i ++) { + 8001a8: c7 45 f0 00 00 00 00 movl $0x0,-0x10(%ebp) + 8001af: eb 15 jmp 8001c6 + a[i] = va_arg(ap, uint32_t); + 8001b1: 8b 45 e8 mov -0x18(%ebp),%eax + 8001b4: 8d 50 04 lea 0x4(%eax),%edx + 8001b7: 89 55 e8 mov %edx,-0x18(%ebp) + 8001ba: 8b 10 mov (%eax),%edx + 8001bc: 8b 45 f0 mov -0x10(%ebp),%eax + 8001bf: 89 54 85 d4 mov %edx,-0x2c(%ebp,%eax,4) + for (i = 0; i < MAX_ARGS; i ++) { + 8001c3: ff 45 f0 incl -0x10(%ebp) + 8001c6: 83 7d f0 04 cmpl $0x4,-0x10(%ebp) + 8001ca: 7e e5 jle 8001b1 + asm volatile ( + "int %1;" + : "=a" (ret) + : "i" (T_SYSCALL), + "a" (num), + "d" (a[0]), + 8001cc: 8b 55 d4 mov -0x2c(%ebp),%edx + "c" (a[1]), + 8001cf: 8b 4d d8 mov -0x28(%ebp),%ecx + "b" (a[2]), + 8001d2: 8b 5d dc mov -0x24(%ebp),%ebx + "D" (a[3]), + 8001d5: 8b 7d e0 mov -0x20(%ebp),%edi + "S" (a[4]) + 8001d8: 8b 75 e4 mov -0x1c(%ebp),%esi + asm volatile ( + 8001db: 8b 45 08 mov 0x8(%ebp),%eax + 8001de: cd 80 int $0x80 + 8001e0: 89 45 ec mov %eax,-0x14(%ebp) + : "cc", "memory"); + return ret; + 8001e3: 8b 45 ec mov -0x14(%ebp),%eax +} + 8001e6: 83 c4 20 add $0x20,%esp + 8001e9: 5b pop %ebx + 8001ea: 5e pop %esi + 8001eb: 5f pop %edi + 8001ec: 5d pop %ebp + 8001ed: c3 ret + +008001ee : + +int +sys_exit(int error_code) { + 8001ee: 55 push %ebp + 8001ef: 89 e5 mov %esp,%ebp + 8001f1: 83 ec 08 sub $0x8,%esp + return syscall(SYS_exit, error_code); + 8001f4: 8b 45 08 mov 0x8(%ebp),%eax + 8001f7: 89 44 24 04 mov %eax,0x4(%esp) + 8001fb: c7 04 24 01 00 00 00 movl $0x1,(%esp) + 800202: e8 92 ff ff ff call 800199 +} + 800207: 89 ec mov %ebp,%esp + 800209: 5d pop %ebp + 80020a: c3 ret + +0080020b : + +int +sys_fork(void) { + 80020b: 55 push %ebp + 80020c: 89 e5 mov %esp,%ebp + 80020e: 83 ec 04 sub $0x4,%esp + return syscall(SYS_fork); + 800211: c7 04 24 02 00 00 00 movl $0x2,(%esp) + 800218: e8 7c ff ff ff call 800199 +} + 80021d: 89 ec mov %ebp,%esp + 80021f: 5d pop %ebp + 800220: c3 ret + +00800221 : + +int +sys_wait(int pid, int *store) { + 800221: 55 push %ebp + 800222: 89 e5 mov %esp,%ebp + 800224: 83 ec 0c sub $0xc,%esp + return syscall(SYS_wait, pid, store); + 800227: 8b 45 0c mov 0xc(%ebp),%eax + 80022a: 89 44 24 08 mov %eax,0x8(%esp) + 80022e: 8b 45 08 mov 0x8(%ebp),%eax + 800231: 89 44 24 04 mov %eax,0x4(%esp) + 800235: c7 04 24 03 00 00 00 movl $0x3,(%esp) + 80023c: e8 58 ff ff ff call 800199 +} + 800241: 89 ec mov %ebp,%esp + 800243: 5d pop %ebp + 800244: c3 ret + +00800245 : + +int +sys_yield(void) { + 800245: 55 push %ebp + 800246: 89 e5 mov %esp,%ebp + 800248: 83 ec 04 sub $0x4,%esp + return syscall(SYS_yield); + 80024b: c7 04 24 0a 00 00 00 movl $0xa,(%esp) + 800252: e8 42 ff ff ff call 800199 +} + 800257: 89 ec mov %ebp,%esp + 800259: 5d pop %ebp + 80025a: c3 ret + +0080025b : + +int +sys_kill(int pid) { + 80025b: 55 push %ebp + 80025c: 89 e5 mov %esp,%ebp + 80025e: 83 ec 08 sub $0x8,%esp + return syscall(SYS_kill, pid); + 800261: 8b 45 08 mov 0x8(%ebp),%eax + 800264: 89 44 24 04 mov %eax,0x4(%esp) + 800268: c7 04 24 0c 00 00 00 movl $0xc,(%esp) + 80026f: e8 25 ff ff ff call 800199 +} + 800274: 89 ec mov %ebp,%esp + 800276: 5d pop %ebp + 800277: c3 ret + +00800278 : + +int +sys_getpid(void) { + 800278: 55 push %ebp + 800279: 89 e5 mov %esp,%ebp + 80027b: 83 ec 04 sub $0x4,%esp + return syscall(SYS_getpid); + 80027e: c7 04 24 12 00 00 00 movl $0x12,(%esp) + 800285: e8 0f ff ff ff call 800199 +} + 80028a: 89 ec mov %ebp,%esp + 80028c: 5d pop %ebp + 80028d: c3 ret + +0080028e : + +int +sys_putc(int c) { + 80028e: 55 push %ebp + 80028f: 89 e5 mov %esp,%ebp + 800291: 83 ec 08 sub $0x8,%esp + return syscall(SYS_putc, c); + 800294: 8b 45 08 mov 0x8(%ebp),%eax + 800297: 89 44 24 04 mov %eax,0x4(%esp) + 80029b: c7 04 24 1e 00 00 00 movl $0x1e,(%esp) + 8002a2: e8 f2 fe ff ff call 800199 +} + 8002a7: 89 ec mov %ebp,%esp + 8002a9: 5d pop %ebp + 8002aa: c3 ret + +008002ab : + +int +sys_pgdir(void) { + 8002ab: 55 push %ebp + 8002ac: 89 e5 mov %esp,%ebp + 8002ae: 83 ec 04 sub $0x4,%esp + return syscall(SYS_pgdir); + 8002b1: c7 04 24 1f 00 00 00 movl $0x1f,(%esp) + 8002b8: e8 dc fe ff ff call 800199 +} + 8002bd: 89 ec mov %ebp,%esp + 8002bf: 5d pop %ebp + 8002c0: c3 ret + +008002c1 : +#include +#include +#include + +void +exit(int error_code) { + 8002c1: 55 push %ebp + 8002c2: 89 e5 mov %esp,%ebp + 8002c4: 83 ec 18 sub $0x18,%esp + sys_exit(error_code); + 8002c7: 8b 45 08 mov 0x8(%ebp),%eax + 8002ca: 89 04 24 mov %eax,(%esp) + 8002cd: e8 1c ff ff ff call 8001ee + cprintf("BUG: exit failed.\n"); + 8002d2: c7 04 24 18 11 80 00 movl $0x801118,(%esp) + 8002d9: e8 42 fe ff ff call 800120 + while (1); + 8002de: eb fe jmp 8002de + +008002e0 : +} + +int +fork(void) { + 8002e0: 55 push %ebp + 8002e1: 89 e5 mov %esp,%ebp + 8002e3: 83 ec 08 sub $0x8,%esp + return sys_fork(); + 8002e6: e8 20 ff ff ff call 80020b +} + 8002eb: 89 ec mov %ebp,%esp + 8002ed: 5d pop %ebp + 8002ee: c3 ret + +008002ef : + +int +wait(void) { + 8002ef: 55 push %ebp + 8002f0: 89 e5 mov %esp,%ebp + 8002f2: 83 ec 18 sub $0x18,%esp + return sys_wait(0, NULL); + 8002f5: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) + 8002fc: 00 + 8002fd: c7 04 24 00 00 00 00 movl $0x0,(%esp) + 800304: e8 18 ff ff ff call 800221 +} + 800309: 89 ec mov %ebp,%esp + 80030b: 5d pop %ebp + 80030c: c3 ret + +0080030d : + +int +waitpid(int pid, int *store) { + 80030d: 55 push %ebp + 80030e: 89 e5 mov %esp,%ebp + 800310: 83 ec 18 sub $0x18,%esp + return sys_wait(pid, store); + 800313: 8b 45 0c mov 0xc(%ebp),%eax + 800316: 89 44 24 04 mov %eax,0x4(%esp) + 80031a: 8b 45 08 mov 0x8(%ebp),%eax + 80031d: 89 04 24 mov %eax,(%esp) + 800320: e8 fc fe ff ff call 800221 +} + 800325: 89 ec mov %ebp,%esp + 800327: 5d pop %ebp + 800328: c3 ret + +00800329 : + +void +yield(void) { + 800329: 55 push %ebp + 80032a: 89 e5 mov %esp,%ebp + 80032c: 83 ec 08 sub $0x8,%esp + sys_yield(); + 80032f: e8 11 ff ff ff call 800245 +} + 800334: 90 nop + 800335: 89 ec mov %ebp,%esp + 800337: 5d pop %ebp + 800338: c3 ret + +00800339 : + +int +kill(int pid) { + 800339: 55 push %ebp + 80033a: 89 e5 mov %esp,%ebp + 80033c: 83 ec 18 sub $0x18,%esp + return sys_kill(pid); + 80033f: 8b 45 08 mov 0x8(%ebp),%eax + 800342: 89 04 24 mov %eax,(%esp) + 800345: e8 11 ff ff ff call 80025b +} + 80034a: 89 ec mov %ebp,%esp + 80034c: 5d pop %ebp + 80034d: c3 ret + +0080034e : + +int +getpid(void) { + 80034e: 55 push %ebp + 80034f: 89 e5 mov %esp,%ebp + 800351: 83 ec 08 sub $0x8,%esp + return sys_getpid(); + 800354: e8 1f ff ff ff call 800278 +} + 800359: 89 ec mov %ebp,%esp + 80035b: 5d pop %ebp + 80035c: c3 ret + +0080035d : + +//print_pgdir - print the PDT&PT +void +print_pgdir(void) { + 80035d: 55 push %ebp + 80035e: 89 e5 mov %esp,%ebp + 800360: 83 ec 08 sub $0x8,%esp + sys_pgdir(); + 800363: e8 43 ff ff ff call 8002ab +} + 800368: 90 nop + 800369: 89 ec mov %ebp,%esp + 80036b: 5d pop %ebp + 80036c: c3 ret + +0080036d : +#include + +int main(void); + +void +umain(void) { + 80036d: 55 push %ebp + 80036e: 89 e5 mov %esp,%ebp + 800370: 83 ec 28 sub $0x28,%esp + int ret = main(); + 800373: e8 37 0c 00 00 call 800faf
+ 800378: 89 45 f4 mov %eax,-0xc(%ebp) + exit(ret); + 80037b: 8b 45 f4 mov -0xc(%ebp),%eax + 80037e: 89 04 24 mov %eax,(%esp) + 800381: e8 3b ff ff ff call 8002c1 + +00800386 : + * @bits: the number of bits in a return value + * + * High bits are more random, so we use them. + * */ +uint32_t +hash32(uint32_t val, unsigned int bits) { + 800386: 55 push %ebp + 800387: 89 e5 mov %esp,%ebp + 800389: 83 ec 10 sub $0x10,%esp + uint32_t hash = val * GOLDEN_RATIO_PRIME_32; + 80038c: 8b 45 08 mov 0x8(%ebp),%eax + 80038f: 69 c0 01 00 37 9e imul $0x9e370001,%eax,%eax + 800395: 89 45 fc mov %eax,-0x4(%ebp) + return (hash >> (32 - bits)); + 800398: b8 20 00 00 00 mov $0x20,%eax + 80039d: 2b 45 0c sub 0xc(%ebp),%eax + 8003a0: 8b 55 fc mov -0x4(%ebp),%edx + 8003a3: 88 c1 mov %al,%cl + 8003a5: d3 ea shr %cl,%edx + 8003a7: 89 d0 mov %edx,%eax +} + 8003a9: 89 ec mov %ebp,%esp + 8003ab: 5d pop %ebp + 8003ac: c3 ret + +008003ad : + * @width: maximum number of digits, if the actual width is less than @width, use @padc instead + * @padc: character that padded on the left if the actual width is less than @width + * */ +static void +printnum(void (*putch)(int, void*), void *putdat, + unsigned long long num, unsigned base, int width, int padc) { + 8003ad: 55 push %ebp + 8003ae: 89 e5 mov %esp,%ebp + 8003b0: 83 ec 58 sub $0x58,%esp + 8003b3: 8b 45 10 mov 0x10(%ebp),%eax + 8003b6: 89 45 d0 mov %eax,-0x30(%ebp) + 8003b9: 8b 45 14 mov 0x14(%ebp),%eax + 8003bc: 89 45 d4 mov %eax,-0x2c(%ebp) + unsigned long long result = num; + 8003bf: 8b 45 d0 mov -0x30(%ebp),%eax + 8003c2: 8b 55 d4 mov -0x2c(%ebp),%edx + 8003c5: 89 45 e8 mov %eax,-0x18(%ebp) + 8003c8: 89 55 ec mov %edx,-0x14(%ebp) + unsigned mod = do_div(result, base); + 8003cb: 8b 45 18 mov 0x18(%ebp),%eax + 8003ce: 89 45 e4 mov %eax,-0x1c(%ebp) + 8003d1: 8b 45 e8 mov -0x18(%ebp),%eax + 8003d4: 8b 55 ec mov -0x14(%ebp),%edx + 8003d7: 89 45 e0 mov %eax,-0x20(%ebp) + 8003da: 89 55 f0 mov %edx,-0x10(%ebp) + 8003dd: 8b 45 f0 mov -0x10(%ebp),%eax + 8003e0: 89 45 f4 mov %eax,-0xc(%ebp) + 8003e3: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) + 8003e7: 74 1c je 800405 + 8003e9: 8b 45 f0 mov -0x10(%ebp),%eax + 8003ec: ba 00 00 00 00 mov $0x0,%edx + 8003f1: f7 75 e4 divl -0x1c(%ebp) + 8003f4: 89 55 f4 mov %edx,-0xc(%ebp) + 8003f7: 8b 45 f0 mov -0x10(%ebp),%eax + 8003fa: ba 00 00 00 00 mov $0x0,%edx + 8003ff: f7 75 e4 divl -0x1c(%ebp) + 800402: 89 45 f0 mov %eax,-0x10(%ebp) + 800405: 8b 45 e0 mov -0x20(%ebp),%eax + 800408: 8b 55 f4 mov -0xc(%ebp),%edx + 80040b: f7 75 e4 divl -0x1c(%ebp) + 80040e: 89 45 e0 mov %eax,-0x20(%ebp) + 800411: 89 55 dc mov %edx,-0x24(%ebp) + 800414: 8b 45 e0 mov -0x20(%ebp),%eax + 800417: 8b 55 f0 mov -0x10(%ebp),%edx + 80041a: 89 45 e8 mov %eax,-0x18(%ebp) + 80041d: 89 55 ec mov %edx,-0x14(%ebp) + 800420: 8b 45 dc mov -0x24(%ebp),%eax + 800423: 89 45 d8 mov %eax,-0x28(%ebp) + + // first recursively print all preceding (more significant) digits + if (num >= base) { + 800426: 8b 45 18 mov 0x18(%ebp),%eax + 800429: ba 00 00 00 00 mov $0x0,%edx + 80042e: 8b 4d d4 mov -0x2c(%ebp),%ecx + 800431: 39 45 d0 cmp %eax,-0x30(%ebp) + 800434: 19 d1 sbb %edx,%ecx + 800436: 72 4c jb 800484 + printnum(putch, putdat, result, base, width - 1, padc); + 800438: 8b 45 1c mov 0x1c(%ebp),%eax + 80043b: 8d 50 ff lea -0x1(%eax),%edx + 80043e: 8b 45 20 mov 0x20(%ebp),%eax + 800441: 89 44 24 18 mov %eax,0x18(%esp) + 800445: 89 54 24 14 mov %edx,0x14(%esp) + 800449: 8b 45 18 mov 0x18(%ebp),%eax + 80044c: 89 44 24 10 mov %eax,0x10(%esp) + 800450: 8b 45 e8 mov -0x18(%ebp),%eax + 800453: 8b 55 ec mov -0x14(%ebp),%edx + 800456: 89 44 24 08 mov %eax,0x8(%esp) + 80045a: 89 54 24 0c mov %edx,0xc(%esp) + 80045e: 8b 45 0c mov 0xc(%ebp),%eax + 800461: 89 44 24 04 mov %eax,0x4(%esp) + 800465: 8b 45 08 mov 0x8(%ebp),%eax + 800468: 89 04 24 mov %eax,(%esp) + 80046b: e8 3d ff ff ff call 8003ad + 800470: eb 1b jmp 80048d + } else { + // print any needed pad characters before first digit + while (-- width > 0) + putch(padc, putdat); + 800472: 8b 45 0c mov 0xc(%ebp),%eax + 800475: 89 44 24 04 mov %eax,0x4(%esp) + 800479: 8b 45 20 mov 0x20(%ebp),%eax + 80047c: 89 04 24 mov %eax,(%esp) + 80047f: 8b 45 08 mov 0x8(%ebp),%eax + 800482: ff d0 call *%eax + while (-- width > 0) + 800484: ff 4d 1c decl 0x1c(%ebp) + 800487: 83 7d 1c 00 cmpl $0x0,0x1c(%ebp) + 80048b: 7f e5 jg 800472 + } + // then print this (the least significant) digit + putch("0123456789abcdef"[mod], putdat); + 80048d: 8b 45 d8 mov -0x28(%ebp),%eax + 800490: 05 44 12 80 00 add $0x801244,%eax + 800495: 0f b6 00 movzbl (%eax),%eax + 800498: 0f be c0 movsbl %al,%eax + 80049b: 8b 55 0c mov 0xc(%ebp),%edx + 80049e: 89 54 24 04 mov %edx,0x4(%esp) + 8004a2: 89 04 24 mov %eax,(%esp) + 8004a5: 8b 45 08 mov 0x8(%ebp),%eax + 8004a8: ff d0 call *%eax +} + 8004aa: 90 nop + 8004ab: 89 ec mov %ebp,%esp + 8004ad: 5d pop %ebp + 8004ae: c3 ret + +008004af : + * getuint - get an unsigned int of various possible sizes from a varargs list + * @ap: a varargs list pointer + * @lflag: determines the size of the vararg that @ap points to + * */ +static unsigned long long +getuint(va_list *ap, int lflag) { + 8004af: 55 push %ebp + 8004b0: 89 e5 mov %esp,%ebp + if (lflag >= 2) { + 8004b2: 83 7d 0c 01 cmpl $0x1,0xc(%ebp) + 8004b6: 7e 14 jle 8004cc + return va_arg(*ap, unsigned long long); + 8004b8: 8b 45 08 mov 0x8(%ebp),%eax + 8004bb: 8b 00 mov (%eax),%eax + 8004bd: 8d 48 08 lea 0x8(%eax),%ecx + 8004c0: 8b 55 08 mov 0x8(%ebp),%edx + 8004c3: 89 0a mov %ecx,(%edx) + 8004c5: 8b 50 04 mov 0x4(%eax),%edx + 8004c8: 8b 00 mov (%eax),%eax + 8004ca: eb 30 jmp 8004fc + } + else if (lflag) { + 8004cc: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) + 8004d0: 74 16 je 8004e8 + return va_arg(*ap, unsigned long); + 8004d2: 8b 45 08 mov 0x8(%ebp),%eax + 8004d5: 8b 00 mov (%eax),%eax + 8004d7: 8d 48 04 lea 0x4(%eax),%ecx + 8004da: 8b 55 08 mov 0x8(%ebp),%edx + 8004dd: 89 0a mov %ecx,(%edx) + 8004df: 8b 00 mov (%eax),%eax + 8004e1: ba 00 00 00 00 mov $0x0,%edx + 8004e6: eb 14 jmp 8004fc + } + else { + return va_arg(*ap, unsigned int); + 8004e8: 8b 45 08 mov 0x8(%ebp),%eax + 8004eb: 8b 00 mov (%eax),%eax + 8004ed: 8d 48 04 lea 0x4(%eax),%ecx + 8004f0: 8b 55 08 mov 0x8(%ebp),%edx + 8004f3: 89 0a mov %ecx,(%edx) + 8004f5: 8b 00 mov (%eax),%eax + 8004f7: ba 00 00 00 00 mov $0x0,%edx + } +} + 8004fc: 5d pop %ebp + 8004fd: c3 ret + +008004fe : + * getint - same as getuint but signed, we can't use getuint because of sign extension + * @ap: a varargs list pointer + * @lflag: determines the size of the vararg that @ap points to + * */ +static long long +getint(va_list *ap, int lflag) { + 8004fe: 55 push %ebp + 8004ff: 89 e5 mov %esp,%ebp + if (lflag >= 2) { + 800501: 83 7d 0c 01 cmpl $0x1,0xc(%ebp) + 800505: 7e 14 jle 80051b + return va_arg(*ap, long long); + 800507: 8b 45 08 mov 0x8(%ebp),%eax + 80050a: 8b 00 mov (%eax),%eax + 80050c: 8d 48 08 lea 0x8(%eax),%ecx + 80050f: 8b 55 08 mov 0x8(%ebp),%edx + 800512: 89 0a mov %ecx,(%edx) + 800514: 8b 50 04 mov 0x4(%eax),%edx + 800517: 8b 00 mov (%eax),%eax + 800519: eb 28 jmp 800543 + } + else if (lflag) { + 80051b: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) + 80051f: 74 12 je 800533 + return va_arg(*ap, long); + 800521: 8b 45 08 mov 0x8(%ebp),%eax + 800524: 8b 00 mov (%eax),%eax + 800526: 8d 48 04 lea 0x4(%eax),%ecx + 800529: 8b 55 08 mov 0x8(%ebp),%edx + 80052c: 89 0a mov %ecx,(%edx) + 80052e: 8b 00 mov (%eax),%eax + 800530: 99 cltd + 800531: eb 10 jmp 800543 + } + else { + return va_arg(*ap, int); + 800533: 8b 45 08 mov 0x8(%ebp),%eax + 800536: 8b 00 mov (%eax),%eax + 800538: 8d 48 04 lea 0x4(%eax),%ecx + 80053b: 8b 55 08 mov 0x8(%ebp),%edx + 80053e: 89 0a mov %ecx,(%edx) + 800540: 8b 00 mov (%eax),%eax + 800542: 99 cltd + } +} + 800543: 5d pop %ebp + 800544: c3 ret + +00800545 : + * @putch: specified putch function, print a single character + * @putdat: used by @putch function + * @fmt: the format string to use + * */ +void +printfmt(void (*putch)(int, void*), void *putdat, const char *fmt, ...) { + 800545: 55 push %ebp + 800546: 89 e5 mov %esp,%ebp + 800548: 83 ec 28 sub $0x28,%esp + va_list ap; + + va_start(ap, fmt); + 80054b: 8d 45 14 lea 0x14(%ebp),%eax + 80054e: 89 45 f4 mov %eax,-0xc(%ebp) + vprintfmt(putch, putdat, fmt, ap); + 800551: 8b 45 f4 mov -0xc(%ebp),%eax + 800554: 89 44 24 0c mov %eax,0xc(%esp) + 800558: 8b 45 10 mov 0x10(%ebp),%eax + 80055b: 89 44 24 08 mov %eax,0x8(%esp) + 80055f: 8b 45 0c mov 0xc(%ebp),%eax + 800562: 89 44 24 04 mov %eax,0x4(%esp) + 800566: 8b 45 08 mov 0x8(%ebp),%eax + 800569: 89 04 24 mov %eax,(%esp) + 80056c: e8 05 00 00 00 call 800576 + va_end(ap); +} + 800571: 90 nop + 800572: 89 ec mov %ebp,%esp + 800574: 5d pop %ebp + 800575: c3 ret + +00800576 : + * + * Call this function if you are already dealing with a va_list. + * Or you probably want printfmt() instead. + * */ +void +vprintfmt(void (*putch)(int, void*), void *putdat, const char *fmt, va_list ap) { + 800576: 55 push %ebp + 800577: 89 e5 mov %esp,%ebp + 800579: 56 push %esi + 80057a: 53 push %ebx + 80057b: 83 ec 40 sub $0x40,%esp + register int ch, err; + unsigned long long num; + int base, width, precision, lflag, altflag; + + while (1) { + while ((ch = *(unsigned char *)fmt ++) != '%') { + 80057e: eb 17 jmp 800597 + if (ch == '\0') { + 800580: 85 db test %ebx,%ebx + 800582: 0f 84 bf 03 00 00 je 800947 + return; + } + putch(ch, putdat); + 800588: 8b 45 0c mov 0xc(%ebp),%eax + 80058b: 89 44 24 04 mov %eax,0x4(%esp) + 80058f: 89 1c 24 mov %ebx,(%esp) + 800592: 8b 45 08 mov 0x8(%ebp),%eax + 800595: ff d0 call *%eax + while ((ch = *(unsigned char *)fmt ++) != '%') { + 800597: 8b 45 10 mov 0x10(%ebp),%eax + 80059a: 8d 50 01 lea 0x1(%eax),%edx + 80059d: 89 55 10 mov %edx,0x10(%ebp) + 8005a0: 0f b6 00 movzbl (%eax),%eax + 8005a3: 0f b6 d8 movzbl %al,%ebx + 8005a6: 83 fb 25 cmp $0x25,%ebx + 8005a9: 75 d5 jne 800580 + } + + // Process a %-escape sequence + char padc = ' '; + 8005ab: c6 45 db 20 movb $0x20,-0x25(%ebp) + width = precision = -1; + 8005af: c7 45 e4 ff ff ff ff movl $0xffffffff,-0x1c(%ebp) + 8005b6: 8b 45 e4 mov -0x1c(%ebp),%eax + 8005b9: 89 45 e8 mov %eax,-0x18(%ebp) + lflag = altflag = 0; + 8005bc: c7 45 dc 00 00 00 00 movl $0x0,-0x24(%ebp) + 8005c3: 8b 45 dc mov -0x24(%ebp),%eax + 8005c6: 89 45 e0 mov %eax,-0x20(%ebp) + + reswitch: + switch (ch = *(unsigned char *)fmt ++) { + 8005c9: 8b 45 10 mov 0x10(%ebp),%eax + 8005cc: 8d 50 01 lea 0x1(%eax),%edx + 8005cf: 89 55 10 mov %edx,0x10(%ebp) + 8005d2: 0f b6 00 movzbl (%eax),%eax + 8005d5: 0f b6 d8 movzbl %al,%ebx + 8005d8: 8d 43 dd lea -0x23(%ebx),%eax + 8005db: 83 f8 55 cmp $0x55,%eax + 8005de: 0f 87 37 03 00 00 ja 80091b + 8005e4: 8b 04 85 68 12 80 00 mov 0x801268(,%eax,4),%eax + 8005eb: ff e0 jmp *%eax + + // flag to pad on the right + case '-': + padc = '-'; + 8005ed: c6 45 db 2d movb $0x2d,-0x25(%ebp) + goto reswitch; + 8005f1: eb d6 jmp 8005c9 + + // flag to pad with 0's instead of spaces + case '0': + padc = '0'; + 8005f3: c6 45 db 30 movb $0x30,-0x25(%ebp) + goto reswitch; + 8005f7: eb d0 jmp 8005c9 + + // width field + case '1' ... '9': + for (precision = 0; ; ++ fmt) { + 8005f9: c7 45 e4 00 00 00 00 movl $0x0,-0x1c(%ebp) + precision = precision * 10 + ch - '0'; + 800600: 8b 55 e4 mov -0x1c(%ebp),%edx + 800603: 89 d0 mov %edx,%eax + 800605: c1 e0 02 shl $0x2,%eax + 800608: 01 d0 add %edx,%eax + 80060a: 01 c0 add %eax,%eax + 80060c: 01 d8 add %ebx,%eax + 80060e: 83 e8 30 sub $0x30,%eax + 800611: 89 45 e4 mov %eax,-0x1c(%ebp) + ch = *fmt; + 800614: 8b 45 10 mov 0x10(%ebp),%eax + 800617: 0f b6 00 movzbl (%eax),%eax + 80061a: 0f be d8 movsbl %al,%ebx + if (ch < '0' || ch > '9') { + 80061d: 83 fb 2f cmp $0x2f,%ebx + 800620: 7e 38 jle 80065a + 800622: 83 fb 39 cmp $0x39,%ebx + 800625: 7f 33 jg 80065a + for (precision = 0; ; ++ fmt) { + 800627: ff 45 10 incl 0x10(%ebp) + precision = precision * 10 + ch - '0'; + 80062a: eb d4 jmp 800600 + } + } + goto process_precision; + + case '*': + precision = va_arg(ap, int); + 80062c: 8b 45 14 mov 0x14(%ebp),%eax + 80062f: 8d 50 04 lea 0x4(%eax),%edx + 800632: 89 55 14 mov %edx,0x14(%ebp) + 800635: 8b 00 mov (%eax),%eax + 800637: 89 45 e4 mov %eax,-0x1c(%ebp) + goto process_precision; + 80063a: eb 1f jmp 80065b + + case '.': + if (width < 0) + 80063c: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 800640: 79 87 jns 8005c9 + width = 0; + 800642: c7 45 e8 00 00 00 00 movl $0x0,-0x18(%ebp) + goto reswitch; + 800649: e9 7b ff ff ff jmp 8005c9 + + case '#': + altflag = 1; + 80064e: c7 45 dc 01 00 00 00 movl $0x1,-0x24(%ebp) + goto reswitch; + 800655: e9 6f ff ff ff jmp 8005c9 + goto process_precision; + 80065a: 90 nop + + process_precision: + if (width < 0) + 80065b: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 80065f: 0f 89 64 ff ff ff jns 8005c9 + width = precision, precision = -1; + 800665: 8b 45 e4 mov -0x1c(%ebp),%eax + 800668: 89 45 e8 mov %eax,-0x18(%ebp) + 80066b: c7 45 e4 ff ff ff ff movl $0xffffffff,-0x1c(%ebp) + goto reswitch; + 800672: e9 52 ff ff ff jmp 8005c9 + + // long flag (doubled for long long) + case 'l': + lflag ++; + 800677: ff 45 e0 incl -0x20(%ebp) + goto reswitch; + 80067a: e9 4a ff ff ff jmp 8005c9 + + // character + case 'c': + putch(va_arg(ap, int), putdat); + 80067f: 8b 45 14 mov 0x14(%ebp),%eax + 800682: 8d 50 04 lea 0x4(%eax),%edx + 800685: 89 55 14 mov %edx,0x14(%ebp) + 800688: 8b 00 mov (%eax),%eax + 80068a: 8b 55 0c mov 0xc(%ebp),%edx + 80068d: 89 54 24 04 mov %edx,0x4(%esp) + 800691: 89 04 24 mov %eax,(%esp) + 800694: 8b 45 08 mov 0x8(%ebp),%eax + 800697: ff d0 call *%eax + break; + 800699: e9 a4 02 00 00 jmp 800942 + + // error message + case 'e': + err = va_arg(ap, int); + 80069e: 8b 45 14 mov 0x14(%ebp),%eax + 8006a1: 8d 50 04 lea 0x4(%eax),%edx + 8006a4: 89 55 14 mov %edx,0x14(%ebp) + 8006a7: 8b 18 mov (%eax),%ebx + if (err < 0) { + 8006a9: 85 db test %ebx,%ebx + 8006ab: 79 02 jns 8006af + err = -err; + 8006ad: f7 db neg %ebx + } + if (err > MAXERROR || (p = error_string[err]) == NULL) { + 8006af: 83 fb 18 cmp $0x18,%ebx + 8006b2: 7f 0b jg 8006bf + 8006b4: 8b 34 9d e0 11 80 00 mov 0x8011e0(,%ebx,4),%esi + 8006bb: 85 f6 test %esi,%esi + 8006bd: 75 23 jne 8006e2 + printfmt(putch, putdat, "error %d", err); + 8006bf: 89 5c 24 0c mov %ebx,0xc(%esp) + 8006c3: c7 44 24 08 55 12 80 movl $0x801255,0x8(%esp) + 8006ca: 00 + 8006cb: 8b 45 0c mov 0xc(%ebp),%eax + 8006ce: 89 44 24 04 mov %eax,0x4(%esp) + 8006d2: 8b 45 08 mov 0x8(%ebp),%eax + 8006d5: 89 04 24 mov %eax,(%esp) + 8006d8: e8 68 fe ff ff call 800545 + } + else { + printfmt(putch, putdat, "%s", p); + } + break; + 8006dd: e9 60 02 00 00 jmp 800942 + printfmt(putch, putdat, "%s", p); + 8006e2: 89 74 24 0c mov %esi,0xc(%esp) + 8006e6: c7 44 24 08 5e 12 80 movl $0x80125e,0x8(%esp) + 8006ed: 00 + 8006ee: 8b 45 0c mov 0xc(%ebp),%eax + 8006f1: 89 44 24 04 mov %eax,0x4(%esp) + 8006f5: 8b 45 08 mov 0x8(%ebp),%eax + 8006f8: 89 04 24 mov %eax,(%esp) + 8006fb: e8 45 fe ff ff call 800545 + break; + 800700: e9 3d 02 00 00 jmp 800942 + + // string + case 's': + if ((p = va_arg(ap, char *)) == NULL) { + 800705: 8b 45 14 mov 0x14(%ebp),%eax + 800708: 8d 50 04 lea 0x4(%eax),%edx + 80070b: 89 55 14 mov %edx,0x14(%ebp) + 80070e: 8b 30 mov (%eax),%esi + 800710: 85 f6 test %esi,%esi + 800712: 75 05 jne 800719 + p = "(null)"; + 800714: be 61 12 80 00 mov $0x801261,%esi + } + if (width > 0 && padc != '-') { + 800719: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 80071d: 7e 76 jle 800795 + 80071f: 80 7d db 2d cmpb $0x2d,-0x25(%ebp) + 800723: 74 70 je 800795 + for (width -= strnlen(p, precision); width > 0; width --) { + 800725: 8b 45 e4 mov -0x1c(%ebp),%eax + 800728: 89 44 24 04 mov %eax,0x4(%esp) + 80072c: 89 34 24 mov %esi,(%esp) + 80072f: e8 ee 03 00 00 call 800b22 + 800734: 89 c2 mov %eax,%edx + 800736: 8b 45 e8 mov -0x18(%ebp),%eax + 800739: 29 d0 sub %edx,%eax + 80073b: 89 45 e8 mov %eax,-0x18(%ebp) + 80073e: eb 16 jmp 800756 + putch(padc, putdat); + 800740: 0f be 45 db movsbl -0x25(%ebp),%eax + 800744: 8b 55 0c mov 0xc(%ebp),%edx + 800747: 89 54 24 04 mov %edx,0x4(%esp) + 80074b: 89 04 24 mov %eax,(%esp) + 80074e: 8b 45 08 mov 0x8(%ebp),%eax + 800751: ff d0 call *%eax + for (width -= strnlen(p, precision); width > 0; width --) { + 800753: ff 4d e8 decl -0x18(%ebp) + 800756: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 80075a: 7f e4 jg 800740 + } + } + for (; (ch = *p ++) != '\0' && (precision < 0 || -- precision >= 0); width --) { + 80075c: eb 37 jmp 800795 + if (altflag && (ch < ' ' || ch > '~')) { + 80075e: 83 7d dc 00 cmpl $0x0,-0x24(%ebp) + 800762: 74 1f je 800783 + 800764: 83 fb 1f cmp $0x1f,%ebx + 800767: 7e 05 jle 80076e + 800769: 83 fb 7e cmp $0x7e,%ebx + 80076c: 7e 15 jle 800783 + putch('?', putdat); + 80076e: 8b 45 0c mov 0xc(%ebp),%eax + 800771: 89 44 24 04 mov %eax,0x4(%esp) + 800775: c7 04 24 3f 00 00 00 movl $0x3f,(%esp) + 80077c: 8b 45 08 mov 0x8(%ebp),%eax + 80077f: ff d0 call *%eax + 800781: eb 0f jmp 800792 + } + else { + putch(ch, putdat); + 800783: 8b 45 0c mov 0xc(%ebp),%eax + 800786: 89 44 24 04 mov %eax,0x4(%esp) + 80078a: 89 1c 24 mov %ebx,(%esp) + 80078d: 8b 45 08 mov 0x8(%ebp),%eax + 800790: ff d0 call *%eax + for (; (ch = *p ++) != '\0' && (precision < 0 || -- precision >= 0); width --) { + 800792: ff 4d e8 decl -0x18(%ebp) + 800795: 89 f0 mov %esi,%eax + 800797: 8d 70 01 lea 0x1(%eax),%esi + 80079a: 0f b6 00 movzbl (%eax),%eax + 80079d: 0f be d8 movsbl %al,%ebx + 8007a0: 85 db test %ebx,%ebx + 8007a2: 74 27 je 8007cb + 8007a4: 83 7d e4 00 cmpl $0x0,-0x1c(%ebp) + 8007a8: 78 b4 js 80075e + 8007aa: ff 4d e4 decl -0x1c(%ebp) + 8007ad: 83 7d e4 00 cmpl $0x0,-0x1c(%ebp) + 8007b1: 79 ab jns 80075e + } + } + for (; width > 0; width --) { + 8007b3: eb 16 jmp 8007cb + putch(' ', putdat); + 8007b5: 8b 45 0c mov 0xc(%ebp),%eax + 8007b8: 89 44 24 04 mov %eax,0x4(%esp) + 8007bc: c7 04 24 20 00 00 00 movl $0x20,(%esp) + 8007c3: 8b 45 08 mov 0x8(%ebp),%eax + 8007c6: ff d0 call *%eax + for (; width > 0; width --) { + 8007c8: ff 4d e8 decl -0x18(%ebp) + 8007cb: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 8007cf: 7f e4 jg 8007b5 + } + break; + 8007d1: e9 6c 01 00 00 jmp 800942 + + // (signed) decimal + case 'd': + num = getint(&ap, lflag); + 8007d6: 8b 45 e0 mov -0x20(%ebp),%eax + 8007d9: 89 44 24 04 mov %eax,0x4(%esp) + 8007dd: 8d 45 14 lea 0x14(%ebp),%eax + 8007e0: 89 04 24 mov %eax,(%esp) + 8007e3: e8 16 fd ff ff call 8004fe + 8007e8: 89 45 f0 mov %eax,-0x10(%ebp) + 8007eb: 89 55 f4 mov %edx,-0xc(%ebp) + if ((long long)num < 0) { + 8007ee: 8b 45 f0 mov -0x10(%ebp),%eax + 8007f1: 8b 55 f4 mov -0xc(%ebp),%edx + 8007f4: 85 d2 test %edx,%edx + 8007f6: 79 26 jns 80081e + putch('-', putdat); + 8007f8: 8b 45 0c mov 0xc(%ebp),%eax + 8007fb: 89 44 24 04 mov %eax,0x4(%esp) + 8007ff: c7 04 24 2d 00 00 00 movl $0x2d,(%esp) + 800806: 8b 45 08 mov 0x8(%ebp),%eax + 800809: ff d0 call *%eax + num = -(long long)num; + 80080b: 8b 45 f0 mov -0x10(%ebp),%eax + 80080e: 8b 55 f4 mov -0xc(%ebp),%edx + 800811: f7 d8 neg %eax + 800813: 83 d2 00 adc $0x0,%edx + 800816: f7 da neg %edx + 800818: 89 45 f0 mov %eax,-0x10(%ebp) + 80081b: 89 55 f4 mov %edx,-0xc(%ebp) + } + base = 10; + 80081e: c7 45 ec 0a 00 00 00 movl $0xa,-0x14(%ebp) + goto number; + 800825: e9 a8 00 00 00 jmp 8008d2 + + // unsigned decimal + case 'u': + num = getuint(&ap, lflag); + 80082a: 8b 45 e0 mov -0x20(%ebp),%eax + 80082d: 89 44 24 04 mov %eax,0x4(%esp) + 800831: 8d 45 14 lea 0x14(%ebp),%eax + 800834: 89 04 24 mov %eax,(%esp) + 800837: e8 73 fc ff ff call 8004af + 80083c: 89 45 f0 mov %eax,-0x10(%ebp) + 80083f: 89 55 f4 mov %edx,-0xc(%ebp) + base = 10; + 800842: c7 45 ec 0a 00 00 00 movl $0xa,-0x14(%ebp) + goto number; + 800849: e9 84 00 00 00 jmp 8008d2 + + // (unsigned) octal + case 'o': + num = getuint(&ap, lflag); + 80084e: 8b 45 e0 mov -0x20(%ebp),%eax + 800851: 89 44 24 04 mov %eax,0x4(%esp) + 800855: 8d 45 14 lea 0x14(%ebp),%eax + 800858: 89 04 24 mov %eax,(%esp) + 80085b: e8 4f fc ff ff call 8004af + 800860: 89 45 f0 mov %eax,-0x10(%ebp) + 800863: 89 55 f4 mov %edx,-0xc(%ebp) + base = 8; + 800866: c7 45 ec 08 00 00 00 movl $0x8,-0x14(%ebp) + goto number; + 80086d: eb 63 jmp 8008d2 + + // pointer + case 'p': + putch('0', putdat); + 80086f: 8b 45 0c mov 0xc(%ebp),%eax + 800872: 89 44 24 04 mov %eax,0x4(%esp) + 800876: c7 04 24 30 00 00 00 movl $0x30,(%esp) + 80087d: 8b 45 08 mov 0x8(%ebp),%eax + 800880: ff d0 call *%eax + putch('x', putdat); + 800882: 8b 45 0c mov 0xc(%ebp),%eax + 800885: 89 44 24 04 mov %eax,0x4(%esp) + 800889: c7 04 24 78 00 00 00 movl $0x78,(%esp) + 800890: 8b 45 08 mov 0x8(%ebp),%eax + 800893: ff d0 call *%eax + num = (unsigned long long)(uintptr_t)va_arg(ap, void *); + 800895: 8b 45 14 mov 0x14(%ebp),%eax + 800898: 8d 50 04 lea 0x4(%eax),%edx + 80089b: 89 55 14 mov %edx,0x14(%ebp) + 80089e: 8b 00 mov (%eax),%eax + 8008a0: 89 45 f0 mov %eax,-0x10(%ebp) + 8008a3: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + base = 16; + 8008aa: c7 45 ec 10 00 00 00 movl $0x10,-0x14(%ebp) + goto number; + 8008b1: eb 1f jmp 8008d2 + + // (unsigned) hexadecimal + case 'x': + num = getuint(&ap, lflag); + 8008b3: 8b 45 e0 mov -0x20(%ebp),%eax + 8008b6: 89 44 24 04 mov %eax,0x4(%esp) + 8008ba: 8d 45 14 lea 0x14(%ebp),%eax + 8008bd: 89 04 24 mov %eax,(%esp) + 8008c0: e8 ea fb ff ff call 8004af + 8008c5: 89 45 f0 mov %eax,-0x10(%ebp) + 8008c8: 89 55 f4 mov %edx,-0xc(%ebp) + base = 16; + 8008cb: c7 45 ec 10 00 00 00 movl $0x10,-0x14(%ebp) + number: + printnum(putch, putdat, num, base, width, padc); + 8008d2: 0f be 55 db movsbl -0x25(%ebp),%edx + 8008d6: 8b 45 ec mov -0x14(%ebp),%eax + 8008d9: 89 54 24 18 mov %edx,0x18(%esp) + 8008dd: 8b 55 e8 mov -0x18(%ebp),%edx + 8008e0: 89 54 24 14 mov %edx,0x14(%esp) + 8008e4: 89 44 24 10 mov %eax,0x10(%esp) + 8008e8: 8b 45 f0 mov -0x10(%ebp),%eax + 8008eb: 8b 55 f4 mov -0xc(%ebp),%edx + 8008ee: 89 44 24 08 mov %eax,0x8(%esp) + 8008f2: 89 54 24 0c mov %edx,0xc(%esp) + 8008f6: 8b 45 0c mov 0xc(%ebp),%eax + 8008f9: 89 44 24 04 mov %eax,0x4(%esp) + 8008fd: 8b 45 08 mov 0x8(%ebp),%eax + 800900: 89 04 24 mov %eax,(%esp) + 800903: e8 a5 fa ff ff call 8003ad + break; + 800908: eb 38 jmp 800942 + + // escaped '%' character + case '%': + putch(ch, putdat); + 80090a: 8b 45 0c mov 0xc(%ebp),%eax + 80090d: 89 44 24 04 mov %eax,0x4(%esp) + 800911: 89 1c 24 mov %ebx,(%esp) + 800914: 8b 45 08 mov 0x8(%ebp),%eax + 800917: ff d0 call *%eax + break; + 800919: eb 27 jmp 800942 + + // unrecognized escape sequence - just print it literally + default: + putch('%', putdat); + 80091b: 8b 45 0c mov 0xc(%ebp),%eax + 80091e: 89 44 24 04 mov %eax,0x4(%esp) + 800922: c7 04 24 25 00 00 00 movl $0x25,(%esp) + 800929: 8b 45 08 mov 0x8(%ebp),%eax + 80092c: ff d0 call *%eax + for (fmt --; fmt[-1] != '%'; fmt --) + 80092e: ff 4d 10 decl 0x10(%ebp) + 800931: eb 03 jmp 800936 + 800933: ff 4d 10 decl 0x10(%ebp) + 800936: 8b 45 10 mov 0x10(%ebp),%eax + 800939: 48 dec %eax + 80093a: 0f b6 00 movzbl (%eax),%eax + 80093d: 3c 25 cmp $0x25,%al + 80093f: 75 f2 jne 800933 + /* do nothing */; + break; + 800941: 90 nop + while (1) { + 800942: e9 37 fc ff ff jmp 80057e + return; + 800947: 90 nop + } + } +} + 800948: 83 c4 40 add $0x40,%esp + 80094b: 5b pop %ebx + 80094c: 5e pop %esi + 80094d: 5d pop %ebp + 80094e: c3 ret + +0080094f : + * sprintputch - 'print' a single character in a buffer + * @ch: the character will be printed + * @b: the buffer to place the character @ch + * */ +static void +sprintputch(int ch, struct sprintbuf *b) { + 80094f: 55 push %ebp + 800950: 89 e5 mov %esp,%ebp + b->cnt ++; + 800952: 8b 45 0c mov 0xc(%ebp),%eax + 800955: 8b 40 08 mov 0x8(%eax),%eax + 800958: 8d 50 01 lea 0x1(%eax),%edx + 80095b: 8b 45 0c mov 0xc(%ebp),%eax + 80095e: 89 50 08 mov %edx,0x8(%eax) + if (b->buf < b->ebuf) { + 800961: 8b 45 0c mov 0xc(%ebp),%eax + 800964: 8b 10 mov (%eax),%edx + 800966: 8b 45 0c mov 0xc(%ebp),%eax + 800969: 8b 40 04 mov 0x4(%eax),%eax + 80096c: 39 c2 cmp %eax,%edx + 80096e: 73 12 jae 800982 + *b->buf ++ = ch; + 800970: 8b 45 0c mov 0xc(%ebp),%eax + 800973: 8b 00 mov (%eax),%eax + 800975: 8d 48 01 lea 0x1(%eax),%ecx + 800978: 8b 55 0c mov 0xc(%ebp),%edx + 80097b: 89 0a mov %ecx,(%edx) + 80097d: 8b 55 08 mov 0x8(%ebp),%edx + 800980: 88 10 mov %dl,(%eax) + } +} + 800982: 90 nop + 800983: 5d pop %ebp + 800984: c3 ret + +00800985 : + * @str: the buffer to place the result into + * @size: the size of buffer, including the trailing null space + * @fmt: the format string to use + * */ +int +snprintf(char *str, size_t size, const char *fmt, ...) { + 800985: 55 push %ebp + 800986: 89 e5 mov %esp,%ebp + 800988: 83 ec 28 sub $0x28,%esp + va_list ap; + int cnt; + va_start(ap, fmt); + 80098b: 8d 45 14 lea 0x14(%ebp),%eax + 80098e: 89 45 f0 mov %eax,-0x10(%ebp) + cnt = vsnprintf(str, size, fmt, ap); + 800991: 8b 45 f0 mov -0x10(%ebp),%eax + 800994: 89 44 24 0c mov %eax,0xc(%esp) + 800998: 8b 45 10 mov 0x10(%ebp),%eax + 80099b: 89 44 24 08 mov %eax,0x8(%esp) + 80099f: 8b 45 0c mov 0xc(%ebp),%eax + 8009a2: 89 44 24 04 mov %eax,0x4(%esp) + 8009a6: 8b 45 08 mov 0x8(%ebp),%eax + 8009a9: 89 04 24 mov %eax,(%esp) + 8009ac: e8 0a 00 00 00 call 8009bb + 8009b1: 89 45 f4 mov %eax,-0xc(%ebp) + va_end(ap); + return cnt; + 8009b4: 8b 45 f4 mov -0xc(%ebp),%eax +} + 8009b7: 89 ec mov %ebp,%esp + 8009b9: 5d pop %ebp + 8009ba: c3 ret + +008009bb : + * + * Call this function if you are already dealing with a va_list. + * Or you probably want snprintf() instead. + * */ +int +vsnprintf(char *str, size_t size, const char *fmt, va_list ap) { + 8009bb: 55 push %ebp + 8009bc: 89 e5 mov %esp,%ebp + 8009be: 83 ec 28 sub $0x28,%esp + struct sprintbuf b = {str, str + size - 1, 0}; + 8009c1: 8b 45 08 mov 0x8(%ebp),%eax + 8009c4: 89 45 ec mov %eax,-0x14(%ebp) + 8009c7: 8b 45 0c mov 0xc(%ebp),%eax + 8009ca: 8d 50 ff lea -0x1(%eax),%edx + 8009cd: 8b 45 08 mov 0x8(%ebp),%eax + 8009d0: 01 d0 add %edx,%eax + 8009d2: 89 45 f0 mov %eax,-0x10(%ebp) + 8009d5: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + if (str == NULL || b.buf > b.ebuf) { + 8009dc: 83 7d 08 00 cmpl $0x0,0x8(%ebp) + 8009e0: 74 0a je 8009ec + 8009e2: 8b 55 ec mov -0x14(%ebp),%edx + 8009e5: 8b 45 f0 mov -0x10(%ebp),%eax + 8009e8: 39 c2 cmp %eax,%edx + 8009ea: 76 07 jbe 8009f3 + return -E_INVAL; + 8009ec: b8 fd ff ff ff mov $0xfffffffd,%eax + 8009f1: eb 2a jmp 800a1d + } + // print the string to the buffer + vprintfmt((void*)sprintputch, &b, fmt, ap); + 8009f3: 8b 45 14 mov 0x14(%ebp),%eax + 8009f6: 89 44 24 0c mov %eax,0xc(%esp) + 8009fa: 8b 45 10 mov 0x10(%ebp),%eax + 8009fd: 89 44 24 08 mov %eax,0x8(%esp) + 800a01: 8d 45 ec lea -0x14(%ebp),%eax + 800a04: 89 44 24 04 mov %eax,0x4(%esp) + 800a08: c7 04 24 4f 09 80 00 movl $0x80094f,(%esp) + 800a0f: e8 62 fb ff ff call 800576 + // null terminate the buffer + *b.buf = '\0'; + 800a14: 8b 45 ec mov -0x14(%ebp),%eax + 800a17: c6 00 00 movb $0x0,(%eax) + return b.cnt; + 800a1a: 8b 45 f4 mov -0xc(%ebp),%eax +} + 800a1d: 89 ec mov %ebp,%esp + 800a1f: 5d pop %ebp + 800a20: c3 ret + +00800a21 : + * rand - returns a pseudo-random integer + * + * The rand() function return a value in the range [0, RAND_MAX]. + * */ +int +rand(void) { + 800a21: 55 push %ebp + 800a22: 89 e5 mov %esp,%ebp + 800a24: 57 push %edi + 800a25: 56 push %esi + 800a26: 53 push %ebx + 800a27: 83 ec 24 sub $0x24,%esp + next = (next * 0x5DEECE66DLL + 0xBLL) & ((1LL << 48) - 1); + 800a2a: a1 00 20 80 00 mov 0x802000,%eax + 800a2f: 8b 15 04 20 80 00 mov 0x802004,%edx + 800a35: 69 fa 6d e6 ec de imul $0xdeece66d,%edx,%edi + 800a3b: 6b f0 05 imul $0x5,%eax,%esi + 800a3e: 01 fe add %edi,%esi + 800a40: bf 6d e6 ec de mov $0xdeece66d,%edi + 800a45: f7 e7 mul %edi + 800a47: 01 d6 add %edx,%esi + 800a49: 89 f2 mov %esi,%edx + 800a4b: 83 c0 0b add $0xb,%eax + 800a4e: 83 d2 00 adc $0x0,%edx + 800a51: 89 c7 mov %eax,%edi + 800a53: 83 e7 ff and $0xffffffff,%edi + 800a56: 89 f9 mov %edi,%ecx + 800a58: 0f b7 da movzwl %dx,%ebx + 800a5b: 89 0d 00 20 80 00 mov %ecx,0x802000 + 800a61: 89 1d 04 20 80 00 mov %ebx,0x802004 + unsigned long long result = (next >> 12); + 800a67: a1 00 20 80 00 mov 0x802000,%eax + 800a6c: 8b 15 04 20 80 00 mov 0x802004,%edx + 800a72: 0f ac d0 0c shrd $0xc,%edx,%eax + 800a76: c1 ea 0c shr $0xc,%edx + 800a79: 89 45 e0 mov %eax,-0x20(%ebp) + 800a7c: 89 55 e4 mov %edx,-0x1c(%ebp) + return (int)do_div(result, RAND_MAX + 1); + 800a7f: c7 45 dc 00 00 00 80 movl $0x80000000,-0x24(%ebp) + 800a86: 8b 45 e0 mov -0x20(%ebp),%eax + 800a89: 8b 55 e4 mov -0x1c(%ebp),%edx + 800a8c: 89 45 d8 mov %eax,-0x28(%ebp) + 800a8f: 89 55 e8 mov %edx,-0x18(%ebp) + 800a92: 8b 45 e8 mov -0x18(%ebp),%eax + 800a95: 89 45 ec mov %eax,-0x14(%ebp) + 800a98: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 800a9c: 74 1c je 800aba + 800a9e: 8b 45 e8 mov -0x18(%ebp),%eax + 800aa1: ba 00 00 00 00 mov $0x0,%edx + 800aa6: f7 75 dc divl -0x24(%ebp) + 800aa9: 89 55 ec mov %edx,-0x14(%ebp) + 800aac: 8b 45 e8 mov -0x18(%ebp),%eax + 800aaf: ba 00 00 00 00 mov $0x0,%edx + 800ab4: f7 75 dc divl -0x24(%ebp) + 800ab7: 89 45 e8 mov %eax,-0x18(%ebp) + 800aba: 8b 45 d8 mov -0x28(%ebp),%eax + 800abd: 8b 55 ec mov -0x14(%ebp),%edx + 800ac0: f7 75 dc divl -0x24(%ebp) + 800ac3: 89 45 d8 mov %eax,-0x28(%ebp) + 800ac6: 89 55 d4 mov %edx,-0x2c(%ebp) + 800ac9: 8b 45 d8 mov -0x28(%ebp),%eax + 800acc: 8b 55 e8 mov -0x18(%ebp),%edx + 800acf: 89 45 e0 mov %eax,-0x20(%ebp) + 800ad2: 89 55 e4 mov %edx,-0x1c(%ebp) + 800ad5: 8b 45 d4 mov -0x2c(%ebp),%eax +} + 800ad8: 83 c4 24 add $0x24,%esp + 800adb: 5b pop %ebx + 800adc: 5e pop %esi + 800add: 5f pop %edi + 800ade: 5d pop %ebp + 800adf: c3 ret + +00800ae0 : +/* * + * srand - seed the random number generator with the given number + * @seed: the required seed number + * */ +void +srand(unsigned int seed) { + 800ae0: 55 push %ebp + 800ae1: 89 e5 mov %esp,%ebp + next = seed; + 800ae3: 8b 45 08 mov 0x8(%ebp),%eax + 800ae6: ba 00 00 00 00 mov $0x0,%edx + 800aeb: a3 00 20 80 00 mov %eax,0x802000 + 800af0: 89 15 04 20 80 00 mov %edx,0x802004 +} + 800af6: 90 nop + 800af7: 5d pop %ebp + 800af8: c3 ret + +00800af9 : + * @s: the input string + * + * The strlen() function returns the length of string @s. + * */ +size_t +strlen(const char *s) { + 800af9: 55 push %ebp + 800afa: 89 e5 mov %esp,%ebp + 800afc: 83 ec 10 sub $0x10,%esp + size_t cnt = 0; + 800aff: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + while (*s ++ != '\0') { + 800b06: eb 03 jmp 800b0b + cnt ++; + 800b08: ff 45 fc incl -0x4(%ebp) + while (*s ++ != '\0') { + 800b0b: 8b 45 08 mov 0x8(%ebp),%eax + 800b0e: 8d 50 01 lea 0x1(%eax),%edx + 800b11: 89 55 08 mov %edx,0x8(%ebp) + 800b14: 0f b6 00 movzbl (%eax),%eax + 800b17: 84 c0 test %al,%al + 800b19: 75 ed jne 800b08 + } + return cnt; + 800b1b: 8b 45 fc mov -0x4(%ebp),%eax +} + 800b1e: 89 ec mov %ebp,%esp + 800b20: 5d pop %ebp + 800b21: c3 ret + +00800b22 : + * The return value is strlen(s), if that is less than @len, or + * @len if there is no '\0' character among the first @len characters + * pointed by @s. + * */ +size_t +strnlen(const char *s, size_t len) { + 800b22: 55 push %ebp + 800b23: 89 e5 mov %esp,%ebp + 800b25: 83 ec 10 sub $0x10,%esp + size_t cnt = 0; + 800b28: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + while (cnt < len && *s ++ != '\0') { + 800b2f: eb 03 jmp 800b34 + cnt ++; + 800b31: ff 45 fc incl -0x4(%ebp) + while (cnt < len && *s ++ != '\0') { + 800b34: 8b 45 fc mov -0x4(%ebp),%eax + 800b37: 3b 45 0c cmp 0xc(%ebp),%eax + 800b3a: 73 10 jae 800b4c + 800b3c: 8b 45 08 mov 0x8(%ebp),%eax + 800b3f: 8d 50 01 lea 0x1(%eax),%edx + 800b42: 89 55 08 mov %edx,0x8(%ebp) + 800b45: 0f b6 00 movzbl (%eax),%eax + 800b48: 84 c0 test %al,%al + 800b4a: 75 e5 jne 800b31 + } + return cnt; + 800b4c: 8b 45 fc mov -0x4(%ebp),%eax +} + 800b4f: 89 ec mov %ebp,%esp + 800b51: 5d pop %ebp + 800b52: c3 ret + +00800b53 : + * To avoid overflows, the size of array pointed by @dst should be long enough to + * contain the same string as @src (including the terminating null character), and + * should not overlap in memory with @src. + * */ +char * +strcpy(char *dst, const char *src) { + 800b53: 55 push %ebp + 800b54: 89 e5 mov %esp,%ebp + 800b56: 57 push %edi + 800b57: 56 push %esi + 800b58: 83 ec 20 sub $0x20,%esp + 800b5b: 8b 45 08 mov 0x8(%ebp),%eax + 800b5e: 89 45 f4 mov %eax,-0xc(%ebp) + 800b61: 8b 45 0c mov 0xc(%ebp),%eax + 800b64: 89 45 f0 mov %eax,-0x10(%ebp) +#ifndef __HAVE_ARCH_STRCPY +#define __HAVE_ARCH_STRCPY +static inline char * +__strcpy(char *dst, const char *src) { + int d0, d1, d2; + asm volatile ( + 800b67: 8b 55 f0 mov -0x10(%ebp),%edx + 800b6a: 8b 45 f4 mov -0xc(%ebp),%eax + 800b6d: 89 d1 mov %edx,%ecx + 800b6f: 89 c2 mov %eax,%edx + 800b71: 89 ce mov %ecx,%esi + 800b73: 89 d7 mov %edx,%edi + 800b75: ac lods %ds:(%esi),%al + 800b76: aa stos %al,%es:(%edi) + 800b77: 84 c0 test %al,%al + 800b79: 75 fa jne 800b75 + 800b7b: 89 fa mov %edi,%edx + 800b7d: 89 f1 mov %esi,%ecx + 800b7f: 89 4d ec mov %ecx,-0x14(%ebp) + 800b82: 89 55 e8 mov %edx,-0x18(%ebp) + 800b85: 89 45 e4 mov %eax,-0x1c(%ebp) + "stosb;" + "testb %%al, %%al;" + "jne 1b;" + : "=&S" (d0), "=&D" (d1), "=&a" (d2) + : "0" (src), "1" (dst) : "memory"); + return dst; + 800b88: 8b 45 f4 mov -0xc(%ebp),%eax + char *p = dst; + while ((*p ++ = *src ++) != '\0') + /* nothing */; + return dst; +#endif /* __HAVE_ARCH_STRCPY */ +} + 800b8b: 83 c4 20 add $0x20,%esp + 800b8e: 5e pop %esi + 800b8f: 5f pop %edi + 800b90: 5d pop %ebp + 800b91: c3 ret + +00800b92 : + * @len: maximum number of characters to be copied from @src + * + * The return value is @dst + * */ +char * +strncpy(char *dst, const char *src, size_t len) { + 800b92: 55 push %ebp + 800b93: 89 e5 mov %esp,%ebp + 800b95: 83 ec 10 sub $0x10,%esp + char *p = dst; + 800b98: 8b 45 08 mov 0x8(%ebp),%eax + 800b9b: 89 45 fc mov %eax,-0x4(%ebp) + while (len > 0) { + 800b9e: eb 1e jmp 800bbe + if ((*p = *src) != '\0') { + 800ba0: 8b 45 0c mov 0xc(%ebp),%eax + 800ba3: 0f b6 10 movzbl (%eax),%edx + 800ba6: 8b 45 fc mov -0x4(%ebp),%eax + 800ba9: 88 10 mov %dl,(%eax) + 800bab: 8b 45 fc mov -0x4(%ebp),%eax + 800bae: 0f b6 00 movzbl (%eax),%eax + 800bb1: 84 c0 test %al,%al + 800bb3: 74 03 je 800bb8 + src ++; + 800bb5: ff 45 0c incl 0xc(%ebp) + } + p ++, len --; + 800bb8: ff 45 fc incl -0x4(%ebp) + 800bbb: ff 4d 10 decl 0x10(%ebp) + while (len > 0) { + 800bbe: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800bc2: 75 dc jne 800ba0 + } + return dst; + 800bc4: 8b 45 08 mov 0x8(%ebp),%eax +} + 800bc7: 89 ec mov %ebp,%esp + 800bc9: 5d pop %ebp + 800bca: c3 ret + +00800bcb : + * - A value greater than zero indicates that the first character that does + * not match has a greater value in @s1 than in @s2; + * - And a value less than zero indicates the opposite. + * */ +int +strcmp(const char *s1, const char *s2) { + 800bcb: 55 push %ebp + 800bcc: 89 e5 mov %esp,%ebp + 800bce: 57 push %edi + 800bcf: 56 push %esi + 800bd0: 83 ec 20 sub $0x20,%esp + 800bd3: 8b 45 08 mov 0x8(%ebp),%eax + 800bd6: 89 45 f4 mov %eax,-0xc(%ebp) + 800bd9: 8b 45 0c mov 0xc(%ebp),%eax + 800bdc: 89 45 f0 mov %eax,-0x10(%ebp) + asm volatile ( + 800bdf: 8b 55 f4 mov -0xc(%ebp),%edx + 800be2: 8b 45 f0 mov -0x10(%ebp),%eax + 800be5: 89 d1 mov %edx,%ecx + 800be7: 89 c2 mov %eax,%edx + 800be9: 89 ce mov %ecx,%esi + 800beb: 89 d7 mov %edx,%edi + 800bed: ac lods %ds:(%esi),%al + 800bee: ae scas %es:(%edi),%al + 800bef: 75 08 jne 800bf9 + 800bf1: 84 c0 test %al,%al + 800bf3: 75 f8 jne 800bed + 800bf5: 31 c0 xor %eax,%eax + 800bf7: eb 04 jmp 800bfd + 800bf9: 19 c0 sbb %eax,%eax + 800bfb: 0c 01 or $0x1,%al + 800bfd: 89 fa mov %edi,%edx + 800bff: 89 f1 mov %esi,%ecx + 800c01: 89 45 ec mov %eax,-0x14(%ebp) + 800c04: 89 4d e8 mov %ecx,-0x18(%ebp) + 800c07: 89 55 e4 mov %edx,-0x1c(%ebp) + return ret; + 800c0a: 8b 45 ec mov -0x14(%ebp),%eax + while (*s1 != '\0' && *s1 == *s2) { + s1 ++, s2 ++; + } + return (int)((unsigned char)*s1 - (unsigned char)*s2); +#endif /* __HAVE_ARCH_STRCMP */ +} + 800c0d: 83 c4 20 add $0x20,%esp + 800c10: 5e pop %esi + 800c11: 5f pop %edi + 800c12: 5d pop %ebp + 800c13: c3 ret + +00800c14 : + * they are equal to each other, it continues with the following pairs until + * the characters differ, until a terminating null-character is reached, or + * until @n characters match in both strings, whichever happens first. + * */ +int +strncmp(const char *s1, const char *s2, size_t n) { + 800c14: 55 push %ebp + 800c15: 89 e5 mov %esp,%ebp + while (n > 0 && *s1 != '\0' && *s1 == *s2) { + 800c17: eb 09 jmp 800c22 + n --, s1 ++, s2 ++; + 800c19: ff 4d 10 decl 0x10(%ebp) + 800c1c: ff 45 08 incl 0x8(%ebp) + 800c1f: ff 45 0c incl 0xc(%ebp) + while (n > 0 && *s1 != '\0' && *s1 == *s2) { + 800c22: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800c26: 74 1a je 800c42 + 800c28: 8b 45 08 mov 0x8(%ebp),%eax + 800c2b: 0f b6 00 movzbl (%eax),%eax + 800c2e: 84 c0 test %al,%al + 800c30: 74 10 je 800c42 + 800c32: 8b 45 08 mov 0x8(%ebp),%eax + 800c35: 0f b6 10 movzbl (%eax),%edx + 800c38: 8b 45 0c mov 0xc(%ebp),%eax + 800c3b: 0f b6 00 movzbl (%eax),%eax + 800c3e: 38 c2 cmp %al,%dl + 800c40: 74 d7 je 800c19 + } + return (n == 0) ? 0 : (int)((unsigned char)*s1 - (unsigned char)*s2); + 800c42: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800c46: 74 18 je 800c60 + 800c48: 8b 45 08 mov 0x8(%ebp),%eax + 800c4b: 0f b6 00 movzbl (%eax),%eax + 800c4e: 0f b6 d0 movzbl %al,%edx + 800c51: 8b 45 0c mov 0xc(%ebp),%eax + 800c54: 0f b6 00 movzbl (%eax),%eax + 800c57: 0f b6 c8 movzbl %al,%ecx + 800c5a: 89 d0 mov %edx,%eax + 800c5c: 29 c8 sub %ecx,%eax + 800c5e: eb 05 jmp 800c65 + 800c60: b8 00 00 00 00 mov $0x0,%eax +} + 800c65: 5d pop %ebp + 800c66: c3 ret + +00800c67 : + * + * The strchr() function returns a pointer to the first occurrence of + * character in @s. If the value is not found, the function returns 'NULL'. + * */ +char * +strchr(const char *s, char c) { + 800c67: 55 push %ebp + 800c68: 89 e5 mov %esp,%ebp + 800c6a: 83 ec 04 sub $0x4,%esp + 800c6d: 8b 45 0c mov 0xc(%ebp),%eax + 800c70: 88 45 fc mov %al,-0x4(%ebp) + while (*s != '\0') { + 800c73: eb 13 jmp 800c88 + if (*s == c) { + 800c75: 8b 45 08 mov 0x8(%ebp),%eax + 800c78: 0f b6 00 movzbl (%eax),%eax + 800c7b: 38 45 fc cmp %al,-0x4(%ebp) + 800c7e: 75 05 jne 800c85 + return (char *)s; + 800c80: 8b 45 08 mov 0x8(%ebp),%eax + 800c83: eb 12 jmp 800c97 + } + s ++; + 800c85: ff 45 08 incl 0x8(%ebp) + while (*s != '\0') { + 800c88: 8b 45 08 mov 0x8(%ebp),%eax + 800c8b: 0f b6 00 movzbl (%eax),%eax + 800c8e: 84 c0 test %al,%al + 800c90: 75 e3 jne 800c75 + } + return NULL; + 800c92: b8 00 00 00 00 mov $0x0,%eax +} + 800c97: 89 ec mov %ebp,%esp + 800c99: 5d pop %ebp + 800c9a: c3 ret + +00800c9b : + * The strfind() function is like strchr() except that if @c is + * not found in @s, then it returns a pointer to the null byte at the + * end of @s, rather than 'NULL'. + * */ +char * +strfind(const char *s, char c) { + 800c9b: 55 push %ebp + 800c9c: 89 e5 mov %esp,%ebp + 800c9e: 83 ec 04 sub $0x4,%esp + 800ca1: 8b 45 0c mov 0xc(%ebp),%eax + 800ca4: 88 45 fc mov %al,-0x4(%ebp) + while (*s != '\0') { + 800ca7: eb 0e jmp 800cb7 + if (*s == c) { + 800ca9: 8b 45 08 mov 0x8(%ebp),%eax + 800cac: 0f b6 00 movzbl (%eax),%eax + 800caf: 38 45 fc cmp %al,-0x4(%ebp) + 800cb2: 74 0f je 800cc3 + break; + } + s ++; + 800cb4: ff 45 08 incl 0x8(%ebp) + while (*s != '\0') { + 800cb7: 8b 45 08 mov 0x8(%ebp),%eax + 800cba: 0f b6 00 movzbl (%eax),%eax + 800cbd: 84 c0 test %al,%al + 800cbf: 75 e8 jne 800ca9 + 800cc1: eb 01 jmp 800cc4 + break; + 800cc3: 90 nop + } + return (char *)s; + 800cc4: 8b 45 08 mov 0x8(%ebp),%eax +} + 800cc7: 89 ec mov %ebp,%esp + 800cc9: 5d pop %ebp + 800cca: c3 ret + +00800ccb : + * an optional "0x" or "0X" prefix. + * + * The strtol() function returns the converted integral number as a long int value. + * */ +long +strtol(const char *s, char **endptr, int base) { + 800ccb: 55 push %ebp + 800ccc: 89 e5 mov %esp,%ebp + 800cce: 83 ec 10 sub $0x10,%esp + int neg = 0; + 800cd1: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + long val = 0; + 800cd8: c7 45 f8 00 00 00 00 movl $0x0,-0x8(%ebp) + + // gobble initial whitespace + while (*s == ' ' || *s == '\t') { + 800cdf: eb 03 jmp 800ce4 + s ++; + 800ce1: ff 45 08 incl 0x8(%ebp) + while (*s == ' ' || *s == '\t') { + 800ce4: 8b 45 08 mov 0x8(%ebp),%eax + 800ce7: 0f b6 00 movzbl (%eax),%eax + 800cea: 3c 20 cmp $0x20,%al + 800cec: 74 f3 je 800ce1 + 800cee: 8b 45 08 mov 0x8(%ebp),%eax + 800cf1: 0f b6 00 movzbl (%eax),%eax + 800cf4: 3c 09 cmp $0x9,%al + 800cf6: 74 e9 je 800ce1 + } + + // plus/minus sign + if (*s == '+') { + 800cf8: 8b 45 08 mov 0x8(%ebp),%eax + 800cfb: 0f b6 00 movzbl (%eax),%eax + 800cfe: 3c 2b cmp $0x2b,%al + 800d00: 75 05 jne 800d07 + s ++; + 800d02: ff 45 08 incl 0x8(%ebp) + 800d05: eb 14 jmp 800d1b + } + else if (*s == '-') { + 800d07: 8b 45 08 mov 0x8(%ebp),%eax + 800d0a: 0f b6 00 movzbl (%eax),%eax + 800d0d: 3c 2d cmp $0x2d,%al + 800d0f: 75 0a jne 800d1b + s ++, neg = 1; + 800d11: ff 45 08 incl 0x8(%ebp) + 800d14: c7 45 fc 01 00 00 00 movl $0x1,-0x4(%ebp) + } + + // hex or octal base prefix + if ((base == 0 || base == 16) && (s[0] == '0' && s[1] == 'x')) { + 800d1b: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800d1f: 74 06 je 800d27 + 800d21: 83 7d 10 10 cmpl $0x10,0x10(%ebp) + 800d25: 75 22 jne 800d49 + 800d27: 8b 45 08 mov 0x8(%ebp),%eax + 800d2a: 0f b6 00 movzbl (%eax),%eax + 800d2d: 3c 30 cmp $0x30,%al + 800d2f: 75 18 jne 800d49 + 800d31: 8b 45 08 mov 0x8(%ebp),%eax + 800d34: 40 inc %eax + 800d35: 0f b6 00 movzbl (%eax),%eax + 800d38: 3c 78 cmp $0x78,%al + 800d3a: 75 0d jne 800d49 + s += 2, base = 16; + 800d3c: 83 45 08 02 addl $0x2,0x8(%ebp) + 800d40: c7 45 10 10 00 00 00 movl $0x10,0x10(%ebp) + 800d47: eb 29 jmp 800d72 + } + else if (base == 0 && s[0] == '0') { + 800d49: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800d4d: 75 16 jne 800d65 + 800d4f: 8b 45 08 mov 0x8(%ebp),%eax + 800d52: 0f b6 00 movzbl (%eax),%eax + 800d55: 3c 30 cmp $0x30,%al + 800d57: 75 0c jne 800d65 + s ++, base = 8; + 800d59: ff 45 08 incl 0x8(%ebp) + 800d5c: c7 45 10 08 00 00 00 movl $0x8,0x10(%ebp) + 800d63: eb 0d jmp 800d72 + } + else if (base == 0) { + 800d65: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800d69: 75 07 jne 800d72 + base = 10; + 800d6b: c7 45 10 0a 00 00 00 movl $0xa,0x10(%ebp) + + // digits + while (1) { + int dig; + + if (*s >= '0' && *s <= '9') { + 800d72: 8b 45 08 mov 0x8(%ebp),%eax + 800d75: 0f b6 00 movzbl (%eax),%eax + 800d78: 3c 2f cmp $0x2f,%al + 800d7a: 7e 1b jle 800d97 + 800d7c: 8b 45 08 mov 0x8(%ebp),%eax + 800d7f: 0f b6 00 movzbl (%eax),%eax + 800d82: 3c 39 cmp $0x39,%al + 800d84: 7f 11 jg 800d97 + dig = *s - '0'; + 800d86: 8b 45 08 mov 0x8(%ebp),%eax + 800d89: 0f b6 00 movzbl (%eax),%eax + 800d8c: 0f be c0 movsbl %al,%eax + 800d8f: 83 e8 30 sub $0x30,%eax + 800d92: 89 45 f4 mov %eax,-0xc(%ebp) + 800d95: eb 48 jmp 800ddf + } + else if (*s >= 'a' && *s <= 'z') { + 800d97: 8b 45 08 mov 0x8(%ebp),%eax + 800d9a: 0f b6 00 movzbl (%eax),%eax + 800d9d: 3c 60 cmp $0x60,%al + 800d9f: 7e 1b jle 800dbc + 800da1: 8b 45 08 mov 0x8(%ebp),%eax + 800da4: 0f b6 00 movzbl (%eax),%eax + 800da7: 3c 7a cmp $0x7a,%al + 800da9: 7f 11 jg 800dbc + dig = *s - 'a' + 10; + 800dab: 8b 45 08 mov 0x8(%ebp),%eax + 800dae: 0f b6 00 movzbl (%eax),%eax + 800db1: 0f be c0 movsbl %al,%eax + 800db4: 83 e8 57 sub $0x57,%eax + 800db7: 89 45 f4 mov %eax,-0xc(%ebp) + 800dba: eb 23 jmp 800ddf + } + else if (*s >= 'A' && *s <= 'Z') { + 800dbc: 8b 45 08 mov 0x8(%ebp),%eax + 800dbf: 0f b6 00 movzbl (%eax),%eax + 800dc2: 3c 40 cmp $0x40,%al + 800dc4: 7e 3b jle 800e01 + 800dc6: 8b 45 08 mov 0x8(%ebp),%eax + 800dc9: 0f b6 00 movzbl (%eax),%eax + 800dcc: 3c 5a cmp $0x5a,%al + 800dce: 7f 31 jg 800e01 + dig = *s - 'A' + 10; + 800dd0: 8b 45 08 mov 0x8(%ebp),%eax + 800dd3: 0f b6 00 movzbl (%eax),%eax + 800dd6: 0f be c0 movsbl %al,%eax + 800dd9: 83 e8 37 sub $0x37,%eax + 800ddc: 89 45 f4 mov %eax,-0xc(%ebp) + } + else { + break; + } + if (dig >= base) { + 800ddf: 8b 45 f4 mov -0xc(%ebp),%eax + 800de2: 3b 45 10 cmp 0x10(%ebp),%eax + 800de5: 7d 19 jge 800e00 + break; + } + s ++, val = (val * base) + dig; + 800de7: ff 45 08 incl 0x8(%ebp) + 800dea: 8b 45 f8 mov -0x8(%ebp),%eax + 800ded: 0f af 45 10 imul 0x10(%ebp),%eax + 800df1: 89 c2 mov %eax,%edx + 800df3: 8b 45 f4 mov -0xc(%ebp),%eax + 800df6: 01 d0 add %edx,%eax + 800df8: 89 45 f8 mov %eax,-0x8(%ebp) + while (1) { + 800dfb: e9 72 ff ff ff jmp 800d72 + break; + 800e00: 90 nop + // we don't properly detect overflow! + } + + if (endptr) { + 800e01: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) + 800e05: 74 08 je 800e0f + *endptr = (char *) s; + 800e07: 8b 45 0c mov 0xc(%ebp),%eax + 800e0a: 8b 55 08 mov 0x8(%ebp),%edx + 800e0d: 89 10 mov %edx,(%eax) + } + return (neg ? -val : val); + 800e0f: 83 7d fc 00 cmpl $0x0,-0x4(%ebp) + 800e13: 74 07 je 800e1c + 800e15: 8b 45 f8 mov -0x8(%ebp),%eax + 800e18: f7 d8 neg %eax + 800e1a: eb 03 jmp 800e1f + 800e1c: 8b 45 f8 mov -0x8(%ebp),%eax +} + 800e1f: 89 ec mov %ebp,%esp + 800e21: 5d pop %ebp + 800e22: c3 ret + +00800e23 : + * @n: number of bytes to be set to the value + * + * The memset() function returns @s. + * */ +void * +memset(void *s, char c, size_t n) { + 800e23: 55 push %ebp + 800e24: 89 e5 mov %esp,%ebp + 800e26: 83 ec 28 sub $0x28,%esp + 800e29: 89 7d fc mov %edi,-0x4(%ebp) + 800e2c: 8b 45 0c mov 0xc(%ebp),%eax + 800e2f: 88 45 d8 mov %al,-0x28(%ebp) +#ifdef __HAVE_ARCH_MEMSET + return __memset(s, c, n); + 800e32: 0f be 55 d8 movsbl -0x28(%ebp),%edx + 800e36: 8b 45 08 mov 0x8(%ebp),%eax + 800e39: 89 45 f8 mov %eax,-0x8(%ebp) + 800e3c: 88 55 f7 mov %dl,-0x9(%ebp) + 800e3f: 8b 45 10 mov 0x10(%ebp),%eax + 800e42: 89 45 f0 mov %eax,-0x10(%ebp) +#ifndef __HAVE_ARCH_MEMSET +#define __HAVE_ARCH_MEMSET +static inline void * +__memset(void *s, char c, size_t n) { + int d0, d1; + asm volatile ( + 800e45: 8b 4d f0 mov -0x10(%ebp),%ecx + 800e48: 0f b6 45 f7 movzbl -0x9(%ebp),%eax + 800e4c: 8b 55 f8 mov -0x8(%ebp),%edx + 800e4f: 89 d7 mov %edx,%edi + 800e51: f3 aa rep stos %al,%es:(%edi) + 800e53: 89 fa mov %edi,%edx + 800e55: 89 4d ec mov %ecx,-0x14(%ebp) + 800e58: 89 55 e8 mov %edx,-0x18(%ebp) + "rep; stosb;" + : "=&c" (d0), "=&D" (d1) + : "0" (n), "a" (c), "1" (s) + : "memory"); + return s; + 800e5b: 8b 45 f8 mov -0x8(%ebp),%eax + while (n -- > 0) { + *p ++ = c; + } + return s; +#endif /* __HAVE_ARCH_MEMSET */ +} + 800e5e: 8b 7d fc mov -0x4(%ebp),%edi + 800e61: 89 ec mov %ebp,%esp + 800e63: 5d pop %ebp + 800e64: c3 ret + +00800e65 : + * @n: number of bytes to copy + * + * The memmove() function returns @dst. + * */ +void * +memmove(void *dst, const void *src, size_t n) { + 800e65: 55 push %ebp + 800e66: 89 e5 mov %esp,%ebp + 800e68: 57 push %edi + 800e69: 56 push %esi + 800e6a: 53 push %ebx + 800e6b: 83 ec 30 sub $0x30,%esp + 800e6e: 8b 45 08 mov 0x8(%ebp),%eax + 800e71: 89 45 f0 mov %eax,-0x10(%ebp) + 800e74: 8b 45 0c mov 0xc(%ebp),%eax + 800e77: 89 45 ec mov %eax,-0x14(%ebp) + 800e7a: 8b 45 10 mov 0x10(%ebp),%eax + 800e7d: 89 45 e8 mov %eax,-0x18(%ebp) + +#ifndef __HAVE_ARCH_MEMMOVE +#define __HAVE_ARCH_MEMMOVE +static inline void * +__memmove(void *dst, const void *src, size_t n) { + if (dst < src) { + 800e80: 8b 45 f0 mov -0x10(%ebp),%eax + 800e83: 3b 45 ec cmp -0x14(%ebp),%eax + 800e86: 73 42 jae 800eca + 800e88: 8b 45 f0 mov -0x10(%ebp),%eax + 800e8b: 89 45 e4 mov %eax,-0x1c(%ebp) + 800e8e: 8b 45 ec mov -0x14(%ebp),%eax + 800e91: 89 45 e0 mov %eax,-0x20(%ebp) + 800e94: 8b 45 e8 mov -0x18(%ebp),%eax + 800e97: 89 45 dc mov %eax,-0x24(%ebp) + "andl $3, %%ecx;" + "jz 1f;" + "rep; movsb;" + "1:" + : "=&c" (d0), "=&D" (d1), "=&S" (d2) + : "0" (n / 4), "g" (n), "1" (dst), "2" (src) + 800e9a: 8b 45 dc mov -0x24(%ebp),%eax + 800e9d: c1 e8 02 shr $0x2,%eax + 800ea0: 89 c1 mov %eax,%ecx + asm volatile ( + 800ea2: 8b 55 e4 mov -0x1c(%ebp),%edx + 800ea5: 8b 45 e0 mov -0x20(%ebp),%eax + 800ea8: 89 d7 mov %edx,%edi + 800eaa: 89 c6 mov %eax,%esi + 800eac: f3 a5 rep movsl %ds:(%esi),%es:(%edi) + 800eae: 8b 4d dc mov -0x24(%ebp),%ecx + 800eb1: 83 e1 03 and $0x3,%ecx + 800eb4: 74 02 je 800eb8 + 800eb6: f3 a4 rep movsb %ds:(%esi),%es:(%edi) + 800eb8: 89 f0 mov %esi,%eax + 800eba: 89 fa mov %edi,%edx + 800ebc: 89 4d d8 mov %ecx,-0x28(%ebp) + 800ebf: 89 55 d4 mov %edx,-0x2c(%ebp) + 800ec2: 89 45 d0 mov %eax,-0x30(%ebp) + : "memory"); + return dst; + 800ec5: 8b 45 e4 mov -0x1c(%ebp),%eax + return __memcpy(dst, src, n); + 800ec8: eb 36 jmp 800f00 + : "0" (n), "1" (n - 1 + src), "2" (n - 1 + dst) + 800eca: 8b 45 e8 mov -0x18(%ebp),%eax + 800ecd: 8d 50 ff lea -0x1(%eax),%edx + 800ed0: 8b 45 ec mov -0x14(%ebp),%eax + 800ed3: 01 c2 add %eax,%edx + 800ed5: 8b 45 e8 mov -0x18(%ebp),%eax + 800ed8: 8d 48 ff lea -0x1(%eax),%ecx + 800edb: 8b 45 f0 mov -0x10(%ebp),%eax + 800ede: 8d 1c 01 lea (%ecx,%eax,1),%ebx + asm volatile ( + 800ee1: 8b 45 e8 mov -0x18(%ebp),%eax + 800ee4: 89 c1 mov %eax,%ecx + 800ee6: 89 d8 mov %ebx,%eax + 800ee8: 89 d6 mov %edx,%esi + 800eea: 89 c7 mov %eax,%edi + 800eec: fd std + 800eed: f3 a4 rep movsb %ds:(%esi),%es:(%edi) + 800eef: fc cld + 800ef0: 89 f8 mov %edi,%eax + 800ef2: 89 f2 mov %esi,%edx + 800ef4: 89 4d cc mov %ecx,-0x34(%ebp) + 800ef7: 89 55 c8 mov %edx,-0x38(%ebp) + 800efa: 89 45 c4 mov %eax,-0x3c(%ebp) + return dst; + 800efd: 8b 45 f0 mov -0x10(%ebp),%eax + *d ++ = *s ++; + } + } + return dst; +#endif /* __HAVE_ARCH_MEMMOVE */ +} + 800f00: 83 c4 30 add $0x30,%esp + 800f03: 5b pop %ebx + 800f04: 5e pop %esi + 800f05: 5f pop %edi + 800f06: 5d pop %ebp + 800f07: c3 ret + +00800f08 : + * it always copies exactly @n bytes. To avoid overflows, the size of arrays pointed + * by both @src and @dst, should be at least @n bytes, and should not overlap + * (for overlapping memory area, memmove is a safer approach). + * */ +void * +memcpy(void *dst, const void *src, size_t n) { + 800f08: 55 push %ebp + 800f09: 89 e5 mov %esp,%ebp + 800f0b: 57 push %edi + 800f0c: 56 push %esi + 800f0d: 83 ec 20 sub $0x20,%esp + 800f10: 8b 45 08 mov 0x8(%ebp),%eax + 800f13: 89 45 f4 mov %eax,-0xc(%ebp) + 800f16: 8b 45 0c mov 0xc(%ebp),%eax + 800f19: 89 45 f0 mov %eax,-0x10(%ebp) + 800f1c: 8b 45 10 mov 0x10(%ebp),%eax + 800f1f: 89 45 ec mov %eax,-0x14(%ebp) + : "0" (n / 4), "g" (n), "1" (dst), "2" (src) + 800f22: 8b 45 ec mov -0x14(%ebp),%eax + 800f25: c1 e8 02 shr $0x2,%eax + 800f28: 89 c1 mov %eax,%ecx + asm volatile ( + 800f2a: 8b 55 f4 mov -0xc(%ebp),%edx + 800f2d: 8b 45 f0 mov -0x10(%ebp),%eax + 800f30: 89 d7 mov %edx,%edi + 800f32: 89 c6 mov %eax,%esi + 800f34: f3 a5 rep movsl %ds:(%esi),%es:(%edi) + 800f36: 8b 4d ec mov -0x14(%ebp),%ecx + 800f39: 83 e1 03 and $0x3,%ecx + 800f3c: 74 02 je 800f40 + 800f3e: f3 a4 rep movsb %ds:(%esi),%es:(%edi) + 800f40: 89 f0 mov %esi,%eax + 800f42: 89 fa mov %edi,%edx + 800f44: 89 4d e8 mov %ecx,-0x18(%ebp) + 800f47: 89 55 e4 mov %edx,-0x1c(%ebp) + 800f4a: 89 45 e0 mov %eax,-0x20(%ebp) + return dst; + 800f4d: 8b 45 f4 mov -0xc(%ebp),%eax + while (n -- > 0) { + *d ++ = *s ++; + } + return dst; +#endif /* __HAVE_ARCH_MEMCPY */ +} + 800f50: 83 c4 20 add $0x20,%esp + 800f53: 5e pop %esi + 800f54: 5f pop %edi + 800f55: 5d pop %ebp + 800f56: c3 ret + +00800f57 : + * match in both memory blocks has a greater value in @v1 than in @v2 + * as if evaluated as unsigned char values; + * - And a value less than zero indicates the opposite. + * */ +int +memcmp(const void *v1, const void *v2, size_t n) { + 800f57: 55 push %ebp + 800f58: 89 e5 mov %esp,%ebp + 800f5a: 83 ec 10 sub $0x10,%esp + const char *s1 = (const char *)v1; + 800f5d: 8b 45 08 mov 0x8(%ebp),%eax + 800f60: 89 45 fc mov %eax,-0x4(%ebp) + const char *s2 = (const char *)v2; + 800f63: 8b 45 0c mov 0xc(%ebp),%eax + 800f66: 89 45 f8 mov %eax,-0x8(%ebp) + while (n -- > 0) { + 800f69: eb 2e jmp 800f99 + if (*s1 != *s2) { + 800f6b: 8b 45 fc mov -0x4(%ebp),%eax + 800f6e: 0f b6 10 movzbl (%eax),%edx + 800f71: 8b 45 f8 mov -0x8(%ebp),%eax + 800f74: 0f b6 00 movzbl (%eax),%eax + 800f77: 38 c2 cmp %al,%dl + 800f79: 74 18 je 800f93 + return (int)((unsigned char)*s1 - (unsigned char)*s2); + 800f7b: 8b 45 fc mov -0x4(%ebp),%eax + 800f7e: 0f b6 00 movzbl (%eax),%eax + 800f81: 0f b6 d0 movzbl %al,%edx + 800f84: 8b 45 f8 mov -0x8(%ebp),%eax + 800f87: 0f b6 00 movzbl (%eax),%eax + 800f8a: 0f b6 c8 movzbl %al,%ecx + 800f8d: 89 d0 mov %edx,%eax + 800f8f: 29 c8 sub %ecx,%eax + 800f91: eb 18 jmp 800fab + } + s1 ++, s2 ++; + 800f93: ff 45 fc incl -0x4(%ebp) + 800f96: ff 45 f8 incl -0x8(%ebp) + while (n -- > 0) { + 800f99: 8b 45 10 mov 0x10(%ebp),%eax + 800f9c: 8d 50 ff lea -0x1(%eax),%edx + 800f9f: 89 55 10 mov %edx,0x10(%ebp) + 800fa2: 85 c0 test %eax,%eax + 800fa4: 75 c5 jne 800f6b + } + return 0; + 800fa6: b8 00 00 00 00 mov $0x0,%eax +} + 800fab: 89 ec mov %ebp,%esp + 800fad: 5d pop %ebp + 800fae: c3 ret + +00800faf
: +#include +#include + +int +main(void) { + 800faf: 55 push %ebp + 800fb0: 89 e5 mov %esp,%ebp + 800fb2: 83 e4 f0 and $0xfffffff0,%esp + 800fb5: 83 ec 20 sub $0x20,%esp + int pid, ret; + cprintf("I am the parent. Forking the child...\n"); + 800fb8: c7 04 24 c0 13 80 00 movl $0x8013c0,(%esp) + 800fbf: e8 5c f1 ff ff call 800120 + if ((pid = fork()) == 0) { + 800fc4: e8 17 f3 ff ff call 8002e0 + 800fc9: 89 44 24 1c mov %eax,0x1c(%esp) + 800fcd: 83 7c 24 1c 00 cmpl $0x0,0x1c(%esp) + 800fd2: 75 0e jne 800fe2 + cprintf("I am the child. spinning ...\n"); + 800fd4: c7 04 24 e7 13 80 00 movl $0x8013e7,(%esp) + 800fdb: e8 40 f1 ff ff call 800120 + while (1); + 800fe0: eb fe jmp 800fe0 + } + cprintf("I am the parent. Running the child...\n"); + 800fe2: c7 04 24 08 14 80 00 movl $0x801408,(%esp) + 800fe9: e8 32 f1 ff ff call 800120 + + yield(); + 800fee: e8 36 f3 ff ff call 800329 + yield(); + 800ff3: e8 31 f3 ff ff call 800329 + yield(); + 800ff8: e8 2c f3 ff ff call 800329 + + cprintf("I am the parent. Killing the child...\n"); + 800ffd: c7 04 24 30 14 80 00 movl $0x801430,(%esp) + 801004: e8 17 f1 ff ff call 800120 + + assert((ret = kill(pid)) == 0); + 801009: 8b 44 24 1c mov 0x1c(%esp),%eax + 80100d: 89 04 24 mov %eax,(%esp) + 801010: e8 24 f3 ff ff call 800339 + 801015: 89 44 24 18 mov %eax,0x18(%esp) + 801019: 83 7c 24 18 00 cmpl $0x0,0x18(%esp) + 80101e: 74 24 je 801044 + 801020: c7 44 24 0c 58 14 80 movl $0x801458,0xc(%esp) + 801027: 00 + 801028: c7 44 24 08 6f 14 80 movl $0x80146f,0x8(%esp) + 80102f: 00 + 801030: c7 44 24 04 14 00 00 movl $0x14,0x4(%esp) + 801037: 00 + 801038: c7 04 24 84 14 80 00 movl $0x801484,(%esp) + 80103f: e8 eb ef ff ff call 80002f <__panic> + cprintf("kill returns %d\n", ret); + 801044: 8b 44 24 18 mov 0x18(%esp),%eax + 801048: 89 44 24 04 mov %eax,0x4(%esp) + 80104c: c7 04 24 90 14 80 00 movl $0x801490,(%esp) + 801053: e8 c8 f0 ff ff call 800120 + + assert((ret = waitpid(pid, NULL)) == 0); + 801058: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) + 80105f: 00 + 801060: 8b 44 24 1c mov 0x1c(%esp),%eax + 801064: 89 04 24 mov %eax,(%esp) + 801067: e8 a1 f2 ff ff call 80030d + 80106c: 89 44 24 18 mov %eax,0x18(%esp) + 801070: 83 7c 24 18 00 cmpl $0x0,0x18(%esp) + 801075: 74 24 je 80109b + 801077: c7 44 24 0c a4 14 80 movl $0x8014a4,0xc(%esp) + 80107e: 00 + 80107f: c7 44 24 08 6f 14 80 movl $0x80146f,0x8(%esp) + 801086: 00 + 801087: c7 44 24 04 17 00 00 movl $0x17,0x4(%esp) + 80108e: 00 + 80108f: c7 04 24 84 14 80 00 movl $0x801484,(%esp) + 801096: e8 94 ef ff ff call 80002f <__panic> + cprintf("wait returns %d\n", ret); + 80109b: 8b 44 24 18 mov 0x18(%esp),%eax + 80109f: 89 44 24 04 mov %eax,0x4(%esp) + 8010a3: c7 04 24 c4 14 80 00 movl $0x8014c4,(%esp) + 8010aa: e8 71 f0 ff ff call 800120 + + cprintf("spin may pass.\n"); + 8010af: c7 04 24 d5 14 80 00 movl $0x8014d5,(%esp) + 8010b6: e8 65 f0 ff ff call 800120 + return 0; + 8010bb: b8 00 00 00 00 mov $0x0,%eax +} + 8010c0: 89 ec mov %ebp,%esp + 8010c2: 5d pop %ebp + 8010c3: c3 ret diff --git a/labcodes/lab5/obj/user/spin.d b/labcodes/lab5/obj/user/spin.d new file mode 100644 index 0000000000000000000000000000000000000000..b0882d9294299a5ede3026b2f0a25b39f9cc70dc --- /dev/null +++ b/labcodes/lab5/obj/user/spin.d @@ -0,0 +1,2 @@ +obj/user/spin.o obj/user/spin.d: user/spin.c libs/stdio.h libs/defs.h \ + libs/stdarg.h user/libs/ulib.h diff --git a/labcodes/lab5/obj/user/spin.o b/labcodes/lab5/obj/user/spin.o new file mode 100644 index 0000000000000000000000000000000000000000..faeda0f693c3c6e4448c37b6c0970161915782d1 Binary files /dev/null and b/labcodes/lab5/obj/user/spin.o differ diff --git a/labcodes/lab5/obj/user/spin.sym b/labcodes/lab5/obj/user/spin.sym new file mode 100644 index 0000000000000000000000000000000000000000..01216145de8a8925793a8b99712f5a8feedbe225 --- /dev/null +++ b/labcodes/lab5/obj/user/spin.sym @@ -0,0 +1,66 @@ +00000000 panic.c +00000000 stdio.c +008000c8 cputch +00000000 syscall.c +00800199 syscall +00000000 ulib.c +00000000 umain.c +00000000 hash.c +00000000 printfmt.c +008011e0 error_string +008003ad printnum +008004af getuint +008004fe getint +0080094f sprintputch +00000000 rand.c +00802000 next +00000000 string.c +00000000 spin.c +00800b53 strcpy +00800329 yield +0080030d waitpid +00800245 sys_yield +00800e65 memmove +00800985 snprintf +00800576 vprintfmt +0080020b sys_fork +00800120 cprintf +0080034e getpid +00800f08 memcpy +008009bb vsnprintf +0080036d umain +002027c4 __STAB_END__ +0080025b sys_kill +002027c5 __STABSTR_BEGIN__ +0080002f __panic +00800ccb strtol +00800b22 strnlen +0080035d print_pgdir +00800339 kill +00800c9b strfind +008002ef wait +00800020 _start +00800a21 rand +00800c14 strncmp +0080028e sys_putc +00800b92 strncpy +00800f57 memcmp +008002e0 fork +00800e23 memset +00800faf main +00800ae0 srand +00800386 hash32 +00800545 printfmt +002036ed __STABSTR_END__ +00800bcb strcmp +008000eb vcprintf +0080007f __warn +00800148 cputs +008002c1 exit +00800221 sys_wait +008001ee sys_exit +00200010 __STAB_BEGIN__ +00800af9 strlen +008002ab sys_pgdir +00800c67 strchr +00800278 sys_getpid diff --git a/labcodes/lab5/obj/user/testbss.asm b/labcodes/lab5/obj/user/testbss.asm new file mode 100644 index 0000000000000000000000000000000000000000..8df6b763eccc049e1e06fbd7ed0213782c3c4cf3 --- /dev/null +++ b/labcodes/lab5/obj/user/testbss.asm @@ -0,0 +1,2400 @@ + +obj/__user_testbss.out: file format elf32-i386 + + +Disassembly of section .text: + +00800020 <_start>: +.text +.globl _start +_start: + # set ebp for backtrace + movl $0x0, %ebp + 800020: bd 00 00 00 00 mov $0x0,%ebp + + # move down the esp register + # since it may cause page fault in backtrace + subl $0x20, %esp + 800025: 83 ec 20 sub $0x20,%esp + + # call user-program function + call umain + 800028: e8 40 03 00 00 call 80036d +1: jmp 1b + 80002d: eb fe jmp 80002d <_start+0xd> + +0080002f <__panic>: +#include +#include +#include + +void +__panic(const char *file, int line, const char *fmt, ...) { + 80002f: 55 push %ebp + 800030: 89 e5 mov %esp,%ebp + 800032: 83 ec 28 sub $0x28,%esp + // print the 'message' + va_list ap; + va_start(ap, fmt); + 800035: 8d 45 14 lea 0x14(%ebp),%eax + 800038: 89 45 f4 mov %eax,-0xc(%ebp) + cprintf("user panic at %s:%d:\n ", file, line); + 80003b: 8b 45 0c mov 0xc(%ebp),%eax + 80003e: 89 44 24 08 mov %eax,0x8(%esp) + 800042: 8b 45 08 mov 0x8(%ebp),%eax + 800045: 89 44 24 04 mov %eax,0x4(%esp) + 800049: c7 04 24 e0 10 80 00 movl $0x8010e0,(%esp) + 800050: e8 cb 00 00 00 call 800120 + vcprintf(fmt, ap); + 800055: 8b 45 f4 mov -0xc(%ebp),%eax + 800058: 89 44 24 04 mov %eax,0x4(%esp) + 80005c: 8b 45 10 mov 0x10(%ebp),%eax + 80005f: 89 04 24 mov %eax,(%esp) + 800062: e8 84 00 00 00 call 8000eb + cprintf("\n"); + 800067: c7 04 24 fa 10 80 00 movl $0x8010fa,(%esp) + 80006e: e8 ad 00 00 00 call 800120 + va_end(ap); + exit(-E_PANIC); + 800073: c7 04 24 f6 ff ff ff movl $0xfffffff6,(%esp) + 80007a: e8 42 02 00 00 call 8002c1 + +0080007f <__warn>: +} + +void +__warn(const char *file, int line, const char *fmt, ...) { + 80007f: 55 push %ebp + 800080: 89 e5 mov %esp,%ebp + 800082: 83 ec 28 sub $0x28,%esp + va_list ap; + va_start(ap, fmt); + 800085: 8d 45 14 lea 0x14(%ebp),%eax + 800088: 89 45 f4 mov %eax,-0xc(%ebp) + cprintf("user warning at %s:%d:\n ", file, line); + 80008b: 8b 45 0c mov 0xc(%ebp),%eax + 80008e: 89 44 24 08 mov %eax,0x8(%esp) + 800092: 8b 45 08 mov 0x8(%ebp),%eax + 800095: 89 44 24 04 mov %eax,0x4(%esp) + 800099: c7 04 24 fc 10 80 00 movl $0x8010fc,(%esp) + 8000a0: e8 7b 00 00 00 call 800120 + vcprintf(fmt, ap); + 8000a5: 8b 45 f4 mov -0xc(%ebp),%eax + 8000a8: 89 44 24 04 mov %eax,0x4(%esp) + 8000ac: 8b 45 10 mov 0x10(%ebp),%eax + 8000af: 89 04 24 mov %eax,(%esp) + 8000b2: e8 34 00 00 00 call 8000eb + cprintf("\n"); + 8000b7: c7 04 24 fa 10 80 00 movl $0x8010fa,(%esp) + 8000be: e8 5d 00 00 00 call 800120 + va_end(ap); +} + 8000c3: 90 nop + 8000c4: 89 ec mov %ebp,%esp + 8000c6: 5d pop %ebp + 8000c7: c3 ret + +008000c8 : +/* * + * cputch - writes a single character @c to stdout, and it will + * increace the value of counter pointed by @cnt. + * */ +static void +cputch(int c, int *cnt) { + 8000c8: 55 push %ebp + 8000c9: 89 e5 mov %esp,%ebp + 8000cb: 83 ec 18 sub $0x18,%esp + sys_putc(c); + 8000ce: 8b 45 08 mov 0x8(%ebp),%eax + 8000d1: 89 04 24 mov %eax,(%esp) + 8000d4: e8 b5 01 00 00 call 80028e + (*cnt) ++; + 8000d9: 8b 45 0c mov 0xc(%ebp),%eax + 8000dc: 8b 00 mov (%eax),%eax + 8000de: 8d 50 01 lea 0x1(%eax),%edx + 8000e1: 8b 45 0c mov 0xc(%ebp),%eax + 8000e4: 89 10 mov %edx,(%eax) +} + 8000e6: 90 nop + 8000e7: 89 ec mov %ebp,%esp + 8000e9: 5d pop %ebp + 8000ea: c3 ret + +008000eb : + * + * Call this function if you are already dealing with a va_list. + * Or you probably want cprintf() instead. + * */ +int +vcprintf(const char *fmt, va_list ap) { + 8000eb: 55 push %ebp + 8000ec: 89 e5 mov %esp,%ebp + 8000ee: 83 ec 28 sub $0x28,%esp + int cnt = 0; + 8000f1: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + vprintfmt((void*)cputch, &cnt, fmt, ap); + 8000f8: 8b 45 0c mov 0xc(%ebp),%eax + 8000fb: 89 44 24 0c mov %eax,0xc(%esp) + 8000ff: 8b 45 08 mov 0x8(%ebp),%eax + 800102: 89 44 24 08 mov %eax,0x8(%esp) + 800106: 8d 45 f4 lea -0xc(%ebp),%eax + 800109: 89 44 24 04 mov %eax,0x4(%esp) + 80010d: c7 04 24 c8 00 80 00 movl $0x8000c8,(%esp) + 800114: e8 5d 04 00 00 call 800576 + return cnt; + 800119: 8b 45 f4 mov -0xc(%ebp),%eax +} + 80011c: 89 ec mov %ebp,%esp + 80011e: 5d pop %ebp + 80011f: c3 ret + +00800120 : + * + * The return value is the number of characters which would be + * written to stdout. + * */ +int +cprintf(const char *fmt, ...) { + 800120: 55 push %ebp + 800121: 89 e5 mov %esp,%ebp + 800123: 83 ec 28 sub $0x28,%esp + va_list ap; + + va_start(ap, fmt); + 800126: 8d 45 0c lea 0xc(%ebp),%eax + 800129: 89 45 f0 mov %eax,-0x10(%ebp) + int cnt = vcprintf(fmt, ap); + 80012c: 8b 45 f0 mov -0x10(%ebp),%eax + 80012f: 89 44 24 04 mov %eax,0x4(%esp) + 800133: 8b 45 08 mov 0x8(%ebp),%eax + 800136: 89 04 24 mov %eax,(%esp) + 800139: e8 ad ff ff ff call 8000eb + 80013e: 89 45 f4 mov %eax,-0xc(%ebp) + va_end(ap); + + return cnt; + 800141: 8b 45 f4 mov -0xc(%ebp),%eax +} + 800144: 89 ec mov %ebp,%esp + 800146: 5d pop %ebp + 800147: c3 ret + +00800148 : +/* * + * cputs- writes the string pointed by @str to stdout and + * appends a newline character. + * */ +int +cputs(const char *str) { + 800148: 55 push %ebp + 800149: 89 e5 mov %esp,%ebp + 80014b: 83 ec 28 sub $0x28,%esp + int cnt = 0; + 80014e: c7 45 f0 00 00 00 00 movl $0x0,-0x10(%ebp) + char c; + while ((c = *str ++) != '\0') { + 800155: eb 13 jmp 80016a + cputch(c, &cnt); + 800157: 0f be 45 f7 movsbl -0x9(%ebp),%eax + 80015b: 8d 55 f0 lea -0x10(%ebp),%edx + 80015e: 89 54 24 04 mov %edx,0x4(%esp) + 800162: 89 04 24 mov %eax,(%esp) + 800165: e8 5e ff ff ff call 8000c8 + while ((c = *str ++) != '\0') { + 80016a: 8b 45 08 mov 0x8(%ebp),%eax + 80016d: 8d 50 01 lea 0x1(%eax),%edx + 800170: 89 55 08 mov %edx,0x8(%ebp) + 800173: 0f b6 00 movzbl (%eax),%eax + 800176: 88 45 f7 mov %al,-0x9(%ebp) + 800179: 80 7d f7 00 cmpb $0x0,-0x9(%ebp) + 80017d: 75 d8 jne 800157 + } + cputch('\n', &cnt); + 80017f: 8d 45 f0 lea -0x10(%ebp),%eax + 800182: 89 44 24 04 mov %eax,0x4(%esp) + 800186: c7 04 24 0a 00 00 00 movl $0xa,(%esp) + 80018d: e8 36 ff ff ff call 8000c8 + return cnt; + 800192: 8b 45 f0 mov -0x10(%ebp),%eax +} + 800195: 89 ec mov %ebp,%esp + 800197: 5d pop %ebp + 800198: c3 ret + +00800199 : +#include + +#define MAX_ARGS 5 + +static inline int +syscall(int num, ...) { + 800199: 55 push %ebp + 80019a: 89 e5 mov %esp,%ebp + 80019c: 57 push %edi + 80019d: 56 push %esi + 80019e: 53 push %ebx + 80019f: 83 ec 20 sub $0x20,%esp + va_list ap; + va_start(ap, num); + 8001a2: 8d 45 0c lea 0xc(%ebp),%eax + 8001a5: 89 45 e8 mov %eax,-0x18(%ebp) + uint32_t a[MAX_ARGS]; + int i, ret; + for (i = 0; i < MAX_ARGS; i ++) { + 8001a8: c7 45 f0 00 00 00 00 movl $0x0,-0x10(%ebp) + 8001af: eb 15 jmp 8001c6 + a[i] = va_arg(ap, uint32_t); + 8001b1: 8b 45 e8 mov -0x18(%ebp),%eax + 8001b4: 8d 50 04 lea 0x4(%eax),%edx + 8001b7: 89 55 e8 mov %edx,-0x18(%ebp) + 8001ba: 8b 10 mov (%eax),%edx + 8001bc: 8b 45 f0 mov -0x10(%ebp),%eax + 8001bf: 89 54 85 d4 mov %edx,-0x2c(%ebp,%eax,4) + for (i = 0; i < MAX_ARGS; i ++) { + 8001c3: ff 45 f0 incl -0x10(%ebp) + 8001c6: 83 7d f0 04 cmpl $0x4,-0x10(%ebp) + 8001ca: 7e e5 jle 8001b1 + asm volatile ( + "int %1;" + : "=a" (ret) + : "i" (T_SYSCALL), + "a" (num), + "d" (a[0]), + 8001cc: 8b 55 d4 mov -0x2c(%ebp),%edx + "c" (a[1]), + 8001cf: 8b 4d d8 mov -0x28(%ebp),%ecx + "b" (a[2]), + 8001d2: 8b 5d dc mov -0x24(%ebp),%ebx + "D" (a[3]), + 8001d5: 8b 7d e0 mov -0x20(%ebp),%edi + "S" (a[4]) + 8001d8: 8b 75 e4 mov -0x1c(%ebp),%esi + asm volatile ( + 8001db: 8b 45 08 mov 0x8(%ebp),%eax + 8001de: cd 80 int $0x80 + 8001e0: 89 45 ec mov %eax,-0x14(%ebp) + : "cc", "memory"); + return ret; + 8001e3: 8b 45 ec mov -0x14(%ebp),%eax +} + 8001e6: 83 c4 20 add $0x20,%esp + 8001e9: 5b pop %ebx + 8001ea: 5e pop %esi + 8001eb: 5f pop %edi + 8001ec: 5d pop %ebp + 8001ed: c3 ret + +008001ee : + +int +sys_exit(int error_code) { + 8001ee: 55 push %ebp + 8001ef: 89 e5 mov %esp,%ebp + 8001f1: 83 ec 08 sub $0x8,%esp + return syscall(SYS_exit, error_code); + 8001f4: 8b 45 08 mov 0x8(%ebp),%eax + 8001f7: 89 44 24 04 mov %eax,0x4(%esp) + 8001fb: c7 04 24 01 00 00 00 movl $0x1,(%esp) + 800202: e8 92 ff ff ff call 800199 +} + 800207: 89 ec mov %ebp,%esp + 800209: 5d pop %ebp + 80020a: c3 ret + +0080020b : + +int +sys_fork(void) { + 80020b: 55 push %ebp + 80020c: 89 e5 mov %esp,%ebp + 80020e: 83 ec 04 sub $0x4,%esp + return syscall(SYS_fork); + 800211: c7 04 24 02 00 00 00 movl $0x2,(%esp) + 800218: e8 7c ff ff ff call 800199 +} + 80021d: 89 ec mov %ebp,%esp + 80021f: 5d pop %ebp + 800220: c3 ret + +00800221 : + +int +sys_wait(int pid, int *store) { + 800221: 55 push %ebp + 800222: 89 e5 mov %esp,%ebp + 800224: 83 ec 0c sub $0xc,%esp + return syscall(SYS_wait, pid, store); + 800227: 8b 45 0c mov 0xc(%ebp),%eax + 80022a: 89 44 24 08 mov %eax,0x8(%esp) + 80022e: 8b 45 08 mov 0x8(%ebp),%eax + 800231: 89 44 24 04 mov %eax,0x4(%esp) + 800235: c7 04 24 03 00 00 00 movl $0x3,(%esp) + 80023c: e8 58 ff ff ff call 800199 +} + 800241: 89 ec mov %ebp,%esp + 800243: 5d pop %ebp + 800244: c3 ret + +00800245 : + +int +sys_yield(void) { + 800245: 55 push %ebp + 800246: 89 e5 mov %esp,%ebp + 800248: 83 ec 04 sub $0x4,%esp + return syscall(SYS_yield); + 80024b: c7 04 24 0a 00 00 00 movl $0xa,(%esp) + 800252: e8 42 ff ff ff call 800199 +} + 800257: 89 ec mov %ebp,%esp + 800259: 5d pop %ebp + 80025a: c3 ret + +0080025b : + +int +sys_kill(int pid) { + 80025b: 55 push %ebp + 80025c: 89 e5 mov %esp,%ebp + 80025e: 83 ec 08 sub $0x8,%esp + return syscall(SYS_kill, pid); + 800261: 8b 45 08 mov 0x8(%ebp),%eax + 800264: 89 44 24 04 mov %eax,0x4(%esp) + 800268: c7 04 24 0c 00 00 00 movl $0xc,(%esp) + 80026f: e8 25 ff ff ff call 800199 +} + 800274: 89 ec mov %ebp,%esp + 800276: 5d pop %ebp + 800277: c3 ret + +00800278 : + +int +sys_getpid(void) { + 800278: 55 push %ebp + 800279: 89 e5 mov %esp,%ebp + 80027b: 83 ec 04 sub $0x4,%esp + return syscall(SYS_getpid); + 80027e: c7 04 24 12 00 00 00 movl $0x12,(%esp) + 800285: e8 0f ff ff ff call 800199 +} + 80028a: 89 ec mov %ebp,%esp + 80028c: 5d pop %ebp + 80028d: c3 ret + +0080028e : + +int +sys_putc(int c) { + 80028e: 55 push %ebp + 80028f: 89 e5 mov %esp,%ebp + 800291: 83 ec 08 sub $0x8,%esp + return syscall(SYS_putc, c); + 800294: 8b 45 08 mov 0x8(%ebp),%eax + 800297: 89 44 24 04 mov %eax,0x4(%esp) + 80029b: c7 04 24 1e 00 00 00 movl $0x1e,(%esp) + 8002a2: e8 f2 fe ff ff call 800199 +} + 8002a7: 89 ec mov %ebp,%esp + 8002a9: 5d pop %ebp + 8002aa: c3 ret + +008002ab : + +int +sys_pgdir(void) { + 8002ab: 55 push %ebp + 8002ac: 89 e5 mov %esp,%ebp + 8002ae: 83 ec 04 sub $0x4,%esp + return syscall(SYS_pgdir); + 8002b1: c7 04 24 1f 00 00 00 movl $0x1f,(%esp) + 8002b8: e8 dc fe ff ff call 800199 +} + 8002bd: 89 ec mov %ebp,%esp + 8002bf: 5d pop %ebp + 8002c0: c3 ret + +008002c1 : +#include +#include +#include + +void +exit(int error_code) { + 8002c1: 55 push %ebp + 8002c2: 89 e5 mov %esp,%ebp + 8002c4: 83 ec 18 sub $0x18,%esp + sys_exit(error_code); + 8002c7: 8b 45 08 mov 0x8(%ebp),%eax + 8002ca: 89 04 24 mov %eax,(%esp) + 8002cd: e8 1c ff ff ff call 8001ee + cprintf("BUG: exit failed.\n"); + 8002d2: c7 04 24 18 11 80 00 movl $0x801118,(%esp) + 8002d9: e8 42 fe ff ff call 800120 + while (1); + 8002de: eb fe jmp 8002de + +008002e0 : +} + +int +fork(void) { + 8002e0: 55 push %ebp + 8002e1: 89 e5 mov %esp,%ebp + 8002e3: 83 ec 08 sub $0x8,%esp + return sys_fork(); + 8002e6: e8 20 ff ff ff call 80020b +} + 8002eb: 89 ec mov %ebp,%esp + 8002ed: 5d pop %ebp + 8002ee: c3 ret + +008002ef : + +int +wait(void) { + 8002ef: 55 push %ebp + 8002f0: 89 e5 mov %esp,%ebp + 8002f2: 83 ec 18 sub $0x18,%esp + return sys_wait(0, NULL); + 8002f5: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) + 8002fc: 00 + 8002fd: c7 04 24 00 00 00 00 movl $0x0,(%esp) + 800304: e8 18 ff ff ff call 800221 +} + 800309: 89 ec mov %ebp,%esp + 80030b: 5d pop %ebp + 80030c: c3 ret + +0080030d : + +int +waitpid(int pid, int *store) { + 80030d: 55 push %ebp + 80030e: 89 e5 mov %esp,%ebp + 800310: 83 ec 18 sub $0x18,%esp + return sys_wait(pid, store); + 800313: 8b 45 0c mov 0xc(%ebp),%eax + 800316: 89 44 24 04 mov %eax,0x4(%esp) + 80031a: 8b 45 08 mov 0x8(%ebp),%eax + 80031d: 89 04 24 mov %eax,(%esp) + 800320: e8 fc fe ff ff call 800221 +} + 800325: 89 ec mov %ebp,%esp + 800327: 5d pop %ebp + 800328: c3 ret + +00800329 : + +void +yield(void) { + 800329: 55 push %ebp + 80032a: 89 e5 mov %esp,%ebp + 80032c: 83 ec 08 sub $0x8,%esp + sys_yield(); + 80032f: e8 11 ff ff ff call 800245 +} + 800334: 90 nop + 800335: 89 ec mov %ebp,%esp + 800337: 5d pop %ebp + 800338: c3 ret + +00800339 : + +int +kill(int pid) { + 800339: 55 push %ebp + 80033a: 89 e5 mov %esp,%ebp + 80033c: 83 ec 18 sub $0x18,%esp + return sys_kill(pid); + 80033f: 8b 45 08 mov 0x8(%ebp),%eax + 800342: 89 04 24 mov %eax,(%esp) + 800345: e8 11 ff ff ff call 80025b +} + 80034a: 89 ec mov %ebp,%esp + 80034c: 5d pop %ebp + 80034d: c3 ret + +0080034e : + +int +getpid(void) { + 80034e: 55 push %ebp + 80034f: 89 e5 mov %esp,%ebp + 800351: 83 ec 08 sub $0x8,%esp + return sys_getpid(); + 800354: e8 1f ff ff ff call 800278 +} + 800359: 89 ec mov %ebp,%esp + 80035b: 5d pop %ebp + 80035c: c3 ret + +0080035d : + +//print_pgdir - print the PDT&PT +void +print_pgdir(void) { + 80035d: 55 push %ebp + 80035e: 89 e5 mov %esp,%ebp + 800360: 83 ec 08 sub $0x8,%esp + sys_pgdir(); + 800363: e8 43 ff ff ff call 8002ab +} + 800368: 90 nop + 800369: 89 ec mov %ebp,%esp + 80036b: 5d pop %ebp + 80036c: c3 ret + +0080036d : +#include + +int main(void); + +void +umain(void) { + 80036d: 55 push %ebp + 80036e: 89 e5 mov %esp,%ebp + 800370: 83 ec 28 sub $0x28,%esp + int ret = main(); + 800373: e8 37 0c 00 00 call 800faf
+ 800378: 89 45 f4 mov %eax,-0xc(%ebp) + exit(ret); + 80037b: 8b 45 f4 mov -0xc(%ebp),%eax + 80037e: 89 04 24 mov %eax,(%esp) + 800381: e8 3b ff ff ff call 8002c1 + +00800386 : + * @bits: the number of bits in a return value + * + * High bits are more random, so we use them. + * */ +uint32_t +hash32(uint32_t val, unsigned int bits) { + 800386: 55 push %ebp + 800387: 89 e5 mov %esp,%ebp + 800389: 83 ec 10 sub $0x10,%esp + uint32_t hash = val * GOLDEN_RATIO_PRIME_32; + 80038c: 8b 45 08 mov 0x8(%ebp),%eax + 80038f: 69 c0 01 00 37 9e imul $0x9e370001,%eax,%eax + 800395: 89 45 fc mov %eax,-0x4(%ebp) + return (hash >> (32 - bits)); + 800398: b8 20 00 00 00 mov $0x20,%eax + 80039d: 2b 45 0c sub 0xc(%ebp),%eax + 8003a0: 8b 55 fc mov -0x4(%ebp),%edx + 8003a3: 88 c1 mov %al,%cl + 8003a5: d3 ea shr %cl,%edx + 8003a7: 89 d0 mov %edx,%eax +} + 8003a9: 89 ec mov %ebp,%esp + 8003ab: 5d pop %ebp + 8003ac: c3 ret + +008003ad : + * @width: maximum number of digits, if the actual width is less than @width, use @padc instead + * @padc: character that padded on the left if the actual width is less than @width + * */ +static void +printnum(void (*putch)(int, void*), void *putdat, + unsigned long long num, unsigned base, int width, int padc) { + 8003ad: 55 push %ebp + 8003ae: 89 e5 mov %esp,%ebp + 8003b0: 83 ec 58 sub $0x58,%esp + 8003b3: 8b 45 10 mov 0x10(%ebp),%eax + 8003b6: 89 45 d0 mov %eax,-0x30(%ebp) + 8003b9: 8b 45 14 mov 0x14(%ebp),%eax + 8003bc: 89 45 d4 mov %eax,-0x2c(%ebp) + unsigned long long result = num; + 8003bf: 8b 45 d0 mov -0x30(%ebp),%eax + 8003c2: 8b 55 d4 mov -0x2c(%ebp),%edx + 8003c5: 89 45 e8 mov %eax,-0x18(%ebp) + 8003c8: 89 55 ec mov %edx,-0x14(%ebp) + unsigned mod = do_div(result, base); + 8003cb: 8b 45 18 mov 0x18(%ebp),%eax + 8003ce: 89 45 e4 mov %eax,-0x1c(%ebp) + 8003d1: 8b 45 e8 mov -0x18(%ebp),%eax + 8003d4: 8b 55 ec mov -0x14(%ebp),%edx + 8003d7: 89 45 e0 mov %eax,-0x20(%ebp) + 8003da: 89 55 f0 mov %edx,-0x10(%ebp) + 8003dd: 8b 45 f0 mov -0x10(%ebp),%eax + 8003e0: 89 45 f4 mov %eax,-0xc(%ebp) + 8003e3: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) + 8003e7: 74 1c je 800405 + 8003e9: 8b 45 f0 mov -0x10(%ebp),%eax + 8003ec: ba 00 00 00 00 mov $0x0,%edx + 8003f1: f7 75 e4 divl -0x1c(%ebp) + 8003f4: 89 55 f4 mov %edx,-0xc(%ebp) + 8003f7: 8b 45 f0 mov -0x10(%ebp),%eax + 8003fa: ba 00 00 00 00 mov $0x0,%edx + 8003ff: f7 75 e4 divl -0x1c(%ebp) + 800402: 89 45 f0 mov %eax,-0x10(%ebp) + 800405: 8b 45 e0 mov -0x20(%ebp),%eax + 800408: 8b 55 f4 mov -0xc(%ebp),%edx + 80040b: f7 75 e4 divl -0x1c(%ebp) + 80040e: 89 45 e0 mov %eax,-0x20(%ebp) + 800411: 89 55 dc mov %edx,-0x24(%ebp) + 800414: 8b 45 e0 mov -0x20(%ebp),%eax + 800417: 8b 55 f0 mov -0x10(%ebp),%edx + 80041a: 89 45 e8 mov %eax,-0x18(%ebp) + 80041d: 89 55 ec mov %edx,-0x14(%ebp) + 800420: 8b 45 dc mov -0x24(%ebp),%eax + 800423: 89 45 d8 mov %eax,-0x28(%ebp) + + // first recursively print all preceding (more significant) digits + if (num >= base) { + 800426: 8b 45 18 mov 0x18(%ebp),%eax + 800429: ba 00 00 00 00 mov $0x0,%edx + 80042e: 8b 4d d4 mov -0x2c(%ebp),%ecx + 800431: 39 45 d0 cmp %eax,-0x30(%ebp) + 800434: 19 d1 sbb %edx,%ecx + 800436: 72 4c jb 800484 + printnum(putch, putdat, result, base, width - 1, padc); + 800438: 8b 45 1c mov 0x1c(%ebp),%eax + 80043b: 8d 50 ff lea -0x1(%eax),%edx + 80043e: 8b 45 20 mov 0x20(%ebp),%eax + 800441: 89 44 24 18 mov %eax,0x18(%esp) + 800445: 89 54 24 14 mov %edx,0x14(%esp) + 800449: 8b 45 18 mov 0x18(%ebp),%eax + 80044c: 89 44 24 10 mov %eax,0x10(%esp) + 800450: 8b 45 e8 mov -0x18(%ebp),%eax + 800453: 8b 55 ec mov -0x14(%ebp),%edx + 800456: 89 44 24 08 mov %eax,0x8(%esp) + 80045a: 89 54 24 0c mov %edx,0xc(%esp) + 80045e: 8b 45 0c mov 0xc(%ebp),%eax + 800461: 89 44 24 04 mov %eax,0x4(%esp) + 800465: 8b 45 08 mov 0x8(%ebp),%eax + 800468: 89 04 24 mov %eax,(%esp) + 80046b: e8 3d ff ff ff call 8003ad + 800470: eb 1b jmp 80048d + } else { + // print any needed pad characters before first digit + while (-- width > 0) + putch(padc, putdat); + 800472: 8b 45 0c mov 0xc(%ebp),%eax + 800475: 89 44 24 04 mov %eax,0x4(%esp) + 800479: 8b 45 20 mov 0x20(%ebp),%eax + 80047c: 89 04 24 mov %eax,(%esp) + 80047f: 8b 45 08 mov 0x8(%ebp),%eax + 800482: ff d0 call *%eax + while (-- width > 0) + 800484: ff 4d 1c decl 0x1c(%ebp) + 800487: 83 7d 1c 00 cmpl $0x0,0x1c(%ebp) + 80048b: 7f e5 jg 800472 + } + // then print this (the least significant) digit + putch("0123456789abcdef"[mod], putdat); + 80048d: 8b 45 d8 mov -0x28(%ebp),%eax + 800490: 05 44 12 80 00 add $0x801244,%eax + 800495: 0f b6 00 movzbl (%eax),%eax + 800498: 0f be c0 movsbl %al,%eax + 80049b: 8b 55 0c mov 0xc(%ebp),%edx + 80049e: 89 54 24 04 mov %edx,0x4(%esp) + 8004a2: 89 04 24 mov %eax,(%esp) + 8004a5: 8b 45 08 mov 0x8(%ebp),%eax + 8004a8: ff d0 call *%eax +} + 8004aa: 90 nop + 8004ab: 89 ec mov %ebp,%esp + 8004ad: 5d pop %ebp + 8004ae: c3 ret + +008004af : + * getuint - get an unsigned int of various possible sizes from a varargs list + * @ap: a varargs list pointer + * @lflag: determines the size of the vararg that @ap points to + * */ +static unsigned long long +getuint(va_list *ap, int lflag) { + 8004af: 55 push %ebp + 8004b0: 89 e5 mov %esp,%ebp + if (lflag >= 2) { + 8004b2: 83 7d 0c 01 cmpl $0x1,0xc(%ebp) + 8004b6: 7e 14 jle 8004cc + return va_arg(*ap, unsigned long long); + 8004b8: 8b 45 08 mov 0x8(%ebp),%eax + 8004bb: 8b 00 mov (%eax),%eax + 8004bd: 8d 48 08 lea 0x8(%eax),%ecx + 8004c0: 8b 55 08 mov 0x8(%ebp),%edx + 8004c3: 89 0a mov %ecx,(%edx) + 8004c5: 8b 50 04 mov 0x4(%eax),%edx + 8004c8: 8b 00 mov (%eax),%eax + 8004ca: eb 30 jmp 8004fc + } + else if (lflag) { + 8004cc: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) + 8004d0: 74 16 je 8004e8 + return va_arg(*ap, unsigned long); + 8004d2: 8b 45 08 mov 0x8(%ebp),%eax + 8004d5: 8b 00 mov (%eax),%eax + 8004d7: 8d 48 04 lea 0x4(%eax),%ecx + 8004da: 8b 55 08 mov 0x8(%ebp),%edx + 8004dd: 89 0a mov %ecx,(%edx) + 8004df: 8b 00 mov (%eax),%eax + 8004e1: ba 00 00 00 00 mov $0x0,%edx + 8004e6: eb 14 jmp 8004fc + } + else { + return va_arg(*ap, unsigned int); + 8004e8: 8b 45 08 mov 0x8(%ebp),%eax + 8004eb: 8b 00 mov (%eax),%eax + 8004ed: 8d 48 04 lea 0x4(%eax),%ecx + 8004f0: 8b 55 08 mov 0x8(%ebp),%edx + 8004f3: 89 0a mov %ecx,(%edx) + 8004f5: 8b 00 mov (%eax),%eax + 8004f7: ba 00 00 00 00 mov $0x0,%edx + } +} + 8004fc: 5d pop %ebp + 8004fd: c3 ret + +008004fe : + * getint - same as getuint but signed, we can't use getuint because of sign extension + * @ap: a varargs list pointer + * @lflag: determines the size of the vararg that @ap points to + * */ +static long long +getint(va_list *ap, int lflag) { + 8004fe: 55 push %ebp + 8004ff: 89 e5 mov %esp,%ebp + if (lflag >= 2) { + 800501: 83 7d 0c 01 cmpl $0x1,0xc(%ebp) + 800505: 7e 14 jle 80051b + return va_arg(*ap, long long); + 800507: 8b 45 08 mov 0x8(%ebp),%eax + 80050a: 8b 00 mov (%eax),%eax + 80050c: 8d 48 08 lea 0x8(%eax),%ecx + 80050f: 8b 55 08 mov 0x8(%ebp),%edx + 800512: 89 0a mov %ecx,(%edx) + 800514: 8b 50 04 mov 0x4(%eax),%edx + 800517: 8b 00 mov (%eax),%eax + 800519: eb 28 jmp 800543 + } + else if (lflag) { + 80051b: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) + 80051f: 74 12 je 800533 + return va_arg(*ap, long); + 800521: 8b 45 08 mov 0x8(%ebp),%eax + 800524: 8b 00 mov (%eax),%eax + 800526: 8d 48 04 lea 0x4(%eax),%ecx + 800529: 8b 55 08 mov 0x8(%ebp),%edx + 80052c: 89 0a mov %ecx,(%edx) + 80052e: 8b 00 mov (%eax),%eax + 800530: 99 cltd + 800531: eb 10 jmp 800543 + } + else { + return va_arg(*ap, int); + 800533: 8b 45 08 mov 0x8(%ebp),%eax + 800536: 8b 00 mov (%eax),%eax + 800538: 8d 48 04 lea 0x4(%eax),%ecx + 80053b: 8b 55 08 mov 0x8(%ebp),%edx + 80053e: 89 0a mov %ecx,(%edx) + 800540: 8b 00 mov (%eax),%eax + 800542: 99 cltd + } +} + 800543: 5d pop %ebp + 800544: c3 ret + +00800545 : + * @putch: specified putch function, print a single character + * @putdat: used by @putch function + * @fmt: the format string to use + * */ +void +printfmt(void (*putch)(int, void*), void *putdat, const char *fmt, ...) { + 800545: 55 push %ebp + 800546: 89 e5 mov %esp,%ebp + 800548: 83 ec 28 sub $0x28,%esp + va_list ap; + + va_start(ap, fmt); + 80054b: 8d 45 14 lea 0x14(%ebp),%eax + 80054e: 89 45 f4 mov %eax,-0xc(%ebp) + vprintfmt(putch, putdat, fmt, ap); + 800551: 8b 45 f4 mov -0xc(%ebp),%eax + 800554: 89 44 24 0c mov %eax,0xc(%esp) + 800558: 8b 45 10 mov 0x10(%ebp),%eax + 80055b: 89 44 24 08 mov %eax,0x8(%esp) + 80055f: 8b 45 0c mov 0xc(%ebp),%eax + 800562: 89 44 24 04 mov %eax,0x4(%esp) + 800566: 8b 45 08 mov 0x8(%ebp),%eax + 800569: 89 04 24 mov %eax,(%esp) + 80056c: e8 05 00 00 00 call 800576 + va_end(ap); +} + 800571: 90 nop + 800572: 89 ec mov %ebp,%esp + 800574: 5d pop %ebp + 800575: c3 ret + +00800576 : + * + * Call this function if you are already dealing with a va_list. + * Or you probably want printfmt() instead. + * */ +void +vprintfmt(void (*putch)(int, void*), void *putdat, const char *fmt, va_list ap) { + 800576: 55 push %ebp + 800577: 89 e5 mov %esp,%ebp + 800579: 56 push %esi + 80057a: 53 push %ebx + 80057b: 83 ec 40 sub $0x40,%esp + register int ch, err; + unsigned long long num; + int base, width, precision, lflag, altflag; + + while (1) { + while ((ch = *(unsigned char *)fmt ++) != '%') { + 80057e: eb 17 jmp 800597 + if (ch == '\0') { + 800580: 85 db test %ebx,%ebx + 800582: 0f 84 bf 03 00 00 je 800947 + return; + } + putch(ch, putdat); + 800588: 8b 45 0c mov 0xc(%ebp),%eax + 80058b: 89 44 24 04 mov %eax,0x4(%esp) + 80058f: 89 1c 24 mov %ebx,(%esp) + 800592: 8b 45 08 mov 0x8(%ebp),%eax + 800595: ff d0 call *%eax + while ((ch = *(unsigned char *)fmt ++) != '%') { + 800597: 8b 45 10 mov 0x10(%ebp),%eax + 80059a: 8d 50 01 lea 0x1(%eax),%edx + 80059d: 89 55 10 mov %edx,0x10(%ebp) + 8005a0: 0f b6 00 movzbl (%eax),%eax + 8005a3: 0f b6 d8 movzbl %al,%ebx + 8005a6: 83 fb 25 cmp $0x25,%ebx + 8005a9: 75 d5 jne 800580 + } + + // Process a %-escape sequence + char padc = ' '; + 8005ab: c6 45 db 20 movb $0x20,-0x25(%ebp) + width = precision = -1; + 8005af: c7 45 e4 ff ff ff ff movl $0xffffffff,-0x1c(%ebp) + 8005b6: 8b 45 e4 mov -0x1c(%ebp),%eax + 8005b9: 89 45 e8 mov %eax,-0x18(%ebp) + lflag = altflag = 0; + 8005bc: c7 45 dc 00 00 00 00 movl $0x0,-0x24(%ebp) + 8005c3: 8b 45 dc mov -0x24(%ebp),%eax + 8005c6: 89 45 e0 mov %eax,-0x20(%ebp) + + reswitch: + switch (ch = *(unsigned char *)fmt ++) { + 8005c9: 8b 45 10 mov 0x10(%ebp),%eax + 8005cc: 8d 50 01 lea 0x1(%eax),%edx + 8005cf: 89 55 10 mov %edx,0x10(%ebp) + 8005d2: 0f b6 00 movzbl (%eax),%eax + 8005d5: 0f b6 d8 movzbl %al,%ebx + 8005d8: 8d 43 dd lea -0x23(%ebx),%eax + 8005db: 83 f8 55 cmp $0x55,%eax + 8005de: 0f 87 37 03 00 00 ja 80091b + 8005e4: 8b 04 85 68 12 80 00 mov 0x801268(,%eax,4),%eax + 8005eb: ff e0 jmp *%eax + + // flag to pad on the right + case '-': + padc = '-'; + 8005ed: c6 45 db 2d movb $0x2d,-0x25(%ebp) + goto reswitch; + 8005f1: eb d6 jmp 8005c9 + + // flag to pad with 0's instead of spaces + case '0': + padc = '0'; + 8005f3: c6 45 db 30 movb $0x30,-0x25(%ebp) + goto reswitch; + 8005f7: eb d0 jmp 8005c9 + + // width field + case '1' ... '9': + for (precision = 0; ; ++ fmt) { + 8005f9: c7 45 e4 00 00 00 00 movl $0x0,-0x1c(%ebp) + precision = precision * 10 + ch - '0'; + 800600: 8b 55 e4 mov -0x1c(%ebp),%edx + 800603: 89 d0 mov %edx,%eax + 800605: c1 e0 02 shl $0x2,%eax + 800608: 01 d0 add %edx,%eax + 80060a: 01 c0 add %eax,%eax + 80060c: 01 d8 add %ebx,%eax + 80060e: 83 e8 30 sub $0x30,%eax + 800611: 89 45 e4 mov %eax,-0x1c(%ebp) + ch = *fmt; + 800614: 8b 45 10 mov 0x10(%ebp),%eax + 800617: 0f b6 00 movzbl (%eax),%eax + 80061a: 0f be d8 movsbl %al,%ebx + if (ch < '0' || ch > '9') { + 80061d: 83 fb 2f cmp $0x2f,%ebx + 800620: 7e 38 jle 80065a + 800622: 83 fb 39 cmp $0x39,%ebx + 800625: 7f 33 jg 80065a + for (precision = 0; ; ++ fmt) { + 800627: ff 45 10 incl 0x10(%ebp) + precision = precision * 10 + ch - '0'; + 80062a: eb d4 jmp 800600 + } + } + goto process_precision; + + case '*': + precision = va_arg(ap, int); + 80062c: 8b 45 14 mov 0x14(%ebp),%eax + 80062f: 8d 50 04 lea 0x4(%eax),%edx + 800632: 89 55 14 mov %edx,0x14(%ebp) + 800635: 8b 00 mov (%eax),%eax + 800637: 89 45 e4 mov %eax,-0x1c(%ebp) + goto process_precision; + 80063a: eb 1f jmp 80065b + + case '.': + if (width < 0) + 80063c: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 800640: 79 87 jns 8005c9 + width = 0; + 800642: c7 45 e8 00 00 00 00 movl $0x0,-0x18(%ebp) + goto reswitch; + 800649: e9 7b ff ff ff jmp 8005c9 + + case '#': + altflag = 1; + 80064e: c7 45 dc 01 00 00 00 movl $0x1,-0x24(%ebp) + goto reswitch; + 800655: e9 6f ff ff ff jmp 8005c9 + goto process_precision; + 80065a: 90 nop + + process_precision: + if (width < 0) + 80065b: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 80065f: 0f 89 64 ff ff ff jns 8005c9 + width = precision, precision = -1; + 800665: 8b 45 e4 mov -0x1c(%ebp),%eax + 800668: 89 45 e8 mov %eax,-0x18(%ebp) + 80066b: c7 45 e4 ff ff ff ff movl $0xffffffff,-0x1c(%ebp) + goto reswitch; + 800672: e9 52 ff ff ff jmp 8005c9 + + // long flag (doubled for long long) + case 'l': + lflag ++; + 800677: ff 45 e0 incl -0x20(%ebp) + goto reswitch; + 80067a: e9 4a ff ff ff jmp 8005c9 + + // character + case 'c': + putch(va_arg(ap, int), putdat); + 80067f: 8b 45 14 mov 0x14(%ebp),%eax + 800682: 8d 50 04 lea 0x4(%eax),%edx + 800685: 89 55 14 mov %edx,0x14(%ebp) + 800688: 8b 00 mov (%eax),%eax + 80068a: 8b 55 0c mov 0xc(%ebp),%edx + 80068d: 89 54 24 04 mov %edx,0x4(%esp) + 800691: 89 04 24 mov %eax,(%esp) + 800694: 8b 45 08 mov 0x8(%ebp),%eax + 800697: ff d0 call *%eax + break; + 800699: e9 a4 02 00 00 jmp 800942 + + // error message + case 'e': + err = va_arg(ap, int); + 80069e: 8b 45 14 mov 0x14(%ebp),%eax + 8006a1: 8d 50 04 lea 0x4(%eax),%edx + 8006a4: 89 55 14 mov %edx,0x14(%ebp) + 8006a7: 8b 18 mov (%eax),%ebx + if (err < 0) { + 8006a9: 85 db test %ebx,%ebx + 8006ab: 79 02 jns 8006af + err = -err; + 8006ad: f7 db neg %ebx + } + if (err > MAXERROR || (p = error_string[err]) == NULL) { + 8006af: 83 fb 18 cmp $0x18,%ebx + 8006b2: 7f 0b jg 8006bf + 8006b4: 8b 34 9d e0 11 80 00 mov 0x8011e0(,%ebx,4),%esi + 8006bb: 85 f6 test %esi,%esi + 8006bd: 75 23 jne 8006e2 + printfmt(putch, putdat, "error %d", err); + 8006bf: 89 5c 24 0c mov %ebx,0xc(%esp) + 8006c3: c7 44 24 08 55 12 80 movl $0x801255,0x8(%esp) + 8006ca: 00 + 8006cb: 8b 45 0c mov 0xc(%ebp),%eax + 8006ce: 89 44 24 04 mov %eax,0x4(%esp) + 8006d2: 8b 45 08 mov 0x8(%ebp),%eax + 8006d5: 89 04 24 mov %eax,(%esp) + 8006d8: e8 68 fe ff ff call 800545 + } + else { + printfmt(putch, putdat, "%s", p); + } + break; + 8006dd: e9 60 02 00 00 jmp 800942 + printfmt(putch, putdat, "%s", p); + 8006e2: 89 74 24 0c mov %esi,0xc(%esp) + 8006e6: c7 44 24 08 5e 12 80 movl $0x80125e,0x8(%esp) + 8006ed: 00 + 8006ee: 8b 45 0c mov 0xc(%ebp),%eax + 8006f1: 89 44 24 04 mov %eax,0x4(%esp) + 8006f5: 8b 45 08 mov 0x8(%ebp),%eax + 8006f8: 89 04 24 mov %eax,(%esp) + 8006fb: e8 45 fe ff ff call 800545 + break; + 800700: e9 3d 02 00 00 jmp 800942 + + // string + case 's': + if ((p = va_arg(ap, char *)) == NULL) { + 800705: 8b 45 14 mov 0x14(%ebp),%eax + 800708: 8d 50 04 lea 0x4(%eax),%edx + 80070b: 89 55 14 mov %edx,0x14(%ebp) + 80070e: 8b 30 mov (%eax),%esi + 800710: 85 f6 test %esi,%esi + 800712: 75 05 jne 800719 + p = "(null)"; + 800714: be 61 12 80 00 mov $0x801261,%esi + } + if (width > 0 && padc != '-') { + 800719: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 80071d: 7e 76 jle 800795 + 80071f: 80 7d db 2d cmpb $0x2d,-0x25(%ebp) + 800723: 74 70 je 800795 + for (width -= strnlen(p, precision); width > 0; width --) { + 800725: 8b 45 e4 mov -0x1c(%ebp),%eax + 800728: 89 44 24 04 mov %eax,0x4(%esp) + 80072c: 89 34 24 mov %esi,(%esp) + 80072f: e8 ee 03 00 00 call 800b22 + 800734: 89 c2 mov %eax,%edx + 800736: 8b 45 e8 mov -0x18(%ebp),%eax + 800739: 29 d0 sub %edx,%eax + 80073b: 89 45 e8 mov %eax,-0x18(%ebp) + 80073e: eb 16 jmp 800756 + putch(padc, putdat); + 800740: 0f be 45 db movsbl -0x25(%ebp),%eax + 800744: 8b 55 0c mov 0xc(%ebp),%edx + 800747: 89 54 24 04 mov %edx,0x4(%esp) + 80074b: 89 04 24 mov %eax,(%esp) + 80074e: 8b 45 08 mov 0x8(%ebp),%eax + 800751: ff d0 call *%eax + for (width -= strnlen(p, precision); width > 0; width --) { + 800753: ff 4d e8 decl -0x18(%ebp) + 800756: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 80075a: 7f e4 jg 800740 + } + } + for (; (ch = *p ++) != '\0' && (precision < 0 || -- precision >= 0); width --) { + 80075c: eb 37 jmp 800795 + if (altflag && (ch < ' ' || ch > '~')) { + 80075e: 83 7d dc 00 cmpl $0x0,-0x24(%ebp) + 800762: 74 1f je 800783 + 800764: 83 fb 1f cmp $0x1f,%ebx + 800767: 7e 05 jle 80076e + 800769: 83 fb 7e cmp $0x7e,%ebx + 80076c: 7e 15 jle 800783 + putch('?', putdat); + 80076e: 8b 45 0c mov 0xc(%ebp),%eax + 800771: 89 44 24 04 mov %eax,0x4(%esp) + 800775: c7 04 24 3f 00 00 00 movl $0x3f,(%esp) + 80077c: 8b 45 08 mov 0x8(%ebp),%eax + 80077f: ff d0 call *%eax + 800781: eb 0f jmp 800792 + } + else { + putch(ch, putdat); + 800783: 8b 45 0c mov 0xc(%ebp),%eax + 800786: 89 44 24 04 mov %eax,0x4(%esp) + 80078a: 89 1c 24 mov %ebx,(%esp) + 80078d: 8b 45 08 mov 0x8(%ebp),%eax + 800790: ff d0 call *%eax + for (; (ch = *p ++) != '\0' && (precision < 0 || -- precision >= 0); width --) { + 800792: ff 4d e8 decl -0x18(%ebp) + 800795: 89 f0 mov %esi,%eax + 800797: 8d 70 01 lea 0x1(%eax),%esi + 80079a: 0f b6 00 movzbl (%eax),%eax + 80079d: 0f be d8 movsbl %al,%ebx + 8007a0: 85 db test %ebx,%ebx + 8007a2: 74 27 je 8007cb + 8007a4: 83 7d e4 00 cmpl $0x0,-0x1c(%ebp) + 8007a8: 78 b4 js 80075e + 8007aa: ff 4d e4 decl -0x1c(%ebp) + 8007ad: 83 7d e4 00 cmpl $0x0,-0x1c(%ebp) + 8007b1: 79 ab jns 80075e + } + } + for (; width > 0; width --) { + 8007b3: eb 16 jmp 8007cb + putch(' ', putdat); + 8007b5: 8b 45 0c mov 0xc(%ebp),%eax + 8007b8: 89 44 24 04 mov %eax,0x4(%esp) + 8007bc: c7 04 24 20 00 00 00 movl $0x20,(%esp) + 8007c3: 8b 45 08 mov 0x8(%ebp),%eax + 8007c6: ff d0 call *%eax + for (; width > 0; width --) { + 8007c8: ff 4d e8 decl -0x18(%ebp) + 8007cb: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 8007cf: 7f e4 jg 8007b5 + } + break; + 8007d1: e9 6c 01 00 00 jmp 800942 + + // (signed) decimal + case 'd': + num = getint(&ap, lflag); + 8007d6: 8b 45 e0 mov -0x20(%ebp),%eax + 8007d9: 89 44 24 04 mov %eax,0x4(%esp) + 8007dd: 8d 45 14 lea 0x14(%ebp),%eax + 8007e0: 89 04 24 mov %eax,(%esp) + 8007e3: e8 16 fd ff ff call 8004fe + 8007e8: 89 45 f0 mov %eax,-0x10(%ebp) + 8007eb: 89 55 f4 mov %edx,-0xc(%ebp) + if ((long long)num < 0) { + 8007ee: 8b 45 f0 mov -0x10(%ebp),%eax + 8007f1: 8b 55 f4 mov -0xc(%ebp),%edx + 8007f4: 85 d2 test %edx,%edx + 8007f6: 79 26 jns 80081e + putch('-', putdat); + 8007f8: 8b 45 0c mov 0xc(%ebp),%eax + 8007fb: 89 44 24 04 mov %eax,0x4(%esp) + 8007ff: c7 04 24 2d 00 00 00 movl $0x2d,(%esp) + 800806: 8b 45 08 mov 0x8(%ebp),%eax + 800809: ff d0 call *%eax + num = -(long long)num; + 80080b: 8b 45 f0 mov -0x10(%ebp),%eax + 80080e: 8b 55 f4 mov -0xc(%ebp),%edx + 800811: f7 d8 neg %eax + 800813: 83 d2 00 adc $0x0,%edx + 800816: f7 da neg %edx + 800818: 89 45 f0 mov %eax,-0x10(%ebp) + 80081b: 89 55 f4 mov %edx,-0xc(%ebp) + } + base = 10; + 80081e: c7 45 ec 0a 00 00 00 movl $0xa,-0x14(%ebp) + goto number; + 800825: e9 a8 00 00 00 jmp 8008d2 + + // unsigned decimal + case 'u': + num = getuint(&ap, lflag); + 80082a: 8b 45 e0 mov -0x20(%ebp),%eax + 80082d: 89 44 24 04 mov %eax,0x4(%esp) + 800831: 8d 45 14 lea 0x14(%ebp),%eax + 800834: 89 04 24 mov %eax,(%esp) + 800837: e8 73 fc ff ff call 8004af + 80083c: 89 45 f0 mov %eax,-0x10(%ebp) + 80083f: 89 55 f4 mov %edx,-0xc(%ebp) + base = 10; + 800842: c7 45 ec 0a 00 00 00 movl $0xa,-0x14(%ebp) + goto number; + 800849: e9 84 00 00 00 jmp 8008d2 + + // (unsigned) octal + case 'o': + num = getuint(&ap, lflag); + 80084e: 8b 45 e0 mov -0x20(%ebp),%eax + 800851: 89 44 24 04 mov %eax,0x4(%esp) + 800855: 8d 45 14 lea 0x14(%ebp),%eax + 800858: 89 04 24 mov %eax,(%esp) + 80085b: e8 4f fc ff ff call 8004af + 800860: 89 45 f0 mov %eax,-0x10(%ebp) + 800863: 89 55 f4 mov %edx,-0xc(%ebp) + base = 8; + 800866: c7 45 ec 08 00 00 00 movl $0x8,-0x14(%ebp) + goto number; + 80086d: eb 63 jmp 8008d2 + + // pointer + case 'p': + putch('0', putdat); + 80086f: 8b 45 0c mov 0xc(%ebp),%eax + 800872: 89 44 24 04 mov %eax,0x4(%esp) + 800876: c7 04 24 30 00 00 00 movl $0x30,(%esp) + 80087d: 8b 45 08 mov 0x8(%ebp),%eax + 800880: ff d0 call *%eax + putch('x', putdat); + 800882: 8b 45 0c mov 0xc(%ebp),%eax + 800885: 89 44 24 04 mov %eax,0x4(%esp) + 800889: c7 04 24 78 00 00 00 movl $0x78,(%esp) + 800890: 8b 45 08 mov 0x8(%ebp),%eax + 800893: ff d0 call *%eax + num = (unsigned long long)(uintptr_t)va_arg(ap, void *); + 800895: 8b 45 14 mov 0x14(%ebp),%eax + 800898: 8d 50 04 lea 0x4(%eax),%edx + 80089b: 89 55 14 mov %edx,0x14(%ebp) + 80089e: 8b 00 mov (%eax),%eax + 8008a0: 89 45 f0 mov %eax,-0x10(%ebp) + 8008a3: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + base = 16; + 8008aa: c7 45 ec 10 00 00 00 movl $0x10,-0x14(%ebp) + goto number; + 8008b1: eb 1f jmp 8008d2 + + // (unsigned) hexadecimal + case 'x': + num = getuint(&ap, lflag); + 8008b3: 8b 45 e0 mov -0x20(%ebp),%eax + 8008b6: 89 44 24 04 mov %eax,0x4(%esp) + 8008ba: 8d 45 14 lea 0x14(%ebp),%eax + 8008bd: 89 04 24 mov %eax,(%esp) + 8008c0: e8 ea fb ff ff call 8004af + 8008c5: 89 45 f0 mov %eax,-0x10(%ebp) + 8008c8: 89 55 f4 mov %edx,-0xc(%ebp) + base = 16; + 8008cb: c7 45 ec 10 00 00 00 movl $0x10,-0x14(%ebp) + number: + printnum(putch, putdat, num, base, width, padc); + 8008d2: 0f be 55 db movsbl -0x25(%ebp),%edx + 8008d6: 8b 45 ec mov -0x14(%ebp),%eax + 8008d9: 89 54 24 18 mov %edx,0x18(%esp) + 8008dd: 8b 55 e8 mov -0x18(%ebp),%edx + 8008e0: 89 54 24 14 mov %edx,0x14(%esp) + 8008e4: 89 44 24 10 mov %eax,0x10(%esp) + 8008e8: 8b 45 f0 mov -0x10(%ebp),%eax + 8008eb: 8b 55 f4 mov -0xc(%ebp),%edx + 8008ee: 89 44 24 08 mov %eax,0x8(%esp) + 8008f2: 89 54 24 0c mov %edx,0xc(%esp) + 8008f6: 8b 45 0c mov 0xc(%ebp),%eax + 8008f9: 89 44 24 04 mov %eax,0x4(%esp) + 8008fd: 8b 45 08 mov 0x8(%ebp),%eax + 800900: 89 04 24 mov %eax,(%esp) + 800903: e8 a5 fa ff ff call 8003ad + break; + 800908: eb 38 jmp 800942 + + // escaped '%' character + case '%': + putch(ch, putdat); + 80090a: 8b 45 0c mov 0xc(%ebp),%eax + 80090d: 89 44 24 04 mov %eax,0x4(%esp) + 800911: 89 1c 24 mov %ebx,(%esp) + 800914: 8b 45 08 mov 0x8(%ebp),%eax + 800917: ff d0 call *%eax + break; + 800919: eb 27 jmp 800942 + + // unrecognized escape sequence - just print it literally + default: + putch('%', putdat); + 80091b: 8b 45 0c mov 0xc(%ebp),%eax + 80091e: 89 44 24 04 mov %eax,0x4(%esp) + 800922: c7 04 24 25 00 00 00 movl $0x25,(%esp) + 800929: 8b 45 08 mov 0x8(%ebp),%eax + 80092c: ff d0 call *%eax + for (fmt --; fmt[-1] != '%'; fmt --) + 80092e: ff 4d 10 decl 0x10(%ebp) + 800931: eb 03 jmp 800936 + 800933: ff 4d 10 decl 0x10(%ebp) + 800936: 8b 45 10 mov 0x10(%ebp),%eax + 800939: 48 dec %eax + 80093a: 0f b6 00 movzbl (%eax),%eax + 80093d: 3c 25 cmp $0x25,%al + 80093f: 75 f2 jne 800933 + /* do nothing */; + break; + 800941: 90 nop + while (1) { + 800942: e9 37 fc ff ff jmp 80057e + return; + 800947: 90 nop + } + } +} + 800948: 83 c4 40 add $0x40,%esp + 80094b: 5b pop %ebx + 80094c: 5e pop %esi + 80094d: 5d pop %ebp + 80094e: c3 ret + +0080094f : + * sprintputch - 'print' a single character in a buffer + * @ch: the character will be printed + * @b: the buffer to place the character @ch + * */ +static void +sprintputch(int ch, struct sprintbuf *b) { + 80094f: 55 push %ebp + 800950: 89 e5 mov %esp,%ebp + b->cnt ++; + 800952: 8b 45 0c mov 0xc(%ebp),%eax + 800955: 8b 40 08 mov 0x8(%eax),%eax + 800958: 8d 50 01 lea 0x1(%eax),%edx + 80095b: 8b 45 0c mov 0xc(%ebp),%eax + 80095e: 89 50 08 mov %edx,0x8(%eax) + if (b->buf < b->ebuf) { + 800961: 8b 45 0c mov 0xc(%ebp),%eax + 800964: 8b 10 mov (%eax),%edx + 800966: 8b 45 0c mov 0xc(%ebp),%eax + 800969: 8b 40 04 mov 0x4(%eax),%eax + 80096c: 39 c2 cmp %eax,%edx + 80096e: 73 12 jae 800982 + *b->buf ++ = ch; + 800970: 8b 45 0c mov 0xc(%ebp),%eax + 800973: 8b 00 mov (%eax),%eax + 800975: 8d 48 01 lea 0x1(%eax),%ecx + 800978: 8b 55 0c mov 0xc(%ebp),%edx + 80097b: 89 0a mov %ecx,(%edx) + 80097d: 8b 55 08 mov 0x8(%ebp),%edx + 800980: 88 10 mov %dl,(%eax) + } +} + 800982: 90 nop + 800983: 5d pop %ebp + 800984: c3 ret + +00800985 : + * @str: the buffer to place the result into + * @size: the size of buffer, including the trailing null space + * @fmt: the format string to use + * */ +int +snprintf(char *str, size_t size, const char *fmt, ...) { + 800985: 55 push %ebp + 800986: 89 e5 mov %esp,%ebp + 800988: 83 ec 28 sub $0x28,%esp + va_list ap; + int cnt; + va_start(ap, fmt); + 80098b: 8d 45 14 lea 0x14(%ebp),%eax + 80098e: 89 45 f0 mov %eax,-0x10(%ebp) + cnt = vsnprintf(str, size, fmt, ap); + 800991: 8b 45 f0 mov -0x10(%ebp),%eax + 800994: 89 44 24 0c mov %eax,0xc(%esp) + 800998: 8b 45 10 mov 0x10(%ebp),%eax + 80099b: 89 44 24 08 mov %eax,0x8(%esp) + 80099f: 8b 45 0c mov 0xc(%ebp),%eax + 8009a2: 89 44 24 04 mov %eax,0x4(%esp) + 8009a6: 8b 45 08 mov 0x8(%ebp),%eax + 8009a9: 89 04 24 mov %eax,(%esp) + 8009ac: e8 0a 00 00 00 call 8009bb + 8009b1: 89 45 f4 mov %eax,-0xc(%ebp) + va_end(ap); + return cnt; + 8009b4: 8b 45 f4 mov -0xc(%ebp),%eax +} + 8009b7: 89 ec mov %ebp,%esp + 8009b9: 5d pop %ebp + 8009ba: c3 ret + +008009bb : + * + * Call this function if you are already dealing with a va_list. + * Or you probably want snprintf() instead. + * */ +int +vsnprintf(char *str, size_t size, const char *fmt, va_list ap) { + 8009bb: 55 push %ebp + 8009bc: 89 e5 mov %esp,%ebp + 8009be: 83 ec 28 sub $0x28,%esp + struct sprintbuf b = {str, str + size - 1, 0}; + 8009c1: 8b 45 08 mov 0x8(%ebp),%eax + 8009c4: 89 45 ec mov %eax,-0x14(%ebp) + 8009c7: 8b 45 0c mov 0xc(%ebp),%eax + 8009ca: 8d 50 ff lea -0x1(%eax),%edx + 8009cd: 8b 45 08 mov 0x8(%ebp),%eax + 8009d0: 01 d0 add %edx,%eax + 8009d2: 89 45 f0 mov %eax,-0x10(%ebp) + 8009d5: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + if (str == NULL || b.buf > b.ebuf) { + 8009dc: 83 7d 08 00 cmpl $0x0,0x8(%ebp) + 8009e0: 74 0a je 8009ec + 8009e2: 8b 55 ec mov -0x14(%ebp),%edx + 8009e5: 8b 45 f0 mov -0x10(%ebp),%eax + 8009e8: 39 c2 cmp %eax,%edx + 8009ea: 76 07 jbe 8009f3 + return -E_INVAL; + 8009ec: b8 fd ff ff ff mov $0xfffffffd,%eax + 8009f1: eb 2a jmp 800a1d + } + // print the string to the buffer + vprintfmt((void*)sprintputch, &b, fmt, ap); + 8009f3: 8b 45 14 mov 0x14(%ebp),%eax + 8009f6: 89 44 24 0c mov %eax,0xc(%esp) + 8009fa: 8b 45 10 mov 0x10(%ebp),%eax + 8009fd: 89 44 24 08 mov %eax,0x8(%esp) + 800a01: 8d 45 ec lea -0x14(%ebp),%eax + 800a04: 89 44 24 04 mov %eax,0x4(%esp) + 800a08: c7 04 24 4f 09 80 00 movl $0x80094f,(%esp) + 800a0f: e8 62 fb ff ff call 800576 + // null terminate the buffer + *b.buf = '\0'; + 800a14: 8b 45 ec mov -0x14(%ebp),%eax + 800a17: c6 00 00 movb $0x0,(%eax) + return b.cnt; + 800a1a: 8b 45 f4 mov -0xc(%ebp),%eax +} + 800a1d: 89 ec mov %ebp,%esp + 800a1f: 5d pop %ebp + 800a20: c3 ret + +00800a21 : + * rand - returns a pseudo-random integer + * + * The rand() function return a value in the range [0, RAND_MAX]. + * */ +int +rand(void) { + 800a21: 55 push %ebp + 800a22: 89 e5 mov %esp,%ebp + 800a24: 57 push %edi + 800a25: 56 push %esi + 800a26: 53 push %ebx + 800a27: 83 ec 24 sub $0x24,%esp + next = (next * 0x5DEECE66DLL + 0xBLL) & ((1LL << 48) - 1); + 800a2a: a1 00 20 80 00 mov 0x802000,%eax + 800a2f: 8b 15 04 20 80 00 mov 0x802004,%edx + 800a35: 69 fa 6d e6 ec de imul $0xdeece66d,%edx,%edi + 800a3b: 6b f0 05 imul $0x5,%eax,%esi + 800a3e: 01 fe add %edi,%esi + 800a40: bf 6d e6 ec de mov $0xdeece66d,%edi + 800a45: f7 e7 mul %edi + 800a47: 01 d6 add %edx,%esi + 800a49: 89 f2 mov %esi,%edx + 800a4b: 83 c0 0b add $0xb,%eax + 800a4e: 83 d2 00 adc $0x0,%edx + 800a51: 89 c7 mov %eax,%edi + 800a53: 83 e7 ff and $0xffffffff,%edi + 800a56: 89 f9 mov %edi,%ecx + 800a58: 0f b7 da movzwl %dx,%ebx + 800a5b: 89 0d 00 20 80 00 mov %ecx,0x802000 + 800a61: 89 1d 04 20 80 00 mov %ebx,0x802004 + unsigned long long result = (next >> 12); + 800a67: a1 00 20 80 00 mov 0x802000,%eax + 800a6c: 8b 15 04 20 80 00 mov 0x802004,%edx + 800a72: 0f ac d0 0c shrd $0xc,%edx,%eax + 800a76: c1 ea 0c shr $0xc,%edx + 800a79: 89 45 e0 mov %eax,-0x20(%ebp) + 800a7c: 89 55 e4 mov %edx,-0x1c(%ebp) + return (int)do_div(result, RAND_MAX + 1); + 800a7f: c7 45 dc 00 00 00 80 movl $0x80000000,-0x24(%ebp) + 800a86: 8b 45 e0 mov -0x20(%ebp),%eax + 800a89: 8b 55 e4 mov -0x1c(%ebp),%edx + 800a8c: 89 45 d8 mov %eax,-0x28(%ebp) + 800a8f: 89 55 e8 mov %edx,-0x18(%ebp) + 800a92: 8b 45 e8 mov -0x18(%ebp),%eax + 800a95: 89 45 ec mov %eax,-0x14(%ebp) + 800a98: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 800a9c: 74 1c je 800aba + 800a9e: 8b 45 e8 mov -0x18(%ebp),%eax + 800aa1: ba 00 00 00 00 mov $0x0,%edx + 800aa6: f7 75 dc divl -0x24(%ebp) + 800aa9: 89 55 ec mov %edx,-0x14(%ebp) + 800aac: 8b 45 e8 mov -0x18(%ebp),%eax + 800aaf: ba 00 00 00 00 mov $0x0,%edx + 800ab4: f7 75 dc divl -0x24(%ebp) + 800ab7: 89 45 e8 mov %eax,-0x18(%ebp) + 800aba: 8b 45 d8 mov -0x28(%ebp),%eax + 800abd: 8b 55 ec mov -0x14(%ebp),%edx + 800ac0: f7 75 dc divl -0x24(%ebp) + 800ac3: 89 45 d8 mov %eax,-0x28(%ebp) + 800ac6: 89 55 d4 mov %edx,-0x2c(%ebp) + 800ac9: 8b 45 d8 mov -0x28(%ebp),%eax + 800acc: 8b 55 e8 mov -0x18(%ebp),%edx + 800acf: 89 45 e0 mov %eax,-0x20(%ebp) + 800ad2: 89 55 e4 mov %edx,-0x1c(%ebp) + 800ad5: 8b 45 d4 mov -0x2c(%ebp),%eax +} + 800ad8: 83 c4 24 add $0x24,%esp + 800adb: 5b pop %ebx + 800adc: 5e pop %esi + 800add: 5f pop %edi + 800ade: 5d pop %ebp + 800adf: c3 ret + +00800ae0 : +/* * + * srand - seed the random number generator with the given number + * @seed: the required seed number + * */ +void +srand(unsigned int seed) { + 800ae0: 55 push %ebp + 800ae1: 89 e5 mov %esp,%ebp + next = seed; + 800ae3: 8b 45 08 mov 0x8(%ebp),%eax + 800ae6: ba 00 00 00 00 mov $0x0,%edx + 800aeb: a3 00 20 80 00 mov %eax,0x802000 + 800af0: 89 15 04 20 80 00 mov %edx,0x802004 +} + 800af6: 90 nop + 800af7: 5d pop %ebp + 800af8: c3 ret + +00800af9 : + * @s: the input string + * + * The strlen() function returns the length of string @s. + * */ +size_t +strlen(const char *s) { + 800af9: 55 push %ebp + 800afa: 89 e5 mov %esp,%ebp + 800afc: 83 ec 10 sub $0x10,%esp + size_t cnt = 0; + 800aff: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + while (*s ++ != '\0') { + 800b06: eb 03 jmp 800b0b + cnt ++; + 800b08: ff 45 fc incl -0x4(%ebp) + while (*s ++ != '\0') { + 800b0b: 8b 45 08 mov 0x8(%ebp),%eax + 800b0e: 8d 50 01 lea 0x1(%eax),%edx + 800b11: 89 55 08 mov %edx,0x8(%ebp) + 800b14: 0f b6 00 movzbl (%eax),%eax + 800b17: 84 c0 test %al,%al + 800b19: 75 ed jne 800b08 + } + return cnt; + 800b1b: 8b 45 fc mov -0x4(%ebp),%eax +} + 800b1e: 89 ec mov %ebp,%esp + 800b20: 5d pop %ebp + 800b21: c3 ret + +00800b22 : + * The return value is strlen(s), if that is less than @len, or + * @len if there is no '\0' character among the first @len characters + * pointed by @s. + * */ +size_t +strnlen(const char *s, size_t len) { + 800b22: 55 push %ebp + 800b23: 89 e5 mov %esp,%ebp + 800b25: 83 ec 10 sub $0x10,%esp + size_t cnt = 0; + 800b28: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + while (cnt < len && *s ++ != '\0') { + 800b2f: eb 03 jmp 800b34 + cnt ++; + 800b31: ff 45 fc incl -0x4(%ebp) + while (cnt < len && *s ++ != '\0') { + 800b34: 8b 45 fc mov -0x4(%ebp),%eax + 800b37: 3b 45 0c cmp 0xc(%ebp),%eax + 800b3a: 73 10 jae 800b4c + 800b3c: 8b 45 08 mov 0x8(%ebp),%eax + 800b3f: 8d 50 01 lea 0x1(%eax),%edx + 800b42: 89 55 08 mov %edx,0x8(%ebp) + 800b45: 0f b6 00 movzbl (%eax),%eax + 800b48: 84 c0 test %al,%al + 800b4a: 75 e5 jne 800b31 + } + return cnt; + 800b4c: 8b 45 fc mov -0x4(%ebp),%eax +} + 800b4f: 89 ec mov %ebp,%esp + 800b51: 5d pop %ebp + 800b52: c3 ret + +00800b53 : + * To avoid overflows, the size of array pointed by @dst should be long enough to + * contain the same string as @src (including the terminating null character), and + * should not overlap in memory with @src. + * */ +char * +strcpy(char *dst, const char *src) { + 800b53: 55 push %ebp + 800b54: 89 e5 mov %esp,%ebp + 800b56: 57 push %edi + 800b57: 56 push %esi + 800b58: 83 ec 20 sub $0x20,%esp + 800b5b: 8b 45 08 mov 0x8(%ebp),%eax + 800b5e: 89 45 f4 mov %eax,-0xc(%ebp) + 800b61: 8b 45 0c mov 0xc(%ebp),%eax + 800b64: 89 45 f0 mov %eax,-0x10(%ebp) +#ifndef __HAVE_ARCH_STRCPY +#define __HAVE_ARCH_STRCPY +static inline char * +__strcpy(char *dst, const char *src) { + int d0, d1, d2; + asm volatile ( + 800b67: 8b 55 f0 mov -0x10(%ebp),%edx + 800b6a: 8b 45 f4 mov -0xc(%ebp),%eax + 800b6d: 89 d1 mov %edx,%ecx + 800b6f: 89 c2 mov %eax,%edx + 800b71: 89 ce mov %ecx,%esi + 800b73: 89 d7 mov %edx,%edi + 800b75: ac lods %ds:(%esi),%al + 800b76: aa stos %al,%es:(%edi) + 800b77: 84 c0 test %al,%al + 800b79: 75 fa jne 800b75 + 800b7b: 89 fa mov %edi,%edx + 800b7d: 89 f1 mov %esi,%ecx + 800b7f: 89 4d ec mov %ecx,-0x14(%ebp) + 800b82: 89 55 e8 mov %edx,-0x18(%ebp) + 800b85: 89 45 e4 mov %eax,-0x1c(%ebp) + "stosb;" + "testb %%al, %%al;" + "jne 1b;" + : "=&S" (d0), "=&D" (d1), "=&a" (d2) + : "0" (src), "1" (dst) : "memory"); + return dst; + 800b88: 8b 45 f4 mov -0xc(%ebp),%eax + char *p = dst; + while ((*p ++ = *src ++) != '\0') + /* nothing */; + return dst; +#endif /* __HAVE_ARCH_STRCPY */ +} + 800b8b: 83 c4 20 add $0x20,%esp + 800b8e: 5e pop %esi + 800b8f: 5f pop %edi + 800b90: 5d pop %ebp + 800b91: c3 ret + +00800b92 : + * @len: maximum number of characters to be copied from @src + * + * The return value is @dst + * */ +char * +strncpy(char *dst, const char *src, size_t len) { + 800b92: 55 push %ebp + 800b93: 89 e5 mov %esp,%ebp + 800b95: 83 ec 10 sub $0x10,%esp + char *p = dst; + 800b98: 8b 45 08 mov 0x8(%ebp),%eax + 800b9b: 89 45 fc mov %eax,-0x4(%ebp) + while (len > 0) { + 800b9e: eb 1e jmp 800bbe + if ((*p = *src) != '\0') { + 800ba0: 8b 45 0c mov 0xc(%ebp),%eax + 800ba3: 0f b6 10 movzbl (%eax),%edx + 800ba6: 8b 45 fc mov -0x4(%ebp),%eax + 800ba9: 88 10 mov %dl,(%eax) + 800bab: 8b 45 fc mov -0x4(%ebp),%eax + 800bae: 0f b6 00 movzbl (%eax),%eax + 800bb1: 84 c0 test %al,%al + 800bb3: 74 03 je 800bb8 + src ++; + 800bb5: ff 45 0c incl 0xc(%ebp) + } + p ++, len --; + 800bb8: ff 45 fc incl -0x4(%ebp) + 800bbb: ff 4d 10 decl 0x10(%ebp) + while (len > 0) { + 800bbe: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800bc2: 75 dc jne 800ba0 + } + return dst; + 800bc4: 8b 45 08 mov 0x8(%ebp),%eax +} + 800bc7: 89 ec mov %ebp,%esp + 800bc9: 5d pop %ebp + 800bca: c3 ret + +00800bcb : + * - A value greater than zero indicates that the first character that does + * not match has a greater value in @s1 than in @s2; + * - And a value less than zero indicates the opposite. + * */ +int +strcmp(const char *s1, const char *s2) { + 800bcb: 55 push %ebp + 800bcc: 89 e5 mov %esp,%ebp + 800bce: 57 push %edi + 800bcf: 56 push %esi + 800bd0: 83 ec 20 sub $0x20,%esp + 800bd3: 8b 45 08 mov 0x8(%ebp),%eax + 800bd6: 89 45 f4 mov %eax,-0xc(%ebp) + 800bd9: 8b 45 0c mov 0xc(%ebp),%eax + 800bdc: 89 45 f0 mov %eax,-0x10(%ebp) + asm volatile ( + 800bdf: 8b 55 f4 mov -0xc(%ebp),%edx + 800be2: 8b 45 f0 mov -0x10(%ebp),%eax + 800be5: 89 d1 mov %edx,%ecx + 800be7: 89 c2 mov %eax,%edx + 800be9: 89 ce mov %ecx,%esi + 800beb: 89 d7 mov %edx,%edi + 800bed: ac lods %ds:(%esi),%al + 800bee: ae scas %es:(%edi),%al + 800bef: 75 08 jne 800bf9 + 800bf1: 84 c0 test %al,%al + 800bf3: 75 f8 jne 800bed + 800bf5: 31 c0 xor %eax,%eax + 800bf7: eb 04 jmp 800bfd + 800bf9: 19 c0 sbb %eax,%eax + 800bfb: 0c 01 or $0x1,%al + 800bfd: 89 fa mov %edi,%edx + 800bff: 89 f1 mov %esi,%ecx + 800c01: 89 45 ec mov %eax,-0x14(%ebp) + 800c04: 89 4d e8 mov %ecx,-0x18(%ebp) + 800c07: 89 55 e4 mov %edx,-0x1c(%ebp) + return ret; + 800c0a: 8b 45 ec mov -0x14(%ebp),%eax + while (*s1 != '\0' && *s1 == *s2) { + s1 ++, s2 ++; + } + return (int)((unsigned char)*s1 - (unsigned char)*s2); +#endif /* __HAVE_ARCH_STRCMP */ +} + 800c0d: 83 c4 20 add $0x20,%esp + 800c10: 5e pop %esi + 800c11: 5f pop %edi + 800c12: 5d pop %ebp + 800c13: c3 ret + +00800c14 : + * they are equal to each other, it continues with the following pairs until + * the characters differ, until a terminating null-character is reached, or + * until @n characters match in both strings, whichever happens first. + * */ +int +strncmp(const char *s1, const char *s2, size_t n) { + 800c14: 55 push %ebp + 800c15: 89 e5 mov %esp,%ebp + while (n > 0 && *s1 != '\0' && *s1 == *s2) { + 800c17: eb 09 jmp 800c22 + n --, s1 ++, s2 ++; + 800c19: ff 4d 10 decl 0x10(%ebp) + 800c1c: ff 45 08 incl 0x8(%ebp) + 800c1f: ff 45 0c incl 0xc(%ebp) + while (n > 0 && *s1 != '\0' && *s1 == *s2) { + 800c22: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800c26: 74 1a je 800c42 + 800c28: 8b 45 08 mov 0x8(%ebp),%eax + 800c2b: 0f b6 00 movzbl (%eax),%eax + 800c2e: 84 c0 test %al,%al + 800c30: 74 10 je 800c42 + 800c32: 8b 45 08 mov 0x8(%ebp),%eax + 800c35: 0f b6 10 movzbl (%eax),%edx + 800c38: 8b 45 0c mov 0xc(%ebp),%eax + 800c3b: 0f b6 00 movzbl (%eax),%eax + 800c3e: 38 c2 cmp %al,%dl + 800c40: 74 d7 je 800c19 + } + return (n == 0) ? 0 : (int)((unsigned char)*s1 - (unsigned char)*s2); + 800c42: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800c46: 74 18 je 800c60 + 800c48: 8b 45 08 mov 0x8(%ebp),%eax + 800c4b: 0f b6 00 movzbl (%eax),%eax + 800c4e: 0f b6 d0 movzbl %al,%edx + 800c51: 8b 45 0c mov 0xc(%ebp),%eax + 800c54: 0f b6 00 movzbl (%eax),%eax + 800c57: 0f b6 c8 movzbl %al,%ecx + 800c5a: 89 d0 mov %edx,%eax + 800c5c: 29 c8 sub %ecx,%eax + 800c5e: eb 05 jmp 800c65 + 800c60: b8 00 00 00 00 mov $0x0,%eax +} + 800c65: 5d pop %ebp + 800c66: c3 ret + +00800c67 : + * + * The strchr() function returns a pointer to the first occurrence of + * character in @s. If the value is not found, the function returns 'NULL'. + * */ +char * +strchr(const char *s, char c) { + 800c67: 55 push %ebp + 800c68: 89 e5 mov %esp,%ebp + 800c6a: 83 ec 04 sub $0x4,%esp + 800c6d: 8b 45 0c mov 0xc(%ebp),%eax + 800c70: 88 45 fc mov %al,-0x4(%ebp) + while (*s != '\0') { + 800c73: eb 13 jmp 800c88 + if (*s == c) { + 800c75: 8b 45 08 mov 0x8(%ebp),%eax + 800c78: 0f b6 00 movzbl (%eax),%eax + 800c7b: 38 45 fc cmp %al,-0x4(%ebp) + 800c7e: 75 05 jne 800c85 + return (char *)s; + 800c80: 8b 45 08 mov 0x8(%ebp),%eax + 800c83: eb 12 jmp 800c97 + } + s ++; + 800c85: ff 45 08 incl 0x8(%ebp) + while (*s != '\0') { + 800c88: 8b 45 08 mov 0x8(%ebp),%eax + 800c8b: 0f b6 00 movzbl (%eax),%eax + 800c8e: 84 c0 test %al,%al + 800c90: 75 e3 jne 800c75 + } + return NULL; + 800c92: b8 00 00 00 00 mov $0x0,%eax +} + 800c97: 89 ec mov %ebp,%esp + 800c99: 5d pop %ebp + 800c9a: c3 ret + +00800c9b : + * The strfind() function is like strchr() except that if @c is + * not found in @s, then it returns a pointer to the null byte at the + * end of @s, rather than 'NULL'. + * */ +char * +strfind(const char *s, char c) { + 800c9b: 55 push %ebp + 800c9c: 89 e5 mov %esp,%ebp + 800c9e: 83 ec 04 sub $0x4,%esp + 800ca1: 8b 45 0c mov 0xc(%ebp),%eax + 800ca4: 88 45 fc mov %al,-0x4(%ebp) + while (*s != '\0') { + 800ca7: eb 0e jmp 800cb7 + if (*s == c) { + 800ca9: 8b 45 08 mov 0x8(%ebp),%eax + 800cac: 0f b6 00 movzbl (%eax),%eax + 800caf: 38 45 fc cmp %al,-0x4(%ebp) + 800cb2: 74 0f je 800cc3 + break; + } + s ++; + 800cb4: ff 45 08 incl 0x8(%ebp) + while (*s != '\0') { + 800cb7: 8b 45 08 mov 0x8(%ebp),%eax + 800cba: 0f b6 00 movzbl (%eax),%eax + 800cbd: 84 c0 test %al,%al + 800cbf: 75 e8 jne 800ca9 + 800cc1: eb 01 jmp 800cc4 + break; + 800cc3: 90 nop + } + return (char *)s; + 800cc4: 8b 45 08 mov 0x8(%ebp),%eax +} + 800cc7: 89 ec mov %ebp,%esp + 800cc9: 5d pop %ebp + 800cca: c3 ret + +00800ccb : + * an optional "0x" or "0X" prefix. + * + * The strtol() function returns the converted integral number as a long int value. + * */ +long +strtol(const char *s, char **endptr, int base) { + 800ccb: 55 push %ebp + 800ccc: 89 e5 mov %esp,%ebp + 800cce: 83 ec 10 sub $0x10,%esp + int neg = 0; + 800cd1: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + long val = 0; + 800cd8: c7 45 f8 00 00 00 00 movl $0x0,-0x8(%ebp) + + // gobble initial whitespace + while (*s == ' ' || *s == '\t') { + 800cdf: eb 03 jmp 800ce4 + s ++; + 800ce1: ff 45 08 incl 0x8(%ebp) + while (*s == ' ' || *s == '\t') { + 800ce4: 8b 45 08 mov 0x8(%ebp),%eax + 800ce7: 0f b6 00 movzbl (%eax),%eax + 800cea: 3c 20 cmp $0x20,%al + 800cec: 74 f3 je 800ce1 + 800cee: 8b 45 08 mov 0x8(%ebp),%eax + 800cf1: 0f b6 00 movzbl (%eax),%eax + 800cf4: 3c 09 cmp $0x9,%al + 800cf6: 74 e9 je 800ce1 + } + + // plus/minus sign + if (*s == '+') { + 800cf8: 8b 45 08 mov 0x8(%ebp),%eax + 800cfb: 0f b6 00 movzbl (%eax),%eax + 800cfe: 3c 2b cmp $0x2b,%al + 800d00: 75 05 jne 800d07 + s ++; + 800d02: ff 45 08 incl 0x8(%ebp) + 800d05: eb 14 jmp 800d1b + } + else if (*s == '-') { + 800d07: 8b 45 08 mov 0x8(%ebp),%eax + 800d0a: 0f b6 00 movzbl (%eax),%eax + 800d0d: 3c 2d cmp $0x2d,%al + 800d0f: 75 0a jne 800d1b + s ++, neg = 1; + 800d11: ff 45 08 incl 0x8(%ebp) + 800d14: c7 45 fc 01 00 00 00 movl $0x1,-0x4(%ebp) + } + + // hex or octal base prefix + if ((base == 0 || base == 16) && (s[0] == '0' && s[1] == 'x')) { + 800d1b: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800d1f: 74 06 je 800d27 + 800d21: 83 7d 10 10 cmpl $0x10,0x10(%ebp) + 800d25: 75 22 jne 800d49 + 800d27: 8b 45 08 mov 0x8(%ebp),%eax + 800d2a: 0f b6 00 movzbl (%eax),%eax + 800d2d: 3c 30 cmp $0x30,%al + 800d2f: 75 18 jne 800d49 + 800d31: 8b 45 08 mov 0x8(%ebp),%eax + 800d34: 40 inc %eax + 800d35: 0f b6 00 movzbl (%eax),%eax + 800d38: 3c 78 cmp $0x78,%al + 800d3a: 75 0d jne 800d49 + s += 2, base = 16; + 800d3c: 83 45 08 02 addl $0x2,0x8(%ebp) + 800d40: c7 45 10 10 00 00 00 movl $0x10,0x10(%ebp) + 800d47: eb 29 jmp 800d72 + } + else if (base == 0 && s[0] == '0') { + 800d49: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800d4d: 75 16 jne 800d65 + 800d4f: 8b 45 08 mov 0x8(%ebp),%eax + 800d52: 0f b6 00 movzbl (%eax),%eax + 800d55: 3c 30 cmp $0x30,%al + 800d57: 75 0c jne 800d65 + s ++, base = 8; + 800d59: ff 45 08 incl 0x8(%ebp) + 800d5c: c7 45 10 08 00 00 00 movl $0x8,0x10(%ebp) + 800d63: eb 0d jmp 800d72 + } + else if (base == 0) { + 800d65: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800d69: 75 07 jne 800d72 + base = 10; + 800d6b: c7 45 10 0a 00 00 00 movl $0xa,0x10(%ebp) + + // digits + while (1) { + int dig; + + if (*s >= '0' && *s <= '9') { + 800d72: 8b 45 08 mov 0x8(%ebp),%eax + 800d75: 0f b6 00 movzbl (%eax),%eax + 800d78: 3c 2f cmp $0x2f,%al + 800d7a: 7e 1b jle 800d97 + 800d7c: 8b 45 08 mov 0x8(%ebp),%eax + 800d7f: 0f b6 00 movzbl (%eax),%eax + 800d82: 3c 39 cmp $0x39,%al + 800d84: 7f 11 jg 800d97 + dig = *s - '0'; + 800d86: 8b 45 08 mov 0x8(%ebp),%eax + 800d89: 0f b6 00 movzbl (%eax),%eax + 800d8c: 0f be c0 movsbl %al,%eax + 800d8f: 83 e8 30 sub $0x30,%eax + 800d92: 89 45 f4 mov %eax,-0xc(%ebp) + 800d95: eb 48 jmp 800ddf + } + else if (*s >= 'a' && *s <= 'z') { + 800d97: 8b 45 08 mov 0x8(%ebp),%eax + 800d9a: 0f b6 00 movzbl (%eax),%eax + 800d9d: 3c 60 cmp $0x60,%al + 800d9f: 7e 1b jle 800dbc + 800da1: 8b 45 08 mov 0x8(%ebp),%eax + 800da4: 0f b6 00 movzbl (%eax),%eax + 800da7: 3c 7a cmp $0x7a,%al + 800da9: 7f 11 jg 800dbc + dig = *s - 'a' + 10; + 800dab: 8b 45 08 mov 0x8(%ebp),%eax + 800dae: 0f b6 00 movzbl (%eax),%eax + 800db1: 0f be c0 movsbl %al,%eax + 800db4: 83 e8 57 sub $0x57,%eax + 800db7: 89 45 f4 mov %eax,-0xc(%ebp) + 800dba: eb 23 jmp 800ddf + } + else if (*s >= 'A' && *s <= 'Z') { + 800dbc: 8b 45 08 mov 0x8(%ebp),%eax + 800dbf: 0f b6 00 movzbl (%eax),%eax + 800dc2: 3c 40 cmp $0x40,%al + 800dc4: 7e 3b jle 800e01 + 800dc6: 8b 45 08 mov 0x8(%ebp),%eax + 800dc9: 0f b6 00 movzbl (%eax),%eax + 800dcc: 3c 5a cmp $0x5a,%al + 800dce: 7f 31 jg 800e01 + dig = *s - 'A' + 10; + 800dd0: 8b 45 08 mov 0x8(%ebp),%eax + 800dd3: 0f b6 00 movzbl (%eax),%eax + 800dd6: 0f be c0 movsbl %al,%eax + 800dd9: 83 e8 37 sub $0x37,%eax + 800ddc: 89 45 f4 mov %eax,-0xc(%ebp) + } + else { + break; + } + if (dig >= base) { + 800ddf: 8b 45 f4 mov -0xc(%ebp),%eax + 800de2: 3b 45 10 cmp 0x10(%ebp),%eax + 800de5: 7d 19 jge 800e00 + break; + } + s ++, val = (val * base) + dig; + 800de7: ff 45 08 incl 0x8(%ebp) + 800dea: 8b 45 f8 mov -0x8(%ebp),%eax + 800ded: 0f af 45 10 imul 0x10(%ebp),%eax + 800df1: 89 c2 mov %eax,%edx + 800df3: 8b 45 f4 mov -0xc(%ebp),%eax + 800df6: 01 d0 add %edx,%eax + 800df8: 89 45 f8 mov %eax,-0x8(%ebp) + while (1) { + 800dfb: e9 72 ff ff ff jmp 800d72 + break; + 800e00: 90 nop + // we don't properly detect overflow! + } + + if (endptr) { + 800e01: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) + 800e05: 74 08 je 800e0f + *endptr = (char *) s; + 800e07: 8b 45 0c mov 0xc(%ebp),%eax + 800e0a: 8b 55 08 mov 0x8(%ebp),%edx + 800e0d: 89 10 mov %edx,(%eax) + } + return (neg ? -val : val); + 800e0f: 83 7d fc 00 cmpl $0x0,-0x4(%ebp) + 800e13: 74 07 je 800e1c + 800e15: 8b 45 f8 mov -0x8(%ebp),%eax + 800e18: f7 d8 neg %eax + 800e1a: eb 03 jmp 800e1f + 800e1c: 8b 45 f8 mov -0x8(%ebp),%eax +} + 800e1f: 89 ec mov %ebp,%esp + 800e21: 5d pop %ebp + 800e22: c3 ret + +00800e23 : + * @n: number of bytes to be set to the value + * + * The memset() function returns @s. + * */ +void * +memset(void *s, char c, size_t n) { + 800e23: 55 push %ebp + 800e24: 89 e5 mov %esp,%ebp + 800e26: 83 ec 28 sub $0x28,%esp + 800e29: 89 7d fc mov %edi,-0x4(%ebp) + 800e2c: 8b 45 0c mov 0xc(%ebp),%eax + 800e2f: 88 45 d8 mov %al,-0x28(%ebp) +#ifdef __HAVE_ARCH_MEMSET + return __memset(s, c, n); + 800e32: 0f be 55 d8 movsbl -0x28(%ebp),%edx + 800e36: 8b 45 08 mov 0x8(%ebp),%eax + 800e39: 89 45 f8 mov %eax,-0x8(%ebp) + 800e3c: 88 55 f7 mov %dl,-0x9(%ebp) + 800e3f: 8b 45 10 mov 0x10(%ebp),%eax + 800e42: 89 45 f0 mov %eax,-0x10(%ebp) +#ifndef __HAVE_ARCH_MEMSET +#define __HAVE_ARCH_MEMSET +static inline void * +__memset(void *s, char c, size_t n) { + int d0, d1; + asm volatile ( + 800e45: 8b 4d f0 mov -0x10(%ebp),%ecx + 800e48: 0f b6 45 f7 movzbl -0x9(%ebp),%eax + 800e4c: 8b 55 f8 mov -0x8(%ebp),%edx + 800e4f: 89 d7 mov %edx,%edi + 800e51: f3 aa rep stos %al,%es:(%edi) + 800e53: 89 fa mov %edi,%edx + 800e55: 89 4d ec mov %ecx,-0x14(%ebp) + 800e58: 89 55 e8 mov %edx,-0x18(%ebp) + "rep; stosb;" + : "=&c" (d0), "=&D" (d1) + : "0" (n), "a" (c), "1" (s) + : "memory"); + return s; + 800e5b: 8b 45 f8 mov -0x8(%ebp),%eax + while (n -- > 0) { + *p ++ = c; + } + return s; +#endif /* __HAVE_ARCH_MEMSET */ +} + 800e5e: 8b 7d fc mov -0x4(%ebp),%edi + 800e61: 89 ec mov %ebp,%esp + 800e63: 5d pop %ebp + 800e64: c3 ret + +00800e65 : + * @n: number of bytes to copy + * + * The memmove() function returns @dst. + * */ +void * +memmove(void *dst, const void *src, size_t n) { + 800e65: 55 push %ebp + 800e66: 89 e5 mov %esp,%ebp + 800e68: 57 push %edi + 800e69: 56 push %esi + 800e6a: 53 push %ebx + 800e6b: 83 ec 30 sub $0x30,%esp + 800e6e: 8b 45 08 mov 0x8(%ebp),%eax + 800e71: 89 45 f0 mov %eax,-0x10(%ebp) + 800e74: 8b 45 0c mov 0xc(%ebp),%eax + 800e77: 89 45 ec mov %eax,-0x14(%ebp) + 800e7a: 8b 45 10 mov 0x10(%ebp),%eax + 800e7d: 89 45 e8 mov %eax,-0x18(%ebp) + +#ifndef __HAVE_ARCH_MEMMOVE +#define __HAVE_ARCH_MEMMOVE +static inline void * +__memmove(void *dst, const void *src, size_t n) { + if (dst < src) { + 800e80: 8b 45 f0 mov -0x10(%ebp),%eax + 800e83: 3b 45 ec cmp -0x14(%ebp),%eax + 800e86: 73 42 jae 800eca + 800e88: 8b 45 f0 mov -0x10(%ebp),%eax + 800e8b: 89 45 e4 mov %eax,-0x1c(%ebp) + 800e8e: 8b 45 ec mov -0x14(%ebp),%eax + 800e91: 89 45 e0 mov %eax,-0x20(%ebp) + 800e94: 8b 45 e8 mov -0x18(%ebp),%eax + 800e97: 89 45 dc mov %eax,-0x24(%ebp) + "andl $3, %%ecx;" + "jz 1f;" + "rep; movsb;" + "1:" + : "=&c" (d0), "=&D" (d1), "=&S" (d2) + : "0" (n / 4), "g" (n), "1" (dst), "2" (src) + 800e9a: 8b 45 dc mov -0x24(%ebp),%eax + 800e9d: c1 e8 02 shr $0x2,%eax + 800ea0: 89 c1 mov %eax,%ecx + asm volatile ( + 800ea2: 8b 55 e4 mov -0x1c(%ebp),%edx + 800ea5: 8b 45 e0 mov -0x20(%ebp),%eax + 800ea8: 89 d7 mov %edx,%edi + 800eaa: 89 c6 mov %eax,%esi + 800eac: f3 a5 rep movsl %ds:(%esi),%es:(%edi) + 800eae: 8b 4d dc mov -0x24(%ebp),%ecx + 800eb1: 83 e1 03 and $0x3,%ecx + 800eb4: 74 02 je 800eb8 + 800eb6: f3 a4 rep movsb %ds:(%esi),%es:(%edi) + 800eb8: 89 f0 mov %esi,%eax + 800eba: 89 fa mov %edi,%edx + 800ebc: 89 4d d8 mov %ecx,-0x28(%ebp) + 800ebf: 89 55 d4 mov %edx,-0x2c(%ebp) + 800ec2: 89 45 d0 mov %eax,-0x30(%ebp) + : "memory"); + return dst; + 800ec5: 8b 45 e4 mov -0x1c(%ebp),%eax + return __memcpy(dst, src, n); + 800ec8: eb 36 jmp 800f00 + : "0" (n), "1" (n - 1 + src), "2" (n - 1 + dst) + 800eca: 8b 45 e8 mov -0x18(%ebp),%eax + 800ecd: 8d 50 ff lea -0x1(%eax),%edx + 800ed0: 8b 45 ec mov -0x14(%ebp),%eax + 800ed3: 01 c2 add %eax,%edx + 800ed5: 8b 45 e8 mov -0x18(%ebp),%eax + 800ed8: 8d 48 ff lea -0x1(%eax),%ecx + 800edb: 8b 45 f0 mov -0x10(%ebp),%eax + 800ede: 8d 1c 01 lea (%ecx,%eax,1),%ebx + asm volatile ( + 800ee1: 8b 45 e8 mov -0x18(%ebp),%eax + 800ee4: 89 c1 mov %eax,%ecx + 800ee6: 89 d8 mov %ebx,%eax + 800ee8: 89 d6 mov %edx,%esi + 800eea: 89 c7 mov %eax,%edi + 800eec: fd std + 800eed: f3 a4 rep movsb %ds:(%esi),%es:(%edi) + 800eef: fc cld + 800ef0: 89 f8 mov %edi,%eax + 800ef2: 89 f2 mov %esi,%edx + 800ef4: 89 4d cc mov %ecx,-0x34(%ebp) + 800ef7: 89 55 c8 mov %edx,-0x38(%ebp) + 800efa: 89 45 c4 mov %eax,-0x3c(%ebp) + return dst; + 800efd: 8b 45 f0 mov -0x10(%ebp),%eax + *d ++ = *s ++; + } + } + return dst; +#endif /* __HAVE_ARCH_MEMMOVE */ +} + 800f00: 83 c4 30 add $0x30,%esp + 800f03: 5b pop %ebx + 800f04: 5e pop %esi + 800f05: 5f pop %edi + 800f06: 5d pop %ebp + 800f07: c3 ret + +00800f08 : + * it always copies exactly @n bytes. To avoid overflows, the size of arrays pointed + * by both @src and @dst, should be at least @n bytes, and should not overlap + * (for overlapping memory area, memmove is a safer approach). + * */ +void * +memcpy(void *dst, const void *src, size_t n) { + 800f08: 55 push %ebp + 800f09: 89 e5 mov %esp,%ebp + 800f0b: 57 push %edi + 800f0c: 56 push %esi + 800f0d: 83 ec 20 sub $0x20,%esp + 800f10: 8b 45 08 mov 0x8(%ebp),%eax + 800f13: 89 45 f4 mov %eax,-0xc(%ebp) + 800f16: 8b 45 0c mov 0xc(%ebp),%eax + 800f19: 89 45 f0 mov %eax,-0x10(%ebp) + 800f1c: 8b 45 10 mov 0x10(%ebp),%eax + 800f1f: 89 45 ec mov %eax,-0x14(%ebp) + : "0" (n / 4), "g" (n), "1" (dst), "2" (src) + 800f22: 8b 45 ec mov -0x14(%ebp),%eax + 800f25: c1 e8 02 shr $0x2,%eax + 800f28: 89 c1 mov %eax,%ecx + asm volatile ( + 800f2a: 8b 55 f4 mov -0xc(%ebp),%edx + 800f2d: 8b 45 f0 mov -0x10(%ebp),%eax + 800f30: 89 d7 mov %edx,%edi + 800f32: 89 c6 mov %eax,%esi + 800f34: f3 a5 rep movsl %ds:(%esi),%es:(%edi) + 800f36: 8b 4d ec mov -0x14(%ebp),%ecx + 800f39: 83 e1 03 and $0x3,%ecx + 800f3c: 74 02 je 800f40 + 800f3e: f3 a4 rep movsb %ds:(%esi),%es:(%edi) + 800f40: 89 f0 mov %esi,%eax + 800f42: 89 fa mov %edi,%edx + 800f44: 89 4d e8 mov %ecx,-0x18(%ebp) + 800f47: 89 55 e4 mov %edx,-0x1c(%ebp) + 800f4a: 89 45 e0 mov %eax,-0x20(%ebp) + return dst; + 800f4d: 8b 45 f4 mov -0xc(%ebp),%eax + while (n -- > 0) { + *d ++ = *s ++; + } + return dst; +#endif /* __HAVE_ARCH_MEMCPY */ +} + 800f50: 83 c4 20 add $0x20,%esp + 800f53: 5e pop %esi + 800f54: 5f pop %edi + 800f55: 5d pop %ebp + 800f56: c3 ret + +00800f57 : + * match in both memory blocks has a greater value in @v1 than in @v2 + * as if evaluated as unsigned char values; + * - And a value less than zero indicates the opposite. + * */ +int +memcmp(const void *v1, const void *v2, size_t n) { + 800f57: 55 push %ebp + 800f58: 89 e5 mov %esp,%ebp + 800f5a: 83 ec 10 sub $0x10,%esp + const char *s1 = (const char *)v1; + 800f5d: 8b 45 08 mov 0x8(%ebp),%eax + 800f60: 89 45 fc mov %eax,-0x4(%ebp) + const char *s2 = (const char *)v2; + 800f63: 8b 45 0c mov 0xc(%ebp),%eax + 800f66: 89 45 f8 mov %eax,-0x8(%ebp) + while (n -- > 0) { + 800f69: eb 2e jmp 800f99 + if (*s1 != *s2) { + 800f6b: 8b 45 fc mov -0x4(%ebp),%eax + 800f6e: 0f b6 10 movzbl (%eax),%edx + 800f71: 8b 45 f8 mov -0x8(%ebp),%eax + 800f74: 0f b6 00 movzbl (%eax),%eax + 800f77: 38 c2 cmp %al,%dl + 800f79: 74 18 je 800f93 + return (int)((unsigned char)*s1 - (unsigned char)*s2); + 800f7b: 8b 45 fc mov -0x4(%ebp),%eax + 800f7e: 0f b6 00 movzbl (%eax),%eax + 800f81: 0f b6 d0 movzbl %al,%edx + 800f84: 8b 45 f8 mov -0x8(%ebp),%eax + 800f87: 0f b6 00 movzbl (%eax),%eax + 800f8a: 0f b6 c8 movzbl %al,%ecx + 800f8d: 89 d0 mov %edx,%eax + 800f8f: 29 c8 sub %ecx,%eax + 800f91: eb 18 jmp 800fab + } + s1 ++, s2 ++; + 800f93: ff 45 fc incl -0x4(%ebp) + 800f96: ff 45 f8 incl -0x8(%ebp) + while (n -- > 0) { + 800f99: 8b 45 10 mov 0x10(%ebp),%eax + 800f9c: 8d 50 ff lea -0x1(%eax),%edx + 800f9f: 89 55 10 mov %edx,0x10(%ebp) + 800fa2: 85 c0 test %eax,%eax + 800fa4: 75 c5 jne 800f6b + } + return 0; + 800fa6: b8 00 00 00 00 mov $0x0,%eax +} + 800fab: 89 ec mov %ebp,%esp + 800fad: 5d pop %ebp + 800fae: c3 ret + +00800faf
: +#define ARRAYSIZE (1024*1024) + +uint32_t bigarray[ARRAYSIZE]; + +int +main(void) { + 800faf: 55 push %ebp + 800fb0: 89 e5 mov %esp,%ebp + 800fb2: 83 e4 f0 and $0xfffffff0,%esp + 800fb5: 83 ec 20 sub $0x20,%esp + cprintf("Making sure bss works right...\n"); + 800fb8: c7 04 24 c0 13 80 00 movl $0x8013c0,(%esp) + 800fbf: e8 5c f1 ff ff call 800120 + int i; + for (i = 0; i < ARRAYSIZE; i ++) { + 800fc4: c7 44 24 1c 00 00 00 movl $0x0,0x1c(%esp) + 800fcb: 00 + 800fcc: eb 37 jmp 801005 + if (bigarray[i] != 0) { + 800fce: 8b 44 24 1c mov 0x1c(%esp),%eax + 800fd2: 8b 04 85 20 20 80 00 mov 0x802020(,%eax,4),%eax + 800fd9: 85 c0 test %eax,%eax + 800fdb: 74 24 je 801001 + panic("bigarray[%d] isn't cleared!\n", i); + 800fdd: 8b 44 24 1c mov 0x1c(%esp),%eax + 800fe1: 89 44 24 0c mov %eax,0xc(%esp) + 800fe5: c7 44 24 08 e0 13 80 movl $0x8013e0,0x8(%esp) + 800fec: 00 + 800fed: c7 44 24 04 0e 00 00 movl $0xe,0x4(%esp) + 800ff4: 00 + 800ff5: c7 04 24 fd 13 80 00 movl $0x8013fd,(%esp) + 800ffc: e8 2e f0 ff ff call 80002f <__panic> + for (i = 0; i < ARRAYSIZE; i ++) { + 801001: ff 44 24 1c incl 0x1c(%esp) + 801005: 81 7c 24 1c ff ff 0f cmpl $0xfffff,0x1c(%esp) + 80100c: 00 + 80100d: 7e bf jle 800fce + } + } + for (i = 0; i < ARRAYSIZE; i ++) { + 80100f: c7 44 24 1c 00 00 00 movl $0x0,0x1c(%esp) + 801016: 00 + 801017: eb 13 jmp 80102c + bigarray[i] = i; + 801019: 8b 54 24 1c mov 0x1c(%esp),%edx + 80101d: 8b 44 24 1c mov 0x1c(%esp),%eax + 801021: 89 14 85 20 20 80 00 mov %edx,0x802020(,%eax,4) + for (i = 0; i < ARRAYSIZE; i ++) { + 801028: ff 44 24 1c incl 0x1c(%esp) + 80102c: 81 7c 24 1c ff ff 0f cmpl $0xfffff,0x1c(%esp) + 801033: 00 + 801034: 7e e3 jle 801019 + } + for (i = 0; i < ARRAYSIZE; i ++) { + 801036: c7 44 24 1c 00 00 00 movl $0x0,0x1c(%esp) + 80103d: 00 + 80103e: eb 3b jmp 80107b + if (bigarray[i] != i) { + 801040: 8b 44 24 1c mov 0x1c(%esp),%eax + 801044: 8b 14 85 20 20 80 00 mov 0x802020(,%eax,4),%edx + 80104b: 8b 44 24 1c mov 0x1c(%esp),%eax + 80104f: 39 c2 cmp %eax,%edx + 801051: 74 24 je 801077 + panic("bigarray[%d] didn't hold its value!\n", i); + 801053: 8b 44 24 1c mov 0x1c(%esp),%eax + 801057: 89 44 24 0c mov %eax,0xc(%esp) + 80105b: c7 44 24 08 0c 14 80 movl $0x80140c,0x8(%esp) + 801062: 00 + 801063: c7 44 24 04 16 00 00 movl $0x16,0x4(%esp) + 80106a: 00 + 80106b: c7 04 24 fd 13 80 00 movl $0x8013fd,(%esp) + 801072: e8 b8 ef ff ff call 80002f <__panic> + for (i = 0; i < ARRAYSIZE; i ++) { + 801077: ff 44 24 1c incl 0x1c(%esp) + 80107b: 81 7c 24 1c ff ff 0f cmpl $0xfffff,0x1c(%esp) + 801082: 00 + 801083: 7e bb jle 801040 + } + } + + cprintf("Yes, good. Now doing a wild write off the end...\n"); + 801085: c7 04 24 34 14 80 00 movl $0x801434,(%esp) + 80108c: e8 8f f0 ff ff call 800120 + cprintf("testbss may pass.\n"); + 801091: c7 04 24 67 14 80 00 movl $0x801467,(%esp) + 801098: e8 83 f0 ff ff call 800120 + + bigarray[ARRAYSIZE + 1024] = 0; + 80109d: c7 05 20 30 c0 00 00 movl $0x0,0xc03020 + 8010a4: 00 00 00 + asm volatile ("int $0x14"); + 8010a7: cd 14 int $0x14 + panic("FAIL: T.T\n"); + 8010a9: c7 44 24 08 7a 14 80 movl $0x80147a,0x8(%esp) + 8010b0: 00 + 8010b1: c7 44 24 04 1f 00 00 movl $0x1f,0x4(%esp) + 8010b8: 00 + 8010b9: c7 04 24 fd 13 80 00 movl $0x8013fd,(%esp) + 8010c0: e8 6a ef ff ff call 80002f <__panic> diff --git a/labcodes/lab5/obj/user/testbss.d b/labcodes/lab5/obj/user/testbss.d new file mode 100644 index 0000000000000000000000000000000000000000..c0a525c78c12c2646ae81e3bdd67c88d2bf80514 --- /dev/null +++ b/labcodes/lab5/obj/user/testbss.d @@ -0,0 +1,2 @@ +obj/user/testbss.o obj/user/testbss.d: user/testbss.c libs/stdio.h \ + libs/defs.h libs/stdarg.h user/libs/ulib.h diff --git a/labcodes/lab5/obj/user/testbss.o b/labcodes/lab5/obj/user/testbss.o new file mode 100644 index 0000000000000000000000000000000000000000..d099a0959d671f9400788e87bbb8841e12ec1c27 Binary files /dev/null and b/labcodes/lab5/obj/user/testbss.o differ diff --git a/labcodes/lab5/obj/user/testbss.sym b/labcodes/lab5/obj/user/testbss.sym new file mode 100644 index 0000000000000000000000000000000000000000..5c65ae444e3d30839ee4f1c0c20db876999b19b2 --- /dev/null +++ b/labcodes/lab5/obj/user/testbss.sym @@ -0,0 +1,67 @@ +00000000 panic.c +00000000 stdio.c +008000c8 cputch +00000000 syscall.c +00800199 syscall +00000000 ulib.c +00000000 umain.c +00000000 hash.c +00000000 printfmt.c +008011e0 error_string +008003ad printnum +008004af getuint +008004fe getint +0080094f sprintputch +00000000 rand.c +00802000 next +00000000 string.c +00000000 testbss.c +00800b53 strcpy +00800329 yield +0080030d waitpid +00800245 sys_yield +00800e65 memmove +00800985 snprintf +00800576 vprintfmt +0080020b sys_fork +00800120 cprintf +0080034e getpid +00800f08 memcpy +008009bb vsnprintf +0080036d umain +00202824 __STAB_END__ +0080025b sys_kill +00202825 __STABSTR_BEGIN__ +0080002f __panic +00800ccb strtol +00800b22 strnlen +00802020 bigarray +0080035d print_pgdir +00800339 kill +00800c9b strfind +008002ef wait +00800020 _start +00800a21 rand +00800c14 strncmp +0080028e sys_putc +00800b92 strncpy +00800f57 memcmp +008002e0 fork +00800e23 memset +00800faf main +00800ae0 srand +00800386 hash32 +00800545 printfmt +0020379f __STABSTR_END__ +00800bcb strcmp +008000eb vcprintf +0080007f __warn +00800148 cputs +008002c1 exit +00800221 sys_wait +008001ee sys_exit +00200010 __STAB_BEGIN__ +00800af9 strlen +008002ab sys_pgdir +00800c67 strchr +00800278 sys_getpid diff --git a/labcodes/lab5/obj/user/waitkill.asm b/labcodes/lab5/obj/user/waitkill.asm new file mode 100644 index 0000000000000000000000000000000000000000..d6694c58f241754b2dcec4bec2ade0c5b06be8f9 --- /dev/null +++ b/labcodes/lab5/obj/user/waitkill.asm @@ -0,0 +1,2464 @@ + +obj/__user_waitkill.out: file format elf32-i386 + + +Disassembly of section .text: + +00800020 <_start>: +.text +.globl _start +_start: + # set ebp for backtrace + movl $0x0, %ebp + 800020: bd 00 00 00 00 mov $0x0,%ebp + + # move down the esp register + # since it may cause page fault in backtrace + subl $0x20, %esp + 800025: 83 ec 20 sub $0x20,%esp + + # call user-program function + call umain + 800028: e8 40 03 00 00 call 80036d +1: jmp 1b + 80002d: eb fe jmp 80002d <_start+0xd> + +0080002f <__panic>: +#include +#include +#include + +void +__panic(const char *file, int line, const char *fmt, ...) { + 80002f: 55 push %ebp + 800030: 89 e5 mov %esp,%ebp + 800032: 83 ec 28 sub $0x28,%esp + // print the 'message' + va_list ap; + va_start(ap, fmt); + 800035: 8d 45 14 lea 0x14(%ebp),%eax + 800038: 89 45 f4 mov %eax,-0xc(%ebp) + cprintf("user panic at %s:%d:\n ", file, line); + 80003b: 8b 45 0c mov 0xc(%ebp),%eax + 80003e: 89 44 24 08 mov %eax,0x8(%esp) + 800042: 8b 45 08 mov 0x8(%ebp),%eax + 800045: 89 44 24 04 mov %eax,0x4(%esp) + 800049: c7 04 24 60 11 80 00 movl $0x801160,(%esp) + 800050: e8 cb 00 00 00 call 800120 + vcprintf(fmt, ap); + 800055: 8b 45 f4 mov -0xc(%ebp),%eax + 800058: 89 44 24 04 mov %eax,0x4(%esp) + 80005c: 8b 45 10 mov 0x10(%ebp),%eax + 80005f: 89 04 24 mov %eax,(%esp) + 800062: e8 84 00 00 00 call 8000eb + cprintf("\n"); + 800067: c7 04 24 7a 11 80 00 movl $0x80117a,(%esp) + 80006e: e8 ad 00 00 00 call 800120 + va_end(ap); + exit(-E_PANIC); + 800073: c7 04 24 f6 ff ff ff movl $0xfffffff6,(%esp) + 80007a: e8 42 02 00 00 call 8002c1 + +0080007f <__warn>: +} + +void +__warn(const char *file, int line, const char *fmt, ...) { + 80007f: 55 push %ebp + 800080: 89 e5 mov %esp,%ebp + 800082: 83 ec 28 sub $0x28,%esp + va_list ap; + va_start(ap, fmt); + 800085: 8d 45 14 lea 0x14(%ebp),%eax + 800088: 89 45 f4 mov %eax,-0xc(%ebp) + cprintf("user warning at %s:%d:\n ", file, line); + 80008b: 8b 45 0c mov 0xc(%ebp),%eax + 80008e: 89 44 24 08 mov %eax,0x8(%esp) + 800092: 8b 45 08 mov 0x8(%ebp),%eax + 800095: 89 44 24 04 mov %eax,0x4(%esp) + 800099: c7 04 24 7c 11 80 00 movl $0x80117c,(%esp) + 8000a0: e8 7b 00 00 00 call 800120 + vcprintf(fmt, ap); + 8000a5: 8b 45 f4 mov -0xc(%ebp),%eax + 8000a8: 89 44 24 04 mov %eax,0x4(%esp) + 8000ac: 8b 45 10 mov 0x10(%ebp),%eax + 8000af: 89 04 24 mov %eax,(%esp) + 8000b2: e8 34 00 00 00 call 8000eb + cprintf("\n"); + 8000b7: c7 04 24 7a 11 80 00 movl $0x80117a,(%esp) + 8000be: e8 5d 00 00 00 call 800120 + va_end(ap); +} + 8000c3: 90 nop + 8000c4: 89 ec mov %ebp,%esp + 8000c6: 5d pop %ebp + 8000c7: c3 ret + +008000c8 : +/* * + * cputch - writes a single character @c to stdout, and it will + * increace the value of counter pointed by @cnt. + * */ +static void +cputch(int c, int *cnt) { + 8000c8: 55 push %ebp + 8000c9: 89 e5 mov %esp,%ebp + 8000cb: 83 ec 18 sub $0x18,%esp + sys_putc(c); + 8000ce: 8b 45 08 mov 0x8(%ebp),%eax + 8000d1: 89 04 24 mov %eax,(%esp) + 8000d4: e8 b5 01 00 00 call 80028e + (*cnt) ++; + 8000d9: 8b 45 0c mov 0xc(%ebp),%eax + 8000dc: 8b 00 mov (%eax),%eax + 8000de: 8d 50 01 lea 0x1(%eax),%edx + 8000e1: 8b 45 0c mov 0xc(%ebp),%eax + 8000e4: 89 10 mov %edx,(%eax) +} + 8000e6: 90 nop + 8000e7: 89 ec mov %ebp,%esp + 8000e9: 5d pop %ebp + 8000ea: c3 ret + +008000eb : + * + * Call this function if you are already dealing with a va_list. + * Or you probably want cprintf() instead. + * */ +int +vcprintf(const char *fmt, va_list ap) { + 8000eb: 55 push %ebp + 8000ec: 89 e5 mov %esp,%ebp + 8000ee: 83 ec 28 sub $0x28,%esp + int cnt = 0; + 8000f1: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + vprintfmt((void*)cputch, &cnt, fmt, ap); + 8000f8: 8b 45 0c mov 0xc(%ebp),%eax + 8000fb: 89 44 24 0c mov %eax,0xc(%esp) + 8000ff: 8b 45 08 mov 0x8(%ebp),%eax + 800102: 89 44 24 08 mov %eax,0x8(%esp) + 800106: 8d 45 f4 lea -0xc(%ebp),%eax + 800109: 89 44 24 04 mov %eax,0x4(%esp) + 80010d: c7 04 24 c8 00 80 00 movl $0x8000c8,(%esp) + 800114: e8 5d 04 00 00 call 800576 + return cnt; + 800119: 8b 45 f4 mov -0xc(%ebp),%eax +} + 80011c: 89 ec mov %ebp,%esp + 80011e: 5d pop %ebp + 80011f: c3 ret + +00800120 : + * + * The return value is the number of characters which would be + * written to stdout. + * */ +int +cprintf(const char *fmt, ...) { + 800120: 55 push %ebp + 800121: 89 e5 mov %esp,%ebp + 800123: 83 ec 28 sub $0x28,%esp + va_list ap; + + va_start(ap, fmt); + 800126: 8d 45 0c lea 0xc(%ebp),%eax + 800129: 89 45 f0 mov %eax,-0x10(%ebp) + int cnt = vcprintf(fmt, ap); + 80012c: 8b 45 f0 mov -0x10(%ebp),%eax + 80012f: 89 44 24 04 mov %eax,0x4(%esp) + 800133: 8b 45 08 mov 0x8(%ebp),%eax + 800136: 89 04 24 mov %eax,(%esp) + 800139: e8 ad ff ff ff call 8000eb + 80013e: 89 45 f4 mov %eax,-0xc(%ebp) + va_end(ap); + + return cnt; + 800141: 8b 45 f4 mov -0xc(%ebp),%eax +} + 800144: 89 ec mov %ebp,%esp + 800146: 5d pop %ebp + 800147: c3 ret + +00800148 : +/* * + * cputs- writes the string pointed by @str to stdout and + * appends a newline character. + * */ +int +cputs(const char *str) { + 800148: 55 push %ebp + 800149: 89 e5 mov %esp,%ebp + 80014b: 83 ec 28 sub $0x28,%esp + int cnt = 0; + 80014e: c7 45 f0 00 00 00 00 movl $0x0,-0x10(%ebp) + char c; + while ((c = *str ++) != '\0') { + 800155: eb 13 jmp 80016a + cputch(c, &cnt); + 800157: 0f be 45 f7 movsbl -0x9(%ebp),%eax + 80015b: 8d 55 f0 lea -0x10(%ebp),%edx + 80015e: 89 54 24 04 mov %edx,0x4(%esp) + 800162: 89 04 24 mov %eax,(%esp) + 800165: e8 5e ff ff ff call 8000c8 + while ((c = *str ++) != '\0') { + 80016a: 8b 45 08 mov 0x8(%ebp),%eax + 80016d: 8d 50 01 lea 0x1(%eax),%edx + 800170: 89 55 08 mov %edx,0x8(%ebp) + 800173: 0f b6 00 movzbl (%eax),%eax + 800176: 88 45 f7 mov %al,-0x9(%ebp) + 800179: 80 7d f7 00 cmpb $0x0,-0x9(%ebp) + 80017d: 75 d8 jne 800157 + } + cputch('\n', &cnt); + 80017f: 8d 45 f0 lea -0x10(%ebp),%eax + 800182: 89 44 24 04 mov %eax,0x4(%esp) + 800186: c7 04 24 0a 00 00 00 movl $0xa,(%esp) + 80018d: e8 36 ff ff ff call 8000c8 + return cnt; + 800192: 8b 45 f0 mov -0x10(%ebp),%eax +} + 800195: 89 ec mov %ebp,%esp + 800197: 5d pop %ebp + 800198: c3 ret + +00800199 : +#include + +#define MAX_ARGS 5 + +static inline int +syscall(int num, ...) { + 800199: 55 push %ebp + 80019a: 89 e5 mov %esp,%ebp + 80019c: 57 push %edi + 80019d: 56 push %esi + 80019e: 53 push %ebx + 80019f: 83 ec 20 sub $0x20,%esp + va_list ap; + va_start(ap, num); + 8001a2: 8d 45 0c lea 0xc(%ebp),%eax + 8001a5: 89 45 e8 mov %eax,-0x18(%ebp) + uint32_t a[MAX_ARGS]; + int i, ret; + for (i = 0; i < MAX_ARGS; i ++) { + 8001a8: c7 45 f0 00 00 00 00 movl $0x0,-0x10(%ebp) + 8001af: eb 15 jmp 8001c6 + a[i] = va_arg(ap, uint32_t); + 8001b1: 8b 45 e8 mov -0x18(%ebp),%eax + 8001b4: 8d 50 04 lea 0x4(%eax),%edx + 8001b7: 89 55 e8 mov %edx,-0x18(%ebp) + 8001ba: 8b 10 mov (%eax),%edx + 8001bc: 8b 45 f0 mov -0x10(%ebp),%eax + 8001bf: 89 54 85 d4 mov %edx,-0x2c(%ebp,%eax,4) + for (i = 0; i < MAX_ARGS; i ++) { + 8001c3: ff 45 f0 incl -0x10(%ebp) + 8001c6: 83 7d f0 04 cmpl $0x4,-0x10(%ebp) + 8001ca: 7e e5 jle 8001b1 + asm volatile ( + "int %1;" + : "=a" (ret) + : "i" (T_SYSCALL), + "a" (num), + "d" (a[0]), + 8001cc: 8b 55 d4 mov -0x2c(%ebp),%edx + "c" (a[1]), + 8001cf: 8b 4d d8 mov -0x28(%ebp),%ecx + "b" (a[2]), + 8001d2: 8b 5d dc mov -0x24(%ebp),%ebx + "D" (a[3]), + 8001d5: 8b 7d e0 mov -0x20(%ebp),%edi + "S" (a[4]) + 8001d8: 8b 75 e4 mov -0x1c(%ebp),%esi + asm volatile ( + 8001db: 8b 45 08 mov 0x8(%ebp),%eax + 8001de: cd 80 int $0x80 + 8001e0: 89 45 ec mov %eax,-0x14(%ebp) + : "cc", "memory"); + return ret; + 8001e3: 8b 45 ec mov -0x14(%ebp),%eax +} + 8001e6: 83 c4 20 add $0x20,%esp + 8001e9: 5b pop %ebx + 8001ea: 5e pop %esi + 8001eb: 5f pop %edi + 8001ec: 5d pop %ebp + 8001ed: c3 ret + +008001ee : + +int +sys_exit(int error_code) { + 8001ee: 55 push %ebp + 8001ef: 89 e5 mov %esp,%ebp + 8001f1: 83 ec 08 sub $0x8,%esp + return syscall(SYS_exit, error_code); + 8001f4: 8b 45 08 mov 0x8(%ebp),%eax + 8001f7: 89 44 24 04 mov %eax,0x4(%esp) + 8001fb: c7 04 24 01 00 00 00 movl $0x1,(%esp) + 800202: e8 92 ff ff ff call 800199 +} + 800207: 89 ec mov %ebp,%esp + 800209: 5d pop %ebp + 80020a: c3 ret + +0080020b : + +int +sys_fork(void) { + 80020b: 55 push %ebp + 80020c: 89 e5 mov %esp,%ebp + 80020e: 83 ec 04 sub $0x4,%esp + return syscall(SYS_fork); + 800211: c7 04 24 02 00 00 00 movl $0x2,(%esp) + 800218: e8 7c ff ff ff call 800199 +} + 80021d: 89 ec mov %ebp,%esp + 80021f: 5d pop %ebp + 800220: c3 ret + +00800221 : + +int +sys_wait(int pid, int *store) { + 800221: 55 push %ebp + 800222: 89 e5 mov %esp,%ebp + 800224: 83 ec 0c sub $0xc,%esp + return syscall(SYS_wait, pid, store); + 800227: 8b 45 0c mov 0xc(%ebp),%eax + 80022a: 89 44 24 08 mov %eax,0x8(%esp) + 80022e: 8b 45 08 mov 0x8(%ebp),%eax + 800231: 89 44 24 04 mov %eax,0x4(%esp) + 800235: c7 04 24 03 00 00 00 movl $0x3,(%esp) + 80023c: e8 58 ff ff ff call 800199 +} + 800241: 89 ec mov %ebp,%esp + 800243: 5d pop %ebp + 800244: c3 ret + +00800245 : + +int +sys_yield(void) { + 800245: 55 push %ebp + 800246: 89 e5 mov %esp,%ebp + 800248: 83 ec 04 sub $0x4,%esp + return syscall(SYS_yield); + 80024b: c7 04 24 0a 00 00 00 movl $0xa,(%esp) + 800252: e8 42 ff ff ff call 800199 +} + 800257: 89 ec mov %ebp,%esp + 800259: 5d pop %ebp + 80025a: c3 ret + +0080025b : + +int +sys_kill(int pid) { + 80025b: 55 push %ebp + 80025c: 89 e5 mov %esp,%ebp + 80025e: 83 ec 08 sub $0x8,%esp + return syscall(SYS_kill, pid); + 800261: 8b 45 08 mov 0x8(%ebp),%eax + 800264: 89 44 24 04 mov %eax,0x4(%esp) + 800268: c7 04 24 0c 00 00 00 movl $0xc,(%esp) + 80026f: e8 25 ff ff ff call 800199 +} + 800274: 89 ec mov %ebp,%esp + 800276: 5d pop %ebp + 800277: c3 ret + +00800278 : + +int +sys_getpid(void) { + 800278: 55 push %ebp + 800279: 89 e5 mov %esp,%ebp + 80027b: 83 ec 04 sub $0x4,%esp + return syscall(SYS_getpid); + 80027e: c7 04 24 12 00 00 00 movl $0x12,(%esp) + 800285: e8 0f ff ff ff call 800199 +} + 80028a: 89 ec mov %ebp,%esp + 80028c: 5d pop %ebp + 80028d: c3 ret + +0080028e : + +int +sys_putc(int c) { + 80028e: 55 push %ebp + 80028f: 89 e5 mov %esp,%ebp + 800291: 83 ec 08 sub $0x8,%esp + return syscall(SYS_putc, c); + 800294: 8b 45 08 mov 0x8(%ebp),%eax + 800297: 89 44 24 04 mov %eax,0x4(%esp) + 80029b: c7 04 24 1e 00 00 00 movl $0x1e,(%esp) + 8002a2: e8 f2 fe ff ff call 800199 +} + 8002a7: 89 ec mov %ebp,%esp + 8002a9: 5d pop %ebp + 8002aa: c3 ret + +008002ab : + +int +sys_pgdir(void) { + 8002ab: 55 push %ebp + 8002ac: 89 e5 mov %esp,%ebp + 8002ae: 83 ec 04 sub $0x4,%esp + return syscall(SYS_pgdir); + 8002b1: c7 04 24 1f 00 00 00 movl $0x1f,(%esp) + 8002b8: e8 dc fe ff ff call 800199 +} + 8002bd: 89 ec mov %ebp,%esp + 8002bf: 5d pop %ebp + 8002c0: c3 ret + +008002c1 : +#include +#include +#include + +void +exit(int error_code) { + 8002c1: 55 push %ebp + 8002c2: 89 e5 mov %esp,%ebp + 8002c4: 83 ec 18 sub $0x18,%esp + sys_exit(error_code); + 8002c7: 8b 45 08 mov 0x8(%ebp),%eax + 8002ca: 89 04 24 mov %eax,(%esp) + 8002cd: e8 1c ff ff ff call 8001ee + cprintf("BUG: exit failed.\n"); + 8002d2: c7 04 24 98 11 80 00 movl $0x801198,(%esp) + 8002d9: e8 42 fe ff ff call 800120 + while (1); + 8002de: eb fe jmp 8002de + +008002e0 : +} + +int +fork(void) { + 8002e0: 55 push %ebp + 8002e1: 89 e5 mov %esp,%ebp + 8002e3: 83 ec 08 sub $0x8,%esp + return sys_fork(); + 8002e6: e8 20 ff ff ff call 80020b +} + 8002eb: 89 ec mov %ebp,%esp + 8002ed: 5d pop %ebp + 8002ee: c3 ret + +008002ef : + +int +wait(void) { + 8002ef: 55 push %ebp + 8002f0: 89 e5 mov %esp,%ebp + 8002f2: 83 ec 18 sub $0x18,%esp + return sys_wait(0, NULL); + 8002f5: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) + 8002fc: 00 + 8002fd: c7 04 24 00 00 00 00 movl $0x0,(%esp) + 800304: e8 18 ff ff ff call 800221 +} + 800309: 89 ec mov %ebp,%esp + 80030b: 5d pop %ebp + 80030c: c3 ret + +0080030d : + +int +waitpid(int pid, int *store) { + 80030d: 55 push %ebp + 80030e: 89 e5 mov %esp,%ebp + 800310: 83 ec 18 sub $0x18,%esp + return sys_wait(pid, store); + 800313: 8b 45 0c mov 0xc(%ebp),%eax + 800316: 89 44 24 04 mov %eax,0x4(%esp) + 80031a: 8b 45 08 mov 0x8(%ebp),%eax + 80031d: 89 04 24 mov %eax,(%esp) + 800320: e8 fc fe ff ff call 800221 +} + 800325: 89 ec mov %ebp,%esp + 800327: 5d pop %ebp + 800328: c3 ret + +00800329 : + +void +yield(void) { + 800329: 55 push %ebp + 80032a: 89 e5 mov %esp,%ebp + 80032c: 83 ec 08 sub $0x8,%esp + sys_yield(); + 80032f: e8 11 ff ff ff call 800245 +} + 800334: 90 nop + 800335: 89 ec mov %ebp,%esp + 800337: 5d pop %ebp + 800338: c3 ret + +00800339 : + +int +kill(int pid) { + 800339: 55 push %ebp + 80033a: 89 e5 mov %esp,%ebp + 80033c: 83 ec 18 sub $0x18,%esp + return sys_kill(pid); + 80033f: 8b 45 08 mov 0x8(%ebp),%eax + 800342: 89 04 24 mov %eax,(%esp) + 800345: e8 11 ff ff ff call 80025b +} + 80034a: 89 ec mov %ebp,%esp + 80034c: 5d pop %ebp + 80034d: c3 ret + +0080034e : + +int +getpid(void) { + 80034e: 55 push %ebp + 80034f: 89 e5 mov %esp,%ebp + 800351: 83 ec 08 sub $0x8,%esp + return sys_getpid(); + 800354: e8 1f ff ff ff call 800278 +} + 800359: 89 ec mov %ebp,%esp + 80035b: 5d pop %ebp + 80035c: c3 ret + +0080035d : + +//print_pgdir - print the PDT&PT +void +print_pgdir(void) { + 80035d: 55 push %ebp + 80035e: 89 e5 mov %esp,%ebp + 800360: 83 ec 08 sub $0x8,%esp + sys_pgdir(); + 800363: e8 43 ff ff ff call 8002ab +} + 800368: 90 nop + 800369: 89 ec mov %ebp,%esp + 80036b: 5d pop %ebp + 80036c: c3 ret + +0080036d : +#include + +int main(void); + +void +umain(void) { + 80036d: 55 push %ebp + 80036e: 89 e5 mov %esp,%ebp + 800370: 83 ec 28 sub $0x28,%esp + int ret = main(); + 800373: e8 e2 0c 00 00 call 80105a
+ 800378: 89 45 f4 mov %eax,-0xc(%ebp) + exit(ret); + 80037b: 8b 45 f4 mov -0xc(%ebp),%eax + 80037e: 89 04 24 mov %eax,(%esp) + 800381: e8 3b ff ff ff call 8002c1 + +00800386 : + * @bits: the number of bits in a return value + * + * High bits are more random, so we use them. + * */ +uint32_t +hash32(uint32_t val, unsigned int bits) { + 800386: 55 push %ebp + 800387: 89 e5 mov %esp,%ebp + 800389: 83 ec 10 sub $0x10,%esp + uint32_t hash = val * GOLDEN_RATIO_PRIME_32; + 80038c: 8b 45 08 mov 0x8(%ebp),%eax + 80038f: 69 c0 01 00 37 9e imul $0x9e370001,%eax,%eax + 800395: 89 45 fc mov %eax,-0x4(%ebp) + return (hash >> (32 - bits)); + 800398: b8 20 00 00 00 mov $0x20,%eax + 80039d: 2b 45 0c sub 0xc(%ebp),%eax + 8003a0: 8b 55 fc mov -0x4(%ebp),%edx + 8003a3: 88 c1 mov %al,%cl + 8003a5: d3 ea shr %cl,%edx + 8003a7: 89 d0 mov %edx,%eax +} + 8003a9: 89 ec mov %ebp,%esp + 8003ab: 5d pop %ebp + 8003ac: c3 ret + +008003ad : + * @width: maximum number of digits, if the actual width is less than @width, use @padc instead + * @padc: character that padded on the left if the actual width is less than @width + * */ +static void +printnum(void (*putch)(int, void*), void *putdat, + unsigned long long num, unsigned base, int width, int padc) { + 8003ad: 55 push %ebp + 8003ae: 89 e5 mov %esp,%ebp + 8003b0: 83 ec 58 sub $0x58,%esp + 8003b3: 8b 45 10 mov 0x10(%ebp),%eax + 8003b6: 89 45 d0 mov %eax,-0x30(%ebp) + 8003b9: 8b 45 14 mov 0x14(%ebp),%eax + 8003bc: 89 45 d4 mov %eax,-0x2c(%ebp) + unsigned long long result = num; + 8003bf: 8b 45 d0 mov -0x30(%ebp),%eax + 8003c2: 8b 55 d4 mov -0x2c(%ebp),%edx + 8003c5: 89 45 e8 mov %eax,-0x18(%ebp) + 8003c8: 89 55 ec mov %edx,-0x14(%ebp) + unsigned mod = do_div(result, base); + 8003cb: 8b 45 18 mov 0x18(%ebp),%eax + 8003ce: 89 45 e4 mov %eax,-0x1c(%ebp) + 8003d1: 8b 45 e8 mov -0x18(%ebp),%eax + 8003d4: 8b 55 ec mov -0x14(%ebp),%edx + 8003d7: 89 45 e0 mov %eax,-0x20(%ebp) + 8003da: 89 55 f0 mov %edx,-0x10(%ebp) + 8003dd: 8b 45 f0 mov -0x10(%ebp),%eax + 8003e0: 89 45 f4 mov %eax,-0xc(%ebp) + 8003e3: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) + 8003e7: 74 1c je 800405 + 8003e9: 8b 45 f0 mov -0x10(%ebp),%eax + 8003ec: ba 00 00 00 00 mov $0x0,%edx + 8003f1: f7 75 e4 divl -0x1c(%ebp) + 8003f4: 89 55 f4 mov %edx,-0xc(%ebp) + 8003f7: 8b 45 f0 mov -0x10(%ebp),%eax + 8003fa: ba 00 00 00 00 mov $0x0,%edx + 8003ff: f7 75 e4 divl -0x1c(%ebp) + 800402: 89 45 f0 mov %eax,-0x10(%ebp) + 800405: 8b 45 e0 mov -0x20(%ebp),%eax + 800408: 8b 55 f4 mov -0xc(%ebp),%edx + 80040b: f7 75 e4 divl -0x1c(%ebp) + 80040e: 89 45 e0 mov %eax,-0x20(%ebp) + 800411: 89 55 dc mov %edx,-0x24(%ebp) + 800414: 8b 45 e0 mov -0x20(%ebp),%eax + 800417: 8b 55 f0 mov -0x10(%ebp),%edx + 80041a: 89 45 e8 mov %eax,-0x18(%ebp) + 80041d: 89 55 ec mov %edx,-0x14(%ebp) + 800420: 8b 45 dc mov -0x24(%ebp),%eax + 800423: 89 45 d8 mov %eax,-0x28(%ebp) + + // first recursively print all preceding (more significant) digits + if (num >= base) { + 800426: 8b 45 18 mov 0x18(%ebp),%eax + 800429: ba 00 00 00 00 mov $0x0,%edx + 80042e: 8b 4d d4 mov -0x2c(%ebp),%ecx + 800431: 39 45 d0 cmp %eax,-0x30(%ebp) + 800434: 19 d1 sbb %edx,%ecx + 800436: 72 4c jb 800484 + printnum(putch, putdat, result, base, width - 1, padc); + 800438: 8b 45 1c mov 0x1c(%ebp),%eax + 80043b: 8d 50 ff lea -0x1(%eax),%edx + 80043e: 8b 45 20 mov 0x20(%ebp),%eax + 800441: 89 44 24 18 mov %eax,0x18(%esp) + 800445: 89 54 24 14 mov %edx,0x14(%esp) + 800449: 8b 45 18 mov 0x18(%ebp),%eax + 80044c: 89 44 24 10 mov %eax,0x10(%esp) + 800450: 8b 45 e8 mov -0x18(%ebp),%eax + 800453: 8b 55 ec mov -0x14(%ebp),%edx + 800456: 89 44 24 08 mov %eax,0x8(%esp) + 80045a: 89 54 24 0c mov %edx,0xc(%esp) + 80045e: 8b 45 0c mov 0xc(%ebp),%eax + 800461: 89 44 24 04 mov %eax,0x4(%esp) + 800465: 8b 45 08 mov 0x8(%ebp),%eax + 800468: 89 04 24 mov %eax,(%esp) + 80046b: e8 3d ff ff ff call 8003ad + 800470: eb 1b jmp 80048d + } else { + // print any needed pad characters before first digit + while (-- width > 0) + putch(padc, putdat); + 800472: 8b 45 0c mov 0xc(%ebp),%eax + 800475: 89 44 24 04 mov %eax,0x4(%esp) + 800479: 8b 45 20 mov 0x20(%ebp),%eax + 80047c: 89 04 24 mov %eax,(%esp) + 80047f: 8b 45 08 mov 0x8(%ebp),%eax + 800482: ff d0 call *%eax + while (-- width > 0) + 800484: ff 4d 1c decl 0x1c(%ebp) + 800487: 83 7d 1c 00 cmpl $0x0,0x1c(%ebp) + 80048b: 7f e5 jg 800472 + } + // then print this (the least significant) digit + putch("0123456789abcdef"[mod], putdat); + 80048d: 8b 45 d8 mov -0x28(%ebp),%eax + 800490: 05 c4 12 80 00 add $0x8012c4,%eax + 800495: 0f b6 00 movzbl (%eax),%eax + 800498: 0f be c0 movsbl %al,%eax + 80049b: 8b 55 0c mov 0xc(%ebp),%edx + 80049e: 89 54 24 04 mov %edx,0x4(%esp) + 8004a2: 89 04 24 mov %eax,(%esp) + 8004a5: 8b 45 08 mov 0x8(%ebp),%eax + 8004a8: ff d0 call *%eax +} + 8004aa: 90 nop + 8004ab: 89 ec mov %ebp,%esp + 8004ad: 5d pop %ebp + 8004ae: c3 ret + +008004af : + * getuint - get an unsigned int of various possible sizes from a varargs list + * @ap: a varargs list pointer + * @lflag: determines the size of the vararg that @ap points to + * */ +static unsigned long long +getuint(va_list *ap, int lflag) { + 8004af: 55 push %ebp + 8004b0: 89 e5 mov %esp,%ebp + if (lflag >= 2) { + 8004b2: 83 7d 0c 01 cmpl $0x1,0xc(%ebp) + 8004b6: 7e 14 jle 8004cc + return va_arg(*ap, unsigned long long); + 8004b8: 8b 45 08 mov 0x8(%ebp),%eax + 8004bb: 8b 00 mov (%eax),%eax + 8004bd: 8d 48 08 lea 0x8(%eax),%ecx + 8004c0: 8b 55 08 mov 0x8(%ebp),%edx + 8004c3: 89 0a mov %ecx,(%edx) + 8004c5: 8b 50 04 mov 0x4(%eax),%edx + 8004c8: 8b 00 mov (%eax),%eax + 8004ca: eb 30 jmp 8004fc + } + else if (lflag) { + 8004cc: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) + 8004d0: 74 16 je 8004e8 + return va_arg(*ap, unsigned long); + 8004d2: 8b 45 08 mov 0x8(%ebp),%eax + 8004d5: 8b 00 mov (%eax),%eax + 8004d7: 8d 48 04 lea 0x4(%eax),%ecx + 8004da: 8b 55 08 mov 0x8(%ebp),%edx + 8004dd: 89 0a mov %ecx,(%edx) + 8004df: 8b 00 mov (%eax),%eax + 8004e1: ba 00 00 00 00 mov $0x0,%edx + 8004e6: eb 14 jmp 8004fc + } + else { + return va_arg(*ap, unsigned int); + 8004e8: 8b 45 08 mov 0x8(%ebp),%eax + 8004eb: 8b 00 mov (%eax),%eax + 8004ed: 8d 48 04 lea 0x4(%eax),%ecx + 8004f0: 8b 55 08 mov 0x8(%ebp),%edx + 8004f3: 89 0a mov %ecx,(%edx) + 8004f5: 8b 00 mov (%eax),%eax + 8004f7: ba 00 00 00 00 mov $0x0,%edx + } +} + 8004fc: 5d pop %ebp + 8004fd: c3 ret + +008004fe : + * getint - same as getuint but signed, we can't use getuint because of sign extension + * @ap: a varargs list pointer + * @lflag: determines the size of the vararg that @ap points to + * */ +static long long +getint(va_list *ap, int lflag) { + 8004fe: 55 push %ebp + 8004ff: 89 e5 mov %esp,%ebp + if (lflag >= 2) { + 800501: 83 7d 0c 01 cmpl $0x1,0xc(%ebp) + 800505: 7e 14 jle 80051b + return va_arg(*ap, long long); + 800507: 8b 45 08 mov 0x8(%ebp),%eax + 80050a: 8b 00 mov (%eax),%eax + 80050c: 8d 48 08 lea 0x8(%eax),%ecx + 80050f: 8b 55 08 mov 0x8(%ebp),%edx + 800512: 89 0a mov %ecx,(%edx) + 800514: 8b 50 04 mov 0x4(%eax),%edx + 800517: 8b 00 mov (%eax),%eax + 800519: eb 28 jmp 800543 + } + else if (lflag) { + 80051b: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) + 80051f: 74 12 je 800533 + return va_arg(*ap, long); + 800521: 8b 45 08 mov 0x8(%ebp),%eax + 800524: 8b 00 mov (%eax),%eax + 800526: 8d 48 04 lea 0x4(%eax),%ecx + 800529: 8b 55 08 mov 0x8(%ebp),%edx + 80052c: 89 0a mov %ecx,(%edx) + 80052e: 8b 00 mov (%eax),%eax + 800530: 99 cltd + 800531: eb 10 jmp 800543 + } + else { + return va_arg(*ap, int); + 800533: 8b 45 08 mov 0x8(%ebp),%eax + 800536: 8b 00 mov (%eax),%eax + 800538: 8d 48 04 lea 0x4(%eax),%ecx + 80053b: 8b 55 08 mov 0x8(%ebp),%edx + 80053e: 89 0a mov %ecx,(%edx) + 800540: 8b 00 mov (%eax),%eax + 800542: 99 cltd + } +} + 800543: 5d pop %ebp + 800544: c3 ret + +00800545 : + * @putch: specified putch function, print a single character + * @putdat: used by @putch function + * @fmt: the format string to use + * */ +void +printfmt(void (*putch)(int, void*), void *putdat, const char *fmt, ...) { + 800545: 55 push %ebp + 800546: 89 e5 mov %esp,%ebp + 800548: 83 ec 28 sub $0x28,%esp + va_list ap; + + va_start(ap, fmt); + 80054b: 8d 45 14 lea 0x14(%ebp),%eax + 80054e: 89 45 f4 mov %eax,-0xc(%ebp) + vprintfmt(putch, putdat, fmt, ap); + 800551: 8b 45 f4 mov -0xc(%ebp),%eax + 800554: 89 44 24 0c mov %eax,0xc(%esp) + 800558: 8b 45 10 mov 0x10(%ebp),%eax + 80055b: 89 44 24 08 mov %eax,0x8(%esp) + 80055f: 8b 45 0c mov 0xc(%ebp),%eax + 800562: 89 44 24 04 mov %eax,0x4(%esp) + 800566: 8b 45 08 mov 0x8(%ebp),%eax + 800569: 89 04 24 mov %eax,(%esp) + 80056c: e8 05 00 00 00 call 800576 + va_end(ap); +} + 800571: 90 nop + 800572: 89 ec mov %ebp,%esp + 800574: 5d pop %ebp + 800575: c3 ret + +00800576 : + * + * Call this function if you are already dealing with a va_list. + * Or you probably want printfmt() instead. + * */ +void +vprintfmt(void (*putch)(int, void*), void *putdat, const char *fmt, va_list ap) { + 800576: 55 push %ebp + 800577: 89 e5 mov %esp,%ebp + 800579: 56 push %esi + 80057a: 53 push %ebx + 80057b: 83 ec 40 sub $0x40,%esp + register int ch, err; + unsigned long long num; + int base, width, precision, lflag, altflag; + + while (1) { + while ((ch = *(unsigned char *)fmt ++) != '%') { + 80057e: eb 17 jmp 800597 + if (ch == '\0') { + 800580: 85 db test %ebx,%ebx + 800582: 0f 84 bf 03 00 00 je 800947 + return; + } + putch(ch, putdat); + 800588: 8b 45 0c mov 0xc(%ebp),%eax + 80058b: 89 44 24 04 mov %eax,0x4(%esp) + 80058f: 89 1c 24 mov %ebx,(%esp) + 800592: 8b 45 08 mov 0x8(%ebp),%eax + 800595: ff d0 call *%eax + while ((ch = *(unsigned char *)fmt ++) != '%') { + 800597: 8b 45 10 mov 0x10(%ebp),%eax + 80059a: 8d 50 01 lea 0x1(%eax),%edx + 80059d: 89 55 10 mov %edx,0x10(%ebp) + 8005a0: 0f b6 00 movzbl (%eax),%eax + 8005a3: 0f b6 d8 movzbl %al,%ebx + 8005a6: 83 fb 25 cmp $0x25,%ebx + 8005a9: 75 d5 jne 800580 + } + + // Process a %-escape sequence + char padc = ' '; + 8005ab: c6 45 db 20 movb $0x20,-0x25(%ebp) + width = precision = -1; + 8005af: c7 45 e4 ff ff ff ff movl $0xffffffff,-0x1c(%ebp) + 8005b6: 8b 45 e4 mov -0x1c(%ebp),%eax + 8005b9: 89 45 e8 mov %eax,-0x18(%ebp) + lflag = altflag = 0; + 8005bc: c7 45 dc 00 00 00 00 movl $0x0,-0x24(%ebp) + 8005c3: 8b 45 dc mov -0x24(%ebp),%eax + 8005c6: 89 45 e0 mov %eax,-0x20(%ebp) + + reswitch: + switch (ch = *(unsigned char *)fmt ++) { + 8005c9: 8b 45 10 mov 0x10(%ebp),%eax + 8005cc: 8d 50 01 lea 0x1(%eax),%edx + 8005cf: 89 55 10 mov %edx,0x10(%ebp) + 8005d2: 0f b6 00 movzbl (%eax),%eax + 8005d5: 0f b6 d8 movzbl %al,%ebx + 8005d8: 8d 43 dd lea -0x23(%ebx),%eax + 8005db: 83 f8 55 cmp $0x55,%eax + 8005de: 0f 87 37 03 00 00 ja 80091b + 8005e4: 8b 04 85 e8 12 80 00 mov 0x8012e8(,%eax,4),%eax + 8005eb: ff e0 jmp *%eax + + // flag to pad on the right + case '-': + padc = '-'; + 8005ed: c6 45 db 2d movb $0x2d,-0x25(%ebp) + goto reswitch; + 8005f1: eb d6 jmp 8005c9 + + // flag to pad with 0's instead of spaces + case '0': + padc = '0'; + 8005f3: c6 45 db 30 movb $0x30,-0x25(%ebp) + goto reswitch; + 8005f7: eb d0 jmp 8005c9 + + // width field + case '1' ... '9': + for (precision = 0; ; ++ fmt) { + 8005f9: c7 45 e4 00 00 00 00 movl $0x0,-0x1c(%ebp) + precision = precision * 10 + ch - '0'; + 800600: 8b 55 e4 mov -0x1c(%ebp),%edx + 800603: 89 d0 mov %edx,%eax + 800605: c1 e0 02 shl $0x2,%eax + 800608: 01 d0 add %edx,%eax + 80060a: 01 c0 add %eax,%eax + 80060c: 01 d8 add %ebx,%eax + 80060e: 83 e8 30 sub $0x30,%eax + 800611: 89 45 e4 mov %eax,-0x1c(%ebp) + ch = *fmt; + 800614: 8b 45 10 mov 0x10(%ebp),%eax + 800617: 0f b6 00 movzbl (%eax),%eax + 80061a: 0f be d8 movsbl %al,%ebx + if (ch < '0' || ch > '9') { + 80061d: 83 fb 2f cmp $0x2f,%ebx + 800620: 7e 38 jle 80065a + 800622: 83 fb 39 cmp $0x39,%ebx + 800625: 7f 33 jg 80065a + for (precision = 0; ; ++ fmt) { + 800627: ff 45 10 incl 0x10(%ebp) + precision = precision * 10 + ch - '0'; + 80062a: eb d4 jmp 800600 + } + } + goto process_precision; + + case '*': + precision = va_arg(ap, int); + 80062c: 8b 45 14 mov 0x14(%ebp),%eax + 80062f: 8d 50 04 lea 0x4(%eax),%edx + 800632: 89 55 14 mov %edx,0x14(%ebp) + 800635: 8b 00 mov (%eax),%eax + 800637: 89 45 e4 mov %eax,-0x1c(%ebp) + goto process_precision; + 80063a: eb 1f jmp 80065b + + case '.': + if (width < 0) + 80063c: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 800640: 79 87 jns 8005c9 + width = 0; + 800642: c7 45 e8 00 00 00 00 movl $0x0,-0x18(%ebp) + goto reswitch; + 800649: e9 7b ff ff ff jmp 8005c9 + + case '#': + altflag = 1; + 80064e: c7 45 dc 01 00 00 00 movl $0x1,-0x24(%ebp) + goto reswitch; + 800655: e9 6f ff ff ff jmp 8005c9 + goto process_precision; + 80065a: 90 nop + + process_precision: + if (width < 0) + 80065b: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 80065f: 0f 89 64 ff ff ff jns 8005c9 + width = precision, precision = -1; + 800665: 8b 45 e4 mov -0x1c(%ebp),%eax + 800668: 89 45 e8 mov %eax,-0x18(%ebp) + 80066b: c7 45 e4 ff ff ff ff movl $0xffffffff,-0x1c(%ebp) + goto reswitch; + 800672: e9 52 ff ff ff jmp 8005c9 + + // long flag (doubled for long long) + case 'l': + lflag ++; + 800677: ff 45 e0 incl -0x20(%ebp) + goto reswitch; + 80067a: e9 4a ff ff ff jmp 8005c9 + + // character + case 'c': + putch(va_arg(ap, int), putdat); + 80067f: 8b 45 14 mov 0x14(%ebp),%eax + 800682: 8d 50 04 lea 0x4(%eax),%edx + 800685: 89 55 14 mov %edx,0x14(%ebp) + 800688: 8b 00 mov (%eax),%eax + 80068a: 8b 55 0c mov 0xc(%ebp),%edx + 80068d: 89 54 24 04 mov %edx,0x4(%esp) + 800691: 89 04 24 mov %eax,(%esp) + 800694: 8b 45 08 mov 0x8(%ebp),%eax + 800697: ff d0 call *%eax + break; + 800699: e9 a4 02 00 00 jmp 800942 + + // error message + case 'e': + err = va_arg(ap, int); + 80069e: 8b 45 14 mov 0x14(%ebp),%eax + 8006a1: 8d 50 04 lea 0x4(%eax),%edx + 8006a4: 89 55 14 mov %edx,0x14(%ebp) + 8006a7: 8b 18 mov (%eax),%ebx + if (err < 0) { + 8006a9: 85 db test %ebx,%ebx + 8006ab: 79 02 jns 8006af + err = -err; + 8006ad: f7 db neg %ebx + } + if (err > MAXERROR || (p = error_string[err]) == NULL) { + 8006af: 83 fb 18 cmp $0x18,%ebx + 8006b2: 7f 0b jg 8006bf + 8006b4: 8b 34 9d 60 12 80 00 mov 0x801260(,%ebx,4),%esi + 8006bb: 85 f6 test %esi,%esi + 8006bd: 75 23 jne 8006e2 + printfmt(putch, putdat, "error %d", err); + 8006bf: 89 5c 24 0c mov %ebx,0xc(%esp) + 8006c3: c7 44 24 08 d5 12 80 movl $0x8012d5,0x8(%esp) + 8006ca: 00 + 8006cb: 8b 45 0c mov 0xc(%ebp),%eax + 8006ce: 89 44 24 04 mov %eax,0x4(%esp) + 8006d2: 8b 45 08 mov 0x8(%ebp),%eax + 8006d5: 89 04 24 mov %eax,(%esp) + 8006d8: e8 68 fe ff ff call 800545 + } + else { + printfmt(putch, putdat, "%s", p); + } + break; + 8006dd: e9 60 02 00 00 jmp 800942 + printfmt(putch, putdat, "%s", p); + 8006e2: 89 74 24 0c mov %esi,0xc(%esp) + 8006e6: c7 44 24 08 de 12 80 movl $0x8012de,0x8(%esp) + 8006ed: 00 + 8006ee: 8b 45 0c mov 0xc(%ebp),%eax + 8006f1: 89 44 24 04 mov %eax,0x4(%esp) + 8006f5: 8b 45 08 mov 0x8(%ebp),%eax + 8006f8: 89 04 24 mov %eax,(%esp) + 8006fb: e8 45 fe ff ff call 800545 + break; + 800700: e9 3d 02 00 00 jmp 800942 + + // string + case 's': + if ((p = va_arg(ap, char *)) == NULL) { + 800705: 8b 45 14 mov 0x14(%ebp),%eax + 800708: 8d 50 04 lea 0x4(%eax),%edx + 80070b: 89 55 14 mov %edx,0x14(%ebp) + 80070e: 8b 30 mov (%eax),%esi + 800710: 85 f6 test %esi,%esi + 800712: 75 05 jne 800719 + p = "(null)"; + 800714: be e1 12 80 00 mov $0x8012e1,%esi + } + if (width > 0 && padc != '-') { + 800719: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 80071d: 7e 76 jle 800795 + 80071f: 80 7d db 2d cmpb $0x2d,-0x25(%ebp) + 800723: 74 70 je 800795 + for (width -= strnlen(p, precision); width > 0; width --) { + 800725: 8b 45 e4 mov -0x1c(%ebp),%eax + 800728: 89 44 24 04 mov %eax,0x4(%esp) + 80072c: 89 34 24 mov %esi,(%esp) + 80072f: e8 ee 03 00 00 call 800b22 + 800734: 89 c2 mov %eax,%edx + 800736: 8b 45 e8 mov -0x18(%ebp),%eax + 800739: 29 d0 sub %edx,%eax + 80073b: 89 45 e8 mov %eax,-0x18(%ebp) + 80073e: eb 16 jmp 800756 + putch(padc, putdat); + 800740: 0f be 45 db movsbl -0x25(%ebp),%eax + 800744: 8b 55 0c mov 0xc(%ebp),%edx + 800747: 89 54 24 04 mov %edx,0x4(%esp) + 80074b: 89 04 24 mov %eax,(%esp) + 80074e: 8b 45 08 mov 0x8(%ebp),%eax + 800751: ff d0 call *%eax + for (width -= strnlen(p, precision); width > 0; width --) { + 800753: ff 4d e8 decl -0x18(%ebp) + 800756: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 80075a: 7f e4 jg 800740 + } + } + for (; (ch = *p ++) != '\0' && (precision < 0 || -- precision >= 0); width --) { + 80075c: eb 37 jmp 800795 + if (altflag && (ch < ' ' || ch > '~')) { + 80075e: 83 7d dc 00 cmpl $0x0,-0x24(%ebp) + 800762: 74 1f je 800783 + 800764: 83 fb 1f cmp $0x1f,%ebx + 800767: 7e 05 jle 80076e + 800769: 83 fb 7e cmp $0x7e,%ebx + 80076c: 7e 15 jle 800783 + putch('?', putdat); + 80076e: 8b 45 0c mov 0xc(%ebp),%eax + 800771: 89 44 24 04 mov %eax,0x4(%esp) + 800775: c7 04 24 3f 00 00 00 movl $0x3f,(%esp) + 80077c: 8b 45 08 mov 0x8(%ebp),%eax + 80077f: ff d0 call *%eax + 800781: eb 0f jmp 800792 + } + else { + putch(ch, putdat); + 800783: 8b 45 0c mov 0xc(%ebp),%eax + 800786: 89 44 24 04 mov %eax,0x4(%esp) + 80078a: 89 1c 24 mov %ebx,(%esp) + 80078d: 8b 45 08 mov 0x8(%ebp),%eax + 800790: ff d0 call *%eax + for (; (ch = *p ++) != '\0' && (precision < 0 || -- precision >= 0); width --) { + 800792: ff 4d e8 decl -0x18(%ebp) + 800795: 89 f0 mov %esi,%eax + 800797: 8d 70 01 lea 0x1(%eax),%esi + 80079a: 0f b6 00 movzbl (%eax),%eax + 80079d: 0f be d8 movsbl %al,%ebx + 8007a0: 85 db test %ebx,%ebx + 8007a2: 74 27 je 8007cb + 8007a4: 83 7d e4 00 cmpl $0x0,-0x1c(%ebp) + 8007a8: 78 b4 js 80075e + 8007aa: ff 4d e4 decl -0x1c(%ebp) + 8007ad: 83 7d e4 00 cmpl $0x0,-0x1c(%ebp) + 8007b1: 79 ab jns 80075e + } + } + for (; width > 0; width --) { + 8007b3: eb 16 jmp 8007cb + putch(' ', putdat); + 8007b5: 8b 45 0c mov 0xc(%ebp),%eax + 8007b8: 89 44 24 04 mov %eax,0x4(%esp) + 8007bc: c7 04 24 20 00 00 00 movl $0x20,(%esp) + 8007c3: 8b 45 08 mov 0x8(%ebp),%eax + 8007c6: ff d0 call *%eax + for (; width > 0; width --) { + 8007c8: ff 4d e8 decl -0x18(%ebp) + 8007cb: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 8007cf: 7f e4 jg 8007b5 + } + break; + 8007d1: e9 6c 01 00 00 jmp 800942 + + // (signed) decimal + case 'd': + num = getint(&ap, lflag); + 8007d6: 8b 45 e0 mov -0x20(%ebp),%eax + 8007d9: 89 44 24 04 mov %eax,0x4(%esp) + 8007dd: 8d 45 14 lea 0x14(%ebp),%eax + 8007e0: 89 04 24 mov %eax,(%esp) + 8007e3: e8 16 fd ff ff call 8004fe + 8007e8: 89 45 f0 mov %eax,-0x10(%ebp) + 8007eb: 89 55 f4 mov %edx,-0xc(%ebp) + if ((long long)num < 0) { + 8007ee: 8b 45 f0 mov -0x10(%ebp),%eax + 8007f1: 8b 55 f4 mov -0xc(%ebp),%edx + 8007f4: 85 d2 test %edx,%edx + 8007f6: 79 26 jns 80081e + putch('-', putdat); + 8007f8: 8b 45 0c mov 0xc(%ebp),%eax + 8007fb: 89 44 24 04 mov %eax,0x4(%esp) + 8007ff: c7 04 24 2d 00 00 00 movl $0x2d,(%esp) + 800806: 8b 45 08 mov 0x8(%ebp),%eax + 800809: ff d0 call *%eax + num = -(long long)num; + 80080b: 8b 45 f0 mov -0x10(%ebp),%eax + 80080e: 8b 55 f4 mov -0xc(%ebp),%edx + 800811: f7 d8 neg %eax + 800813: 83 d2 00 adc $0x0,%edx + 800816: f7 da neg %edx + 800818: 89 45 f0 mov %eax,-0x10(%ebp) + 80081b: 89 55 f4 mov %edx,-0xc(%ebp) + } + base = 10; + 80081e: c7 45 ec 0a 00 00 00 movl $0xa,-0x14(%ebp) + goto number; + 800825: e9 a8 00 00 00 jmp 8008d2 + + // unsigned decimal + case 'u': + num = getuint(&ap, lflag); + 80082a: 8b 45 e0 mov -0x20(%ebp),%eax + 80082d: 89 44 24 04 mov %eax,0x4(%esp) + 800831: 8d 45 14 lea 0x14(%ebp),%eax + 800834: 89 04 24 mov %eax,(%esp) + 800837: e8 73 fc ff ff call 8004af + 80083c: 89 45 f0 mov %eax,-0x10(%ebp) + 80083f: 89 55 f4 mov %edx,-0xc(%ebp) + base = 10; + 800842: c7 45 ec 0a 00 00 00 movl $0xa,-0x14(%ebp) + goto number; + 800849: e9 84 00 00 00 jmp 8008d2 + + // (unsigned) octal + case 'o': + num = getuint(&ap, lflag); + 80084e: 8b 45 e0 mov -0x20(%ebp),%eax + 800851: 89 44 24 04 mov %eax,0x4(%esp) + 800855: 8d 45 14 lea 0x14(%ebp),%eax + 800858: 89 04 24 mov %eax,(%esp) + 80085b: e8 4f fc ff ff call 8004af + 800860: 89 45 f0 mov %eax,-0x10(%ebp) + 800863: 89 55 f4 mov %edx,-0xc(%ebp) + base = 8; + 800866: c7 45 ec 08 00 00 00 movl $0x8,-0x14(%ebp) + goto number; + 80086d: eb 63 jmp 8008d2 + + // pointer + case 'p': + putch('0', putdat); + 80086f: 8b 45 0c mov 0xc(%ebp),%eax + 800872: 89 44 24 04 mov %eax,0x4(%esp) + 800876: c7 04 24 30 00 00 00 movl $0x30,(%esp) + 80087d: 8b 45 08 mov 0x8(%ebp),%eax + 800880: ff d0 call *%eax + putch('x', putdat); + 800882: 8b 45 0c mov 0xc(%ebp),%eax + 800885: 89 44 24 04 mov %eax,0x4(%esp) + 800889: c7 04 24 78 00 00 00 movl $0x78,(%esp) + 800890: 8b 45 08 mov 0x8(%ebp),%eax + 800893: ff d0 call *%eax + num = (unsigned long long)(uintptr_t)va_arg(ap, void *); + 800895: 8b 45 14 mov 0x14(%ebp),%eax + 800898: 8d 50 04 lea 0x4(%eax),%edx + 80089b: 89 55 14 mov %edx,0x14(%ebp) + 80089e: 8b 00 mov (%eax),%eax + 8008a0: 89 45 f0 mov %eax,-0x10(%ebp) + 8008a3: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + base = 16; + 8008aa: c7 45 ec 10 00 00 00 movl $0x10,-0x14(%ebp) + goto number; + 8008b1: eb 1f jmp 8008d2 + + // (unsigned) hexadecimal + case 'x': + num = getuint(&ap, lflag); + 8008b3: 8b 45 e0 mov -0x20(%ebp),%eax + 8008b6: 89 44 24 04 mov %eax,0x4(%esp) + 8008ba: 8d 45 14 lea 0x14(%ebp),%eax + 8008bd: 89 04 24 mov %eax,(%esp) + 8008c0: e8 ea fb ff ff call 8004af + 8008c5: 89 45 f0 mov %eax,-0x10(%ebp) + 8008c8: 89 55 f4 mov %edx,-0xc(%ebp) + base = 16; + 8008cb: c7 45 ec 10 00 00 00 movl $0x10,-0x14(%ebp) + number: + printnum(putch, putdat, num, base, width, padc); + 8008d2: 0f be 55 db movsbl -0x25(%ebp),%edx + 8008d6: 8b 45 ec mov -0x14(%ebp),%eax + 8008d9: 89 54 24 18 mov %edx,0x18(%esp) + 8008dd: 8b 55 e8 mov -0x18(%ebp),%edx + 8008e0: 89 54 24 14 mov %edx,0x14(%esp) + 8008e4: 89 44 24 10 mov %eax,0x10(%esp) + 8008e8: 8b 45 f0 mov -0x10(%ebp),%eax + 8008eb: 8b 55 f4 mov -0xc(%ebp),%edx + 8008ee: 89 44 24 08 mov %eax,0x8(%esp) + 8008f2: 89 54 24 0c mov %edx,0xc(%esp) + 8008f6: 8b 45 0c mov 0xc(%ebp),%eax + 8008f9: 89 44 24 04 mov %eax,0x4(%esp) + 8008fd: 8b 45 08 mov 0x8(%ebp),%eax + 800900: 89 04 24 mov %eax,(%esp) + 800903: e8 a5 fa ff ff call 8003ad + break; + 800908: eb 38 jmp 800942 + + // escaped '%' character + case '%': + putch(ch, putdat); + 80090a: 8b 45 0c mov 0xc(%ebp),%eax + 80090d: 89 44 24 04 mov %eax,0x4(%esp) + 800911: 89 1c 24 mov %ebx,(%esp) + 800914: 8b 45 08 mov 0x8(%ebp),%eax + 800917: ff d0 call *%eax + break; + 800919: eb 27 jmp 800942 + + // unrecognized escape sequence - just print it literally + default: + putch('%', putdat); + 80091b: 8b 45 0c mov 0xc(%ebp),%eax + 80091e: 89 44 24 04 mov %eax,0x4(%esp) + 800922: c7 04 24 25 00 00 00 movl $0x25,(%esp) + 800929: 8b 45 08 mov 0x8(%ebp),%eax + 80092c: ff d0 call *%eax + for (fmt --; fmt[-1] != '%'; fmt --) + 80092e: ff 4d 10 decl 0x10(%ebp) + 800931: eb 03 jmp 800936 + 800933: ff 4d 10 decl 0x10(%ebp) + 800936: 8b 45 10 mov 0x10(%ebp),%eax + 800939: 48 dec %eax + 80093a: 0f b6 00 movzbl (%eax),%eax + 80093d: 3c 25 cmp $0x25,%al + 80093f: 75 f2 jne 800933 + /* do nothing */; + break; + 800941: 90 nop + while (1) { + 800942: e9 37 fc ff ff jmp 80057e + return; + 800947: 90 nop + } + } +} + 800948: 83 c4 40 add $0x40,%esp + 80094b: 5b pop %ebx + 80094c: 5e pop %esi + 80094d: 5d pop %ebp + 80094e: c3 ret + +0080094f : + * sprintputch - 'print' a single character in a buffer + * @ch: the character will be printed + * @b: the buffer to place the character @ch + * */ +static void +sprintputch(int ch, struct sprintbuf *b) { + 80094f: 55 push %ebp + 800950: 89 e5 mov %esp,%ebp + b->cnt ++; + 800952: 8b 45 0c mov 0xc(%ebp),%eax + 800955: 8b 40 08 mov 0x8(%eax),%eax + 800958: 8d 50 01 lea 0x1(%eax),%edx + 80095b: 8b 45 0c mov 0xc(%ebp),%eax + 80095e: 89 50 08 mov %edx,0x8(%eax) + if (b->buf < b->ebuf) { + 800961: 8b 45 0c mov 0xc(%ebp),%eax + 800964: 8b 10 mov (%eax),%edx + 800966: 8b 45 0c mov 0xc(%ebp),%eax + 800969: 8b 40 04 mov 0x4(%eax),%eax + 80096c: 39 c2 cmp %eax,%edx + 80096e: 73 12 jae 800982 + *b->buf ++ = ch; + 800970: 8b 45 0c mov 0xc(%ebp),%eax + 800973: 8b 00 mov (%eax),%eax + 800975: 8d 48 01 lea 0x1(%eax),%ecx + 800978: 8b 55 0c mov 0xc(%ebp),%edx + 80097b: 89 0a mov %ecx,(%edx) + 80097d: 8b 55 08 mov 0x8(%ebp),%edx + 800980: 88 10 mov %dl,(%eax) + } +} + 800982: 90 nop + 800983: 5d pop %ebp + 800984: c3 ret + +00800985 : + * @str: the buffer to place the result into + * @size: the size of buffer, including the trailing null space + * @fmt: the format string to use + * */ +int +snprintf(char *str, size_t size, const char *fmt, ...) { + 800985: 55 push %ebp + 800986: 89 e5 mov %esp,%ebp + 800988: 83 ec 28 sub $0x28,%esp + va_list ap; + int cnt; + va_start(ap, fmt); + 80098b: 8d 45 14 lea 0x14(%ebp),%eax + 80098e: 89 45 f0 mov %eax,-0x10(%ebp) + cnt = vsnprintf(str, size, fmt, ap); + 800991: 8b 45 f0 mov -0x10(%ebp),%eax + 800994: 89 44 24 0c mov %eax,0xc(%esp) + 800998: 8b 45 10 mov 0x10(%ebp),%eax + 80099b: 89 44 24 08 mov %eax,0x8(%esp) + 80099f: 8b 45 0c mov 0xc(%ebp),%eax + 8009a2: 89 44 24 04 mov %eax,0x4(%esp) + 8009a6: 8b 45 08 mov 0x8(%ebp),%eax + 8009a9: 89 04 24 mov %eax,(%esp) + 8009ac: e8 0a 00 00 00 call 8009bb + 8009b1: 89 45 f4 mov %eax,-0xc(%ebp) + va_end(ap); + return cnt; + 8009b4: 8b 45 f4 mov -0xc(%ebp),%eax +} + 8009b7: 89 ec mov %ebp,%esp + 8009b9: 5d pop %ebp + 8009ba: c3 ret + +008009bb : + * + * Call this function if you are already dealing with a va_list. + * Or you probably want snprintf() instead. + * */ +int +vsnprintf(char *str, size_t size, const char *fmt, va_list ap) { + 8009bb: 55 push %ebp + 8009bc: 89 e5 mov %esp,%ebp + 8009be: 83 ec 28 sub $0x28,%esp + struct sprintbuf b = {str, str + size - 1, 0}; + 8009c1: 8b 45 08 mov 0x8(%ebp),%eax + 8009c4: 89 45 ec mov %eax,-0x14(%ebp) + 8009c7: 8b 45 0c mov 0xc(%ebp),%eax + 8009ca: 8d 50 ff lea -0x1(%eax),%edx + 8009cd: 8b 45 08 mov 0x8(%ebp),%eax + 8009d0: 01 d0 add %edx,%eax + 8009d2: 89 45 f0 mov %eax,-0x10(%ebp) + 8009d5: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + if (str == NULL || b.buf > b.ebuf) { + 8009dc: 83 7d 08 00 cmpl $0x0,0x8(%ebp) + 8009e0: 74 0a je 8009ec + 8009e2: 8b 55 ec mov -0x14(%ebp),%edx + 8009e5: 8b 45 f0 mov -0x10(%ebp),%eax + 8009e8: 39 c2 cmp %eax,%edx + 8009ea: 76 07 jbe 8009f3 + return -E_INVAL; + 8009ec: b8 fd ff ff ff mov $0xfffffffd,%eax + 8009f1: eb 2a jmp 800a1d + } + // print the string to the buffer + vprintfmt((void*)sprintputch, &b, fmt, ap); + 8009f3: 8b 45 14 mov 0x14(%ebp),%eax + 8009f6: 89 44 24 0c mov %eax,0xc(%esp) + 8009fa: 8b 45 10 mov 0x10(%ebp),%eax + 8009fd: 89 44 24 08 mov %eax,0x8(%esp) + 800a01: 8d 45 ec lea -0x14(%ebp),%eax + 800a04: 89 44 24 04 mov %eax,0x4(%esp) + 800a08: c7 04 24 4f 09 80 00 movl $0x80094f,(%esp) + 800a0f: e8 62 fb ff ff call 800576 + // null terminate the buffer + *b.buf = '\0'; + 800a14: 8b 45 ec mov -0x14(%ebp),%eax + 800a17: c6 00 00 movb $0x0,(%eax) + return b.cnt; + 800a1a: 8b 45 f4 mov -0xc(%ebp),%eax +} + 800a1d: 89 ec mov %ebp,%esp + 800a1f: 5d pop %ebp + 800a20: c3 ret + +00800a21 : + * rand - returns a pseudo-random integer + * + * The rand() function return a value in the range [0, RAND_MAX]. + * */ +int +rand(void) { + 800a21: 55 push %ebp + 800a22: 89 e5 mov %esp,%ebp + 800a24: 57 push %edi + 800a25: 56 push %esi + 800a26: 53 push %ebx + 800a27: 83 ec 24 sub $0x24,%esp + next = (next * 0x5DEECE66DLL + 0xBLL) & ((1LL << 48) - 1); + 800a2a: a1 00 20 80 00 mov 0x802000,%eax + 800a2f: 8b 15 04 20 80 00 mov 0x802004,%edx + 800a35: 69 fa 6d e6 ec de imul $0xdeece66d,%edx,%edi + 800a3b: 6b f0 05 imul $0x5,%eax,%esi + 800a3e: 01 fe add %edi,%esi + 800a40: bf 6d e6 ec de mov $0xdeece66d,%edi + 800a45: f7 e7 mul %edi + 800a47: 01 d6 add %edx,%esi + 800a49: 89 f2 mov %esi,%edx + 800a4b: 83 c0 0b add $0xb,%eax + 800a4e: 83 d2 00 adc $0x0,%edx + 800a51: 89 c7 mov %eax,%edi + 800a53: 83 e7 ff and $0xffffffff,%edi + 800a56: 89 f9 mov %edi,%ecx + 800a58: 0f b7 da movzwl %dx,%ebx + 800a5b: 89 0d 00 20 80 00 mov %ecx,0x802000 + 800a61: 89 1d 04 20 80 00 mov %ebx,0x802004 + unsigned long long result = (next >> 12); + 800a67: a1 00 20 80 00 mov 0x802000,%eax + 800a6c: 8b 15 04 20 80 00 mov 0x802004,%edx + 800a72: 0f ac d0 0c shrd $0xc,%edx,%eax + 800a76: c1 ea 0c shr $0xc,%edx + 800a79: 89 45 e0 mov %eax,-0x20(%ebp) + 800a7c: 89 55 e4 mov %edx,-0x1c(%ebp) + return (int)do_div(result, RAND_MAX + 1); + 800a7f: c7 45 dc 00 00 00 80 movl $0x80000000,-0x24(%ebp) + 800a86: 8b 45 e0 mov -0x20(%ebp),%eax + 800a89: 8b 55 e4 mov -0x1c(%ebp),%edx + 800a8c: 89 45 d8 mov %eax,-0x28(%ebp) + 800a8f: 89 55 e8 mov %edx,-0x18(%ebp) + 800a92: 8b 45 e8 mov -0x18(%ebp),%eax + 800a95: 89 45 ec mov %eax,-0x14(%ebp) + 800a98: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 800a9c: 74 1c je 800aba + 800a9e: 8b 45 e8 mov -0x18(%ebp),%eax + 800aa1: ba 00 00 00 00 mov $0x0,%edx + 800aa6: f7 75 dc divl -0x24(%ebp) + 800aa9: 89 55 ec mov %edx,-0x14(%ebp) + 800aac: 8b 45 e8 mov -0x18(%ebp),%eax + 800aaf: ba 00 00 00 00 mov $0x0,%edx + 800ab4: f7 75 dc divl -0x24(%ebp) + 800ab7: 89 45 e8 mov %eax,-0x18(%ebp) + 800aba: 8b 45 d8 mov -0x28(%ebp),%eax + 800abd: 8b 55 ec mov -0x14(%ebp),%edx + 800ac0: f7 75 dc divl -0x24(%ebp) + 800ac3: 89 45 d8 mov %eax,-0x28(%ebp) + 800ac6: 89 55 d4 mov %edx,-0x2c(%ebp) + 800ac9: 8b 45 d8 mov -0x28(%ebp),%eax + 800acc: 8b 55 e8 mov -0x18(%ebp),%edx + 800acf: 89 45 e0 mov %eax,-0x20(%ebp) + 800ad2: 89 55 e4 mov %edx,-0x1c(%ebp) + 800ad5: 8b 45 d4 mov -0x2c(%ebp),%eax +} + 800ad8: 83 c4 24 add $0x24,%esp + 800adb: 5b pop %ebx + 800adc: 5e pop %esi + 800add: 5f pop %edi + 800ade: 5d pop %ebp + 800adf: c3 ret + +00800ae0 : +/* * + * srand - seed the random number generator with the given number + * @seed: the required seed number + * */ +void +srand(unsigned int seed) { + 800ae0: 55 push %ebp + 800ae1: 89 e5 mov %esp,%ebp + next = seed; + 800ae3: 8b 45 08 mov 0x8(%ebp),%eax + 800ae6: ba 00 00 00 00 mov $0x0,%edx + 800aeb: a3 00 20 80 00 mov %eax,0x802000 + 800af0: 89 15 04 20 80 00 mov %edx,0x802004 +} + 800af6: 90 nop + 800af7: 5d pop %ebp + 800af8: c3 ret + +00800af9 : + * @s: the input string + * + * The strlen() function returns the length of string @s. + * */ +size_t +strlen(const char *s) { + 800af9: 55 push %ebp + 800afa: 89 e5 mov %esp,%ebp + 800afc: 83 ec 10 sub $0x10,%esp + size_t cnt = 0; + 800aff: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + while (*s ++ != '\0') { + 800b06: eb 03 jmp 800b0b + cnt ++; + 800b08: ff 45 fc incl -0x4(%ebp) + while (*s ++ != '\0') { + 800b0b: 8b 45 08 mov 0x8(%ebp),%eax + 800b0e: 8d 50 01 lea 0x1(%eax),%edx + 800b11: 89 55 08 mov %edx,0x8(%ebp) + 800b14: 0f b6 00 movzbl (%eax),%eax + 800b17: 84 c0 test %al,%al + 800b19: 75 ed jne 800b08 + } + return cnt; + 800b1b: 8b 45 fc mov -0x4(%ebp),%eax +} + 800b1e: 89 ec mov %ebp,%esp + 800b20: 5d pop %ebp + 800b21: c3 ret + +00800b22 : + * The return value is strlen(s), if that is less than @len, or + * @len if there is no '\0' character among the first @len characters + * pointed by @s. + * */ +size_t +strnlen(const char *s, size_t len) { + 800b22: 55 push %ebp + 800b23: 89 e5 mov %esp,%ebp + 800b25: 83 ec 10 sub $0x10,%esp + size_t cnt = 0; + 800b28: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + while (cnt < len && *s ++ != '\0') { + 800b2f: eb 03 jmp 800b34 + cnt ++; + 800b31: ff 45 fc incl -0x4(%ebp) + while (cnt < len && *s ++ != '\0') { + 800b34: 8b 45 fc mov -0x4(%ebp),%eax + 800b37: 3b 45 0c cmp 0xc(%ebp),%eax + 800b3a: 73 10 jae 800b4c + 800b3c: 8b 45 08 mov 0x8(%ebp),%eax + 800b3f: 8d 50 01 lea 0x1(%eax),%edx + 800b42: 89 55 08 mov %edx,0x8(%ebp) + 800b45: 0f b6 00 movzbl (%eax),%eax + 800b48: 84 c0 test %al,%al + 800b4a: 75 e5 jne 800b31 + } + return cnt; + 800b4c: 8b 45 fc mov -0x4(%ebp),%eax +} + 800b4f: 89 ec mov %ebp,%esp + 800b51: 5d pop %ebp + 800b52: c3 ret + +00800b53 : + * To avoid overflows, the size of array pointed by @dst should be long enough to + * contain the same string as @src (including the terminating null character), and + * should not overlap in memory with @src. + * */ +char * +strcpy(char *dst, const char *src) { + 800b53: 55 push %ebp + 800b54: 89 e5 mov %esp,%ebp + 800b56: 57 push %edi + 800b57: 56 push %esi + 800b58: 83 ec 20 sub $0x20,%esp + 800b5b: 8b 45 08 mov 0x8(%ebp),%eax + 800b5e: 89 45 f4 mov %eax,-0xc(%ebp) + 800b61: 8b 45 0c mov 0xc(%ebp),%eax + 800b64: 89 45 f0 mov %eax,-0x10(%ebp) +#ifndef __HAVE_ARCH_STRCPY +#define __HAVE_ARCH_STRCPY +static inline char * +__strcpy(char *dst, const char *src) { + int d0, d1, d2; + asm volatile ( + 800b67: 8b 55 f0 mov -0x10(%ebp),%edx + 800b6a: 8b 45 f4 mov -0xc(%ebp),%eax + 800b6d: 89 d1 mov %edx,%ecx + 800b6f: 89 c2 mov %eax,%edx + 800b71: 89 ce mov %ecx,%esi + 800b73: 89 d7 mov %edx,%edi + 800b75: ac lods %ds:(%esi),%al + 800b76: aa stos %al,%es:(%edi) + 800b77: 84 c0 test %al,%al + 800b79: 75 fa jne 800b75 + 800b7b: 89 fa mov %edi,%edx + 800b7d: 89 f1 mov %esi,%ecx + 800b7f: 89 4d ec mov %ecx,-0x14(%ebp) + 800b82: 89 55 e8 mov %edx,-0x18(%ebp) + 800b85: 89 45 e4 mov %eax,-0x1c(%ebp) + "stosb;" + "testb %%al, %%al;" + "jne 1b;" + : "=&S" (d0), "=&D" (d1), "=&a" (d2) + : "0" (src), "1" (dst) : "memory"); + return dst; + 800b88: 8b 45 f4 mov -0xc(%ebp),%eax + char *p = dst; + while ((*p ++ = *src ++) != '\0') + /* nothing */; + return dst; +#endif /* __HAVE_ARCH_STRCPY */ +} + 800b8b: 83 c4 20 add $0x20,%esp + 800b8e: 5e pop %esi + 800b8f: 5f pop %edi + 800b90: 5d pop %ebp + 800b91: c3 ret + +00800b92 : + * @len: maximum number of characters to be copied from @src + * + * The return value is @dst + * */ +char * +strncpy(char *dst, const char *src, size_t len) { + 800b92: 55 push %ebp + 800b93: 89 e5 mov %esp,%ebp + 800b95: 83 ec 10 sub $0x10,%esp + char *p = dst; + 800b98: 8b 45 08 mov 0x8(%ebp),%eax + 800b9b: 89 45 fc mov %eax,-0x4(%ebp) + while (len > 0) { + 800b9e: eb 1e jmp 800bbe + if ((*p = *src) != '\0') { + 800ba0: 8b 45 0c mov 0xc(%ebp),%eax + 800ba3: 0f b6 10 movzbl (%eax),%edx + 800ba6: 8b 45 fc mov -0x4(%ebp),%eax + 800ba9: 88 10 mov %dl,(%eax) + 800bab: 8b 45 fc mov -0x4(%ebp),%eax + 800bae: 0f b6 00 movzbl (%eax),%eax + 800bb1: 84 c0 test %al,%al + 800bb3: 74 03 je 800bb8 + src ++; + 800bb5: ff 45 0c incl 0xc(%ebp) + } + p ++, len --; + 800bb8: ff 45 fc incl -0x4(%ebp) + 800bbb: ff 4d 10 decl 0x10(%ebp) + while (len > 0) { + 800bbe: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800bc2: 75 dc jne 800ba0 + } + return dst; + 800bc4: 8b 45 08 mov 0x8(%ebp),%eax +} + 800bc7: 89 ec mov %ebp,%esp + 800bc9: 5d pop %ebp + 800bca: c3 ret + +00800bcb : + * - A value greater than zero indicates that the first character that does + * not match has a greater value in @s1 than in @s2; + * - And a value less than zero indicates the opposite. + * */ +int +strcmp(const char *s1, const char *s2) { + 800bcb: 55 push %ebp + 800bcc: 89 e5 mov %esp,%ebp + 800bce: 57 push %edi + 800bcf: 56 push %esi + 800bd0: 83 ec 20 sub $0x20,%esp + 800bd3: 8b 45 08 mov 0x8(%ebp),%eax + 800bd6: 89 45 f4 mov %eax,-0xc(%ebp) + 800bd9: 8b 45 0c mov 0xc(%ebp),%eax + 800bdc: 89 45 f0 mov %eax,-0x10(%ebp) + asm volatile ( + 800bdf: 8b 55 f4 mov -0xc(%ebp),%edx + 800be2: 8b 45 f0 mov -0x10(%ebp),%eax + 800be5: 89 d1 mov %edx,%ecx + 800be7: 89 c2 mov %eax,%edx + 800be9: 89 ce mov %ecx,%esi + 800beb: 89 d7 mov %edx,%edi + 800bed: ac lods %ds:(%esi),%al + 800bee: ae scas %es:(%edi),%al + 800bef: 75 08 jne 800bf9 + 800bf1: 84 c0 test %al,%al + 800bf3: 75 f8 jne 800bed + 800bf5: 31 c0 xor %eax,%eax + 800bf7: eb 04 jmp 800bfd + 800bf9: 19 c0 sbb %eax,%eax + 800bfb: 0c 01 or $0x1,%al + 800bfd: 89 fa mov %edi,%edx + 800bff: 89 f1 mov %esi,%ecx + 800c01: 89 45 ec mov %eax,-0x14(%ebp) + 800c04: 89 4d e8 mov %ecx,-0x18(%ebp) + 800c07: 89 55 e4 mov %edx,-0x1c(%ebp) + return ret; + 800c0a: 8b 45 ec mov -0x14(%ebp),%eax + while (*s1 != '\0' && *s1 == *s2) { + s1 ++, s2 ++; + } + return (int)((unsigned char)*s1 - (unsigned char)*s2); +#endif /* __HAVE_ARCH_STRCMP */ +} + 800c0d: 83 c4 20 add $0x20,%esp + 800c10: 5e pop %esi + 800c11: 5f pop %edi + 800c12: 5d pop %ebp + 800c13: c3 ret + +00800c14 : + * they are equal to each other, it continues with the following pairs until + * the characters differ, until a terminating null-character is reached, or + * until @n characters match in both strings, whichever happens first. + * */ +int +strncmp(const char *s1, const char *s2, size_t n) { + 800c14: 55 push %ebp + 800c15: 89 e5 mov %esp,%ebp + while (n > 0 && *s1 != '\0' && *s1 == *s2) { + 800c17: eb 09 jmp 800c22 + n --, s1 ++, s2 ++; + 800c19: ff 4d 10 decl 0x10(%ebp) + 800c1c: ff 45 08 incl 0x8(%ebp) + 800c1f: ff 45 0c incl 0xc(%ebp) + while (n > 0 && *s1 != '\0' && *s1 == *s2) { + 800c22: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800c26: 74 1a je 800c42 + 800c28: 8b 45 08 mov 0x8(%ebp),%eax + 800c2b: 0f b6 00 movzbl (%eax),%eax + 800c2e: 84 c0 test %al,%al + 800c30: 74 10 je 800c42 + 800c32: 8b 45 08 mov 0x8(%ebp),%eax + 800c35: 0f b6 10 movzbl (%eax),%edx + 800c38: 8b 45 0c mov 0xc(%ebp),%eax + 800c3b: 0f b6 00 movzbl (%eax),%eax + 800c3e: 38 c2 cmp %al,%dl + 800c40: 74 d7 je 800c19 + } + return (n == 0) ? 0 : (int)((unsigned char)*s1 - (unsigned char)*s2); + 800c42: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800c46: 74 18 je 800c60 + 800c48: 8b 45 08 mov 0x8(%ebp),%eax + 800c4b: 0f b6 00 movzbl (%eax),%eax + 800c4e: 0f b6 d0 movzbl %al,%edx + 800c51: 8b 45 0c mov 0xc(%ebp),%eax + 800c54: 0f b6 00 movzbl (%eax),%eax + 800c57: 0f b6 c8 movzbl %al,%ecx + 800c5a: 89 d0 mov %edx,%eax + 800c5c: 29 c8 sub %ecx,%eax + 800c5e: eb 05 jmp 800c65 + 800c60: b8 00 00 00 00 mov $0x0,%eax +} + 800c65: 5d pop %ebp + 800c66: c3 ret + +00800c67 : + * + * The strchr() function returns a pointer to the first occurrence of + * character in @s. If the value is not found, the function returns 'NULL'. + * */ +char * +strchr(const char *s, char c) { + 800c67: 55 push %ebp + 800c68: 89 e5 mov %esp,%ebp + 800c6a: 83 ec 04 sub $0x4,%esp + 800c6d: 8b 45 0c mov 0xc(%ebp),%eax + 800c70: 88 45 fc mov %al,-0x4(%ebp) + while (*s != '\0') { + 800c73: eb 13 jmp 800c88 + if (*s == c) { + 800c75: 8b 45 08 mov 0x8(%ebp),%eax + 800c78: 0f b6 00 movzbl (%eax),%eax + 800c7b: 38 45 fc cmp %al,-0x4(%ebp) + 800c7e: 75 05 jne 800c85 + return (char *)s; + 800c80: 8b 45 08 mov 0x8(%ebp),%eax + 800c83: eb 12 jmp 800c97 + } + s ++; + 800c85: ff 45 08 incl 0x8(%ebp) + while (*s != '\0') { + 800c88: 8b 45 08 mov 0x8(%ebp),%eax + 800c8b: 0f b6 00 movzbl (%eax),%eax + 800c8e: 84 c0 test %al,%al + 800c90: 75 e3 jne 800c75 + } + return NULL; + 800c92: b8 00 00 00 00 mov $0x0,%eax +} + 800c97: 89 ec mov %ebp,%esp + 800c99: 5d pop %ebp + 800c9a: c3 ret + +00800c9b : + * The strfind() function is like strchr() except that if @c is + * not found in @s, then it returns a pointer to the null byte at the + * end of @s, rather than 'NULL'. + * */ +char * +strfind(const char *s, char c) { + 800c9b: 55 push %ebp + 800c9c: 89 e5 mov %esp,%ebp + 800c9e: 83 ec 04 sub $0x4,%esp + 800ca1: 8b 45 0c mov 0xc(%ebp),%eax + 800ca4: 88 45 fc mov %al,-0x4(%ebp) + while (*s != '\0') { + 800ca7: eb 0e jmp 800cb7 + if (*s == c) { + 800ca9: 8b 45 08 mov 0x8(%ebp),%eax + 800cac: 0f b6 00 movzbl (%eax),%eax + 800caf: 38 45 fc cmp %al,-0x4(%ebp) + 800cb2: 74 0f je 800cc3 + break; + } + s ++; + 800cb4: ff 45 08 incl 0x8(%ebp) + while (*s != '\0') { + 800cb7: 8b 45 08 mov 0x8(%ebp),%eax + 800cba: 0f b6 00 movzbl (%eax),%eax + 800cbd: 84 c0 test %al,%al + 800cbf: 75 e8 jne 800ca9 + 800cc1: eb 01 jmp 800cc4 + break; + 800cc3: 90 nop + } + return (char *)s; + 800cc4: 8b 45 08 mov 0x8(%ebp),%eax +} + 800cc7: 89 ec mov %ebp,%esp + 800cc9: 5d pop %ebp + 800cca: c3 ret + +00800ccb : + * an optional "0x" or "0X" prefix. + * + * The strtol() function returns the converted integral number as a long int value. + * */ +long +strtol(const char *s, char **endptr, int base) { + 800ccb: 55 push %ebp + 800ccc: 89 e5 mov %esp,%ebp + 800cce: 83 ec 10 sub $0x10,%esp + int neg = 0; + 800cd1: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + long val = 0; + 800cd8: c7 45 f8 00 00 00 00 movl $0x0,-0x8(%ebp) + + // gobble initial whitespace + while (*s == ' ' || *s == '\t') { + 800cdf: eb 03 jmp 800ce4 + s ++; + 800ce1: ff 45 08 incl 0x8(%ebp) + while (*s == ' ' || *s == '\t') { + 800ce4: 8b 45 08 mov 0x8(%ebp),%eax + 800ce7: 0f b6 00 movzbl (%eax),%eax + 800cea: 3c 20 cmp $0x20,%al + 800cec: 74 f3 je 800ce1 + 800cee: 8b 45 08 mov 0x8(%ebp),%eax + 800cf1: 0f b6 00 movzbl (%eax),%eax + 800cf4: 3c 09 cmp $0x9,%al + 800cf6: 74 e9 je 800ce1 + } + + // plus/minus sign + if (*s == '+') { + 800cf8: 8b 45 08 mov 0x8(%ebp),%eax + 800cfb: 0f b6 00 movzbl (%eax),%eax + 800cfe: 3c 2b cmp $0x2b,%al + 800d00: 75 05 jne 800d07 + s ++; + 800d02: ff 45 08 incl 0x8(%ebp) + 800d05: eb 14 jmp 800d1b + } + else if (*s == '-') { + 800d07: 8b 45 08 mov 0x8(%ebp),%eax + 800d0a: 0f b6 00 movzbl (%eax),%eax + 800d0d: 3c 2d cmp $0x2d,%al + 800d0f: 75 0a jne 800d1b + s ++, neg = 1; + 800d11: ff 45 08 incl 0x8(%ebp) + 800d14: c7 45 fc 01 00 00 00 movl $0x1,-0x4(%ebp) + } + + // hex or octal base prefix + if ((base == 0 || base == 16) && (s[0] == '0' && s[1] == 'x')) { + 800d1b: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800d1f: 74 06 je 800d27 + 800d21: 83 7d 10 10 cmpl $0x10,0x10(%ebp) + 800d25: 75 22 jne 800d49 + 800d27: 8b 45 08 mov 0x8(%ebp),%eax + 800d2a: 0f b6 00 movzbl (%eax),%eax + 800d2d: 3c 30 cmp $0x30,%al + 800d2f: 75 18 jne 800d49 + 800d31: 8b 45 08 mov 0x8(%ebp),%eax + 800d34: 40 inc %eax + 800d35: 0f b6 00 movzbl (%eax),%eax + 800d38: 3c 78 cmp $0x78,%al + 800d3a: 75 0d jne 800d49 + s += 2, base = 16; + 800d3c: 83 45 08 02 addl $0x2,0x8(%ebp) + 800d40: c7 45 10 10 00 00 00 movl $0x10,0x10(%ebp) + 800d47: eb 29 jmp 800d72 + } + else if (base == 0 && s[0] == '0') { + 800d49: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800d4d: 75 16 jne 800d65 + 800d4f: 8b 45 08 mov 0x8(%ebp),%eax + 800d52: 0f b6 00 movzbl (%eax),%eax + 800d55: 3c 30 cmp $0x30,%al + 800d57: 75 0c jne 800d65 + s ++, base = 8; + 800d59: ff 45 08 incl 0x8(%ebp) + 800d5c: c7 45 10 08 00 00 00 movl $0x8,0x10(%ebp) + 800d63: eb 0d jmp 800d72 + } + else if (base == 0) { + 800d65: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800d69: 75 07 jne 800d72 + base = 10; + 800d6b: c7 45 10 0a 00 00 00 movl $0xa,0x10(%ebp) + + // digits + while (1) { + int dig; + + if (*s >= '0' && *s <= '9') { + 800d72: 8b 45 08 mov 0x8(%ebp),%eax + 800d75: 0f b6 00 movzbl (%eax),%eax + 800d78: 3c 2f cmp $0x2f,%al + 800d7a: 7e 1b jle 800d97 + 800d7c: 8b 45 08 mov 0x8(%ebp),%eax + 800d7f: 0f b6 00 movzbl (%eax),%eax + 800d82: 3c 39 cmp $0x39,%al + 800d84: 7f 11 jg 800d97 + dig = *s - '0'; + 800d86: 8b 45 08 mov 0x8(%ebp),%eax + 800d89: 0f b6 00 movzbl (%eax),%eax + 800d8c: 0f be c0 movsbl %al,%eax + 800d8f: 83 e8 30 sub $0x30,%eax + 800d92: 89 45 f4 mov %eax,-0xc(%ebp) + 800d95: eb 48 jmp 800ddf + } + else if (*s >= 'a' && *s <= 'z') { + 800d97: 8b 45 08 mov 0x8(%ebp),%eax + 800d9a: 0f b6 00 movzbl (%eax),%eax + 800d9d: 3c 60 cmp $0x60,%al + 800d9f: 7e 1b jle 800dbc + 800da1: 8b 45 08 mov 0x8(%ebp),%eax + 800da4: 0f b6 00 movzbl (%eax),%eax + 800da7: 3c 7a cmp $0x7a,%al + 800da9: 7f 11 jg 800dbc + dig = *s - 'a' + 10; + 800dab: 8b 45 08 mov 0x8(%ebp),%eax + 800dae: 0f b6 00 movzbl (%eax),%eax + 800db1: 0f be c0 movsbl %al,%eax + 800db4: 83 e8 57 sub $0x57,%eax + 800db7: 89 45 f4 mov %eax,-0xc(%ebp) + 800dba: eb 23 jmp 800ddf + } + else if (*s >= 'A' && *s <= 'Z') { + 800dbc: 8b 45 08 mov 0x8(%ebp),%eax + 800dbf: 0f b6 00 movzbl (%eax),%eax + 800dc2: 3c 40 cmp $0x40,%al + 800dc4: 7e 3b jle 800e01 + 800dc6: 8b 45 08 mov 0x8(%ebp),%eax + 800dc9: 0f b6 00 movzbl (%eax),%eax + 800dcc: 3c 5a cmp $0x5a,%al + 800dce: 7f 31 jg 800e01 + dig = *s - 'A' + 10; + 800dd0: 8b 45 08 mov 0x8(%ebp),%eax + 800dd3: 0f b6 00 movzbl (%eax),%eax + 800dd6: 0f be c0 movsbl %al,%eax + 800dd9: 83 e8 37 sub $0x37,%eax + 800ddc: 89 45 f4 mov %eax,-0xc(%ebp) + } + else { + break; + } + if (dig >= base) { + 800ddf: 8b 45 f4 mov -0xc(%ebp),%eax + 800de2: 3b 45 10 cmp 0x10(%ebp),%eax + 800de5: 7d 19 jge 800e00 + break; + } + s ++, val = (val * base) + dig; + 800de7: ff 45 08 incl 0x8(%ebp) + 800dea: 8b 45 f8 mov -0x8(%ebp),%eax + 800ded: 0f af 45 10 imul 0x10(%ebp),%eax + 800df1: 89 c2 mov %eax,%edx + 800df3: 8b 45 f4 mov -0xc(%ebp),%eax + 800df6: 01 d0 add %edx,%eax + 800df8: 89 45 f8 mov %eax,-0x8(%ebp) + while (1) { + 800dfb: e9 72 ff ff ff jmp 800d72 + break; + 800e00: 90 nop + // we don't properly detect overflow! + } + + if (endptr) { + 800e01: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) + 800e05: 74 08 je 800e0f + *endptr = (char *) s; + 800e07: 8b 45 0c mov 0xc(%ebp),%eax + 800e0a: 8b 55 08 mov 0x8(%ebp),%edx + 800e0d: 89 10 mov %edx,(%eax) + } + return (neg ? -val : val); + 800e0f: 83 7d fc 00 cmpl $0x0,-0x4(%ebp) + 800e13: 74 07 je 800e1c + 800e15: 8b 45 f8 mov -0x8(%ebp),%eax + 800e18: f7 d8 neg %eax + 800e1a: eb 03 jmp 800e1f + 800e1c: 8b 45 f8 mov -0x8(%ebp),%eax +} + 800e1f: 89 ec mov %ebp,%esp + 800e21: 5d pop %ebp + 800e22: c3 ret + +00800e23 : + * @n: number of bytes to be set to the value + * + * The memset() function returns @s. + * */ +void * +memset(void *s, char c, size_t n) { + 800e23: 55 push %ebp + 800e24: 89 e5 mov %esp,%ebp + 800e26: 83 ec 28 sub $0x28,%esp + 800e29: 89 7d fc mov %edi,-0x4(%ebp) + 800e2c: 8b 45 0c mov 0xc(%ebp),%eax + 800e2f: 88 45 d8 mov %al,-0x28(%ebp) +#ifdef __HAVE_ARCH_MEMSET + return __memset(s, c, n); + 800e32: 0f be 55 d8 movsbl -0x28(%ebp),%edx + 800e36: 8b 45 08 mov 0x8(%ebp),%eax + 800e39: 89 45 f8 mov %eax,-0x8(%ebp) + 800e3c: 88 55 f7 mov %dl,-0x9(%ebp) + 800e3f: 8b 45 10 mov 0x10(%ebp),%eax + 800e42: 89 45 f0 mov %eax,-0x10(%ebp) +#ifndef __HAVE_ARCH_MEMSET +#define __HAVE_ARCH_MEMSET +static inline void * +__memset(void *s, char c, size_t n) { + int d0, d1; + asm volatile ( + 800e45: 8b 4d f0 mov -0x10(%ebp),%ecx + 800e48: 0f b6 45 f7 movzbl -0x9(%ebp),%eax + 800e4c: 8b 55 f8 mov -0x8(%ebp),%edx + 800e4f: 89 d7 mov %edx,%edi + 800e51: f3 aa rep stos %al,%es:(%edi) + 800e53: 89 fa mov %edi,%edx + 800e55: 89 4d ec mov %ecx,-0x14(%ebp) + 800e58: 89 55 e8 mov %edx,-0x18(%ebp) + "rep; stosb;" + : "=&c" (d0), "=&D" (d1) + : "0" (n), "a" (c), "1" (s) + : "memory"); + return s; + 800e5b: 8b 45 f8 mov -0x8(%ebp),%eax + while (n -- > 0) { + *p ++ = c; + } + return s; +#endif /* __HAVE_ARCH_MEMSET */ +} + 800e5e: 8b 7d fc mov -0x4(%ebp),%edi + 800e61: 89 ec mov %ebp,%esp + 800e63: 5d pop %ebp + 800e64: c3 ret + +00800e65 : + * @n: number of bytes to copy + * + * The memmove() function returns @dst. + * */ +void * +memmove(void *dst, const void *src, size_t n) { + 800e65: 55 push %ebp + 800e66: 89 e5 mov %esp,%ebp + 800e68: 57 push %edi + 800e69: 56 push %esi + 800e6a: 53 push %ebx + 800e6b: 83 ec 30 sub $0x30,%esp + 800e6e: 8b 45 08 mov 0x8(%ebp),%eax + 800e71: 89 45 f0 mov %eax,-0x10(%ebp) + 800e74: 8b 45 0c mov 0xc(%ebp),%eax + 800e77: 89 45 ec mov %eax,-0x14(%ebp) + 800e7a: 8b 45 10 mov 0x10(%ebp),%eax + 800e7d: 89 45 e8 mov %eax,-0x18(%ebp) + +#ifndef __HAVE_ARCH_MEMMOVE +#define __HAVE_ARCH_MEMMOVE +static inline void * +__memmove(void *dst, const void *src, size_t n) { + if (dst < src) { + 800e80: 8b 45 f0 mov -0x10(%ebp),%eax + 800e83: 3b 45 ec cmp -0x14(%ebp),%eax + 800e86: 73 42 jae 800eca + 800e88: 8b 45 f0 mov -0x10(%ebp),%eax + 800e8b: 89 45 e4 mov %eax,-0x1c(%ebp) + 800e8e: 8b 45 ec mov -0x14(%ebp),%eax + 800e91: 89 45 e0 mov %eax,-0x20(%ebp) + 800e94: 8b 45 e8 mov -0x18(%ebp),%eax + 800e97: 89 45 dc mov %eax,-0x24(%ebp) + "andl $3, %%ecx;" + "jz 1f;" + "rep; movsb;" + "1:" + : "=&c" (d0), "=&D" (d1), "=&S" (d2) + : "0" (n / 4), "g" (n), "1" (dst), "2" (src) + 800e9a: 8b 45 dc mov -0x24(%ebp),%eax + 800e9d: c1 e8 02 shr $0x2,%eax + 800ea0: 89 c1 mov %eax,%ecx + asm volatile ( + 800ea2: 8b 55 e4 mov -0x1c(%ebp),%edx + 800ea5: 8b 45 e0 mov -0x20(%ebp),%eax + 800ea8: 89 d7 mov %edx,%edi + 800eaa: 89 c6 mov %eax,%esi + 800eac: f3 a5 rep movsl %ds:(%esi),%es:(%edi) + 800eae: 8b 4d dc mov -0x24(%ebp),%ecx + 800eb1: 83 e1 03 and $0x3,%ecx + 800eb4: 74 02 je 800eb8 + 800eb6: f3 a4 rep movsb %ds:(%esi),%es:(%edi) + 800eb8: 89 f0 mov %esi,%eax + 800eba: 89 fa mov %edi,%edx + 800ebc: 89 4d d8 mov %ecx,-0x28(%ebp) + 800ebf: 89 55 d4 mov %edx,-0x2c(%ebp) + 800ec2: 89 45 d0 mov %eax,-0x30(%ebp) + : "memory"); + return dst; + 800ec5: 8b 45 e4 mov -0x1c(%ebp),%eax + return __memcpy(dst, src, n); + 800ec8: eb 36 jmp 800f00 + : "0" (n), "1" (n - 1 + src), "2" (n - 1 + dst) + 800eca: 8b 45 e8 mov -0x18(%ebp),%eax + 800ecd: 8d 50 ff lea -0x1(%eax),%edx + 800ed0: 8b 45 ec mov -0x14(%ebp),%eax + 800ed3: 01 c2 add %eax,%edx + 800ed5: 8b 45 e8 mov -0x18(%ebp),%eax + 800ed8: 8d 48 ff lea -0x1(%eax),%ecx + 800edb: 8b 45 f0 mov -0x10(%ebp),%eax + 800ede: 8d 1c 01 lea (%ecx,%eax,1),%ebx + asm volatile ( + 800ee1: 8b 45 e8 mov -0x18(%ebp),%eax + 800ee4: 89 c1 mov %eax,%ecx + 800ee6: 89 d8 mov %ebx,%eax + 800ee8: 89 d6 mov %edx,%esi + 800eea: 89 c7 mov %eax,%edi + 800eec: fd std + 800eed: f3 a4 rep movsb %ds:(%esi),%es:(%edi) + 800eef: fc cld + 800ef0: 89 f8 mov %edi,%eax + 800ef2: 89 f2 mov %esi,%edx + 800ef4: 89 4d cc mov %ecx,-0x34(%ebp) + 800ef7: 89 55 c8 mov %edx,-0x38(%ebp) + 800efa: 89 45 c4 mov %eax,-0x3c(%ebp) + return dst; + 800efd: 8b 45 f0 mov -0x10(%ebp),%eax + *d ++ = *s ++; + } + } + return dst; +#endif /* __HAVE_ARCH_MEMMOVE */ +} + 800f00: 83 c4 30 add $0x30,%esp + 800f03: 5b pop %ebx + 800f04: 5e pop %esi + 800f05: 5f pop %edi + 800f06: 5d pop %ebp + 800f07: c3 ret + +00800f08 : + * it always copies exactly @n bytes. To avoid overflows, the size of arrays pointed + * by both @src and @dst, should be at least @n bytes, and should not overlap + * (for overlapping memory area, memmove is a safer approach). + * */ +void * +memcpy(void *dst, const void *src, size_t n) { + 800f08: 55 push %ebp + 800f09: 89 e5 mov %esp,%ebp + 800f0b: 57 push %edi + 800f0c: 56 push %esi + 800f0d: 83 ec 20 sub $0x20,%esp + 800f10: 8b 45 08 mov 0x8(%ebp),%eax + 800f13: 89 45 f4 mov %eax,-0xc(%ebp) + 800f16: 8b 45 0c mov 0xc(%ebp),%eax + 800f19: 89 45 f0 mov %eax,-0x10(%ebp) + 800f1c: 8b 45 10 mov 0x10(%ebp),%eax + 800f1f: 89 45 ec mov %eax,-0x14(%ebp) + : "0" (n / 4), "g" (n), "1" (dst), "2" (src) + 800f22: 8b 45 ec mov -0x14(%ebp),%eax + 800f25: c1 e8 02 shr $0x2,%eax + 800f28: 89 c1 mov %eax,%ecx + asm volatile ( + 800f2a: 8b 55 f4 mov -0xc(%ebp),%edx + 800f2d: 8b 45 f0 mov -0x10(%ebp),%eax + 800f30: 89 d7 mov %edx,%edi + 800f32: 89 c6 mov %eax,%esi + 800f34: f3 a5 rep movsl %ds:(%esi),%es:(%edi) + 800f36: 8b 4d ec mov -0x14(%ebp),%ecx + 800f39: 83 e1 03 and $0x3,%ecx + 800f3c: 74 02 je 800f40 + 800f3e: f3 a4 rep movsb %ds:(%esi),%es:(%edi) + 800f40: 89 f0 mov %esi,%eax + 800f42: 89 fa mov %edi,%edx + 800f44: 89 4d e8 mov %ecx,-0x18(%ebp) + 800f47: 89 55 e4 mov %edx,-0x1c(%ebp) + 800f4a: 89 45 e0 mov %eax,-0x20(%ebp) + return dst; + 800f4d: 8b 45 f4 mov -0xc(%ebp),%eax + while (n -- > 0) { + *d ++ = *s ++; + } + return dst; +#endif /* __HAVE_ARCH_MEMCPY */ +} + 800f50: 83 c4 20 add $0x20,%esp + 800f53: 5e pop %esi + 800f54: 5f pop %edi + 800f55: 5d pop %ebp + 800f56: c3 ret + +00800f57 : + * match in both memory blocks has a greater value in @v1 than in @v2 + * as if evaluated as unsigned char values; + * - And a value less than zero indicates the opposite. + * */ +int +memcmp(const void *v1, const void *v2, size_t n) { + 800f57: 55 push %ebp + 800f58: 89 e5 mov %esp,%ebp + 800f5a: 83 ec 10 sub $0x10,%esp + const char *s1 = (const char *)v1; + 800f5d: 8b 45 08 mov 0x8(%ebp),%eax + 800f60: 89 45 fc mov %eax,-0x4(%ebp) + const char *s2 = (const char *)v2; + 800f63: 8b 45 0c mov 0xc(%ebp),%eax + 800f66: 89 45 f8 mov %eax,-0x8(%ebp) + while (n -- > 0) { + 800f69: eb 2e jmp 800f99 + if (*s1 != *s2) { + 800f6b: 8b 45 fc mov -0x4(%ebp),%eax + 800f6e: 0f b6 10 movzbl (%eax),%edx + 800f71: 8b 45 f8 mov -0x8(%ebp),%eax + 800f74: 0f b6 00 movzbl (%eax),%eax + 800f77: 38 c2 cmp %al,%dl + 800f79: 74 18 je 800f93 + return (int)((unsigned char)*s1 - (unsigned char)*s2); + 800f7b: 8b 45 fc mov -0x4(%ebp),%eax + 800f7e: 0f b6 00 movzbl (%eax),%eax + 800f81: 0f b6 d0 movzbl %al,%edx + 800f84: 8b 45 f8 mov -0x8(%ebp),%eax + 800f87: 0f b6 00 movzbl (%eax),%eax + 800f8a: 0f b6 c8 movzbl %al,%ecx + 800f8d: 89 d0 mov %edx,%eax + 800f8f: 29 c8 sub %ecx,%eax + 800f91: eb 18 jmp 800fab + } + s1 ++, s2 ++; + 800f93: ff 45 fc incl -0x4(%ebp) + 800f96: ff 45 f8 incl -0x8(%ebp) + while (n -- > 0) { + 800f99: 8b 45 10 mov 0x10(%ebp),%eax + 800f9c: 8d 50 ff lea -0x1(%eax),%edx + 800f9f: 89 55 10 mov %edx,0x10(%ebp) + 800fa2: 85 c0 test %eax,%eax + 800fa4: 75 c5 jne 800f6b + } + return 0; + 800fa6: b8 00 00 00 00 mov $0x0,%eax +} + 800fab: 89 ec mov %ebp,%esp + 800fad: 5d pop %ebp + 800fae: c3 ret + +00800faf : +#include +#include + +void +do_yield(void) { + 800faf: 55 push %ebp + 800fb0: 89 e5 mov %esp,%ebp + 800fb2: 83 ec 08 sub $0x8,%esp + yield(); + 800fb5: e8 6f f3 ff ff call 800329 + yield(); + 800fba: e8 6a f3 ff ff call 800329 + yield(); + 800fbf: e8 65 f3 ff ff call 800329 + yield(); + 800fc4: e8 60 f3 ff ff call 800329 + yield(); + 800fc9: e8 5b f3 ff ff call 800329 + yield(); + 800fce: e8 56 f3 ff ff call 800329 +} + 800fd3: 90 nop + 800fd4: 89 ec mov %ebp,%esp + 800fd6: 5d pop %ebp + 800fd7: c3 ret + +00800fd8 : + +int parent, pid1, pid2; + +void +loop(void) { + 800fd8: 55 push %ebp + 800fd9: 89 e5 mov %esp,%ebp + 800fdb: 83 ec 18 sub $0x18,%esp + cprintf("child 1.\n"); + 800fde: c7 04 24 40 14 80 00 movl $0x801440,(%esp) + 800fe5: e8 36 f1 ff ff call 800120 + while (1); + 800fea: eb fe jmp 800fea + +00800fec : +} + +void +work(void) { + 800fec: 55 push %ebp + 800fed: 89 e5 mov %esp,%ebp + 800fef: 83 ec 18 sub $0x18,%esp + cprintf("child 2.\n"); + 800ff2: c7 04 24 4a 14 80 00 movl $0x80144a,(%esp) + 800ff9: e8 22 f1 ff ff call 800120 + do_yield(); + 800ffe: e8 ac ff ff ff call 800faf + if (kill(parent) == 0) { + 801003: a1 08 20 80 00 mov 0x802008,%eax + 801008: 89 04 24 mov %eax,(%esp) + 80100b: e8 29 f3 ff ff call 800339 + 801010: 85 c0 test %eax,%eax + 801012: 75 3a jne 80104e + cprintf("kill parent ok.\n"); + 801014: c7 04 24 54 14 80 00 movl $0x801454,(%esp) + 80101b: e8 00 f1 ff ff call 800120 + do_yield(); + 801020: e8 8a ff ff ff call 800faf + if (kill(pid1) == 0) { + 801025: a1 0c 20 80 00 mov 0x80200c,%eax + 80102a: 89 04 24 mov %eax,(%esp) + 80102d: e8 07 f3 ff ff call 800339 + 801032: 85 c0 test %eax,%eax + 801034: 75 18 jne 80104e + cprintf("kill child1 ok.\n"); + 801036: c7 04 24 65 14 80 00 movl $0x801465,(%esp) + 80103d: e8 de f0 ff ff call 800120 + exit(0); + 801042: c7 04 24 00 00 00 00 movl $0x0,(%esp) + 801049: e8 73 f2 ff ff call 8002c1 + } + } + exit(-1); + 80104e: c7 04 24 ff ff ff ff movl $0xffffffff,(%esp) + 801055: e8 67 f2 ff ff call 8002c1 + +0080105a
: +} + +int +main(void) { + 80105a: 55 push %ebp + 80105b: 89 e5 mov %esp,%ebp + 80105d: 83 e4 f0 and $0xfffffff0,%esp + 801060: 83 ec 10 sub $0x10,%esp + parent = getpid(); + 801063: e8 e6 f2 ff ff call 80034e + 801068: a3 08 20 80 00 mov %eax,0x802008 + if ((pid1 = fork()) == 0) { + 80106d: e8 6e f2 ff ff call 8002e0 + 801072: a3 0c 20 80 00 mov %eax,0x80200c + 801077: a1 0c 20 80 00 mov 0x80200c,%eax + 80107c: 85 c0 test %eax,%eax + 80107e: 75 05 jne 801085 + loop(); + 801080: e8 53 ff ff ff call 800fd8 + } + + assert(pid1 > 0); + 801085: a1 0c 20 80 00 mov 0x80200c,%eax + 80108a: 85 c0 test %eax,%eax + 80108c: 7f 24 jg 8010b2 + 80108e: c7 44 24 0c 76 14 80 movl $0x801476,0xc(%esp) + 801095: 00 + 801096: c7 44 24 08 7f 14 80 movl $0x80147f,0x8(%esp) + 80109d: 00 + 80109e: c7 44 24 04 2c 00 00 movl $0x2c,0x4(%esp) + 8010a5: 00 + 8010a6: c7 04 24 94 14 80 00 movl $0x801494,(%esp) + 8010ad: e8 7d ef ff ff call 80002f <__panic> + + if ((pid2 = fork()) == 0) { + 8010b2: e8 29 f2 ff ff call 8002e0 + 8010b7: a3 10 20 80 00 mov %eax,0x802010 + 8010bc: a1 10 20 80 00 mov 0x802010,%eax + 8010c1: 85 c0 test %eax,%eax + 8010c3: 75 05 jne 8010ca + work(); + 8010c5: e8 22 ff ff ff call 800fec + } + if (pid2 > 0) { + 8010ca: a1 10 20 80 00 mov 0x802010,%eax + 8010cf: 85 c0 test %eax,%eax + 8010d1: 7e 46 jle 801119 + cprintf("wait child 1.\n"); + 8010d3: c7 04 24 a4 14 80 00 movl $0x8014a4,(%esp) + 8010da: e8 41 f0 ff ff call 800120 + waitpid(pid1, NULL); + 8010df: a1 0c 20 80 00 mov 0x80200c,%eax + 8010e4: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) + 8010eb: 00 + 8010ec: 89 04 24 mov %eax,(%esp) + 8010ef: e8 19 f2 ff ff call 80030d + panic("waitpid %d returns\n", pid1); + 8010f4: a1 0c 20 80 00 mov 0x80200c,%eax + 8010f9: 89 44 24 0c mov %eax,0xc(%esp) + 8010fd: c7 44 24 08 b3 14 80 movl $0x8014b3,0x8(%esp) + 801104: 00 + 801105: c7 44 24 04 34 00 00 movl $0x34,0x4(%esp) + 80110c: 00 + 80110d: c7 04 24 94 14 80 00 movl $0x801494,(%esp) + 801114: e8 16 ef ff ff call 80002f <__panic> + } + else { + kill(pid1); + 801119: a1 0c 20 80 00 mov 0x80200c,%eax + 80111e: 89 04 24 mov %eax,(%esp) + 801121: e8 13 f2 ff ff call 800339 + } + panic("FAIL: T.T\n"); + 801126: c7 44 24 08 c7 14 80 movl $0x8014c7,0x8(%esp) + 80112d: 00 + 80112e: c7 44 24 04 39 00 00 movl $0x39,0x4(%esp) + 801135: 00 + 801136: c7 04 24 94 14 80 00 movl $0x801494,(%esp) + 80113d: e8 ed ee ff ff call 80002f <__panic> diff --git a/labcodes/lab5/obj/user/waitkill.d b/labcodes/lab5/obj/user/waitkill.d new file mode 100644 index 0000000000000000000000000000000000000000..47eb66ee32501a05ed341bee80861268712e34d2 --- /dev/null +++ b/labcodes/lab5/obj/user/waitkill.d @@ -0,0 +1,2 @@ +obj/user/waitkill.o obj/user/waitkill.d: user/waitkill.c user/libs/ulib.h \ + libs/defs.h libs/stdio.h libs/stdarg.h diff --git a/labcodes/lab5/obj/user/waitkill.o b/labcodes/lab5/obj/user/waitkill.o new file mode 100644 index 0000000000000000000000000000000000000000..efc20bf781137f92a456ab97fd2978ad157a7c64 Binary files /dev/null and b/labcodes/lab5/obj/user/waitkill.o differ diff --git a/labcodes/lab5/obj/user/waitkill.sym b/labcodes/lab5/obj/user/waitkill.sym new file mode 100644 index 0000000000000000000000000000000000000000..66adb7a32002eddb8ee909d77ed929c29109446d --- /dev/null +++ b/labcodes/lab5/obj/user/waitkill.sym @@ -0,0 +1,72 @@ +00000000 panic.c +00000000 stdio.c +008000c8 cputch +00000000 syscall.c +00800199 syscall +00000000 ulib.c +00000000 umain.c +00000000 hash.c +00000000 printfmt.c +00801260 error_string +008003ad printnum +008004af getuint +008004fe getint +0080094f sprintputch +00000000 rand.c +00802000 next +00000000 string.c +00000000 waitkill.c +00800b53 strcpy +00800329 yield +0080030d waitpid +00800245 sys_yield +00800e65 memmove +00800985 snprintf +00800576 vprintfmt +0080020b sys_fork +00800120 cprintf +00800fd8 loop +0080034e getpid +00800f08 memcpy +00802008 parent +008009bb vsnprintf +0080036d umain +002028f0 __STAB_END__ +0080025b sys_kill +002028f1 __STABSTR_BEGIN__ +0080002f __panic +00800ccb strtol +00800b22 strnlen +0080035d print_pgdir +00800339 kill +00802010 pid2 +00800c9b strfind +008002ef wait +00800020 _start +00800a21 rand +00800c14 strncmp +0080028e sys_putc +00800b92 strncpy +00800f57 memcmp +008002e0 fork +00800e23 memset +0080105a main +00800ae0 srand +00800386 hash32 +00800545 printfmt +00800faf do_yield +00203855 __STABSTR_END__ +00800bcb strcmp +008000eb vcprintf +0080007f __warn +00800148 cputs +0080200c pid1 +008002c1 exit +00800221 sys_wait +008001ee sys_exit +00200010 __STAB_BEGIN__ +00800af9 strlen +008002ab sys_pgdir +00800c67 strchr +00800278 sys_getpid +00800fec work diff --git a/labcodes/lab5/obj/user/yield.asm b/labcodes/lab5/obj/user/yield.asm new file mode 100644 index 0000000000000000000000000000000000000000..9df624169eea090ef70cf71d87198f53adcc6372 --- /dev/null +++ b/labcodes/lab5/obj/user/yield.asm @@ -0,0 +1,2348 @@ + +obj/__user_yield.out: file format elf32-i386 + + +Disassembly of section .text: + +00800020 <_start>: +.text +.globl _start +_start: + # set ebp for backtrace + movl $0x0, %ebp + 800020: bd 00 00 00 00 mov $0x0,%ebp + + # move down the esp register + # since it may cause page fault in backtrace + subl $0x20, %esp + 800025: 83 ec 20 sub $0x20,%esp + + # call user-program function + call umain + 800028: e8 40 03 00 00 call 80036d +1: jmp 1b + 80002d: eb fe jmp 80002d <_start+0xd> + +0080002f <__panic>: +#include +#include +#include + +void +__panic(const char *file, int line, const char *fmt, ...) { + 80002f: 55 push %ebp + 800030: 89 e5 mov %esp,%ebp + 800032: 83 ec 28 sub $0x28,%esp + // print the 'message' + va_list ap; + va_start(ap, fmt); + 800035: 8d 45 14 lea 0x14(%ebp),%eax + 800038: 89 45 f4 mov %eax,-0xc(%ebp) + cprintf("user panic at %s:%d:\n ", file, line); + 80003b: 8b 45 0c mov 0xc(%ebp),%eax + 80003e: 89 44 24 08 mov %eax,0x8(%esp) + 800042: 8b 45 08 mov 0x8(%ebp),%eax + 800045: 89 44 24 04 mov %eax,0x4(%esp) + 800049: c7 04 24 40 10 80 00 movl $0x801040,(%esp) + 800050: e8 cb 00 00 00 call 800120 + vcprintf(fmt, ap); + 800055: 8b 45 f4 mov -0xc(%ebp),%eax + 800058: 89 44 24 04 mov %eax,0x4(%esp) + 80005c: 8b 45 10 mov 0x10(%ebp),%eax + 80005f: 89 04 24 mov %eax,(%esp) + 800062: e8 84 00 00 00 call 8000eb + cprintf("\n"); + 800067: c7 04 24 5a 10 80 00 movl $0x80105a,(%esp) + 80006e: e8 ad 00 00 00 call 800120 + va_end(ap); + exit(-E_PANIC); + 800073: c7 04 24 f6 ff ff ff movl $0xfffffff6,(%esp) + 80007a: e8 42 02 00 00 call 8002c1 + +0080007f <__warn>: +} + +void +__warn(const char *file, int line, const char *fmt, ...) { + 80007f: 55 push %ebp + 800080: 89 e5 mov %esp,%ebp + 800082: 83 ec 28 sub $0x28,%esp + va_list ap; + va_start(ap, fmt); + 800085: 8d 45 14 lea 0x14(%ebp),%eax + 800088: 89 45 f4 mov %eax,-0xc(%ebp) + cprintf("user warning at %s:%d:\n ", file, line); + 80008b: 8b 45 0c mov 0xc(%ebp),%eax + 80008e: 89 44 24 08 mov %eax,0x8(%esp) + 800092: 8b 45 08 mov 0x8(%ebp),%eax + 800095: 89 44 24 04 mov %eax,0x4(%esp) + 800099: c7 04 24 5c 10 80 00 movl $0x80105c,(%esp) + 8000a0: e8 7b 00 00 00 call 800120 + vcprintf(fmt, ap); + 8000a5: 8b 45 f4 mov -0xc(%ebp),%eax + 8000a8: 89 44 24 04 mov %eax,0x4(%esp) + 8000ac: 8b 45 10 mov 0x10(%ebp),%eax + 8000af: 89 04 24 mov %eax,(%esp) + 8000b2: e8 34 00 00 00 call 8000eb + cprintf("\n"); + 8000b7: c7 04 24 5a 10 80 00 movl $0x80105a,(%esp) + 8000be: e8 5d 00 00 00 call 800120 + va_end(ap); +} + 8000c3: 90 nop + 8000c4: 89 ec mov %ebp,%esp + 8000c6: 5d pop %ebp + 8000c7: c3 ret + +008000c8 : +/* * + * cputch - writes a single character @c to stdout, and it will + * increace the value of counter pointed by @cnt. + * */ +static void +cputch(int c, int *cnt) { + 8000c8: 55 push %ebp + 8000c9: 89 e5 mov %esp,%ebp + 8000cb: 83 ec 18 sub $0x18,%esp + sys_putc(c); + 8000ce: 8b 45 08 mov 0x8(%ebp),%eax + 8000d1: 89 04 24 mov %eax,(%esp) + 8000d4: e8 b5 01 00 00 call 80028e + (*cnt) ++; + 8000d9: 8b 45 0c mov 0xc(%ebp),%eax + 8000dc: 8b 00 mov (%eax),%eax + 8000de: 8d 50 01 lea 0x1(%eax),%edx + 8000e1: 8b 45 0c mov 0xc(%ebp),%eax + 8000e4: 89 10 mov %edx,(%eax) +} + 8000e6: 90 nop + 8000e7: 89 ec mov %ebp,%esp + 8000e9: 5d pop %ebp + 8000ea: c3 ret + +008000eb : + * + * Call this function if you are already dealing with a va_list. + * Or you probably want cprintf() instead. + * */ +int +vcprintf(const char *fmt, va_list ap) { + 8000eb: 55 push %ebp + 8000ec: 89 e5 mov %esp,%ebp + 8000ee: 83 ec 28 sub $0x28,%esp + int cnt = 0; + 8000f1: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + vprintfmt((void*)cputch, &cnt, fmt, ap); + 8000f8: 8b 45 0c mov 0xc(%ebp),%eax + 8000fb: 89 44 24 0c mov %eax,0xc(%esp) + 8000ff: 8b 45 08 mov 0x8(%ebp),%eax + 800102: 89 44 24 08 mov %eax,0x8(%esp) + 800106: 8d 45 f4 lea -0xc(%ebp),%eax + 800109: 89 44 24 04 mov %eax,0x4(%esp) + 80010d: c7 04 24 c8 00 80 00 movl $0x8000c8,(%esp) + 800114: e8 5d 04 00 00 call 800576 + return cnt; + 800119: 8b 45 f4 mov -0xc(%ebp),%eax +} + 80011c: 89 ec mov %ebp,%esp + 80011e: 5d pop %ebp + 80011f: c3 ret + +00800120 : + * + * The return value is the number of characters which would be + * written to stdout. + * */ +int +cprintf(const char *fmt, ...) { + 800120: 55 push %ebp + 800121: 89 e5 mov %esp,%ebp + 800123: 83 ec 28 sub $0x28,%esp + va_list ap; + + va_start(ap, fmt); + 800126: 8d 45 0c lea 0xc(%ebp),%eax + 800129: 89 45 f0 mov %eax,-0x10(%ebp) + int cnt = vcprintf(fmt, ap); + 80012c: 8b 45 f0 mov -0x10(%ebp),%eax + 80012f: 89 44 24 04 mov %eax,0x4(%esp) + 800133: 8b 45 08 mov 0x8(%ebp),%eax + 800136: 89 04 24 mov %eax,(%esp) + 800139: e8 ad ff ff ff call 8000eb + 80013e: 89 45 f4 mov %eax,-0xc(%ebp) + va_end(ap); + + return cnt; + 800141: 8b 45 f4 mov -0xc(%ebp),%eax +} + 800144: 89 ec mov %ebp,%esp + 800146: 5d pop %ebp + 800147: c3 ret + +00800148 : +/* * + * cputs- writes the string pointed by @str to stdout and + * appends a newline character. + * */ +int +cputs(const char *str) { + 800148: 55 push %ebp + 800149: 89 e5 mov %esp,%ebp + 80014b: 83 ec 28 sub $0x28,%esp + int cnt = 0; + 80014e: c7 45 f0 00 00 00 00 movl $0x0,-0x10(%ebp) + char c; + while ((c = *str ++) != '\0') { + 800155: eb 13 jmp 80016a + cputch(c, &cnt); + 800157: 0f be 45 f7 movsbl -0x9(%ebp),%eax + 80015b: 8d 55 f0 lea -0x10(%ebp),%edx + 80015e: 89 54 24 04 mov %edx,0x4(%esp) + 800162: 89 04 24 mov %eax,(%esp) + 800165: e8 5e ff ff ff call 8000c8 + while ((c = *str ++) != '\0') { + 80016a: 8b 45 08 mov 0x8(%ebp),%eax + 80016d: 8d 50 01 lea 0x1(%eax),%edx + 800170: 89 55 08 mov %edx,0x8(%ebp) + 800173: 0f b6 00 movzbl (%eax),%eax + 800176: 88 45 f7 mov %al,-0x9(%ebp) + 800179: 80 7d f7 00 cmpb $0x0,-0x9(%ebp) + 80017d: 75 d8 jne 800157 + } + cputch('\n', &cnt); + 80017f: 8d 45 f0 lea -0x10(%ebp),%eax + 800182: 89 44 24 04 mov %eax,0x4(%esp) + 800186: c7 04 24 0a 00 00 00 movl $0xa,(%esp) + 80018d: e8 36 ff ff ff call 8000c8 + return cnt; + 800192: 8b 45 f0 mov -0x10(%ebp),%eax +} + 800195: 89 ec mov %ebp,%esp + 800197: 5d pop %ebp + 800198: c3 ret + +00800199 : +#include + +#define MAX_ARGS 5 + +static inline int +syscall(int num, ...) { + 800199: 55 push %ebp + 80019a: 89 e5 mov %esp,%ebp + 80019c: 57 push %edi + 80019d: 56 push %esi + 80019e: 53 push %ebx + 80019f: 83 ec 20 sub $0x20,%esp + va_list ap; + va_start(ap, num); + 8001a2: 8d 45 0c lea 0xc(%ebp),%eax + 8001a5: 89 45 e8 mov %eax,-0x18(%ebp) + uint32_t a[MAX_ARGS]; + int i, ret; + for (i = 0; i < MAX_ARGS; i ++) { + 8001a8: c7 45 f0 00 00 00 00 movl $0x0,-0x10(%ebp) + 8001af: eb 15 jmp 8001c6 + a[i] = va_arg(ap, uint32_t); + 8001b1: 8b 45 e8 mov -0x18(%ebp),%eax + 8001b4: 8d 50 04 lea 0x4(%eax),%edx + 8001b7: 89 55 e8 mov %edx,-0x18(%ebp) + 8001ba: 8b 10 mov (%eax),%edx + 8001bc: 8b 45 f0 mov -0x10(%ebp),%eax + 8001bf: 89 54 85 d4 mov %edx,-0x2c(%ebp,%eax,4) + for (i = 0; i < MAX_ARGS; i ++) { + 8001c3: ff 45 f0 incl -0x10(%ebp) + 8001c6: 83 7d f0 04 cmpl $0x4,-0x10(%ebp) + 8001ca: 7e e5 jle 8001b1 + asm volatile ( + "int %1;" + : "=a" (ret) + : "i" (T_SYSCALL), + "a" (num), + "d" (a[0]), + 8001cc: 8b 55 d4 mov -0x2c(%ebp),%edx + "c" (a[1]), + 8001cf: 8b 4d d8 mov -0x28(%ebp),%ecx + "b" (a[2]), + 8001d2: 8b 5d dc mov -0x24(%ebp),%ebx + "D" (a[3]), + 8001d5: 8b 7d e0 mov -0x20(%ebp),%edi + "S" (a[4]) + 8001d8: 8b 75 e4 mov -0x1c(%ebp),%esi + asm volatile ( + 8001db: 8b 45 08 mov 0x8(%ebp),%eax + 8001de: cd 80 int $0x80 + 8001e0: 89 45 ec mov %eax,-0x14(%ebp) + : "cc", "memory"); + return ret; + 8001e3: 8b 45 ec mov -0x14(%ebp),%eax +} + 8001e6: 83 c4 20 add $0x20,%esp + 8001e9: 5b pop %ebx + 8001ea: 5e pop %esi + 8001eb: 5f pop %edi + 8001ec: 5d pop %ebp + 8001ed: c3 ret + +008001ee : + +int +sys_exit(int error_code) { + 8001ee: 55 push %ebp + 8001ef: 89 e5 mov %esp,%ebp + 8001f1: 83 ec 08 sub $0x8,%esp + return syscall(SYS_exit, error_code); + 8001f4: 8b 45 08 mov 0x8(%ebp),%eax + 8001f7: 89 44 24 04 mov %eax,0x4(%esp) + 8001fb: c7 04 24 01 00 00 00 movl $0x1,(%esp) + 800202: e8 92 ff ff ff call 800199 +} + 800207: 89 ec mov %ebp,%esp + 800209: 5d pop %ebp + 80020a: c3 ret + +0080020b : + +int +sys_fork(void) { + 80020b: 55 push %ebp + 80020c: 89 e5 mov %esp,%ebp + 80020e: 83 ec 04 sub $0x4,%esp + return syscall(SYS_fork); + 800211: c7 04 24 02 00 00 00 movl $0x2,(%esp) + 800218: e8 7c ff ff ff call 800199 +} + 80021d: 89 ec mov %ebp,%esp + 80021f: 5d pop %ebp + 800220: c3 ret + +00800221 : + +int +sys_wait(int pid, int *store) { + 800221: 55 push %ebp + 800222: 89 e5 mov %esp,%ebp + 800224: 83 ec 0c sub $0xc,%esp + return syscall(SYS_wait, pid, store); + 800227: 8b 45 0c mov 0xc(%ebp),%eax + 80022a: 89 44 24 08 mov %eax,0x8(%esp) + 80022e: 8b 45 08 mov 0x8(%ebp),%eax + 800231: 89 44 24 04 mov %eax,0x4(%esp) + 800235: c7 04 24 03 00 00 00 movl $0x3,(%esp) + 80023c: e8 58 ff ff ff call 800199 +} + 800241: 89 ec mov %ebp,%esp + 800243: 5d pop %ebp + 800244: c3 ret + +00800245 : + +int +sys_yield(void) { + 800245: 55 push %ebp + 800246: 89 e5 mov %esp,%ebp + 800248: 83 ec 04 sub $0x4,%esp + return syscall(SYS_yield); + 80024b: c7 04 24 0a 00 00 00 movl $0xa,(%esp) + 800252: e8 42 ff ff ff call 800199 +} + 800257: 89 ec mov %ebp,%esp + 800259: 5d pop %ebp + 80025a: c3 ret + +0080025b : + +int +sys_kill(int pid) { + 80025b: 55 push %ebp + 80025c: 89 e5 mov %esp,%ebp + 80025e: 83 ec 08 sub $0x8,%esp + return syscall(SYS_kill, pid); + 800261: 8b 45 08 mov 0x8(%ebp),%eax + 800264: 89 44 24 04 mov %eax,0x4(%esp) + 800268: c7 04 24 0c 00 00 00 movl $0xc,(%esp) + 80026f: e8 25 ff ff ff call 800199 +} + 800274: 89 ec mov %ebp,%esp + 800276: 5d pop %ebp + 800277: c3 ret + +00800278 : + +int +sys_getpid(void) { + 800278: 55 push %ebp + 800279: 89 e5 mov %esp,%ebp + 80027b: 83 ec 04 sub $0x4,%esp + return syscall(SYS_getpid); + 80027e: c7 04 24 12 00 00 00 movl $0x12,(%esp) + 800285: e8 0f ff ff ff call 800199 +} + 80028a: 89 ec mov %ebp,%esp + 80028c: 5d pop %ebp + 80028d: c3 ret + +0080028e : + +int +sys_putc(int c) { + 80028e: 55 push %ebp + 80028f: 89 e5 mov %esp,%ebp + 800291: 83 ec 08 sub $0x8,%esp + return syscall(SYS_putc, c); + 800294: 8b 45 08 mov 0x8(%ebp),%eax + 800297: 89 44 24 04 mov %eax,0x4(%esp) + 80029b: c7 04 24 1e 00 00 00 movl $0x1e,(%esp) + 8002a2: e8 f2 fe ff ff call 800199 +} + 8002a7: 89 ec mov %ebp,%esp + 8002a9: 5d pop %ebp + 8002aa: c3 ret + +008002ab : + +int +sys_pgdir(void) { + 8002ab: 55 push %ebp + 8002ac: 89 e5 mov %esp,%ebp + 8002ae: 83 ec 04 sub $0x4,%esp + return syscall(SYS_pgdir); + 8002b1: c7 04 24 1f 00 00 00 movl $0x1f,(%esp) + 8002b8: e8 dc fe ff ff call 800199 +} + 8002bd: 89 ec mov %ebp,%esp + 8002bf: 5d pop %ebp + 8002c0: c3 ret + +008002c1 : +#include +#include +#include + +void +exit(int error_code) { + 8002c1: 55 push %ebp + 8002c2: 89 e5 mov %esp,%ebp + 8002c4: 83 ec 18 sub $0x18,%esp + sys_exit(error_code); + 8002c7: 8b 45 08 mov 0x8(%ebp),%eax + 8002ca: 89 04 24 mov %eax,(%esp) + 8002cd: e8 1c ff ff ff call 8001ee + cprintf("BUG: exit failed.\n"); + 8002d2: c7 04 24 78 10 80 00 movl $0x801078,(%esp) + 8002d9: e8 42 fe ff ff call 800120 + while (1); + 8002de: eb fe jmp 8002de + +008002e0 : +} + +int +fork(void) { + 8002e0: 55 push %ebp + 8002e1: 89 e5 mov %esp,%ebp + 8002e3: 83 ec 08 sub $0x8,%esp + return sys_fork(); + 8002e6: e8 20 ff ff ff call 80020b +} + 8002eb: 89 ec mov %ebp,%esp + 8002ed: 5d pop %ebp + 8002ee: c3 ret + +008002ef : + +int +wait(void) { + 8002ef: 55 push %ebp + 8002f0: 89 e5 mov %esp,%ebp + 8002f2: 83 ec 18 sub $0x18,%esp + return sys_wait(0, NULL); + 8002f5: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) + 8002fc: 00 + 8002fd: c7 04 24 00 00 00 00 movl $0x0,(%esp) + 800304: e8 18 ff ff ff call 800221 +} + 800309: 89 ec mov %ebp,%esp + 80030b: 5d pop %ebp + 80030c: c3 ret + +0080030d : + +int +waitpid(int pid, int *store) { + 80030d: 55 push %ebp + 80030e: 89 e5 mov %esp,%ebp + 800310: 83 ec 18 sub $0x18,%esp + return sys_wait(pid, store); + 800313: 8b 45 0c mov 0xc(%ebp),%eax + 800316: 89 44 24 04 mov %eax,0x4(%esp) + 80031a: 8b 45 08 mov 0x8(%ebp),%eax + 80031d: 89 04 24 mov %eax,(%esp) + 800320: e8 fc fe ff ff call 800221 +} + 800325: 89 ec mov %ebp,%esp + 800327: 5d pop %ebp + 800328: c3 ret + +00800329 : + +void +yield(void) { + 800329: 55 push %ebp + 80032a: 89 e5 mov %esp,%ebp + 80032c: 83 ec 08 sub $0x8,%esp + sys_yield(); + 80032f: e8 11 ff ff ff call 800245 +} + 800334: 90 nop + 800335: 89 ec mov %ebp,%esp + 800337: 5d pop %ebp + 800338: c3 ret + +00800339 : + +int +kill(int pid) { + 800339: 55 push %ebp + 80033a: 89 e5 mov %esp,%ebp + 80033c: 83 ec 18 sub $0x18,%esp + return sys_kill(pid); + 80033f: 8b 45 08 mov 0x8(%ebp),%eax + 800342: 89 04 24 mov %eax,(%esp) + 800345: e8 11 ff ff ff call 80025b +} + 80034a: 89 ec mov %ebp,%esp + 80034c: 5d pop %ebp + 80034d: c3 ret + +0080034e : + +int +getpid(void) { + 80034e: 55 push %ebp + 80034f: 89 e5 mov %esp,%ebp + 800351: 83 ec 08 sub $0x8,%esp + return sys_getpid(); + 800354: e8 1f ff ff ff call 800278 +} + 800359: 89 ec mov %ebp,%esp + 80035b: 5d pop %ebp + 80035c: c3 ret + +0080035d : + +//print_pgdir - print the PDT&PT +void +print_pgdir(void) { + 80035d: 55 push %ebp + 80035e: 89 e5 mov %esp,%ebp + 800360: 83 ec 08 sub $0x8,%esp + sys_pgdir(); + 800363: e8 43 ff ff ff call 8002ab +} + 800368: 90 nop + 800369: 89 ec mov %ebp,%esp + 80036b: 5d pop %ebp + 80036c: c3 ret + +0080036d : +#include + +int main(void); + +void +umain(void) { + 80036d: 55 push %ebp + 80036e: 89 e5 mov %esp,%ebp + 800370: 83 ec 28 sub $0x28,%esp + int ret = main(); + 800373: e8 37 0c 00 00 call 800faf
+ 800378: 89 45 f4 mov %eax,-0xc(%ebp) + exit(ret); + 80037b: 8b 45 f4 mov -0xc(%ebp),%eax + 80037e: 89 04 24 mov %eax,(%esp) + 800381: e8 3b ff ff ff call 8002c1 + +00800386 : + * @bits: the number of bits in a return value + * + * High bits are more random, so we use them. + * */ +uint32_t +hash32(uint32_t val, unsigned int bits) { + 800386: 55 push %ebp + 800387: 89 e5 mov %esp,%ebp + 800389: 83 ec 10 sub $0x10,%esp + uint32_t hash = val * GOLDEN_RATIO_PRIME_32; + 80038c: 8b 45 08 mov 0x8(%ebp),%eax + 80038f: 69 c0 01 00 37 9e imul $0x9e370001,%eax,%eax + 800395: 89 45 fc mov %eax,-0x4(%ebp) + return (hash >> (32 - bits)); + 800398: b8 20 00 00 00 mov $0x20,%eax + 80039d: 2b 45 0c sub 0xc(%ebp),%eax + 8003a0: 8b 55 fc mov -0x4(%ebp),%edx + 8003a3: 88 c1 mov %al,%cl + 8003a5: d3 ea shr %cl,%edx + 8003a7: 89 d0 mov %edx,%eax +} + 8003a9: 89 ec mov %ebp,%esp + 8003ab: 5d pop %ebp + 8003ac: c3 ret + +008003ad : + * @width: maximum number of digits, if the actual width is less than @width, use @padc instead + * @padc: character that padded on the left if the actual width is less than @width + * */ +static void +printnum(void (*putch)(int, void*), void *putdat, + unsigned long long num, unsigned base, int width, int padc) { + 8003ad: 55 push %ebp + 8003ae: 89 e5 mov %esp,%ebp + 8003b0: 83 ec 58 sub $0x58,%esp + 8003b3: 8b 45 10 mov 0x10(%ebp),%eax + 8003b6: 89 45 d0 mov %eax,-0x30(%ebp) + 8003b9: 8b 45 14 mov 0x14(%ebp),%eax + 8003bc: 89 45 d4 mov %eax,-0x2c(%ebp) + unsigned long long result = num; + 8003bf: 8b 45 d0 mov -0x30(%ebp),%eax + 8003c2: 8b 55 d4 mov -0x2c(%ebp),%edx + 8003c5: 89 45 e8 mov %eax,-0x18(%ebp) + 8003c8: 89 55 ec mov %edx,-0x14(%ebp) + unsigned mod = do_div(result, base); + 8003cb: 8b 45 18 mov 0x18(%ebp),%eax + 8003ce: 89 45 e4 mov %eax,-0x1c(%ebp) + 8003d1: 8b 45 e8 mov -0x18(%ebp),%eax + 8003d4: 8b 55 ec mov -0x14(%ebp),%edx + 8003d7: 89 45 e0 mov %eax,-0x20(%ebp) + 8003da: 89 55 f0 mov %edx,-0x10(%ebp) + 8003dd: 8b 45 f0 mov -0x10(%ebp),%eax + 8003e0: 89 45 f4 mov %eax,-0xc(%ebp) + 8003e3: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) + 8003e7: 74 1c je 800405 + 8003e9: 8b 45 f0 mov -0x10(%ebp),%eax + 8003ec: ba 00 00 00 00 mov $0x0,%edx + 8003f1: f7 75 e4 divl -0x1c(%ebp) + 8003f4: 89 55 f4 mov %edx,-0xc(%ebp) + 8003f7: 8b 45 f0 mov -0x10(%ebp),%eax + 8003fa: ba 00 00 00 00 mov $0x0,%edx + 8003ff: f7 75 e4 divl -0x1c(%ebp) + 800402: 89 45 f0 mov %eax,-0x10(%ebp) + 800405: 8b 45 e0 mov -0x20(%ebp),%eax + 800408: 8b 55 f4 mov -0xc(%ebp),%edx + 80040b: f7 75 e4 divl -0x1c(%ebp) + 80040e: 89 45 e0 mov %eax,-0x20(%ebp) + 800411: 89 55 dc mov %edx,-0x24(%ebp) + 800414: 8b 45 e0 mov -0x20(%ebp),%eax + 800417: 8b 55 f0 mov -0x10(%ebp),%edx + 80041a: 89 45 e8 mov %eax,-0x18(%ebp) + 80041d: 89 55 ec mov %edx,-0x14(%ebp) + 800420: 8b 45 dc mov -0x24(%ebp),%eax + 800423: 89 45 d8 mov %eax,-0x28(%ebp) + + // first recursively print all preceding (more significant) digits + if (num >= base) { + 800426: 8b 45 18 mov 0x18(%ebp),%eax + 800429: ba 00 00 00 00 mov $0x0,%edx + 80042e: 8b 4d d4 mov -0x2c(%ebp),%ecx + 800431: 39 45 d0 cmp %eax,-0x30(%ebp) + 800434: 19 d1 sbb %edx,%ecx + 800436: 72 4c jb 800484 + printnum(putch, putdat, result, base, width - 1, padc); + 800438: 8b 45 1c mov 0x1c(%ebp),%eax + 80043b: 8d 50 ff lea -0x1(%eax),%edx + 80043e: 8b 45 20 mov 0x20(%ebp),%eax + 800441: 89 44 24 18 mov %eax,0x18(%esp) + 800445: 89 54 24 14 mov %edx,0x14(%esp) + 800449: 8b 45 18 mov 0x18(%ebp),%eax + 80044c: 89 44 24 10 mov %eax,0x10(%esp) + 800450: 8b 45 e8 mov -0x18(%ebp),%eax + 800453: 8b 55 ec mov -0x14(%ebp),%edx + 800456: 89 44 24 08 mov %eax,0x8(%esp) + 80045a: 89 54 24 0c mov %edx,0xc(%esp) + 80045e: 8b 45 0c mov 0xc(%ebp),%eax + 800461: 89 44 24 04 mov %eax,0x4(%esp) + 800465: 8b 45 08 mov 0x8(%ebp),%eax + 800468: 89 04 24 mov %eax,(%esp) + 80046b: e8 3d ff ff ff call 8003ad + 800470: eb 1b jmp 80048d + } else { + // print any needed pad characters before first digit + while (-- width > 0) + putch(padc, putdat); + 800472: 8b 45 0c mov 0xc(%ebp),%eax + 800475: 89 44 24 04 mov %eax,0x4(%esp) + 800479: 8b 45 20 mov 0x20(%ebp),%eax + 80047c: 89 04 24 mov %eax,(%esp) + 80047f: 8b 45 08 mov 0x8(%ebp),%eax + 800482: ff d0 call *%eax + while (-- width > 0) + 800484: ff 4d 1c decl 0x1c(%ebp) + 800487: 83 7d 1c 00 cmpl $0x0,0x1c(%ebp) + 80048b: 7f e5 jg 800472 + } + // then print this (the least significant) digit + putch("0123456789abcdef"[mod], putdat); + 80048d: 8b 45 d8 mov -0x28(%ebp),%eax + 800490: 05 a4 11 80 00 add $0x8011a4,%eax + 800495: 0f b6 00 movzbl (%eax),%eax + 800498: 0f be c0 movsbl %al,%eax + 80049b: 8b 55 0c mov 0xc(%ebp),%edx + 80049e: 89 54 24 04 mov %edx,0x4(%esp) + 8004a2: 89 04 24 mov %eax,(%esp) + 8004a5: 8b 45 08 mov 0x8(%ebp),%eax + 8004a8: ff d0 call *%eax +} + 8004aa: 90 nop + 8004ab: 89 ec mov %ebp,%esp + 8004ad: 5d pop %ebp + 8004ae: c3 ret + +008004af : + * getuint - get an unsigned int of various possible sizes from a varargs list + * @ap: a varargs list pointer + * @lflag: determines the size of the vararg that @ap points to + * */ +static unsigned long long +getuint(va_list *ap, int lflag) { + 8004af: 55 push %ebp + 8004b0: 89 e5 mov %esp,%ebp + if (lflag >= 2) { + 8004b2: 83 7d 0c 01 cmpl $0x1,0xc(%ebp) + 8004b6: 7e 14 jle 8004cc + return va_arg(*ap, unsigned long long); + 8004b8: 8b 45 08 mov 0x8(%ebp),%eax + 8004bb: 8b 00 mov (%eax),%eax + 8004bd: 8d 48 08 lea 0x8(%eax),%ecx + 8004c0: 8b 55 08 mov 0x8(%ebp),%edx + 8004c3: 89 0a mov %ecx,(%edx) + 8004c5: 8b 50 04 mov 0x4(%eax),%edx + 8004c8: 8b 00 mov (%eax),%eax + 8004ca: eb 30 jmp 8004fc + } + else if (lflag) { + 8004cc: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) + 8004d0: 74 16 je 8004e8 + return va_arg(*ap, unsigned long); + 8004d2: 8b 45 08 mov 0x8(%ebp),%eax + 8004d5: 8b 00 mov (%eax),%eax + 8004d7: 8d 48 04 lea 0x4(%eax),%ecx + 8004da: 8b 55 08 mov 0x8(%ebp),%edx + 8004dd: 89 0a mov %ecx,(%edx) + 8004df: 8b 00 mov (%eax),%eax + 8004e1: ba 00 00 00 00 mov $0x0,%edx + 8004e6: eb 14 jmp 8004fc + } + else { + return va_arg(*ap, unsigned int); + 8004e8: 8b 45 08 mov 0x8(%ebp),%eax + 8004eb: 8b 00 mov (%eax),%eax + 8004ed: 8d 48 04 lea 0x4(%eax),%ecx + 8004f0: 8b 55 08 mov 0x8(%ebp),%edx + 8004f3: 89 0a mov %ecx,(%edx) + 8004f5: 8b 00 mov (%eax),%eax + 8004f7: ba 00 00 00 00 mov $0x0,%edx + } +} + 8004fc: 5d pop %ebp + 8004fd: c3 ret + +008004fe : + * getint - same as getuint but signed, we can't use getuint because of sign extension + * @ap: a varargs list pointer + * @lflag: determines the size of the vararg that @ap points to + * */ +static long long +getint(va_list *ap, int lflag) { + 8004fe: 55 push %ebp + 8004ff: 89 e5 mov %esp,%ebp + if (lflag >= 2) { + 800501: 83 7d 0c 01 cmpl $0x1,0xc(%ebp) + 800505: 7e 14 jle 80051b + return va_arg(*ap, long long); + 800507: 8b 45 08 mov 0x8(%ebp),%eax + 80050a: 8b 00 mov (%eax),%eax + 80050c: 8d 48 08 lea 0x8(%eax),%ecx + 80050f: 8b 55 08 mov 0x8(%ebp),%edx + 800512: 89 0a mov %ecx,(%edx) + 800514: 8b 50 04 mov 0x4(%eax),%edx + 800517: 8b 00 mov (%eax),%eax + 800519: eb 28 jmp 800543 + } + else if (lflag) { + 80051b: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) + 80051f: 74 12 je 800533 + return va_arg(*ap, long); + 800521: 8b 45 08 mov 0x8(%ebp),%eax + 800524: 8b 00 mov (%eax),%eax + 800526: 8d 48 04 lea 0x4(%eax),%ecx + 800529: 8b 55 08 mov 0x8(%ebp),%edx + 80052c: 89 0a mov %ecx,(%edx) + 80052e: 8b 00 mov (%eax),%eax + 800530: 99 cltd + 800531: eb 10 jmp 800543 + } + else { + return va_arg(*ap, int); + 800533: 8b 45 08 mov 0x8(%ebp),%eax + 800536: 8b 00 mov (%eax),%eax + 800538: 8d 48 04 lea 0x4(%eax),%ecx + 80053b: 8b 55 08 mov 0x8(%ebp),%edx + 80053e: 89 0a mov %ecx,(%edx) + 800540: 8b 00 mov (%eax),%eax + 800542: 99 cltd + } +} + 800543: 5d pop %ebp + 800544: c3 ret + +00800545 : + * @putch: specified putch function, print a single character + * @putdat: used by @putch function + * @fmt: the format string to use + * */ +void +printfmt(void (*putch)(int, void*), void *putdat, const char *fmt, ...) { + 800545: 55 push %ebp + 800546: 89 e5 mov %esp,%ebp + 800548: 83 ec 28 sub $0x28,%esp + va_list ap; + + va_start(ap, fmt); + 80054b: 8d 45 14 lea 0x14(%ebp),%eax + 80054e: 89 45 f4 mov %eax,-0xc(%ebp) + vprintfmt(putch, putdat, fmt, ap); + 800551: 8b 45 f4 mov -0xc(%ebp),%eax + 800554: 89 44 24 0c mov %eax,0xc(%esp) + 800558: 8b 45 10 mov 0x10(%ebp),%eax + 80055b: 89 44 24 08 mov %eax,0x8(%esp) + 80055f: 8b 45 0c mov 0xc(%ebp),%eax + 800562: 89 44 24 04 mov %eax,0x4(%esp) + 800566: 8b 45 08 mov 0x8(%ebp),%eax + 800569: 89 04 24 mov %eax,(%esp) + 80056c: e8 05 00 00 00 call 800576 + va_end(ap); +} + 800571: 90 nop + 800572: 89 ec mov %ebp,%esp + 800574: 5d pop %ebp + 800575: c3 ret + +00800576 : + * + * Call this function if you are already dealing with a va_list. + * Or you probably want printfmt() instead. + * */ +void +vprintfmt(void (*putch)(int, void*), void *putdat, const char *fmt, va_list ap) { + 800576: 55 push %ebp + 800577: 89 e5 mov %esp,%ebp + 800579: 56 push %esi + 80057a: 53 push %ebx + 80057b: 83 ec 40 sub $0x40,%esp + register int ch, err; + unsigned long long num; + int base, width, precision, lflag, altflag; + + while (1) { + while ((ch = *(unsigned char *)fmt ++) != '%') { + 80057e: eb 17 jmp 800597 + if (ch == '\0') { + 800580: 85 db test %ebx,%ebx + 800582: 0f 84 bf 03 00 00 je 800947 + return; + } + putch(ch, putdat); + 800588: 8b 45 0c mov 0xc(%ebp),%eax + 80058b: 89 44 24 04 mov %eax,0x4(%esp) + 80058f: 89 1c 24 mov %ebx,(%esp) + 800592: 8b 45 08 mov 0x8(%ebp),%eax + 800595: ff d0 call *%eax + while ((ch = *(unsigned char *)fmt ++) != '%') { + 800597: 8b 45 10 mov 0x10(%ebp),%eax + 80059a: 8d 50 01 lea 0x1(%eax),%edx + 80059d: 89 55 10 mov %edx,0x10(%ebp) + 8005a0: 0f b6 00 movzbl (%eax),%eax + 8005a3: 0f b6 d8 movzbl %al,%ebx + 8005a6: 83 fb 25 cmp $0x25,%ebx + 8005a9: 75 d5 jne 800580 + } + + // Process a %-escape sequence + char padc = ' '; + 8005ab: c6 45 db 20 movb $0x20,-0x25(%ebp) + width = precision = -1; + 8005af: c7 45 e4 ff ff ff ff movl $0xffffffff,-0x1c(%ebp) + 8005b6: 8b 45 e4 mov -0x1c(%ebp),%eax + 8005b9: 89 45 e8 mov %eax,-0x18(%ebp) + lflag = altflag = 0; + 8005bc: c7 45 dc 00 00 00 00 movl $0x0,-0x24(%ebp) + 8005c3: 8b 45 dc mov -0x24(%ebp),%eax + 8005c6: 89 45 e0 mov %eax,-0x20(%ebp) + + reswitch: + switch (ch = *(unsigned char *)fmt ++) { + 8005c9: 8b 45 10 mov 0x10(%ebp),%eax + 8005cc: 8d 50 01 lea 0x1(%eax),%edx + 8005cf: 89 55 10 mov %edx,0x10(%ebp) + 8005d2: 0f b6 00 movzbl (%eax),%eax + 8005d5: 0f b6 d8 movzbl %al,%ebx + 8005d8: 8d 43 dd lea -0x23(%ebx),%eax + 8005db: 83 f8 55 cmp $0x55,%eax + 8005de: 0f 87 37 03 00 00 ja 80091b + 8005e4: 8b 04 85 c8 11 80 00 mov 0x8011c8(,%eax,4),%eax + 8005eb: ff e0 jmp *%eax + + // flag to pad on the right + case '-': + padc = '-'; + 8005ed: c6 45 db 2d movb $0x2d,-0x25(%ebp) + goto reswitch; + 8005f1: eb d6 jmp 8005c9 + + // flag to pad with 0's instead of spaces + case '0': + padc = '0'; + 8005f3: c6 45 db 30 movb $0x30,-0x25(%ebp) + goto reswitch; + 8005f7: eb d0 jmp 8005c9 + + // width field + case '1' ... '9': + for (precision = 0; ; ++ fmt) { + 8005f9: c7 45 e4 00 00 00 00 movl $0x0,-0x1c(%ebp) + precision = precision * 10 + ch - '0'; + 800600: 8b 55 e4 mov -0x1c(%ebp),%edx + 800603: 89 d0 mov %edx,%eax + 800605: c1 e0 02 shl $0x2,%eax + 800608: 01 d0 add %edx,%eax + 80060a: 01 c0 add %eax,%eax + 80060c: 01 d8 add %ebx,%eax + 80060e: 83 e8 30 sub $0x30,%eax + 800611: 89 45 e4 mov %eax,-0x1c(%ebp) + ch = *fmt; + 800614: 8b 45 10 mov 0x10(%ebp),%eax + 800617: 0f b6 00 movzbl (%eax),%eax + 80061a: 0f be d8 movsbl %al,%ebx + if (ch < '0' || ch > '9') { + 80061d: 83 fb 2f cmp $0x2f,%ebx + 800620: 7e 38 jle 80065a + 800622: 83 fb 39 cmp $0x39,%ebx + 800625: 7f 33 jg 80065a + for (precision = 0; ; ++ fmt) { + 800627: ff 45 10 incl 0x10(%ebp) + precision = precision * 10 + ch - '0'; + 80062a: eb d4 jmp 800600 + } + } + goto process_precision; + + case '*': + precision = va_arg(ap, int); + 80062c: 8b 45 14 mov 0x14(%ebp),%eax + 80062f: 8d 50 04 lea 0x4(%eax),%edx + 800632: 89 55 14 mov %edx,0x14(%ebp) + 800635: 8b 00 mov (%eax),%eax + 800637: 89 45 e4 mov %eax,-0x1c(%ebp) + goto process_precision; + 80063a: eb 1f jmp 80065b + + case '.': + if (width < 0) + 80063c: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 800640: 79 87 jns 8005c9 + width = 0; + 800642: c7 45 e8 00 00 00 00 movl $0x0,-0x18(%ebp) + goto reswitch; + 800649: e9 7b ff ff ff jmp 8005c9 + + case '#': + altflag = 1; + 80064e: c7 45 dc 01 00 00 00 movl $0x1,-0x24(%ebp) + goto reswitch; + 800655: e9 6f ff ff ff jmp 8005c9 + goto process_precision; + 80065a: 90 nop + + process_precision: + if (width < 0) + 80065b: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 80065f: 0f 89 64 ff ff ff jns 8005c9 + width = precision, precision = -1; + 800665: 8b 45 e4 mov -0x1c(%ebp),%eax + 800668: 89 45 e8 mov %eax,-0x18(%ebp) + 80066b: c7 45 e4 ff ff ff ff movl $0xffffffff,-0x1c(%ebp) + goto reswitch; + 800672: e9 52 ff ff ff jmp 8005c9 + + // long flag (doubled for long long) + case 'l': + lflag ++; + 800677: ff 45 e0 incl -0x20(%ebp) + goto reswitch; + 80067a: e9 4a ff ff ff jmp 8005c9 + + // character + case 'c': + putch(va_arg(ap, int), putdat); + 80067f: 8b 45 14 mov 0x14(%ebp),%eax + 800682: 8d 50 04 lea 0x4(%eax),%edx + 800685: 89 55 14 mov %edx,0x14(%ebp) + 800688: 8b 00 mov (%eax),%eax + 80068a: 8b 55 0c mov 0xc(%ebp),%edx + 80068d: 89 54 24 04 mov %edx,0x4(%esp) + 800691: 89 04 24 mov %eax,(%esp) + 800694: 8b 45 08 mov 0x8(%ebp),%eax + 800697: ff d0 call *%eax + break; + 800699: e9 a4 02 00 00 jmp 800942 + + // error message + case 'e': + err = va_arg(ap, int); + 80069e: 8b 45 14 mov 0x14(%ebp),%eax + 8006a1: 8d 50 04 lea 0x4(%eax),%edx + 8006a4: 89 55 14 mov %edx,0x14(%ebp) + 8006a7: 8b 18 mov (%eax),%ebx + if (err < 0) { + 8006a9: 85 db test %ebx,%ebx + 8006ab: 79 02 jns 8006af + err = -err; + 8006ad: f7 db neg %ebx + } + if (err > MAXERROR || (p = error_string[err]) == NULL) { + 8006af: 83 fb 18 cmp $0x18,%ebx + 8006b2: 7f 0b jg 8006bf + 8006b4: 8b 34 9d 40 11 80 00 mov 0x801140(,%ebx,4),%esi + 8006bb: 85 f6 test %esi,%esi + 8006bd: 75 23 jne 8006e2 + printfmt(putch, putdat, "error %d", err); + 8006bf: 89 5c 24 0c mov %ebx,0xc(%esp) + 8006c3: c7 44 24 08 b5 11 80 movl $0x8011b5,0x8(%esp) + 8006ca: 00 + 8006cb: 8b 45 0c mov 0xc(%ebp),%eax + 8006ce: 89 44 24 04 mov %eax,0x4(%esp) + 8006d2: 8b 45 08 mov 0x8(%ebp),%eax + 8006d5: 89 04 24 mov %eax,(%esp) + 8006d8: e8 68 fe ff ff call 800545 + } + else { + printfmt(putch, putdat, "%s", p); + } + break; + 8006dd: e9 60 02 00 00 jmp 800942 + printfmt(putch, putdat, "%s", p); + 8006e2: 89 74 24 0c mov %esi,0xc(%esp) + 8006e6: c7 44 24 08 be 11 80 movl $0x8011be,0x8(%esp) + 8006ed: 00 + 8006ee: 8b 45 0c mov 0xc(%ebp),%eax + 8006f1: 89 44 24 04 mov %eax,0x4(%esp) + 8006f5: 8b 45 08 mov 0x8(%ebp),%eax + 8006f8: 89 04 24 mov %eax,(%esp) + 8006fb: e8 45 fe ff ff call 800545 + break; + 800700: e9 3d 02 00 00 jmp 800942 + + // string + case 's': + if ((p = va_arg(ap, char *)) == NULL) { + 800705: 8b 45 14 mov 0x14(%ebp),%eax + 800708: 8d 50 04 lea 0x4(%eax),%edx + 80070b: 89 55 14 mov %edx,0x14(%ebp) + 80070e: 8b 30 mov (%eax),%esi + 800710: 85 f6 test %esi,%esi + 800712: 75 05 jne 800719 + p = "(null)"; + 800714: be c1 11 80 00 mov $0x8011c1,%esi + } + if (width > 0 && padc != '-') { + 800719: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 80071d: 7e 76 jle 800795 + 80071f: 80 7d db 2d cmpb $0x2d,-0x25(%ebp) + 800723: 74 70 je 800795 + for (width -= strnlen(p, precision); width > 0; width --) { + 800725: 8b 45 e4 mov -0x1c(%ebp),%eax + 800728: 89 44 24 04 mov %eax,0x4(%esp) + 80072c: 89 34 24 mov %esi,(%esp) + 80072f: e8 ee 03 00 00 call 800b22 + 800734: 89 c2 mov %eax,%edx + 800736: 8b 45 e8 mov -0x18(%ebp),%eax + 800739: 29 d0 sub %edx,%eax + 80073b: 89 45 e8 mov %eax,-0x18(%ebp) + 80073e: eb 16 jmp 800756 + putch(padc, putdat); + 800740: 0f be 45 db movsbl -0x25(%ebp),%eax + 800744: 8b 55 0c mov 0xc(%ebp),%edx + 800747: 89 54 24 04 mov %edx,0x4(%esp) + 80074b: 89 04 24 mov %eax,(%esp) + 80074e: 8b 45 08 mov 0x8(%ebp),%eax + 800751: ff d0 call *%eax + for (width -= strnlen(p, precision); width > 0; width --) { + 800753: ff 4d e8 decl -0x18(%ebp) + 800756: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 80075a: 7f e4 jg 800740 + } + } + for (; (ch = *p ++) != '\0' && (precision < 0 || -- precision >= 0); width --) { + 80075c: eb 37 jmp 800795 + if (altflag && (ch < ' ' || ch > '~')) { + 80075e: 83 7d dc 00 cmpl $0x0,-0x24(%ebp) + 800762: 74 1f je 800783 + 800764: 83 fb 1f cmp $0x1f,%ebx + 800767: 7e 05 jle 80076e + 800769: 83 fb 7e cmp $0x7e,%ebx + 80076c: 7e 15 jle 800783 + putch('?', putdat); + 80076e: 8b 45 0c mov 0xc(%ebp),%eax + 800771: 89 44 24 04 mov %eax,0x4(%esp) + 800775: c7 04 24 3f 00 00 00 movl $0x3f,(%esp) + 80077c: 8b 45 08 mov 0x8(%ebp),%eax + 80077f: ff d0 call *%eax + 800781: eb 0f jmp 800792 + } + else { + putch(ch, putdat); + 800783: 8b 45 0c mov 0xc(%ebp),%eax + 800786: 89 44 24 04 mov %eax,0x4(%esp) + 80078a: 89 1c 24 mov %ebx,(%esp) + 80078d: 8b 45 08 mov 0x8(%ebp),%eax + 800790: ff d0 call *%eax + for (; (ch = *p ++) != '\0' && (precision < 0 || -- precision >= 0); width --) { + 800792: ff 4d e8 decl -0x18(%ebp) + 800795: 89 f0 mov %esi,%eax + 800797: 8d 70 01 lea 0x1(%eax),%esi + 80079a: 0f b6 00 movzbl (%eax),%eax + 80079d: 0f be d8 movsbl %al,%ebx + 8007a0: 85 db test %ebx,%ebx + 8007a2: 74 27 je 8007cb + 8007a4: 83 7d e4 00 cmpl $0x0,-0x1c(%ebp) + 8007a8: 78 b4 js 80075e + 8007aa: ff 4d e4 decl -0x1c(%ebp) + 8007ad: 83 7d e4 00 cmpl $0x0,-0x1c(%ebp) + 8007b1: 79 ab jns 80075e + } + } + for (; width > 0; width --) { + 8007b3: eb 16 jmp 8007cb + putch(' ', putdat); + 8007b5: 8b 45 0c mov 0xc(%ebp),%eax + 8007b8: 89 44 24 04 mov %eax,0x4(%esp) + 8007bc: c7 04 24 20 00 00 00 movl $0x20,(%esp) + 8007c3: 8b 45 08 mov 0x8(%ebp),%eax + 8007c6: ff d0 call *%eax + for (; width > 0; width --) { + 8007c8: ff 4d e8 decl -0x18(%ebp) + 8007cb: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 8007cf: 7f e4 jg 8007b5 + } + break; + 8007d1: e9 6c 01 00 00 jmp 800942 + + // (signed) decimal + case 'd': + num = getint(&ap, lflag); + 8007d6: 8b 45 e0 mov -0x20(%ebp),%eax + 8007d9: 89 44 24 04 mov %eax,0x4(%esp) + 8007dd: 8d 45 14 lea 0x14(%ebp),%eax + 8007e0: 89 04 24 mov %eax,(%esp) + 8007e3: e8 16 fd ff ff call 8004fe + 8007e8: 89 45 f0 mov %eax,-0x10(%ebp) + 8007eb: 89 55 f4 mov %edx,-0xc(%ebp) + if ((long long)num < 0) { + 8007ee: 8b 45 f0 mov -0x10(%ebp),%eax + 8007f1: 8b 55 f4 mov -0xc(%ebp),%edx + 8007f4: 85 d2 test %edx,%edx + 8007f6: 79 26 jns 80081e + putch('-', putdat); + 8007f8: 8b 45 0c mov 0xc(%ebp),%eax + 8007fb: 89 44 24 04 mov %eax,0x4(%esp) + 8007ff: c7 04 24 2d 00 00 00 movl $0x2d,(%esp) + 800806: 8b 45 08 mov 0x8(%ebp),%eax + 800809: ff d0 call *%eax + num = -(long long)num; + 80080b: 8b 45 f0 mov -0x10(%ebp),%eax + 80080e: 8b 55 f4 mov -0xc(%ebp),%edx + 800811: f7 d8 neg %eax + 800813: 83 d2 00 adc $0x0,%edx + 800816: f7 da neg %edx + 800818: 89 45 f0 mov %eax,-0x10(%ebp) + 80081b: 89 55 f4 mov %edx,-0xc(%ebp) + } + base = 10; + 80081e: c7 45 ec 0a 00 00 00 movl $0xa,-0x14(%ebp) + goto number; + 800825: e9 a8 00 00 00 jmp 8008d2 + + // unsigned decimal + case 'u': + num = getuint(&ap, lflag); + 80082a: 8b 45 e0 mov -0x20(%ebp),%eax + 80082d: 89 44 24 04 mov %eax,0x4(%esp) + 800831: 8d 45 14 lea 0x14(%ebp),%eax + 800834: 89 04 24 mov %eax,(%esp) + 800837: e8 73 fc ff ff call 8004af + 80083c: 89 45 f0 mov %eax,-0x10(%ebp) + 80083f: 89 55 f4 mov %edx,-0xc(%ebp) + base = 10; + 800842: c7 45 ec 0a 00 00 00 movl $0xa,-0x14(%ebp) + goto number; + 800849: e9 84 00 00 00 jmp 8008d2 + + // (unsigned) octal + case 'o': + num = getuint(&ap, lflag); + 80084e: 8b 45 e0 mov -0x20(%ebp),%eax + 800851: 89 44 24 04 mov %eax,0x4(%esp) + 800855: 8d 45 14 lea 0x14(%ebp),%eax + 800858: 89 04 24 mov %eax,(%esp) + 80085b: e8 4f fc ff ff call 8004af + 800860: 89 45 f0 mov %eax,-0x10(%ebp) + 800863: 89 55 f4 mov %edx,-0xc(%ebp) + base = 8; + 800866: c7 45 ec 08 00 00 00 movl $0x8,-0x14(%ebp) + goto number; + 80086d: eb 63 jmp 8008d2 + + // pointer + case 'p': + putch('0', putdat); + 80086f: 8b 45 0c mov 0xc(%ebp),%eax + 800872: 89 44 24 04 mov %eax,0x4(%esp) + 800876: c7 04 24 30 00 00 00 movl $0x30,(%esp) + 80087d: 8b 45 08 mov 0x8(%ebp),%eax + 800880: ff d0 call *%eax + putch('x', putdat); + 800882: 8b 45 0c mov 0xc(%ebp),%eax + 800885: 89 44 24 04 mov %eax,0x4(%esp) + 800889: c7 04 24 78 00 00 00 movl $0x78,(%esp) + 800890: 8b 45 08 mov 0x8(%ebp),%eax + 800893: ff d0 call *%eax + num = (unsigned long long)(uintptr_t)va_arg(ap, void *); + 800895: 8b 45 14 mov 0x14(%ebp),%eax + 800898: 8d 50 04 lea 0x4(%eax),%edx + 80089b: 89 55 14 mov %edx,0x14(%ebp) + 80089e: 8b 00 mov (%eax),%eax + 8008a0: 89 45 f0 mov %eax,-0x10(%ebp) + 8008a3: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + base = 16; + 8008aa: c7 45 ec 10 00 00 00 movl $0x10,-0x14(%ebp) + goto number; + 8008b1: eb 1f jmp 8008d2 + + // (unsigned) hexadecimal + case 'x': + num = getuint(&ap, lflag); + 8008b3: 8b 45 e0 mov -0x20(%ebp),%eax + 8008b6: 89 44 24 04 mov %eax,0x4(%esp) + 8008ba: 8d 45 14 lea 0x14(%ebp),%eax + 8008bd: 89 04 24 mov %eax,(%esp) + 8008c0: e8 ea fb ff ff call 8004af + 8008c5: 89 45 f0 mov %eax,-0x10(%ebp) + 8008c8: 89 55 f4 mov %edx,-0xc(%ebp) + base = 16; + 8008cb: c7 45 ec 10 00 00 00 movl $0x10,-0x14(%ebp) + number: + printnum(putch, putdat, num, base, width, padc); + 8008d2: 0f be 55 db movsbl -0x25(%ebp),%edx + 8008d6: 8b 45 ec mov -0x14(%ebp),%eax + 8008d9: 89 54 24 18 mov %edx,0x18(%esp) + 8008dd: 8b 55 e8 mov -0x18(%ebp),%edx + 8008e0: 89 54 24 14 mov %edx,0x14(%esp) + 8008e4: 89 44 24 10 mov %eax,0x10(%esp) + 8008e8: 8b 45 f0 mov -0x10(%ebp),%eax + 8008eb: 8b 55 f4 mov -0xc(%ebp),%edx + 8008ee: 89 44 24 08 mov %eax,0x8(%esp) + 8008f2: 89 54 24 0c mov %edx,0xc(%esp) + 8008f6: 8b 45 0c mov 0xc(%ebp),%eax + 8008f9: 89 44 24 04 mov %eax,0x4(%esp) + 8008fd: 8b 45 08 mov 0x8(%ebp),%eax + 800900: 89 04 24 mov %eax,(%esp) + 800903: e8 a5 fa ff ff call 8003ad + break; + 800908: eb 38 jmp 800942 + + // escaped '%' character + case '%': + putch(ch, putdat); + 80090a: 8b 45 0c mov 0xc(%ebp),%eax + 80090d: 89 44 24 04 mov %eax,0x4(%esp) + 800911: 89 1c 24 mov %ebx,(%esp) + 800914: 8b 45 08 mov 0x8(%ebp),%eax + 800917: ff d0 call *%eax + break; + 800919: eb 27 jmp 800942 + + // unrecognized escape sequence - just print it literally + default: + putch('%', putdat); + 80091b: 8b 45 0c mov 0xc(%ebp),%eax + 80091e: 89 44 24 04 mov %eax,0x4(%esp) + 800922: c7 04 24 25 00 00 00 movl $0x25,(%esp) + 800929: 8b 45 08 mov 0x8(%ebp),%eax + 80092c: ff d0 call *%eax + for (fmt --; fmt[-1] != '%'; fmt --) + 80092e: ff 4d 10 decl 0x10(%ebp) + 800931: eb 03 jmp 800936 + 800933: ff 4d 10 decl 0x10(%ebp) + 800936: 8b 45 10 mov 0x10(%ebp),%eax + 800939: 48 dec %eax + 80093a: 0f b6 00 movzbl (%eax),%eax + 80093d: 3c 25 cmp $0x25,%al + 80093f: 75 f2 jne 800933 + /* do nothing */; + break; + 800941: 90 nop + while (1) { + 800942: e9 37 fc ff ff jmp 80057e + return; + 800947: 90 nop + } + } +} + 800948: 83 c4 40 add $0x40,%esp + 80094b: 5b pop %ebx + 80094c: 5e pop %esi + 80094d: 5d pop %ebp + 80094e: c3 ret + +0080094f : + * sprintputch - 'print' a single character in a buffer + * @ch: the character will be printed + * @b: the buffer to place the character @ch + * */ +static void +sprintputch(int ch, struct sprintbuf *b) { + 80094f: 55 push %ebp + 800950: 89 e5 mov %esp,%ebp + b->cnt ++; + 800952: 8b 45 0c mov 0xc(%ebp),%eax + 800955: 8b 40 08 mov 0x8(%eax),%eax + 800958: 8d 50 01 lea 0x1(%eax),%edx + 80095b: 8b 45 0c mov 0xc(%ebp),%eax + 80095e: 89 50 08 mov %edx,0x8(%eax) + if (b->buf < b->ebuf) { + 800961: 8b 45 0c mov 0xc(%ebp),%eax + 800964: 8b 10 mov (%eax),%edx + 800966: 8b 45 0c mov 0xc(%ebp),%eax + 800969: 8b 40 04 mov 0x4(%eax),%eax + 80096c: 39 c2 cmp %eax,%edx + 80096e: 73 12 jae 800982 + *b->buf ++ = ch; + 800970: 8b 45 0c mov 0xc(%ebp),%eax + 800973: 8b 00 mov (%eax),%eax + 800975: 8d 48 01 lea 0x1(%eax),%ecx + 800978: 8b 55 0c mov 0xc(%ebp),%edx + 80097b: 89 0a mov %ecx,(%edx) + 80097d: 8b 55 08 mov 0x8(%ebp),%edx + 800980: 88 10 mov %dl,(%eax) + } +} + 800982: 90 nop + 800983: 5d pop %ebp + 800984: c3 ret + +00800985 : + * @str: the buffer to place the result into + * @size: the size of buffer, including the trailing null space + * @fmt: the format string to use + * */ +int +snprintf(char *str, size_t size, const char *fmt, ...) { + 800985: 55 push %ebp + 800986: 89 e5 mov %esp,%ebp + 800988: 83 ec 28 sub $0x28,%esp + va_list ap; + int cnt; + va_start(ap, fmt); + 80098b: 8d 45 14 lea 0x14(%ebp),%eax + 80098e: 89 45 f0 mov %eax,-0x10(%ebp) + cnt = vsnprintf(str, size, fmt, ap); + 800991: 8b 45 f0 mov -0x10(%ebp),%eax + 800994: 89 44 24 0c mov %eax,0xc(%esp) + 800998: 8b 45 10 mov 0x10(%ebp),%eax + 80099b: 89 44 24 08 mov %eax,0x8(%esp) + 80099f: 8b 45 0c mov 0xc(%ebp),%eax + 8009a2: 89 44 24 04 mov %eax,0x4(%esp) + 8009a6: 8b 45 08 mov 0x8(%ebp),%eax + 8009a9: 89 04 24 mov %eax,(%esp) + 8009ac: e8 0a 00 00 00 call 8009bb + 8009b1: 89 45 f4 mov %eax,-0xc(%ebp) + va_end(ap); + return cnt; + 8009b4: 8b 45 f4 mov -0xc(%ebp),%eax +} + 8009b7: 89 ec mov %ebp,%esp + 8009b9: 5d pop %ebp + 8009ba: c3 ret + +008009bb : + * + * Call this function if you are already dealing with a va_list. + * Or you probably want snprintf() instead. + * */ +int +vsnprintf(char *str, size_t size, const char *fmt, va_list ap) { + 8009bb: 55 push %ebp + 8009bc: 89 e5 mov %esp,%ebp + 8009be: 83 ec 28 sub $0x28,%esp + struct sprintbuf b = {str, str + size - 1, 0}; + 8009c1: 8b 45 08 mov 0x8(%ebp),%eax + 8009c4: 89 45 ec mov %eax,-0x14(%ebp) + 8009c7: 8b 45 0c mov 0xc(%ebp),%eax + 8009ca: 8d 50 ff lea -0x1(%eax),%edx + 8009cd: 8b 45 08 mov 0x8(%ebp),%eax + 8009d0: 01 d0 add %edx,%eax + 8009d2: 89 45 f0 mov %eax,-0x10(%ebp) + 8009d5: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + if (str == NULL || b.buf > b.ebuf) { + 8009dc: 83 7d 08 00 cmpl $0x0,0x8(%ebp) + 8009e0: 74 0a je 8009ec + 8009e2: 8b 55 ec mov -0x14(%ebp),%edx + 8009e5: 8b 45 f0 mov -0x10(%ebp),%eax + 8009e8: 39 c2 cmp %eax,%edx + 8009ea: 76 07 jbe 8009f3 + return -E_INVAL; + 8009ec: b8 fd ff ff ff mov $0xfffffffd,%eax + 8009f1: eb 2a jmp 800a1d + } + // print the string to the buffer + vprintfmt((void*)sprintputch, &b, fmt, ap); + 8009f3: 8b 45 14 mov 0x14(%ebp),%eax + 8009f6: 89 44 24 0c mov %eax,0xc(%esp) + 8009fa: 8b 45 10 mov 0x10(%ebp),%eax + 8009fd: 89 44 24 08 mov %eax,0x8(%esp) + 800a01: 8d 45 ec lea -0x14(%ebp),%eax + 800a04: 89 44 24 04 mov %eax,0x4(%esp) + 800a08: c7 04 24 4f 09 80 00 movl $0x80094f,(%esp) + 800a0f: e8 62 fb ff ff call 800576 + // null terminate the buffer + *b.buf = '\0'; + 800a14: 8b 45 ec mov -0x14(%ebp),%eax + 800a17: c6 00 00 movb $0x0,(%eax) + return b.cnt; + 800a1a: 8b 45 f4 mov -0xc(%ebp),%eax +} + 800a1d: 89 ec mov %ebp,%esp + 800a1f: 5d pop %ebp + 800a20: c3 ret + +00800a21 : + * rand - returns a pseudo-random integer + * + * The rand() function return a value in the range [0, RAND_MAX]. + * */ +int +rand(void) { + 800a21: 55 push %ebp + 800a22: 89 e5 mov %esp,%ebp + 800a24: 57 push %edi + 800a25: 56 push %esi + 800a26: 53 push %ebx + 800a27: 83 ec 24 sub $0x24,%esp + next = (next * 0x5DEECE66DLL + 0xBLL) & ((1LL << 48) - 1); + 800a2a: a1 00 20 80 00 mov 0x802000,%eax + 800a2f: 8b 15 04 20 80 00 mov 0x802004,%edx + 800a35: 69 fa 6d e6 ec de imul $0xdeece66d,%edx,%edi + 800a3b: 6b f0 05 imul $0x5,%eax,%esi + 800a3e: 01 fe add %edi,%esi + 800a40: bf 6d e6 ec de mov $0xdeece66d,%edi + 800a45: f7 e7 mul %edi + 800a47: 01 d6 add %edx,%esi + 800a49: 89 f2 mov %esi,%edx + 800a4b: 83 c0 0b add $0xb,%eax + 800a4e: 83 d2 00 adc $0x0,%edx + 800a51: 89 c7 mov %eax,%edi + 800a53: 83 e7 ff and $0xffffffff,%edi + 800a56: 89 f9 mov %edi,%ecx + 800a58: 0f b7 da movzwl %dx,%ebx + 800a5b: 89 0d 00 20 80 00 mov %ecx,0x802000 + 800a61: 89 1d 04 20 80 00 mov %ebx,0x802004 + unsigned long long result = (next >> 12); + 800a67: a1 00 20 80 00 mov 0x802000,%eax + 800a6c: 8b 15 04 20 80 00 mov 0x802004,%edx + 800a72: 0f ac d0 0c shrd $0xc,%edx,%eax + 800a76: c1 ea 0c shr $0xc,%edx + 800a79: 89 45 e0 mov %eax,-0x20(%ebp) + 800a7c: 89 55 e4 mov %edx,-0x1c(%ebp) + return (int)do_div(result, RAND_MAX + 1); + 800a7f: c7 45 dc 00 00 00 80 movl $0x80000000,-0x24(%ebp) + 800a86: 8b 45 e0 mov -0x20(%ebp),%eax + 800a89: 8b 55 e4 mov -0x1c(%ebp),%edx + 800a8c: 89 45 d8 mov %eax,-0x28(%ebp) + 800a8f: 89 55 e8 mov %edx,-0x18(%ebp) + 800a92: 8b 45 e8 mov -0x18(%ebp),%eax + 800a95: 89 45 ec mov %eax,-0x14(%ebp) + 800a98: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 800a9c: 74 1c je 800aba + 800a9e: 8b 45 e8 mov -0x18(%ebp),%eax + 800aa1: ba 00 00 00 00 mov $0x0,%edx + 800aa6: f7 75 dc divl -0x24(%ebp) + 800aa9: 89 55 ec mov %edx,-0x14(%ebp) + 800aac: 8b 45 e8 mov -0x18(%ebp),%eax + 800aaf: ba 00 00 00 00 mov $0x0,%edx + 800ab4: f7 75 dc divl -0x24(%ebp) + 800ab7: 89 45 e8 mov %eax,-0x18(%ebp) + 800aba: 8b 45 d8 mov -0x28(%ebp),%eax + 800abd: 8b 55 ec mov -0x14(%ebp),%edx + 800ac0: f7 75 dc divl -0x24(%ebp) + 800ac3: 89 45 d8 mov %eax,-0x28(%ebp) + 800ac6: 89 55 d4 mov %edx,-0x2c(%ebp) + 800ac9: 8b 45 d8 mov -0x28(%ebp),%eax + 800acc: 8b 55 e8 mov -0x18(%ebp),%edx + 800acf: 89 45 e0 mov %eax,-0x20(%ebp) + 800ad2: 89 55 e4 mov %edx,-0x1c(%ebp) + 800ad5: 8b 45 d4 mov -0x2c(%ebp),%eax +} + 800ad8: 83 c4 24 add $0x24,%esp + 800adb: 5b pop %ebx + 800adc: 5e pop %esi + 800add: 5f pop %edi + 800ade: 5d pop %ebp + 800adf: c3 ret + +00800ae0 : +/* * + * srand - seed the random number generator with the given number + * @seed: the required seed number + * */ +void +srand(unsigned int seed) { + 800ae0: 55 push %ebp + 800ae1: 89 e5 mov %esp,%ebp + next = seed; + 800ae3: 8b 45 08 mov 0x8(%ebp),%eax + 800ae6: ba 00 00 00 00 mov $0x0,%edx + 800aeb: a3 00 20 80 00 mov %eax,0x802000 + 800af0: 89 15 04 20 80 00 mov %edx,0x802004 +} + 800af6: 90 nop + 800af7: 5d pop %ebp + 800af8: c3 ret + +00800af9 : + * @s: the input string + * + * The strlen() function returns the length of string @s. + * */ +size_t +strlen(const char *s) { + 800af9: 55 push %ebp + 800afa: 89 e5 mov %esp,%ebp + 800afc: 83 ec 10 sub $0x10,%esp + size_t cnt = 0; + 800aff: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + while (*s ++ != '\0') { + 800b06: eb 03 jmp 800b0b + cnt ++; + 800b08: ff 45 fc incl -0x4(%ebp) + while (*s ++ != '\0') { + 800b0b: 8b 45 08 mov 0x8(%ebp),%eax + 800b0e: 8d 50 01 lea 0x1(%eax),%edx + 800b11: 89 55 08 mov %edx,0x8(%ebp) + 800b14: 0f b6 00 movzbl (%eax),%eax + 800b17: 84 c0 test %al,%al + 800b19: 75 ed jne 800b08 + } + return cnt; + 800b1b: 8b 45 fc mov -0x4(%ebp),%eax +} + 800b1e: 89 ec mov %ebp,%esp + 800b20: 5d pop %ebp + 800b21: c3 ret + +00800b22 : + * The return value is strlen(s), if that is less than @len, or + * @len if there is no '\0' character among the first @len characters + * pointed by @s. + * */ +size_t +strnlen(const char *s, size_t len) { + 800b22: 55 push %ebp + 800b23: 89 e5 mov %esp,%ebp + 800b25: 83 ec 10 sub $0x10,%esp + size_t cnt = 0; + 800b28: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + while (cnt < len && *s ++ != '\0') { + 800b2f: eb 03 jmp 800b34 + cnt ++; + 800b31: ff 45 fc incl -0x4(%ebp) + while (cnt < len && *s ++ != '\0') { + 800b34: 8b 45 fc mov -0x4(%ebp),%eax + 800b37: 3b 45 0c cmp 0xc(%ebp),%eax + 800b3a: 73 10 jae 800b4c + 800b3c: 8b 45 08 mov 0x8(%ebp),%eax + 800b3f: 8d 50 01 lea 0x1(%eax),%edx + 800b42: 89 55 08 mov %edx,0x8(%ebp) + 800b45: 0f b6 00 movzbl (%eax),%eax + 800b48: 84 c0 test %al,%al + 800b4a: 75 e5 jne 800b31 + } + return cnt; + 800b4c: 8b 45 fc mov -0x4(%ebp),%eax +} + 800b4f: 89 ec mov %ebp,%esp + 800b51: 5d pop %ebp + 800b52: c3 ret + +00800b53 : + * To avoid overflows, the size of array pointed by @dst should be long enough to + * contain the same string as @src (including the terminating null character), and + * should not overlap in memory with @src. + * */ +char * +strcpy(char *dst, const char *src) { + 800b53: 55 push %ebp + 800b54: 89 e5 mov %esp,%ebp + 800b56: 57 push %edi + 800b57: 56 push %esi + 800b58: 83 ec 20 sub $0x20,%esp + 800b5b: 8b 45 08 mov 0x8(%ebp),%eax + 800b5e: 89 45 f4 mov %eax,-0xc(%ebp) + 800b61: 8b 45 0c mov 0xc(%ebp),%eax + 800b64: 89 45 f0 mov %eax,-0x10(%ebp) +#ifndef __HAVE_ARCH_STRCPY +#define __HAVE_ARCH_STRCPY +static inline char * +__strcpy(char *dst, const char *src) { + int d0, d1, d2; + asm volatile ( + 800b67: 8b 55 f0 mov -0x10(%ebp),%edx + 800b6a: 8b 45 f4 mov -0xc(%ebp),%eax + 800b6d: 89 d1 mov %edx,%ecx + 800b6f: 89 c2 mov %eax,%edx + 800b71: 89 ce mov %ecx,%esi + 800b73: 89 d7 mov %edx,%edi + 800b75: ac lods %ds:(%esi),%al + 800b76: aa stos %al,%es:(%edi) + 800b77: 84 c0 test %al,%al + 800b79: 75 fa jne 800b75 + 800b7b: 89 fa mov %edi,%edx + 800b7d: 89 f1 mov %esi,%ecx + 800b7f: 89 4d ec mov %ecx,-0x14(%ebp) + 800b82: 89 55 e8 mov %edx,-0x18(%ebp) + 800b85: 89 45 e4 mov %eax,-0x1c(%ebp) + "stosb;" + "testb %%al, %%al;" + "jne 1b;" + : "=&S" (d0), "=&D" (d1), "=&a" (d2) + : "0" (src), "1" (dst) : "memory"); + return dst; + 800b88: 8b 45 f4 mov -0xc(%ebp),%eax + char *p = dst; + while ((*p ++ = *src ++) != '\0') + /* nothing */; + return dst; +#endif /* __HAVE_ARCH_STRCPY */ +} + 800b8b: 83 c4 20 add $0x20,%esp + 800b8e: 5e pop %esi + 800b8f: 5f pop %edi + 800b90: 5d pop %ebp + 800b91: c3 ret + +00800b92 : + * @len: maximum number of characters to be copied from @src + * + * The return value is @dst + * */ +char * +strncpy(char *dst, const char *src, size_t len) { + 800b92: 55 push %ebp + 800b93: 89 e5 mov %esp,%ebp + 800b95: 83 ec 10 sub $0x10,%esp + char *p = dst; + 800b98: 8b 45 08 mov 0x8(%ebp),%eax + 800b9b: 89 45 fc mov %eax,-0x4(%ebp) + while (len > 0) { + 800b9e: eb 1e jmp 800bbe + if ((*p = *src) != '\0') { + 800ba0: 8b 45 0c mov 0xc(%ebp),%eax + 800ba3: 0f b6 10 movzbl (%eax),%edx + 800ba6: 8b 45 fc mov -0x4(%ebp),%eax + 800ba9: 88 10 mov %dl,(%eax) + 800bab: 8b 45 fc mov -0x4(%ebp),%eax + 800bae: 0f b6 00 movzbl (%eax),%eax + 800bb1: 84 c0 test %al,%al + 800bb3: 74 03 je 800bb8 + src ++; + 800bb5: ff 45 0c incl 0xc(%ebp) + } + p ++, len --; + 800bb8: ff 45 fc incl -0x4(%ebp) + 800bbb: ff 4d 10 decl 0x10(%ebp) + while (len > 0) { + 800bbe: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800bc2: 75 dc jne 800ba0 + } + return dst; + 800bc4: 8b 45 08 mov 0x8(%ebp),%eax +} + 800bc7: 89 ec mov %ebp,%esp + 800bc9: 5d pop %ebp + 800bca: c3 ret + +00800bcb : + * - A value greater than zero indicates that the first character that does + * not match has a greater value in @s1 than in @s2; + * - And a value less than zero indicates the opposite. + * */ +int +strcmp(const char *s1, const char *s2) { + 800bcb: 55 push %ebp + 800bcc: 89 e5 mov %esp,%ebp + 800bce: 57 push %edi + 800bcf: 56 push %esi + 800bd0: 83 ec 20 sub $0x20,%esp + 800bd3: 8b 45 08 mov 0x8(%ebp),%eax + 800bd6: 89 45 f4 mov %eax,-0xc(%ebp) + 800bd9: 8b 45 0c mov 0xc(%ebp),%eax + 800bdc: 89 45 f0 mov %eax,-0x10(%ebp) + asm volatile ( + 800bdf: 8b 55 f4 mov -0xc(%ebp),%edx + 800be2: 8b 45 f0 mov -0x10(%ebp),%eax + 800be5: 89 d1 mov %edx,%ecx + 800be7: 89 c2 mov %eax,%edx + 800be9: 89 ce mov %ecx,%esi + 800beb: 89 d7 mov %edx,%edi + 800bed: ac lods %ds:(%esi),%al + 800bee: ae scas %es:(%edi),%al + 800bef: 75 08 jne 800bf9 + 800bf1: 84 c0 test %al,%al + 800bf3: 75 f8 jne 800bed + 800bf5: 31 c0 xor %eax,%eax + 800bf7: eb 04 jmp 800bfd + 800bf9: 19 c0 sbb %eax,%eax + 800bfb: 0c 01 or $0x1,%al + 800bfd: 89 fa mov %edi,%edx + 800bff: 89 f1 mov %esi,%ecx + 800c01: 89 45 ec mov %eax,-0x14(%ebp) + 800c04: 89 4d e8 mov %ecx,-0x18(%ebp) + 800c07: 89 55 e4 mov %edx,-0x1c(%ebp) + return ret; + 800c0a: 8b 45 ec mov -0x14(%ebp),%eax + while (*s1 != '\0' && *s1 == *s2) { + s1 ++, s2 ++; + } + return (int)((unsigned char)*s1 - (unsigned char)*s2); +#endif /* __HAVE_ARCH_STRCMP */ +} + 800c0d: 83 c4 20 add $0x20,%esp + 800c10: 5e pop %esi + 800c11: 5f pop %edi + 800c12: 5d pop %ebp + 800c13: c3 ret + +00800c14 : + * they are equal to each other, it continues with the following pairs until + * the characters differ, until a terminating null-character is reached, or + * until @n characters match in both strings, whichever happens first. + * */ +int +strncmp(const char *s1, const char *s2, size_t n) { + 800c14: 55 push %ebp + 800c15: 89 e5 mov %esp,%ebp + while (n > 0 && *s1 != '\0' && *s1 == *s2) { + 800c17: eb 09 jmp 800c22 + n --, s1 ++, s2 ++; + 800c19: ff 4d 10 decl 0x10(%ebp) + 800c1c: ff 45 08 incl 0x8(%ebp) + 800c1f: ff 45 0c incl 0xc(%ebp) + while (n > 0 && *s1 != '\0' && *s1 == *s2) { + 800c22: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800c26: 74 1a je 800c42 + 800c28: 8b 45 08 mov 0x8(%ebp),%eax + 800c2b: 0f b6 00 movzbl (%eax),%eax + 800c2e: 84 c0 test %al,%al + 800c30: 74 10 je 800c42 + 800c32: 8b 45 08 mov 0x8(%ebp),%eax + 800c35: 0f b6 10 movzbl (%eax),%edx + 800c38: 8b 45 0c mov 0xc(%ebp),%eax + 800c3b: 0f b6 00 movzbl (%eax),%eax + 800c3e: 38 c2 cmp %al,%dl + 800c40: 74 d7 je 800c19 + } + return (n == 0) ? 0 : (int)((unsigned char)*s1 - (unsigned char)*s2); + 800c42: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800c46: 74 18 je 800c60 + 800c48: 8b 45 08 mov 0x8(%ebp),%eax + 800c4b: 0f b6 00 movzbl (%eax),%eax + 800c4e: 0f b6 d0 movzbl %al,%edx + 800c51: 8b 45 0c mov 0xc(%ebp),%eax + 800c54: 0f b6 00 movzbl (%eax),%eax + 800c57: 0f b6 c8 movzbl %al,%ecx + 800c5a: 89 d0 mov %edx,%eax + 800c5c: 29 c8 sub %ecx,%eax + 800c5e: eb 05 jmp 800c65 + 800c60: b8 00 00 00 00 mov $0x0,%eax +} + 800c65: 5d pop %ebp + 800c66: c3 ret + +00800c67 : + * + * The strchr() function returns a pointer to the first occurrence of + * character in @s. If the value is not found, the function returns 'NULL'. + * */ +char * +strchr(const char *s, char c) { + 800c67: 55 push %ebp + 800c68: 89 e5 mov %esp,%ebp + 800c6a: 83 ec 04 sub $0x4,%esp + 800c6d: 8b 45 0c mov 0xc(%ebp),%eax + 800c70: 88 45 fc mov %al,-0x4(%ebp) + while (*s != '\0') { + 800c73: eb 13 jmp 800c88 + if (*s == c) { + 800c75: 8b 45 08 mov 0x8(%ebp),%eax + 800c78: 0f b6 00 movzbl (%eax),%eax + 800c7b: 38 45 fc cmp %al,-0x4(%ebp) + 800c7e: 75 05 jne 800c85 + return (char *)s; + 800c80: 8b 45 08 mov 0x8(%ebp),%eax + 800c83: eb 12 jmp 800c97 + } + s ++; + 800c85: ff 45 08 incl 0x8(%ebp) + while (*s != '\0') { + 800c88: 8b 45 08 mov 0x8(%ebp),%eax + 800c8b: 0f b6 00 movzbl (%eax),%eax + 800c8e: 84 c0 test %al,%al + 800c90: 75 e3 jne 800c75 + } + return NULL; + 800c92: b8 00 00 00 00 mov $0x0,%eax +} + 800c97: 89 ec mov %ebp,%esp + 800c99: 5d pop %ebp + 800c9a: c3 ret + +00800c9b : + * The strfind() function is like strchr() except that if @c is + * not found in @s, then it returns a pointer to the null byte at the + * end of @s, rather than 'NULL'. + * */ +char * +strfind(const char *s, char c) { + 800c9b: 55 push %ebp + 800c9c: 89 e5 mov %esp,%ebp + 800c9e: 83 ec 04 sub $0x4,%esp + 800ca1: 8b 45 0c mov 0xc(%ebp),%eax + 800ca4: 88 45 fc mov %al,-0x4(%ebp) + while (*s != '\0') { + 800ca7: eb 0e jmp 800cb7 + if (*s == c) { + 800ca9: 8b 45 08 mov 0x8(%ebp),%eax + 800cac: 0f b6 00 movzbl (%eax),%eax + 800caf: 38 45 fc cmp %al,-0x4(%ebp) + 800cb2: 74 0f je 800cc3 + break; + } + s ++; + 800cb4: ff 45 08 incl 0x8(%ebp) + while (*s != '\0') { + 800cb7: 8b 45 08 mov 0x8(%ebp),%eax + 800cba: 0f b6 00 movzbl (%eax),%eax + 800cbd: 84 c0 test %al,%al + 800cbf: 75 e8 jne 800ca9 + 800cc1: eb 01 jmp 800cc4 + break; + 800cc3: 90 nop + } + return (char *)s; + 800cc4: 8b 45 08 mov 0x8(%ebp),%eax +} + 800cc7: 89 ec mov %ebp,%esp + 800cc9: 5d pop %ebp + 800cca: c3 ret + +00800ccb : + * an optional "0x" or "0X" prefix. + * + * The strtol() function returns the converted integral number as a long int value. + * */ +long +strtol(const char *s, char **endptr, int base) { + 800ccb: 55 push %ebp + 800ccc: 89 e5 mov %esp,%ebp + 800cce: 83 ec 10 sub $0x10,%esp + int neg = 0; + 800cd1: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + long val = 0; + 800cd8: c7 45 f8 00 00 00 00 movl $0x0,-0x8(%ebp) + + // gobble initial whitespace + while (*s == ' ' || *s == '\t') { + 800cdf: eb 03 jmp 800ce4 + s ++; + 800ce1: ff 45 08 incl 0x8(%ebp) + while (*s == ' ' || *s == '\t') { + 800ce4: 8b 45 08 mov 0x8(%ebp),%eax + 800ce7: 0f b6 00 movzbl (%eax),%eax + 800cea: 3c 20 cmp $0x20,%al + 800cec: 74 f3 je 800ce1 + 800cee: 8b 45 08 mov 0x8(%ebp),%eax + 800cf1: 0f b6 00 movzbl (%eax),%eax + 800cf4: 3c 09 cmp $0x9,%al + 800cf6: 74 e9 je 800ce1 + } + + // plus/minus sign + if (*s == '+') { + 800cf8: 8b 45 08 mov 0x8(%ebp),%eax + 800cfb: 0f b6 00 movzbl (%eax),%eax + 800cfe: 3c 2b cmp $0x2b,%al + 800d00: 75 05 jne 800d07 + s ++; + 800d02: ff 45 08 incl 0x8(%ebp) + 800d05: eb 14 jmp 800d1b + } + else if (*s == '-') { + 800d07: 8b 45 08 mov 0x8(%ebp),%eax + 800d0a: 0f b6 00 movzbl (%eax),%eax + 800d0d: 3c 2d cmp $0x2d,%al + 800d0f: 75 0a jne 800d1b + s ++, neg = 1; + 800d11: ff 45 08 incl 0x8(%ebp) + 800d14: c7 45 fc 01 00 00 00 movl $0x1,-0x4(%ebp) + } + + // hex or octal base prefix + if ((base == 0 || base == 16) && (s[0] == '0' && s[1] == 'x')) { + 800d1b: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800d1f: 74 06 je 800d27 + 800d21: 83 7d 10 10 cmpl $0x10,0x10(%ebp) + 800d25: 75 22 jne 800d49 + 800d27: 8b 45 08 mov 0x8(%ebp),%eax + 800d2a: 0f b6 00 movzbl (%eax),%eax + 800d2d: 3c 30 cmp $0x30,%al + 800d2f: 75 18 jne 800d49 + 800d31: 8b 45 08 mov 0x8(%ebp),%eax + 800d34: 40 inc %eax + 800d35: 0f b6 00 movzbl (%eax),%eax + 800d38: 3c 78 cmp $0x78,%al + 800d3a: 75 0d jne 800d49 + s += 2, base = 16; + 800d3c: 83 45 08 02 addl $0x2,0x8(%ebp) + 800d40: c7 45 10 10 00 00 00 movl $0x10,0x10(%ebp) + 800d47: eb 29 jmp 800d72 + } + else if (base == 0 && s[0] == '0') { + 800d49: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800d4d: 75 16 jne 800d65 + 800d4f: 8b 45 08 mov 0x8(%ebp),%eax + 800d52: 0f b6 00 movzbl (%eax),%eax + 800d55: 3c 30 cmp $0x30,%al + 800d57: 75 0c jne 800d65 + s ++, base = 8; + 800d59: ff 45 08 incl 0x8(%ebp) + 800d5c: c7 45 10 08 00 00 00 movl $0x8,0x10(%ebp) + 800d63: eb 0d jmp 800d72 + } + else if (base == 0) { + 800d65: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 800d69: 75 07 jne 800d72 + base = 10; + 800d6b: c7 45 10 0a 00 00 00 movl $0xa,0x10(%ebp) + + // digits + while (1) { + int dig; + + if (*s >= '0' && *s <= '9') { + 800d72: 8b 45 08 mov 0x8(%ebp),%eax + 800d75: 0f b6 00 movzbl (%eax),%eax + 800d78: 3c 2f cmp $0x2f,%al + 800d7a: 7e 1b jle 800d97 + 800d7c: 8b 45 08 mov 0x8(%ebp),%eax + 800d7f: 0f b6 00 movzbl (%eax),%eax + 800d82: 3c 39 cmp $0x39,%al + 800d84: 7f 11 jg 800d97 + dig = *s - '0'; + 800d86: 8b 45 08 mov 0x8(%ebp),%eax + 800d89: 0f b6 00 movzbl (%eax),%eax + 800d8c: 0f be c0 movsbl %al,%eax + 800d8f: 83 e8 30 sub $0x30,%eax + 800d92: 89 45 f4 mov %eax,-0xc(%ebp) + 800d95: eb 48 jmp 800ddf + } + else if (*s >= 'a' && *s <= 'z') { + 800d97: 8b 45 08 mov 0x8(%ebp),%eax + 800d9a: 0f b6 00 movzbl (%eax),%eax + 800d9d: 3c 60 cmp $0x60,%al + 800d9f: 7e 1b jle 800dbc + 800da1: 8b 45 08 mov 0x8(%ebp),%eax + 800da4: 0f b6 00 movzbl (%eax),%eax + 800da7: 3c 7a cmp $0x7a,%al + 800da9: 7f 11 jg 800dbc + dig = *s - 'a' + 10; + 800dab: 8b 45 08 mov 0x8(%ebp),%eax + 800dae: 0f b6 00 movzbl (%eax),%eax + 800db1: 0f be c0 movsbl %al,%eax + 800db4: 83 e8 57 sub $0x57,%eax + 800db7: 89 45 f4 mov %eax,-0xc(%ebp) + 800dba: eb 23 jmp 800ddf + } + else if (*s >= 'A' && *s <= 'Z') { + 800dbc: 8b 45 08 mov 0x8(%ebp),%eax + 800dbf: 0f b6 00 movzbl (%eax),%eax + 800dc2: 3c 40 cmp $0x40,%al + 800dc4: 7e 3b jle 800e01 + 800dc6: 8b 45 08 mov 0x8(%ebp),%eax + 800dc9: 0f b6 00 movzbl (%eax),%eax + 800dcc: 3c 5a cmp $0x5a,%al + 800dce: 7f 31 jg 800e01 + dig = *s - 'A' + 10; + 800dd0: 8b 45 08 mov 0x8(%ebp),%eax + 800dd3: 0f b6 00 movzbl (%eax),%eax + 800dd6: 0f be c0 movsbl %al,%eax + 800dd9: 83 e8 37 sub $0x37,%eax + 800ddc: 89 45 f4 mov %eax,-0xc(%ebp) + } + else { + break; + } + if (dig >= base) { + 800ddf: 8b 45 f4 mov -0xc(%ebp),%eax + 800de2: 3b 45 10 cmp 0x10(%ebp),%eax + 800de5: 7d 19 jge 800e00 + break; + } + s ++, val = (val * base) + dig; + 800de7: ff 45 08 incl 0x8(%ebp) + 800dea: 8b 45 f8 mov -0x8(%ebp),%eax + 800ded: 0f af 45 10 imul 0x10(%ebp),%eax + 800df1: 89 c2 mov %eax,%edx + 800df3: 8b 45 f4 mov -0xc(%ebp),%eax + 800df6: 01 d0 add %edx,%eax + 800df8: 89 45 f8 mov %eax,-0x8(%ebp) + while (1) { + 800dfb: e9 72 ff ff ff jmp 800d72 + break; + 800e00: 90 nop + // we don't properly detect overflow! + } + + if (endptr) { + 800e01: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) + 800e05: 74 08 je 800e0f + *endptr = (char *) s; + 800e07: 8b 45 0c mov 0xc(%ebp),%eax + 800e0a: 8b 55 08 mov 0x8(%ebp),%edx + 800e0d: 89 10 mov %edx,(%eax) + } + return (neg ? -val : val); + 800e0f: 83 7d fc 00 cmpl $0x0,-0x4(%ebp) + 800e13: 74 07 je 800e1c + 800e15: 8b 45 f8 mov -0x8(%ebp),%eax + 800e18: f7 d8 neg %eax + 800e1a: eb 03 jmp 800e1f + 800e1c: 8b 45 f8 mov -0x8(%ebp),%eax +} + 800e1f: 89 ec mov %ebp,%esp + 800e21: 5d pop %ebp + 800e22: c3 ret + +00800e23 : + * @n: number of bytes to be set to the value + * + * The memset() function returns @s. + * */ +void * +memset(void *s, char c, size_t n) { + 800e23: 55 push %ebp + 800e24: 89 e5 mov %esp,%ebp + 800e26: 83 ec 28 sub $0x28,%esp + 800e29: 89 7d fc mov %edi,-0x4(%ebp) + 800e2c: 8b 45 0c mov 0xc(%ebp),%eax + 800e2f: 88 45 d8 mov %al,-0x28(%ebp) +#ifdef __HAVE_ARCH_MEMSET + return __memset(s, c, n); + 800e32: 0f be 55 d8 movsbl -0x28(%ebp),%edx + 800e36: 8b 45 08 mov 0x8(%ebp),%eax + 800e39: 89 45 f8 mov %eax,-0x8(%ebp) + 800e3c: 88 55 f7 mov %dl,-0x9(%ebp) + 800e3f: 8b 45 10 mov 0x10(%ebp),%eax + 800e42: 89 45 f0 mov %eax,-0x10(%ebp) +#ifndef __HAVE_ARCH_MEMSET +#define __HAVE_ARCH_MEMSET +static inline void * +__memset(void *s, char c, size_t n) { + int d0, d1; + asm volatile ( + 800e45: 8b 4d f0 mov -0x10(%ebp),%ecx + 800e48: 0f b6 45 f7 movzbl -0x9(%ebp),%eax + 800e4c: 8b 55 f8 mov -0x8(%ebp),%edx + 800e4f: 89 d7 mov %edx,%edi + 800e51: f3 aa rep stos %al,%es:(%edi) + 800e53: 89 fa mov %edi,%edx + 800e55: 89 4d ec mov %ecx,-0x14(%ebp) + 800e58: 89 55 e8 mov %edx,-0x18(%ebp) + "rep; stosb;" + : "=&c" (d0), "=&D" (d1) + : "0" (n), "a" (c), "1" (s) + : "memory"); + return s; + 800e5b: 8b 45 f8 mov -0x8(%ebp),%eax + while (n -- > 0) { + *p ++ = c; + } + return s; +#endif /* __HAVE_ARCH_MEMSET */ +} + 800e5e: 8b 7d fc mov -0x4(%ebp),%edi + 800e61: 89 ec mov %ebp,%esp + 800e63: 5d pop %ebp + 800e64: c3 ret + +00800e65 : + * @n: number of bytes to copy + * + * The memmove() function returns @dst. + * */ +void * +memmove(void *dst, const void *src, size_t n) { + 800e65: 55 push %ebp + 800e66: 89 e5 mov %esp,%ebp + 800e68: 57 push %edi + 800e69: 56 push %esi + 800e6a: 53 push %ebx + 800e6b: 83 ec 30 sub $0x30,%esp + 800e6e: 8b 45 08 mov 0x8(%ebp),%eax + 800e71: 89 45 f0 mov %eax,-0x10(%ebp) + 800e74: 8b 45 0c mov 0xc(%ebp),%eax + 800e77: 89 45 ec mov %eax,-0x14(%ebp) + 800e7a: 8b 45 10 mov 0x10(%ebp),%eax + 800e7d: 89 45 e8 mov %eax,-0x18(%ebp) + +#ifndef __HAVE_ARCH_MEMMOVE +#define __HAVE_ARCH_MEMMOVE +static inline void * +__memmove(void *dst, const void *src, size_t n) { + if (dst < src) { + 800e80: 8b 45 f0 mov -0x10(%ebp),%eax + 800e83: 3b 45 ec cmp -0x14(%ebp),%eax + 800e86: 73 42 jae 800eca + 800e88: 8b 45 f0 mov -0x10(%ebp),%eax + 800e8b: 89 45 e4 mov %eax,-0x1c(%ebp) + 800e8e: 8b 45 ec mov -0x14(%ebp),%eax + 800e91: 89 45 e0 mov %eax,-0x20(%ebp) + 800e94: 8b 45 e8 mov -0x18(%ebp),%eax + 800e97: 89 45 dc mov %eax,-0x24(%ebp) + "andl $3, %%ecx;" + "jz 1f;" + "rep; movsb;" + "1:" + : "=&c" (d0), "=&D" (d1), "=&S" (d2) + : "0" (n / 4), "g" (n), "1" (dst), "2" (src) + 800e9a: 8b 45 dc mov -0x24(%ebp),%eax + 800e9d: c1 e8 02 shr $0x2,%eax + 800ea0: 89 c1 mov %eax,%ecx + asm volatile ( + 800ea2: 8b 55 e4 mov -0x1c(%ebp),%edx + 800ea5: 8b 45 e0 mov -0x20(%ebp),%eax + 800ea8: 89 d7 mov %edx,%edi + 800eaa: 89 c6 mov %eax,%esi + 800eac: f3 a5 rep movsl %ds:(%esi),%es:(%edi) + 800eae: 8b 4d dc mov -0x24(%ebp),%ecx + 800eb1: 83 e1 03 and $0x3,%ecx + 800eb4: 74 02 je 800eb8 + 800eb6: f3 a4 rep movsb %ds:(%esi),%es:(%edi) + 800eb8: 89 f0 mov %esi,%eax + 800eba: 89 fa mov %edi,%edx + 800ebc: 89 4d d8 mov %ecx,-0x28(%ebp) + 800ebf: 89 55 d4 mov %edx,-0x2c(%ebp) + 800ec2: 89 45 d0 mov %eax,-0x30(%ebp) + : "memory"); + return dst; + 800ec5: 8b 45 e4 mov -0x1c(%ebp),%eax + return __memcpy(dst, src, n); + 800ec8: eb 36 jmp 800f00 + : "0" (n), "1" (n - 1 + src), "2" (n - 1 + dst) + 800eca: 8b 45 e8 mov -0x18(%ebp),%eax + 800ecd: 8d 50 ff lea -0x1(%eax),%edx + 800ed0: 8b 45 ec mov -0x14(%ebp),%eax + 800ed3: 01 c2 add %eax,%edx + 800ed5: 8b 45 e8 mov -0x18(%ebp),%eax + 800ed8: 8d 48 ff lea -0x1(%eax),%ecx + 800edb: 8b 45 f0 mov -0x10(%ebp),%eax + 800ede: 8d 1c 01 lea (%ecx,%eax,1),%ebx + asm volatile ( + 800ee1: 8b 45 e8 mov -0x18(%ebp),%eax + 800ee4: 89 c1 mov %eax,%ecx + 800ee6: 89 d8 mov %ebx,%eax + 800ee8: 89 d6 mov %edx,%esi + 800eea: 89 c7 mov %eax,%edi + 800eec: fd std + 800eed: f3 a4 rep movsb %ds:(%esi),%es:(%edi) + 800eef: fc cld + 800ef0: 89 f8 mov %edi,%eax + 800ef2: 89 f2 mov %esi,%edx + 800ef4: 89 4d cc mov %ecx,-0x34(%ebp) + 800ef7: 89 55 c8 mov %edx,-0x38(%ebp) + 800efa: 89 45 c4 mov %eax,-0x3c(%ebp) + return dst; + 800efd: 8b 45 f0 mov -0x10(%ebp),%eax + *d ++ = *s ++; + } + } + return dst; +#endif /* __HAVE_ARCH_MEMMOVE */ +} + 800f00: 83 c4 30 add $0x30,%esp + 800f03: 5b pop %ebx + 800f04: 5e pop %esi + 800f05: 5f pop %edi + 800f06: 5d pop %ebp + 800f07: c3 ret + +00800f08 : + * it always copies exactly @n bytes. To avoid overflows, the size of arrays pointed + * by both @src and @dst, should be at least @n bytes, and should not overlap + * (for overlapping memory area, memmove is a safer approach). + * */ +void * +memcpy(void *dst, const void *src, size_t n) { + 800f08: 55 push %ebp + 800f09: 89 e5 mov %esp,%ebp + 800f0b: 57 push %edi + 800f0c: 56 push %esi + 800f0d: 83 ec 20 sub $0x20,%esp + 800f10: 8b 45 08 mov 0x8(%ebp),%eax + 800f13: 89 45 f4 mov %eax,-0xc(%ebp) + 800f16: 8b 45 0c mov 0xc(%ebp),%eax + 800f19: 89 45 f0 mov %eax,-0x10(%ebp) + 800f1c: 8b 45 10 mov 0x10(%ebp),%eax + 800f1f: 89 45 ec mov %eax,-0x14(%ebp) + : "0" (n / 4), "g" (n), "1" (dst), "2" (src) + 800f22: 8b 45 ec mov -0x14(%ebp),%eax + 800f25: c1 e8 02 shr $0x2,%eax + 800f28: 89 c1 mov %eax,%ecx + asm volatile ( + 800f2a: 8b 55 f4 mov -0xc(%ebp),%edx + 800f2d: 8b 45 f0 mov -0x10(%ebp),%eax + 800f30: 89 d7 mov %edx,%edi + 800f32: 89 c6 mov %eax,%esi + 800f34: f3 a5 rep movsl %ds:(%esi),%es:(%edi) + 800f36: 8b 4d ec mov -0x14(%ebp),%ecx + 800f39: 83 e1 03 and $0x3,%ecx + 800f3c: 74 02 je 800f40 + 800f3e: f3 a4 rep movsb %ds:(%esi),%es:(%edi) + 800f40: 89 f0 mov %esi,%eax + 800f42: 89 fa mov %edi,%edx + 800f44: 89 4d e8 mov %ecx,-0x18(%ebp) + 800f47: 89 55 e4 mov %edx,-0x1c(%ebp) + 800f4a: 89 45 e0 mov %eax,-0x20(%ebp) + return dst; + 800f4d: 8b 45 f4 mov -0xc(%ebp),%eax + while (n -- > 0) { + *d ++ = *s ++; + } + return dst; +#endif /* __HAVE_ARCH_MEMCPY */ +} + 800f50: 83 c4 20 add $0x20,%esp + 800f53: 5e pop %esi + 800f54: 5f pop %edi + 800f55: 5d pop %ebp + 800f56: c3 ret + +00800f57 : + * match in both memory blocks has a greater value in @v1 than in @v2 + * as if evaluated as unsigned char values; + * - And a value less than zero indicates the opposite. + * */ +int +memcmp(const void *v1, const void *v2, size_t n) { + 800f57: 55 push %ebp + 800f58: 89 e5 mov %esp,%ebp + 800f5a: 83 ec 10 sub $0x10,%esp + const char *s1 = (const char *)v1; + 800f5d: 8b 45 08 mov 0x8(%ebp),%eax + 800f60: 89 45 fc mov %eax,-0x4(%ebp) + const char *s2 = (const char *)v2; + 800f63: 8b 45 0c mov 0xc(%ebp),%eax + 800f66: 89 45 f8 mov %eax,-0x8(%ebp) + while (n -- > 0) { + 800f69: eb 2e jmp 800f99 + if (*s1 != *s2) { + 800f6b: 8b 45 fc mov -0x4(%ebp),%eax + 800f6e: 0f b6 10 movzbl (%eax),%edx + 800f71: 8b 45 f8 mov -0x8(%ebp),%eax + 800f74: 0f b6 00 movzbl (%eax),%eax + 800f77: 38 c2 cmp %al,%dl + 800f79: 74 18 je 800f93 + return (int)((unsigned char)*s1 - (unsigned char)*s2); + 800f7b: 8b 45 fc mov -0x4(%ebp),%eax + 800f7e: 0f b6 00 movzbl (%eax),%eax + 800f81: 0f b6 d0 movzbl %al,%edx + 800f84: 8b 45 f8 mov -0x8(%ebp),%eax + 800f87: 0f b6 00 movzbl (%eax),%eax + 800f8a: 0f b6 c8 movzbl %al,%ecx + 800f8d: 89 d0 mov %edx,%eax + 800f8f: 29 c8 sub %ecx,%eax + 800f91: eb 18 jmp 800fab + } + s1 ++, s2 ++; + 800f93: ff 45 fc incl -0x4(%ebp) + 800f96: ff 45 f8 incl -0x8(%ebp) + while (n -- > 0) { + 800f99: 8b 45 10 mov 0x10(%ebp),%eax + 800f9c: 8d 50 ff lea -0x1(%eax),%edx + 800f9f: 89 55 10 mov %edx,0x10(%ebp) + 800fa2: 85 c0 test %eax,%eax + 800fa4: 75 c5 jne 800f6b + } + return 0; + 800fa6: b8 00 00 00 00 mov $0x0,%eax +} + 800fab: 89 ec mov %ebp,%esp + 800fad: 5d pop %ebp + 800fae: c3 ret + +00800faf
: +#include +#include + +int +main(void) { + 800faf: 55 push %ebp + 800fb0: 89 e5 mov %esp,%ebp + 800fb2: 83 e4 f0 and $0xfffffff0,%esp + 800fb5: 83 ec 20 sub $0x20,%esp + int i; + cprintf("Hello, I am process %d.\n", getpid()); + 800fb8: e8 91 f3 ff ff call 80034e + 800fbd: 89 44 24 04 mov %eax,0x4(%esp) + 800fc1: c7 04 24 20 13 80 00 movl $0x801320,(%esp) + 800fc8: e8 53 f1 ff ff call 800120 + for (i = 0; i < 5; i ++) { + 800fcd: c7 44 24 1c 00 00 00 movl $0x0,0x1c(%esp) + 800fd4: 00 + 800fd5: eb 26 jmp 800ffd + yield(); + 800fd7: e8 4d f3 ff ff call 800329 + cprintf("Back in process %d, iteration %d.\n", getpid(), i); + 800fdc: e8 6d f3 ff ff call 80034e + 800fe1: 8b 54 24 1c mov 0x1c(%esp),%edx + 800fe5: 89 54 24 08 mov %edx,0x8(%esp) + 800fe9: 89 44 24 04 mov %eax,0x4(%esp) + 800fed: c7 04 24 3c 13 80 00 movl $0x80133c,(%esp) + 800ff4: e8 27 f1 ff ff call 800120 + for (i = 0; i < 5; i ++) { + 800ff9: ff 44 24 1c incl 0x1c(%esp) + 800ffd: 83 7c 24 1c 04 cmpl $0x4,0x1c(%esp) + 801002: 7e d3 jle 800fd7 + } + cprintf("All done in process %d.\n", getpid()); + 801004: e8 45 f3 ff ff call 80034e + 801009: 89 44 24 04 mov %eax,0x4(%esp) + 80100d: c7 04 24 5f 13 80 00 movl $0x80135f,(%esp) + 801014: e8 07 f1 ff ff call 800120 + cprintf("yield pass.\n"); + 801019: c7 04 24 78 13 80 00 movl $0x801378,(%esp) + 801020: e8 fb f0 ff ff call 800120 + return 0; + 801025: b8 00 00 00 00 mov $0x0,%eax +} + 80102a: 89 ec mov %ebp,%esp + 80102c: 5d pop %ebp + 80102d: c3 ret diff --git a/labcodes/lab5/obj/user/yield.d b/labcodes/lab5/obj/user/yield.d new file mode 100644 index 0000000000000000000000000000000000000000..ca92619982b0606256b298121c3842bacc3eb032 --- /dev/null +++ b/labcodes/lab5/obj/user/yield.d @@ -0,0 +1,2 @@ +obj/user/yield.o obj/user/yield.d: user/yield.c user/libs/ulib.h \ + libs/defs.h libs/stdio.h libs/stdarg.h diff --git a/labcodes/lab5/obj/user/yield.o b/labcodes/lab5/obj/user/yield.o new file mode 100644 index 0000000000000000000000000000000000000000..67bc41f7fa1cf69ebb8bc909dce2e6765783e7db Binary files /dev/null and b/labcodes/lab5/obj/user/yield.o differ diff --git a/labcodes/lab5/obj/user/yield.sym b/labcodes/lab5/obj/user/yield.sym new file mode 100644 index 0000000000000000000000000000000000000000..9938d1917272cde750260bb9d7e96313800edf33 --- /dev/null +++ b/labcodes/lab5/obj/user/yield.sym @@ -0,0 +1,66 @@ +00000000 panic.c +00000000 stdio.c +008000c8 cputch +00000000 syscall.c +00800199 syscall +00000000 ulib.c +00000000 umain.c +00000000 hash.c +00000000 printfmt.c +00801140 error_string +008003ad printnum +008004af getuint +008004fe getint +0080094f sprintputch +00000000 rand.c +00802000 next +00000000 string.c +00000000 yield.c +00800b53 strcpy +00800329 yield +0080030d waitpid +00800245 sys_yield +00800e65 memmove +00800985 snprintf +00800576 vprintfmt +0080020b sys_fork +00800120 cprintf +0080034e getpid +00800f08 memcpy +008009bb vsnprintf +0080036d umain +0020274c __STAB_END__ +0080025b sys_kill +0020274d __STABSTR_BEGIN__ +0080002f __panic +00800ccb strtol +00800b22 strnlen +0080035d print_pgdir +00800339 kill +00800c9b strfind +008002ef wait +00800020 _start +00800a21 rand +00800c14 strncmp +0080028e sys_putc +00800b92 strncpy +00800f57 memcmp +008002e0 fork +00800e23 memset +00800faf main +00800ae0 srand +00800386 hash32 +00800545 printfmt +0020365a __STABSTR_END__ +00800bcb strcmp +008000eb vcprintf +0080007f __warn +00800148 cputs +008002c1 exit +00800221 sys_wait +008001ee sys_exit +00200010 __STAB_BEGIN__ +00800af9 strlen +008002ab sys_pgdir +00800c67 strchr +00800278 sys_getpid diff --git a/labcodes/lab5/tools/gdbinit b/labcodes/lab5/tools/gdbinit index df5df85be4fc6cbcedb1c6f1547ab92a7fbc1cac..f1e5cfc597f56f54ee58257c5ef7b51d5e1b21ba 100644 --- a/labcodes/lab5/tools/gdbinit +++ b/labcodes/lab5/tools/gdbinit @@ -1,3 +1,10 @@ file bin/kernel target remote :1234 -break kern_init +b kern_init +b schedule +b user_main +b kernel_execve +b syscall +b sys_exec +b do_execve +continue \ No newline at end of file diff --git a/labcodes/lab5/user/libs/syscall.c b/labcodes/lab5/user/libs/syscall.c index 7bdc0d24a165f6545e13d53d5c5781affdfca5ee..23ea47a68e11be2f24768970ef9daeb182e12d76 100644 --- a/labcodes/lab5/user/libs/syscall.c +++ b/labcodes/lab5/user/libs/syscall.c @@ -5,17 +5,44 @@ #define MAX_ARGS 5 +/** + * 执行系统调用的封装函数 + * 该函数使用可变参数列表和内联汇编来处理系统调用,旨在提供一种通用的方法 + * 来调用操作系统提供的服务,同时确保代码的可移植性和效率 + * + * @param num 系统调用号,用于指定请求操作系统执行的具体操作 + * @param ... 可变参数列表,包含系统调用所需的参数 + * @return 系统调用的返回值,其含义取决于具体的系统调用 + * + * 注意:此函数假设系统调用号和参数的数量是正确的,且不会进行错误检查 + * MAX_ARGS 定义了系统调用可接受的最大参数数量,超过此数量的参数将被忽略 + * T_SYSCALL 是中断向量号,用于触发系统调用中断 + */ static inline int syscall(int num, ...) { + // 初始化可变参数列表 va_list ap; va_start(ap, num); + + //a数组用于存储系统调用的参数 uint32_t a[MAX_ARGS]; int i, ret; + + // 将可变参数列表中的参数提取到a数组中 for (i = 0; i < MAX_ARGS; i ++) { a[i] = va_arg(ap, uint32_t); } + + // 结束可变参数列表的使用 va_end(ap); + // 使用内联汇编执行系统调用 + // "int %1" 触发中断,执行系统调用 + // "=a" (ret) 指定eax寄存器用于接收系统调用的返回值 + // "i" (T_SYSCALL) 指定中断向量号 + // "a" (num) 将系统调用号放入eax寄存器 + // "d" (a[0])、"c" (a[1])、"b" (a[2])、"D" (a[3])、"S" (a[4]) 将参数放入相应的寄存器 + // "cc" 表示中断会改变条件码,"memory" 表示中断可能会修改任意内存位置的值 asm volatile ( "int %1;" : "=a" (ret) @@ -27,6 +54,7 @@ syscall(int num, ...) { "D" (a[3]), "S" (a[4]) : "cc", "memory"); + // 返回系统调用的结果 return ret; }