diff --git a/labcodes/lab2/bin/bootblock b/labcodes/lab2/bin/bootblock new file mode 100644 index 0000000000000000000000000000000000000000..b04b04f58b3af9b64903fdd9b677a794735388c2 Binary files /dev/null and b/labcodes/lab2/bin/bootblock differ diff --git a/labcodes/lab2/bin/kernel b/labcodes/lab2/bin/kernel new file mode 100755 index 0000000000000000000000000000000000000000..263cca8ae6a466cc836bd67889563eff9d3e1a98 Binary files /dev/null and b/labcodes/lab2/bin/kernel differ diff --git a/labcodes/lab2/bin/kernel_nopage b/labcodes/lab2/bin/kernel_nopage new file mode 100755 index 0000000000000000000000000000000000000000..c4a3dc9f0b7a3a195e6151648d7add4e0ccc8d74 Binary files /dev/null and b/labcodes/lab2/bin/kernel_nopage differ diff --git a/labcodes/lab2/bin/sign b/labcodes/lab2/bin/sign new file mode 100755 index 0000000000000000000000000000000000000000..4c69da8f26a9573c07a1d247b6b26a80f5319392 Binary files /dev/null and b/labcodes/lab2/bin/sign differ diff --git a/labcodes/lab2/bin/ucore.img b/labcodes/lab2/bin/ucore.img new file mode 100644 index 0000000000000000000000000000000000000000..57ec409fac360aeb16cfd7aadddf05b7157a3630 Binary files /dev/null and b/labcodes/lab2/bin/ucore.img differ diff --git a/labcodes/lab2/boot/bootasm.S b/labcodes/lab2/boot/bootasm.S index 6f769b719e80d97ffd29240de2f1a816ff8f47b5..e41d363a28dbd63b586a21c3fbc2963018134782 100644 --- a/labcodes/lab2/boot/bootasm.S +++ b/labcodes/lab2/boot/bootasm.S @@ -42,24 +42,24 @@ seta20.2: movb $0xdf, %al # 0xdf -> port 0x60 outb %al, $0x60 # 0xdf = 11011111, means set P2's A20 bit(the 1 bit) to 1 - +# 标识内存探测的开始位置 probe_memory: - movl $0, 0x8000 - xorl %ebx, %ebx - movw $0x8004, %di -start_probe: - movl $0xE820, %eax - movl $20, %ecx - movl $SMAP, %edx - int $0x15 - jnc cont - movw $12345, 0x8000 - jmp finish_probe + movl $0, 0x8000 # 将值 0 移动到物理地址 0x8000,初始化一个内存区域 + xorl %ebx, %ebx # 将寄存器 %ebx 清零,用于在后续逻辑中进行计数或状态标志 + movw $0x8004, %di # 将值 0x8004 移动到 %di 寄存器 +start_probe: # 定义 start_probe 的标签,探测的开始 + movl $0xE820, %eax # 将值 0xE820 移动到 %eax 中,这是用来请求内存映射信息的中断号。 + movl $20, %ecx # 将值 20 移动到 %ecx 中,这是中断处理程序返回的数据长度。 + movl $SMAP, %edx # 将 SMAP 的标签的地址移动到 %edx 中,表示将要存储内存映射结果的缓冲区地址。 + int $0x15 # 触发 0x15 中断,向BIOS请求内存映射信息。 + jnc cont # 检查中断是否成功,没有错误,程序将跳转到 cont 标签继续执行 + movw $12345, 0x8000 # 将错误码 12345 移动到物理地址 0x8000 中,表示探测失败 + jmp finish_probe # 程序将跳转到 finish_probe 标签,结束探测 cont: - addw $20, %di - incl 0x8000 - cmpl $0, %ebx - jnz start_probe + addw $20, %di # 将 %di 加 20,用于移动到下一个内存映射信息的位置 + incl 0x8000 # 将存储在物理地址 0x8000 的值加一,表示成功探测到的内存区域数量 + cmpl $0, %ebx # 检查 %ebx 是否为零,如果为零,表示已经探测到了所有内存区域,程序将跳转到 finish_probe 标签 + jnz start_probe # 如果没有,程序将跳转到 start_probe 标签,继续探测下一个内存映射信息 finish_probe: # Switch from real to protected mode, using a bootstrap GDT diff --git a/labcodes/lab2/kern/init/init.c b/labcodes/lab2/kern/init/init.c index 3d67b593aa072c762b4def3f51cffc35dbbee0af..698a5c42e00f18756c150075ca40ba816b237abc 100644 --- a/labcodes/lab2/kern/init/init.c +++ b/labcodes/lab2/kern/init/init.c @@ -38,7 +38,7 @@ kern_init(void) { //LAB1: CAHLLENGE 1 If you try to do it, uncomment lab1_switch_test() // user/kernel mode switch test - //lab1_switch_test(); + lab1_switch_test(); /* do nothing */ while (1); @@ -85,11 +85,24 @@ lab1_print_cur_status(void) { static void lab1_switch_to_user(void) { //LAB1 CHALLENGE 1 : TODO + asm volatile ( + "sub $0x8, %%esp \n" + "int %0 \n" + "movl %%ebp, %%esp" + : + : "i"(T_SWITCH_TOU) + ); } static void lab1_switch_to_kernel(void) { //LAB1 CHALLENGE 1 : TODO + asm volatile ( + "int %0 \n" + "movl %%ebp, %%esp \n" + : + : "i"(T_SWITCH_TOK) + ); } static void diff --git a/labcodes/lab2/kern/mm/default_pmm.c b/labcodes/lab2/kern/mm/default_pmm.c index f2f54d04ade7f7388e6ec82ce53806cecfa31440..c072c1c9436f30af08b0d9f2b9378a7ccb8c4503 100644 --- a/labcodes/lab2/kern/mm/default_pmm.c +++ b/labcodes/lab2/kern/mm/default_pmm.c @@ -9,60 +9,86 @@ * 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`. + * 调用图:`kern_init` --> `pmm_init` --> `page_init` --> `init_memmap` --> `pmm_manager` --> `init_memmap`。 * This function is used to initialize a free block (with parameter `addr_base`, * `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. + * `p->ref` 应设置为 0,因为现在 `p` 是空闲的,没有引用。 * After that, We can use `p->page_link` to link this page into `free_list`. + * 之后,我们可以使用 `p->page_link` 将此页链接到 `free_list` 中。 * (e.g.: `list_add_before(&free_list, &(p->page_link));` ) + * (例如:`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: + * So you should search the free list like this:所以你应这样搜索空闲列表: * list_entry_t le = &free_list; * while((le=list_next(le)) != &free_list) { * ... * (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,165 +96,193 @@ * >= 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 * = p->property - n;`) + * 如果 `p->property > n`,我们应重新计算该空闲块剩余页的数量。 * (4.1.3) * Re-caluclate `nr_free` (number of the the rest of all free block). + * 重新计算 `nr_free`(剩余所有空闲块的数量)。 * (4.1.4) * return `p`. * (4.2) * If we can not find a free block with its size >=n, then return NULL. + * 如果找不到大小 >= n 的空闲块,则返回 NULL。 * (5) `default_free_pages`: * re-link the pages into the free list, and may merge small free blocks into - * the big ones. + * the big ones. 将页重新链接到空闲列表中,并可能将小空闲块合并为大块。 * (5.1) * According to the base address of the withdrawed blocks, search the free * list for its correct position (with address from low to high), and insert * the pages. (May use `list_next`, `le2page`, `list_add_before`) + * 根据撤回块的基地址,在空闲列表中搜索其正确位置(按地址从低到高), + * 并插入页面。(可以使用 `list_next`、`le2page`、`list_add_before`) * (5.2) * Reset the fields of the pages, such as `p->ref` and `p->flags` (PageProperty) + * 重置页的字段,例如 `p->ref` 和 `p->flags`(PageProperty)。 * (5.3) * Try to merge blocks at lower or higher addresses. Notice: This should * change some pages' `p->property` correctly. + * 尝试合并低地址或高地址的块。注意:这应正确更改某些页的 `p->property`。 */ 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(&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;// 更新剩余块的页数 + list_add(&free_list, &(p->page_link));// 将剩余块添加回空闲列表 } - nr_free -= n; - ClearPageProperty(page); + 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; - list_add(&free_list, &(base->page_link)); + nr_free += n;// 更新空闲页的计数 + list_add(&free_list, &(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,64 +294,66 @@ 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) { - assert(le->next->prev == le && le->prev->next == le); - struct Page *p = le2page(le, page_link); + assert(le->next->prev == le && le->prev->next == le);// 验证双向链表 + 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 = { diff --git a/labcodes/lab2/kern/mm/pmm.c b/labcodes/lab2/kern/mm/pmm.c index 5c09bb04613458e29bc93f3dd38c2e52b46add82..30b3eeaa05bb6fb8be2b6587bdef986a2a5cfa72 100644 --- a/labcodes/lab2/kern/mm/pmm.c +++ b/labcodes/lab2/kern/mm/pmm.c @@ -10,100 +10,126 @@ #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) { - 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 ("lgdt (%0)" :: "r" (pd));//这行汇编代码使用 lgdt 指令加载 GDT。%0 被替换为指向 pd 的指针,告诉处理器 GDT 的地址。 + 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)); } @@ -111,62 +137,81 @@ 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 - 调用 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 保存当前的中断状态,以避免在分配内存时发生中断。 local_intr_save(intr_flag); { + //调用物理内存管理器的 alloc_pages 函数分配 n 页的内存。 page = pmm_manager->alloc_pages(n); } + //恢复之前保存的中断状态。 local_intr_restore(intr_flag); return page; } //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); @@ -174,65 +219,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; + uint64_t maxpa = 0;// 初始化最大物理地址为0 - cprintf("e820map:\n"); + 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);// 初始化内存页映射 } } } @@ -241,19 +289,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; } } @@ -261,20 +319,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). @@ -282,38 +345,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(); // 打印页目录表 } @@ -324,6 +405,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 @@ -359,18 +447,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; } @@ -404,12 +516,24 @@ 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 + } } //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); } @@ -423,131 +547,182 @@ 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); } } 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); + assert(strlen((const char *)0x100) == 0);// 验证字符串长度为0 - free_page(p); - free_page(pde2page(boot_pgdir[0])); - boot_pgdir[0] = 0; + free_page(p);// 释放页面 p + free_page(pde2page(boot_pgdir[0]));// 释放页目录项对应的页面 + boot_pgdir[0] = 0;// 将页目录的第一个项设为0 - cprintf("check_boot_pgdir() succeeded!\n"); + 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; } @@ -563,40 +738,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/lab2/kern/trap/trap.c b/labcodes/lab2/kern/trap/trap.c index af786765f43336f69f9217d9e299eea6d1fb2a08..3c6e420eefef09f5c8b59630e03451e0bd49720f 100644 --- a/labcodes/lab2/kern/trap/trap.c +++ b/labcodes/lab2/kern/trap/trap.c @@ -46,6 +46,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_SWITCH_TOK], 0, GD_KTEXT, __vectors[T_SWITCH_TOK], DPL_USER); + // load the IDT + //使用 lidt 指令将 IDT 描述符加载到 CPU 中 + lidt(&idt_pd); } static const char * @@ -134,6 +148,7 @@ print_regs(struct pushregs *regs) { cprintf(" eax 0x%08x\n", regs->reg_eax); } +struct trapframe switchk2u, *switchu2k; /* trap_dispatch - dispatch based on what type of trap occurred */ static void trap_dispatch(struct trapframe *tf) { @@ -147,6 +162,11 @@ trap_dispatch(struct trapframe *tf) { * (2) Every TICK_NUM cycle, you can print some info using a funciton, such as print_ticks(). * (3) Too Simple? Yes, I think so! */ + ticks ++; //记录中断事件 + if (ticks % TICK_NUM == 0) + { + print_ticks(); + }//每经过 TICK_NUM 次周期时,调用 print_ticks() 打印信息。 break; case IRQ_OFFSET + IRQ_COM1: c = cons_getc(); @@ -157,10 +177,38 @@ trap_dispatch(struct trapframe *tf) { cprintf("kbd [%03d] %c\n", c, c); break; //LAB1 CHALLENGE 1 : YOUR CODE you should modify below codes. - case T_SWITCH_TOU: - case T_SWITCH_TOK: - panic("T_SWITCH_** ??\n"); + case T_SWITCH_TOU://表示发生了从内核模式切换到用户模式的请求。 + if (tf->tf_cs != USER_CS) {//判断当前是否在内核模式下 + switchk2u = *tf; //保存当前陷阱框架 + switchk2u.tf_cs = USER_CS;//设置用户模式的段寄存器 + //将数据段和栈段寄存器 都设置为 USER_DS(用户数据段) + switchk2u.tf_ds = switchk2u.tf_es = switchk2u.tf_ss = USER_DS; + switchk2u.tf_esp = (uint32_t)tf + sizeof(struct trapframe) - 8; + + // set eflags, make sure ucore can use io under user mode. + // if CPL > IOPL, then cpu will generate a general protection. + switchk2u.tf_eflags |= FL_IOPL_MASK;//允许用户模式下进行 I/O 操作 + + // set temporary stack + // then iret will jump to the right stack + *((uint32_t *)tf - 1) = (uint32_t)&switchk2u; + } + break; + case T_SWITCH_TOK: // T_SWITCH_TOK 表示发生了从用户模式切换到内核模式的请求。 + if (tf->tf_cs != KERNEL_CS) { //判断当前是否在用户模式下 + tf->tf_cs = KERNEL_CS; + tf->tf_ds = tf->tf_es = KERNEL_DS; + //设置内核模式的段寄存器 + tf->tf_eflags &= ~FL_IOPL_MASK; //清除 I/O 权限标志 + switchu2k = (struct trapframe *)(tf->tf_esp - (sizeof(struct trapframe) - 8)); + //使用 memmove 将当前的陷阱框架(除了最后8个字节)复制到新的陷阱框架位置 switchu2k + memmove(switchu2k, tf, sizeof(struct trapframe) - 8); + //将新的陷阱框架地址 switchu2k 存储到当前陷阱框架之前的一个栈位置 + *((uint32_t *)tf - 1) = (uint32_t)switchu2k; + } break; + // panic("T_SWITCH_** ??\n"); + // break; case IRQ_OFFSET + IRQ_IDE1: case IRQ_OFFSET + IRQ_IDE2: /* do nothing */ diff --git a/labcodes/lab2/obj/boot/bootasm.d b/labcodes/lab2/obj/boot/bootasm.d new file mode 100644 index 0000000000000000000000000000000000000000..0814674615b0e7471d87201075118ec74cb33a79 --- /dev/null +++ b/labcodes/lab2/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/lab2/obj/boot/bootasm.o b/labcodes/lab2/obj/boot/bootasm.o new file mode 100644 index 0000000000000000000000000000000000000000..6229f43ab2491dce3b30d5f3ab500718935228dd Binary files /dev/null and b/labcodes/lab2/obj/boot/bootasm.o differ diff --git a/labcodes/lab2/obj/boot/bootmain.d b/labcodes/lab2/obj/boot/bootmain.d new file mode 100644 index 0000000000000000000000000000000000000000..c0d98e63cd309eaf0c4e92439e4ea83bd1c9acc0 --- /dev/null +++ b/labcodes/lab2/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/lab2/obj/boot/bootmain.o b/labcodes/lab2/obj/boot/bootmain.o new file mode 100644 index 0000000000000000000000000000000000000000..c72e25d0a0da0d07b6a528c4edddda1156d4be4d Binary files /dev/null and b/labcodes/lab2/obj/boot/bootmain.o differ diff --git a/labcodes/lab2/obj/bootblock.asm b/labcodes/lab2/obj/bootblock.asm new file mode 100644 index 0000000000000000000000000000000000000000..b7395761d3d8de444c9d945b869c828c8a645ba2 --- /dev/null +++ b/labcodes/lab2/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/lab2/obj/bootblock.o b/labcodes/lab2/obj/bootblock.o new file mode 100755 index 0000000000000000000000000000000000000000..9c2239c7790d23b4b950cce04bd0b65ee073d289 Binary files /dev/null and b/labcodes/lab2/obj/bootblock.o differ diff --git a/labcodes/lab2/obj/bootblock.out b/labcodes/lab2/obj/bootblock.out new file mode 100755 index 0000000000000000000000000000000000000000..4bbb6755d2289c820b5c874c4ecdfe0a93460849 Binary files /dev/null and b/labcodes/lab2/obj/bootblock.out differ diff --git a/labcodes/lab2/obj/kern/debug/kdebug.d b/labcodes/lab2/obj/kern/debug/kdebug.d new file mode 100644 index 0000000000000000000000000000000000000000..61cab792070b9ed485adef8cc68384e4978048db --- /dev/null +++ b/labcodes/lab2/obj/kern/debug/kdebug.d @@ -0,0 +1,5 @@ +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/sync/sync.h kern/driver/intr.h kern/mm/mmu.h \ + kern/debug/kdebug.h kern/trap/trap.h kern/debug/kmonitor.h \ + kern/debug/assert.h diff --git a/labcodes/lab2/obj/kern/debug/kdebug.o b/labcodes/lab2/obj/kern/debug/kdebug.o new file mode 100644 index 0000000000000000000000000000000000000000..f31d934ae957860b65b5cd56231804fb083be26a Binary files /dev/null and b/labcodes/lab2/obj/kern/debug/kdebug.o differ diff --git a/labcodes/lab2/obj/kern/debug/kmonitor.d b/labcodes/lab2/obj/kern/debug/kmonitor.d new file mode 100644 index 0000000000000000000000000000000000000000..11c2af26a538a8fae989f8ac595edba72ba9fdb0 --- /dev/null +++ b/labcodes/lab2/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/lab2/obj/kern/debug/kmonitor.o b/labcodes/lab2/obj/kern/debug/kmonitor.o new file mode 100644 index 0000000000000000000000000000000000000000..c017d8b574656587ef3fa54b8fb2a3eefa687c2e Binary files /dev/null and b/labcodes/lab2/obj/kern/debug/kmonitor.o differ diff --git a/labcodes/lab2/obj/kern/debug/panic.d b/labcodes/lab2/obj/kern/debug/panic.d new file mode 100644 index 0000000000000000000000000000000000000000..084ebb66bb08c9eec69fc03aac82918ef9b8ae9e --- /dev/null +++ b/labcodes/lab2/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/lab2/obj/kern/debug/panic.o b/labcodes/lab2/obj/kern/debug/panic.o new file mode 100644 index 0000000000000000000000000000000000000000..b96eab54e3e8c064ff8fbc46dcf963bc98851cd9 Binary files /dev/null and b/labcodes/lab2/obj/kern/debug/panic.o differ diff --git a/labcodes/lab2/obj/kern/driver/clock.d b/labcodes/lab2/obj/kern/driver/clock.d new file mode 100644 index 0000000000000000000000000000000000000000..bdff3ffda4b8e673a5a6103b981d74b45f82c665 --- /dev/null +++ b/labcodes/lab2/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/lab2/obj/kern/driver/clock.o b/labcodes/lab2/obj/kern/driver/clock.o new file mode 100644 index 0000000000000000000000000000000000000000..621e9a16d966fcd3554e8567fa51fcae9eeb6ffb Binary files /dev/null and b/labcodes/lab2/obj/kern/driver/clock.o differ diff --git a/labcodes/lab2/obj/kern/driver/console.d b/labcodes/lab2/obj/kern/driver/console.d new file mode 100644 index 0000000000000000000000000000000000000000..196db2fc19aa221ae97806823bed746f0f23bce9 --- /dev/null +++ b/labcodes/lab2/obj/kern/driver/console.d @@ -0,0 +1,5 @@ +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 diff --git a/labcodes/lab2/obj/kern/driver/console.o b/labcodes/lab2/obj/kern/driver/console.o new file mode 100644 index 0000000000000000000000000000000000000000..a99691ff3cde0d772f1625450f95aa3d06250c1c Binary files /dev/null and b/labcodes/lab2/obj/kern/driver/console.o differ diff --git a/labcodes/lab2/obj/kern/driver/intr.d b/labcodes/lab2/obj/kern/driver/intr.d new file mode 100644 index 0000000000000000000000000000000000000000..d0f9177c9eaeab75af2601390be216c9e6129ec8 --- /dev/null +++ b/labcodes/lab2/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/lab2/obj/kern/driver/intr.o b/labcodes/lab2/obj/kern/driver/intr.o new file mode 100644 index 0000000000000000000000000000000000000000..ae30eda041cbc61fe690d88a4c1694d2a98aa496 Binary files /dev/null and b/labcodes/lab2/obj/kern/driver/intr.o differ diff --git a/labcodes/lab2/obj/kern/driver/picirq.d b/labcodes/lab2/obj/kern/driver/picirq.d new file mode 100644 index 0000000000000000000000000000000000000000..2de8ab1899f9f2be93bd10d4b213864803b6e5b9 --- /dev/null +++ b/labcodes/lab2/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/lab2/obj/kern/driver/picirq.o b/labcodes/lab2/obj/kern/driver/picirq.o new file mode 100644 index 0000000000000000000000000000000000000000..ace5347e92cc594c1b60313b8f6615275b5e4439 Binary files /dev/null and b/labcodes/lab2/obj/kern/driver/picirq.o differ diff --git a/labcodes/lab2/obj/kern/init/entry.d b/labcodes/lab2/obj/kern/init/entry.d new file mode 100644 index 0000000000000000000000000000000000000000..c6b2d371d41761b6f69cfb032098321e2ec91c41 --- /dev/null +++ b/labcodes/lab2/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/lab2/obj/kern/init/entry.o b/labcodes/lab2/obj/kern/init/entry.o new file mode 100644 index 0000000000000000000000000000000000000000..7be1cb868271a54dcf06aee81bbc282276941ed8 Binary files /dev/null and b/labcodes/lab2/obj/kern/init/entry.o differ diff --git a/labcodes/lab2/obj/kern/init/init.d b/labcodes/lab2/obj/kern/init/init.d new file mode 100644 index 0000000000000000000000000000000000000000..9982ea0b6cbd7b3bf105efe2a6e5f363e7976c1a --- /dev/null +++ b/labcodes/lab2/obj/kern/init/init.d @@ -0,0 +1,6 @@ +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/debug/kmonitor.h diff --git a/labcodes/lab2/obj/kern/init/init.o b/labcodes/lab2/obj/kern/init/init.o new file mode 100644 index 0000000000000000000000000000000000000000..1dfa705f9e879f2e0dbdc1c33104a5a5908e73c4 Binary files /dev/null and b/labcodes/lab2/obj/kern/init/init.o differ diff --git a/labcodes/lab2/obj/kern/libs/readline.d b/labcodes/lab2/obj/kern/libs/readline.d new file mode 100644 index 0000000000000000000000000000000000000000..656abf96b4c816940c02189bdc6490372dfc3c49 --- /dev/null +++ b/labcodes/lab2/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/lab2/obj/kern/libs/readline.o b/labcodes/lab2/obj/kern/libs/readline.o new file mode 100644 index 0000000000000000000000000000000000000000..ff86b2d49d90136bac3939da6bc1486807bd25d6 Binary files /dev/null and b/labcodes/lab2/obj/kern/libs/readline.o differ diff --git a/labcodes/lab2/obj/kern/libs/stdio.d b/labcodes/lab2/obj/kern/libs/stdio.d new file mode 100644 index 0000000000000000000000000000000000000000..5e205ace5babb64121955473f1af46dbc8b90e51 --- /dev/null +++ b/labcodes/lab2/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/lab2/obj/kern/libs/stdio.o b/labcodes/lab2/obj/kern/libs/stdio.o new file mode 100644 index 0000000000000000000000000000000000000000..11b8d8ca228c5be48a85dacc97347b50c7b57379 Binary files /dev/null and b/labcodes/lab2/obj/kern/libs/stdio.o differ diff --git a/labcodes/lab2/obj/kern/mm/default_pmm.d b/labcodes/lab2/obj/kern/mm/default_pmm.d new file mode 100644 index 0000000000000000000000000000000000000000..8c415bfea7b5a19a92a142688e8c23e11882b103 --- /dev/null +++ b/labcodes/lab2/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/lab2/obj/kern/mm/default_pmm.o b/labcodes/lab2/obj/kern/mm/default_pmm.o new file mode 100644 index 0000000000000000000000000000000000000000..53b8db29341613d9123a91004d4ba85bd32386db Binary files /dev/null and b/labcodes/lab2/obj/kern/mm/default_pmm.o differ diff --git a/labcodes/lab2/obj/kern/mm/pmm.d b/labcodes/lab2/obj/kern/mm/pmm.d new file mode 100644 index 0000000000000000000000000000000000000000..b9182e26ab70f85c10aa1098c821d7d7d6406f12 --- /dev/null +++ b/labcodes/lab2/obj/kern/mm/pmm.d @@ -0,0 +1,5 @@ +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 libs/error.h diff --git a/labcodes/lab2/obj/kern/mm/pmm.o b/labcodes/lab2/obj/kern/mm/pmm.o new file mode 100644 index 0000000000000000000000000000000000000000..44e3240325c3d20299a66fbabeec5fab4cd8ac4b Binary files /dev/null and b/labcodes/lab2/obj/kern/mm/pmm.o differ diff --git a/labcodes/lab2/obj/kern/trap/trap.d b/labcodes/lab2/obj/kern/trap/trap.d new file mode 100644 index 0000000000000000000000000000000000000000..c91f221a11506429fd025a984ea935ba1f8a223b --- /dev/null +++ b/labcodes/lab2/obj/kern/trap/trap.d @@ -0,0 +1,5 @@ +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/debug/kdebug.h diff --git a/labcodes/lab2/obj/kern/trap/trap.o b/labcodes/lab2/obj/kern/trap/trap.o new file mode 100644 index 0000000000000000000000000000000000000000..7939ce47ccc19fe88d749c01ea0d3077136a7570 Binary files /dev/null and b/labcodes/lab2/obj/kern/trap/trap.o differ diff --git a/labcodes/lab2/obj/kern/trap/trapentry.d b/labcodes/lab2/obj/kern/trap/trapentry.d new file mode 100644 index 0000000000000000000000000000000000000000..f37d596cc0396e7d31650d6b287624a3bdcdfdbb --- /dev/null +++ b/labcodes/lab2/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/lab2/obj/kern/trap/trapentry.o b/labcodes/lab2/obj/kern/trap/trapentry.o new file mode 100644 index 0000000000000000000000000000000000000000..af8304d12a169cca1511f832a8772cc87a07e0ce Binary files /dev/null and b/labcodes/lab2/obj/kern/trap/trapentry.o differ diff --git a/labcodes/lab2/obj/kern/trap/vectors.d b/labcodes/lab2/obj/kern/trap/vectors.d new file mode 100644 index 0000000000000000000000000000000000000000..e5813e7765cbb429b0beea10b102bb5b7897e374 --- /dev/null +++ b/labcodes/lab2/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/lab2/obj/kern/trap/vectors.o b/labcodes/lab2/obj/kern/trap/vectors.o new file mode 100644 index 0000000000000000000000000000000000000000..97c94cccc58446c53006fa817cc2d3d697382b5d Binary files /dev/null and b/labcodes/lab2/obj/kern/trap/vectors.o differ diff --git a/labcodes/lab2/obj/kernel.asm b/labcodes/lab2/obj/kernel.asm new file mode 100644 index 0000000000000000000000000000000000000000..a6ade7782d13b3e930bb5df35357631b50742345 --- /dev/null +++ b/labcodes/lab2/obj/kernel.asm @@ -0,0 +1,12382 @@ + +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 a0 11 00 mov $0x11a000,%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 a0 11 c0 mov %eax,0xc011a000 + + # 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 90 11 c0 mov $0xc0119000,%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 : +int kern_init(void) __attribute__((noreturn)); +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[]; + memset(edata, 0, end - edata); +c010003c: b8 8c cf 11 c0 mov $0xc011cf8c,%eax +c0100041: 2d 00 c0 11 c0 sub $0xc011c000,%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 c0 11 c0 movl $0xc011c000,(%esp) +c0100059: e8 aa 5e 00 00 call c0105f08 + + cons_init(); // init the console +c010005e: e8 42 15 00 00 call c01015a5 + + const char *message = "(THU.CST) os is loading ..."; +c0100063: c7 45 f4 a0 60 10 c0 movl $0xc01060a0,-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 bc 60 10 c0 movl $0xc01060bc,(%esp) +c0100078: e8 e9 02 00 00 call c0100366 + + print_kerninfo(); +c010007d: e8 07 08 00 00 call c0100889 + + grade_backtrace(); +c0100082: e8 95 00 00 00 call c010011c + + pmm_init(); // init physical memory management +c0100087: e8 f3 43 00 00 call c010447f + + pic_init(); // init interrupt controller +c010008c: e8 95 16 00 00 call c0101726 + idt_init(); // init interrupt descriptor table +c0100091: e8 f9 17 00 00 call c010188f + + clock_init(); // init clock interrupt +c0100096: e8 69 0c 00 00 call c0100d04 + intr_enable(); // enable irq interrupt +c010009b: e8 e4 15 00 00 call c0101684 + + //LAB1: CAHLLENGE 1 If you try to do it, uncomment lab1_switch_test() + // user/kernel mode switch test + lab1_switch_test(); +c01000a0: e8 76 01 00 00 call c010021b + + /* do nothing */ + while (1); +c01000a5: eb fe jmp c01000a5 + +c01000a7 : +} + +void __attribute__((noinline)) +grade_backtrace2(int arg0, int arg1, int arg2, int arg3) { +c01000a7: 55 push %ebp +c01000a8: 89 e5 mov %esp,%ebp +c01000aa: 83 ec 18 sub $0x18,%esp + mon_backtrace(0, NULL, NULL); +c01000ad: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) +c01000b4: 00 +c01000b5: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) +c01000bc: 00 +c01000bd: c7 04 24 00 00 00 00 movl $0x0,(%esp) +c01000c4: e8 56 0b 00 00 call c0100c1f +} +c01000c9: 90 nop +c01000ca: 89 ec mov %ebp,%esp +c01000cc: 5d pop %ebp +c01000cd: c3 ret + +c01000ce : + +void __attribute__((noinline)) +grade_backtrace1(int arg0, int arg1) { +c01000ce: 55 push %ebp +c01000cf: 89 e5 mov %esp,%ebp +c01000d1: 83 ec 18 sub $0x18,%esp +c01000d4: 89 5d fc mov %ebx,-0x4(%ebp) + grade_backtrace2(arg0, (int)&arg0, arg1, (int)&arg1); +c01000d7: 8d 4d 0c lea 0xc(%ebp),%ecx +c01000da: 8b 55 0c mov 0xc(%ebp),%edx +c01000dd: 8d 5d 08 lea 0x8(%ebp),%ebx +c01000e0: 8b 45 08 mov 0x8(%ebp),%eax +c01000e3: 89 4c 24 0c mov %ecx,0xc(%esp) +c01000e7: 89 54 24 08 mov %edx,0x8(%esp) +c01000eb: 89 5c 24 04 mov %ebx,0x4(%esp) +c01000ef: 89 04 24 mov %eax,(%esp) +c01000f2: e8 b0 ff ff ff call c01000a7 +} +c01000f7: 90 nop +c01000f8: 8b 5d fc mov -0x4(%ebp),%ebx +c01000fb: 89 ec mov %ebp,%esp +c01000fd: 5d pop %ebp +c01000fe: c3 ret + +c01000ff : + +void __attribute__((noinline)) +grade_backtrace0(int arg0, int arg1, int arg2) { +c01000ff: 55 push %ebp +c0100100: 89 e5 mov %esp,%ebp +c0100102: 83 ec 18 sub $0x18,%esp + grade_backtrace1(arg0, arg2); +c0100105: 8b 45 10 mov 0x10(%ebp),%eax +c0100108: 89 44 24 04 mov %eax,0x4(%esp) +c010010c: 8b 45 08 mov 0x8(%ebp),%eax +c010010f: 89 04 24 mov %eax,(%esp) +c0100112: e8 b7 ff ff ff call c01000ce +} +c0100117: 90 nop +c0100118: 89 ec mov %ebp,%esp +c010011a: 5d pop %ebp +c010011b: c3 ret + +c010011c : + +void +grade_backtrace(void) { +c010011c: 55 push %ebp +c010011d: 89 e5 mov %esp,%ebp +c010011f: 83 ec 18 sub $0x18,%esp + grade_backtrace0(0, (int)kern_init, 0xffff0000); +c0100122: b8 36 00 10 c0 mov $0xc0100036,%eax +c0100127: c7 44 24 08 00 00 ff movl $0xffff0000,0x8(%esp) +c010012e: ff +c010012f: 89 44 24 04 mov %eax,0x4(%esp) +c0100133: c7 04 24 00 00 00 00 movl $0x0,(%esp) +c010013a: e8 c0 ff ff ff call c01000ff +} +c010013f: 90 nop +c0100140: 89 ec mov %ebp,%esp +c0100142: 5d pop %ebp +c0100143: c3 ret + +c0100144 : + +static void +lab1_print_cur_status(void) { +c0100144: 55 push %ebp +c0100145: 89 e5 mov %esp,%ebp +c0100147: 83 ec 28 sub $0x28,%esp + static int round = 0; + uint16_t reg1, reg2, reg3, reg4; + asm volatile ( +c010014a: 8c 4d f6 mov %cs,-0xa(%ebp) +c010014d: 8c 5d f4 mov %ds,-0xc(%ebp) +c0100150: 8c 45 f2 mov %es,-0xe(%ebp) +c0100153: 8c 55 f0 mov %ss,-0x10(%ebp) + "mov %%cs, %0;" + "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); +c0100156: 0f b7 45 f6 movzwl -0xa(%ebp),%eax +c010015a: 83 e0 03 and $0x3,%eax +c010015d: 89 c2 mov %eax,%edx +c010015f: a1 00 c0 11 c0 mov 0xc011c000,%eax +c0100164: 89 54 24 08 mov %edx,0x8(%esp) +c0100168: 89 44 24 04 mov %eax,0x4(%esp) +c010016c: c7 04 24 c1 60 10 c0 movl $0xc01060c1,(%esp) +c0100173: e8 ee 01 00 00 call c0100366 + cprintf("%d: cs = %x\n", round, reg1); +c0100178: 0f b7 45 f6 movzwl -0xa(%ebp),%eax +c010017c: 89 c2 mov %eax,%edx +c010017e: a1 00 c0 11 c0 mov 0xc011c000,%eax +c0100183: 89 54 24 08 mov %edx,0x8(%esp) +c0100187: 89 44 24 04 mov %eax,0x4(%esp) +c010018b: c7 04 24 cf 60 10 c0 movl $0xc01060cf,(%esp) +c0100192: e8 cf 01 00 00 call c0100366 + cprintf("%d: ds = %x\n", round, reg2); +c0100197: 0f b7 45 f4 movzwl -0xc(%ebp),%eax +c010019b: 89 c2 mov %eax,%edx +c010019d: a1 00 c0 11 c0 mov 0xc011c000,%eax +c01001a2: 89 54 24 08 mov %edx,0x8(%esp) +c01001a6: 89 44 24 04 mov %eax,0x4(%esp) +c01001aa: c7 04 24 dd 60 10 c0 movl $0xc01060dd,(%esp) +c01001b1: e8 b0 01 00 00 call c0100366 + cprintf("%d: es = %x\n", round, reg3); +c01001b6: 0f b7 45 f2 movzwl -0xe(%ebp),%eax +c01001ba: 89 c2 mov %eax,%edx +c01001bc: a1 00 c0 11 c0 mov 0xc011c000,%eax +c01001c1: 89 54 24 08 mov %edx,0x8(%esp) +c01001c5: 89 44 24 04 mov %eax,0x4(%esp) +c01001c9: c7 04 24 eb 60 10 c0 movl $0xc01060eb,(%esp) +c01001d0: e8 91 01 00 00 call c0100366 + cprintf("%d: ss = %x\n", round, reg4); +c01001d5: 0f b7 45 f0 movzwl -0x10(%ebp),%eax +c01001d9: 89 c2 mov %eax,%edx +c01001db: a1 00 c0 11 c0 mov 0xc011c000,%eax +c01001e0: 89 54 24 08 mov %edx,0x8(%esp) +c01001e4: 89 44 24 04 mov %eax,0x4(%esp) +c01001e8: c7 04 24 f9 60 10 c0 movl $0xc01060f9,(%esp) +c01001ef: e8 72 01 00 00 call c0100366 + round ++; +c01001f4: a1 00 c0 11 c0 mov 0xc011c000,%eax +c01001f9: 40 inc %eax +c01001fa: a3 00 c0 11 c0 mov %eax,0xc011c000 +} +c01001ff: 90 nop +c0100200: 89 ec mov %ebp,%esp +c0100202: 5d pop %ebp +c0100203: c3 ret + +c0100204 : + +static void +lab1_switch_to_user(void) { +c0100204: 55 push %ebp +c0100205: 89 e5 mov %esp,%ebp + //LAB1 CHALLENGE 1 : TODO + asm volatile ( +c0100207: 83 ec 08 sub $0x8,%esp +c010020a: cd 78 int $0x78 +c010020c: 89 ec mov %ebp,%esp + "int %0 \n" + "movl %%ebp, %%esp" + : + : "i"(T_SWITCH_TOU) + ); +} +c010020e: 90 nop +c010020f: 5d pop %ebp +c0100210: c3 ret + +c0100211 : + +static void +lab1_switch_to_kernel(void) { +c0100211: 55 push %ebp +c0100212: 89 e5 mov %esp,%ebp + //LAB1 CHALLENGE 1 : TODO + asm volatile ( +c0100214: cd 79 int $0x79 +c0100216: 89 ec mov %ebp,%esp + "int %0 \n" + "movl %%ebp, %%esp \n" + : + : "i"(T_SWITCH_TOK) + ); +} +c0100218: 90 nop +c0100219: 5d pop %ebp +c010021a: c3 ret + +c010021b : + +static void +lab1_switch_test(void) { +c010021b: 55 push %ebp +c010021c: 89 e5 mov %esp,%ebp +c010021e: 83 ec 18 sub $0x18,%esp + lab1_print_cur_status(); +c0100221: e8 1e ff ff ff call c0100144 + cprintf("+++ switch to user mode +++\n"); +c0100226: c7 04 24 08 61 10 c0 movl $0xc0106108,(%esp) +c010022d: e8 34 01 00 00 call c0100366 + lab1_switch_to_user(); +c0100232: e8 cd ff ff ff call c0100204 + lab1_print_cur_status(); +c0100237: e8 08 ff ff ff call c0100144 + cprintf("+++ switch to kernel mode +++\n"); +c010023c: c7 04 24 28 61 10 c0 movl $0xc0106128,(%esp) +c0100243: e8 1e 01 00 00 call c0100366 + lab1_switch_to_kernel(); +c0100248: e8 c4 ff ff ff call c0100211 + lab1_print_cur_status(); +c010024d: e8 f2 fe ff ff call c0100144 +} +c0100252: 90 nop +c0100253: 89 ec mov %ebp,%esp +c0100255: 5d pop %ebp +c0100256: c3 ret + +c0100257 : + * 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) { +c0100257: 55 push %ebp +c0100258: 89 e5 mov %esp,%ebp +c010025a: 83 ec 28 sub $0x28,%esp + if (prompt != NULL) { +c010025d: 83 7d 08 00 cmpl $0x0,0x8(%ebp) +c0100261: 74 13 je c0100276 + cprintf("%s", prompt); +c0100263: 8b 45 08 mov 0x8(%ebp),%eax +c0100266: 89 44 24 04 mov %eax,0x4(%esp) +c010026a: c7 04 24 47 61 10 c0 movl $0xc0106147,(%esp) +c0100271: e8 f0 00 00 00 call c0100366 + } + int i = 0, c; +c0100276: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + while (1) { + c = getchar(); +c010027d: e8 73 01 00 00 call c01003f5 +c0100282: 89 45 f0 mov %eax,-0x10(%ebp) + if (c < 0) { +c0100285: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) +c0100289: 79 07 jns c0100292 + return NULL; +c010028b: b8 00 00 00 00 mov $0x0,%eax +c0100290: eb 78 jmp c010030a + } + else if (c >= ' ' && i < BUFSIZE - 1) { +c0100292: 83 7d f0 1f cmpl $0x1f,-0x10(%ebp) +c0100296: 7e 28 jle c01002c0 +c0100298: 81 7d f4 fe 03 00 00 cmpl $0x3fe,-0xc(%ebp) +c010029f: 7f 1f jg c01002c0 + cputchar(c); +c01002a1: 8b 45 f0 mov -0x10(%ebp),%eax +c01002a4: 89 04 24 mov %eax,(%esp) +c01002a7: e8 e2 00 00 00 call c010038e + buf[i ++] = c; +c01002ac: 8b 45 f4 mov -0xc(%ebp),%eax +c01002af: 8d 50 01 lea 0x1(%eax),%edx +c01002b2: 89 55 f4 mov %edx,-0xc(%ebp) +c01002b5: 8b 55 f0 mov -0x10(%ebp),%edx +c01002b8: 88 90 20 c0 11 c0 mov %dl,-0x3fee3fe0(%eax) +c01002be: eb 45 jmp c0100305 + } + else if (c == '\b' && i > 0) { +c01002c0: 83 7d f0 08 cmpl $0x8,-0x10(%ebp) +c01002c4: 75 16 jne c01002dc +c01002c6: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c01002ca: 7e 10 jle c01002dc + cputchar(c); +c01002cc: 8b 45 f0 mov -0x10(%ebp),%eax +c01002cf: 89 04 24 mov %eax,(%esp) +c01002d2: e8 b7 00 00 00 call c010038e + i --; +c01002d7: ff 4d f4 decl -0xc(%ebp) +c01002da: eb 29 jmp c0100305 + } + else if (c == '\n' || c == '\r') { +c01002dc: 83 7d f0 0a cmpl $0xa,-0x10(%ebp) +c01002e0: 74 06 je c01002e8 +c01002e2: 83 7d f0 0d cmpl $0xd,-0x10(%ebp) +c01002e6: 75 95 jne c010027d + cputchar(c); +c01002e8: 8b 45 f0 mov -0x10(%ebp),%eax +c01002eb: 89 04 24 mov %eax,(%esp) +c01002ee: e8 9b 00 00 00 call c010038e + buf[i] = '\0'; +c01002f3: 8b 45 f4 mov -0xc(%ebp),%eax +c01002f6: 05 20 c0 11 c0 add $0xc011c020,%eax +c01002fb: c6 00 00 movb $0x0,(%eax) + return buf; +c01002fe: b8 20 c0 11 c0 mov $0xc011c020,%eax +c0100303: eb 05 jmp c010030a + c = getchar(); +c0100305: e9 73 ff ff ff jmp c010027d + } + } +} +c010030a: 89 ec mov %ebp,%esp +c010030c: 5d pop %ebp +c010030d: c3 ret + +c010030e : +/* * + * 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) { +c010030e: 55 push %ebp +c010030f: 89 e5 mov %esp,%ebp +c0100311: 83 ec 18 sub $0x18,%esp + cons_putc(c); +c0100314: 8b 45 08 mov 0x8(%ebp),%eax +c0100317: 89 04 24 mov %eax,(%esp) +c010031a: e8 b5 12 00 00 call c01015d4 + (*cnt) ++; +c010031f: 8b 45 0c mov 0xc(%ebp),%eax +c0100322: 8b 00 mov (%eax),%eax +c0100324: 8d 50 01 lea 0x1(%eax),%edx +c0100327: 8b 45 0c mov 0xc(%ebp),%eax +c010032a: 89 10 mov %edx,(%eax) +} +c010032c: 90 nop +c010032d: 89 ec mov %ebp,%esp +c010032f: 5d pop %ebp +c0100330: c3 ret + +c0100331 : + * + * 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) { +c0100331: 55 push %ebp +c0100332: 89 e5 mov %esp,%ebp +c0100334: 83 ec 28 sub $0x28,%esp + int cnt = 0; +c0100337: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + vprintfmt((void*)cputch, &cnt, fmt, ap); +c010033e: 8b 45 0c mov 0xc(%ebp),%eax +c0100341: 89 44 24 0c mov %eax,0xc(%esp) +c0100345: 8b 45 08 mov 0x8(%ebp),%eax +c0100348: 89 44 24 08 mov %eax,0x8(%esp) +c010034c: 8d 45 f4 lea -0xc(%ebp),%eax +c010034f: 89 44 24 04 mov %eax,0x4(%esp) +c0100353: c7 04 24 0e 03 10 c0 movl $0xc010030e,(%esp) +c010035a: e8 d4 53 00 00 call c0105733 + return cnt; +c010035f: 8b 45 f4 mov -0xc(%ebp),%eax +} +c0100362: 89 ec mov %ebp,%esp +c0100364: 5d pop %ebp +c0100365: c3 ret + +c0100366 : + * + * The return value is the number of characters which would be + * written to stdout. + * */ +int +cprintf(const char *fmt, ...) { +c0100366: 55 push %ebp +c0100367: 89 e5 mov %esp,%ebp +c0100369: 83 ec 28 sub $0x28,%esp + va_list ap; + int cnt; + va_start(ap, fmt); +c010036c: 8d 45 0c lea 0xc(%ebp),%eax +c010036f: 89 45 f0 mov %eax,-0x10(%ebp) + cnt = vcprintf(fmt, ap); +c0100372: 8b 45 f0 mov -0x10(%ebp),%eax +c0100375: 89 44 24 04 mov %eax,0x4(%esp) +c0100379: 8b 45 08 mov 0x8(%ebp),%eax +c010037c: 89 04 24 mov %eax,(%esp) +c010037f: e8 ad ff ff ff call c0100331 +c0100384: 89 45 f4 mov %eax,-0xc(%ebp) + va_end(ap); + return cnt; +c0100387: 8b 45 f4 mov -0xc(%ebp),%eax +} +c010038a: 89 ec mov %ebp,%esp +c010038c: 5d pop %ebp +c010038d: c3 ret + +c010038e : + +/* cputchar - writes a single character to stdout */ +void +cputchar(int c) { +c010038e: 55 push %ebp +c010038f: 89 e5 mov %esp,%ebp +c0100391: 83 ec 18 sub $0x18,%esp + cons_putc(c); +c0100394: 8b 45 08 mov 0x8(%ebp),%eax +c0100397: 89 04 24 mov %eax,(%esp) +c010039a: e8 35 12 00 00 call c01015d4 +} +c010039f: 90 nop +c01003a0: 89 ec mov %ebp,%esp +c01003a2: 5d pop %ebp +c01003a3: c3 ret + +c01003a4 : +/* * + * cputs- writes the string pointed by @str to stdout and + * appends a newline character. + * */ +int +cputs(const char *str) { +c01003a4: 55 push %ebp +c01003a5: 89 e5 mov %esp,%ebp +c01003a7: 83 ec 28 sub $0x28,%esp + int cnt = 0; +c01003aa: c7 45 f0 00 00 00 00 movl $0x0,-0x10(%ebp) + char c; + while ((c = *str ++) != '\0') { +c01003b1: eb 13 jmp c01003c6 + cputch(c, &cnt); +c01003b3: 0f be 45 f7 movsbl -0x9(%ebp),%eax +c01003b7: 8d 55 f0 lea -0x10(%ebp),%edx +c01003ba: 89 54 24 04 mov %edx,0x4(%esp) +c01003be: 89 04 24 mov %eax,(%esp) +c01003c1: e8 48 ff ff ff call c010030e + while ((c = *str ++) != '\0') { +c01003c6: 8b 45 08 mov 0x8(%ebp),%eax +c01003c9: 8d 50 01 lea 0x1(%eax),%edx +c01003cc: 89 55 08 mov %edx,0x8(%ebp) +c01003cf: 0f b6 00 movzbl (%eax),%eax +c01003d2: 88 45 f7 mov %al,-0x9(%ebp) +c01003d5: 80 7d f7 00 cmpb $0x0,-0x9(%ebp) +c01003d9: 75 d8 jne c01003b3 + } + cputch('\n', &cnt); +c01003db: 8d 45 f0 lea -0x10(%ebp),%eax +c01003de: 89 44 24 04 mov %eax,0x4(%esp) +c01003e2: c7 04 24 0a 00 00 00 movl $0xa,(%esp) +c01003e9: e8 20 ff ff ff call c010030e + return cnt; +c01003ee: 8b 45 f0 mov -0x10(%ebp),%eax +} +c01003f1: 89 ec mov %ebp,%esp +c01003f3: 5d pop %ebp +c01003f4: c3 ret + +c01003f5 : + +/* getchar - reads a single non-zero character from stdin */ +int +getchar(void) { +c01003f5: 55 push %ebp +c01003f6: 89 e5 mov %esp,%ebp +c01003f8: 83 ec 18 sub $0x18,%esp + int c; + while ((c = cons_getc()) == 0) +c01003fb: 90 nop +c01003fc: e8 12 12 00 00 call c0101613 +c0100401: 89 45 f4 mov %eax,-0xc(%ebp) +c0100404: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c0100408: 74 f2 je c01003fc + /* do nothing */; + return c; +c010040a: 8b 45 f4 mov -0xc(%ebp),%eax +} +c010040d: 89 ec mov %ebp,%esp +c010040f: 5d pop %ebp +c0100410: c3 ret + +c0100411 : + * 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) { +c0100411: 55 push %ebp +c0100412: 89 e5 mov %esp,%ebp +c0100414: 83 ec 20 sub $0x20,%esp + int l = *region_left, r = *region_right, any_matches = 0; +c0100417: 8b 45 0c mov 0xc(%ebp),%eax +c010041a: 8b 00 mov (%eax),%eax +c010041c: 89 45 fc mov %eax,-0x4(%ebp) +c010041f: 8b 45 10 mov 0x10(%ebp),%eax +c0100422: 8b 00 mov (%eax),%eax +c0100424: 89 45 f8 mov %eax,-0x8(%ebp) +c0100427: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + + while (l <= r) { +c010042e: e9 ca 00 00 00 jmp c01004fd + int true_m = (l + r) / 2, m = true_m; +c0100433: 8b 55 fc mov -0x4(%ebp),%edx +c0100436: 8b 45 f8 mov -0x8(%ebp),%eax +c0100439: 01 d0 add %edx,%eax +c010043b: 89 c2 mov %eax,%edx +c010043d: c1 ea 1f shr $0x1f,%edx +c0100440: 01 d0 add %edx,%eax +c0100442: d1 f8 sar %eax +c0100444: 89 45 ec mov %eax,-0x14(%ebp) +c0100447: 8b 45 ec mov -0x14(%ebp),%eax +c010044a: 89 45 f0 mov %eax,-0x10(%ebp) + + // search for earliest stab with right type + while (m >= l && stabs[m].n_type != type) { +c010044d: eb 03 jmp c0100452 + m --; +c010044f: ff 4d f0 decl -0x10(%ebp) + while (m >= l && stabs[m].n_type != type) { +c0100452: 8b 45 f0 mov -0x10(%ebp),%eax +c0100455: 3b 45 fc cmp -0x4(%ebp),%eax +c0100458: 7c 1f jl c0100479 +c010045a: 8b 55 f0 mov -0x10(%ebp),%edx +c010045d: 89 d0 mov %edx,%eax +c010045f: 01 c0 add %eax,%eax +c0100461: 01 d0 add %edx,%eax +c0100463: c1 e0 02 shl $0x2,%eax +c0100466: 89 c2 mov %eax,%edx +c0100468: 8b 45 08 mov 0x8(%ebp),%eax +c010046b: 01 d0 add %edx,%eax +c010046d: 0f b6 40 04 movzbl 0x4(%eax),%eax +c0100471: 0f b6 c0 movzbl %al,%eax +c0100474: 39 45 14 cmp %eax,0x14(%ebp) +c0100477: 75 d6 jne c010044f + } + if (m < l) { // no match in [l, m] +c0100479: 8b 45 f0 mov -0x10(%ebp),%eax +c010047c: 3b 45 fc cmp -0x4(%ebp),%eax +c010047f: 7d 09 jge c010048a + l = true_m + 1; +c0100481: 8b 45 ec mov -0x14(%ebp),%eax +c0100484: 40 inc %eax +c0100485: 89 45 fc mov %eax,-0x4(%ebp) + continue; +c0100488: eb 73 jmp c01004fd + } + + // actual binary search + any_matches = 1; +c010048a: c7 45 f4 01 00 00 00 movl $0x1,-0xc(%ebp) + if (stabs[m].n_value < addr) { +c0100491: 8b 55 f0 mov -0x10(%ebp),%edx +c0100494: 89 d0 mov %edx,%eax +c0100496: 01 c0 add %eax,%eax +c0100498: 01 d0 add %edx,%eax +c010049a: c1 e0 02 shl $0x2,%eax +c010049d: 89 c2 mov %eax,%edx +c010049f: 8b 45 08 mov 0x8(%ebp),%eax +c01004a2: 01 d0 add %edx,%eax +c01004a4: 8b 40 08 mov 0x8(%eax),%eax +c01004a7: 39 45 18 cmp %eax,0x18(%ebp) +c01004aa: 76 11 jbe c01004bd + *region_left = m; +c01004ac: 8b 45 0c mov 0xc(%ebp),%eax +c01004af: 8b 55 f0 mov -0x10(%ebp),%edx +c01004b2: 89 10 mov %edx,(%eax) + l = true_m + 1; +c01004b4: 8b 45 ec mov -0x14(%ebp),%eax +c01004b7: 40 inc %eax +c01004b8: 89 45 fc mov %eax,-0x4(%ebp) +c01004bb: eb 40 jmp c01004fd + } else if (stabs[m].n_value > addr) { +c01004bd: 8b 55 f0 mov -0x10(%ebp),%edx +c01004c0: 89 d0 mov %edx,%eax +c01004c2: 01 c0 add %eax,%eax +c01004c4: 01 d0 add %edx,%eax +c01004c6: c1 e0 02 shl $0x2,%eax +c01004c9: 89 c2 mov %eax,%edx +c01004cb: 8b 45 08 mov 0x8(%ebp),%eax +c01004ce: 01 d0 add %edx,%eax +c01004d0: 8b 40 08 mov 0x8(%eax),%eax +c01004d3: 39 45 18 cmp %eax,0x18(%ebp) +c01004d6: 73 14 jae c01004ec + *region_right = m - 1; +c01004d8: 8b 45 f0 mov -0x10(%ebp),%eax +c01004db: 8d 50 ff lea -0x1(%eax),%edx +c01004de: 8b 45 10 mov 0x10(%ebp),%eax +c01004e1: 89 10 mov %edx,(%eax) + r = m - 1; +c01004e3: 8b 45 f0 mov -0x10(%ebp),%eax +c01004e6: 48 dec %eax +c01004e7: 89 45 f8 mov %eax,-0x8(%ebp) +c01004ea: eb 11 jmp c01004fd + } else { + // exact match for 'addr', but continue loop to find + // *region_right + *region_left = m; +c01004ec: 8b 45 0c mov 0xc(%ebp),%eax +c01004ef: 8b 55 f0 mov -0x10(%ebp),%edx +c01004f2: 89 10 mov %edx,(%eax) + l = m; +c01004f4: 8b 45 f0 mov -0x10(%ebp),%eax +c01004f7: 89 45 fc mov %eax,-0x4(%ebp) + addr ++; +c01004fa: ff 45 18 incl 0x18(%ebp) + while (l <= r) { +c01004fd: 8b 45 fc mov -0x4(%ebp),%eax +c0100500: 3b 45 f8 cmp -0x8(%ebp),%eax +c0100503: 0f 8e 2a ff ff ff jle c0100433 + } + } + + if (!any_matches) { +c0100509: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c010050d: 75 0f jne c010051e + *region_right = *region_left - 1; +c010050f: 8b 45 0c mov 0xc(%ebp),%eax +c0100512: 8b 00 mov (%eax),%eax +c0100514: 8d 50 ff lea -0x1(%eax),%edx +c0100517: 8b 45 10 mov 0x10(%ebp),%eax +c010051a: 89 10 mov %edx,(%eax) + l = *region_right; + for (; l > *region_left && stabs[l].n_type != type; l --) + /* do nothing */; + *region_left = l; + } +} +c010051c: eb 3e jmp c010055c + l = *region_right; +c010051e: 8b 45 10 mov 0x10(%ebp),%eax +c0100521: 8b 00 mov (%eax),%eax +c0100523: 89 45 fc mov %eax,-0x4(%ebp) + for (; l > *region_left && stabs[l].n_type != type; l --) +c0100526: eb 03 jmp c010052b +c0100528: ff 4d fc decl -0x4(%ebp) +c010052b: 8b 45 0c mov 0xc(%ebp),%eax +c010052e: 8b 00 mov (%eax),%eax +c0100530: 39 45 fc cmp %eax,-0x4(%ebp) +c0100533: 7e 1f jle c0100554 +c0100535: 8b 55 fc mov -0x4(%ebp),%edx +c0100538: 89 d0 mov %edx,%eax +c010053a: 01 c0 add %eax,%eax +c010053c: 01 d0 add %edx,%eax +c010053e: c1 e0 02 shl $0x2,%eax +c0100541: 89 c2 mov %eax,%edx +c0100543: 8b 45 08 mov 0x8(%ebp),%eax +c0100546: 01 d0 add %edx,%eax +c0100548: 0f b6 40 04 movzbl 0x4(%eax),%eax +c010054c: 0f b6 c0 movzbl %al,%eax +c010054f: 39 45 14 cmp %eax,0x14(%ebp) +c0100552: 75 d4 jne c0100528 + *region_left = l; +c0100554: 8b 45 0c mov 0xc(%ebp),%eax +c0100557: 8b 55 fc mov -0x4(%ebp),%edx +c010055a: 89 10 mov %edx,(%eax) +} +c010055c: 90 nop +c010055d: 89 ec mov %ebp,%esp +c010055f: 5d pop %ebp +c0100560: c3 ret + +c0100561 : + * 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) { +c0100561: 55 push %ebp +c0100562: 89 e5 mov %esp,%ebp +c0100564: 83 ec 58 sub $0x58,%esp + const struct stab *stabs, *stab_end; + const char *stabstr, *stabstr_end; + + info->eip_file = ""; +c0100567: 8b 45 0c mov 0xc(%ebp),%eax +c010056a: c7 00 4c 61 10 c0 movl $0xc010614c,(%eax) + info->eip_line = 0; +c0100570: 8b 45 0c mov 0xc(%ebp),%eax +c0100573: c7 40 04 00 00 00 00 movl $0x0,0x4(%eax) + info->eip_fn_name = ""; +c010057a: 8b 45 0c mov 0xc(%ebp),%eax +c010057d: c7 40 08 4c 61 10 c0 movl $0xc010614c,0x8(%eax) + info->eip_fn_namelen = 9; +c0100584: 8b 45 0c mov 0xc(%ebp),%eax +c0100587: c7 40 0c 09 00 00 00 movl $0x9,0xc(%eax) + info->eip_fn_addr = addr; +c010058e: 8b 45 0c mov 0xc(%ebp),%eax +c0100591: 8b 55 08 mov 0x8(%ebp),%edx +c0100594: 89 50 10 mov %edx,0x10(%eax) + info->eip_fn_narg = 0; +c0100597: 8b 45 0c mov 0xc(%ebp),%eax +c010059a: c7 40 14 00 00 00 00 movl $0x0,0x14(%eax) + + stabs = __STAB_BEGIN__; +c01005a1: c7 45 f4 b8 73 10 c0 movl $0xc01073b8,-0xc(%ebp) + stab_end = __STAB_END__; +c01005a8: c7 45 f0 ac 2a 11 c0 movl $0xc0112aac,-0x10(%ebp) + stabstr = __STABSTR_BEGIN__; +c01005af: c7 45 ec ad 2a 11 c0 movl $0xc0112aad,-0x14(%ebp) + stabstr_end = __STABSTR_END__; +c01005b6: c7 45 e8 44 60 11 c0 movl $0xc0116044,-0x18(%ebp) + + // String table validity checks + if (stabstr_end <= stabstr || stabstr_end[-1] != 0) { +c01005bd: 8b 45 e8 mov -0x18(%ebp),%eax +c01005c0: 3b 45 ec cmp -0x14(%ebp),%eax +c01005c3: 76 0b jbe c01005d0 +c01005c5: 8b 45 e8 mov -0x18(%ebp),%eax +c01005c8: 48 dec %eax +c01005c9: 0f b6 00 movzbl (%eax),%eax +c01005cc: 84 c0 test %al,%al +c01005ce: 74 0a je c01005da + return -1; +c01005d0: b8 ff ff ff ff mov $0xffffffff,%eax +c01005d5: e9 ab 02 00 00 jmp c0100885 + // '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; +c01005da: c7 45 e4 00 00 00 00 movl $0x0,-0x1c(%ebp) +c01005e1: 8b 45 f0 mov -0x10(%ebp),%eax +c01005e4: 2b 45 f4 sub -0xc(%ebp),%eax +c01005e7: c1 f8 02 sar $0x2,%eax +c01005ea: 69 c0 ab aa aa aa imul $0xaaaaaaab,%eax,%eax +c01005f0: 48 dec %eax +c01005f1: 89 45 e0 mov %eax,-0x20(%ebp) + stab_binsearch(stabs, &lfile, &rfile, N_SO, addr); +c01005f4: 8b 45 08 mov 0x8(%ebp),%eax +c01005f7: 89 44 24 10 mov %eax,0x10(%esp) +c01005fb: c7 44 24 0c 64 00 00 movl $0x64,0xc(%esp) +c0100602: 00 +c0100603: 8d 45 e0 lea -0x20(%ebp),%eax +c0100606: 89 44 24 08 mov %eax,0x8(%esp) +c010060a: 8d 45 e4 lea -0x1c(%ebp),%eax +c010060d: 89 44 24 04 mov %eax,0x4(%esp) +c0100611: 8b 45 f4 mov -0xc(%ebp),%eax +c0100614: 89 04 24 mov %eax,(%esp) +c0100617: e8 f5 fd ff ff call c0100411 + if (lfile == 0) +c010061c: 8b 45 e4 mov -0x1c(%ebp),%eax +c010061f: 85 c0 test %eax,%eax +c0100621: 75 0a jne c010062d + return -1; +c0100623: b8 ff ff ff ff mov $0xffffffff,%eax +c0100628: e9 58 02 00 00 jmp c0100885 + + // Search within that file's stabs for the function definition + // (N_FUN). + int lfun = lfile, rfun = rfile; +c010062d: 8b 45 e4 mov -0x1c(%ebp),%eax +c0100630: 89 45 dc mov %eax,-0x24(%ebp) +c0100633: 8b 45 e0 mov -0x20(%ebp),%eax +c0100636: 89 45 d8 mov %eax,-0x28(%ebp) + int lline, rline; + stab_binsearch(stabs, &lfun, &rfun, N_FUN, addr); +c0100639: 8b 45 08 mov 0x8(%ebp),%eax +c010063c: 89 44 24 10 mov %eax,0x10(%esp) +c0100640: c7 44 24 0c 24 00 00 movl $0x24,0xc(%esp) +c0100647: 00 +c0100648: 8d 45 d8 lea -0x28(%ebp),%eax +c010064b: 89 44 24 08 mov %eax,0x8(%esp) +c010064f: 8d 45 dc lea -0x24(%ebp),%eax +c0100652: 89 44 24 04 mov %eax,0x4(%esp) +c0100656: 8b 45 f4 mov -0xc(%ebp),%eax +c0100659: 89 04 24 mov %eax,(%esp) +c010065c: e8 b0 fd ff ff call c0100411 + + if (lfun <= rfun) { +c0100661: 8b 55 dc mov -0x24(%ebp),%edx +c0100664: 8b 45 d8 mov -0x28(%ebp),%eax +c0100667: 39 c2 cmp %eax,%edx +c0100669: 7f 78 jg c01006e3 + // 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) { +c010066b: 8b 45 dc mov -0x24(%ebp),%eax +c010066e: 89 c2 mov %eax,%edx +c0100670: 89 d0 mov %edx,%eax +c0100672: 01 c0 add %eax,%eax +c0100674: 01 d0 add %edx,%eax +c0100676: c1 e0 02 shl $0x2,%eax +c0100679: 89 c2 mov %eax,%edx +c010067b: 8b 45 f4 mov -0xc(%ebp),%eax +c010067e: 01 d0 add %edx,%eax +c0100680: 8b 10 mov (%eax),%edx +c0100682: 8b 45 e8 mov -0x18(%ebp),%eax +c0100685: 2b 45 ec sub -0x14(%ebp),%eax +c0100688: 39 c2 cmp %eax,%edx +c010068a: 73 22 jae c01006ae + info->eip_fn_name = stabstr + stabs[lfun].n_strx; +c010068c: 8b 45 dc mov -0x24(%ebp),%eax +c010068f: 89 c2 mov %eax,%edx +c0100691: 89 d0 mov %edx,%eax +c0100693: 01 c0 add %eax,%eax +c0100695: 01 d0 add %edx,%eax +c0100697: c1 e0 02 shl $0x2,%eax +c010069a: 89 c2 mov %eax,%edx +c010069c: 8b 45 f4 mov -0xc(%ebp),%eax +c010069f: 01 d0 add %edx,%eax +c01006a1: 8b 10 mov (%eax),%edx +c01006a3: 8b 45 ec mov -0x14(%ebp),%eax +c01006a6: 01 c2 add %eax,%edx +c01006a8: 8b 45 0c mov 0xc(%ebp),%eax +c01006ab: 89 50 08 mov %edx,0x8(%eax) + } + info->eip_fn_addr = stabs[lfun].n_value; +c01006ae: 8b 45 dc mov -0x24(%ebp),%eax +c01006b1: 89 c2 mov %eax,%edx +c01006b3: 89 d0 mov %edx,%eax +c01006b5: 01 c0 add %eax,%eax +c01006b7: 01 d0 add %edx,%eax +c01006b9: c1 e0 02 shl $0x2,%eax +c01006bc: 89 c2 mov %eax,%edx +c01006be: 8b 45 f4 mov -0xc(%ebp),%eax +c01006c1: 01 d0 add %edx,%eax +c01006c3: 8b 50 08 mov 0x8(%eax),%edx +c01006c6: 8b 45 0c mov 0xc(%ebp),%eax +c01006c9: 89 50 10 mov %edx,0x10(%eax) + addr -= info->eip_fn_addr; +c01006cc: 8b 45 0c mov 0xc(%ebp),%eax +c01006cf: 8b 40 10 mov 0x10(%eax),%eax +c01006d2: 29 45 08 sub %eax,0x8(%ebp) + // Search within the function definition for the line number. + lline = lfun; +c01006d5: 8b 45 dc mov -0x24(%ebp),%eax +c01006d8: 89 45 d4 mov %eax,-0x2c(%ebp) + rline = rfun; +c01006db: 8b 45 d8 mov -0x28(%ebp),%eax +c01006de: 89 45 d0 mov %eax,-0x30(%ebp) +c01006e1: eb 15 jmp c01006f8 + } 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; +c01006e3: 8b 45 0c mov 0xc(%ebp),%eax +c01006e6: 8b 55 08 mov 0x8(%ebp),%edx +c01006e9: 89 50 10 mov %edx,0x10(%eax) + lline = lfile; +c01006ec: 8b 45 e4 mov -0x1c(%ebp),%eax +c01006ef: 89 45 d4 mov %eax,-0x2c(%ebp) + rline = rfile; +c01006f2: 8b 45 e0 mov -0x20(%ebp),%eax +c01006f5: 89 45 d0 mov %eax,-0x30(%ebp) + } + info->eip_fn_namelen = strfind(info->eip_fn_name, ':') - info->eip_fn_name; +c01006f8: 8b 45 0c mov 0xc(%ebp),%eax +c01006fb: 8b 40 08 mov 0x8(%eax),%eax +c01006fe: c7 44 24 04 3a 00 00 movl $0x3a,0x4(%esp) +c0100705: 00 +c0100706: 89 04 24 mov %eax,(%esp) +c0100709: e8 72 56 00 00 call c0105d80 +c010070e: 8b 55 0c mov 0xc(%ebp),%edx +c0100711: 8b 4a 08 mov 0x8(%edx),%ecx +c0100714: 29 c8 sub %ecx,%eax +c0100716: 89 c2 mov %eax,%edx +c0100718: 8b 45 0c mov 0xc(%ebp),%eax +c010071b: 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); +c010071e: 8b 45 08 mov 0x8(%ebp),%eax +c0100721: 89 44 24 10 mov %eax,0x10(%esp) +c0100725: c7 44 24 0c 44 00 00 movl $0x44,0xc(%esp) +c010072c: 00 +c010072d: 8d 45 d0 lea -0x30(%ebp),%eax +c0100730: 89 44 24 08 mov %eax,0x8(%esp) +c0100734: 8d 45 d4 lea -0x2c(%ebp),%eax +c0100737: 89 44 24 04 mov %eax,0x4(%esp) +c010073b: 8b 45 f4 mov -0xc(%ebp),%eax +c010073e: 89 04 24 mov %eax,(%esp) +c0100741: e8 cb fc ff ff call c0100411 + if (lline <= rline) { +c0100746: 8b 55 d4 mov -0x2c(%ebp),%edx +c0100749: 8b 45 d0 mov -0x30(%ebp),%eax +c010074c: 39 c2 cmp %eax,%edx +c010074e: 7f 23 jg c0100773 + info->eip_line = stabs[rline].n_desc; +c0100750: 8b 45 d0 mov -0x30(%ebp),%eax +c0100753: 89 c2 mov %eax,%edx +c0100755: 89 d0 mov %edx,%eax +c0100757: 01 c0 add %eax,%eax +c0100759: 01 d0 add %edx,%eax +c010075b: c1 e0 02 shl $0x2,%eax +c010075e: 89 c2 mov %eax,%edx +c0100760: 8b 45 f4 mov -0xc(%ebp),%eax +c0100763: 01 d0 add %edx,%eax +c0100765: 0f b7 40 06 movzwl 0x6(%eax),%eax +c0100769: 89 c2 mov %eax,%edx +c010076b: 8b 45 0c mov 0xc(%ebp),%eax +c010076e: 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 +c0100771: eb 11 jmp c0100784 + return -1; +c0100773: b8 ff ff ff ff mov $0xffffffff,%eax +c0100778: e9 08 01 00 00 jmp c0100885 + && stabs[lline].n_type != N_SOL + && (stabs[lline].n_type != N_SO || !stabs[lline].n_value)) { + lline --; +c010077d: 8b 45 d4 mov -0x2c(%ebp),%eax +c0100780: 48 dec %eax +c0100781: 89 45 d4 mov %eax,-0x2c(%ebp) + while (lline >= lfile +c0100784: 8b 55 d4 mov -0x2c(%ebp),%edx +c0100787: 8b 45 e4 mov -0x1c(%ebp),%eax + && (stabs[lline].n_type != N_SO || !stabs[lline].n_value)) { +c010078a: 39 c2 cmp %eax,%edx +c010078c: 7c 56 jl c01007e4 + && stabs[lline].n_type != N_SOL +c010078e: 8b 45 d4 mov -0x2c(%ebp),%eax +c0100791: 89 c2 mov %eax,%edx +c0100793: 89 d0 mov %edx,%eax +c0100795: 01 c0 add %eax,%eax +c0100797: 01 d0 add %edx,%eax +c0100799: c1 e0 02 shl $0x2,%eax +c010079c: 89 c2 mov %eax,%edx +c010079e: 8b 45 f4 mov -0xc(%ebp),%eax +c01007a1: 01 d0 add %edx,%eax +c01007a3: 0f b6 40 04 movzbl 0x4(%eax),%eax +c01007a7: 3c 84 cmp $0x84,%al +c01007a9: 74 39 je c01007e4 + && (stabs[lline].n_type != N_SO || !stabs[lline].n_value)) { +c01007ab: 8b 45 d4 mov -0x2c(%ebp),%eax +c01007ae: 89 c2 mov %eax,%edx +c01007b0: 89 d0 mov %edx,%eax +c01007b2: 01 c0 add %eax,%eax +c01007b4: 01 d0 add %edx,%eax +c01007b6: c1 e0 02 shl $0x2,%eax +c01007b9: 89 c2 mov %eax,%edx +c01007bb: 8b 45 f4 mov -0xc(%ebp),%eax +c01007be: 01 d0 add %edx,%eax +c01007c0: 0f b6 40 04 movzbl 0x4(%eax),%eax +c01007c4: 3c 64 cmp $0x64,%al +c01007c6: 75 b5 jne c010077d +c01007c8: 8b 45 d4 mov -0x2c(%ebp),%eax +c01007cb: 89 c2 mov %eax,%edx +c01007cd: 89 d0 mov %edx,%eax +c01007cf: 01 c0 add %eax,%eax +c01007d1: 01 d0 add %edx,%eax +c01007d3: c1 e0 02 shl $0x2,%eax +c01007d6: 89 c2 mov %eax,%edx +c01007d8: 8b 45 f4 mov -0xc(%ebp),%eax +c01007db: 01 d0 add %edx,%eax +c01007dd: 8b 40 08 mov 0x8(%eax),%eax +c01007e0: 85 c0 test %eax,%eax +c01007e2: 74 99 je c010077d + } + if (lline >= lfile && stabs[lline].n_strx < stabstr_end - stabstr) { +c01007e4: 8b 55 d4 mov -0x2c(%ebp),%edx +c01007e7: 8b 45 e4 mov -0x1c(%ebp),%eax +c01007ea: 39 c2 cmp %eax,%edx +c01007ec: 7c 42 jl c0100830 +c01007ee: 8b 45 d4 mov -0x2c(%ebp),%eax +c01007f1: 89 c2 mov %eax,%edx +c01007f3: 89 d0 mov %edx,%eax +c01007f5: 01 c0 add %eax,%eax +c01007f7: 01 d0 add %edx,%eax +c01007f9: c1 e0 02 shl $0x2,%eax +c01007fc: 89 c2 mov %eax,%edx +c01007fe: 8b 45 f4 mov -0xc(%ebp),%eax +c0100801: 01 d0 add %edx,%eax +c0100803: 8b 10 mov (%eax),%edx +c0100805: 8b 45 e8 mov -0x18(%ebp),%eax +c0100808: 2b 45 ec sub -0x14(%ebp),%eax +c010080b: 39 c2 cmp %eax,%edx +c010080d: 73 21 jae c0100830 + info->eip_file = stabstr + stabs[lline].n_strx; +c010080f: 8b 45 d4 mov -0x2c(%ebp),%eax +c0100812: 89 c2 mov %eax,%edx +c0100814: 89 d0 mov %edx,%eax +c0100816: 01 c0 add %eax,%eax +c0100818: 01 d0 add %edx,%eax +c010081a: c1 e0 02 shl $0x2,%eax +c010081d: 89 c2 mov %eax,%edx +c010081f: 8b 45 f4 mov -0xc(%ebp),%eax +c0100822: 01 d0 add %edx,%eax +c0100824: 8b 10 mov (%eax),%edx +c0100826: 8b 45 ec mov -0x14(%ebp),%eax +c0100829: 01 c2 add %eax,%edx +c010082b: 8b 45 0c mov 0xc(%ebp),%eax +c010082e: 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) { +c0100830: 8b 55 dc mov -0x24(%ebp),%edx +c0100833: 8b 45 d8 mov -0x28(%ebp),%eax +c0100836: 39 c2 cmp %eax,%edx +c0100838: 7d 46 jge c0100880 + for (lline = lfun + 1; +c010083a: 8b 45 dc mov -0x24(%ebp),%eax +c010083d: 40 inc %eax +c010083e: 89 45 d4 mov %eax,-0x2c(%ebp) +c0100841: eb 16 jmp c0100859 + lline < rfun && stabs[lline].n_type == N_PSYM; + lline ++) { + info->eip_fn_narg ++; +c0100843: 8b 45 0c mov 0xc(%ebp),%eax +c0100846: 8b 40 14 mov 0x14(%eax),%eax +c0100849: 8d 50 01 lea 0x1(%eax),%edx +c010084c: 8b 45 0c mov 0xc(%ebp),%eax +c010084f: 89 50 14 mov %edx,0x14(%eax) + lline ++) { +c0100852: 8b 45 d4 mov -0x2c(%ebp),%eax +c0100855: 40 inc %eax +c0100856: 89 45 d4 mov %eax,-0x2c(%ebp) + lline < rfun && stabs[lline].n_type == N_PSYM; +c0100859: 8b 55 d4 mov -0x2c(%ebp),%edx +c010085c: 8b 45 d8 mov -0x28(%ebp),%eax +c010085f: 39 c2 cmp %eax,%edx +c0100861: 7d 1d jge c0100880 +c0100863: 8b 45 d4 mov -0x2c(%ebp),%eax +c0100866: 89 c2 mov %eax,%edx +c0100868: 89 d0 mov %edx,%eax +c010086a: 01 c0 add %eax,%eax +c010086c: 01 d0 add %edx,%eax +c010086e: c1 e0 02 shl $0x2,%eax +c0100871: 89 c2 mov %eax,%edx +c0100873: 8b 45 f4 mov -0xc(%ebp),%eax +c0100876: 01 d0 add %edx,%eax +c0100878: 0f b6 40 04 movzbl 0x4(%eax),%eax +c010087c: 3c a0 cmp $0xa0,%al +c010087e: 74 c3 je c0100843 + } + } + return 0; +c0100880: b8 00 00 00 00 mov $0x0,%eax +} +c0100885: 89 ec mov %ebp,%esp +c0100887: 5d pop %ebp +c0100888: c3 ret + +c0100889 : + * 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) { +c0100889: 55 push %ebp +c010088a: 89 e5 mov %esp,%ebp +c010088c: 83 ec 18 sub $0x18,%esp + extern char etext[], edata[], end[], kern_init[]; + cprintf("Special kernel symbols:\n"); +c010088f: c7 04 24 56 61 10 c0 movl $0xc0106156,(%esp) +c0100896: e8 cb fa ff ff call c0100366 + cprintf(" entry 0x%08x (phys)\n", kern_init); +c010089b: c7 44 24 04 36 00 10 movl $0xc0100036,0x4(%esp) +c01008a2: c0 +c01008a3: c7 04 24 6f 61 10 c0 movl $0xc010616f,(%esp) +c01008aa: e8 b7 fa ff ff call c0100366 + cprintf(" etext 0x%08x (phys)\n", etext); +c01008af: c7 44 24 04 94 60 10 movl $0xc0106094,0x4(%esp) +c01008b6: c0 +c01008b7: c7 04 24 87 61 10 c0 movl $0xc0106187,(%esp) +c01008be: e8 a3 fa ff ff call c0100366 + cprintf(" edata 0x%08x (phys)\n", edata); +c01008c3: c7 44 24 04 00 c0 11 movl $0xc011c000,0x4(%esp) +c01008ca: c0 +c01008cb: c7 04 24 9f 61 10 c0 movl $0xc010619f,(%esp) +c01008d2: e8 8f fa ff ff call c0100366 + cprintf(" end 0x%08x (phys)\n", end); +c01008d7: c7 44 24 04 8c cf 11 movl $0xc011cf8c,0x4(%esp) +c01008de: c0 +c01008df: c7 04 24 b7 61 10 c0 movl $0xc01061b7,(%esp) +c01008e6: e8 7b fa ff ff call c0100366 + cprintf("Kernel executable memory footprint: %dKB\n", (end - kern_init + 1023)/1024); +c01008eb: b8 8c cf 11 c0 mov $0xc011cf8c,%eax +c01008f0: 2d 36 00 10 c0 sub $0xc0100036,%eax +c01008f5: 05 ff 03 00 00 add $0x3ff,%eax +c01008fa: 8d 90 ff 03 00 00 lea 0x3ff(%eax),%edx +c0100900: 85 c0 test %eax,%eax +c0100902: 0f 48 c2 cmovs %edx,%eax +c0100905: c1 f8 0a sar $0xa,%eax +c0100908: 89 44 24 04 mov %eax,0x4(%esp) +c010090c: c7 04 24 d0 61 10 c0 movl $0xc01061d0,(%esp) +c0100913: e8 4e fa ff ff call c0100366 +} +c0100918: 90 nop +c0100919: 89 ec mov %ebp,%esp +c010091b: 5d pop %ebp +c010091c: c3 ret + +c010091d : +/* * + * 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) { +c010091d: 55 push %ebp +c010091e: 89 e5 mov %esp,%ebp +c0100920: 81 ec 48 01 00 00 sub $0x148,%esp + struct eipdebuginfo info; + if (debuginfo_eip(eip, &info) != 0) { +c0100926: 8d 45 dc lea -0x24(%ebp),%eax +c0100929: 89 44 24 04 mov %eax,0x4(%esp) +c010092d: 8b 45 08 mov 0x8(%ebp),%eax +c0100930: 89 04 24 mov %eax,(%esp) +c0100933: e8 29 fc ff ff call c0100561 +c0100938: 85 c0 test %eax,%eax +c010093a: 74 15 je c0100951 + cprintf(" : -- 0x%08x --\n", eip); +c010093c: 8b 45 08 mov 0x8(%ebp),%eax +c010093f: 89 44 24 04 mov %eax,0x4(%esp) +c0100943: c7 04 24 fa 61 10 c0 movl $0xc01061fa,(%esp) +c010094a: e8 17 fa ff ff call c0100366 + } + fnname[j] = '\0'; + cprintf(" %s:%d: %s+%d\n", info.eip_file, info.eip_line, + fnname, eip - info.eip_fn_addr); + } +} +c010094f: eb 6c jmp c01009bd + for (j = 0; j < info.eip_fn_namelen; j ++) { +c0100951: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) +c0100958: eb 1b jmp c0100975 + fnname[j] = info.eip_fn_name[j]; +c010095a: 8b 55 e4 mov -0x1c(%ebp),%edx +c010095d: 8b 45 f4 mov -0xc(%ebp),%eax +c0100960: 01 d0 add %edx,%eax +c0100962: 0f b6 10 movzbl (%eax),%edx +c0100965: 8d 8d dc fe ff ff lea -0x124(%ebp),%ecx +c010096b: 8b 45 f4 mov -0xc(%ebp),%eax +c010096e: 01 c8 add %ecx,%eax +c0100970: 88 10 mov %dl,(%eax) + for (j = 0; j < info.eip_fn_namelen; j ++) { +c0100972: ff 45 f4 incl -0xc(%ebp) +c0100975: 8b 45 e8 mov -0x18(%ebp),%eax +c0100978: 39 45 f4 cmp %eax,-0xc(%ebp) +c010097b: 7c dd jl c010095a + fnname[j] = '\0'; +c010097d: 8d 95 dc fe ff ff lea -0x124(%ebp),%edx +c0100983: 8b 45 f4 mov -0xc(%ebp),%eax +c0100986: 01 d0 add %edx,%eax +c0100988: c6 00 00 movb $0x0,(%eax) + fnname, eip - info.eip_fn_addr); +c010098b: 8b 55 ec mov -0x14(%ebp),%edx + cprintf(" %s:%d: %s+%d\n", info.eip_file, info.eip_line, +c010098e: 8b 45 08 mov 0x8(%ebp),%eax +c0100991: 29 d0 sub %edx,%eax +c0100993: 89 c1 mov %eax,%ecx +c0100995: 8b 55 e0 mov -0x20(%ebp),%edx +c0100998: 8b 45 dc mov -0x24(%ebp),%eax +c010099b: 89 4c 24 10 mov %ecx,0x10(%esp) +c010099f: 8d 8d dc fe ff ff lea -0x124(%ebp),%ecx +c01009a5: 89 4c 24 0c mov %ecx,0xc(%esp) +c01009a9: 89 54 24 08 mov %edx,0x8(%esp) +c01009ad: 89 44 24 04 mov %eax,0x4(%esp) +c01009b1: c7 04 24 16 62 10 c0 movl $0xc0106216,(%esp) +c01009b8: e8 a9 f9 ff ff call c0100366 +} +c01009bd: 90 nop +c01009be: 89 ec mov %ebp,%esp +c01009c0: 5d pop %ebp +c01009c1: c3 ret + +c01009c2 : + +static __noinline uint32_t +read_eip(void) { +c01009c2: 55 push %ebp +c01009c3: 89 e5 mov %esp,%ebp +c01009c5: 83 ec 10 sub $0x10,%esp + uint32_t eip; + asm volatile("movl 4(%%ebp), %0" : "=r" (eip)); +c01009c8: 8b 45 04 mov 0x4(%ebp),%eax +c01009cb: 89 45 fc mov %eax,-0x4(%ebp) + return eip; +c01009ce: 8b 45 fc mov -0x4(%ebp),%eax +} +c01009d1: 89 ec mov %ebp,%esp +c01009d3: 5d pop %ebp +c01009d4: c3 ret + +c01009d5 : + * + * 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) { +c01009d5: 55 push %ebp +c01009d6: 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] + */ +} +c01009d8: 90 nop +c01009d9: 5d pop %ebp +c01009da: c3 ret + +c01009db : +#define MAXARGS 16 +#define WHITESPACE " \t\n\r" + +/* parse - parse the command buffer into whitespace-separated arguments */ +static int +parse(char *buf, char **argv) { +c01009db: 55 push %ebp +c01009dc: 89 e5 mov %esp,%ebp +c01009de: 83 ec 28 sub $0x28,%esp + int argc = 0; +c01009e1: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + while (1) { + // find global whitespace + while (*buf != '\0' && strchr(WHITESPACE, *buf) != NULL) { +c01009e8: eb 0c jmp c01009f6 + *buf ++ = '\0'; +c01009ea: 8b 45 08 mov 0x8(%ebp),%eax +c01009ed: 8d 50 01 lea 0x1(%eax),%edx +c01009f0: 89 55 08 mov %edx,0x8(%ebp) +c01009f3: c6 00 00 movb $0x0,(%eax) + while (*buf != '\0' && strchr(WHITESPACE, *buf) != NULL) { +c01009f6: 8b 45 08 mov 0x8(%ebp),%eax +c01009f9: 0f b6 00 movzbl (%eax),%eax +c01009fc: 84 c0 test %al,%al +c01009fe: 74 1d je c0100a1d +c0100a00: 8b 45 08 mov 0x8(%ebp),%eax +c0100a03: 0f b6 00 movzbl (%eax),%eax +c0100a06: 0f be c0 movsbl %al,%eax +c0100a09: 89 44 24 04 mov %eax,0x4(%esp) +c0100a0d: c7 04 24 a8 62 10 c0 movl $0xc01062a8,(%esp) +c0100a14: e8 33 53 00 00 call c0105d4c +c0100a19: 85 c0 test %eax,%eax +c0100a1b: 75 cd jne c01009ea + } + if (*buf == '\0') { +c0100a1d: 8b 45 08 mov 0x8(%ebp),%eax +c0100a20: 0f b6 00 movzbl (%eax),%eax +c0100a23: 84 c0 test %al,%al +c0100a25: 74 65 je c0100a8c + break; + } + + // save and scan past next arg + if (argc == MAXARGS - 1) { +c0100a27: 83 7d f4 0f cmpl $0xf,-0xc(%ebp) +c0100a2b: 75 14 jne c0100a41 + cprintf("Too many arguments (max %d).\n", MAXARGS); +c0100a2d: c7 44 24 04 10 00 00 movl $0x10,0x4(%esp) +c0100a34: 00 +c0100a35: c7 04 24 ad 62 10 c0 movl $0xc01062ad,(%esp) +c0100a3c: e8 25 f9 ff ff call c0100366 + } + argv[argc ++] = buf; +c0100a41: 8b 45 f4 mov -0xc(%ebp),%eax +c0100a44: 8d 50 01 lea 0x1(%eax),%edx +c0100a47: 89 55 f4 mov %edx,-0xc(%ebp) +c0100a4a: 8d 14 85 00 00 00 00 lea 0x0(,%eax,4),%edx +c0100a51: 8b 45 0c mov 0xc(%ebp),%eax +c0100a54: 01 c2 add %eax,%edx +c0100a56: 8b 45 08 mov 0x8(%ebp),%eax +c0100a59: 89 02 mov %eax,(%edx) + while (*buf != '\0' && strchr(WHITESPACE, *buf) == NULL) { +c0100a5b: eb 03 jmp c0100a60 + buf ++; +c0100a5d: ff 45 08 incl 0x8(%ebp) + while (*buf != '\0' && strchr(WHITESPACE, *buf) == NULL) { +c0100a60: 8b 45 08 mov 0x8(%ebp),%eax +c0100a63: 0f b6 00 movzbl (%eax),%eax +c0100a66: 84 c0 test %al,%al +c0100a68: 74 8c je c01009f6 +c0100a6a: 8b 45 08 mov 0x8(%ebp),%eax +c0100a6d: 0f b6 00 movzbl (%eax),%eax +c0100a70: 0f be c0 movsbl %al,%eax +c0100a73: 89 44 24 04 mov %eax,0x4(%esp) +c0100a77: c7 04 24 a8 62 10 c0 movl $0xc01062a8,(%esp) +c0100a7e: e8 c9 52 00 00 call c0105d4c +c0100a83: 85 c0 test %eax,%eax +c0100a85: 74 d6 je c0100a5d + while (*buf != '\0' && strchr(WHITESPACE, *buf) != NULL) { +c0100a87: e9 6a ff ff ff jmp c01009f6 + break; +c0100a8c: 90 nop + } + } + return argc; +c0100a8d: 8b 45 f4 mov -0xc(%ebp),%eax +} +c0100a90: 89 ec mov %ebp,%esp +c0100a92: 5d pop %ebp +c0100a93: c3 ret + +c0100a94 : +/* * + * 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) { +c0100a94: 55 push %ebp +c0100a95: 89 e5 mov %esp,%ebp +c0100a97: 83 ec 68 sub $0x68,%esp +c0100a9a: 89 5d fc mov %ebx,-0x4(%ebp) + char *argv[MAXARGS]; + int argc = parse(buf, argv); +c0100a9d: 8d 45 b0 lea -0x50(%ebp),%eax +c0100aa0: 89 44 24 04 mov %eax,0x4(%esp) +c0100aa4: 8b 45 08 mov 0x8(%ebp),%eax +c0100aa7: 89 04 24 mov %eax,(%esp) +c0100aaa: e8 2c ff ff ff call c01009db +c0100aaf: 89 45 f0 mov %eax,-0x10(%ebp) + if (argc == 0) { +c0100ab2: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) +c0100ab6: 75 0a jne c0100ac2 + return 0; +c0100ab8: b8 00 00 00 00 mov $0x0,%eax +c0100abd: e9 83 00 00 00 jmp c0100b45 + } + int i; + for (i = 0; i < NCOMMANDS; i ++) { +c0100ac2: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) +c0100ac9: eb 5a jmp c0100b25 + if (strcmp(commands[i].name, argv[0]) == 0) { +c0100acb: 8b 55 b0 mov -0x50(%ebp),%edx +c0100ace: 8b 4d f4 mov -0xc(%ebp),%ecx +c0100ad1: 89 c8 mov %ecx,%eax +c0100ad3: 01 c0 add %eax,%eax +c0100ad5: 01 c8 add %ecx,%eax +c0100ad7: c1 e0 02 shl $0x2,%eax +c0100ada: 05 00 90 11 c0 add $0xc0119000,%eax +c0100adf: 8b 00 mov (%eax),%eax +c0100ae1: 89 54 24 04 mov %edx,0x4(%esp) +c0100ae5: 89 04 24 mov %eax,(%esp) +c0100ae8: e8 c3 51 00 00 call c0105cb0 +c0100aed: 85 c0 test %eax,%eax +c0100aef: 75 31 jne c0100b22 + return commands[i].func(argc - 1, argv + 1, tf); +c0100af1: 8b 55 f4 mov -0xc(%ebp),%edx +c0100af4: 89 d0 mov %edx,%eax +c0100af6: 01 c0 add %eax,%eax +c0100af8: 01 d0 add %edx,%eax +c0100afa: c1 e0 02 shl $0x2,%eax +c0100afd: 05 08 90 11 c0 add $0xc0119008,%eax +c0100b02: 8b 10 mov (%eax),%edx +c0100b04: 8d 45 b0 lea -0x50(%ebp),%eax +c0100b07: 83 c0 04 add $0x4,%eax +c0100b0a: 8b 4d f0 mov -0x10(%ebp),%ecx +c0100b0d: 8d 59 ff lea -0x1(%ecx),%ebx +c0100b10: 8b 4d 0c mov 0xc(%ebp),%ecx +c0100b13: 89 4c 24 08 mov %ecx,0x8(%esp) +c0100b17: 89 44 24 04 mov %eax,0x4(%esp) +c0100b1b: 89 1c 24 mov %ebx,(%esp) +c0100b1e: ff d2 call *%edx +c0100b20: eb 23 jmp c0100b45 + for (i = 0; i < NCOMMANDS; i ++) { +c0100b22: ff 45 f4 incl -0xc(%ebp) +c0100b25: 8b 45 f4 mov -0xc(%ebp),%eax +c0100b28: 83 f8 02 cmp $0x2,%eax +c0100b2b: 76 9e jbe c0100acb + } + } + cprintf("Unknown command '%s'\n", argv[0]); +c0100b2d: 8b 45 b0 mov -0x50(%ebp),%eax +c0100b30: 89 44 24 04 mov %eax,0x4(%esp) +c0100b34: c7 04 24 cb 62 10 c0 movl $0xc01062cb,(%esp) +c0100b3b: e8 26 f8 ff ff call c0100366 + return 0; +c0100b40: b8 00 00 00 00 mov $0x0,%eax +} +c0100b45: 8b 5d fc mov -0x4(%ebp),%ebx +c0100b48: 89 ec mov %ebp,%esp +c0100b4a: 5d pop %ebp +c0100b4b: c3 ret + +c0100b4c : + +/***** Implementations of basic kernel monitor commands *****/ + +void +kmonitor(struct trapframe *tf) { +c0100b4c: 55 push %ebp +c0100b4d: 89 e5 mov %esp,%ebp +c0100b4f: 83 ec 28 sub $0x28,%esp + cprintf("Welcome to the kernel debug monitor!!\n"); +c0100b52: c7 04 24 e4 62 10 c0 movl $0xc01062e4,(%esp) +c0100b59: e8 08 f8 ff ff call c0100366 + cprintf("Type 'help' for a list of commands.\n"); +c0100b5e: c7 04 24 0c 63 10 c0 movl $0xc010630c,(%esp) +c0100b65: e8 fc f7 ff ff call c0100366 + + if (tf != NULL) { +c0100b6a: 83 7d 08 00 cmpl $0x0,0x8(%ebp) +c0100b6e: 74 0b je c0100b7b + print_trapframe(tf); +c0100b70: 8b 45 08 mov 0x8(%ebp),%eax +c0100b73: 89 04 24 mov %eax,(%esp) +c0100b76: e8 cf 0e 00 00 call c0101a4a + } + + char *buf; + while (1) { + if ((buf = readline("K> ")) != NULL) { +c0100b7b: c7 04 24 31 63 10 c0 movl $0xc0106331,(%esp) +c0100b82: e8 d0 f6 ff ff call c0100257 +c0100b87: 89 45 f4 mov %eax,-0xc(%ebp) +c0100b8a: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c0100b8e: 74 eb je c0100b7b + if (runcmd(buf, tf) < 0) { +c0100b90: 8b 45 08 mov 0x8(%ebp),%eax +c0100b93: 89 44 24 04 mov %eax,0x4(%esp) +c0100b97: 8b 45 f4 mov -0xc(%ebp),%eax +c0100b9a: 89 04 24 mov %eax,(%esp) +c0100b9d: e8 f2 fe ff ff call c0100a94 +c0100ba2: 85 c0 test %eax,%eax +c0100ba4: 78 02 js c0100ba8 + if ((buf = readline("K> ")) != NULL) { +c0100ba6: eb d3 jmp c0100b7b + break; +c0100ba8: 90 nop + } + } + } +} +c0100ba9: 90 nop +c0100baa: 89 ec mov %ebp,%esp +c0100bac: 5d pop %ebp +c0100bad: c3 ret + +c0100bae : + +/* mon_help - print the information about mon_* functions */ +int +mon_help(int argc, char **argv, struct trapframe *tf) { +c0100bae: 55 push %ebp +c0100baf: 89 e5 mov %esp,%ebp +c0100bb1: 83 ec 28 sub $0x28,%esp + int i; + for (i = 0; i < NCOMMANDS; i ++) { +c0100bb4: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) +c0100bbb: eb 3d jmp c0100bfa + cprintf("%s - %s\n", commands[i].name, commands[i].desc); +c0100bbd: 8b 55 f4 mov -0xc(%ebp),%edx +c0100bc0: 89 d0 mov %edx,%eax +c0100bc2: 01 c0 add %eax,%eax +c0100bc4: 01 d0 add %edx,%eax +c0100bc6: c1 e0 02 shl $0x2,%eax +c0100bc9: 05 04 90 11 c0 add $0xc0119004,%eax +c0100bce: 8b 10 mov (%eax),%edx +c0100bd0: 8b 4d f4 mov -0xc(%ebp),%ecx +c0100bd3: 89 c8 mov %ecx,%eax +c0100bd5: 01 c0 add %eax,%eax +c0100bd7: 01 c8 add %ecx,%eax +c0100bd9: c1 e0 02 shl $0x2,%eax +c0100bdc: 05 00 90 11 c0 add $0xc0119000,%eax +c0100be1: 8b 00 mov (%eax),%eax +c0100be3: 89 54 24 08 mov %edx,0x8(%esp) +c0100be7: 89 44 24 04 mov %eax,0x4(%esp) +c0100beb: c7 04 24 35 63 10 c0 movl $0xc0106335,(%esp) +c0100bf2: e8 6f f7 ff ff call c0100366 + for (i = 0; i < NCOMMANDS; i ++) { +c0100bf7: ff 45 f4 incl -0xc(%ebp) +c0100bfa: 8b 45 f4 mov -0xc(%ebp),%eax +c0100bfd: 83 f8 02 cmp $0x2,%eax +c0100c00: 76 bb jbe c0100bbd + } + return 0; +c0100c02: b8 00 00 00 00 mov $0x0,%eax +} +c0100c07: 89 ec mov %ebp,%esp +c0100c09: 5d pop %ebp +c0100c0a: c3 ret + +c0100c0b : +/* * + * 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) { +c0100c0b: 55 push %ebp +c0100c0c: 89 e5 mov %esp,%ebp +c0100c0e: 83 ec 08 sub $0x8,%esp + print_kerninfo(); +c0100c11: e8 73 fc ff ff call c0100889 + return 0; +c0100c16: b8 00 00 00 00 mov $0x0,%eax +} +c0100c1b: 89 ec mov %ebp,%esp +c0100c1d: 5d pop %ebp +c0100c1e: c3 ret + +c0100c1f : +/* * + * 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) { +c0100c1f: 55 push %ebp +c0100c20: 89 e5 mov %esp,%ebp +c0100c22: 83 ec 08 sub $0x8,%esp + print_stackframe(); +c0100c25: e8 ab fd ff ff call c01009d5 + return 0; +c0100c2a: b8 00 00 00 00 mov $0x0,%eax +} +c0100c2f: 89 ec mov %ebp,%esp +c0100c31: 5d pop %ebp +c0100c32: c3 ret + +c0100c33 <__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, ...) { +c0100c33: 55 push %ebp +c0100c34: 89 e5 mov %esp,%ebp +c0100c36: 83 ec 28 sub $0x28,%esp + if (is_panic) { +c0100c39: a1 20 c4 11 c0 mov 0xc011c420,%eax +c0100c3e: 85 c0 test %eax,%eax +c0100c40: 75 5b jne c0100c9d <__panic+0x6a> + goto panic_dead; + } + is_panic = 1; +c0100c42: c7 05 20 c4 11 c0 01 movl $0x1,0xc011c420 +c0100c49: 00 00 00 + + // print the 'message' + va_list ap; + va_start(ap, fmt); +c0100c4c: 8d 45 14 lea 0x14(%ebp),%eax +c0100c4f: 89 45 f4 mov %eax,-0xc(%ebp) + cprintf("kernel panic at %s:%d:\n ", file, line); +c0100c52: 8b 45 0c mov 0xc(%ebp),%eax +c0100c55: 89 44 24 08 mov %eax,0x8(%esp) +c0100c59: 8b 45 08 mov 0x8(%ebp),%eax +c0100c5c: 89 44 24 04 mov %eax,0x4(%esp) +c0100c60: c7 04 24 3e 63 10 c0 movl $0xc010633e,(%esp) +c0100c67: e8 fa f6 ff ff call c0100366 + vcprintf(fmt, ap); +c0100c6c: 8b 45 f4 mov -0xc(%ebp),%eax +c0100c6f: 89 44 24 04 mov %eax,0x4(%esp) +c0100c73: 8b 45 10 mov 0x10(%ebp),%eax +c0100c76: 89 04 24 mov %eax,(%esp) +c0100c79: e8 b3 f6 ff ff call c0100331 + cprintf("\n"); +c0100c7e: c7 04 24 5a 63 10 c0 movl $0xc010635a,(%esp) +c0100c85: e8 dc f6 ff ff call c0100366 + + cprintf("stack trackback:\n"); +c0100c8a: c7 04 24 5c 63 10 c0 movl $0xc010635c,(%esp) +c0100c91: e8 d0 f6 ff ff call c0100366 + print_stackframe(); +c0100c96: e8 3a fd ff ff call c01009d5 +c0100c9b: eb 01 jmp c0100c9e <__panic+0x6b> + goto panic_dead; +c0100c9d: 90 nop + + va_end(ap); + +panic_dead: + intr_disable(); +c0100c9e: e8 e9 09 00 00 call c010168c + while (1) { + kmonitor(NULL); +c0100ca3: c7 04 24 00 00 00 00 movl $0x0,(%esp) +c0100caa: e8 9d fe ff ff call c0100b4c +c0100caf: eb f2 jmp c0100ca3 <__panic+0x70> + +c0100cb1 <__warn>: + } +} + +/* __warn - like panic, but don't */ +void +__warn(const char *file, int line, const char *fmt, ...) { +c0100cb1: 55 push %ebp +c0100cb2: 89 e5 mov %esp,%ebp +c0100cb4: 83 ec 28 sub $0x28,%esp + va_list ap; + va_start(ap, fmt); +c0100cb7: 8d 45 14 lea 0x14(%ebp),%eax +c0100cba: 89 45 f4 mov %eax,-0xc(%ebp) + cprintf("kernel warning at %s:%d:\n ", file, line); +c0100cbd: 8b 45 0c mov 0xc(%ebp),%eax +c0100cc0: 89 44 24 08 mov %eax,0x8(%esp) +c0100cc4: 8b 45 08 mov 0x8(%ebp),%eax +c0100cc7: 89 44 24 04 mov %eax,0x4(%esp) +c0100ccb: c7 04 24 6e 63 10 c0 movl $0xc010636e,(%esp) +c0100cd2: e8 8f f6 ff ff call c0100366 + vcprintf(fmt, ap); +c0100cd7: 8b 45 f4 mov -0xc(%ebp),%eax +c0100cda: 89 44 24 04 mov %eax,0x4(%esp) +c0100cde: 8b 45 10 mov 0x10(%ebp),%eax +c0100ce1: 89 04 24 mov %eax,(%esp) +c0100ce4: e8 48 f6 ff ff call c0100331 + cprintf("\n"); +c0100ce9: c7 04 24 5a 63 10 c0 movl $0xc010635a,(%esp) +c0100cf0: e8 71 f6 ff ff call c0100366 + va_end(ap); +} +c0100cf5: 90 nop +c0100cf6: 89 ec mov %ebp,%esp +c0100cf8: 5d pop %ebp +c0100cf9: c3 ret + +c0100cfa : + +bool +is_kernel_panic(void) { +c0100cfa: 55 push %ebp +c0100cfb: 89 e5 mov %esp,%ebp + return is_panic; +c0100cfd: a1 20 c4 11 c0 mov 0xc011c420,%eax +} +c0100d02: 5d pop %ebp +c0100d03: c3 ret + +c0100d04 : +/* * + * clock_init - initialize 8253 clock to interrupt 100 times per second, + * and then enable IRQ_TIMER. + * */ +void +clock_init(void) { +c0100d04: 55 push %ebp +c0100d05: 89 e5 mov %esp,%ebp +c0100d07: 83 ec 28 sub $0x28,%esp +c0100d0a: 66 c7 45 ee 43 00 movw $0x43,-0x12(%ebp) +c0100d10: 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"); +c0100d14: 0f b6 45 ed movzbl -0x13(%ebp),%eax +c0100d18: 0f b7 55 ee movzwl -0x12(%ebp),%edx +c0100d1c: ee out %al,(%dx) +} +c0100d1d: 90 nop +c0100d1e: 66 c7 45 f2 40 00 movw $0x40,-0xe(%ebp) +c0100d24: c6 45 f1 9c movb $0x9c,-0xf(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0100d28: 0f b6 45 f1 movzbl -0xf(%ebp),%eax +c0100d2c: 0f b7 55 f2 movzwl -0xe(%ebp),%edx +c0100d30: ee out %al,(%dx) +} +c0100d31: 90 nop +c0100d32: 66 c7 45 f6 40 00 movw $0x40,-0xa(%ebp) +c0100d38: c6 45 f5 2e movb $0x2e,-0xb(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0100d3c: 0f b6 45 f5 movzbl -0xb(%ebp),%eax +c0100d40: 0f b7 55 f6 movzwl -0xa(%ebp),%edx +c0100d44: ee out %al,(%dx) +} +c0100d45: 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; +c0100d46: c7 05 24 c4 11 c0 00 movl $0x0,0xc011c424 +c0100d4d: 00 00 00 + + cprintf("++ setup timer interrupts\n"); +c0100d50: c7 04 24 8c 63 10 c0 movl $0xc010638c,(%esp) +c0100d57: e8 0a f6 ff ff call c0100366 + pic_enable(IRQ_TIMER); +c0100d5c: c7 04 24 00 00 00 00 movl $0x0,(%esp) +c0100d63: e8 89 09 00 00 call c01016f1 +} +c0100d68: 90 nop +c0100d69: 89 ec mov %ebp,%esp +c0100d6b: 5d pop %ebp +c0100d6c: c3 ret + +c0100d6d <__intr_save>: +#include +#include +#include + +static inline bool +__intr_save(void) { +c0100d6d: 55 push %ebp +c0100d6e: 89 e5 mov %esp,%ebp +c0100d70: 83 ec 18 sub $0x18,%esp +} + +static inline uint32_t +read_eflags(void) { + uint32_t eflags; + asm volatile ("pushfl; popl %0" : "=r" (eflags)); +c0100d73: 9c pushf +c0100d74: 58 pop %eax +c0100d75: 89 45 f4 mov %eax,-0xc(%ebp) + return eflags; +c0100d78: 8b 45 f4 mov -0xc(%ebp),%eax + if (read_eflags() & FL_IF) { +c0100d7b: 25 00 02 00 00 and $0x200,%eax +c0100d80: 85 c0 test %eax,%eax +c0100d82: 74 0c je c0100d90 <__intr_save+0x23> + intr_disable(); +c0100d84: e8 03 09 00 00 call c010168c + return 1; +c0100d89: b8 01 00 00 00 mov $0x1,%eax +c0100d8e: eb 05 jmp c0100d95 <__intr_save+0x28> + } + return 0; +c0100d90: b8 00 00 00 00 mov $0x0,%eax +} +c0100d95: 89 ec mov %ebp,%esp +c0100d97: 5d pop %ebp +c0100d98: c3 ret + +c0100d99 <__intr_restore>: + +static inline void +__intr_restore(bool flag) { +c0100d99: 55 push %ebp +c0100d9a: 89 e5 mov %esp,%ebp +c0100d9c: 83 ec 08 sub $0x8,%esp + if (flag) { +c0100d9f: 83 7d 08 00 cmpl $0x0,0x8(%ebp) +c0100da3: 74 05 je c0100daa <__intr_restore+0x11> + intr_enable(); +c0100da5: e8 da 08 00 00 call c0101684 + } +} +c0100daa: 90 nop +c0100dab: 89 ec mov %ebp,%esp +c0100dad: 5d pop %ebp +c0100dae: c3 ret + +c0100daf : +#include +#include + +/* stupid I/O delay routine necessitated by historical PC design flaws */ +static void +delay(void) { +c0100daf: 55 push %ebp +c0100db0: 89 e5 mov %esp,%ebp +c0100db2: 83 ec 10 sub $0x10,%esp +c0100db5: 66 c7 45 f2 84 00 movw $0x84,-0xe(%ebp) + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); +c0100dbb: 0f b7 45 f2 movzwl -0xe(%ebp),%eax +c0100dbf: 89 c2 mov %eax,%edx +c0100dc1: ec in (%dx),%al +c0100dc2: 88 45 f1 mov %al,-0xf(%ebp) +c0100dc5: 66 c7 45 f6 84 00 movw $0x84,-0xa(%ebp) +c0100dcb: 0f b7 45 f6 movzwl -0xa(%ebp),%eax +c0100dcf: 89 c2 mov %eax,%edx +c0100dd1: ec in (%dx),%al +c0100dd2: 88 45 f5 mov %al,-0xb(%ebp) +c0100dd5: 66 c7 45 fa 84 00 movw $0x84,-0x6(%ebp) +c0100ddb: 0f b7 45 fa movzwl -0x6(%ebp),%eax +c0100ddf: 89 c2 mov %eax,%edx +c0100de1: ec in (%dx),%al +c0100de2: 88 45 f9 mov %al,-0x7(%ebp) +c0100de5: 66 c7 45 fe 84 00 movw $0x84,-0x2(%ebp) +c0100deb: 0f b7 45 fe movzwl -0x2(%ebp),%eax +c0100def: 89 c2 mov %eax,%edx +c0100df1: ec in (%dx),%al +c0100df2: 88 45 fd mov %al,-0x3(%ebp) + inb(0x84); + inb(0x84); + inb(0x84); + inb(0x84); +} +c0100df5: 90 nop +c0100df6: 89 ec mov %ebp,%esp +c0100df8: 5d pop %ebp +c0100df9: c3 ret + +c0100dfa : +static uint16_t addr_6845; + +/* TEXT-mode CGA/VGA display output */ + +static void +cga_init(void) { +c0100dfa: 55 push %ebp +c0100dfb: 89 e5 mov %esp,%ebp +c0100dfd: 83 ec 20 sub $0x20,%esp + volatile uint16_t *cp = (uint16_t *)(CGA_BUF + KERNBASE); +c0100e00: c7 45 fc 00 80 0b c0 movl $0xc00b8000,-0x4(%ebp) + uint16_t was = *cp; +c0100e07: 8b 45 fc mov -0x4(%ebp),%eax +c0100e0a: 0f b7 00 movzwl (%eax),%eax +c0100e0d: 66 89 45 fa mov %ax,-0x6(%ebp) + *cp = (uint16_t) 0xA55A; +c0100e11: 8b 45 fc mov -0x4(%ebp),%eax +c0100e14: 66 c7 00 5a a5 movw $0xa55a,(%eax) + if (*cp != 0xA55A) { +c0100e19: 8b 45 fc mov -0x4(%ebp),%eax +c0100e1c: 0f b7 00 movzwl (%eax),%eax +c0100e1f: 0f b7 c0 movzwl %ax,%eax +c0100e22: 3d 5a a5 00 00 cmp $0xa55a,%eax +c0100e27: 74 12 je c0100e3b + cp = (uint16_t*)(MONO_BUF + KERNBASE); +c0100e29: c7 45 fc 00 00 0b c0 movl $0xc00b0000,-0x4(%ebp) + addr_6845 = MONO_BASE; +c0100e30: 66 c7 05 46 c4 11 c0 movw $0x3b4,0xc011c446 +c0100e37: b4 03 +c0100e39: eb 13 jmp c0100e4e + } else { + *cp = was; +c0100e3b: 8b 45 fc mov -0x4(%ebp),%eax +c0100e3e: 0f b7 55 fa movzwl -0x6(%ebp),%edx +c0100e42: 66 89 10 mov %dx,(%eax) + addr_6845 = CGA_BASE; +c0100e45: 66 c7 05 46 c4 11 c0 movw $0x3d4,0xc011c446 +c0100e4c: d4 03 + } + + // Extract cursor location + uint32_t pos; + outb(addr_6845, 14); +c0100e4e: 0f b7 05 46 c4 11 c0 movzwl 0xc011c446,%eax +c0100e55: 66 89 45 e6 mov %ax,-0x1a(%ebp) +c0100e59: c6 45 e5 0e movb $0xe,-0x1b(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0100e5d: 0f b6 45 e5 movzbl -0x1b(%ebp),%eax +c0100e61: 0f b7 55 e6 movzwl -0x1a(%ebp),%edx +c0100e65: ee out %al,(%dx) +} +c0100e66: 90 nop + pos = inb(addr_6845 + 1) << 8; +c0100e67: 0f b7 05 46 c4 11 c0 movzwl 0xc011c446,%eax +c0100e6e: 40 inc %eax +c0100e6f: 0f b7 c0 movzwl %ax,%eax +c0100e72: 66 89 45 ea mov %ax,-0x16(%ebp) + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); +c0100e76: 0f b7 45 ea movzwl -0x16(%ebp),%eax +c0100e7a: 89 c2 mov %eax,%edx +c0100e7c: ec in (%dx),%al +c0100e7d: 88 45 e9 mov %al,-0x17(%ebp) + return data; +c0100e80: 0f b6 45 e9 movzbl -0x17(%ebp),%eax +c0100e84: 0f b6 c0 movzbl %al,%eax +c0100e87: c1 e0 08 shl $0x8,%eax +c0100e8a: 89 45 f4 mov %eax,-0xc(%ebp) + outb(addr_6845, 15); +c0100e8d: 0f b7 05 46 c4 11 c0 movzwl 0xc011c446,%eax +c0100e94: 66 89 45 ee mov %ax,-0x12(%ebp) +c0100e98: c6 45 ed 0f movb $0xf,-0x13(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0100e9c: 0f b6 45 ed movzbl -0x13(%ebp),%eax +c0100ea0: 0f b7 55 ee movzwl -0x12(%ebp),%edx +c0100ea4: ee out %al,(%dx) +} +c0100ea5: 90 nop + pos |= inb(addr_6845 + 1); +c0100ea6: 0f b7 05 46 c4 11 c0 movzwl 0xc011c446,%eax +c0100ead: 40 inc %eax +c0100eae: 0f b7 c0 movzwl %ax,%eax +c0100eb1: 66 89 45 f2 mov %ax,-0xe(%ebp) + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); +c0100eb5: 0f b7 45 f2 movzwl -0xe(%ebp),%eax +c0100eb9: 89 c2 mov %eax,%edx +c0100ebb: ec in (%dx),%al +c0100ebc: 88 45 f1 mov %al,-0xf(%ebp) + return data; +c0100ebf: 0f b6 45 f1 movzbl -0xf(%ebp),%eax +c0100ec3: 0f b6 c0 movzbl %al,%eax +c0100ec6: 09 45 f4 or %eax,-0xc(%ebp) + + crt_buf = (uint16_t*) cp; +c0100ec9: 8b 45 fc mov -0x4(%ebp),%eax +c0100ecc: a3 40 c4 11 c0 mov %eax,0xc011c440 + crt_pos = pos; +c0100ed1: 8b 45 f4 mov -0xc(%ebp),%eax +c0100ed4: 0f b7 c0 movzwl %ax,%eax +c0100ed7: 66 a3 44 c4 11 c0 mov %ax,0xc011c444 +} +c0100edd: 90 nop +c0100ede: 89 ec mov %ebp,%esp +c0100ee0: 5d pop %ebp +c0100ee1: c3 ret + +c0100ee2 : + +static bool serial_exists = 0; + +static void +serial_init(void) { +c0100ee2: 55 push %ebp +c0100ee3: 89 e5 mov %esp,%ebp +c0100ee5: 83 ec 48 sub $0x48,%esp +c0100ee8: 66 c7 45 d2 fa 03 movw $0x3fa,-0x2e(%ebp) +c0100eee: c6 45 d1 00 movb $0x0,-0x2f(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0100ef2: 0f b6 45 d1 movzbl -0x2f(%ebp),%eax +c0100ef6: 0f b7 55 d2 movzwl -0x2e(%ebp),%edx +c0100efa: ee out %al,(%dx) +} +c0100efb: 90 nop +c0100efc: 66 c7 45 d6 fb 03 movw $0x3fb,-0x2a(%ebp) +c0100f02: c6 45 d5 80 movb $0x80,-0x2b(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0100f06: 0f b6 45 d5 movzbl -0x2b(%ebp),%eax +c0100f0a: 0f b7 55 d6 movzwl -0x2a(%ebp),%edx +c0100f0e: ee out %al,(%dx) +} +c0100f0f: 90 nop +c0100f10: 66 c7 45 da f8 03 movw $0x3f8,-0x26(%ebp) +c0100f16: c6 45 d9 0c movb $0xc,-0x27(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0100f1a: 0f b6 45 d9 movzbl -0x27(%ebp),%eax +c0100f1e: 0f b7 55 da movzwl -0x26(%ebp),%edx +c0100f22: ee out %al,(%dx) +} +c0100f23: 90 nop +c0100f24: 66 c7 45 de f9 03 movw $0x3f9,-0x22(%ebp) +c0100f2a: c6 45 dd 00 movb $0x0,-0x23(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0100f2e: 0f b6 45 dd movzbl -0x23(%ebp),%eax +c0100f32: 0f b7 55 de movzwl -0x22(%ebp),%edx +c0100f36: ee out %al,(%dx) +} +c0100f37: 90 nop +c0100f38: 66 c7 45 e2 fb 03 movw $0x3fb,-0x1e(%ebp) +c0100f3e: c6 45 e1 03 movb $0x3,-0x1f(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0100f42: 0f b6 45 e1 movzbl -0x1f(%ebp),%eax +c0100f46: 0f b7 55 e2 movzwl -0x1e(%ebp),%edx +c0100f4a: ee out %al,(%dx) +} +c0100f4b: 90 nop +c0100f4c: 66 c7 45 e6 fc 03 movw $0x3fc,-0x1a(%ebp) +c0100f52: c6 45 e5 00 movb $0x0,-0x1b(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0100f56: 0f b6 45 e5 movzbl -0x1b(%ebp),%eax +c0100f5a: 0f b7 55 e6 movzwl -0x1a(%ebp),%edx +c0100f5e: ee out %al,(%dx) +} +c0100f5f: 90 nop +c0100f60: 66 c7 45 ea f9 03 movw $0x3f9,-0x16(%ebp) +c0100f66: c6 45 e9 01 movb $0x1,-0x17(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0100f6a: 0f b6 45 e9 movzbl -0x17(%ebp),%eax +c0100f6e: 0f b7 55 ea movzwl -0x16(%ebp),%edx +c0100f72: ee out %al,(%dx) +} +c0100f73: 90 nop +c0100f74: 66 c7 45 ee fd 03 movw $0x3fd,-0x12(%ebp) + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); +c0100f7a: 0f b7 45 ee movzwl -0x12(%ebp),%eax +c0100f7e: 89 c2 mov %eax,%edx +c0100f80: ec in (%dx),%al +c0100f81: 88 45 ed mov %al,-0x13(%ebp) + return data; +c0100f84: 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); +c0100f88: 3c ff cmp $0xff,%al +c0100f8a: 0f 95 c0 setne %al +c0100f8d: 0f b6 c0 movzbl %al,%eax +c0100f90: a3 48 c4 11 c0 mov %eax,0xc011c448 +c0100f95: 66 c7 45 f2 fa 03 movw $0x3fa,-0xe(%ebp) + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); +c0100f9b: 0f b7 45 f2 movzwl -0xe(%ebp),%eax +c0100f9f: 89 c2 mov %eax,%edx +c0100fa1: ec in (%dx),%al +c0100fa2: 88 45 f1 mov %al,-0xf(%ebp) +c0100fa5: 66 c7 45 f6 f8 03 movw $0x3f8,-0xa(%ebp) +c0100fab: 0f b7 45 f6 movzwl -0xa(%ebp),%eax +c0100faf: 89 c2 mov %eax,%edx +c0100fb1: ec in (%dx),%al +c0100fb2: 88 45 f5 mov %al,-0xb(%ebp) + (void) inb(COM1+COM_IIR); + (void) inb(COM1+COM_RX); + + if (serial_exists) { +c0100fb5: a1 48 c4 11 c0 mov 0xc011c448,%eax +c0100fba: 85 c0 test %eax,%eax +c0100fbc: 74 0c je c0100fca + pic_enable(IRQ_COM1); +c0100fbe: c7 04 24 04 00 00 00 movl $0x4,(%esp) +c0100fc5: e8 27 07 00 00 call c01016f1 + } +} +c0100fca: 90 nop +c0100fcb: 89 ec mov %ebp,%esp +c0100fcd: 5d pop %ebp +c0100fce: c3 ret + +c0100fcf : + +static void +lpt_putc_sub(int c) { +c0100fcf: 55 push %ebp +c0100fd0: 89 e5 mov %esp,%ebp +c0100fd2: 83 ec 20 sub $0x20,%esp + int i; + for (i = 0; !(inb(LPTPORT + 1) & 0x80) && i < 12800; i ++) { +c0100fd5: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) +c0100fdc: eb 08 jmp c0100fe6 + delay(); +c0100fde: e8 cc fd ff ff call c0100daf + for (i = 0; !(inb(LPTPORT + 1) & 0x80) && i < 12800; i ++) { +c0100fe3: ff 45 fc incl -0x4(%ebp) +c0100fe6: 66 c7 45 fa 79 03 movw $0x379,-0x6(%ebp) +c0100fec: 0f b7 45 fa movzwl -0x6(%ebp),%eax +c0100ff0: 89 c2 mov %eax,%edx +c0100ff2: ec in (%dx),%al +c0100ff3: 88 45 f9 mov %al,-0x7(%ebp) + return data; +c0100ff6: 0f b6 45 f9 movzbl -0x7(%ebp),%eax +c0100ffa: 84 c0 test %al,%al +c0100ffc: 78 09 js c0101007 +c0100ffe: 81 7d fc ff 31 00 00 cmpl $0x31ff,-0x4(%ebp) +c0101005: 7e d7 jle c0100fde + } + outb(LPTPORT + 0, c); +c0101007: 8b 45 08 mov 0x8(%ebp),%eax +c010100a: 0f b6 c0 movzbl %al,%eax +c010100d: 66 c7 45 ee 78 03 movw $0x378,-0x12(%ebp) +c0101013: 88 45 ed mov %al,-0x13(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101016: 0f b6 45 ed movzbl -0x13(%ebp),%eax +c010101a: 0f b7 55 ee movzwl -0x12(%ebp),%edx +c010101e: ee out %al,(%dx) +} +c010101f: 90 nop +c0101020: 66 c7 45 f2 7a 03 movw $0x37a,-0xe(%ebp) +c0101026: c6 45 f1 0d movb $0xd,-0xf(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c010102a: 0f b6 45 f1 movzbl -0xf(%ebp),%eax +c010102e: 0f b7 55 f2 movzwl -0xe(%ebp),%edx +c0101032: ee out %al,(%dx) +} +c0101033: 90 nop +c0101034: 66 c7 45 f6 7a 03 movw $0x37a,-0xa(%ebp) +c010103a: c6 45 f5 08 movb $0x8,-0xb(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c010103e: 0f b6 45 f5 movzbl -0xb(%ebp),%eax +c0101042: 0f b7 55 f6 movzwl -0xa(%ebp),%edx +c0101046: ee out %al,(%dx) +} +c0101047: 90 nop + outb(LPTPORT + 2, 0x08 | 0x04 | 0x01); + outb(LPTPORT + 2, 0x08); +} +c0101048: 90 nop +c0101049: 89 ec mov %ebp,%esp +c010104b: 5d pop %ebp +c010104c: c3 ret + +c010104d : + +/* lpt_putc - copy console output to parallel port */ +static void +lpt_putc(int c) { +c010104d: 55 push %ebp +c010104e: 89 e5 mov %esp,%ebp +c0101050: 83 ec 04 sub $0x4,%esp + if (c != '\b') { +c0101053: 83 7d 08 08 cmpl $0x8,0x8(%ebp) +c0101057: 74 0d je c0101066 + lpt_putc_sub(c); +c0101059: 8b 45 08 mov 0x8(%ebp),%eax +c010105c: 89 04 24 mov %eax,(%esp) +c010105f: e8 6b ff ff ff call c0100fcf + else { + lpt_putc_sub('\b'); + lpt_putc_sub(' '); + lpt_putc_sub('\b'); + } +} +c0101064: eb 24 jmp c010108a + lpt_putc_sub('\b'); +c0101066: c7 04 24 08 00 00 00 movl $0x8,(%esp) +c010106d: e8 5d ff ff ff call c0100fcf + lpt_putc_sub(' '); +c0101072: c7 04 24 20 00 00 00 movl $0x20,(%esp) +c0101079: e8 51 ff ff ff call c0100fcf + lpt_putc_sub('\b'); +c010107e: c7 04 24 08 00 00 00 movl $0x8,(%esp) +c0101085: e8 45 ff ff ff call c0100fcf +} +c010108a: 90 nop +c010108b: 89 ec mov %ebp,%esp +c010108d: 5d pop %ebp +c010108e: c3 ret + +c010108f : + +/* cga_putc - print character to console */ +static void +cga_putc(int c) { +c010108f: 55 push %ebp +c0101090: 89 e5 mov %esp,%ebp +c0101092: 83 ec 38 sub $0x38,%esp +c0101095: 89 5d fc mov %ebx,-0x4(%ebp) + // set black on white + if (!(c & ~0xFF)) { +c0101098: 8b 45 08 mov 0x8(%ebp),%eax +c010109b: 25 00 ff ff ff and $0xffffff00,%eax +c01010a0: 85 c0 test %eax,%eax +c01010a2: 75 07 jne c01010ab + c |= 0x0700; +c01010a4: 81 4d 08 00 07 00 00 orl $0x700,0x8(%ebp) + } + + switch (c & 0xff) { +c01010ab: 8b 45 08 mov 0x8(%ebp),%eax +c01010ae: 0f b6 c0 movzbl %al,%eax +c01010b1: 83 f8 0d cmp $0xd,%eax +c01010b4: 74 72 je c0101128 +c01010b6: 83 f8 0d cmp $0xd,%eax +c01010b9: 0f 8f a3 00 00 00 jg c0101162 +c01010bf: 83 f8 08 cmp $0x8,%eax +c01010c2: 74 0a je c01010ce +c01010c4: 83 f8 0a cmp $0xa,%eax +c01010c7: 74 4c je c0101115 +c01010c9: e9 94 00 00 00 jmp c0101162 + case '\b': + if (crt_pos > 0) { +c01010ce: 0f b7 05 44 c4 11 c0 movzwl 0xc011c444,%eax +c01010d5: 85 c0 test %eax,%eax +c01010d7: 0f 84 af 00 00 00 je c010118c + crt_pos --; +c01010dd: 0f b7 05 44 c4 11 c0 movzwl 0xc011c444,%eax +c01010e4: 48 dec %eax +c01010e5: 0f b7 c0 movzwl %ax,%eax +c01010e8: 66 a3 44 c4 11 c0 mov %ax,0xc011c444 + crt_buf[crt_pos] = (c & ~0xff) | ' '; +c01010ee: 8b 45 08 mov 0x8(%ebp),%eax +c01010f1: 98 cwtl +c01010f2: 25 00 ff ff ff and $0xffffff00,%eax +c01010f7: 98 cwtl +c01010f8: 83 c8 20 or $0x20,%eax +c01010fb: 98 cwtl +c01010fc: 8b 0d 40 c4 11 c0 mov 0xc011c440,%ecx +c0101102: 0f b7 15 44 c4 11 c0 movzwl 0xc011c444,%edx +c0101109: 01 d2 add %edx,%edx +c010110b: 01 ca add %ecx,%edx +c010110d: 0f b7 c0 movzwl %ax,%eax +c0101110: 66 89 02 mov %ax,(%edx) + } + break; +c0101113: eb 77 jmp c010118c + case '\n': + crt_pos += CRT_COLS; +c0101115: 0f b7 05 44 c4 11 c0 movzwl 0xc011c444,%eax +c010111c: 83 c0 50 add $0x50,%eax +c010111f: 0f b7 c0 movzwl %ax,%eax +c0101122: 66 a3 44 c4 11 c0 mov %ax,0xc011c444 + case '\r': + crt_pos -= (crt_pos % CRT_COLS); +c0101128: 0f b7 1d 44 c4 11 c0 movzwl 0xc011c444,%ebx +c010112f: 0f b7 0d 44 c4 11 c0 movzwl 0xc011c444,%ecx +c0101136: ba cd cc cc cc mov $0xcccccccd,%edx +c010113b: 89 c8 mov %ecx,%eax +c010113d: f7 e2 mul %edx +c010113f: c1 ea 06 shr $0x6,%edx +c0101142: 89 d0 mov %edx,%eax +c0101144: c1 e0 02 shl $0x2,%eax +c0101147: 01 d0 add %edx,%eax +c0101149: c1 e0 04 shl $0x4,%eax +c010114c: 29 c1 sub %eax,%ecx +c010114e: 89 ca mov %ecx,%edx +c0101150: 0f b7 d2 movzwl %dx,%edx +c0101153: 89 d8 mov %ebx,%eax +c0101155: 29 d0 sub %edx,%eax +c0101157: 0f b7 c0 movzwl %ax,%eax +c010115a: 66 a3 44 c4 11 c0 mov %ax,0xc011c444 + break; +c0101160: eb 2b jmp c010118d + default: + crt_buf[crt_pos ++] = c; // write the character +c0101162: 8b 0d 40 c4 11 c0 mov 0xc011c440,%ecx +c0101168: 0f b7 05 44 c4 11 c0 movzwl 0xc011c444,%eax +c010116f: 8d 50 01 lea 0x1(%eax),%edx +c0101172: 0f b7 d2 movzwl %dx,%edx +c0101175: 66 89 15 44 c4 11 c0 mov %dx,0xc011c444 +c010117c: 01 c0 add %eax,%eax +c010117e: 8d 14 01 lea (%ecx,%eax,1),%edx +c0101181: 8b 45 08 mov 0x8(%ebp),%eax +c0101184: 0f b7 c0 movzwl %ax,%eax +c0101187: 66 89 02 mov %ax,(%edx) + break; +c010118a: eb 01 jmp c010118d + break; +c010118c: 90 nop + } + + // What is the purpose of this? + if (crt_pos >= CRT_SIZE) { +c010118d: 0f b7 05 44 c4 11 c0 movzwl 0xc011c444,%eax +c0101194: 3d cf 07 00 00 cmp $0x7cf,%eax +c0101199: 76 5e jbe c01011f9 + int i; + memmove(crt_buf, crt_buf + CRT_COLS, (CRT_SIZE - CRT_COLS) * sizeof(uint16_t)); +c010119b: a1 40 c4 11 c0 mov 0xc011c440,%eax +c01011a0: 8d 90 a0 00 00 00 lea 0xa0(%eax),%edx +c01011a6: a1 40 c4 11 c0 mov 0xc011c440,%eax +c01011ab: c7 44 24 08 00 0f 00 movl $0xf00,0x8(%esp) +c01011b2: 00 +c01011b3: 89 54 24 04 mov %edx,0x4(%esp) +c01011b7: 89 04 24 mov %eax,(%esp) +c01011ba: e8 8b 4d 00 00 call c0105f4a + for (i = CRT_SIZE - CRT_COLS; i < CRT_SIZE; i ++) { +c01011bf: c7 45 f4 80 07 00 00 movl $0x780,-0xc(%ebp) +c01011c6: eb 15 jmp c01011dd + crt_buf[i] = 0x0700 | ' '; +c01011c8: 8b 15 40 c4 11 c0 mov 0xc011c440,%edx +c01011ce: 8b 45 f4 mov -0xc(%ebp),%eax +c01011d1: 01 c0 add %eax,%eax +c01011d3: 01 d0 add %edx,%eax +c01011d5: 66 c7 00 20 07 movw $0x720,(%eax) + for (i = CRT_SIZE - CRT_COLS; i < CRT_SIZE; i ++) { +c01011da: ff 45 f4 incl -0xc(%ebp) +c01011dd: 81 7d f4 cf 07 00 00 cmpl $0x7cf,-0xc(%ebp) +c01011e4: 7e e2 jle c01011c8 + } + crt_pos -= CRT_COLS; +c01011e6: 0f b7 05 44 c4 11 c0 movzwl 0xc011c444,%eax +c01011ed: 83 e8 50 sub $0x50,%eax +c01011f0: 0f b7 c0 movzwl %ax,%eax +c01011f3: 66 a3 44 c4 11 c0 mov %ax,0xc011c444 + } + + // move that little blinky thing + outb(addr_6845, 14); +c01011f9: 0f b7 05 46 c4 11 c0 movzwl 0xc011c446,%eax +c0101200: 66 89 45 e6 mov %ax,-0x1a(%ebp) +c0101204: c6 45 e5 0e movb $0xe,-0x1b(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101208: 0f b6 45 e5 movzbl -0x1b(%ebp),%eax +c010120c: 0f b7 55 e6 movzwl -0x1a(%ebp),%edx +c0101210: ee out %al,(%dx) +} +c0101211: 90 nop + outb(addr_6845 + 1, crt_pos >> 8); +c0101212: 0f b7 05 44 c4 11 c0 movzwl 0xc011c444,%eax +c0101219: c1 e8 08 shr $0x8,%eax +c010121c: 0f b7 c0 movzwl %ax,%eax +c010121f: 0f b6 c0 movzbl %al,%eax +c0101222: 0f b7 15 46 c4 11 c0 movzwl 0xc011c446,%edx +c0101229: 42 inc %edx +c010122a: 0f b7 d2 movzwl %dx,%edx +c010122d: 66 89 55 ea mov %dx,-0x16(%ebp) +c0101231: 88 45 e9 mov %al,-0x17(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101234: 0f b6 45 e9 movzbl -0x17(%ebp),%eax +c0101238: 0f b7 55 ea movzwl -0x16(%ebp),%edx +c010123c: ee out %al,(%dx) +} +c010123d: 90 nop + outb(addr_6845, 15); +c010123e: 0f b7 05 46 c4 11 c0 movzwl 0xc011c446,%eax +c0101245: 66 89 45 ee mov %ax,-0x12(%ebp) +c0101249: c6 45 ed 0f movb $0xf,-0x13(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c010124d: 0f b6 45 ed movzbl -0x13(%ebp),%eax +c0101251: 0f b7 55 ee movzwl -0x12(%ebp),%edx +c0101255: ee out %al,(%dx) +} +c0101256: 90 nop + outb(addr_6845 + 1, crt_pos); +c0101257: 0f b7 05 44 c4 11 c0 movzwl 0xc011c444,%eax +c010125e: 0f b6 c0 movzbl %al,%eax +c0101261: 0f b7 15 46 c4 11 c0 movzwl 0xc011c446,%edx +c0101268: 42 inc %edx +c0101269: 0f b7 d2 movzwl %dx,%edx +c010126c: 66 89 55 f2 mov %dx,-0xe(%ebp) +c0101270: 88 45 f1 mov %al,-0xf(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101273: 0f b6 45 f1 movzbl -0xf(%ebp),%eax +c0101277: 0f b7 55 f2 movzwl -0xe(%ebp),%edx +c010127b: ee out %al,(%dx) +} +c010127c: 90 nop +} +c010127d: 90 nop +c010127e: 8b 5d fc mov -0x4(%ebp),%ebx +c0101281: 89 ec mov %ebp,%esp +c0101283: 5d pop %ebp +c0101284: c3 ret + +c0101285 : + +static void +serial_putc_sub(int c) { +c0101285: 55 push %ebp +c0101286: 89 e5 mov %esp,%ebp +c0101288: 83 ec 10 sub $0x10,%esp + int i; + for (i = 0; !(inb(COM1 + COM_LSR) & COM_LSR_TXRDY) && i < 12800; i ++) { +c010128b: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) +c0101292: eb 08 jmp c010129c + delay(); +c0101294: e8 16 fb ff ff call c0100daf + for (i = 0; !(inb(COM1 + COM_LSR) & COM_LSR_TXRDY) && i < 12800; i ++) { +c0101299: ff 45 fc incl -0x4(%ebp) +c010129c: 66 c7 45 fa fd 03 movw $0x3fd,-0x6(%ebp) + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); +c01012a2: 0f b7 45 fa movzwl -0x6(%ebp),%eax +c01012a6: 89 c2 mov %eax,%edx +c01012a8: ec in (%dx),%al +c01012a9: 88 45 f9 mov %al,-0x7(%ebp) + return data; +c01012ac: 0f b6 45 f9 movzbl -0x7(%ebp),%eax +c01012b0: 0f b6 c0 movzbl %al,%eax +c01012b3: 83 e0 20 and $0x20,%eax +c01012b6: 85 c0 test %eax,%eax +c01012b8: 75 09 jne c01012c3 +c01012ba: 81 7d fc ff 31 00 00 cmpl $0x31ff,-0x4(%ebp) +c01012c1: 7e d1 jle c0101294 + } + outb(COM1 + COM_TX, c); +c01012c3: 8b 45 08 mov 0x8(%ebp),%eax +c01012c6: 0f b6 c0 movzbl %al,%eax +c01012c9: 66 c7 45 f6 f8 03 movw $0x3f8,-0xa(%ebp) +c01012cf: 88 45 f5 mov %al,-0xb(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c01012d2: 0f b6 45 f5 movzbl -0xb(%ebp),%eax +c01012d6: 0f b7 55 f6 movzwl -0xa(%ebp),%edx +c01012da: ee out %al,(%dx) +} +c01012db: 90 nop +} +c01012dc: 90 nop +c01012dd: 89 ec mov %ebp,%esp +c01012df: 5d pop %ebp +c01012e0: c3 ret + +c01012e1 : + +/* serial_putc - print character to serial port */ +static void +serial_putc(int c) { +c01012e1: 55 push %ebp +c01012e2: 89 e5 mov %esp,%ebp +c01012e4: 83 ec 04 sub $0x4,%esp + if (c != '\b') { +c01012e7: 83 7d 08 08 cmpl $0x8,0x8(%ebp) +c01012eb: 74 0d je c01012fa + serial_putc_sub(c); +c01012ed: 8b 45 08 mov 0x8(%ebp),%eax +c01012f0: 89 04 24 mov %eax,(%esp) +c01012f3: e8 8d ff ff ff call c0101285 + else { + serial_putc_sub('\b'); + serial_putc_sub(' '); + serial_putc_sub('\b'); + } +} +c01012f8: eb 24 jmp c010131e + serial_putc_sub('\b'); +c01012fa: c7 04 24 08 00 00 00 movl $0x8,(%esp) +c0101301: e8 7f ff ff ff call c0101285 + serial_putc_sub(' '); +c0101306: c7 04 24 20 00 00 00 movl $0x20,(%esp) +c010130d: e8 73 ff ff ff call c0101285 + serial_putc_sub('\b'); +c0101312: c7 04 24 08 00 00 00 movl $0x8,(%esp) +c0101319: e8 67 ff ff ff call c0101285 +} +c010131e: 90 nop +c010131f: 89 ec mov %ebp,%esp +c0101321: 5d pop %ebp +c0101322: c3 ret + +c0101323 : +/* * + * cons_intr - called by device interrupt routines to feed input + * characters into the circular console input buffer. + * */ +static void +cons_intr(int (*proc)(void)) { +c0101323: 55 push %ebp +c0101324: 89 e5 mov %esp,%ebp +c0101326: 83 ec 18 sub $0x18,%esp + int c; + while ((c = (*proc)()) != -1) { +c0101329: eb 33 jmp c010135e + if (c != 0) { +c010132b: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c010132f: 74 2d je c010135e + cons.buf[cons.wpos ++] = c; +c0101331: a1 64 c6 11 c0 mov 0xc011c664,%eax +c0101336: 8d 50 01 lea 0x1(%eax),%edx +c0101339: 89 15 64 c6 11 c0 mov %edx,0xc011c664 +c010133f: 8b 55 f4 mov -0xc(%ebp),%edx +c0101342: 88 90 60 c4 11 c0 mov %dl,-0x3fee3ba0(%eax) + if (cons.wpos == CONSBUFSIZE) { +c0101348: a1 64 c6 11 c0 mov 0xc011c664,%eax +c010134d: 3d 00 02 00 00 cmp $0x200,%eax +c0101352: 75 0a jne c010135e + cons.wpos = 0; +c0101354: c7 05 64 c6 11 c0 00 movl $0x0,0xc011c664 +c010135b: 00 00 00 + while ((c = (*proc)()) != -1) { +c010135e: 8b 45 08 mov 0x8(%ebp),%eax +c0101361: ff d0 call *%eax +c0101363: 89 45 f4 mov %eax,-0xc(%ebp) +c0101366: 83 7d f4 ff cmpl $0xffffffff,-0xc(%ebp) +c010136a: 75 bf jne c010132b + } + } + } +} +c010136c: 90 nop +c010136d: 90 nop +c010136e: 89 ec mov %ebp,%esp +c0101370: 5d pop %ebp +c0101371: c3 ret + +c0101372 : + +/* serial_proc_data - get data from serial port */ +static int +serial_proc_data(void) { +c0101372: 55 push %ebp +c0101373: 89 e5 mov %esp,%ebp +c0101375: 83 ec 10 sub $0x10,%esp +c0101378: 66 c7 45 fa fd 03 movw $0x3fd,-0x6(%ebp) + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); +c010137e: 0f b7 45 fa movzwl -0x6(%ebp),%eax +c0101382: 89 c2 mov %eax,%edx +c0101384: ec in (%dx),%al +c0101385: 88 45 f9 mov %al,-0x7(%ebp) + return data; +c0101388: 0f b6 45 f9 movzbl -0x7(%ebp),%eax + if (!(inb(COM1 + COM_LSR) & COM_LSR_DATA)) { +c010138c: 0f b6 c0 movzbl %al,%eax +c010138f: 83 e0 01 and $0x1,%eax +c0101392: 85 c0 test %eax,%eax +c0101394: 75 07 jne c010139d + return -1; +c0101396: b8 ff ff ff ff mov $0xffffffff,%eax +c010139b: eb 2a jmp c01013c7 +c010139d: 66 c7 45 f6 f8 03 movw $0x3f8,-0xa(%ebp) + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); +c01013a3: 0f b7 45 f6 movzwl -0xa(%ebp),%eax +c01013a7: 89 c2 mov %eax,%edx +c01013a9: ec in (%dx),%al +c01013aa: 88 45 f5 mov %al,-0xb(%ebp) + return data; +c01013ad: 0f b6 45 f5 movzbl -0xb(%ebp),%eax + } + int c = inb(COM1 + COM_RX); +c01013b1: 0f b6 c0 movzbl %al,%eax +c01013b4: 89 45 fc mov %eax,-0x4(%ebp) + if (c == 127) { +c01013b7: 83 7d fc 7f cmpl $0x7f,-0x4(%ebp) +c01013bb: 75 07 jne c01013c4 + c = '\b'; +c01013bd: c7 45 fc 08 00 00 00 movl $0x8,-0x4(%ebp) + } + return c; +c01013c4: 8b 45 fc mov -0x4(%ebp),%eax +} +c01013c7: 89 ec mov %ebp,%esp +c01013c9: 5d pop %ebp +c01013ca: c3 ret + +c01013cb : + +/* serial_intr - try to feed input characters from serial port */ +void +serial_intr(void) { +c01013cb: 55 push %ebp +c01013cc: 89 e5 mov %esp,%ebp +c01013ce: 83 ec 18 sub $0x18,%esp + if (serial_exists) { +c01013d1: a1 48 c4 11 c0 mov 0xc011c448,%eax +c01013d6: 85 c0 test %eax,%eax +c01013d8: 74 0c je c01013e6 + cons_intr(serial_proc_data); +c01013da: c7 04 24 72 13 10 c0 movl $0xc0101372,(%esp) +c01013e1: e8 3d ff ff ff call c0101323 + } +} +c01013e6: 90 nop +c01013e7: 89 ec mov %ebp,%esp +c01013e9: 5d pop %ebp +c01013ea: c3 ret + +c01013eb : + * + * 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) { +c01013eb: 55 push %ebp +c01013ec: 89 e5 mov %esp,%ebp +c01013ee: 83 ec 38 sub $0x38,%esp +c01013f1: 66 c7 45 f0 64 00 movw $0x64,-0x10(%ebp) + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); +c01013f7: 8b 45 f0 mov -0x10(%ebp),%eax +c01013fa: 89 c2 mov %eax,%edx +c01013fc: ec in (%dx),%al +c01013fd: 88 45 ef mov %al,-0x11(%ebp) + return data; +c0101400: 0f b6 45 ef movzbl -0x11(%ebp),%eax + int c; + uint8_t data; + static uint32_t shift; + + if ((inb(KBSTATP) & KBS_DIB) == 0) { +c0101404: 0f b6 c0 movzbl %al,%eax +c0101407: 83 e0 01 and $0x1,%eax +c010140a: 85 c0 test %eax,%eax +c010140c: 75 0a jne c0101418 + return -1; +c010140e: b8 ff ff ff ff mov $0xffffffff,%eax +c0101413: e9 56 01 00 00 jmp c010156e +c0101418: 66 c7 45 ec 60 00 movw $0x60,-0x14(%ebp) + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); +c010141e: 8b 45 ec mov -0x14(%ebp),%eax +c0101421: 89 c2 mov %eax,%edx +c0101423: ec in (%dx),%al +c0101424: 88 45 eb mov %al,-0x15(%ebp) + return data; +c0101427: 0f b6 45 eb movzbl -0x15(%ebp),%eax + } + + data = inb(KBDATAP); +c010142b: 88 45 f3 mov %al,-0xd(%ebp) + + if (data == 0xE0) { +c010142e: 80 7d f3 e0 cmpb $0xe0,-0xd(%ebp) +c0101432: 75 17 jne c010144b + // E0 escape character + shift |= E0ESC; +c0101434: a1 68 c6 11 c0 mov 0xc011c668,%eax +c0101439: 83 c8 40 or $0x40,%eax +c010143c: a3 68 c6 11 c0 mov %eax,0xc011c668 + return 0; +c0101441: b8 00 00 00 00 mov $0x0,%eax +c0101446: e9 23 01 00 00 jmp c010156e + } else if (data & 0x80) { +c010144b: 0f b6 45 f3 movzbl -0xd(%ebp),%eax +c010144f: 84 c0 test %al,%al +c0101451: 79 45 jns c0101498 + // Key released + data = (shift & E0ESC ? data : data & 0x7F); +c0101453: a1 68 c6 11 c0 mov 0xc011c668,%eax +c0101458: 83 e0 40 and $0x40,%eax +c010145b: 85 c0 test %eax,%eax +c010145d: 75 08 jne c0101467 +c010145f: 0f b6 45 f3 movzbl -0xd(%ebp),%eax +c0101463: 24 7f and $0x7f,%al +c0101465: eb 04 jmp c010146b +c0101467: 0f b6 45 f3 movzbl -0xd(%ebp),%eax +c010146b: 88 45 f3 mov %al,-0xd(%ebp) + shift &= ~(shiftcode[data] | E0ESC); +c010146e: 0f b6 45 f3 movzbl -0xd(%ebp),%eax +c0101472: 0f b6 80 40 90 11 c0 movzbl -0x3fee6fc0(%eax),%eax +c0101479: 0c 40 or $0x40,%al +c010147b: 0f b6 c0 movzbl %al,%eax +c010147e: f7 d0 not %eax +c0101480: 89 c2 mov %eax,%edx +c0101482: a1 68 c6 11 c0 mov 0xc011c668,%eax +c0101487: 21 d0 and %edx,%eax +c0101489: a3 68 c6 11 c0 mov %eax,0xc011c668 + return 0; +c010148e: b8 00 00 00 00 mov $0x0,%eax +c0101493: e9 d6 00 00 00 jmp c010156e + } else if (shift & E0ESC) { +c0101498: a1 68 c6 11 c0 mov 0xc011c668,%eax +c010149d: 83 e0 40 and $0x40,%eax +c01014a0: 85 c0 test %eax,%eax +c01014a2: 74 11 je c01014b5 + // Last character was an E0 escape; or with 0x80 + data |= 0x80; +c01014a4: 80 4d f3 80 orb $0x80,-0xd(%ebp) + shift &= ~E0ESC; +c01014a8: a1 68 c6 11 c0 mov 0xc011c668,%eax +c01014ad: 83 e0 bf and $0xffffffbf,%eax +c01014b0: a3 68 c6 11 c0 mov %eax,0xc011c668 + } + + shift |= shiftcode[data]; +c01014b5: 0f b6 45 f3 movzbl -0xd(%ebp),%eax +c01014b9: 0f b6 80 40 90 11 c0 movzbl -0x3fee6fc0(%eax),%eax +c01014c0: 0f b6 d0 movzbl %al,%edx +c01014c3: a1 68 c6 11 c0 mov 0xc011c668,%eax +c01014c8: 09 d0 or %edx,%eax +c01014ca: a3 68 c6 11 c0 mov %eax,0xc011c668 + shift ^= togglecode[data]; +c01014cf: 0f b6 45 f3 movzbl -0xd(%ebp),%eax +c01014d3: 0f b6 80 40 91 11 c0 movzbl -0x3fee6ec0(%eax),%eax +c01014da: 0f b6 d0 movzbl %al,%edx +c01014dd: a1 68 c6 11 c0 mov 0xc011c668,%eax +c01014e2: 31 d0 xor %edx,%eax +c01014e4: a3 68 c6 11 c0 mov %eax,0xc011c668 + + c = charcode[shift & (CTL | SHIFT)][data]; +c01014e9: a1 68 c6 11 c0 mov 0xc011c668,%eax +c01014ee: 83 e0 03 and $0x3,%eax +c01014f1: 8b 14 85 40 95 11 c0 mov -0x3fee6ac0(,%eax,4),%edx +c01014f8: 0f b6 45 f3 movzbl -0xd(%ebp),%eax +c01014fc: 01 d0 add %edx,%eax +c01014fe: 0f b6 00 movzbl (%eax),%eax +c0101501: 0f b6 c0 movzbl %al,%eax +c0101504: 89 45 f4 mov %eax,-0xc(%ebp) + if (shift & CAPSLOCK) { +c0101507: a1 68 c6 11 c0 mov 0xc011c668,%eax +c010150c: 83 e0 08 and $0x8,%eax +c010150f: 85 c0 test %eax,%eax +c0101511: 74 22 je c0101535 + if ('a' <= c && c <= 'z') +c0101513: 83 7d f4 60 cmpl $0x60,-0xc(%ebp) +c0101517: 7e 0c jle c0101525 +c0101519: 83 7d f4 7a cmpl $0x7a,-0xc(%ebp) +c010151d: 7f 06 jg c0101525 + c += 'A' - 'a'; +c010151f: 83 6d f4 20 subl $0x20,-0xc(%ebp) +c0101523: eb 10 jmp c0101535 + else if ('A' <= c && c <= 'Z') +c0101525: 83 7d f4 40 cmpl $0x40,-0xc(%ebp) +c0101529: 7e 0a jle c0101535 +c010152b: 83 7d f4 5a cmpl $0x5a,-0xc(%ebp) +c010152f: 7f 04 jg c0101535 + c += 'a' - 'A'; +c0101531: 83 45 f4 20 addl $0x20,-0xc(%ebp) + } + + // Process special keys + // Ctrl-Alt-Del: reboot + if (!(~shift & (CTL | ALT)) && c == KEY_DEL) { +c0101535: a1 68 c6 11 c0 mov 0xc011c668,%eax +c010153a: f7 d0 not %eax +c010153c: 83 e0 06 and $0x6,%eax +c010153f: 85 c0 test %eax,%eax +c0101541: 75 28 jne c010156b +c0101543: 81 7d f4 e9 00 00 00 cmpl $0xe9,-0xc(%ebp) +c010154a: 75 1f jne c010156b + cprintf("Rebooting!\n"); +c010154c: c7 04 24 a7 63 10 c0 movl $0xc01063a7,(%esp) +c0101553: e8 0e ee ff ff call c0100366 +c0101558: 66 c7 45 e8 92 00 movw $0x92,-0x18(%ebp) +c010155e: c6 45 e7 03 movb $0x3,-0x19(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101562: 0f b6 45 e7 movzbl -0x19(%ebp),%eax +c0101566: 8b 55 e8 mov -0x18(%ebp),%edx +c0101569: ee out %al,(%dx) +} +c010156a: 90 nop + outb(0x92, 0x3); // courtesy of Chris Frost + } + return c; +c010156b: 8b 45 f4 mov -0xc(%ebp),%eax +} +c010156e: 89 ec mov %ebp,%esp +c0101570: 5d pop %ebp +c0101571: c3 ret + +c0101572 : + +/* kbd_intr - try to feed input characters from keyboard */ +static void +kbd_intr(void) { +c0101572: 55 push %ebp +c0101573: 89 e5 mov %esp,%ebp +c0101575: 83 ec 18 sub $0x18,%esp + cons_intr(kbd_proc_data); +c0101578: c7 04 24 eb 13 10 c0 movl $0xc01013eb,(%esp) +c010157f: e8 9f fd ff ff call c0101323 +} +c0101584: 90 nop +c0101585: 89 ec mov %ebp,%esp +c0101587: 5d pop %ebp +c0101588: c3 ret + +c0101589 : + +static void +kbd_init(void) { +c0101589: 55 push %ebp +c010158a: 89 e5 mov %esp,%ebp +c010158c: 83 ec 18 sub $0x18,%esp + // drain the kbd buffer + kbd_intr(); +c010158f: e8 de ff ff ff call c0101572 + pic_enable(IRQ_KBD); +c0101594: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c010159b: e8 51 01 00 00 call c01016f1 +} +c01015a0: 90 nop +c01015a1: 89 ec mov %ebp,%esp +c01015a3: 5d pop %ebp +c01015a4: c3 ret + +c01015a5 : + +/* cons_init - initializes the console devices */ +void +cons_init(void) { +c01015a5: 55 push %ebp +c01015a6: 89 e5 mov %esp,%ebp +c01015a8: 83 ec 18 sub $0x18,%esp + cga_init(); +c01015ab: e8 4a f8 ff ff call c0100dfa + serial_init(); +c01015b0: e8 2d f9 ff ff call c0100ee2 + kbd_init(); +c01015b5: e8 cf ff ff ff call c0101589 + if (!serial_exists) { +c01015ba: a1 48 c4 11 c0 mov 0xc011c448,%eax +c01015bf: 85 c0 test %eax,%eax +c01015c1: 75 0c jne c01015cf + cprintf("serial port does not exist!!\n"); +c01015c3: c7 04 24 b3 63 10 c0 movl $0xc01063b3,(%esp) +c01015ca: e8 97 ed ff ff call c0100366 + } +} +c01015cf: 90 nop +c01015d0: 89 ec mov %ebp,%esp +c01015d2: 5d pop %ebp +c01015d3: c3 ret + +c01015d4 : + +/* cons_putc - print a single character @c to console devices */ +void +cons_putc(int c) { +c01015d4: 55 push %ebp +c01015d5: 89 e5 mov %esp,%ebp +c01015d7: 83 ec 28 sub $0x28,%esp + bool intr_flag; + local_intr_save(intr_flag); +c01015da: e8 8e f7 ff ff call c0100d6d <__intr_save> +c01015df: 89 45 f4 mov %eax,-0xc(%ebp) + { + lpt_putc(c); +c01015e2: 8b 45 08 mov 0x8(%ebp),%eax +c01015e5: 89 04 24 mov %eax,(%esp) +c01015e8: e8 60 fa ff ff call c010104d + cga_putc(c); +c01015ed: 8b 45 08 mov 0x8(%ebp),%eax +c01015f0: 89 04 24 mov %eax,(%esp) +c01015f3: e8 97 fa ff ff call c010108f + serial_putc(c); +c01015f8: 8b 45 08 mov 0x8(%ebp),%eax +c01015fb: 89 04 24 mov %eax,(%esp) +c01015fe: e8 de fc ff ff call c01012e1 + } + local_intr_restore(intr_flag); +c0101603: 8b 45 f4 mov -0xc(%ebp),%eax +c0101606: 89 04 24 mov %eax,(%esp) +c0101609: e8 8b f7 ff ff call c0100d99 <__intr_restore> +} +c010160e: 90 nop +c010160f: 89 ec mov %ebp,%esp +c0101611: 5d pop %ebp +c0101612: c3 ret + +c0101613 : +/* * + * cons_getc - return the next input character from console, + * or 0 if none waiting. + * */ +int +cons_getc(void) { +c0101613: 55 push %ebp +c0101614: 89 e5 mov %esp,%ebp +c0101616: 83 ec 28 sub $0x28,%esp + int c = 0; +c0101619: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + bool intr_flag; + local_intr_save(intr_flag); +c0101620: e8 48 f7 ff ff call c0100d6d <__intr_save> +c0101625: 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(); +c0101628: e8 9e fd ff ff call c01013cb + kbd_intr(); +c010162d: e8 40 ff ff ff call c0101572 + + // grab the next character from the input buffer. + if (cons.rpos != cons.wpos) { +c0101632: 8b 15 60 c6 11 c0 mov 0xc011c660,%edx +c0101638: a1 64 c6 11 c0 mov 0xc011c664,%eax +c010163d: 39 c2 cmp %eax,%edx +c010163f: 74 31 je c0101672 + c = cons.buf[cons.rpos ++]; +c0101641: a1 60 c6 11 c0 mov 0xc011c660,%eax +c0101646: 8d 50 01 lea 0x1(%eax),%edx +c0101649: 89 15 60 c6 11 c0 mov %edx,0xc011c660 +c010164f: 0f b6 80 60 c4 11 c0 movzbl -0x3fee3ba0(%eax),%eax +c0101656: 0f b6 c0 movzbl %al,%eax +c0101659: 89 45 f4 mov %eax,-0xc(%ebp) + if (cons.rpos == CONSBUFSIZE) { +c010165c: a1 60 c6 11 c0 mov 0xc011c660,%eax +c0101661: 3d 00 02 00 00 cmp $0x200,%eax +c0101666: 75 0a jne c0101672 + cons.rpos = 0; +c0101668: c7 05 60 c6 11 c0 00 movl $0x0,0xc011c660 +c010166f: 00 00 00 + } + } + } + local_intr_restore(intr_flag); +c0101672: 8b 45 f0 mov -0x10(%ebp),%eax +c0101675: 89 04 24 mov %eax,(%esp) +c0101678: e8 1c f7 ff ff call c0100d99 <__intr_restore> + return c; +c010167d: 8b 45 f4 mov -0xc(%ebp),%eax +} +c0101680: 89 ec mov %ebp,%esp +c0101682: 5d pop %ebp +c0101683: c3 ret + +c0101684 : +#include +#include + +/* intr_enable - enable irq interrupt */ +void +intr_enable(void) { +c0101684: 55 push %ebp +c0101685: 89 e5 mov %esp,%ebp + asm volatile ("sti"); +c0101687: fb sti +} +c0101688: 90 nop + sti(); +} +c0101689: 90 nop +c010168a: 5d pop %ebp +c010168b: c3 ret + +c010168c : + +/* intr_disable - disable irq interrupt */ +void +intr_disable(void) { +c010168c: 55 push %ebp +c010168d: 89 e5 mov %esp,%ebp + asm volatile ("cli" ::: "memory"); +c010168f: fa cli +} +c0101690: 90 nop + cli(); +} +c0101691: 90 nop +c0101692: 5d pop %ebp +c0101693: c3 ret + +c0101694 : +// 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) { +c0101694: 55 push %ebp +c0101695: 89 e5 mov %esp,%ebp +c0101697: 83 ec 14 sub $0x14,%esp +c010169a: 8b 45 08 mov 0x8(%ebp),%eax +c010169d: 66 89 45 ec mov %ax,-0x14(%ebp) + irq_mask = mask; +c01016a1: 8b 45 ec mov -0x14(%ebp),%eax +c01016a4: 66 a3 50 95 11 c0 mov %ax,0xc0119550 + if (did_init) { +c01016aa: a1 6c c6 11 c0 mov 0xc011c66c,%eax +c01016af: 85 c0 test %eax,%eax +c01016b1: 74 39 je c01016ec + outb(IO_PIC1 + 1, mask); +c01016b3: 8b 45 ec mov -0x14(%ebp),%eax +c01016b6: 0f b6 c0 movzbl %al,%eax +c01016b9: 66 c7 45 fa 21 00 movw $0x21,-0x6(%ebp) +c01016bf: 88 45 f9 mov %al,-0x7(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c01016c2: 0f b6 45 f9 movzbl -0x7(%ebp),%eax +c01016c6: 0f b7 55 fa movzwl -0x6(%ebp),%edx +c01016ca: ee out %al,(%dx) +} +c01016cb: 90 nop + outb(IO_PIC2 + 1, mask >> 8); +c01016cc: 0f b7 45 ec movzwl -0x14(%ebp),%eax +c01016d0: c1 e8 08 shr $0x8,%eax +c01016d3: 0f b7 c0 movzwl %ax,%eax +c01016d6: 0f b6 c0 movzbl %al,%eax +c01016d9: 66 c7 45 fe a1 00 movw $0xa1,-0x2(%ebp) +c01016df: 88 45 fd mov %al,-0x3(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c01016e2: 0f b6 45 fd movzbl -0x3(%ebp),%eax +c01016e6: 0f b7 55 fe movzwl -0x2(%ebp),%edx +c01016ea: ee out %al,(%dx) +} +c01016eb: 90 nop + } +} +c01016ec: 90 nop +c01016ed: 89 ec mov %ebp,%esp +c01016ef: 5d pop %ebp +c01016f0: c3 ret + +c01016f1 : + +void +pic_enable(unsigned int irq) { +c01016f1: 55 push %ebp +c01016f2: 89 e5 mov %esp,%ebp +c01016f4: 83 ec 04 sub $0x4,%esp + pic_setmask(irq_mask & ~(1 << irq)); +c01016f7: 8b 45 08 mov 0x8(%ebp),%eax +c01016fa: ba 01 00 00 00 mov $0x1,%edx +c01016ff: 88 c1 mov %al,%cl +c0101701: d3 e2 shl %cl,%edx +c0101703: 89 d0 mov %edx,%eax +c0101705: 98 cwtl +c0101706: f7 d0 not %eax +c0101708: 0f bf d0 movswl %ax,%edx +c010170b: 0f b7 05 50 95 11 c0 movzwl 0xc0119550,%eax +c0101712: 98 cwtl +c0101713: 21 d0 and %edx,%eax +c0101715: 98 cwtl +c0101716: 0f b7 c0 movzwl %ax,%eax +c0101719: 89 04 24 mov %eax,(%esp) +c010171c: e8 73 ff ff ff call c0101694 +} +c0101721: 90 nop +c0101722: 89 ec mov %ebp,%esp +c0101724: 5d pop %ebp +c0101725: c3 ret + +c0101726 : + +/* pic_init - initialize the 8259A interrupt controllers */ +void +pic_init(void) { +c0101726: 55 push %ebp +c0101727: 89 e5 mov %esp,%ebp +c0101729: 83 ec 44 sub $0x44,%esp + did_init = 1; +c010172c: c7 05 6c c6 11 c0 01 movl $0x1,0xc011c66c +c0101733: 00 00 00 +c0101736: 66 c7 45 ca 21 00 movw $0x21,-0x36(%ebp) +c010173c: c6 45 c9 ff movb $0xff,-0x37(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101740: 0f b6 45 c9 movzbl -0x37(%ebp),%eax +c0101744: 0f b7 55 ca movzwl -0x36(%ebp),%edx +c0101748: ee out %al,(%dx) +} +c0101749: 90 nop +c010174a: 66 c7 45 ce a1 00 movw $0xa1,-0x32(%ebp) +c0101750: c6 45 cd ff movb $0xff,-0x33(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101754: 0f b6 45 cd movzbl -0x33(%ebp),%eax +c0101758: 0f b7 55 ce movzwl -0x32(%ebp),%edx +c010175c: ee out %al,(%dx) +} +c010175d: 90 nop +c010175e: 66 c7 45 d2 20 00 movw $0x20,-0x2e(%ebp) +c0101764: c6 45 d1 11 movb $0x11,-0x2f(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101768: 0f b6 45 d1 movzbl -0x2f(%ebp),%eax +c010176c: 0f b7 55 d2 movzwl -0x2e(%ebp),%edx +c0101770: ee out %al,(%dx) +} +c0101771: 90 nop +c0101772: 66 c7 45 d6 21 00 movw $0x21,-0x2a(%ebp) +c0101778: c6 45 d5 20 movb $0x20,-0x2b(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c010177c: 0f b6 45 d5 movzbl -0x2b(%ebp),%eax +c0101780: 0f b7 55 d6 movzwl -0x2a(%ebp),%edx +c0101784: ee out %al,(%dx) +} +c0101785: 90 nop +c0101786: 66 c7 45 da 21 00 movw $0x21,-0x26(%ebp) +c010178c: c6 45 d9 04 movb $0x4,-0x27(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101790: 0f b6 45 d9 movzbl -0x27(%ebp),%eax +c0101794: 0f b7 55 da movzwl -0x26(%ebp),%edx +c0101798: ee out %al,(%dx) +} +c0101799: 90 nop +c010179a: 66 c7 45 de 21 00 movw $0x21,-0x22(%ebp) +c01017a0: c6 45 dd 03 movb $0x3,-0x23(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c01017a4: 0f b6 45 dd movzbl -0x23(%ebp),%eax +c01017a8: 0f b7 55 de movzwl -0x22(%ebp),%edx +c01017ac: ee out %al,(%dx) +} +c01017ad: 90 nop +c01017ae: 66 c7 45 e2 a0 00 movw $0xa0,-0x1e(%ebp) +c01017b4: c6 45 e1 11 movb $0x11,-0x1f(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c01017b8: 0f b6 45 e1 movzbl -0x1f(%ebp),%eax +c01017bc: 0f b7 55 e2 movzwl -0x1e(%ebp),%edx +c01017c0: ee out %al,(%dx) +} +c01017c1: 90 nop +c01017c2: 66 c7 45 e6 a1 00 movw $0xa1,-0x1a(%ebp) +c01017c8: c6 45 e5 28 movb $0x28,-0x1b(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c01017cc: 0f b6 45 e5 movzbl -0x1b(%ebp),%eax +c01017d0: 0f b7 55 e6 movzwl -0x1a(%ebp),%edx +c01017d4: ee out %al,(%dx) +} +c01017d5: 90 nop +c01017d6: 66 c7 45 ea a1 00 movw $0xa1,-0x16(%ebp) +c01017dc: c6 45 e9 02 movb $0x2,-0x17(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c01017e0: 0f b6 45 e9 movzbl -0x17(%ebp),%eax +c01017e4: 0f b7 55 ea movzwl -0x16(%ebp),%edx +c01017e8: ee out %al,(%dx) +} +c01017e9: 90 nop +c01017ea: 66 c7 45 ee a1 00 movw $0xa1,-0x12(%ebp) +c01017f0: c6 45 ed 03 movb $0x3,-0x13(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c01017f4: 0f b6 45 ed movzbl -0x13(%ebp),%eax +c01017f8: 0f b7 55 ee movzwl -0x12(%ebp),%edx +c01017fc: ee out %al,(%dx) +} +c01017fd: 90 nop +c01017fe: 66 c7 45 f2 20 00 movw $0x20,-0xe(%ebp) +c0101804: c6 45 f1 68 movb $0x68,-0xf(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101808: 0f b6 45 f1 movzbl -0xf(%ebp),%eax +c010180c: 0f b7 55 f2 movzwl -0xe(%ebp),%edx +c0101810: ee out %al,(%dx) +} +c0101811: 90 nop +c0101812: 66 c7 45 f6 20 00 movw $0x20,-0xa(%ebp) +c0101818: c6 45 f5 0a movb $0xa,-0xb(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c010181c: 0f b6 45 f5 movzbl -0xb(%ebp),%eax +c0101820: 0f b7 55 f6 movzwl -0xa(%ebp),%edx +c0101824: ee out %al,(%dx) +} +c0101825: 90 nop +c0101826: 66 c7 45 fa a0 00 movw $0xa0,-0x6(%ebp) +c010182c: c6 45 f9 68 movb $0x68,-0x7(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101830: 0f b6 45 f9 movzbl -0x7(%ebp),%eax +c0101834: 0f b7 55 fa movzwl -0x6(%ebp),%edx +c0101838: ee out %al,(%dx) +} +c0101839: 90 nop +c010183a: 66 c7 45 fe a0 00 movw $0xa0,-0x2(%ebp) +c0101840: c6 45 fd 0a movb $0xa,-0x3(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101844: 0f b6 45 fd movzbl -0x3(%ebp),%eax +c0101848: 0f b7 55 fe movzwl -0x2(%ebp),%edx +c010184c: ee out %al,(%dx) +} +c010184d: 90 nop + outb(IO_PIC1, 0x0a); // read IRR by default + + outb(IO_PIC2, 0x68); // OCW3 + outb(IO_PIC2, 0x0a); // OCW3 + + if (irq_mask != 0xFFFF) { +c010184e: 0f b7 05 50 95 11 c0 movzwl 0xc0119550,%eax +c0101855: 3d ff ff 00 00 cmp $0xffff,%eax +c010185a: 74 0f je c010186b + pic_setmask(irq_mask); +c010185c: 0f b7 05 50 95 11 c0 movzwl 0xc0119550,%eax +c0101863: 89 04 24 mov %eax,(%esp) +c0101866: e8 29 fe ff ff call c0101694 + } +} +c010186b: 90 nop +c010186c: 89 ec mov %ebp,%esp +c010186e: 5d pop %ebp +c010186f: c3 ret + +c0101870 : +#include +#include + +#define TICK_NUM 100 + +static void print_ticks() { +c0101870: 55 push %ebp +c0101871: 89 e5 mov %esp,%ebp +c0101873: 83 ec 18 sub $0x18,%esp + cprintf("%d ticks\n",TICK_NUM); +c0101876: c7 44 24 04 64 00 00 movl $0x64,0x4(%esp) +c010187d: 00 +c010187e: c7 04 24 e0 63 10 c0 movl $0xc01063e0,(%esp) +c0101885: e8 dc ea ff ff call c0100366 +#ifdef DEBUG_GRADE + cprintf("End of Test.\n"); + panic("EOT: kernel seems ok."); +#endif +} +c010188a: 90 nop +c010188b: 89 ec mov %ebp,%esp +c010188d: 5d pop %ebp +c010188e: c3 ret + +c010188f : + 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) { +c010188f: 55 push %ebp +c0101890: 89 e5 mov %esp,%ebp +c0101892: 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 ++) { +c0101895: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) +c010189c: e9 c4 00 00 00 jmp c0101965 + SETGATE(idt[i], 0, GD_KTEXT, __vectors[i], DPL_KERNEL); +c01018a1: 8b 45 fc mov -0x4(%ebp),%eax +c01018a4: 8b 04 85 e0 95 11 c0 mov -0x3fee6a20(,%eax,4),%eax +c01018ab: 0f b7 d0 movzwl %ax,%edx +c01018ae: 8b 45 fc mov -0x4(%ebp),%eax +c01018b1: 66 89 14 c5 e0 c6 11 mov %dx,-0x3fee3920(,%eax,8) +c01018b8: c0 +c01018b9: 8b 45 fc mov -0x4(%ebp),%eax +c01018bc: 66 c7 04 c5 e2 c6 11 movw $0x8,-0x3fee391e(,%eax,8) +c01018c3: c0 08 00 +c01018c6: 8b 45 fc mov -0x4(%ebp),%eax +c01018c9: 0f b6 14 c5 e4 c6 11 movzbl -0x3fee391c(,%eax,8),%edx +c01018d0: c0 +c01018d1: 80 e2 e0 and $0xe0,%dl +c01018d4: 88 14 c5 e4 c6 11 c0 mov %dl,-0x3fee391c(,%eax,8) +c01018db: 8b 45 fc mov -0x4(%ebp),%eax +c01018de: 0f b6 14 c5 e4 c6 11 movzbl -0x3fee391c(,%eax,8),%edx +c01018e5: c0 +c01018e6: 80 e2 1f and $0x1f,%dl +c01018e9: 88 14 c5 e4 c6 11 c0 mov %dl,-0x3fee391c(,%eax,8) +c01018f0: 8b 45 fc mov -0x4(%ebp),%eax +c01018f3: 0f b6 14 c5 e5 c6 11 movzbl -0x3fee391b(,%eax,8),%edx +c01018fa: c0 +c01018fb: 80 e2 f0 and $0xf0,%dl +c01018fe: 80 ca 0e or $0xe,%dl +c0101901: 88 14 c5 e5 c6 11 c0 mov %dl,-0x3fee391b(,%eax,8) +c0101908: 8b 45 fc mov -0x4(%ebp),%eax +c010190b: 0f b6 14 c5 e5 c6 11 movzbl -0x3fee391b(,%eax,8),%edx +c0101912: c0 +c0101913: 80 e2 ef and $0xef,%dl +c0101916: 88 14 c5 e5 c6 11 c0 mov %dl,-0x3fee391b(,%eax,8) +c010191d: 8b 45 fc mov -0x4(%ebp),%eax +c0101920: 0f b6 14 c5 e5 c6 11 movzbl -0x3fee391b(,%eax,8),%edx +c0101927: c0 +c0101928: 80 e2 9f and $0x9f,%dl +c010192b: 88 14 c5 e5 c6 11 c0 mov %dl,-0x3fee391b(,%eax,8) +c0101932: 8b 45 fc mov -0x4(%ebp),%eax +c0101935: 0f b6 14 c5 e5 c6 11 movzbl -0x3fee391b(,%eax,8),%edx +c010193c: c0 +c010193d: 80 ca 80 or $0x80,%dl +c0101940: 88 14 c5 e5 c6 11 c0 mov %dl,-0x3fee391b(,%eax,8) +c0101947: 8b 45 fc mov -0x4(%ebp),%eax +c010194a: 8b 04 85 e0 95 11 c0 mov -0x3fee6a20(,%eax,4),%eax +c0101951: c1 e8 10 shr $0x10,%eax +c0101954: 0f b7 d0 movzwl %ax,%edx +c0101957: 8b 45 fc mov -0x4(%ebp),%eax +c010195a: 66 89 14 c5 e6 c6 11 mov %dx,-0x3fee391a(,%eax,8) +c0101961: c0 + for (i = 0; i < sizeof(idt) / sizeof(struct gatedesc); i ++) { +c0101962: ff 45 fc incl -0x4(%ebp) +c0101965: 8b 45 fc mov -0x4(%ebp),%eax +c0101968: 3d ff 00 00 00 cmp $0xff,%eax +c010196d: 0f 86 2e ff ff ff jbe c01018a1 + //宏用于配置每个 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_SWITCH_TOK], 0, GD_KTEXT, __vectors[T_SWITCH_TOK], DPL_USER); +c0101973: a1 c4 97 11 c0 mov 0xc01197c4,%eax +c0101978: 0f b7 c0 movzwl %ax,%eax +c010197b: 66 a3 a8 ca 11 c0 mov %ax,0xc011caa8 +c0101981: 66 c7 05 aa ca 11 c0 movw $0x8,0xc011caaa +c0101988: 08 00 +c010198a: 0f b6 05 ac ca 11 c0 movzbl 0xc011caac,%eax +c0101991: 24 e0 and $0xe0,%al +c0101993: a2 ac ca 11 c0 mov %al,0xc011caac +c0101998: 0f b6 05 ac ca 11 c0 movzbl 0xc011caac,%eax +c010199f: 24 1f and $0x1f,%al +c01019a1: a2 ac ca 11 c0 mov %al,0xc011caac +c01019a6: 0f b6 05 ad ca 11 c0 movzbl 0xc011caad,%eax +c01019ad: 24 f0 and $0xf0,%al +c01019af: 0c 0e or $0xe,%al +c01019b1: a2 ad ca 11 c0 mov %al,0xc011caad +c01019b6: 0f b6 05 ad ca 11 c0 movzbl 0xc011caad,%eax +c01019bd: 24 ef and $0xef,%al +c01019bf: a2 ad ca 11 c0 mov %al,0xc011caad +c01019c4: 0f b6 05 ad ca 11 c0 movzbl 0xc011caad,%eax +c01019cb: 0c 60 or $0x60,%al +c01019cd: a2 ad ca 11 c0 mov %al,0xc011caad +c01019d2: 0f b6 05 ad ca 11 c0 movzbl 0xc011caad,%eax +c01019d9: 0c 80 or $0x80,%al +c01019db: a2 ad ca 11 c0 mov %al,0xc011caad +c01019e0: a1 c4 97 11 c0 mov 0xc01197c4,%eax +c01019e5: c1 e8 10 shr $0x10,%eax +c01019e8: 0f b7 c0 movzwl %ax,%eax +c01019eb: 66 a3 ae ca 11 c0 mov %ax,0xc011caae +c01019f1: c7 45 f8 60 95 11 c0 movl $0xc0119560,-0x8(%ebp) + asm volatile ("lidt (%0)" :: "r" (pd) : "memory"); +c01019f8: 8b 45 f8 mov -0x8(%ebp),%eax +c01019fb: 0f 01 18 lidtl (%eax) +} +c01019fe: 90 nop + // load the IDT + //使用 lidt 指令将 IDT 描述符加载到 CPU 中 + lidt(&idt_pd); +} +c01019ff: 90 nop +c0101a00: 89 ec mov %ebp,%esp +c0101a02: 5d pop %ebp +c0101a03: c3 ret + +c0101a04 : + +static const char * +trapname(int trapno) { +c0101a04: 55 push %ebp +c0101a05: 89 e5 mov %esp,%ebp + "Alignment Check", + "Machine-Check", + "SIMD Floating-Point Exception" + }; + + if (trapno < sizeof(excnames)/sizeof(const char * const)) { +c0101a07: 8b 45 08 mov 0x8(%ebp),%eax +c0101a0a: 83 f8 13 cmp $0x13,%eax +c0101a0d: 77 0c ja c0101a1b + return excnames[trapno]; +c0101a0f: 8b 45 08 mov 0x8(%ebp),%eax +c0101a12: 8b 04 85 40 67 10 c0 mov -0x3fef98c0(,%eax,4),%eax +c0101a19: eb 18 jmp c0101a33 + } + if (trapno >= IRQ_OFFSET && trapno < IRQ_OFFSET + 16) { +c0101a1b: 83 7d 08 1f cmpl $0x1f,0x8(%ebp) +c0101a1f: 7e 0d jle c0101a2e +c0101a21: 83 7d 08 2f cmpl $0x2f,0x8(%ebp) +c0101a25: 7f 07 jg c0101a2e + return "Hardware Interrupt"; +c0101a27: b8 ea 63 10 c0 mov $0xc01063ea,%eax +c0101a2c: eb 05 jmp c0101a33 + } + return "(unknown trap)"; +c0101a2e: b8 fd 63 10 c0 mov $0xc01063fd,%eax +} +c0101a33: 5d pop %ebp +c0101a34: c3 ret + +c0101a35 : + +/* trap_in_kernel - test if trap happened in kernel */ +bool +trap_in_kernel(struct trapframe *tf) { +c0101a35: 55 push %ebp +c0101a36: 89 e5 mov %esp,%ebp + return (tf->tf_cs == (uint16_t)KERNEL_CS); +c0101a38: 8b 45 08 mov 0x8(%ebp),%eax +c0101a3b: 0f b7 40 3c movzwl 0x3c(%eax),%eax +c0101a3f: 83 f8 08 cmp $0x8,%eax +c0101a42: 0f 94 c0 sete %al +c0101a45: 0f b6 c0 movzbl %al,%eax +} +c0101a48: 5d pop %ebp +c0101a49: c3 ret + +c0101a4a : + "TF", "IF", "DF", "OF", NULL, NULL, "NT", NULL, + "RF", "VM", "AC", "VIF", "VIP", "ID", NULL, NULL, +}; + +void +print_trapframe(struct trapframe *tf) { +c0101a4a: 55 push %ebp +c0101a4b: 89 e5 mov %esp,%ebp +c0101a4d: 83 ec 28 sub $0x28,%esp + cprintf("trapframe at %p\n", tf); +c0101a50: 8b 45 08 mov 0x8(%ebp),%eax +c0101a53: 89 44 24 04 mov %eax,0x4(%esp) +c0101a57: c7 04 24 3e 64 10 c0 movl $0xc010643e,(%esp) +c0101a5e: e8 03 e9 ff ff call c0100366 + print_regs(&tf->tf_regs); +c0101a63: 8b 45 08 mov 0x8(%ebp),%eax +c0101a66: 89 04 24 mov %eax,(%esp) +c0101a69: e8 8f 01 00 00 call c0101bfd + cprintf(" ds 0x----%04x\n", tf->tf_ds); +c0101a6e: 8b 45 08 mov 0x8(%ebp),%eax +c0101a71: 0f b7 40 2c movzwl 0x2c(%eax),%eax +c0101a75: 89 44 24 04 mov %eax,0x4(%esp) +c0101a79: c7 04 24 4f 64 10 c0 movl $0xc010644f,(%esp) +c0101a80: e8 e1 e8 ff ff call c0100366 + cprintf(" es 0x----%04x\n", tf->tf_es); +c0101a85: 8b 45 08 mov 0x8(%ebp),%eax +c0101a88: 0f b7 40 28 movzwl 0x28(%eax),%eax +c0101a8c: 89 44 24 04 mov %eax,0x4(%esp) +c0101a90: c7 04 24 62 64 10 c0 movl $0xc0106462,(%esp) +c0101a97: e8 ca e8 ff ff call c0100366 + cprintf(" fs 0x----%04x\n", tf->tf_fs); +c0101a9c: 8b 45 08 mov 0x8(%ebp),%eax +c0101a9f: 0f b7 40 24 movzwl 0x24(%eax),%eax +c0101aa3: 89 44 24 04 mov %eax,0x4(%esp) +c0101aa7: c7 04 24 75 64 10 c0 movl $0xc0106475,(%esp) +c0101aae: e8 b3 e8 ff ff call c0100366 + cprintf(" gs 0x----%04x\n", tf->tf_gs); +c0101ab3: 8b 45 08 mov 0x8(%ebp),%eax +c0101ab6: 0f b7 40 20 movzwl 0x20(%eax),%eax +c0101aba: 89 44 24 04 mov %eax,0x4(%esp) +c0101abe: c7 04 24 88 64 10 c0 movl $0xc0106488,(%esp) +c0101ac5: e8 9c e8 ff ff call c0100366 + cprintf(" trap 0x%08x %s\n", tf->tf_trapno, trapname(tf->tf_trapno)); +c0101aca: 8b 45 08 mov 0x8(%ebp),%eax +c0101acd: 8b 40 30 mov 0x30(%eax),%eax +c0101ad0: 89 04 24 mov %eax,(%esp) +c0101ad3: e8 2c ff ff ff call c0101a04 +c0101ad8: 8b 55 08 mov 0x8(%ebp),%edx +c0101adb: 8b 52 30 mov 0x30(%edx),%edx +c0101ade: 89 44 24 08 mov %eax,0x8(%esp) +c0101ae2: 89 54 24 04 mov %edx,0x4(%esp) +c0101ae6: c7 04 24 9b 64 10 c0 movl $0xc010649b,(%esp) +c0101aed: e8 74 e8 ff ff call c0100366 + cprintf(" err 0x%08x\n", tf->tf_err); +c0101af2: 8b 45 08 mov 0x8(%ebp),%eax +c0101af5: 8b 40 34 mov 0x34(%eax),%eax +c0101af8: 89 44 24 04 mov %eax,0x4(%esp) +c0101afc: c7 04 24 ad 64 10 c0 movl $0xc01064ad,(%esp) +c0101b03: e8 5e e8 ff ff call c0100366 + cprintf(" eip 0x%08x\n", tf->tf_eip); +c0101b08: 8b 45 08 mov 0x8(%ebp),%eax +c0101b0b: 8b 40 38 mov 0x38(%eax),%eax +c0101b0e: 89 44 24 04 mov %eax,0x4(%esp) +c0101b12: c7 04 24 bc 64 10 c0 movl $0xc01064bc,(%esp) +c0101b19: e8 48 e8 ff ff call c0100366 + cprintf(" cs 0x----%04x\n", tf->tf_cs); +c0101b1e: 8b 45 08 mov 0x8(%ebp),%eax +c0101b21: 0f b7 40 3c movzwl 0x3c(%eax),%eax +c0101b25: 89 44 24 04 mov %eax,0x4(%esp) +c0101b29: c7 04 24 cb 64 10 c0 movl $0xc01064cb,(%esp) +c0101b30: e8 31 e8 ff ff call c0100366 + cprintf(" flag 0x%08x ", tf->tf_eflags); +c0101b35: 8b 45 08 mov 0x8(%ebp),%eax +c0101b38: 8b 40 40 mov 0x40(%eax),%eax +c0101b3b: 89 44 24 04 mov %eax,0x4(%esp) +c0101b3f: c7 04 24 de 64 10 c0 movl $0xc01064de,(%esp) +c0101b46: e8 1b e8 ff ff call c0100366 + + int i, j; + for (i = 0, j = 1; i < sizeof(IA32flags) / sizeof(IA32flags[0]); i ++, j <<= 1) { +c0101b4b: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) +c0101b52: c7 45 f0 01 00 00 00 movl $0x1,-0x10(%ebp) +c0101b59: eb 3d jmp c0101b98 + if ((tf->tf_eflags & j) && IA32flags[i] != NULL) { +c0101b5b: 8b 45 08 mov 0x8(%ebp),%eax +c0101b5e: 8b 50 40 mov 0x40(%eax),%edx +c0101b61: 8b 45 f0 mov -0x10(%ebp),%eax +c0101b64: 21 d0 and %edx,%eax +c0101b66: 85 c0 test %eax,%eax +c0101b68: 74 28 je c0101b92 +c0101b6a: 8b 45 f4 mov -0xc(%ebp),%eax +c0101b6d: 8b 04 85 80 95 11 c0 mov -0x3fee6a80(,%eax,4),%eax +c0101b74: 85 c0 test %eax,%eax +c0101b76: 74 1a je c0101b92 + cprintf("%s,", IA32flags[i]); +c0101b78: 8b 45 f4 mov -0xc(%ebp),%eax +c0101b7b: 8b 04 85 80 95 11 c0 mov -0x3fee6a80(,%eax,4),%eax +c0101b82: 89 44 24 04 mov %eax,0x4(%esp) +c0101b86: c7 04 24 ed 64 10 c0 movl $0xc01064ed,(%esp) +c0101b8d: e8 d4 e7 ff ff call c0100366 + for (i = 0, j = 1; i < sizeof(IA32flags) / sizeof(IA32flags[0]); i ++, j <<= 1) { +c0101b92: ff 45 f4 incl -0xc(%ebp) +c0101b95: d1 65 f0 shll -0x10(%ebp) +c0101b98: 8b 45 f4 mov -0xc(%ebp),%eax +c0101b9b: 83 f8 17 cmp $0x17,%eax +c0101b9e: 76 bb jbe c0101b5b + } + } + cprintf("IOPL=%d\n", (tf->tf_eflags & FL_IOPL_MASK) >> 12); +c0101ba0: 8b 45 08 mov 0x8(%ebp),%eax +c0101ba3: 8b 40 40 mov 0x40(%eax),%eax +c0101ba6: c1 e8 0c shr $0xc,%eax +c0101ba9: 83 e0 03 and $0x3,%eax +c0101bac: 89 44 24 04 mov %eax,0x4(%esp) +c0101bb0: c7 04 24 f1 64 10 c0 movl $0xc01064f1,(%esp) +c0101bb7: e8 aa e7 ff ff call c0100366 + + if (!trap_in_kernel(tf)) { +c0101bbc: 8b 45 08 mov 0x8(%ebp),%eax +c0101bbf: 89 04 24 mov %eax,(%esp) +c0101bc2: e8 6e fe ff ff call c0101a35 +c0101bc7: 85 c0 test %eax,%eax +c0101bc9: 75 2d jne c0101bf8 + cprintf(" esp 0x%08x\n", tf->tf_esp); +c0101bcb: 8b 45 08 mov 0x8(%ebp),%eax +c0101bce: 8b 40 44 mov 0x44(%eax),%eax +c0101bd1: 89 44 24 04 mov %eax,0x4(%esp) +c0101bd5: c7 04 24 fa 64 10 c0 movl $0xc01064fa,(%esp) +c0101bdc: e8 85 e7 ff ff call c0100366 + cprintf(" ss 0x----%04x\n", tf->tf_ss); +c0101be1: 8b 45 08 mov 0x8(%ebp),%eax +c0101be4: 0f b7 40 48 movzwl 0x48(%eax),%eax +c0101be8: 89 44 24 04 mov %eax,0x4(%esp) +c0101bec: c7 04 24 09 65 10 c0 movl $0xc0106509,(%esp) +c0101bf3: e8 6e e7 ff ff call c0100366 + } +} +c0101bf8: 90 nop +c0101bf9: 89 ec mov %ebp,%esp +c0101bfb: 5d pop %ebp +c0101bfc: c3 ret + +c0101bfd : + +void +print_regs(struct pushregs *regs) { +c0101bfd: 55 push %ebp +c0101bfe: 89 e5 mov %esp,%ebp +c0101c00: 83 ec 18 sub $0x18,%esp + cprintf(" edi 0x%08x\n", regs->reg_edi); +c0101c03: 8b 45 08 mov 0x8(%ebp),%eax +c0101c06: 8b 00 mov (%eax),%eax +c0101c08: 89 44 24 04 mov %eax,0x4(%esp) +c0101c0c: c7 04 24 1c 65 10 c0 movl $0xc010651c,(%esp) +c0101c13: e8 4e e7 ff ff call c0100366 + cprintf(" esi 0x%08x\n", regs->reg_esi); +c0101c18: 8b 45 08 mov 0x8(%ebp),%eax +c0101c1b: 8b 40 04 mov 0x4(%eax),%eax +c0101c1e: 89 44 24 04 mov %eax,0x4(%esp) +c0101c22: c7 04 24 2b 65 10 c0 movl $0xc010652b,(%esp) +c0101c29: e8 38 e7 ff ff call c0100366 + cprintf(" ebp 0x%08x\n", regs->reg_ebp); +c0101c2e: 8b 45 08 mov 0x8(%ebp),%eax +c0101c31: 8b 40 08 mov 0x8(%eax),%eax +c0101c34: 89 44 24 04 mov %eax,0x4(%esp) +c0101c38: c7 04 24 3a 65 10 c0 movl $0xc010653a,(%esp) +c0101c3f: e8 22 e7 ff ff call c0100366 + cprintf(" oesp 0x%08x\n", regs->reg_oesp); +c0101c44: 8b 45 08 mov 0x8(%ebp),%eax +c0101c47: 8b 40 0c mov 0xc(%eax),%eax +c0101c4a: 89 44 24 04 mov %eax,0x4(%esp) +c0101c4e: c7 04 24 49 65 10 c0 movl $0xc0106549,(%esp) +c0101c55: e8 0c e7 ff ff call c0100366 + cprintf(" ebx 0x%08x\n", regs->reg_ebx); +c0101c5a: 8b 45 08 mov 0x8(%ebp),%eax +c0101c5d: 8b 40 10 mov 0x10(%eax),%eax +c0101c60: 89 44 24 04 mov %eax,0x4(%esp) +c0101c64: c7 04 24 58 65 10 c0 movl $0xc0106558,(%esp) +c0101c6b: e8 f6 e6 ff ff call c0100366 + cprintf(" edx 0x%08x\n", regs->reg_edx); +c0101c70: 8b 45 08 mov 0x8(%ebp),%eax +c0101c73: 8b 40 14 mov 0x14(%eax),%eax +c0101c76: 89 44 24 04 mov %eax,0x4(%esp) +c0101c7a: c7 04 24 67 65 10 c0 movl $0xc0106567,(%esp) +c0101c81: e8 e0 e6 ff ff call c0100366 + cprintf(" ecx 0x%08x\n", regs->reg_ecx); +c0101c86: 8b 45 08 mov 0x8(%ebp),%eax +c0101c89: 8b 40 18 mov 0x18(%eax),%eax +c0101c8c: 89 44 24 04 mov %eax,0x4(%esp) +c0101c90: c7 04 24 76 65 10 c0 movl $0xc0106576,(%esp) +c0101c97: e8 ca e6 ff ff call c0100366 + cprintf(" eax 0x%08x\n", regs->reg_eax); +c0101c9c: 8b 45 08 mov 0x8(%ebp),%eax +c0101c9f: 8b 40 1c mov 0x1c(%eax),%eax +c0101ca2: 89 44 24 04 mov %eax,0x4(%esp) +c0101ca6: c7 04 24 85 65 10 c0 movl $0xc0106585,(%esp) +c0101cad: e8 b4 e6 ff ff call c0100366 +} +c0101cb2: 90 nop +c0101cb3: 89 ec mov %ebp,%esp +c0101cb5: 5d pop %ebp +c0101cb6: c3 ret + +c0101cb7 : + +struct trapframe switchk2u, *switchu2k; +/* trap_dispatch - dispatch based on what type of trap occurred */ +static void +trap_dispatch(struct trapframe *tf) { +c0101cb7: 55 push %ebp +c0101cb8: 89 e5 mov %esp,%ebp +c0101cba: 83 ec 28 sub $0x28,%esp +c0101cbd: 89 5d fc mov %ebx,-0x4(%ebp) + char c; + + switch (tf->tf_trapno) { +c0101cc0: 8b 45 08 mov 0x8(%ebp),%eax +c0101cc3: 8b 40 30 mov 0x30(%eax),%eax +c0101cc6: 83 f8 79 cmp $0x79,%eax +c0101cc9: 0f 84 6c 01 00 00 je c0101e3b +c0101ccf: 83 f8 79 cmp $0x79,%eax +c0101cd2: 0f 87 e0 01 00 00 ja c0101eb8 +c0101cd8: 83 f8 78 cmp $0x78,%eax +c0101cdb: 0f 84 d0 00 00 00 je c0101db1 +c0101ce1: 83 f8 78 cmp $0x78,%eax +c0101ce4: 0f 87 ce 01 00 00 ja c0101eb8 +c0101cea: 83 f8 2f cmp $0x2f,%eax +c0101ced: 0f 87 c5 01 00 00 ja c0101eb8 +c0101cf3: 83 f8 2e cmp $0x2e,%eax +c0101cf6: 0f 83 f1 01 00 00 jae c0101eed +c0101cfc: 83 f8 24 cmp $0x24,%eax +c0101cff: 74 5e je c0101d5f +c0101d01: 83 f8 24 cmp $0x24,%eax +c0101d04: 0f 87 ae 01 00 00 ja c0101eb8 +c0101d0a: 83 f8 20 cmp $0x20,%eax +c0101d0d: 74 0a je c0101d19 +c0101d0f: 83 f8 21 cmp $0x21,%eax +c0101d12: 74 74 je c0101d88 +c0101d14: e9 9f 01 00 00 jmp c0101eb8 + /* handle the timer interrupt */ + /* (1) After a timer interrupt, you should record this event using a global variable (increase it), such as ticks in kern/driver/clock.c + * (2) Every TICK_NUM cycle, you can print some info using a funciton, such as print_ticks(). + * (3) Too Simple? Yes, I think so! + */ + ticks ++; //记录中断事件 +c0101d19: a1 24 c4 11 c0 mov 0xc011c424,%eax +c0101d1e: 40 inc %eax +c0101d1f: a3 24 c4 11 c0 mov %eax,0xc011c424 + if (ticks % TICK_NUM == 0) +c0101d24: 8b 0d 24 c4 11 c0 mov 0xc011c424,%ecx +c0101d2a: ba 1f 85 eb 51 mov $0x51eb851f,%edx +c0101d2f: 89 c8 mov %ecx,%eax +c0101d31: f7 e2 mul %edx +c0101d33: c1 ea 05 shr $0x5,%edx +c0101d36: 89 d0 mov %edx,%eax +c0101d38: c1 e0 02 shl $0x2,%eax +c0101d3b: 01 d0 add %edx,%eax +c0101d3d: 8d 14 85 00 00 00 00 lea 0x0(,%eax,4),%edx +c0101d44: 01 d0 add %edx,%eax +c0101d46: c1 e0 02 shl $0x2,%eax +c0101d49: 29 c1 sub %eax,%ecx +c0101d4b: 89 ca mov %ecx,%edx +c0101d4d: 85 d2 test %edx,%edx +c0101d4f: 0f 85 9b 01 00 00 jne c0101ef0 + { + print_ticks(); +c0101d55: e8 16 fb ff ff call c0101870 + }//每经过 TICK_NUM 次周期时,调用 print_ticks() 打印信息。 + break; +c0101d5a: e9 91 01 00 00 jmp c0101ef0 + case IRQ_OFFSET + IRQ_COM1: + c = cons_getc(); +c0101d5f: e8 af f8 ff ff call c0101613 +c0101d64: 88 45 f7 mov %al,-0x9(%ebp) + cprintf("serial [%03d] %c\n", c, c); +c0101d67: 0f be 55 f7 movsbl -0x9(%ebp),%edx +c0101d6b: 0f be 45 f7 movsbl -0x9(%ebp),%eax +c0101d6f: 89 54 24 08 mov %edx,0x8(%esp) +c0101d73: 89 44 24 04 mov %eax,0x4(%esp) +c0101d77: c7 04 24 94 65 10 c0 movl $0xc0106594,(%esp) +c0101d7e: e8 e3 e5 ff ff call c0100366 + break; +c0101d83: e9 6f 01 00 00 jmp c0101ef7 + case IRQ_OFFSET + IRQ_KBD: + c = cons_getc(); +c0101d88: e8 86 f8 ff ff call c0101613 +c0101d8d: 88 45 f7 mov %al,-0x9(%ebp) + cprintf("kbd [%03d] %c\n", c, c); +c0101d90: 0f be 55 f7 movsbl -0x9(%ebp),%edx +c0101d94: 0f be 45 f7 movsbl -0x9(%ebp),%eax +c0101d98: 89 54 24 08 mov %edx,0x8(%esp) +c0101d9c: 89 44 24 04 mov %eax,0x4(%esp) +c0101da0: c7 04 24 a6 65 10 c0 movl $0xc01065a6,(%esp) +c0101da7: e8 ba e5 ff ff call c0100366 + break; +c0101dac: e9 46 01 00 00 jmp c0101ef7 + //LAB1 CHALLENGE 1 : YOUR CODE you should modify below codes. + case T_SWITCH_TOU://表示发生了从内核模式切换到用户模式的请求。 + if (tf->tf_cs != USER_CS) {//判断当前是否在内核模式下 +c0101db1: 8b 45 08 mov 0x8(%ebp),%eax +c0101db4: 0f b7 40 3c movzwl 0x3c(%eax),%eax +c0101db8: 83 f8 1b cmp $0x1b,%eax +c0101dbb: 0f 84 32 01 00 00 je c0101ef3 + switchk2u = *tf; //保存当前陷阱框架 +c0101dc1: 8b 4d 08 mov 0x8(%ebp),%ecx +c0101dc4: b8 4c 00 00 00 mov $0x4c,%eax +c0101dc9: 83 e0 fc and $0xfffffffc,%eax +c0101dcc: 89 c3 mov %eax,%ebx +c0101dce: b8 00 00 00 00 mov $0x0,%eax +c0101dd3: 8b 14 01 mov (%ecx,%eax,1),%edx +c0101dd6: 89 90 80 c6 11 c0 mov %edx,-0x3fee3980(%eax) +c0101ddc: 83 c0 04 add $0x4,%eax +c0101ddf: 39 d8 cmp %ebx,%eax +c0101de1: 72 f0 jb c0101dd3 + switchk2u.tf_cs = USER_CS;//设置用户模式的段寄存器 +c0101de3: 66 c7 05 bc c6 11 c0 movw $0x1b,0xc011c6bc +c0101dea: 1b 00 + //将数据段和栈段寄存器 都设置为 USER_DS(用户数据段) + switchk2u.tf_ds = switchk2u.tf_es = switchk2u.tf_ss = USER_DS; +c0101dec: 66 c7 05 c8 c6 11 c0 movw $0x23,0xc011c6c8 +c0101df3: 23 00 +c0101df5: 0f b7 05 c8 c6 11 c0 movzwl 0xc011c6c8,%eax +c0101dfc: 66 a3 a8 c6 11 c0 mov %ax,0xc011c6a8 +c0101e02: 0f b7 05 a8 c6 11 c0 movzwl 0xc011c6a8,%eax +c0101e09: 66 a3 ac c6 11 c0 mov %ax,0xc011c6ac + switchk2u.tf_esp = (uint32_t)tf + sizeof(struct trapframe) - 8; +c0101e0f: 8b 45 08 mov 0x8(%ebp),%eax +c0101e12: 83 c0 44 add $0x44,%eax +c0101e15: a3 c4 c6 11 c0 mov %eax,0xc011c6c4 + + // set eflags, make sure ucore can use io under user mode. + // if CPL > IOPL, then cpu will generate a general protection. + switchk2u.tf_eflags |= FL_IOPL_MASK;//允许用户模式下进行 I/O 操作 +c0101e1a: a1 c0 c6 11 c0 mov 0xc011c6c0,%eax +c0101e1f: 0d 00 30 00 00 or $0x3000,%eax +c0101e24: a3 c0 c6 11 c0 mov %eax,0xc011c6c0 + + // set temporary stack + // then iret will jump to the right stack + *((uint32_t *)tf - 1) = (uint32_t)&switchk2u; +c0101e29: 8b 45 08 mov 0x8(%ebp),%eax +c0101e2c: 83 e8 04 sub $0x4,%eax +c0101e2f: ba 80 c6 11 c0 mov $0xc011c680,%edx +c0101e34: 89 10 mov %edx,(%eax) + } + break; +c0101e36: e9 b8 00 00 00 jmp c0101ef3 + case T_SWITCH_TOK: // T_SWITCH_TOK 表示发生了从用户模式切换到内核模式的请求。 + if (tf->tf_cs != KERNEL_CS) { //判断当前是否在用户模式下 +c0101e3b: 8b 45 08 mov 0x8(%ebp),%eax +c0101e3e: 0f b7 40 3c movzwl 0x3c(%eax),%eax +c0101e42: 83 f8 08 cmp $0x8,%eax +c0101e45: 0f 84 ab 00 00 00 je c0101ef6 + tf->tf_cs = KERNEL_CS; +c0101e4b: 8b 45 08 mov 0x8(%ebp),%eax +c0101e4e: 66 c7 40 3c 08 00 movw $0x8,0x3c(%eax) + tf->tf_ds = tf->tf_es = KERNEL_DS; +c0101e54: 8b 45 08 mov 0x8(%ebp),%eax +c0101e57: 66 c7 40 28 10 00 movw $0x10,0x28(%eax) +c0101e5d: 8b 45 08 mov 0x8(%ebp),%eax +c0101e60: 0f b7 50 28 movzwl 0x28(%eax),%edx +c0101e64: 8b 45 08 mov 0x8(%ebp),%eax +c0101e67: 66 89 50 2c mov %dx,0x2c(%eax) + //设置内核模式的段寄存器 + tf->tf_eflags &= ~FL_IOPL_MASK; //清除 I/O 权限标志 +c0101e6b: 8b 45 08 mov 0x8(%ebp),%eax +c0101e6e: 8b 40 40 mov 0x40(%eax),%eax +c0101e71: 25 ff cf ff ff and $0xffffcfff,%eax +c0101e76: 89 c2 mov %eax,%edx +c0101e78: 8b 45 08 mov 0x8(%ebp),%eax +c0101e7b: 89 50 40 mov %edx,0x40(%eax) + switchu2k = (struct trapframe *)(tf->tf_esp - (sizeof(struct trapframe) - 8)); +c0101e7e: 8b 45 08 mov 0x8(%ebp),%eax +c0101e81: 8b 40 44 mov 0x44(%eax),%eax +c0101e84: 83 e8 44 sub $0x44,%eax +c0101e87: a3 cc c6 11 c0 mov %eax,0xc011c6cc + //使用 memmove 将当前的陷阱框架(除了最后8个字节)复制到新的陷阱框架位置 switchu2k + memmove(switchu2k, tf, sizeof(struct trapframe) - 8); +c0101e8c: a1 cc c6 11 c0 mov 0xc011c6cc,%eax +c0101e91: c7 44 24 08 44 00 00 movl $0x44,0x8(%esp) +c0101e98: 00 +c0101e99: 8b 55 08 mov 0x8(%ebp),%edx +c0101e9c: 89 54 24 04 mov %edx,0x4(%esp) +c0101ea0: 89 04 24 mov %eax,(%esp) +c0101ea3: e8 a2 40 00 00 call c0105f4a + //将新的陷阱框架地址 switchu2k 存储到当前陷阱框架之前的一个栈位置 + *((uint32_t *)tf - 1) = (uint32_t)switchu2k; +c0101ea8: 8b 15 cc c6 11 c0 mov 0xc011c6cc,%edx +c0101eae: 8b 45 08 mov 0x8(%ebp),%eax +c0101eb1: 83 e8 04 sub $0x4,%eax +c0101eb4: 89 10 mov %edx,(%eax) + } + break; +c0101eb6: eb 3e jmp c0101ef6 + case IRQ_OFFSET + IRQ_IDE2: + /* do nothing */ + break; + default: + // in kernel, it must be a mistake + if ((tf->tf_cs & 3) == 0) { +c0101eb8: 8b 45 08 mov 0x8(%ebp),%eax +c0101ebb: 0f b7 40 3c movzwl 0x3c(%eax),%eax +c0101ebf: 83 e0 03 and $0x3,%eax +c0101ec2: 85 c0 test %eax,%eax +c0101ec4: 75 31 jne c0101ef7 + print_trapframe(tf); +c0101ec6: 8b 45 08 mov 0x8(%ebp),%eax +c0101ec9: 89 04 24 mov %eax,(%esp) +c0101ecc: e8 79 fb ff ff call c0101a4a + panic("unexpected trap in kernel.\n"); +c0101ed1: c7 44 24 08 b5 65 10 movl $0xc01065b5,0x8(%esp) +c0101ed8: c0 +c0101ed9: c7 44 24 04 dc 00 00 movl $0xdc,0x4(%esp) +c0101ee0: 00 +c0101ee1: c7 04 24 d1 65 10 c0 movl $0xc01065d1,(%esp) +c0101ee8: e8 46 ed ff ff call c0100c33 <__panic> + break; +c0101eed: 90 nop +c0101eee: eb 07 jmp c0101ef7 + break; +c0101ef0: 90 nop +c0101ef1: eb 04 jmp c0101ef7 + break; +c0101ef3: 90 nop +c0101ef4: eb 01 jmp c0101ef7 + break; +c0101ef6: 90 nop + } + } +} +c0101ef7: 90 nop +c0101ef8: 8b 5d fc mov -0x4(%ebp),%ebx +c0101efb: 89 ec mov %ebp,%esp +c0101efd: 5d pop %ebp +c0101efe: c3 ret + +c0101eff : + * 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) { +c0101eff: 55 push %ebp +c0101f00: 89 e5 mov %esp,%ebp +c0101f02: 83 ec 18 sub $0x18,%esp + // dispatch based on what type of trap occurred + trap_dispatch(tf); +c0101f05: 8b 45 08 mov 0x8(%ebp),%eax +c0101f08: 89 04 24 mov %eax,(%esp) +c0101f0b: e8 a7 fd ff ff call c0101cb7 +} +c0101f10: 90 nop +c0101f11: 89 ec mov %ebp,%esp +c0101f13: 5d pop %ebp +c0101f14: c3 ret + +c0101f15 <__alltraps>: +.text +.globl __alltraps +__alltraps: + # push registers to build a trap frame + # therefore make the stack look like a struct trapframe + pushl %ds +c0101f15: 1e push %ds + pushl %es +c0101f16: 06 push %es + pushl %fs +c0101f17: 0f a0 push %fs + pushl %gs +c0101f19: 0f a8 push %gs + pushal +c0101f1b: 60 pusha + + # load GD_KDATA into %ds and %es to set up data segments for kernel + movl $GD_KDATA, %eax +c0101f1c: b8 10 00 00 00 mov $0x10,%eax + movw %ax, %ds +c0101f21: 8e d8 mov %eax,%ds + movw %ax, %es +c0101f23: 8e c0 mov %eax,%es + + # push %esp to pass a pointer to the trapframe as an argument to trap() + pushl %esp +c0101f25: 54 push %esp + + # call trap(tf), where tf=%esp + call trap +c0101f26: e8 d4 ff ff ff call c0101eff + + # pop the pushed stack pointer + popl %esp +c0101f2b: 5c pop %esp + +c0101f2c <__trapret>: + + # return falls through to trapret... +.globl __trapret +__trapret: + # restore registers from stack + popal +c0101f2c: 61 popa + + # restore %ds, %es, %fs and %gs + popl %gs +c0101f2d: 0f a9 pop %gs + popl %fs +c0101f2f: 0f a1 pop %fs + popl %es +c0101f31: 07 pop %es + popl %ds +c0101f32: 1f pop %ds + + # get rid of the trap number and error code + addl $0x8, %esp +c0101f33: 83 c4 08 add $0x8,%esp + iret +c0101f36: cf iret + +c0101f37 : +# handler +.text +.globl __alltraps +.globl vector0 +vector0: + pushl $0 +c0101f37: 6a 00 push $0x0 + pushl $0 +c0101f39: 6a 00 push $0x0 + jmp __alltraps +c0101f3b: e9 d5 ff ff ff jmp c0101f15 <__alltraps> + +c0101f40 : +.globl vector1 +vector1: + pushl $0 +c0101f40: 6a 00 push $0x0 + pushl $1 +c0101f42: 6a 01 push $0x1 + jmp __alltraps +c0101f44: e9 cc ff ff ff jmp c0101f15 <__alltraps> + +c0101f49 : +.globl vector2 +vector2: + pushl $0 +c0101f49: 6a 00 push $0x0 + pushl $2 +c0101f4b: 6a 02 push $0x2 + jmp __alltraps +c0101f4d: e9 c3 ff ff ff jmp c0101f15 <__alltraps> + +c0101f52 : +.globl vector3 +vector3: + pushl $0 +c0101f52: 6a 00 push $0x0 + pushl $3 +c0101f54: 6a 03 push $0x3 + jmp __alltraps +c0101f56: e9 ba ff ff ff jmp c0101f15 <__alltraps> + +c0101f5b : +.globl vector4 +vector4: + pushl $0 +c0101f5b: 6a 00 push $0x0 + pushl $4 +c0101f5d: 6a 04 push $0x4 + jmp __alltraps +c0101f5f: e9 b1 ff ff ff jmp c0101f15 <__alltraps> + +c0101f64 : +.globl vector5 +vector5: + pushl $0 +c0101f64: 6a 00 push $0x0 + pushl $5 +c0101f66: 6a 05 push $0x5 + jmp __alltraps +c0101f68: e9 a8 ff ff ff jmp c0101f15 <__alltraps> + +c0101f6d : +.globl vector6 +vector6: + pushl $0 +c0101f6d: 6a 00 push $0x0 + pushl $6 +c0101f6f: 6a 06 push $0x6 + jmp __alltraps +c0101f71: e9 9f ff ff ff jmp c0101f15 <__alltraps> + +c0101f76 : +.globl vector7 +vector7: + pushl $0 +c0101f76: 6a 00 push $0x0 + pushl $7 +c0101f78: 6a 07 push $0x7 + jmp __alltraps +c0101f7a: e9 96 ff ff ff jmp c0101f15 <__alltraps> + +c0101f7f : +.globl vector8 +vector8: + pushl $8 +c0101f7f: 6a 08 push $0x8 + jmp __alltraps +c0101f81: e9 8f ff ff ff jmp c0101f15 <__alltraps> + +c0101f86 : +.globl vector9 +vector9: + pushl $0 +c0101f86: 6a 00 push $0x0 + pushl $9 +c0101f88: 6a 09 push $0x9 + jmp __alltraps +c0101f8a: e9 86 ff ff ff jmp c0101f15 <__alltraps> + +c0101f8f : +.globl vector10 +vector10: + pushl $10 +c0101f8f: 6a 0a push $0xa + jmp __alltraps +c0101f91: e9 7f ff ff ff jmp c0101f15 <__alltraps> + +c0101f96 : +.globl vector11 +vector11: + pushl $11 +c0101f96: 6a 0b push $0xb + jmp __alltraps +c0101f98: e9 78 ff ff ff jmp c0101f15 <__alltraps> + +c0101f9d : +.globl vector12 +vector12: + pushl $12 +c0101f9d: 6a 0c push $0xc + jmp __alltraps +c0101f9f: e9 71 ff ff ff jmp c0101f15 <__alltraps> + +c0101fa4 : +.globl vector13 +vector13: + pushl $13 +c0101fa4: 6a 0d push $0xd + jmp __alltraps +c0101fa6: e9 6a ff ff ff jmp c0101f15 <__alltraps> + +c0101fab : +.globl vector14 +vector14: + pushl $14 +c0101fab: 6a 0e push $0xe + jmp __alltraps +c0101fad: e9 63 ff ff ff jmp c0101f15 <__alltraps> + +c0101fb2 : +.globl vector15 +vector15: + pushl $0 +c0101fb2: 6a 00 push $0x0 + pushl $15 +c0101fb4: 6a 0f push $0xf + jmp __alltraps +c0101fb6: e9 5a ff ff ff jmp c0101f15 <__alltraps> + +c0101fbb : +.globl vector16 +vector16: + pushl $0 +c0101fbb: 6a 00 push $0x0 + pushl $16 +c0101fbd: 6a 10 push $0x10 + jmp __alltraps +c0101fbf: e9 51 ff ff ff jmp c0101f15 <__alltraps> + +c0101fc4 : +.globl vector17 +vector17: + pushl $17 +c0101fc4: 6a 11 push $0x11 + jmp __alltraps +c0101fc6: e9 4a ff ff ff jmp c0101f15 <__alltraps> + +c0101fcb : +.globl vector18 +vector18: + pushl $0 +c0101fcb: 6a 00 push $0x0 + pushl $18 +c0101fcd: 6a 12 push $0x12 + jmp __alltraps +c0101fcf: e9 41 ff ff ff jmp c0101f15 <__alltraps> + +c0101fd4 : +.globl vector19 +vector19: + pushl $0 +c0101fd4: 6a 00 push $0x0 + pushl $19 +c0101fd6: 6a 13 push $0x13 + jmp __alltraps +c0101fd8: e9 38 ff ff ff jmp c0101f15 <__alltraps> + +c0101fdd : +.globl vector20 +vector20: + pushl $0 +c0101fdd: 6a 00 push $0x0 + pushl $20 +c0101fdf: 6a 14 push $0x14 + jmp __alltraps +c0101fe1: e9 2f ff ff ff jmp c0101f15 <__alltraps> + +c0101fe6 : +.globl vector21 +vector21: + pushl $0 +c0101fe6: 6a 00 push $0x0 + pushl $21 +c0101fe8: 6a 15 push $0x15 + jmp __alltraps +c0101fea: e9 26 ff ff ff jmp c0101f15 <__alltraps> + +c0101fef : +.globl vector22 +vector22: + pushl $0 +c0101fef: 6a 00 push $0x0 + pushl $22 +c0101ff1: 6a 16 push $0x16 + jmp __alltraps +c0101ff3: e9 1d ff ff ff jmp c0101f15 <__alltraps> + +c0101ff8 : +.globl vector23 +vector23: + pushl $0 +c0101ff8: 6a 00 push $0x0 + pushl $23 +c0101ffa: 6a 17 push $0x17 + jmp __alltraps +c0101ffc: e9 14 ff ff ff jmp c0101f15 <__alltraps> + +c0102001 : +.globl vector24 +vector24: + pushl $0 +c0102001: 6a 00 push $0x0 + pushl $24 +c0102003: 6a 18 push $0x18 + jmp __alltraps +c0102005: e9 0b ff ff ff jmp c0101f15 <__alltraps> + +c010200a : +.globl vector25 +vector25: + pushl $0 +c010200a: 6a 00 push $0x0 + pushl $25 +c010200c: 6a 19 push $0x19 + jmp __alltraps +c010200e: e9 02 ff ff ff jmp c0101f15 <__alltraps> + +c0102013 : +.globl vector26 +vector26: + pushl $0 +c0102013: 6a 00 push $0x0 + pushl $26 +c0102015: 6a 1a push $0x1a + jmp __alltraps +c0102017: e9 f9 fe ff ff jmp c0101f15 <__alltraps> + +c010201c : +.globl vector27 +vector27: + pushl $0 +c010201c: 6a 00 push $0x0 + pushl $27 +c010201e: 6a 1b push $0x1b + jmp __alltraps +c0102020: e9 f0 fe ff ff jmp c0101f15 <__alltraps> + +c0102025 : +.globl vector28 +vector28: + pushl $0 +c0102025: 6a 00 push $0x0 + pushl $28 +c0102027: 6a 1c push $0x1c + jmp __alltraps +c0102029: e9 e7 fe ff ff jmp c0101f15 <__alltraps> + +c010202e : +.globl vector29 +vector29: + pushl $0 +c010202e: 6a 00 push $0x0 + pushl $29 +c0102030: 6a 1d push $0x1d + jmp __alltraps +c0102032: e9 de fe ff ff jmp c0101f15 <__alltraps> + +c0102037 : +.globl vector30 +vector30: + pushl $0 +c0102037: 6a 00 push $0x0 + pushl $30 +c0102039: 6a 1e push $0x1e + jmp __alltraps +c010203b: e9 d5 fe ff ff jmp c0101f15 <__alltraps> + +c0102040 : +.globl vector31 +vector31: + pushl $0 +c0102040: 6a 00 push $0x0 + pushl $31 +c0102042: 6a 1f push $0x1f + jmp __alltraps +c0102044: e9 cc fe ff ff jmp c0101f15 <__alltraps> + +c0102049 : +.globl vector32 +vector32: + pushl $0 +c0102049: 6a 00 push $0x0 + pushl $32 +c010204b: 6a 20 push $0x20 + jmp __alltraps +c010204d: e9 c3 fe ff ff jmp c0101f15 <__alltraps> + +c0102052 : +.globl vector33 +vector33: + pushl $0 +c0102052: 6a 00 push $0x0 + pushl $33 +c0102054: 6a 21 push $0x21 + jmp __alltraps +c0102056: e9 ba fe ff ff jmp c0101f15 <__alltraps> + +c010205b : +.globl vector34 +vector34: + pushl $0 +c010205b: 6a 00 push $0x0 + pushl $34 +c010205d: 6a 22 push $0x22 + jmp __alltraps +c010205f: e9 b1 fe ff ff jmp c0101f15 <__alltraps> + +c0102064 : +.globl vector35 +vector35: + pushl $0 +c0102064: 6a 00 push $0x0 + pushl $35 +c0102066: 6a 23 push $0x23 + jmp __alltraps +c0102068: e9 a8 fe ff ff jmp c0101f15 <__alltraps> + +c010206d : +.globl vector36 +vector36: + pushl $0 +c010206d: 6a 00 push $0x0 + pushl $36 +c010206f: 6a 24 push $0x24 + jmp __alltraps +c0102071: e9 9f fe ff ff jmp c0101f15 <__alltraps> + +c0102076 : +.globl vector37 +vector37: + pushl $0 +c0102076: 6a 00 push $0x0 + pushl $37 +c0102078: 6a 25 push $0x25 + jmp __alltraps +c010207a: e9 96 fe ff ff jmp c0101f15 <__alltraps> + +c010207f : +.globl vector38 +vector38: + pushl $0 +c010207f: 6a 00 push $0x0 + pushl $38 +c0102081: 6a 26 push $0x26 + jmp __alltraps +c0102083: e9 8d fe ff ff jmp c0101f15 <__alltraps> + +c0102088 : +.globl vector39 +vector39: + pushl $0 +c0102088: 6a 00 push $0x0 + pushl $39 +c010208a: 6a 27 push $0x27 + jmp __alltraps +c010208c: e9 84 fe ff ff jmp c0101f15 <__alltraps> + +c0102091 : +.globl vector40 +vector40: + pushl $0 +c0102091: 6a 00 push $0x0 + pushl $40 +c0102093: 6a 28 push $0x28 + jmp __alltraps +c0102095: e9 7b fe ff ff jmp c0101f15 <__alltraps> + +c010209a : +.globl vector41 +vector41: + pushl $0 +c010209a: 6a 00 push $0x0 + pushl $41 +c010209c: 6a 29 push $0x29 + jmp __alltraps +c010209e: e9 72 fe ff ff jmp c0101f15 <__alltraps> + +c01020a3 : +.globl vector42 +vector42: + pushl $0 +c01020a3: 6a 00 push $0x0 + pushl $42 +c01020a5: 6a 2a push $0x2a + jmp __alltraps +c01020a7: e9 69 fe ff ff jmp c0101f15 <__alltraps> + +c01020ac : +.globl vector43 +vector43: + pushl $0 +c01020ac: 6a 00 push $0x0 + pushl $43 +c01020ae: 6a 2b push $0x2b + jmp __alltraps +c01020b0: e9 60 fe ff ff jmp c0101f15 <__alltraps> + +c01020b5 : +.globl vector44 +vector44: + pushl $0 +c01020b5: 6a 00 push $0x0 + pushl $44 +c01020b7: 6a 2c push $0x2c + jmp __alltraps +c01020b9: e9 57 fe ff ff jmp c0101f15 <__alltraps> + +c01020be : +.globl vector45 +vector45: + pushl $0 +c01020be: 6a 00 push $0x0 + pushl $45 +c01020c0: 6a 2d push $0x2d + jmp __alltraps +c01020c2: e9 4e fe ff ff jmp c0101f15 <__alltraps> + +c01020c7 : +.globl vector46 +vector46: + pushl $0 +c01020c7: 6a 00 push $0x0 + pushl $46 +c01020c9: 6a 2e push $0x2e + jmp __alltraps +c01020cb: e9 45 fe ff ff jmp c0101f15 <__alltraps> + +c01020d0 : +.globl vector47 +vector47: + pushl $0 +c01020d0: 6a 00 push $0x0 + pushl $47 +c01020d2: 6a 2f push $0x2f + jmp __alltraps +c01020d4: e9 3c fe ff ff jmp c0101f15 <__alltraps> + +c01020d9 : +.globl vector48 +vector48: + pushl $0 +c01020d9: 6a 00 push $0x0 + pushl $48 +c01020db: 6a 30 push $0x30 + jmp __alltraps +c01020dd: e9 33 fe ff ff jmp c0101f15 <__alltraps> + +c01020e2 : +.globl vector49 +vector49: + pushl $0 +c01020e2: 6a 00 push $0x0 + pushl $49 +c01020e4: 6a 31 push $0x31 + jmp __alltraps +c01020e6: e9 2a fe ff ff jmp c0101f15 <__alltraps> + +c01020eb : +.globl vector50 +vector50: + pushl $0 +c01020eb: 6a 00 push $0x0 + pushl $50 +c01020ed: 6a 32 push $0x32 + jmp __alltraps +c01020ef: e9 21 fe ff ff jmp c0101f15 <__alltraps> + +c01020f4 : +.globl vector51 +vector51: + pushl $0 +c01020f4: 6a 00 push $0x0 + pushl $51 +c01020f6: 6a 33 push $0x33 + jmp __alltraps +c01020f8: e9 18 fe ff ff jmp c0101f15 <__alltraps> + +c01020fd : +.globl vector52 +vector52: + pushl $0 +c01020fd: 6a 00 push $0x0 + pushl $52 +c01020ff: 6a 34 push $0x34 + jmp __alltraps +c0102101: e9 0f fe ff ff jmp c0101f15 <__alltraps> + +c0102106 : +.globl vector53 +vector53: + pushl $0 +c0102106: 6a 00 push $0x0 + pushl $53 +c0102108: 6a 35 push $0x35 + jmp __alltraps +c010210a: e9 06 fe ff ff jmp c0101f15 <__alltraps> + +c010210f : +.globl vector54 +vector54: + pushl $0 +c010210f: 6a 00 push $0x0 + pushl $54 +c0102111: 6a 36 push $0x36 + jmp __alltraps +c0102113: e9 fd fd ff ff jmp c0101f15 <__alltraps> + +c0102118 : +.globl vector55 +vector55: + pushl $0 +c0102118: 6a 00 push $0x0 + pushl $55 +c010211a: 6a 37 push $0x37 + jmp __alltraps +c010211c: e9 f4 fd ff ff jmp c0101f15 <__alltraps> + +c0102121 : +.globl vector56 +vector56: + pushl $0 +c0102121: 6a 00 push $0x0 + pushl $56 +c0102123: 6a 38 push $0x38 + jmp __alltraps +c0102125: e9 eb fd ff ff jmp c0101f15 <__alltraps> + +c010212a : +.globl vector57 +vector57: + pushl $0 +c010212a: 6a 00 push $0x0 + pushl $57 +c010212c: 6a 39 push $0x39 + jmp __alltraps +c010212e: e9 e2 fd ff ff jmp c0101f15 <__alltraps> + +c0102133 : +.globl vector58 +vector58: + pushl $0 +c0102133: 6a 00 push $0x0 + pushl $58 +c0102135: 6a 3a push $0x3a + jmp __alltraps +c0102137: e9 d9 fd ff ff jmp c0101f15 <__alltraps> + +c010213c : +.globl vector59 +vector59: + pushl $0 +c010213c: 6a 00 push $0x0 + pushl $59 +c010213e: 6a 3b push $0x3b + jmp __alltraps +c0102140: e9 d0 fd ff ff jmp c0101f15 <__alltraps> + +c0102145 : +.globl vector60 +vector60: + pushl $0 +c0102145: 6a 00 push $0x0 + pushl $60 +c0102147: 6a 3c push $0x3c + jmp __alltraps +c0102149: e9 c7 fd ff ff jmp c0101f15 <__alltraps> + +c010214e : +.globl vector61 +vector61: + pushl $0 +c010214e: 6a 00 push $0x0 + pushl $61 +c0102150: 6a 3d push $0x3d + jmp __alltraps +c0102152: e9 be fd ff ff jmp c0101f15 <__alltraps> + +c0102157 : +.globl vector62 +vector62: + pushl $0 +c0102157: 6a 00 push $0x0 + pushl $62 +c0102159: 6a 3e push $0x3e + jmp __alltraps +c010215b: e9 b5 fd ff ff jmp c0101f15 <__alltraps> + +c0102160 : +.globl vector63 +vector63: + pushl $0 +c0102160: 6a 00 push $0x0 + pushl $63 +c0102162: 6a 3f push $0x3f + jmp __alltraps +c0102164: e9 ac fd ff ff jmp c0101f15 <__alltraps> + +c0102169 : +.globl vector64 +vector64: + pushl $0 +c0102169: 6a 00 push $0x0 + pushl $64 +c010216b: 6a 40 push $0x40 + jmp __alltraps +c010216d: e9 a3 fd ff ff jmp c0101f15 <__alltraps> + +c0102172 : +.globl vector65 +vector65: + pushl $0 +c0102172: 6a 00 push $0x0 + pushl $65 +c0102174: 6a 41 push $0x41 + jmp __alltraps +c0102176: e9 9a fd ff ff jmp c0101f15 <__alltraps> + +c010217b : +.globl vector66 +vector66: + pushl $0 +c010217b: 6a 00 push $0x0 + pushl $66 +c010217d: 6a 42 push $0x42 + jmp __alltraps +c010217f: e9 91 fd ff ff jmp c0101f15 <__alltraps> + +c0102184 : +.globl vector67 +vector67: + pushl $0 +c0102184: 6a 00 push $0x0 + pushl $67 +c0102186: 6a 43 push $0x43 + jmp __alltraps +c0102188: e9 88 fd ff ff jmp c0101f15 <__alltraps> + +c010218d : +.globl vector68 +vector68: + pushl $0 +c010218d: 6a 00 push $0x0 + pushl $68 +c010218f: 6a 44 push $0x44 + jmp __alltraps +c0102191: e9 7f fd ff ff jmp c0101f15 <__alltraps> + +c0102196 : +.globl vector69 +vector69: + pushl $0 +c0102196: 6a 00 push $0x0 + pushl $69 +c0102198: 6a 45 push $0x45 + jmp __alltraps +c010219a: e9 76 fd ff ff jmp c0101f15 <__alltraps> + +c010219f : +.globl vector70 +vector70: + pushl $0 +c010219f: 6a 00 push $0x0 + pushl $70 +c01021a1: 6a 46 push $0x46 + jmp __alltraps +c01021a3: e9 6d fd ff ff jmp c0101f15 <__alltraps> + +c01021a8 : +.globl vector71 +vector71: + pushl $0 +c01021a8: 6a 00 push $0x0 + pushl $71 +c01021aa: 6a 47 push $0x47 + jmp __alltraps +c01021ac: e9 64 fd ff ff jmp c0101f15 <__alltraps> + +c01021b1 : +.globl vector72 +vector72: + pushl $0 +c01021b1: 6a 00 push $0x0 + pushl $72 +c01021b3: 6a 48 push $0x48 + jmp __alltraps +c01021b5: e9 5b fd ff ff jmp c0101f15 <__alltraps> + +c01021ba : +.globl vector73 +vector73: + pushl $0 +c01021ba: 6a 00 push $0x0 + pushl $73 +c01021bc: 6a 49 push $0x49 + jmp __alltraps +c01021be: e9 52 fd ff ff jmp c0101f15 <__alltraps> + +c01021c3 : +.globl vector74 +vector74: + pushl $0 +c01021c3: 6a 00 push $0x0 + pushl $74 +c01021c5: 6a 4a push $0x4a + jmp __alltraps +c01021c7: e9 49 fd ff ff jmp c0101f15 <__alltraps> + +c01021cc : +.globl vector75 +vector75: + pushl $0 +c01021cc: 6a 00 push $0x0 + pushl $75 +c01021ce: 6a 4b push $0x4b + jmp __alltraps +c01021d0: e9 40 fd ff ff jmp c0101f15 <__alltraps> + +c01021d5 : +.globl vector76 +vector76: + pushl $0 +c01021d5: 6a 00 push $0x0 + pushl $76 +c01021d7: 6a 4c push $0x4c + jmp __alltraps +c01021d9: e9 37 fd ff ff jmp c0101f15 <__alltraps> + +c01021de : +.globl vector77 +vector77: + pushl $0 +c01021de: 6a 00 push $0x0 + pushl $77 +c01021e0: 6a 4d push $0x4d + jmp __alltraps +c01021e2: e9 2e fd ff ff jmp c0101f15 <__alltraps> + +c01021e7 : +.globl vector78 +vector78: + pushl $0 +c01021e7: 6a 00 push $0x0 + pushl $78 +c01021e9: 6a 4e push $0x4e + jmp __alltraps +c01021eb: e9 25 fd ff ff jmp c0101f15 <__alltraps> + +c01021f0 : +.globl vector79 +vector79: + pushl $0 +c01021f0: 6a 00 push $0x0 + pushl $79 +c01021f2: 6a 4f push $0x4f + jmp __alltraps +c01021f4: e9 1c fd ff ff jmp c0101f15 <__alltraps> + +c01021f9 : +.globl vector80 +vector80: + pushl $0 +c01021f9: 6a 00 push $0x0 + pushl $80 +c01021fb: 6a 50 push $0x50 + jmp __alltraps +c01021fd: e9 13 fd ff ff jmp c0101f15 <__alltraps> + +c0102202 : +.globl vector81 +vector81: + pushl $0 +c0102202: 6a 00 push $0x0 + pushl $81 +c0102204: 6a 51 push $0x51 + jmp __alltraps +c0102206: e9 0a fd ff ff jmp c0101f15 <__alltraps> + +c010220b : +.globl vector82 +vector82: + pushl $0 +c010220b: 6a 00 push $0x0 + pushl $82 +c010220d: 6a 52 push $0x52 + jmp __alltraps +c010220f: e9 01 fd ff ff jmp c0101f15 <__alltraps> + +c0102214 : +.globl vector83 +vector83: + pushl $0 +c0102214: 6a 00 push $0x0 + pushl $83 +c0102216: 6a 53 push $0x53 + jmp __alltraps +c0102218: e9 f8 fc ff ff jmp c0101f15 <__alltraps> + +c010221d : +.globl vector84 +vector84: + pushl $0 +c010221d: 6a 00 push $0x0 + pushl $84 +c010221f: 6a 54 push $0x54 + jmp __alltraps +c0102221: e9 ef fc ff ff jmp c0101f15 <__alltraps> + +c0102226 : +.globl vector85 +vector85: + pushl $0 +c0102226: 6a 00 push $0x0 + pushl $85 +c0102228: 6a 55 push $0x55 + jmp __alltraps +c010222a: e9 e6 fc ff ff jmp c0101f15 <__alltraps> + +c010222f : +.globl vector86 +vector86: + pushl $0 +c010222f: 6a 00 push $0x0 + pushl $86 +c0102231: 6a 56 push $0x56 + jmp __alltraps +c0102233: e9 dd fc ff ff jmp c0101f15 <__alltraps> + +c0102238 : +.globl vector87 +vector87: + pushl $0 +c0102238: 6a 00 push $0x0 + pushl $87 +c010223a: 6a 57 push $0x57 + jmp __alltraps +c010223c: e9 d4 fc ff ff jmp c0101f15 <__alltraps> + +c0102241 : +.globl vector88 +vector88: + pushl $0 +c0102241: 6a 00 push $0x0 + pushl $88 +c0102243: 6a 58 push $0x58 + jmp __alltraps +c0102245: e9 cb fc ff ff jmp c0101f15 <__alltraps> + +c010224a : +.globl vector89 +vector89: + pushl $0 +c010224a: 6a 00 push $0x0 + pushl $89 +c010224c: 6a 59 push $0x59 + jmp __alltraps +c010224e: e9 c2 fc ff ff jmp c0101f15 <__alltraps> + +c0102253 : +.globl vector90 +vector90: + pushl $0 +c0102253: 6a 00 push $0x0 + pushl $90 +c0102255: 6a 5a push $0x5a + jmp __alltraps +c0102257: e9 b9 fc ff ff jmp c0101f15 <__alltraps> + +c010225c : +.globl vector91 +vector91: + pushl $0 +c010225c: 6a 00 push $0x0 + pushl $91 +c010225e: 6a 5b push $0x5b + jmp __alltraps +c0102260: e9 b0 fc ff ff jmp c0101f15 <__alltraps> + +c0102265 : +.globl vector92 +vector92: + pushl $0 +c0102265: 6a 00 push $0x0 + pushl $92 +c0102267: 6a 5c push $0x5c + jmp __alltraps +c0102269: e9 a7 fc ff ff jmp c0101f15 <__alltraps> + +c010226e : +.globl vector93 +vector93: + pushl $0 +c010226e: 6a 00 push $0x0 + pushl $93 +c0102270: 6a 5d push $0x5d + jmp __alltraps +c0102272: e9 9e fc ff ff jmp c0101f15 <__alltraps> + +c0102277 : +.globl vector94 +vector94: + pushl $0 +c0102277: 6a 00 push $0x0 + pushl $94 +c0102279: 6a 5e push $0x5e + jmp __alltraps +c010227b: e9 95 fc ff ff jmp c0101f15 <__alltraps> + +c0102280 : +.globl vector95 +vector95: + pushl $0 +c0102280: 6a 00 push $0x0 + pushl $95 +c0102282: 6a 5f push $0x5f + jmp __alltraps +c0102284: e9 8c fc ff ff jmp c0101f15 <__alltraps> + +c0102289 : +.globl vector96 +vector96: + pushl $0 +c0102289: 6a 00 push $0x0 + pushl $96 +c010228b: 6a 60 push $0x60 + jmp __alltraps +c010228d: e9 83 fc ff ff jmp c0101f15 <__alltraps> + +c0102292 : +.globl vector97 +vector97: + pushl $0 +c0102292: 6a 00 push $0x0 + pushl $97 +c0102294: 6a 61 push $0x61 + jmp __alltraps +c0102296: e9 7a fc ff ff jmp c0101f15 <__alltraps> + +c010229b : +.globl vector98 +vector98: + pushl $0 +c010229b: 6a 00 push $0x0 + pushl $98 +c010229d: 6a 62 push $0x62 + jmp __alltraps +c010229f: e9 71 fc ff ff jmp c0101f15 <__alltraps> + +c01022a4 : +.globl vector99 +vector99: + pushl $0 +c01022a4: 6a 00 push $0x0 + pushl $99 +c01022a6: 6a 63 push $0x63 + jmp __alltraps +c01022a8: e9 68 fc ff ff jmp c0101f15 <__alltraps> + +c01022ad : +.globl vector100 +vector100: + pushl $0 +c01022ad: 6a 00 push $0x0 + pushl $100 +c01022af: 6a 64 push $0x64 + jmp __alltraps +c01022b1: e9 5f fc ff ff jmp c0101f15 <__alltraps> + +c01022b6 : +.globl vector101 +vector101: + pushl $0 +c01022b6: 6a 00 push $0x0 + pushl $101 +c01022b8: 6a 65 push $0x65 + jmp __alltraps +c01022ba: e9 56 fc ff ff jmp c0101f15 <__alltraps> + +c01022bf : +.globl vector102 +vector102: + pushl $0 +c01022bf: 6a 00 push $0x0 + pushl $102 +c01022c1: 6a 66 push $0x66 + jmp __alltraps +c01022c3: e9 4d fc ff ff jmp c0101f15 <__alltraps> + +c01022c8 : +.globl vector103 +vector103: + pushl $0 +c01022c8: 6a 00 push $0x0 + pushl $103 +c01022ca: 6a 67 push $0x67 + jmp __alltraps +c01022cc: e9 44 fc ff ff jmp c0101f15 <__alltraps> + +c01022d1 : +.globl vector104 +vector104: + pushl $0 +c01022d1: 6a 00 push $0x0 + pushl $104 +c01022d3: 6a 68 push $0x68 + jmp __alltraps +c01022d5: e9 3b fc ff ff jmp c0101f15 <__alltraps> + +c01022da : +.globl vector105 +vector105: + pushl $0 +c01022da: 6a 00 push $0x0 + pushl $105 +c01022dc: 6a 69 push $0x69 + jmp __alltraps +c01022de: e9 32 fc ff ff jmp c0101f15 <__alltraps> + +c01022e3 : +.globl vector106 +vector106: + pushl $0 +c01022e3: 6a 00 push $0x0 + pushl $106 +c01022e5: 6a 6a push $0x6a + jmp __alltraps +c01022e7: e9 29 fc ff ff jmp c0101f15 <__alltraps> + +c01022ec : +.globl vector107 +vector107: + pushl $0 +c01022ec: 6a 00 push $0x0 + pushl $107 +c01022ee: 6a 6b push $0x6b + jmp __alltraps +c01022f0: e9 20 fc ff ff jmp c0101f15 <__alltraps> + +c01022f5 : +.globl vector108 +vector108: + pushl $0 +c01022f5: 6a 00 push $0x0 + pushl $108 +c01022f7: 6a 6c push $0x6c + jmp __alltraps +c01022f9: e9 17 fc ff ff jmp c0101f15 <__alltraps> + +c01022fe : +.globl vector109 +vector109: + pushl $0 +c01022fe: 6a 00 push $0x0 + pushl $109 +c0102300: 6a 6d push $0x6d + jmp __alltraps +c0102302: e9 0e fc ff ff jmp c0101f15 <__alltraps> + +c0102307 : +.globl vector110 +vector110: + pushl $0 +c0102307: 6a 00 push $0x0 + pushl $110 +c0102309: 6a 6e push $0x6e + jmp __alltraps +c010230b: e9 05 fc ff ff jmp c0101f15 <__alltraps> + +c0102310 : +.globl vector111 +vector111: + pushl $0 +c0102310: 6a 00 push $0x0 + pushl $111 +c0102312: 6a 6f push $0x6f + jmp __alltraps +c0102314: e9 fc fb ff ff jmp c0101f15 <__alltraps> + +c0102319 : +.globl vector112 +vector112: + pushl $0 +c0102319: 6a 00 push $0x0 + pushl $112 +c010231b: 6a 70 push $0x70 + jmp __alltraps +c010231d: e9 f3 fb ff ff jmp c0101f15 <__alltraps> + +c0102322 : +.globl vector113 +vector113: + pushl $0 +c0102322: 6a 00 push $0x0 + pushl $113 +c0102324: 6a 71 push $0x71 + jmp __alltraps +c0102326: e9 ea fb ff ff jmp c0101f15 <__alltraps> + +c010232b : +.globl vector114 +vector114: + pushl $0 +c010232b: 6a 00 push $0x0 + pushl $114 +c010232d: 6a 72 push $0x72 + jmp __alltraps +c010232f: e9 e1 fb ff ff jmp c0101f15 <__alltraps> + +c0102334 : +.globl vector115 +vector115: + pushl $0 +c0102334: 6a 00 push $0x0 + pushl $115 +c0102336: 6a 73 push $0x73 + jmp __alltraps +c0102338: e9 d8 fb ff ff jmp c0101f15 <__alltraps> + +c010233d : +.globl vector116 +vector116: + pushl $0 +c010233d: 6a 00 push $0x0 + pushl $116 +c010233f: 6a 74 push $0x74 + jmp __alltraps +c0102341: e9 cf fb ff ff jmp c0101f15 <__alltraps> + +c0102346 : +.globl vector117 +vector117: + pushl $0 +c0102346: 6a 00 push $0x0 + pushl $117 +c0102348: 6a 75 push $0x75 + jmp __alltraps +c010234a: e9 c6 fb ff ff jmp c0101f15 <__alltraps> + +c010234f : +.globl vector118 +vector118: + pushl $0 +c010234f: 6a 00 push $0x0 + pushl $118 +c0102351: 6a 76 push $0x76 + jmp __alltraps +c0102353: e9 bd fb ff ff jmp c0101f15 <__alltraps> + +c0102358 : +.globl vector119 +vector119: + pushl $0 +c0102358: 6a 00 push $0x0 + pushl $119 +c010235a: 6a 77 push $0x77 + jmp __alltraps +c010235c: e9 b4 fb ff ff jmp c0101f15 <__alltraps> + +c0102361 : +.globl vector120 +vector120: + pushl $0 +c0102361: 6a 00 push $0x0 + pushl $120 +c0102363: 6a 78 push $0x78 + jmp __alltraps +c0102365: e9 ab fb ff ff jmp c0101f15 <__alltraps> + +c010236a : +.globl vector121 +vector121: + pushl $0 +c010236a: 6a 00 push $0x0 + pushl $121 +c010236c: 6a 79 push $0x79 + jmp __alltraps +c010236e: e9 a2 fb ff ff jmp c0101f15 <__alltraps> + +c0102373 : +.globl vector122 +vector122: + pushl $0 +c0102373: 6a 00 push $0x0 + pushl $122 +c0102375: 6a 7a push $0x7a + jmp __alltraps +c0102377: e9 99 fb ff ff jmp c0101f15 <__alltraps> + +c010237c : +.globl vector123 +vector123: + pushl $0 +c010237c: 6a 00 push $0x0 + pushl $123 +c010237e: 6a 7b push $0x7b + jmp __alltraps +c0102380: e9 90 fb ff ff jmp c0101f15 <__alltraps> + +c0102385 : +.globl vector124 +vector124: + pushl $0 +c0102385: 6a 00 push $0x0 + pushl $124 +c0102387: 6a 7c push $0x7c + jmp __alltraps +c0102389: e9 87 fb ff ff jmp c0101f15 <__alltraps> + +c010238e : +.globl vector125 +vector125: + pushl $0 +c010238e: 6a 00 push $0x0 + pushl $125 +c0102390: 6a 7d push $0x7d + jmp __alltraps +c0102392: e9 7e fb ff ff jmp c0101f15 <__alltraps> + +c0102397 : +.globl vector126 +vector126: + pushl $0 +c0102397: 6a 00 push $0x0 + pushl $126 +c0102399: 6a 7e push $0x7e + jmp __alltraps +c010239b: e9 75 fb ff ff jmp c0101f15 <__alltraps> + +c01023a0 : +.globl vector127 +vector127: + pushl $0 +c01023a0: 6a 00 push $0x0 + pushl $127 +c01023a2: 6a 7f push $0x7f + jmp __alltraps +c01023a4: e9 6c fb ff ff jmp c0101f15 <__alltraps> + +c01023a9 : +.globl vector128 +vector128: + pushl $0 +c01023a9: 6a 00 push $0x0 + pushl $128 +c01023ab: 68 80 00 00 00 push $0x80 + jmp __alltraps +c01023b0: e9 60 fb ff ff jmp c0101f15 <__alltraps> + +c01023b5 : +.globl vector129 +vector129: + pushl $0 +c01023b5: 6a 00 push $0x0 + pushl $129 +c01023b7: 68 81 00 00 00 push $0x81 + jmp __alltraps +c01023bc: e9 54 fb ff ff jmp c0101f15 <__alltraps> + +c01023c1 : +.globl vector130 +vector130: + pushl $0 +c01023c1: 6a 00 push $0x0 + pushl $130 +c01023c3: 68 82 00 00 00 push $0x82 + jmp __alltraps +c01023c8: e9 48 fb ff ff jmp c0101f15 <__alltraps> + +c01023cd : +.globl vector131 +vector131: + pushl $0 +c01023cd: 6a 00 push $0x0 + pushl $131 +c01023cf: 68 83 00 00 00 push $0x83 + jmp __alltraps +c01023d4: e9 3c fb ff ff jmp c0101f15 <__alltraps> + +c01023d9 : +.globl vector132 +vector132: + pushl $0 +c01023d9: 6a 00 push $0x0 + pushl $132 +c01023db: 68 84 00 00 00 push $0x84 + jmp __alltraps +c01023e0: e9 30 fb ff ff jmp c0101f15 <__alltraps> + +c01023e5 : +.globl vector133 +vector133: + pushl $0 +c01023e5: 6a 00 push $0x0 + pushl $133 +c01023e7: 68 85 00 00 00 push $0x85 + jmp __alltraps +c01023ec: e9 24 fb ff ff jmp c0101f15 <__alltraps> + +c01023f1 : +.globl vector134 +vector134: + pushl $0 +c01023f1: 6a 00 push $0x0 + pushl $134 +c01023f3: 68 86 00 00 00 push $0x86 + jmp __alltraps +c01023f8: e9 18 fb ff ff jmp c0101f15 <__alltraps> + +c01023fd : +.globl vector135 +vector135: + pushl $0 +c01023fd: 6a 00 push $0x0 + pushl $135 +c01023ff: 68 87 00 00 00 push $0x87 + jmp __alltraps +c0102404: e9 0c fb ff ff jmp c0101f15 <__alltraps> + +c0102409 : +.globl vector136 +vector136: + pushl $0 +c0102409: 6a 00 push $0x0 + pushl $136 +c010240b: 68 88 00 00 00 push $0x88 + jmp __alltraps +c0102410: e9 00 fb ff ff jmp c0101f15 <__alltraps> + +c0102415 : +.globl vector137 +vector137: + pushl $0 +c0102415: 6a 00 push $0x0 + pushl $137 +c0102417: 68 89 00 00 00 push $0x89 + jmp __alltraps +c010241c: e9 f4 fa ff ff jmp c0101f15 <__alltraps> + +c0102421 : +.globl vector138 +vector138: + pushl $0 +c0102421: 6a 00 push $0x0 + pushl $138 +c0102423: 68 8a 00 00 00 push $0x8a + jmp __alltraps +c0102428: e9 e8 fa ff ff jmp c0101f15 <__alltraps> + +c010242d : +.globl vector139 +vector139: + pushl $0 +c010242d: 6a 00 push $0x0 + pushl $139 +c010242f: 68 8b 00 00 00 push $0x8b + jmp __alltraps +c0102434: e9 dc fa ff ff jmp c0101f15 <__alltraps> + +c0102439 : +.globl vector140 +vector140: + pushl $0 +c0102439: 6a 00 push $0x0 + pushl $140 +c010243b: 68 8c 00 00 00 push $0x8c + jmp __alltraps +c0102440: e9 d0 fa ff ff jmp c0101f15 <__alltraps> + +c0102445 : +.globl vector141 +vector141: + pushl $0 +c0102445: 6a 00 push $0x0 + pushl $141 +c0102447: 68 8d 00 00 00 push $0x8d + jmp __alltraps +c010244c: e9 c4 fa ff ff jmp c0101f15 <__alltraps> + +c0102451 : +.globl vector142 +vector142: + pushl $0 +c0102451: 6a 00 push $0x0 + pushl $142 +c0102453: 68 8e 00 00 00 push $0x8e + jmp __alltraps +c0102458: e9 b8 fa ff ff jmp c0101f15 <__alltraps> + +c010245d : +.globl vector143 +vector143: + pushl $0 +c010245d: 6a 00 push $0x0 + pushl $143 +c010245f: 68 8f 00 00 00 push $0x8f + jmp __alltraps +c0102464: e9 ac fa ff ff jmp c0101f15 <__alltraps> + +c0102469 : +.globl vector144 +vector144: + pushl $0 +c0102469: 6a 00 push $0x0 + pushl $144 +c010246b: 68 90 00 00 00 push $0x90 + jmp __alltraps +c0102470: e9 a0 fa ff ff jmp c0101f15 <__alltraps> + +c0102475 : +.globl vector145 +vector145: + pushl $0 +c0102475: 6a 00 push $0x0 + pushl $145 +c0102477: 68 91 00 00 00 push $0x91 + jmp __alltraps +c010247c: e9 94 fa ff ff jmp c0101f15 <__alltraps> + +c0102481 : +.globl vector146 +vector146: + pushl $0 +c0102481: 6a 00 push $0x0 + pushl $146 +c0102483: 68 92 00 00 00 push $0x92 + jmp __alltraps +c0102488: e9 88 fa ff ff jmp c0101f15 <__alltraps> + +c010248d : +.globl vector147 +vector147: + pushl $0 +c010248d: 6a 00 push $0x0 + pushl $147 +c010248f: 68 93 00 00 00 push $0x93 + jmp __alltraps +c0102494: e9 7c fa ff ff jmp c0101f15 <__alltraps> + +c0102499 : +.globl vector148 +vector148: + pushl $0 +c0102499: 6a 00 push $0x0 + pushl $148 +c010249b: 68 94 00 00 00 push $0x94 + jmp __alltraps +c01024a0: e9 70 fa ff ff jmp c0101f15 <__alltraps> + +c01024a5 : +.globl vector149 +vector149: + pushl $0 +c01024a5: 6a 00 push $0x0 + pushl $149 +c01024a7: 68 95 00 00 00 push $0x95 + jmp __alltraps +c01024ac: e9 64 fa ff ff jmp c0101f15 <__alltraps> + +c01024b1 : +.globl vector150 +vector150: + pushl $0 +c01024b1: 6a 00 push $0x0 + pushl $150 +c01024b3: 68 96 00 00 00 push $0x96 + jmp __alltraps +c01024b8: e9 58 fa ff ff jmp c0101f15 <__alltraps> + +c01024bd : +.globl vector151 +vector151: + pushl $0 +c01024bd: 6a 00 push $0x0 + pushl $151 +c01024bf: 68 97 00 00 00 push $0x97 + jmp __alltraps +c01024c4: e9 4c fa ff ff jmp c0101f15 <__alltraps> + +c01024c9 : +.globl vector152 +vector152: + pushl $0 +c01024c9: 6a 00 push $0x0 + pushl $152 +c01024cb: 68 98 00 00 00 push $0x98 + jmp __alltraps +c01024d0: e9 40 fa ff ff jmp c0101f15 <__alltraps> + +c01024d5 : +.globl vector153 +vector153: + pushl $0 +c01024d5: 6a 00 push $0x0 + pushl $153 +c01024d7: 68 99 00 00 00 push $0x99 + jmp __alltraps +c01024dc: e9 34 fa ff ff jmp c0101f15 <__alltraps> + +c01024e1 : +.globl vector154 +vector154: + pushl $0 +c01024e1: 6a 00 push $0x0 + pushl $154 +c01024e3: 68 9a 00 00 00 push $0x9a + jmp __alltraps +c01024e8: e9 28 fa ff ff jmp c0101f15 <__alltraps> + +c01024ed : +.globl vector155 +vector155: + pushl $0 +c01024ed: 6a 00 push $0x0 + pushl $155 +c01024ef: 68 9b 00 00 00 push $0x9b + jmp __alltraps +c01024f4: e9 1c fa ff ff jmp c0101f15 <__alltraps> + +c01024f9 : +.globl vector156 +vector156: + pushl $0 +c01024f9: 6a 00 push $0x0 + pushl $156 +c01024fb: 68 9c 00 00 00 push $0x9c + jmp __alltraps +c0102500: e9 10 fa ff ff jmp c0101f15 <__alltraps> + +c0102505 : +.globl vector157 +vector157: + pushl $0 +c0102505: 6a 00 push $0x0 + pushl $157 +c0102507: 68 9d 00 00 00 push $0x9d + jmp __alltraps +c010250c: e9 04 fa ff ff jmp c0101f15 <__alltraps> + +c0102511 : +.globl vector158 +vector158: + pushl $0 +c0102511: 6a 00 push $0x0 + pushl $158 +c0102513: 68 9e 00 00 00 push $0x9e + jmp __alltraps +c0102518: e9 f8 f9 ff ff jmp c0101f15 <__alltraps> + +c010251d : +.globl vector159 +vector159: + pushl $0 +c010251d: 6a 00 push $0x0 + pushl $159 +c010251f: 68 9f 00 00 00 push $0x9f + jmp __alltraps +c0102524: e9 ec f9 ff ff jmp c0101f15 <__alltraps> + +c0102529 : +.globl vector160 +vector160: + pushl $0 +c0102529: 6a 00 push $0x0 + pushl $160 +c010252b: 68 a0 00 00 00 push $0xa0 + jmp __alltraps +c0102530: e9 e0 f9 ff ff jmp c0101f15 <__alltraps> + +c0102535 : +.globl vector161 +vector161: + pushl $0 +c0102535: 6a 00 push $0x0 + pushl $161 +c0102537: 68 a1 00 00 00 push $0xa1 + jmp __alltraps +c010253c: e9 d4 f9 ff ff jmp c0101f15 <__alltraps> + +c0102541 : +.globl vector162 +vector162: + pushl $0 +c0102541: 6a 00 push $0x0 + pushl $162 +c0102543: 68 a2 00 00 00 push $0xa2 + jmp __alltraps +c0102548: e9 c8 f9 ff ff jmp c0101f15 <__alltraps> + +c010254d : +.globl vector163 +vector163: + pushl $0 +c010254d: 6a 00 push $0x0 + pushl $163 +c010254f: 68 a3 00 00 00 push $0xa3 + jmp __alltraps +c0102554: e9 bc f9 ff ff jmp c0101f15 <__alltraps> + +c0102559 : +.globl vector164 +vector164: + pushl $0 +c0102559: 6a 00 push $0x0 + pushl $164 +c010255b: 68 a4 00 00 00 push $0xa4 + jmp __alltraps +c0102560: e9 b0 f9 ff ff jmp c0101f15 <__alltraps> + +c0102565 : +.globl vector165 +vector165: + pushl $0 +c0102565: 6a 00 push $0x0 + pushl $165 +c0102567: 68 a5 00 00 00 push $0xa5 + jmp __alltraps +c010256c: e9 a4 f9 ff ff jmp c0101f15 <__alltraps> + +c0102571 : +.globl vector166 +vector166: + pushl $0 +c0102571: 6a 00 push $0x0 + pushl $166 +c0102573: 68 a6 00 00 00 push $0xa6 + jmp __alltraps +c0102578: e9 98 f9 ff ff jmp c0101f15 <__alltraps> + +c010257d : +.globl vector167 +vector167: + pushl $0 +c010257d: 6a 00 push $0x0 + pushl $167 +c010257f: 68 a7 00 00 00 push $0xa7 + jmp __alltraps +c0102584: e9 8c f9 ff ff jmp c0101f15 <__alltraps> + +c0102589 : +.globl vector168 +vector168: + pushl $0 +c0102589: 6a 00 push $0x0 + pushl $168 +c010258b: 68 a8 00 00 00 push $0xa8 + jmp __alltraps +c0102590: e9 80 f9 ff ff jmp c0101f15 <__alltraps> + +c0102595 : +.globl vector169 +vector169: + pushl $0 +c0102595: 6a 00 push $0x0 + pushl $169 +c0102597: 68 a9 00 00 00 push $0xa9 + jmp __alltraps +c010259c: e9 74 f9 ff ff jmp c0101f15 <__alltraps> + +c01025a1 : +.globl vector170 +vector170: + pushl $0 +c01025a1: 6a 00 push $0x0 + pushl $170 +c01025a3: 68 aa 00 00 00 push $0xaa + jmp __alltraps +c01025a8: e9 68 f9 ff ff jmp c0101f15 <__alltraps> + +c01025ad : +.globl vector171 +vector171: + pushl $0 +c01025ad: 6a 00 push $0x0 + pushl $171 +c01025af: 68 ab 00 00 00 push $0xab + jmp __alltraps +c01025b4: e9 5c f9 ff ff jmp c0101f15 <__alltraps> + +c01025b9 : +.globl vector172 +vector172: + pushl $0 +c01025b9: 6a 00 push $0x0 + pushl $172 +c01025bb: 68 ac 00 00 00 push $0xac + jmp __alltraps +c01025c0: e9 50 f9 ff ff jmp c0101f15 <__alltraps> + +c01025c5 : +.globl vector173 +vector173: + pushl $0 +c01025c5: 6a 00 push $0x0 + pushl $173 +c01025c7: 68 ad 00 00 00 push $0xad + jmp __alltraps +c01025cc: e9 44 f9 ff ff jmp c0101f15 <__alltraps> + +c01025d1 : +.globl vector174 +vector174: + pushl $0 +c01025d1: 6a 00 push $0x0 + pushl $174 +c01025d3: 68 ae 00 00 00 push $0xae + jmp __alltraps +c01025d8: e9 38 f9 ff ff jmp c0101f15 <__alltraps> + +c01025dd : +.globl vector175 +vector175: + pushl $0 +c01025dd: 6a 00 push $0x0 + pushl $175 +c01025df: 68 af 00 00 00 push $0xaf + jmp __alltraps +c01025e4: e9 2c f9 ff ff jmp c0101f15 <__alltraps> + +c01025e9 : +.globl vector176 +vector176: + pushl $0 +c01025e9: 6a 00 push $0x0 + pushl $176 +c01025eb: 68 b0 00 00 00 push $0xb0 + jmp __alltraps +c01025f0: e9 20 f9 ff ff jmp c0101f15 <__alltraps> + +c01025f5 : +.globl vector177 +vector177: + pushl $0 +c01025f5: 6a 00 push $0x0 + pushl $177 +c01025f7: 68 b1 00 00 00 push $0xb1 + jmp __alltraps +c01025fc: e9 14 f9 ff ff jmp c0101f15 <__alltraps> + +c0102601 : +.globl vector178 +vector178: + pushl $0 +c0102601: 6a 00 push $0x0 + pushl $178 +c0102603: 68 b2 00 00 00 push $0xb2 + jmp __alltraps +c0102608: e9 08 f9 ff ff jmp c0101f15 <__alltraps> + +c010260d : +.globl vector179 +vector179: + pushl $0 +c010260d: 6a 00 push $0x0 + pushl $179 +c010260f: 68 b3 00 00 00 push $0xb3 + jmp __alltraps +c0102614: e9 fc f8 ff ff jmp c0101f15 <__alltraps> + +c0102619 : +.globl vector180 +vector180: + pushl $0 +c0102619: 6a 00 push $0x0 + pushl $180 +c010261b: 68 b4 00 00 00 push $0xb4 + jmp __alltraps +c0102620: e9 f0 f8 ff ff jmp c0101f15 <__alltraps> + +c0102625 : +.globl vector181 +vector181: + pushl $0 +c0102625: 6a 00 push $0x0 + pushl $181 +c0102627: 68 b5 00 00 00 push $0xb5 + jmp __alltraps +c010262c: e9 e4 f8 ff ff jmp c0101f15 <__alltraps> + +c0102631 : +.globl vector182 +vector182: + pushl $0 +c0102631: 6a 00 push $0x0 + pushl $182 +c0102633: 68 b6 00 00 00 push $0xb6 + jmp __alltraps +c0102638: e9 d8 f8 ff ff jmp c0101f15 <__alltraps> + +c010263d : +.globl vector183 +vector183: + pushl $0 +c010263d: 6a 00 push $0x0 + pushl $183 +c010263f: 68 b7 00 00 00 push $0xb7 + jmp __alltraps +c0102644: e9 cc f8 ff ff jmp c0101f15 <__alltraps> + +c0102649 : +.globl vector184 +vector184: + pushl $0 +c0102649: 6a 00 push $0x0 + pushl $184 +c010264b: 68 b8 00 00 00 push $0xb8 + jmp __alltraps +c0102650: e9 c0 f8 ff ff jmp c0101f15 <__alltraps> + +c0102655 : +.globl vector185 +vector185: + pushl $0 +c0102655: 6a 00 push $0x0 + pushl $185 +c0102657: 68 b9 00 00 00 push $0xb9 + jmp __alltraps +c010265c: e9 b4 f8 ff ff jmp c0101f15 <__alltraps> + +c0102661 : +.globl vector186 +vector186: + pushl $0 +c0102661: 6a 00 push $0x0 + pushl $186 +c0102663: 68 ba 00 00 00 push $0xba + jmp __alltraps +c0102668: e9 a8 f8 ff ff jmp c0101f15 <__alltraps> + +c010266d : +.globl vector187 +vector187: + pushl $0 +c010266d: 6a 00 push $0x0 + pushl $187 +c010266f: 68 bb 00 00 00 push $0xbb + jmp __alltraps +c0102674: e9 9c f8 ff ff jmp c0101f15 <__alltraps> + +c0102679 : +.globl vector188 +vector188: + pushl $0 +c0102679: 6a 00 push $0x0 + pushl $188 +c010267b: 68 bc 00 00 00 push $0xbc + jmp __alltraps +c0102680: e9 90 f8 ff ff jmp c0101f15 <__alltraps> + +c0102685 : +.globl vector189 +vector189: + pushl $0 +c0102685: 6a 00 push $0x0 + pushl $189 +c0102687: 68 bd 00 00 00 push $0xbd + jmp __alltraps +c010268c: e9 84 f8 ff ff jmp c0101f15 <__alltraps> + +c0102691 : +.globl vector190 +vector190: + pushl $0 +c0102691: 6a 00 push $0x0 + pushl $190 +c0102693: 68 be 00 00 00 push $0xbe + jmp __alltraps +c0102698: e9 78 f8 ff ff jmp c0101f15 <__alltraps> + +c010269d : +.globl vector191 +vector191: + pushl $0 +c010269d: 6a 00 push $0x0 + pushl $191 +c010269f: 68 bf 00 00 00 push $0xbf + jmp __alltraps +c01026a4: e9 6c f8 ff ff jmp c0101f15 <__alltraps> + +c01026a9 : +.globl vector192 +vector192: + pushl $0 +c01026a9: 6a 00 push $0x0 + pushl $192 +c01026ab: 68 c0 00 00 00 push $0xc0 + jmp __alltraps +c01026b0: e9 60 f8 ff ff jmp c0101f15 <__alltraps> + +c01026b5 : +.globl vector193 +vector193: + pushl $0 +c01026b5: 6a 00 push $0x0 + pushl $193 +c01026b7: 68 c1 00 00 00 push $0xc1 + jmp __alltraps +c01026bc: e9 54 f8 ff ff jmp c0101f15 <__alltraps> + +c01026c1 : +.globl vector194 +vector194: + pushl $0 +c01026c1: 6a 00 push $0x0 + pushl $194 +c01026c3: 68 c2 00 00 00 push $0xc2 + jmp __alltraps +c01026c8: e9 48 f8 ff ff jmp c0101f15 <__alltraps> + +c01026cd : +.globl vector195 +vector195: + pushl $0 +c01026cd: 6a 00 push $0x0 + pushl $195 +c01026cf: 68 c3 00 00 00 push $0xc3 + jmp __alltraps +c01026d4: e9 3c f8 ff ff jmp c0101f15 <__alltraps> + +c01026d9 : +.globl vector196 +vector196: + pushl $0 +c01026d9: 6a 00 push $0x0 + pushl $196 +c01026db: 68 c4 00 00 00 push $0xc4 + jmp __alltraps +c01026e0: e9 30 f8 ff ff jmp c0101f15 <__alltraps> + +c01026e5 : +.globl vector197 +vector197: + pushl $0 +c01026e5: 6a 00 push $0x0 + pushl $197 +c01026e7: 68 c5 00 00 00 push $0xc5 + jmp __alltraps +c01026ec: e9 24 f8 ff ff jmp c0101f15 <__alltraps> + +c01026f1 : +.globl vector198 +vector198: + pushl $0 +c01026f1: 6a 00 push $0x0 + pushl $198 +c01026f3: 68 c6 00 00 00 push $0xc6 + jmp __alltraps +c01026f8: e9 18 f8 ff ff jmp c0101f15 <__alltraps> + +c01026fd : +.globl vector199 +vector199: + pushl $0 +c01026fd: 6a 00 push $0x0 + pushl $199 +c01026ff: 68 c7 00 00 00 push $0xc7 + jmp __alltraps +c0102704: e9 0c f8 ff ff jmp c0101f15 <__alltraps> + +c0102709 : +.globl vector200 +vector200: + pushl $0 +c0102709: 6a 00 push $0x0 + pushl $200 +c010270b: 68 c8 00 00 00 push $0xc8 + jmp __alltraps +c0102710: e9 00 f8 ff ff jmp c0101f15 <__alltraps> + +c0102715 : +.globl vector201 +vector201: + pushl $0 +c0102715: 6a 00 push $0x0 + pushl $201 +c0102717: 68 c9 00 00 00 push $0xc9 + jmp __alltraps +c010271c: e9 f4 f7 ff ff jmp c0101f15 <__alltraps> + +c0102721 : +.globl vector202 +vector202: + pushl $0 +c0102721: 6a 00 push $0x0 + pushl $202 +c0102723: 68 ca 00 00 00 push $0xca + jmp __alltraps +c0102728: e9 e8 f7 ff ff jmp c0101f15 <__alltraps> + +c010272d : +.globl vector203 +vector203: + pushl $0 +c010272d: 6a 00 push $0x0 + pushl $203 +c010272f: 68 cb 00 00 00 push $0xcb + jmp __alltraps +c0102734: e9 dc f7 ff ff jmp c0101f15 <__alltraps> + +c0102739 : +.globl vector204 +vector204: + pushl $0 +c0102739: 6a 00 push $0x0 + pushl $204 +c010273b: 68 cc 00 00 00 push $0xcc + jmp __alltraps +c0102740: e9 d0 f7 ff ff jmp c0101f15 <__alltraps> + +c0102745 : +.globl vector205 +vector205: + pushl $0 +c0102745: 6a 00 push $0x0 + pushl $205 +c0102747: 68 cd 00 00 00 push $0xcd + jmp __alltraps +c010274c: e9 c4 f7 ff ff jmp c0101f15 <__alltraps> + +c0102751 : +.globl vector206 +vector206: + pushl $0 +c0102751: 6a 00 push $0x0 + pushl $206 +c0102753: 68 ce 00 00 00 push $0xce + jmp __alltraps +c0102758: e9 b8 f7 ff ff jmp c0101f15 <__alltraps> + +c010275d : +.globl vector207 +vector207: + pushl $0 +c010275d: 6a 00 push $0x0 + pushl $207 +c010275f: 68 cf 00 00 00 push $0xcf + jmp __alltraps +c0102764: e9 ac f7 ff ff jmp c0101f15 <__alltraps> + +c0102769 : +.globl vector208 +vector208: + pushl $0 +c0102769: 6a 00 push $0x0 + pushl $208 +c010276b: 68 d0 00 00 00 push $0xd0 + jmp __alltraps +c0102770: e9 a0 f7 ff ff jmp c0101f15 <__alltraps> + +c0102775 : +.globl vector209 +vector209: + pushl $0 +c0102775: 6a 00 push $0x0 + pushl $209 +c0102777: 68 d1 00 00 00 push $0xd1 + jmp __alltraps +c010277c: e9 94 f7 ff ff jmp c0101f15 <__alltraps> + +c0102781 : +.globl vector210 +vector210: + pushl $0 +c0102781: 6a 00 push $0x0 + pushl $210 +c0102783: 68 d2 00 00 00 push $0xd2 + jmp __alltraps +c0102788: e9 88 f7 ff ff jmp c0101f15 <__alltraps> + +c010278d : +.globl vector211 +vector211: + pushl $0 +c010278d: 6a 00 push $0x0 + pushl $211 +c010278f: 68 d3 00 00 00 push $0xd3 + jmp __alltraps +c0102794: e9 7c f7 ff ff jmp c0101f15 <__alltraps> + +c0102799 : +.globl vector212 +vector212: + pushl $0 +c0102799: 6a 00 push $0x0 + pushl $212 +c010279b: 68 d4 00 00 00 push $0xd4 + jmp __alltraps +c01027a0: e9 70 f7 ff ff jmp c0101f15 <__alltraps> + +c01027a5 : +.globl vector213 +vector213: + pushl $0 +c01027a5: 6a 00 push $0x0 + pushl $213 +c01027a7: 68 d5 00 00 00 push $0xd5 + jmp __alltraps +c01027ac: e9 64 f7 ff ff jmp c0101f15 <__alltraps> + +c01027b1 : +.globl vector214 +vector214: + pushl $0 +c01027b1: 6a 00 push $0x0 + pushl $214 +c01027b3: 68 d6 00 00 00 push $0xd6 + jmp __alltraps +c01027b8: e9 58 f7 ff ff jmp c0101f15 <__alltraps> + +c01027bd : +.globl vector215 +vector215: + pushl $0 +c01027bd: 6a 00 push $0x0 + pushl $215 +c01027bf: 68 d7 00 00 00 push $0xd7 + jmp __alltraps +c01027c4: e9 4c f7 ff ff jmp c0101f15 <__alltraps> + +c01027c9 : +.globl vector216 +vector216: + pushl $0 +c01027c9: 6a 00 push $0x0 + pushl $216 +c01027cb: 68 d8 00 00 00 push $0xd8 + jmp __alltraps +c01027d0: e9 40 f7 ff ff jmp c0101f15 <__alltraps> + +c01027d5 : +.globl vector217 +vector217: + pushl $0 +c01027d5: 6a 00 push $0x0 + pushl $217 +c01027d7: 68 d9 00 00 00 push $0xd9 + jmp __alltraps +c01027dc: e9 34 f7 ff ff jmp c0101f15 <__alltraps> + +c01027e1 : +.globl vector218 +vector218: + pushl $0 +c01027e1: 6a 00 push $0x0 + pushl $218 +c01027e3: 68 da 00 00 00 push $0xda + jmp __alltraps +c01027e8: e9 28 f7 ff ff jmp c0101f15 <__alltraps> + +c01027ed : +.globl vector219 +vector219: + pushl $0 +c01027ed: 6a 00 push $0x0 + pushl $219 +c01027ef: 68 db 00 00 00 push $0xdb + jmp __alltraps +c01027f4: e9 1c f7 ff ff jmp c0101f15 <__alltraps> + +c01027f9 : +.globl vector220 +vector220: + pushl $0 +c01027f9: 6a 00 push $0x0 + pushl $220 +c01027fb: 68 dc 00 00 00 push $0xdc + jmp __alltraps +c0102800: e9 10 f7 ff ff jmp c0101f15 <__alltraps> + +c0102805 : +.globl vector221 +vector221: + pushl $0 +c0102805: 6a 00 push $0x0 + pushl $221 +c0102807: 68 dd 00 00 00 push $0xdd + jmp __alltraps +c010280c: e9 04 f7 ff ff jmp c0101f15 <__alltraps> + +c0102811 : +.globl vector222 +vector222: + pushl $0 +c0102811: 6a 00 push $0x0 + pushl $222 +c0102813: 68 de 00 00 00 push $0xde + jmp __alltraps +c0102818: e9 f8 f6 ff ff jmp c0101f15 <__alltraps> + +c010281d : +.globl vector223 +vector223: + pushl $0 +c010281d: 6a 00 push $0x0 + pushl $223 +c010281f: 68 df 00 00 00 push $0xdf + jmp __alltraps +c0102824: e9 ec f6 ff ff jmp c0101f15 <__alltraps> + +c0102829 : +.globl vector224 +vector224: + pushl $0 +c0102829: 6a 00 push $0x0 + pushl $224 +c010282b: 68 e0 00 00 00 push $0xe0 + jmp __alltraps +c0102830: e9 e0 f6 ff ff jmp c0101f15 <__alltraps> + +c0102835 : +.globl vector225 +vector225: + pushl $0 +c0102835: 6a 00 push $0x0 + pushl $225 +c0102837: 68 e1 00 00 00 push $0xe1 + jmp __alltraps +c010283c: e9 d4 f6 ff ff jmp c0101f15 <__alltraps> + +c0102841 : +.globl vector226 +vector226: + pushl $0 +c0102841: 6a 00 push $0x0 + pushl $226 +c0102843: 68 e2 00 00 00 push $0xe2 + jmp __alltraps +c0102848: e9 c8 f6 ff ff jmp c0101f15 <__alltraps> + +c010284d : +.globl vector227 +vector227: + pushl $0 +c010284d: 6a 00 push $0x0 + pushl $227 +c010284f: 68 e3 00 00 00 push $0xe3 + jmp __alltraps +c0102854: e9 bc f6 ff ff jmp c0101f15 <__alltraps> + +c0102859 : +.globl vector228 +vector228: + pushl $0 +c0102859: 6a 00 push $0x0 + pushl $228 +c010285b: 68 e4 00 00 00 push $0xe4 + jmp __alltraps +c0102860: e9 b0 f6 ff ff jmp c0101f15 <__alltraps> + +c0102865 : +.globl vector229 +vector229: + pushl $0 +c0102865: 6a 00 push $0x0 + pushl $229 +c0102867: 68 e5 00 00 00 push $0xe5 + jmp __alltraps +c010286c: e9 a4 f6 ff ff jmp c0101f15 <__alltraps> + +c0102871 : +.globl vector230 +vector230: + pushl $0 +c0102871: 6a 00 push $0x0 + pushl $230 +c0102873: 68 e6 00 00 00 push $0xe6 + jmp __alltraps +c0102878: e9 98 f6 ff ff jmp c0101f15 <__alltraps> + +c010287d : +.globl vector231 +vector231: + pushl $0 +c010287d: 6a 00 push $0x0 + pushl $231 +c010287f: 68 e7 00 00 00 push $0xe7 + jmp __alltraps +c0102884: e9 8c f6 ff ff jmp c0101f15 <__alltraps> + +c0102889 : +.globl vector232 +vector232: + pushl $0 +c0102889: 6a 00 push $0x0 + pushl $232 +c010288b: 68 e8 00 00 00 push $0xe8 + jmp __alltraps +c0102890: e9 80 f6 ff ff jmp c0101f15 <__alltraps> + +c0102895 : +.globl vector233 +vector233: + pushl $0 +c0102895: 6a 00 push $0x0 + pushl $233 +c0102897: 68 e9 00 00 00 push $0xe9 + jmp __alltraps +c010289c: e9 74 f6 ff ff jmp c0101f15 <__alltraps> + +c01028a1 : +.globl vector234 +vector234: + pushl $0 +c01028a1: 6a 00 push $0x0 + pushl $234 +c01028a3: 68 ea 00 00 00 push $0xea + jmp __alltraps +c01028a8: e9 68 f6 ff ff jmp c0101f15 <__alltraps> + +c01028ad : +.globl vector235 +vector235: + pushl $0 +c01028ad: 6a 00 push $0x0 + pushl $235 +c01028af: 68 eb 00 00 00 push $0xeb + jmp __alltraps +c01028b4: e9 5c f6 ff ff jmp c0101f15 <__alltraps> + +c01028b9 : +.globl vector236 +vector236: + pushl $0 +c01028b9: 6a 00 push $0x0 + pushl $236 +c01028bb: 68 ec 00 00 00 push $0xec + jmp __alltraps +c01028c0: e9 50 f6 ff ff jmp c0101f15 <__alltraps> + +c01028c5 : +.globl vector237 +vector237: + pushl $0 +c01028c5: 6a 00 push $0x0 + pushl $237 +c01028c7: 68 ed 00 00 00 push $0xed + jmp __alltraps +c01028cc: e9 44 f6 ff ff jmp c0101f15 <__alltraps> + +c01028d1 : +.globl vector238 +vector238: + pushl $0 +c01028d1: 6a 00 push $0x0 + pushl $238 +c01028d3: 68 ee 00 00 00 push $0xee + jmp __alltraps +c01028d8: e9 38 f6 ff ff jmp c0101f15 <__alltraps> + +c01028dd : +.globl vector239 +vector239: + pushl $0 +c01028dd: 6a 00 push $0x0 + pushl $239 +c01028df: 68 ef 00 00 00 push $0xef + jmp __alltraps +c01028e4: e9 2c f6 ff ff jmp c0101f15 <__alltraps> + +c01028e9 : +.globl vector240 +vector240: + pushl $0 +c01028e9: 6a 00 push $0x0 + pushl $240 +c01028eb: 68 f0 00 00 00 push $0xf0 + jmp __alltraps +c01028f0: e9 20 f6 ff ff jmp c0101f15 <__alltraps> + +c01028f5 : +.globl vector241 +vector241: + pushl $0 +c01028f5: 6a 00 push $0x0 + pushl $241 +c01028f7: 68 f1 00 00 00 push $0xf1 + jmp __alltraps +c01028fc: e9 14 f6 ff ff jmp c0101f15 <__alltraps> + +c0102901 : +.globl vector242 +vector242: + pushl $0 +c0102901: 6a 00 push $0x0 + pushl $242 +c0102903: 68 f2 00 00 00 push $0xf2 + jmp __alltraps +c0102908: e9 08 f6 ff ff jmp c0101f15 <__alltraps> + +c010290d : +.globl vector243 +vector243: + pushl $0 +c010290d: 6a 00 push $0x0 + pushl $243 +c010290f: 68 f3 00 00 00 push $0xf3 + jmp __alltraps +c0102914: e9 fc f5 ff ff jmp c0101f15 <__alltraps> + +c0102919 : +.globl vector244 +vector244: + pushl $0 +c0102919: 6a 00 push $0x0 + pushl $244 +c010291b: 68 f4 00 00 00 push $0xf4 + jmp __alltraps +c0102920: e9 f0 f5 ff ff jmp c0101f15 <__alltraps> + +c0102925 : +.globl vector245 +vector245: + pushl $0 +c0102925: 6a 00 push $0x0 + pushl $245 +c0102927: 68 f5 00 00 00 push $0xf5 + jmp __alltraps +c010292c: e9 e4 f5 ff ff jmp c0101f15 <__alltraps> + +c0102931 : +.globl vector246 +vector246: + pushl $0 +c0102931: 6a 00 push $0x0 + pushl $246 +c0102933: 68 f6 00 00 00 push $0xf6 + jmp __alltraps +c0102938: e9 d8 f5 ff ff jmp c0101f15 <__alltraps> + +c010293d : +.globl vector247 +vector247: + pushl $0 +c010293d: 6a 00 push $0x0 + pushl $247 +c010293f: 68 f7 00 00 00 push $0xf7 + jmp __alltraps +c0102944: e9 cc f5 ff ff jmp c0101f15 <__alltraps> + +c0102949 : +.globl vector248 +vector248: + pushl $0 +c0102949: 6a 00 push $0x0 + pushl $248 +c010294b: 68 f8 00 00 00 push $0xf8 + jmp __alltraps +c0102950: e9 c0 f5 ff ff jmp c0101f15 <__alltraps> + +c0102955 : +.globl vector249 +vector249: + pushl $0 +c0102955: 6a 00 push $0x0 + pushl $249 +c0102957: 68 f9 00 00 00 push $0xf9 + jmp __alltraps +c010295c: e9 b4 f5 ff ff jmp c0101f15 <__alltraps> + +c0102961 : +.globl vector250 +vector250: + pushl $0 +c0102961: 6a 00 push $0x0 + pushl $250 +c0102963: 68 fa 00 00 00 push $0xfa + jmp __alltraps +c0102968: e9 a8 f5 ff ff jmp c0101f15 <__alltraps> + +c010296d : +.globl vector251 +vector251: + pushl $0 +c010296d: 6a 00 push $0x0 + pushl $251 +c010296f: 68 fb 00 00 00 push $0xfb + jmp __alltraps +c0102974: e9 9c f5 ff ff jmp c0101f15 <__alltraps> + +c0102979 : +.globl vector252 +vector252: + pushl $0 +c0102979: 6a 00 push $0x0 + pushl $252 +c010297b: 68 fc 00 00 00 push $0xfc + jmp __alltraps +c0102980: e9 90 f5 ff ff jmp c0101f15 <__alltraps> + +c0102985 : +.globl vector253 +vector253: + pushl $0 +c0102985: 6a 00 push $0x0 + pushl $253 +c0102987: 68 fd 00 00 00 push $0xfd + jmp __alltraps +c010298c: e9 84 f5 ff ff jmp c0101f15 <__alltraps> + +c0102991 : +.globl vector254 +vector254: + pushl $0 +c0102991: 6a 00 push $0x0 + pushl $254 +c0102993: 68 fe 00 00 00 push $0xfe + jmp __alltraps +c0102998: e9 78 f5 ff ff jmp c0101f15 <__alltraps> + +c010299d : +.globl vector255 +vector255: + pushl $0 +c010299d: 6a 00 push $0x0 + pushl $255 +c010299f: 68 ff 00 00 00 push $0xff + jmp __alltraps +c01029a4: e9 6c f5 ff ff jmp c0101f15 <__alltraps> + +c01029a9 : + +extern struct Page *pages; +extern size_t npage; + +static inline ppn_t +page2ppn(struct Page *page) { +c01029a9: 55 push %ebp +c01029aa: 89 e5 mov %esp,%ebp + return page - pages; +c01029ac: 8b 15 00 cf 11 c0 mov 0xc011cf00,%edx +c01029b2: 8b 45 08 mov 0x8(%ebp),%eax +c01029b5: 29 d0 sub %edx,%eax +c01029b7: c1 f8 02 sar $0x2,%eax +c01029ba: 69 c0 cd cc cc cc imul $0xcccccccd,%eax,%eax +} +c01029c0: 5d pop %ebp +c01029c1: c3 ret + +c01029c2 : + +static inline uintptr_t +page2pa(struct Page *page) { +c01029c2: 55 push %ebp +c01029c3: 89 e5 mov %esp,%ebp +c01029c5: 83 ec 04 sub $0x4,%esp + return page2ppn(page) << PGSHIFT; +c01029c8: 8b 45 08 mov 0x8(%ebp),%eax +c01029cb: 89 04 24 mov %eax,(%esp) +c01029ce: e8 d6 ff ff ff call c01029a9 +c01029d3: c1 e0 0c shl $0xc,%eax +} +c01029d6: 89 ec mov %ebp,%esp +c01029d8: 5d pop %ebp +c01029d9: c3 ret + +c01029da : +pde2page(pde_t pde) { + return pa2page(PDE_ADDR(pde)); +} + +static inline int +page_ref(struct Page *page) { +c01029da: 55 push %ebp +c01029db: 89 e5 mov %esp,%ebp + return page->ref; +c01029dd: 8b 45 08 mov 0x8(%ebp),%eax +c01029e0: 8b 00 mov (%eax),%eax +} +c01029e2: 5d pop %ebp +c01029e3: c3 ret + +c01029e4 : + +static inline void +set_page_ref(struct Page *page, int val) { +c01029e4: 55 push %ebp +c01029e5: 89 e5 mov %esp,%ebp + page->ref = val; +c01029e7: 8b 45 08 mov 0x8(%ebp),%eax +c01029ea: 8b 55 0c mov 0xc(%ebp),%edx +c01029ed: 89 10 mov %edx,(%eax) +} +c01029ef: 90 nop +c01029f0: 5d pop %ebp +c01029f1: c3 ret + +c01029f2 : +#define nr_free (free_area.nr_free) + +//free_list` 用于记录空闲内存块,nr_free` 是空闲内存块的总数。 +//用default_init函数来初始化 `free_list`,并将 `nr_free` 设置为 0。 +static void +default_init(void) { +c01029f2: 55 push %ebp +c01029f3: 89 e5 mov %esp,%ebp +c01029f5: 83 ec 10 sub $0x10,%esp +c01029f8: c7 45 fc e0 ce 11 c0 movl $0xc011cee0,-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; +c01029ff: 8b 45 fc mov -0x4(%ebp),%eax +c0102a02: 8b 55 fc mov -0x4(%ebp),%edx +c0102a05: 89 50 04 mov %edx,0x4(%eax) +c0102a08: 8b 45 fc mov -0x4(%ebp),%eax +c0102a0b: 8b 50 04 mov 0x4(%eax),%edx +c0102a0e: 8b 45 fc mov -0x4(%ebp),%eax +c0102a11: 89 10 mov %edx,(%eax) +} +c0102a13: 90 nop + list_init(&free_list); + nr_free = 0; +c0102a14: c7 05 e8 ce 11 c0 00 movl $0x0,0xc011cee8 +c0102a1b: 00 00 00 +} +c0102a1e: 90 nop +c0102a1f: 89 ec mov %ebp,%esp +c0102a21: 5d pop %ebp +c0102a22: c3 ret + +c0102a23 : + +//用于初始化一段连续的物理页,并将它们加入到空闲内存管理系统中. +//struct Page *base:指向要初始化的页块的起始地址。size_t n:要初始化的页的数量。 +static void +default_init_memmap(struct Page *base, size_t n) { +c0102a23: 55 push %ebp +c0102a24: 89 e5 mov %esp,%ebp +c0102a26: 83 ec 58 sub $0x58,%esp + assert(n > 0);//// 确保请求的页数大于零 +c0102a29: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) +c0102a2d: 75 24 jne c0102a53 +c0102a2f: c7 44 24 0c 90 67 10 movl $0xc0106790,0xc(%esp) +c0102a36: c0 +c0102a37: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c0102a3e: c0 +c0102a3f: c7 44 24 04 94 00 00 movl $0x94,0x4(%esp) +c0102a46: 00 +c0102a47: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c0102a4e: e8 e0 e1 ff ff call c0100c33 <__panic> + struct Page *p = base;// 指向当前初始化的页 +c0102a53: 8b 45 08 mov 0x8(%ebp),%eax +c0102a56: 89 45 f4 mov %eax,-0xc(%ebp) + //// 遍历每一页,设置其状态 + for (; p != base + n; p ++) { +c0102a59: eb 7d jmp c0102ad8 + assert(PageReserved(p));//检查每个页是否被标记为“保留”。若没有被保留,函数将抛出错误。 +c0102a5b: 8b 45 f4 mov -0xc(%ebp),%eax +c0102a5e: 83 c0 04 add $0x4,%eax +c0102a61: c7 45 f0 00 00 00 00 movl $0x0,-0x10(%ebp) +c0102a68: 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)); +c0102a6b: 8b 45 ec mov -0x14(%ebp),%eax +c0102a6e: 8b 55 f0 mov -0x10(%ebp),%edx +c0102a71: 0f a3 10 bt %edx,(%eax) +c0102a74: 19 c0 sbb %eax,%eax +c0102a76: 89 45 e8 mov %eax,-0x18(%ebp) + return oldbit != 0; +c0102a79: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) +c0102a7d: 0f 95 c0 setne %al +c0102a80: 0f b6 c0 movzbl %al,%eax +c0102a83: 85 c0 test %eax,%eax +c0102a85: 75 24 jne c0102aab +c0102a87: c7 44 24 0c c1 67 10 movl $0xc01067c1,0xc(%esp) +c0102a8e: c0 +c0102a8f: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c0102a96: c0 +c0102a97: c7 44 24 04 98 00 00 movl $0x98,0x4(%esp) +c0102a9e: 00 +c0102a9f: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c0102aa6: e8 88 e1 ff ff call c0100c33 <__panic> + p->flags = p->property = 0;//将页的 flags 和 property 字段设置为 0,表示该页未分配、未使用。 +c0102aab: 8b 45 f4 mov -0xc(%ebp),%eax +c0102aae: c7 40 08 00 00 00 00 movl $0x0,0x8(%eax) +c0102ab5: 8b 45 f4 mov -0xc(%ebp),%eax +c0102ab8: 8b 50 08 mov 0x8(%eax),%edx +c0102abb: 8b 45 f4 mov -0xc(%ebp),%eax +c0102abe: 89 50 04 mov %edx,0x4(%eax) + set_page_ref(p, 0);//将页的引用计数设置为 0,表明没有任何引用指向此页。 +c0102ac1: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) +c0102ac8: 00 +c0102ac9: 8b 45 f4 mov -0xc(%ebp),%eax +c0102acc: 89 04 24 mov %eax,(%esp) +c0102acf: e8 10 ff ff ff call c01029e4 + for (; p != base + n; p ++) { +c0102ad4: 83 45 f4 14 addl $0x14,-0xc(%ebp) +c0102ad8: 8b 55 0c mov 0xc(%ebp),%edx +c0102adb: 89 d0 mov %edx,%eax +c0102add: c1 e0 02 shl $0x2,%eax +c0102ae0: 01 d0 add %edx,%eax +c0102ae2: c1 e0 02 shl $0x2,%eax +c0102ae5: 89 c2 mov %eax,%edx +c0102ae7: 8b 45 08 mov 0x8(%ebp),%eax +c0102aea: 01 d0 add %edx,%eax +c0102aec: 39 45 f4 cmp %eax,-0xc(%ebp) +c0102aef: 0f 85 66 ff ff ff jne c0102a5b + } + // 设置第一个页的 property 为块的总数 + base->property = n; +c0102af5: 8b 45 08 mov 0x8(%ebp),%eax +c0102af8: 8b 55 0c mov 0xc(%ebp),%edx +c0102afb: 89 50 08 mov %edx,0x8(%eax) + SetPageProperty(base);// 设置当前页的有效标志 +c0102afe: 8b 45 08 mov 0x8(%ebp),%eax +c0102b01: 83 c0 04 add $0x4,%eax +c0102b04: c7 45 c8 01 00 00 00 movl $0x1,-0x38(%ebp) +c0102b0b: 89 45 c4 mov %eax,-0x3c(%ebp) + asm volatile ("btsl %1, %0" :"=m" (*(volatile long *)addr) : "Ir" (nr)); +c0102b0e: 8b 45 c4 mov -0x3c(%ebp),%eax +c0102b11: 8b 55 c8 mov -0x38(%ebp),%edx +c0102b14: 0f ab 10 bts %edx,(%eax) +} +c0102b17: 90 nop + nr_free += n;// 更新空闲页计数 +c0102b18: 8b 15 e8 ce 11 c0 mov 0xc011cee8,%edx +c0102b1e: 8b 45 0c mov 0xc(%ebp),%eax +c0102b21: 01 d0 add %edx,%eax +c0102b23: a3 e8 ce 11 c0 mov %eax,0xc011cee8 + list_add(&free_list, &(base->page_link)); // 将该块添加到空闲列表中 +c0102b28: 8b 45 08 mov 0x8(%ebp),%eax +c0102b2b: 83 c0 0c add $0xc,%eax +c0102b2e: c7 45 e4 e0 ce 11 c0 movl $0xc011cee0,-0x1c(%ebp) +c0102b35: 89 45 e0 mov %eax,-0x20(%ebp) +c0102b38: 8b 45 e4 mov -0x1c(%ebp),%eax +c0102b3b: 89 45 dc mov %eax,-0x24(%ebp) +c0102b3e: 8b 45 e0 mov -0x20(%ebp),%eax +c0102b41: 89 45 d8 mov %eax,-0x28(%ebp) + * Insert the new element @elm *after* the element @listelm which + * is already in the list. + * */ +static inline void +list_add_after(list_entry_t *listelm, list_entry_t *elm) { + __list_add(elm, listelm, listelm->next); +c0102b44: 8b 45 dc mov -0x24(%ebp),%eax +c0102b47: 8b 40 04 mov 0x4(%eax),%eax +c0102b4a: 8b 55 d8 mov -0x28(%ebp),%edx +c0102b4d: 89 55 d4 mov %edx,-0x2c(%ebp) +c0102b50: 8b 55 dc mov -0x24(%ebp),%edx +c0102b53: 89 55 d0 mov %edx,-0x30(%ebp) +c0102b56: 89 45 cc mov %eax,-0x34(%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; +c0102b59: 8b 45 cc mov -0x34(%ebp),%eax +c0102b5c: 8b 55 d4 mov -0x2c(%ebp),%edx +c0102b5f: 89 10 mov %edx,(%eax) +c0102b61: 8b 45 cc mov -0x34(%ebp),%eax +c0102b64: 8b 10 mov (%eax),%edx +c0102b66: 8b 45 d0 mov -0x30(%ebp),%eax +c0102b69: 89 50 04 mov %edx,0x4(%eax) + elm->next = next; +c0102b6c: 8b 45 d4 mov -0x2c(%ebp),%eax +c0102b6f: 8b 55 cc mov -0x34(%ebp),%edx +c0102b72: 89 50 04 mov %edx,0x4(%eax) + elm->prev = prev; +c0102b75: 8b 45 d4 mov -0x2c(%ebp),%eax +c0102b78: 8b 55 d0 mov -0x30(%ebp),%edx +c0102b7b: 89 10 mov %edx,(%eax) +} +c0102b7d: 90 nop +} +c0102b7e: 90 nop +} +c0102b7f: 90 nop +} +c0102b80: 90 nop +c0102b81: 89 ec mov %ebp,%esp +c0102b83: 5d pop %ebp +c0102b84: c3 ret + +c0102b85 : + +//用于分配指定数量的连续物理页。该函数实现了首次适应内存分配算法。 +static struct Page * +default_alloc_pages(size_t n) { +c0102b85: 55 push %ebp +c0102b86: 89 e5 mov %esp,%ebp +c0102b88: 83 ec 68 sub $0x68,%esp + assert(n > 0);// 确保请求的页数大于零 +c0102b8b: 83 7d 08 00 cmpl $0x0,0x8(%ebp) +c0102b8f: 75 24 jne c0102bb5 +c0102b91: c7 44 24 0c 90 67 10 movl $0xc0106790,0xc(%esp) +c0102b98: c0 +c0102b99: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c0102ba0: c0 +c0102ba1: c7 44 24 04 a6 00 00 movl $0xa6,0x4(%esp) +c0102ba8: 00 +c0102ba9: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c0102bb0: e8 7e e0 ff ff call c0100c33 <__panic> + if (n > nr_free) {// 检查请求的页数是否超过空闲页数 +c0102bb5: a1 e8 ce 11 c0 mov 0xc011cee8,%eax +c0102bba: 39 45 08 cmp %eax,0x8(%ebp) +c0102bbd: 76 0a jbe c0102bc9 + return NULL; +c0102bbf: b8 00 00 00 00 mov $0x0,%eax +c0102bc4: e9 34 01 00 00 jmp c0102cfd + } + struct Page *page = NULL;// 初始化分配的页指针 +c0102bc9: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + list_entry_t *le = &free_list; // 初始化链表迭代器 +c0102bd0: c7 45 f0 e0 ce 11 c0 movl $0xc011cee0,-0x10(%ebp) + // 遍历空闲列表,寻找第一个满足条件的块 + while ((le = list_next(le)) != &free_list) { +c0102bd7: eb 1c jmp c0102bf5 + struct Page *p = le2page(le, page_link);// 将链表节点转换为 Page 结构体 +c0102bd9: 8b 45 f0 mov -0x10(%ebp),%eax +c0102bdc: 83 e8 0c sub $0xc,%eax +c0102bdf: 89 45 ec mov %eax,-0x14(%ebp) + if (p->property >= n) {// 检查当前块的页数是否满足请求 +c0102be2: 8b 45 ec mov -0x14(%ebp),%eax +c0102be5: 8b 40 08 mov 0x8(%eax),%eax +c0102be8: 39 45 08 cmp %eax,0x8(%ebp) +c0102beb: 77 08 ja c0102bf5 + page = p;// 找到合适的块 +c0102bed: 8b 45 ec mov -0x14(%ebp),%eax +c0102bf0: 89 45 f4 mov %eax,-0xc(%ebp) + break;// 退出循环 +c0102bf3: eb 18 jmp c0102c0d +c0102bf5: 8b 45 f0 mov -0x10(%ebp),%eax +c0102bf8: 89 45 e4 mov %eax,-0x1c(%ebp) + return listelm->next; +c0102bfb: 8b 45 e4 mov -0x1c(%ebp),%eax +c0102bfe: 8b 40 04 mov 0x4(%eax),%eax + while ((le = list_next(le)) != &free_list) { +c0102c01: 89 45 f0 mov %eax,-0x10(%ebp) +c0102c04: 81 7d f0 e0 ce 11 c0 cmpl $0xc011cee0,-0x10(%ebp) +c0102c0b: 75 cc jne c0102bd9 + } + } + if (page != NULL) {// 如果找到合适的块 +c0102c0d: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c0102c11: 0f 84 e3 00 00 00 je c0102cfa + list_del(&(page->page_link));// 从空闲列表中删除该块 +c0102c17: 8b 45 f4 mov -0xc(%ebp),%eax +c0102c1a: 83 c0 0c add $0xc,%eax +c0102c1d: 89 45 e0 mov %eax,-0x20(%ebp) + __list_del(listelm->prev, listelm->next); +c0102c20: 8b 45 e0 mov -0x20(%ebp),%eax +c0102c23: 8b 40 04 mov 0x4(%eax),%eax +c0102c26: 8b 55 e0 mov -0x20(%ebp),%edx +c0102c29: 8b 12 mov (%edx),%edx +c0102c2b: 89 55 dc mov %edx,-0x24(%ebp) +c0102c2e: 89 45 d8 mov %eax,-0x28(%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; +c0102c31: 8b 45 dc mov -0x24(%ebp),%eax +c0102c34: 8b 55 d8 mov -0x28(%ebp),%edx +c0102c37: 89 50 04 mov %edx,0x4(%eax) + next->prev = prev; +c0102c3a: 8b 45 d8 mov -0x28(%ebp),%eax +c0102c3d: 8b 55 dc mov -0x24(%ebp),%edx +c0102c40: 89 10 mov %edx,(%eax) +} +c0102c42: 90 nop +} +c0102c43: 90 nop + if (page->property > n) { +c0102c44: 8b 45 f4 mov -0xc(%ebp),%eax +c0102c47: 8b 40 08 mov 0x8(%eax),%eax +c0102c4a: 39 45 08 cmp %eax,0x8(%ebp) +c0102c4d: 0f 83 80 00 00 00 jae c0102cd3 + struct Page *p = page + n; // 指向剩余的页 +c0102c53: 8b 55 08 mov 0x8(%ebp),%edx +c0102c56: 89 d0 mov %edx,%eax +c0102c58: c1 e0 02 shl $0x2,%eax +c0102c5b: 01 d0 add %edx,%eax +c0102c5d: c1 e0 02 shl $0x2,%eax +c0102c60: 89 c2 mov %eax,%edx +c0102c62: 8b 45 f4 mov -0xc(%ebp),%eax +c0102c65: 01 d0 add %edx,%eax +c0102c67: 89 45 e8 mov %eax,-0x18(%ebp) + p->property = page->property - n;// 更新剩余块的页数 +c0102c6a: 8b 45 f4 mov -0xc(%ebp),%eax +c0102c6d: 8b 40 08 mov 0x8(%eax),%eax +c0102c70: 2b 45 08 sub 0x8(%ebp),%eax +c0102c73: 89 c2 mov %eax,%edx +c0102c75: 8b 45 e8 mov -0x18(%ebp),%eax +c0102c78: 89 50 08 mov %edx,0x8(%eax) + list_add(&free_list, &(p->page_link));// 将剩余块添加回空闲列表 +c0102c7b: 8b 45 e8 mov -0x18(%ebp),%eax +c0102c7e: 83 c0 0c add $0xc,%eax +c0102c81: c7 45 d4 e0 ce 11 c0 movl $0xc011cee0,-0x2c(%ebp) +c0102c88: 89 45 d0 mov %eax,-0x30(%ebp) +c0102c8b: 8b 45 d4 mov -0x2c(%ebp),%eax +c0102c8e: 89 45 cc mov %eax,-0x34(%ebp) +c0102c91: 8b 45 d0 mov -0x30(%ebp),%eax +c0102c94: 89 45 c8 mov %eax,-0x38(%ebp) + __list_add(elm, listelm, listelm->next); +c0102c97: 8b 45 cc mov -0x34(%ebp),%eax +c0102c9a: 8b 40 04 mov 0x4(%eax),%eax +c0102c9d: 8b 55 c8 mov -0x38(%ebp),%edx +c0102ca0: 89 55 c4 mov %edx,-0x3c(%ebp) +c0102ca3: 8b 55 cc mov -0x34(%ebp),%edx +c0102ca6: 89 55 c0 mov %edx,-0x40(%ebp) +c0102ca9: 89 45 bc mov %eax,-0x44(%ebp) + prev->next = next->prev = elm; +c0102cac: 8b 45 bc mov -0x44(%ebp),%eax +c0102caf: 8b 55 c4 mov -0x3c(%ebp),%edx +c0102cb2: 89 10 mov %edx,(%eax) +c0102cb4: 8b 45 bc mov -0x44(%ebp),%eax +c0102cb7: 8b 10 mov (%eax),%edx +c0102cb9: 8b 45 c0 mov -0x40(%ebp),%eax +c0102cbc: 89 50 04 mov %edx,0x4(%eax) + elm->next = next; +c0102cbf: 8b 45 c4 mov -0x3c(%ebp),%eax +c0102cc2: 8b 55 bc mov -0x44(%ebp),%edx +c0102cc5: 89 50 04 mov %edx,0x4(%eax) + elm->prev = prev; +c0102cc8: 8b 45 c4 mov -0x3c(%ebp),%eax +c0102ccb: 8b 55 c0 mov -0x40(%ebp),%edx +c0102cce: 89 10 mov %edx,(%eax) +} +c0102cd0: 90 nop +} +c0102cd1: 90 nop +} +c0102cd2: 90 nop + } + nr_free -= n;// 减少空闲页的计数 +c0102cd3: a1 e8 ce 11 c0 mov 0xc011cee8,%eax +c0102cd8: 2b 45 08 sub 0x8(%ebp),%eax +c0102cdb: a3 e8 ce 11 c0 mov %eax,0xc011cee8 + ClearPageProperty(page); // 清除已分配页的属性 +c0102ce0: 8b 45 f4 mov -0xc(%ebp),%eax +c0102ce3: 83 c0 04 add $0x4,%eax +c0102ce6: c7 45 b8 01 00 00 00 movl $0x1,-0x48(%ebp) +c0102ced: 89 45 b4 mov %eax,-0x4c(%ebp) + asm volatile ("btrl %1, %0" :"=m" (*(volatile long *)addr) : "Ir" (nr)); +c0102cf0: 8b 45 b4 mov -0x4c(%ebp),%eax +c0102cf3: 8b 55 b8 mov -0x48(%ebp),%edx +c0102cf6: 0f b3 10 btr %edx,(%eax) +} +c0102cf9: 90 nop + } + return page;// 返回分配的页块 +c0102cfa: 8b 45 f4 mov -0xc(%ebp),%eax +} +c0102cfd: 89 ec mov %ebp,%esp +c0102cff: 5d pop %ebp +c0102d00: c3 ret + +c0102d01 : + +static void +default_free_pages(struct Page *base, size_t n) { +c0102d01: 55 push %ebp +c0102d02: 89 e5 mov %esp,%ebp +c0102d04: 81 ec 98 00 00 00 sub $0x98,%esp + assert(n > 0);// 确保请求释放的页数大于零 +c0102d0a: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) +c0102d0e: 75 24 jne c0102d34 +c0102d10: c7 44 24 0c 90 67 10 movl $0xc0106790,0xc(%esp) +c0102d17: c0 +c0102d18: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c0102d1f: c0 +c0102d20: c7 44 24 04 c3 00 00 movl $0xc3,0x4(%esp) +c0102d27: 00 +c0102d28: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c0102d2f: e8 ff de ff ff call c0100c33 <__panic> + struct Page *p = base; +c0102d34: 8b 45 08 mov 0x8(%ebp),%eax +c0102d37: 89 45 f4 mov %eax,-0xc(%ebp) + // 遍历释放的页,检查状态并重置 + for (; p != base + n; p ++) { +c0102d3a: e9 9d 00 00 00 jmp c0102ddc + assert(!PageReserved(p) && !PageProperty(p)); // 确保页没有被保留并且没有属性 +c0102d3f: 8b 45 f4 mov -0xc(%ebp),%eax +c0102d42: 83 c0 04 add $0x4,%eax +c0102d45: c7 45 ec 00 00 00 00 movl $0x0,-0x14(%ebp) +c0102d4c: 89 45 e8 mov %eax,-0x18(%ebp) + asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr)); +c0102d4f: 8b 45 e8 mov -0x18(%ebp),%eax +c0102d52: 8b 55 ec mov -0x14(%ebp),%edx +c0102d55: 0f a3 10 bt %edx,(%eax) +c0102d58: 19 c0 sbb %eax,%eax +c0102d5a: 89 45 e4 mov %eax,-0x1c(%ebp) + return oldbit != 0; +c0102d5d: 83 7d e4 00 cmpl $0x0,-0x1c(%ebp) +c0102d61: 0f 95 c0 setne %al +c0102d64: 0f b6 c0 movzbl %al,%eax +c0102d67: 85 c0 test %eax,%eax +c0102d69: 75 2c jne c0102d97 +c0102d6b: 8b 45 f4 mov -0xc(%ebp),%eax +c0102d6e: 83 c0 04 add $0x4,%eax +c0102d71: c7 45 e0 01 00 00 00 movl $0x1,-0x20(%ebp) +c0102d78: 89 45 dc mov %eax,-0x24(%ebp) + asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr)); +c0102d7b: 8b 45 dc mov -0x24(%ebp),%eax +c0102d7e: 8b 55 e0 mov -0x20(%ebp),%edx +c0102d81: 0f a3 10 bt %edx,(%eax) +c0102d84: 19 c0 sbb %eax,%eax +c0102d86: 89 45 d8 mov %eax,-0x28(%ebp) + return oldbit != 0; +c0102d89: 83 7d d8 00 cmpl $0x0,-0x28(%ebp) +c0102d8d: 0f 95 c0 setne %al +c0102d90: 0f b6 c0 movzbl %al,%eax +c0102d93: 85 c0 test %eax,%eax +c0102d95: 74 24 je c0102dbb +c0102d97: c7 44 24 0c d4 67 10 movl $0xc01067d4,0xc(%esp) +c0102d9e: c0 +c0102d9f: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c0102da6: c0 +c0102da7: c7 44 24 04 c7 00 00 movl $0xc7,0x4(%esp) +c0102dae: 00 +c0102daf: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c0102db6: e8 78 de ff ff call c0100c33 <__panic> + p->flags = 0;// 清除 flags 字段 +c0102dbb: 8b 45 f4 mov -0xc(%ebp),%eax +c0102dbe: c7 40 04 00 00 00 00 movl $0x0,0x4(%eax) + set_page_ref(p, 0);// 清除引用计数 +c0102dc5: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) +c0102dcc: 00 +c0102dcd: 8b 45 f4 mov -0xc(%ebp),%eax +c0102dd0: 89 04 24 mov %eax,(%esp) +c0102dd3: e8 0c fc ff ff call c01029e4 + for (; p != base + n; p ++) { +c0102dd8: 83 45 f4 14 addl $0x14,-0xc(%ebp) +c0102ddc: 8b 55 0c mov 0xc(%ebp),%edx +c0102ddf: 89 d0 mov %edx,%eax +c0102de1: c1 e0 02 shl $0x2,%eax +c0102de4: 01 d0 add %edx,%eax +c0102de6: c1 e0 02 shl $0x2,%eax +c0102de9: 89 c2 mov %eax,%edx +c0102deb: 8b 45 08 mov 0x8(%ebp),%eax +c0102dee: 01 d0 add %edx,%eax +c0102df0: 39 45 f4 cmp %eax,-0xc(%ebp) +c0102df3: 0f 85 46 ff ff ff jne c0102d3f + } + // 设置基页的属性为释放的页数 + base->property = n; +c0102df9: 8b 45 08 mov 0x8(%ebp),%eax +c0102dfc: 8b 55 0c mov 0xc(%ebp),%edx +c0102dff: 89 50 08 mov %edx,0x8(%eax) + SetPageProperty(base);// 设置页的有效标志 +c0102e02: 8b 45 08 mov 0x8(%ebp),%eax +c0102e05: 83 c0 04 add $0x4,%eax +c0102e08: c7 45 d0 01 00 00 00 movl $0x1,-0x30(%ebp) +c0102e0f: 89 45 cc mov %eax,-0x34(%ebp) + asm volatile ("btsl %1, %0" :"=m" (*(volatile long *)addr) : "Ir" (nr)); +c0102e12: 8b 45 cc mov -0x34(%ebp),%eax +c0102e15: 8b 55 d0 mov -0x30(%ebp),%edx +c0102e18: 0f ab 10 bts %edx,(%eax) +} +c0102e1b: 90 nop +c0102e1c: c7 45 d4 e0 ce 11 c0 movl $0xc011cee0,-0x2c(%ebp) + return listelm->next; +c0102e23: 8b 45 d4 mov -0x2c(%ebp),%eax +c0102e26: 8b 40 04 mov 0x4(%eax),%eax + // 遍历空闲列表,检查是否需要合并 + list_entry_t *le = list_next(&free_list); +c0102e29: 89 45 f0 mov %eax,-0x10(%ebp) + while (le != &free_list) { +c0102e2c: e9 0e 01 00 00 jmp c0102f3f + p = le2page(le, page_link); +c0102e31: 8b 45 f0 mov -0x10(%ebp),%eax +c0102e34: 83 e8 0c sub $0xc,%eax +c0102e37: 89 45 f4 mov %eax,-0xc(%ebp) +c0102e3a: 8b 45 f0 mov -0x10(%ebp),%eax +c0102e3d: 89 45 c8 mov %eax,-0x38(%ebp) +c0102e40: 8b 45 c8 mov -0x38(%ebp),%eax +c0102e43: 8b 40 04 mov 0x4(%eax),%eax + le = list_next(le); +c0102e46: 89 45 f0 mov %eax,-0x10(%ebp) + // 如果当前页块与释放的页块相邻,合并 + if (base + base->property == p) { +c0102e49: 8b 45 08 mov 0x8(%ebp),%eax +c0102e4c: 8b 50 08 mov 0x8(%eax),%edx +c0102e4f: 89 d0 mov %edx,%eax +c0102e51: c1 e0 02 shl $0x2,%eax +c0102e54: 01 d0 add %edx,%eax +c0102e56: c1 e0 02 shl $0x2,%eax +c0102e59: 89 c2 mov %eax,%edx +c0102e5b: 8b 45 08 mov 0x8(%ebp),%eax +c0102e5e: 01 d0 add %edx,%eax +c0102e60: 39 45 f4 cmp %eax,-0xc(%ebp) +c0102e63: 75 5d jne c0102ec2 + base->property += p->property;// 合并当前页块 +c0102e65: 8b 45 08 mov 0x8(%ebp),%eax +c0102e68: 8b 50 08 mov 0x8(%eax),%edx +c0102e6b: 8b 45 f4 mov -0xc(%ebp),%eax +c0102e6e: 8b 40 08 mov 0x8(%eax),%eax +c0102e71: 01 c2 add %eax,%edx +c0102e73: 8b 45 08 mov 0x8(%ebp),%eax +c0102e76: 89 50 08 mov %edx,0x8(%eax) + ClearPageProperty(p);// 清除合并页的属性 +c0102e79: 8b 45 f4 mov -0xc(%ebp),%eax +c0102e7c: 83 c0 04 add $0x4,%eax +c0102e7f: c7 45 b8 01 00 00 00 movl $0x1,-0x48(%ebp) +c0102e86: 89 45 b4 mov %eax,-0x4c(%ebp) + asm volatile ("btrl %1, %0" :"=m" (*(volatile long *)addr) : "Ir" (nr)); +c0102e89: 8b 45 b4 mov -0x4c(%ebp),%eax +c0102e8c: 8b 55 b8 mov -0x48(%ebp),%edx +c0102e8f: 0f b3 10 btr %edx,(%eax) +} +c0102e92: 90 nop + list_del(&(p->page_link));// 从空闲列表中删除合并页 +c0102e93: 8b 45 f4 mov -0xc(%ebp),%eax +c0102e96: 83 c0 0c add $0xc,%eax +c0102e99: 89 45 c4 mov %eax,-0x3c(%ebp) + __list_del(listelm->prev, listelm->next); +c0102e9c: 8b 45 c4 mov -0x3c(%ebp),%eax +c0102e9f: 8b 40 04 mov 0x4(%eax),%eax +c0102ea2: 8b 55 c4 mov -0x3c(%ebp),%edx +c0102ea5: 8b 12 mov (%edx),%edx +c0102ea7: 89 55 c0 mov %edx,-0x40(%ebp) +c0102eaa: 89 45 bc mov %eax,-0x44(%ebp) + prev->next = next; +c0102ead: 8b 45 c0 mov -0x40(%ebp),%eax +c0102eb0: 8b 55 bc mov -0x44(%ebp),%edx +c0102eb3: 89 50 04 mov %edx,0x4(%eax) + next->prev = prev; +c0102eb6: 8b 45 bc mov -0x44(%ebp),%eax +c0102eb9: 8b 55 c0 mov -0x40(%ebp),%edx +c0102ebc: 89 10 mov %edx,(%eax) +} +c0102ebe: 90 nop +} +c0102ebf: 90 nop +c0102ec0: eb 7d jmp c0102f3f + } + else if (p + p->property == base) { +c0102ec2: 8b 45 f4 mov -0xc(%ebp),%eax +c0102ec5: 8b 50 08 mov 0x8(%eax),%edx +c0102ec8: 89 d0 mov %edx,%eax +c0102eca: c1 e0 02 shl $0x2,%eax +c0102ecd: 01 d0 add %edx,%eax +c0102ecf: c1 e0 02 shl $0x2,%eax +c0102ed2: 89 c2 mov %eax,%edx +c0102ed4: 8b 45 f4 mov -0xc(%ebp),%eax +c0102ed7: 01 d0 add %edx,%eax +c0102ed9: 39 45 08 cmp %eax,0x8(%ebp) +c0102edc: 75 61 jne c0102f3f + p->property += base->property;// 合并前一个页块 +c0102ede: 8b 45 f4 mov -0xc(%ebp),%eax +c0102ee1: 8b 50 08 mov 0x8(%eax),%edx +c0102ee4: 8b 45 08 mov 0x8(%ebp),%eax +c0102ee7: 8b 40 08 mov 0x8(%eax),%eax +c0102eea: 01 c2 add %eax,%edx +c0102eec: 8b 45 f4 mov -0xc(%ebp),%eax +c0102eef: 89 50 08 mov %edx,0x8(%eax) + ClearPageProperty(base);// 清除当前页的属性 +c0102ef2: 8b 45 08 mov 0x8(%ebp),%eax +c0102ef5: 83 c0 04 add $0x4,%eax +c0102ef8: c7 45 a4 01 00 00 00 movl $0x1,-0x5c(%ebp) +c0102eff: 89 45 a0 mov %eax,-0x60(%ebp) + asm volatile ("btrl %1, %0" :"=m" (*(volatile long *)addr) : "Ir" (nr)); +c0102f02: 8b 45 a0 mov -0x60(%ebp),%eax +c0102f05: 8b 55 a4 mov -0x5c(%ebp),%edx +c0102f08: 0f b3 10 btr %edx,(%eax) +} +c0102f0b: 90 nop + base = p;// 更新 base 指针 +c0102f0c: 8b 45 f4 mov -0xc(%ebp),%eax +c0102f0f: 89 45 08 mov %eax,0x8(%ebp) + list_del(&(p->page_link)); // 从空闲列表中删除当前页 +c0102f12: 8b 45 f4 mov -0xc(%ebp),%eax +c0102f15: 83 c0 0c add $0xc,%eax +c0102f18: 89 45 b0 mov %eax,-0x50(%ebp) + __list_del(listelm->prev, listelm->next); +c0102f1b: 8b 45 b0 mov -0x50(%ebp),%eax +c0102f1e: 8b 40 04 mov 0x4(%eax),%eax +c0102f21: 8b 55 b0 mov -0x50(%ebp),%edx +c0102f24: 8b 12 mov (%edx),%edx +c0102f26: 89 55 ac mov %edx,-0x54(%ebp) +c0102f29: 89 45 a8 mov %eax,-0x58(%ebp) + prev->next = next; +c0102f2c: 8b 45 ac mov -0x54(%ebp),%eax +c0102f2f: 8b 55 a8 mov -0x58(%ebp),%edx +c0102f32: 89 50 04 mov %edx,0x4(%eax) + next->prev = prev; +c0102f35: 8b 45 a8 mov -0x58(%ebp),%eax +c0102f38: 8b 55 ac mov -0x54(%ebp),%edx +c0102f3b: 89 10 mov %edx,(%eax) +} +c0102f3d: 90 nop +} +c0102f3e: 90 nop + while (le != &free_list) { +c0102f3f: 81 7d f0 e0 ce 11 c0 cmpl $0xc011cee0,-0x10(%ebp) +c0102f46: 0f 85 e5 fe ff ff jne c0102e31 + } + } + nr_free += n;// 更新空闲页的计数 +c0102f4c: 8b 15 e8 ce 11 c0 mov 0xc011cee8,%edx +c0102f52: 8b 45 0c mov 0xc(%ebp),%eax +c0102f55: 01 d0 add %edx,%eax +c0102f57: a3 e8 ce 11 c0 mov %eax,0xc011cee8 + list_add(&free_list, &(base->page_link));// 将释放的页块添加到空闲列表中 +c0102f5c: 8b 45 08 mov 0x8(%ebp),%eax +c0102f5f: 83 c0 0c add $0xc,%eax +c0102f62: c7 45 9c e0 ce 11 c0 movl $0xc011cee0,-0x64(%ebp) +c0102f69: 89 45 98 mov %eax,-0x68(%ebp) +c0102f6c: 8b 45 9c mov -0x64(%ebp),%eax +c0102f6f: 89 45 94 mov %eax,-0x6c(%ebp) +c0102f72: 8b 45 98 mov -0x68(%ebp),%eax +c0102f75: 89 45 90 mov %eax,-0x70(%ebp) + __list_add(elm, listelm, listelm->next); +c0102f78: 8b 45 94 mov -0x6c(%ebp),%eax +c0102f7b: 8b 40 04 mov 0x4(%eax),%eax +c0102f7e: 8b 55 90 mov -0x70(%ebp),%edx +c0102f81: 89 55 8c mov %edx,-0x74(%ebp) +c0102f84: 8b 55 94 mov -0x6c(%ebp),%edx +c0102f87: 89 55 88 mov %edx,-0x78(%ebp) +c0102f8a: 89 45 84 mov %eax,-0x7c(%ebp) + prev->next = next->prev = elm; +c0102f8d: 8b 45 84 mov -0x7c(%ebp),%eax +c0102f90: 8b 55 8c mov -0x74(%ebp),%edx +c0102f93: 89 10 mov %edx,(%eax) +c0102f95: 8b 45 84 mov -0x7c(%ebp),%eax +c0102f98: 8b 10 mov (%eax),%edx +c0102f9a: 8b 45 88 mov -0x78(%ebp),%eax +c0102f9d: 89 50 04 mov %edx,0x4(%eax) + elm->next = next; +c0102fa0: 8b 45 8c mov -0x74(%ebp),%eax +c0102fa3: 8b 55 84 mov -0x7c(%ebp),%edx +c0102fa6: 89 50 04 mov %edx,0x4(%eax) + elm->prev = prev; +c0102fa9: 8b 45 8c mov -0x74(%ebp),%eax +c0102fac: 8b 55 88 mov -0x78(%ebp),%edx +c0102faf: 89 10 mov %edx,(%eax) +} +c0102fb1: 90 nop +} +c0102fb2: 90 nop +} +c0102fb3: 90 nop +} +c0102fb4: 90 nop +c0102fb5: 89 ec mov %ebp,%esp +c0102fb7: 5d pop %ebp +c0102fb8: c3 ret + +c0102fb9 : + +//用于返回当前系统中可用的空闲页的数量。 +static size_t +default_nr_free_pages(void) { +c0102fb9: 55 push %ebp +c0102fba: 89 e5 mov %esp,%ebp + return nr_free;// 返回当前空闲页的数量 +c0102fbc: a1 e8 ce 11 c0 mov 0xc011cee8,%eax +} +c0102fc1: 5d pop %ebp +c0102fc2: c3 ret + +c0102fc3 : + +//basic_check 函数用于测试内存分配和释放的基本功能, +//确保在不同情况下内存管理系统的正确性,包括分配、释放、合并和引用计数等操作。 +static void +basic_check(void) { +c0102fc3: 55 push %ebp +c0102fc4: 89 e5 mov %esp,%ebp +c0102fc6: 83 ec 48 sub $0x48,%esp + struct Page *p0, *p1, *p2; + p0 = p1 = p2 = NULL; +c0102fc9: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) +c0102fd0: 8b 45 f4 mov -0xc(%ebp),%eax +c0102fd3: 89 45 f0 mov %eax,-0x10(%ebp) +c0102fd6: 8b 45 f0 mov -0x10(%ebp),%eax +c0102fd9: 89 45 ec mov %eax,-0x14(%ebp) + // 分配三个页面 + assert((p0 = alloc_page()) != NULL); +c0102fdc: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c0102fe3: e8 ed 0e 00 00 call c0103ed5 +c0102fe8: 89 45 ec mov %eax,-0x14(%ebp) +c0102feb: 83 7d ec 00 cmpl $0x0,-0x14(%ebp) +c0102fef: 75 24 jne c0103015 +c0102ff1: c7 44 24 0c f9 67 10 movl $0xc01067f9,0xc(%esp) +c0102ff8: c0 +c0102ff9: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c0103000: c0 +c0103001: c7 44 24 04 f1 00 00 movl $0xf1,0x4(%esp) +c0103008: 00 +c0103009: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c0103010: e8 1e dc ff ff call c0100c33 <__panic> + assert((p1 = alloc_page()) != NULL); +c0103015: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c010301c: e8 b4 0e 00 00 call c0103ed5 +c0103021: 89 45 f0 mov %eax,-0x10(%ebp) +c0103024: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) +c0103028: 75 24 jne c010304e +c010302a: c7 44 24 0c 15 68 10 movl $0xc0106815,0xc(%esp) +c0103031: c0 +c0103032: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c0103039: c0 +c010303a: c7 44 24 04 f2 00 00 movl $0xf2,0x4(%esp) +c0103041: 00 +c0103042: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c0103049: e8 e5 db ff ff call c0100c33 <__panic> + assert((p2 = alloc_page()) != NULL); +c010304e: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c0103055: e8 7b 0e 00 00 call c0103ed5 +c010305a: 89 45 f4 mov %eax,-0xc(%ebp) +c010305d: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c0103061: 75 24 jne c0103087 +c0103063: c7 44 24 0c 31 68 10 movl $0xc0106831,0xc(%esp) +c010306a: c0 +c010306b: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c0103072: c0 +c0103073: c7 44 24 04 f3 00 00 movl $0xf3,0x4(%esp) +c010307a: 00 +c010307b: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c0103082: e8 ac db ff ff call c0100c33 <__panic> + // 确保所有分配的页面是不同的 + assert(p0 != p1 && p0 != p2 && p1 != p2); +c0103087: 8b 45 ec mov -0x14(%ebp),%eax +c010308a: 3b 45 f0 cmp -0x10(%ebp),%eax +c010308d: 74 10 je c010309f +c010308f: 8b 45 ec mov -0x14(%ebp),%eax +c0103092: 3b 45 f4 cmp -0xc(%ebp),%eax +c0103095: 74 08 je c010309f +c0103097: 8b 45 f0 mov -0x10(%ebp),%eax +c010309a: 3b 45 f4 cmp -0xc(%ebp),%eax +c010309d: 75 24 jne c01030c3 +c010309f: c7 44 24 0c 50 68 10 movl $0xc0106850,0xc(%esp) +c01030a6: c0 +c01030a7: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c01030ae: c0 +c01030af: c7 44 24 04 f5 00 00 movl $0xf5,0x4(%esp) +c01030b6: 00 +c01030b7: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c01030be: e8 70 db ff ff call c0100c33 <__panic> + // 确保页面的引用计数为 0 + assert(page_ref(p0) == 0 && page_ref(p1) == 0 && page_ref(p2) == 0); +c01030c3: 8b 45 ec mov -0x14(%ebp),%eax +c01030c6: 89 04 24 mov %eax,(%esp) +c01030c9: e8 0c f9 ff ff call c01029da +c01030ce: 85 c0 test %eax,%eax +c01030d0: 75 1e jne c01030f0 +c01030d2: 8b 45 f0 mov -0x10(%ebp),%eax +c01030d5: 89 04 24 mov %eax,(%esp) +c01030d8: e8 fd f8 ff ff call c01029da +c01030dd: 85 c0 test %eax,%eax +c01030df: 75 0f jne c01030f0 +c01030e1: 8b 45 f4 mov -0xc(%ebp),%eax +c01030e4: 89 04 24 mov %eax,(%esp) +c01030e7: e8 ee f8 ff ff call c01029da +c01030ec: 85 c0 test %eax,%eax +c01030ee: 74 24 je c0103114 +c01030f0: c7 44 24 0c 74 68 10 movl $0xc0106874,0xc(%esp) +c01030f7: c0 +c01030f8: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c01030ff: c0 +c0103100: c7 44 24 04 f7 00 00 movl $0xf7,0x4(%esp) +c0103107: 00 +c0103108: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c010310f: e8 1f db ff ff call c0100c33 <__panic> + // 确保页面地址在合法范围内 + assert(page2pa(p0) < npage * PGSIZE); +c0103114: 8b 45 ec mov -0x14(%ebp),%eax +c0103117: 89 04 24 mov %eax,(%esp) +c010311a: e8 a3 f8 ff ff call c01029c2 +c010311f: 8b 15 04 cf 11 c0 mov 0xc011cf04,%edx +c0103125: c1 e2 0c shl $0xc,%edx +c0103128: 39 d0 cmp %edx,%eax +c010312a: 72 24 jb c0103150 +c010312c: c7 44 24 0c b0 68 10 movl $0xc01068b0,0xc(%esp) +c0103133: c0 +c0103134: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c010313b: c0 +c010313c: c7 44 24 04 f9 00 00 movl $0xf9,0x4(%esp) +c0103143: 00 +c0103144: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c010314b: e8 e3 da ff ff call c0100c33 <__panic> + assert(page2pa(p1) < npage * PGSIZE); +c0103150: 8b 45 f0 mov -0x10(%ebp),%eax +c0103153: 89 04 24 mov %eax,(%esp) +c0103156: e8 67 f8 ff ff call c01029c2 +c010315b: 8b 15 04 cf 11 c0 mov 0xc011cf04,%edx +c0103161: c1 e2 0c shl $0xc,%edx +c0103164: 39 d0 cmp %edx,%eax +c0103166: 72 24 jb c010318c +c0103168: c7 44 24 0c cd 68 10 movl $0xc01068cd,0xc(%esp) +c010316f: c0 +c0103170: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c0103177: c0 +c0103178: c7 44 24 04 fa 00 00 movl $0xfa,0x4(%esp) +c010317f: 00 +c0103180: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c0103187: e8 a7 da ff ff call c0100c33 <__panic> + assert(page2pa(p2) < npage * PGSIZE); +c010318c: 8b 45 f4 mov -0xc(%ebp),%eax +c010318f: 89 04 24 mov %eax,(%esp) +c0103192: e8 2b f8 ff ff call c01029c2 +c0103197: 8b 15 04 cf 11 c0 mov 0xc011cf04,%edx +c010319d: c1 e2 0c shl $0xc,%edx +c01031a0: 39 d0 cmp %edx,%eax +c01031a2: 72 24 jb c01031c8 +c01031a4: c7 44 24 0c ea 68 10 movl $0xc01068ea,0xc(%esp) +c01031ab: c0 +c01031ac: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c01031b3: c0 +c01031b4: c7 44 24 04 fb 00 00 movl $0xfb,0x4(%esp) +c01031bb: 00 +c01031bc: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c01031c3: e8 6b da ff ff call c0100c33 <__panic> + // 保存当前的空闲页面链表和数量 + list_entry_t free_list_store = free_list; +c01031c8: a1 e0 ce 11 c0 mov 0xc011cee0,%eax +c01031cd: 8b 15 e4 ce 11 c0 mov 0xc011cee4,%edx +c01031d3: 89 45 d0 mov %eax,-0x30(%ebp) +c01031d6: 89 55 d4 mov %edx,-0x2c(%ebp) +c01031d9: c7 45 dc e0 ce 11 c0 movl $0xc011cee0,-0x24(%ebp) + elm->prev = elm->next = elm; +c01031e0: 8b 45 dc mov -0x24(%ebp),%eax +c01031e3: 8b 55 dc mov -0x24(%ebp),%edx +c01031e6: 89 50 04 mov %edx,0x4(%eax) +c01031e9: 8b 45 dc mov -0x24(%ebp),%eax +c01031ec: 8b 50 04 mov 0x4(%eax),%edx +c01031ef: 8b 45 dc mov -0x24(%ebp),%eax +c01031f2: 89 10 mov %edx,(%eax) +} +c01031f4: 90 nop +c01031f5: c7 45 e0 e0 ce 11 c0 movl $0xc011cee0,-0x20(%ebp) + return list->next == list; +c01031fc: 8b 45 e0 mov -0x20(%ebp),%eax +c01031ff: 8b 40 04 mov 0x4(%eax),%eax +c0103202: 39 45 e0 cmp %eax,-0x20(%ebp) +c0103205: 0f 94 c0 sete %al +c0103208: 0f b6 c0 movzbl %al,%eax + list_init(&free_list);// 初始化空闲列表 + assert(list_empty(&free_list));// 确保空闲列表为空 +c010320b: 85 c0 test %eax,%eax +c010320d: 75 24 jne c0103233 +c010320f: c7 44 24 0c 07 69 10 movl $0xc0106907,0xc(%esp) +c0103216: c0 +c0103217: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c010321e: c0 +c010321f: c7 44 24 04 ff 00 00 movl $0xff,0x4(%esp) +c0103226: 00 +c0103227: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c010322e: e8 00 da ff ff call c0100c33 <__panic> + + unsigned int nr_free_store = nr_free;// 保存当前空闲页数量 +c0103233: a1 e8 ce 11 c0 mov 0xc011cee8,%eax +c0103238: 89 45 e8 mov %eax,-0x18(%ebp) + nr_free = 0;// 将空闲页数量设为 0 +c010323b: c7 05 e8 ce 11 c0 00 movl $0x0,0xc011cee8 +c0103242: 00 00 00 + // 请求分配页面,但当前没有空闲页面 + assert(alloc_page() == NULL); +c0103245: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c010324c: e8 84 0c 00 00 call c0103ed5 +c0103251: 85 c0 test %eax,%eax +c0103253: 74 24 je c0103279 +c0103255: c7 44 24 0c 1e 69 10 movl $0xc010691e,0xc(%esp) +c010325c: c0 +c010325d: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c0103264: c0 +c0103265: c7 44 24 04 04 01 00 movl $0x104,0x4(%esp) +c010326c: 00 +c010326d: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c0103274: e8 ba d9 ff ff call c0100c33 <__panic> + // 释放之前分配的页面 + free_page(p0); +c0103279: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c0103280: 00 +c0103281: 8b 45 ec mov -0x14(%ebp),%eax +c0103284: 89 04 24 mov %eax,(%esp) +c0103287: e8 83 0c 00 00 call c0103f0f + free_page(p1); +c010328c: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c0103293: 00 +c0103294: 8b 45 f0 mov -0x10(%ebp),%eax +c0103297: 89 04 24 mov %eax,(%esp) +c010329a: e8 70 0c 00 00 call c0103f0f + free_page(p2); +c010329f: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c01032a6: 00 +c01032a7: 8b 45 f4 mov -0xc(%ebp),%eax +c01032aa: 89 04 24 mov %eax,(%esp) +c01032ad: e8 5d 0c 00 00 call c0103f0f + assert(nr_free == 3);// 确保释放后空闲页数量为 3 +c01032b2: a1 e8 ce 11 c0 mov 0xc011cee8,%eax +c01032b7: 83 f8 03 cmp $0x3,%eax +c01032ba: 74 24 je c01032e0 +c01032bc: c7 44 24 0c 33 69 10 movl $0xc0106933,0xc(%esp) +c01032c3: c0 +c01032c4: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c01032cb: c0 +c01032cc: c7 44 24 04 09 01 00 movl $0x109,0x4(%esp) +c01032d3: 00 +c01032d4: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c01032db: e8 53 d9 ff ff call c0100c33 <__panic> + // 再次分配三个页面 + assert((p0 = alloc_page()) != NULL); +c01032e0: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c01032e7: e8 e9 0b 00 00 call c0103ed5 +c01032ec: 89 45 ec mov %eax,-0x14(%ebp) +c01032ef: 83 7d ec 00 cmpl $0x0,-0x14(%ebp) +c01032f3: 75 24 jne c0103319 +c01032f5: c7 44 24 0c f9 67 10 movl $0xc01067f9,0xc(%esp) +c01032fc: c0 +c01032fd: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c0103304: c0 +c0103305: c7 44 24 04 0b 01 00 movl $0x10b,0x4(%esp) +c010330c: 00 +c010330d: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c0103314: e8 1a d9 ff ff call c0100c33 <__panic> + assert((p1 = alloc_page()) != NULL); +c0103319: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c0103320: e8 b0 0b 00 00 call c0103ed5 +c0103325: 89 45 f0 mov %eax,-0x10(%ebp) +c0103328: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) +c010332c: 75 24 jne c0103352 +c010332e: c7 44 24 0c 15 68 10 movl $0xc0106815,0xc(%esp) +c0103335: c0 +c0103336: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c010333d: c0 +c010333e: c7 44 24 04 0c 01 00 movl $0x10c,0x4(%esp) +c0103345: 00 +c0103346: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c010334d: e8 e1 d8 ff ff call c0100c33 <__panic> + assert((p2 = alloc_page()) != NULL); +c0103352: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c0103359: e8 77 0b 00 00 call c0103ed5 +c010335e: 89 45 f4 mov %eax,-0xc(%ebp) +c0103361: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c0103365: 75 24 jne c010338b +c0103367: c7 44 24 0c 31 68 10 movl $0xc0106831,0xc(%esp) +c010336e: c0 +c010336f: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c0103376: c0 +c0103377: c7 44 24 04 0d 01 00 movl $0x10d,0x4(%esp) +c010337e: 00 +c010337f: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c0103386: e8 a8 d8 ff ff call c0100c33 <__panic> +// 测试空闲页面是否不足 + assert(alloc_page() == NULL); +c010338b: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c0103392: e8 3e 0b 00 00 call c0103ed5 +c0103397: 85 c0 test %eax,%eax +c0103399: 74 24 je c01033bf +c010339b: c7 44 24 0c 1e 69 10 movl $0xc010691e,0xc(%esp) +c01033a2: c0 +c01033a3: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c01033aa: c0 +c01033ab: c7 44 24 04 0f 01 00 movl $0x10f,0x4(%esp) +c01033b2: 00 +c01033b3: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c01033ba: e8 74 d8 ff ff call c0100c33 <__panic> +// 释放 p0,并检查空闲列表 + free_page(p0); +c01033bf: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c01033c6: 00 +c01033c7: 8b 45 ec mov -0x14(%ebp),%eax +c01033ca: 89 04 24 mov %eax,(%esp) +c01033cd: e8 3d 0b 00 00 call c0103f0f +c01033d2: c7 45 d8 e0 ce 11 c0 movl $0xc011cee0,-0x28(%ebp) +c01033d9: 8b 45 d8 mov -0x28(%ebp),%eax +c01033dc: 8b 40 04 mov 0x4(%eax),%eax +c01033df: 39 45 d8 cmp %eax,-0x28(%ebp) +c01033e2: 0f 94 c0 sete %al +c01033e5: 0f b6 c0 movzbl %al,%eax + assert(!list_empty(&free_list));// 确保空闲列表不为空 +c01033e8: 85 c0 test %eax,%eax +c01033ea: 74 24 je c0103410 +c01033ec: c7 44 24 0c 40 69 10 movl $0xc0106940,0xc(%esp) +c01033f3: c0 +c01033f4: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c01033fb: c0 +c01033fc: c7 44 24 04 12 01 00 movl $0x112,0x4(%esp) +c0103403: 00 +c0103404: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c010340b: e8 23 d8 ff ff call c0100c33 <__panic> + + struct Page *p; + // 重新分配 p0,确保取回的是相同的页面 + assert((p = alloc_page()) == p0); +c0103410: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c0103417: e8 b9 0a 00 00 call c0103ed5 +c010341c: 89 45 e4 mov %eax,-0x1c(%ebp) +c010341f: 8b 45 e4 mov -0x1c(%ebp),%eax +c0103422: 3b 45 ec cmp -0x14(%ebp),%eax +c0103425: 74 24 je c010344b +c0103427: c7 44 24 0c 58 69 10 movl $0xc0106958,0xc(%esp) +c010342e: c0 +c010342f: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c0103436: c0 +c0103437: c7 44 24 04 16 01 00 movl $0x116,0x4(%esp) +c010343e: 00 +c010343f: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c0103446: e8 e8 d7 ff ff call c0100c33 <__panic> + assert(alloc_page() == NULL); // 确保没有更多的页面可分配 +c010344b: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c0103452: e8 7e 0a 00 00 call c0103ed5 +c0103457: 85 c0 test %eax,%eax +c0103459: 74 24 je c010347f +c010345b: c7 44 24 0c 1e 69 10 movl $0xc010691e,0xc(%esp) +c0103462: c0 +c0103463: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c010346a: c0 +c010346b: c7 44 24 04 17 01 00 movl $0x117,0x4(%esp) +c0103472: 00 +c0103473: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c010347a: e8 b4 d7 ff ff call c0100c33 <__panic> + + assert(nr_free == 0);// 确保当前空闲页面数量为 0 +c010347f: a1 e8 ce 11 c0 mov 0xc011cee8,%eax +c0103484: 85 c0 test %eax,%eax +c0103486: 74 24 je c01034ac +c0103488: c7 44 24 0c 71 69 10 movl $0xc0106971,0xc(%esp) +c010348f: c0 +c0103490: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c0103497: c0 +c0103498: c7 44 24 04 19 01 00 movl $0x119,0x4(%esp) +c010349f: 00 +c01034a0: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c01034a7: e8 87 d7 ff ff call c0100c33 <__panic> + // 恢复之前的空闲页面链表和数量 + free_list = free_list_store; +c01034ac: 8b 45 d0 mov -0x30(%ebp),%eax +c01034af: 8b 55 d4 mov -0x2c(%ebp),%edx +c01034b2: a3 e0 ce 11 c0 mov %eax,0xc011cee0 +c01034b7: 89 15 e4 ce 11 c0 mov %edx,0xc011cee4 + nr_free = nr_free_store; +c01034bd: 8b 45 e8 mov -0x18(%ebp),%eax +c01034c0: a3 e8 ce 11 c0 mov %eax,0xc011cee8 + // 释放最后的页面 + free_page(p); +c01034c5: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c01034cc: 00 +c01034cd: 8b 45 e4 mov -0x1c(%ebp),%eax +c01034d0: 89 04 24 mov %eax,(%esp) +c01034d3: e8 37 0a 00 00 call c0103f0f + free_page(p1); +c01034d8: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c01034df: 00 +c01034e0: 8b 45 f0 mov -0x10(%ebp),%eax +c01034e3: 89 04 24 mov %eax,(%esp) +c01034e6: e8 24 0a 00 00 call c0103f0f + free_page(p2); +c01034eb: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c01034f2: 00 +c01034f3: 8b 45 f4 mov -0xc(%ebp),%eax +c01034f6: 89 04 24 mov %eax,(%esp) +c01034f9: e8 11 0a 00 00 call c0103f0f +} +c01034fe: 90 nop +c01034ff: 89 ec mov %ebp,%esp +c0103501: 5d pop %ebp +c0103502: c3 ret + +c0103503 : + +// 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) { +c0103503: 55 push %ebp +c0103504: 89 e5 mov %esp,%ebp +c0103506: 81 ec 98 00 00 00 sub $0x98,%esp + int count = 0, total = 0; +c010350c: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) +c0103513: c7 45 f0 00 00 00 00 movl $0x0,-0x10(%ebp) + list_entry_t *le = &free_list; +c010351a: c7 45 ec e0 ce 11 c0 movl $0xc011cee0,-0x14(%ebp) + // 遍历空闲列表,计算空闲页面的数量和总属性值 + while ((le = list_next(le)) != &free_list) { +c0103521: eb 6a jmp c010358d + struct Page *p = le2page(le, page_link); +c0103523: 8b 45 ec mov -0x14(%ebp),%eax +c0103526: 83 e8 0c sub $0xc,%eax +c0103529: 89 45 d4 mov %eax,-0x2c(%ebp) + assert(PageProperty(p));// 确保每个页面的属性是有效的 +c010352c: 8b 45 d4 mov -0x2c(%ebp),%eax +c010352f: 83 c0 04 add $0x4,%eax +c0103532: c7 45 d0 01 00 00 00 movl $0x1,-0x30(%ebp) +c0103539: 89 45 cc mov %eax,-0x34(%ebp) + asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr)); +c010353c: 8b 45 cc mov -0x34(%ebp),%eax +c010353f: 8b 55 d0 mov -0x30(%ebp),%edx +c0103542: 0f a3 10 bt %edx,(%eax) +c0103545: 19 c0 sbb %eax,%eax +c0103547: 89 45 c8 mov %eax,-0x38(%ebp) + return oldbit != 0; +c010354a: 83 7d c8 00 cmpl $0x0,-0x38(%ebp) +c010354e: 0f 95 c0 setne %al +c0103551: 0f b6 c0 movzbl %al,%eax +c0103554: 85 c0 test %eax,%eax +c0103556: 75 24 jne c010357c +c0103558: c7 44 24 0c 7e 69 10 movl $0xc010697e,0xc(%esp) +c010355f: c0 +c0103560: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c0103567: c0 +c0103568: c7 44 24 04 2c 01 00 movl $0x12c,0x4(%esp) +c010356f: 00 +c0103570: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c0103577: e8 b7 d6 ff ff call c0100c33 <__panic> + count ++, total += p->property;// 累加页面属性 +c010357c: ff 45 f4 incl -0xc(%ebp) +c010357f: 8b 45 d4 mov -0x2c(%ebp),%eax +c0103582: 8b 50 08 mov 0x8(%eax),%edx +c0103585: 8b 45 f0 mov -0x10(%ebp),%eax +c0103588: 01 d0 add %edx,%eax +c010358a: 89 45 f0 mov %eax,-0x10(%ebp) +c010358d: 8b 45 ec mov -0x14(%ebp),%eax +c0103590: 89 45 c4 mov %eax,-0x3c(%ebp) + return listelm->next; +c0103593: 8b 45 c4 mov -0x3c(%ebp),%eax +c0103596: 8b 40 04 mov 0x4(%eax),%eax + while ((le = list_next(le)) != &free_list) { +c0103599: 89 45 ec mov %eax,-0x14(%ebp) +c010359c: 81 7d ec e0 ce 11 c0 cmpl $0xc011cee0,-0x14(%ebp) +c01035a3: 0f 85 7a ff ff ff jne c0103523 + } + // 确保总属性值与空闲页面数量匹配 + assert(total == nr_free_pages()); +c01035a9: e8 96 09 00 00 call c0103f44 +c01035ae: 8b 55 f0 mov -0x10(%ebp),%edx +c01035b1: 39 d0 cmp %edx,%eax +c01035b3: 74 24 je c01035d9 +c01035b5: c7 44 24 0c 8e 69 10 movl $0xc010698e,0xc(%esp) +c01035bc: c0 +c01035bd: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c01035c4: c0 +c01035c5: c7 44 24 04 30 01 00 movl $0x130,0x4(%esp) +c01035cc: 00 +c01035cd: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c01035d4: e8 5a d6 ff ff call c0100c33 <__panic> + // 调用 basic_check 以验证基本的内存管理功能 + basic_check(); +c01035d9: e8 e5 f9 ff ff call c0102fc3 + // 分配 5 个页面 + struct Page *p0 = alloc_pages(5), *p1, *p2; +c01035de: c7 04 24 05 00 00 00 movl $0x5,(%esp) +c01035e5: e8 eb 08 00 00 call c0103ed5 +c01035ea: 89 45 e8 mov %eax,-0x18(%ebp) + assert(p0 != NULL);// 确保成功分配 +c01035ed: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) +c01035f1: 75 24 jne c0103617 +c01035f3: c7 44 24 0c a7 69 10 movl $0xc01069a7,0xc(%esp) +c01035fa: c0 +c01035fb: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c0103602: c0 +c0103603: c7 44 24 04 35 01 00 movl $0x135,0x4(%esp) +c010360a: 00 +c010360b: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c0103612: e8 1c d6 ff ff call c0100c33 <__panic> + assert(!PageProperty(p0));// 确保分配的页面不带属性 +c0103617: 8b 45 e8 mov -0x18(%ebp),%eax +c010361a: 83 c0 04 add $0x4,%eax +c010361d: c7 45 c0 01 00 00 00 movl $0x1,-0x40(%ebp) +c0103624: 89 45 bc mov %eax,-0x44(%ebp) + asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr)); +c0103627: 8b 45 bc mov -0x44(%ebp),%eax +c010362a: 8b 55 c0 mov -0x40(%ebp),%edx +c010362d: 0f a3 10 bt %edx,(%eax) +c0103630: 19 c0 sbb %eax,%eax +c0103632: 89 45 b8 mov %eax,-0x48(%ebp) + return oldbit != 0; +c0103635: 83 7d b8 00 cmpl $0x0,-0x48(%ebp) +c0103639: 0f 95 c0 setne %al +c010363c: 0f b6 c0 movzbl %al,%eax +c010363f: 85 c0 test %eax,%eax +c0103641: 74 24 je c0103667 +c0103643: c7 44 24 0c b2 69 10 movl $0xc01069b2,0xc(%esp) +c010364a: c0 +c010364b: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c0103652: c0 +c0103653: c7 44 24 04 36 01 00 movl $0x136,0x4(%esp) +c010365a: 00 +c010365b: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c0103662: e8 cc d5 ff ff call c0100c33 <__panic> + // 初始化并检查空闲列表 + list_entry_t free_list_store = free_list; +c0103667: a1 e0 ce 11 c0 mov 0xc011cee0,%eax +c010366c: 8b 15 e4 ce 11 c0 mov 0xc011cee4,%edx +c0103672: 89 45 80 mov %eax,-0x80(%ebp) +c0103675: 89 55 84 mov %edx,-0x7c(%ebp) +c0103678: c7 45 b0 e0 ce 11 c0 movl $0xc011cee0,-0x50(%ebp) + elm->prev = elm->next = elm; +c010367f: 8b 45 b0 mov -0x50(%ebp),%eax +c0103682: 8b 55 b0 mov -0x50(%ebp),%edx +c0103685: 89 50 04 mov %edx,0x4(%eax) +c0103688: 8b 45 b0 mov -0x50(%ebp),%eax +c010368b: 8b 50 04 mov 0x4(%eax),%edx +c010368e: 8b 45 b0 mov -0x50(%ebp),%eax +c0103691: 89 10 mov %edx,(%eax) +} +c0103693: 90 nop +c0103694: c7 45 b4 e0 ce 11 c0 movl $0xc011cee0,-0x4c(%ebp) + return list->next == list; +c010369b: 8b 45 b4 mov -0x4c(%ebp),%eax +c010369e: 8b 40 04 mov 0x4(%eax),%eax +c01036a1: 39 45 b4 cmp %eax,-0x4c(%ebp) +c01036a4: 0f 94 c0 sete %al +c01036a7: 0f b6 c0 movzbl %al,%eax + list_init(&free_list); + assert(list_empty(&free_list));// 确保空闲列表为空 +c01036aa: 85 c0 test %eax,%eax +c01036ac: 75 24 jne c01036d2 +c01036ae: c7 44 24 0c 07 69 10 movl $0xc0106907,0xc(%esp) +c01036b5: c0 +c01036b6: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c01036bd: c0 +c01036be: c7 44 24 04 3a 01 00 movl $0x13a,0x4(%esp) +c01036c5: 00 +c01036c6: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c01036cd: e8 61 d5 ff ff call c0100c33 <__panic> + assert(alloc_page() == NULL);// 确保没有页面可分配 +c01036d2: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c01036d9: e8 f7 07 00 00 call c0103ed5 +c01036de: 85 c0 test %eax,%eax +c01036e0: 74 24 je c0103706 +c01036e2: c7 44 24 0c 1e 69 10 movl $0xc010691e,0xc(%esp) +c01036e9: c0 +c01036ea: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c01036f1: c0 +c01036f2: c7 44 24 04 3b 01 00 movl $0x13b,0x4(%esp) +c01036f9: 00 +c01036fa: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c0103701: e8 2d d5 ff ff call c0100c33 <__panic> + + unsigned int nr_free_store = nr_free;// 保存当前空闲页数 +c0103706: a1 e8 ce 11 c0 mov 0xc011cee8,%eax +c010370b: 89 45 e4 mov %eax,-0x1c(%ebp) + nr_free = 0;// 将空闲页数设为 0 +c010370e: c7 05 e8 ce 11 c0 00 movl $0x0,0xc011cee8 +c0103715: 00 00 00 +// 释放 3 个页面并确保分配页面时没有足够的空闲页 + free_pages(p0 + 2, 3); +c0103718: 8b 45 e8 mov -0x18(%ebp),%eax +c010371b: 83 c0 28 add $0x28,%eax +c010371e: c7 44 24 04 03 00 00 movl $0x3,0x4(%esp) +c0103725: 00 +c0103726: 89 04 24 mov %eax,(%esp) +c0103729: e8 e1 07 00 00 call c0103f0f + assert(alloc_pages(4) == NULL);// 确保无法分配 4 个页面 +c010372e: c7 04 24 04 00 00 00 movl $0x4,(%esp) +c0103735: e8 9b 07 00 00 call c0103ed5 +c010373a: 85 c0 test %eax,%eax +c010373c: 74 24 je c0103762 +c010373e: c7 44 24 0c c4 69 10 movl $0xc01069c4,0xc(%esp) +c0103745: c0 +c0103746: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c010374d: c0 +c010374e: c7 44 24 04 41 01 00 movl $0x141,0x4(%esp) +c0103755: 00 +c0103756: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c010375d: e8 d1 d4 ff ff call c0100c33 <__panic> + assert(PageProperty(p0 + 2) && p0[2].property == 3);// 检查页面属性 +c0103762: 8b 45 e8 mov -0x18(%ebp),%eax +c0103765: 83 c0 28 add $0x28,%eax +c0103768: 83 c0 04 add $0x4,%eax +c010376b: c7 45 ac 01 00 00 00 movl $0x1,-0x54(%ebp) +c0103772: 89 45 a8 mov %eax,-0x58(%ebp) + asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr)); +c0103775: 8b 45 a8 mov -0x58(%ebp),%eax +c0103778: 8b 55 ac mov -0x54(%ebp),%edx +c010377b: 0f a3 10 bt %edx,(%eax) +c010377e: 19 c0 sbb %eax,%eax +c0103780: 89 45 a4 mov %eax,-0x5c(%ebp) + return oldbit != 0; +c0103783: 83 7d a4 00 cmpl $0x0,-0x5c(%ebp) +c0103787: 0f 95 c0 setne %al +c010378a: 0f b6 c0 movzbl %al,%eax +c010378d: 85 c0 test %eax,%eax +c010378f: 74 0e je c010379f +c0103791: 8b 45 e8 mov -0x18(%ebp),%eax +c0103794: 83 c0 28 add $0x28,%eax +c0103797: 8b 40 08 mov 0x8(%eax),%eax +c010379a: 83 f8 03 cmp $0x3,%eax +c010379d: 74 24 je c01037c3 +c010379f: c7 44 24 0c dc 69 10 movl $0xc01069dc,0xc(%esp) +c01037a6: c0 +c01037a7: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c01037ae: c0 +c01037af: c7 44 24 04 42 01 00 movl $0x142,0x4(%esp) +c01037b6: 00 +c01037b7: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c01037be: e8 70 d4 ff ff call c0100c33 <__panic> + assert((p1 = alloc_pages(3)) != NULL);// 再次分配 3 个页面 +c01037c3: c7 04 24 03 00 00 00 movl $0x3,(%esp) +c01037ca: e8 06 07 00 00 call c0103ed5 +c01037cf: 89 45 e0 mov %eax,-0x20(%ebp) +c01037d2: 83 7d e0 00 cmpl $0x0,-0x20(%ebp) +c01037d6: 75 24 jne c01037fc +c01037d8: c7 44 24 0c 08 6a 10 movl $0xc0106a08,0xc(%esp) +c01037df: c0 +c01037e0: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c01037e7: c0 +c01037e8: c7 44 24 04 43 01 00 movl $0x143,0x4(%esp) +c01037ef: 00 +c01037f0: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c01037f7: e8 37 d4 ff ff call c0100c33 <__panic> + assert(alloc_page() == NULL);// 确保没有页面可分配 +c01037fc: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c0103803: e8 cd 06 00 00 call c0103ed5 +c0103808: 85 c0 test %eax,%eax +c010380a: 74 24 je c0103830 +c010380c: c7 44 24 0c 1e 69 10 movl $0xc010691e,0xc(%esp) +c0103813: c0 +c0103814: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c010381b: c0 +c010381c: c7 44 24 04 44 01 00 movl $0x144,0x4(%esp) +c0103823: 00 +c0103824: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c010382b: e8 03 d4 ff ff call c0100c33 <__panic> + assert(p0 + 2 == p1);// 确保分配的页面是释放的页面 +c0103830: 8b 45 e8 mov -0x18(%ebp),%eax +c0103833: 83 c0 28 add $0x28,%eax +c0103836: 39 45 e0 cmp %eax,-0x20(%ebp) +c0103839: 74 24 je c010385f +c010383b: c7 44 24 0c 26 6a 10 movl $0xc0106a26,0xc(%esp) +c0103842: c0 +c0103843: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c010384a: c0 +c010384b: c7 44 24 04 45 01 00 movl $0x145,0x4(%esp) +c0103852: 00 +c0103853: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c010385a: e8 d4 d3 ff ff call c0100c33 <__panic> + + p2 = p0 + 1; // 设置 p2 为 p0 的下一个页面 +c010385f: 8b 45 e8 mov -0x18(%ebp),%eax +c0103862: 83 c0 14 add $0x14,%eax +c0103865: 89 45 dc mov %eax,-0x24(%ebp) + free_page(p0);// 释放 p0 页面 +c0103868: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c010386f: 00 +c0103870: 8b 45 e8 mov -0x18(%ebp),%eax +c0103873: 89 04 24 mov %eax,(%esp) +c0103876: e8 94 06 00 00 call c0103f0f + free_pages(p1, 3);// 释放 p1 指向的页面 +c010387b: c7 44 24 04 03 00 00 movl $0x3,0x4(%esp) +c0103882: 00 +c0103883: 8b 45 e0 mov -0x20(%ebp),%eax +c0103886: 89 04 24 mov %eax,(%esp) +c0103889: e8 81 06 00 00 call c0103f0f + assert(PageProperty(p0) && p0->property == 1); // 检查 p0 属性 +c010388e: 8b 45 e8 mov -0x18(%ebp),%eax +c0103891: 83 c0 04 add $0x4,%eax +c0103894: c7 45 a0 01 00 00 00 movl $0x1,-0x60(%ebp) +c010389b: 89 45 9c mov %eax,-0x64(%ebp) + asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr)); +c010389e: 8b 45 9c mov -0x64(%ebp),%eax +c01038a1: 8b 55 a0 mov -0x60(%ebp),%edx +c01038a4: 0f a3 10 bt %edx,(%eax) +c01038a7: 19 c0 sbb %eax,%eax +c01038a9: 89 45 98 mov %eax,-0x68(%ebp) + return oldbit != 0; +c01038ac: 83 7d 98 00 cmpl $0x0,-0x68(%ebp) +c01038b0: 0f 95 c0 setne %al +c01038b3: 0f b6 c0 movzbl %al,%eax +c01038b6: 85 c0 test %eax,%eax +c01038b8: 74 0b je c01038c5 +c01038ba: 8b 45 e8 mov -0x18(%ebp),%eax +c01038bd: 8b 40 08 mov 0x8(%eax),%eax +c01038c0: 83 f8 01 cmp $0x1,%eax +c01038c3: 74 24 je c01038e9 +c01038c5: c7 44 24 0c 34 6a 10 movl $0xc0106a34,0xc(%esp) +c01038cc: c0 +c01038cd: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c01038d4: c0 +c01038d5: c7 44 24 04 4a 01 00 movl $0x14a,0x4(%esp) +c01038dc: 00 +c01038dd: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c01038e4: e8 4a d3 ff ff call c0100c33 <__panic> + assert(PageProperty(p1) && p1->property == 3); // 检查 p1 属性 +c01038e9: 8b 45 e0 mov -0x20(%ebp),%eax +c01038ec: 83 c0 04 add $0x4,%eax +c01038ef: c7 45 94 01 00 00 00 movl $0x1,-0x6c(%ebp) +c01038f6: 89 45 90 mov %eax,-0x70(%ebp) + asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr)); +c01038f9: 8b 45 90 mov -0x70(%ebp),%eax +c01038fc: 8b 55 94 mov -0x6c(%ebp),%edx +c01038ff: 0f a3 10 bt %edx,(%eax) +c0103902: 19 c0 sbb %eax,%eax +c0103904: 89 45 8c mov %eax,-0x74(%ebp) + return oldbit != 0; +c0103907: 83 7d 8c 00 cmpl $0x0,-0x74(%ebp) +c010390b: 0f 95 c0 setne %al +c010390e: 0f b6 c0 movzbl %al,%eax +c0103911: 85 c0 test %eax,%eax +c0103913: 74 0b je c0103920 +c0103915: 8b 45 e0 mov -0x20(%ebp),%eax +c0103918: 8b 40 08 mov 0x8(%eax),%eax +c010391b: 83 f8 03 cmp $0x3,%eax +c010391e: 74 24 je c0103944 +c0103920: c7 44 24 0c 5c 6a 10 movl $0xc0106a5c,0xc(%esp) +c0103927: c0 +c0103928: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c010392f: c0 +c0103930: c7 44 24 04 4b 01 00 movl $0x14b,0x4(%esp) +c0103937: 00 +c0103938: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c010393f: e8 ef d2 ff ff call c0100c33 <__panic> +// 确保重分配的页面是之前释放的页面 + assert((p0 = alloc_page()) == p2 - 1); +c0103944: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c010394b: e8 85 05 00 00 call c0103ed5 +c0103950: 89 45 e8 mov %eax,-0x18(%ebp) +c0103953: 8b 45 dc mov -0x24(%ebp),%eax +c0103956: 83 e8 14 sub $0x14,%eax +c0103959: 39 45 e8 cmp %eax,-0x18(%ebp) +c010395c: 74 24 je c0103982 +c010395e: c7 44 24 0c 82 6a 10 movl $0xc0106a82,0xc(%esp) +c0103965: c0 +c0103966: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c010396d: c0 +c010396e: c7 44 24 04 4d 01 00 movl $0x14d,0x4(%esp) +c0103975: 00 +c0103976: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c010397d: e8 b1 d2 ff ff call c0100c33 <__panic> + free_page(p0);// 释放分配的页面 +c0103982: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c0103989: 00 +c010398a: 8b 45 e8 mov -0x18(%ebp),%eax +c010398d: 89 04 24 mov %eax,(%esp) +c0103990: e8 7a 05 00 00 call c0103f0f + assert((p0 = alloc_pages(2)) == p2 + 1);// 分配 2 个页面并检查 +c0103995: c7 04 24 02 00 00 00 movl $0x2,(%esp) +c010399c: e8 34 05 00 00 call c0103ed5 +c01039a1: 89 45 e8 mov %eax,-0x18(%ebp) +c01039a4: 8b 45 dc mov -0x24(%ebp),%eax +c01039a7: 83 c0 14 add $0x14,%eax +c01039aa: 39 45 e8 cmp %eax,-0x18(%ebp) +c01039ad: 74 24 je c01039d3 +c01039af: c7 44 24 0c a0 6a 10 movl $0xc0106aa0,0xc(%esp) +c01039b6: c0 +c01039b7: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c01039be: c0 +c01039bf: c7 44 24 04 4f 01 00 movl $0x14f,0x4(%esp) +c01039c6: 00 +c01039c7: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c01039ce: e8 60 d2 ff ff call c0100c33 <__panic> +// 释放页面并检查空闲状态 + free_pages(p0, 2); +c01039d3: c7 44 24 04 02 00 00 movl $0x2,0x4(%esp) +c01039da: 00 +c01039db: 8b 45 e8 mov -0x18(%ebp),%eax +c01039de: 89 04 24 mov %eax,(%esp) +c01039e1: e8 29 05 00 00 call c0103f0f + free_page(p2); +c01039e6: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c01039ed: 00 +c01039ee: 8b 45 dc mov -0x24(%ebp),%eax +c01039f1: 89 04 24 mov %eax,(%esp) +c01039f4: e8 16 05 00 00 call c0103f0f +// 再次分配 5 个页面 + assert((p0 = alloc_pages(5)) != NULL); +c01039f9: c7 04 24 05 00 00 00 movl $0x5,(%esp) +c0103a00: e8 d0 04 00 00 call c0103ed5 +c0103a05: 89 45 e8 mov %eax,-0x18(%ebp) +c0103a08: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) +c0103a0c: 75 24 jne c0103a32 +c0103a0e: c7 44 24 0c c0 6a 10 movl $0xc0106ac0,0xc(%esp) +c0103a15: c0 +c0103a16: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c0103a1d: c0 +c0103a1e: c7 44 24 04 54 01 00 movl $0x154,0x4(%esp) +c0103a25: 00 +c0103a26: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c0103a2d: e8 01 d2 ff ff call c0100c33 <__panic> + assert(alloc_page() == NULL);// 确保没有额外页面可分配 +c0103a32: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c0103a39: e8 97 04 00 00 call c0103ed5 +c0103a3e: 85 c0 test %eax,%eax +c0103a40: 74 24 je c0103a66 +c0103a42: c7 44 24 0c 1e 69 10 movl $0xc010691e,0xc(%esp) +c0103a49: c0 +c0103a4a: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c0103a51: c0 +c0103a52: c7 44 24 04 55 01 00 movl $0x155,0x4(%esp) +c0103a59: 00 +c0103a5a: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c0103a61: e8 cd d1 ff ff call c0100c33 <__panic> + + assert(nr_free == 0);// 确保空闲页数为 0 +c0103a66: a1 e8 ce 11 c0 mov 0xc011cee8,%eax +c0103a6b: 85 c0 test %eax,%eax +c0103a6d: 74 24 je c0103a93 +c0103a6f: c7 44 24 0c 71 69 10 movl $0xc0106971,0xc(%esp) +c0103a76: c0 +c0103a77: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c0103a7e: c0 +c0103a7f: c7 44 24 04 57 01 00 movl $0x157,0x4(%esp) +c0103a86: 00 +c0103a87: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c0103a8e: e8 a0 d1 ff ff call c0100c33 <__panic> + nr_free = nr_free_store;// 恢复空闲页数 +c0103a93: 8b 45 e4 mov -0x1c(%ebp),%eax +c0103a96: a3 e8 ce 11 c0 mov %eax,0xc011cee8 +// 恢复空闲列表状态 + free_list = free_list_store; +c0103a9b: 8b 45 80 mov -0x80(%ebp),%eax +c0103a9e: 8b 55 84 mov -0x7c(%ebp),%edx +c0103aa1: a3 e0 ce 11 c0 mov %eax,0xc011cee0 +c0103aa6: 89 15 e4 ce 11 c0 mov %edx,0xc011cee4 + free_pages(p0, 5);// 释放所有分配的页面 +c0103aac: c7 44 24 04 05 00 00 movl $0x5,0x4(%esp) +c0103ab3: 00 +c0103ab4: 8b 45 e8 mov -0x18(%ebp),%eax +c0103ab7: 89 04 24 mov %eax,(%esp) +c0103aba: e8 50 04 00 00 call c0103f0f + // 验证空闲列表的一致性 + le = &free_list; +c0103abf: c7 45 ec e0 ce 11 c0 movl $0xc011cee0,-0x14(%ebp) + while ((le = list_next(le)) != &free_list) { +c0103ac6: eb 5a jmp c0103b22 + assert(le->next->prev == le && le->prev->next == le);// 验证双向链表 +c0103ac8: 8b 45 ec mov -0x14(%ebp),%eax +c0103acb: 8b 40 04 mov 0x4(%eax),%eax +c0103ace: 8b 00 mov (%eax),%eax +c0103ad0: 39 45 ec cmp %eax,-0x14(%ebp) +c0103ad3: 75 0d jne c0103ae2 +c0103ad5: 8b 45 ec mov -0x14(%ebp),%eax +c0103ad8: 8b 00 mov (%eax),%eax +c0103ada: 8b 40 04 mov 0x4(%eax),%eax +c0103add: 39 45 ec cmp %eax,-0x14(%ebp) +c0103ae0: 74 24 je c0103b06 +c0103ae2: c7 44 24 0c e0 6a 10 movl $0xc0106ae0,0xc(%esp) +c0103ae9: c0 +c0103aea: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c0103af1: c0 +c0103af2: c7 44 24 04 5f 01 00 movl $0x15f,0x4(%esp) +c0103af9: 00 +c0103afa: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c0103b01: e8 2d d1 ff ff call c0100c33 <__panic> + struct Page *p = le2page(le, page_link);// 更新计数和总属性值 +c0103b06: 8b 45 ec mov -0x14(%ebp),%eax +c0103b09: 83 e8 0c sub $0xc,%eax +c0103b0c: 89 45 d8 mov %eax,-0x28(%ebp) + count --, total -= p->property; +c0103b0f: ff 4d f4 decl -0xc(%ebp) +c0103b12: 8b 55 f0 mov -0x10(%ebp),%edx +c0103b15: 8b 45 d8 mov -0x28(%ebp),%eax +c0103b18: 8b 48 08 mov 0x8(%eax),%ecx +c0103b1b: 89 d0 mov %edx,%eax +c0103b1d: 29 c8 sub %ecx,%eax +c0103b1f: 89 45 f0 mov %eax,-0x10(%ebp) +c0103b22: 8b 45 ec mov -0x14(%ebp),%eax +c0103b25: 89 45 88 mov %eax,-0x78(%ebp) + return listelm->next; +c0103b28: 8b 45 88 mov -0x78(%ebp),%eax +c0103b2b: 8b 40 04 mov 0x4(%eax),%eax + while ((le = list_next(le)) != &free_list) { +c0103b2e: 89 45 ec mov %eax,-0x14(%ebp) +c0103b31: 81 7d ec e0 ce 11 c0 cmpl $0xc011cee0,-0x14(%ebp) +c0103b38: 75 8e jne c0103ac8 + } + assert(count == 0);// 确保所有页面都已处理 +c0103b3a: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c0103b3e: 74 24 je c0103b64 +c0103b40: c7 44 24 0c 0d 6b 10 movl $0xc0106b0d,0xc(%esp) +c0103b47: c0 +c0103b48: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c0103b4f: c0 +c0103b50: c7 44 24 04 63 01 00 movl $0x163,0x4(%esp) +c0103b57: 00 +c0103b58: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c0103b5f: e8 cf d0 ff ff call c0100c33 <__panic> + assert(total == 0);// 确保总属性值为 0 +c0103b64: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) +c0103b68: 74 24 je c0103b8e +c0103b6a: c7 44 24 0c 18 6b 10 movl $0xc0106b18,0xc(%esp) +c0103b71: c0 +c0103b72: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c0103b79: c0 +c0103b7a: c7 44 24 04 64 01 00 movl $0x164,0x4(%esp) +c0103b81: 00 +c0103b82: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c0103b89: e8 a5 d0 ff ff call c0100c33 <__panic> +} +c0103b8e: 90 nop +c0103b8f: 89 ec mov %ebp,%esp +c0103b91: 5d pop %ebp +c0103b92: c3 ret + +c0103b93 : +page2ppn(struct Page *page) { +c0103b93: 55 push %ebp +c0103b94: 89 e5 mov %esp,%ebp + return page - pages; +c0103b96: 8b 15 00 cf 11 c0 mov 0xc011cf00,%edx +c0103b9c: 8b 45 08 mov 0x8(%ebp),%eax +c0103b9f: 29 d0 sub %edx,%eax +c0103ba1: c1 f8 02 sar $0x2,%eax +c0103ba4: 69 c0 cd cc cc cc imul $0xcccccccd,%eax,%eax +} +c0103baa: 5d pop %ebp +c0103bab: c3 ret + +c0103bac : +page2pa(struct Page *page) { +c0103bac: 55 push %ebp +c0103bad: 89 e5 mov %esp,%ebp +c0103baf: 83 ec 04 sub $0x4,%esp + return page2ppn(page) << PGSHIFT; +c0103bb2: 8b 45 08 mov 0x8(%ebp),%eax +c0103bb5: 89 04 24 mov %eax,(%esp) +c0103bb8: e8 d6 ff ff ff call c0103b93 +c0103bbd: c1 e0 0c shl $0xc,%eax +} +c0103bc0: 89 ec mov %ebp,%esp +c0103bc2: 5d pop %ebp +c0103bc3: c3 ret + +c0103bc4 : +pa2page(uintptr_t pa) { +c0103bc4: 55 push %ebp +c0103bc5: 89 e5 mov %esp,%ebp +c0103bc7: 83 ec 18 sub $0x18,%esp + if (PPN(pa) >= npage) { +c0103bca: 8b 45 08 mov 0x8(%ebp),%eax +c0103bcd: c1 e8 0c shr $0xc,%eax +c0103bd0: 89 c2 mov %eax,%edx +c0103bd2: a1 04 cf 11 c0 mov 0xc011cf04,%eax +c0103bd7: 39 c2 cmp %eax,%edx +c0103bd9: 72 1c jb c0103bf7 + panic("pa2page called with invalid pa"); +c0103bdb: c7 44 24 08 54 6b 10 movl $0xc0106b54,0x8(%esp) +c0103be2: c0 +c0103be3: c7 44 24 04 5a 00 00 movl $0x5a,0x4(%esp) +c0103bea: 00 +c0103beb: c7 04 24 73 6b 10 c0 movl $0xc0106b73,(%esp) +c0103bf2: e8 3c d0 ff ff call c0100c33 <__panic> + return &pages[PPN(pa)]; +c0103bf7: 8b 0d 00 cf 11 c0 mov 0xc011cf00,%ecx +c0103bfd: 8b 45 08 mov 0x8(%ebp),%eax +c0103c00: c1 e8 0c shr $0xc,%eax +c0103c03: 89 c2 mov %eax,%edx +c0103c05: 89 d0 mov %edx,%eax +c0103c07: c1 e0 02 shl $0x2,%eax +c0103c0a: 01 d0 add %edx,%eax +c0103c0c: c1 e0 02 shl $0x2,%eax +c0103c0f: 01 c8 add %ecx,%eax +} +c0103c11: 89 ec mov %ebp,%esp +c0103c13: 5d pop %ebp +c0103c14: c3 ret + +c0103c15 : +page2kva(struct Page *page) { +c0103c15: 55 push %ebp +c0103c16: 89 e5 mov %esp,%ebp +c0103c18: 83 ec 28 sub $0x28,%esp + return KADDR(page2pa(page)); +c0103c1b: 8b 45 08 mov 0x8(%ebp),%eax +c0103c1e: 89 04 24 mov %eax,(%esp) +c0103c21: e8 86 ff ff ff call c0103bac +c0103c26: 89 45 f4 mov %eax,-0xc(%ebp) +c0103c29: 8b 45 f4 mov -0xc(%ebp),%eax +c0103c2c: c1 e8 0c shr $0xc,%eax +c0103c2f: 89 45 f0 mov %eax,-0x10(%ebp) +c0103c32: a1 04 cf 11 c0 mov 0xc011cf04,%eax +c0103c37: 39 45 f0 cmp %eax,-0x10(%ebp) +c0103c3a: 72 23 jb c0103c5f +c0103c3c: 8b 45 f4 mov -0xc(%ebp),%eax +c0103c3f: 89 44 24 0c mov %eax,0xc(%esp) +c0103c43: c7 44 24 08 84 6b 10 movl $0xc0106b84,0x8(%esp) +c0103c4a: c0 +c0103c4b: c7 44 24 04 61 00 00 movl $0x61,0x4(%esp) +c0103c52: 00 +c0103c53: c7 04 24 73 6b 10 c0 movl $0xc0106b73,(%esp) +c0103c5a: e8 d4 cf ff ff call c0100c33 <__panic> +c0103c5f: 8b 45 f4 mov -0xc(%ebp),%eax +c0103c62: 2d 00 00 00 40 sub $0x40000000,%eax +} +c0103c67: 89 ec mov %ebp,%esp +c0103c69: 5d pop %ebp +c0103c6a: c3 ret + +c0103c6b : +pte2page(pte_t pte) { +c0103c6b: 55 push %ebp +c0103c6c: 89 e5 mov %esp,%ebp +c0103c6e: 83 ec 18 sub $0x18,%esp + if (!(pte & PTE_P)) { +c0103c71: 8b 45 08 mov 0x8(%ebp),%eax +c0103c74: 83 e0 01 and $0x1,%eax +c0103c77: 85 c0 test %eax,%eax +c0103c79: 75 1c jne c0103c97 + panic("pte2page called with invalid pte"); +c0103c7b: c7 44 24 08 a8 6b 10 movl $0xc0106ba8,0x8(%esp) +c0103c82: c0 +c0103c83: c7 44 24 04 6c 00 00 movl $0x6c,0x4(%esp) +c0103c8a: 00 +c0103c8b: c7 04 24 73 6b 10 c0 movl $0xc0106b73,(%esp) +c0103c92: e8 9c cf ff ff call c0100c33 <__panic> + return pa2page(PTE_ADDR(pte)); +c0103c97: 8b 45 08 mov 0x8(%ebp),%eax +c0103c9a: 25 00 f0 ff ff and $0xfffff000,%eax +c0103c9f: 89 04 24 mov %eax,(%esp) +c0103ca2: e8 1d ff ff ff call c0103bc4 +} +c0103ca7: 89 ec mov %ebp,%esp +c0103ca9: 5d pop %ebp +c0103caa: c3 ret + +c0103cab : +pde2page(pde_t pde) { +c0103cab: 55 push %ebp +c0103cac: 89 e5 mov %esp,%ebp +c0103cae: 83 ec 18 sub $0x18,%esp + return pa2page(PDE_ADDR(pde)); +c0103cb1: 8b 45 08 mov 0x8(%ebp),%eax +c0103cb4: 25 00 f0 ff ff and $0xfffff000,%eax +c0103cb9: 89 04 24 mov %eax,(%esp) +c0103cbc: e8 03 ff ff ff call c0103bc4 +} +c0103cc1: 89 ec mov %ebp,%esp +c0103cc3: 5d pop %ebp +c0103cc4: c3 ret + +c0103cc5 : +page_ref(struct Page *page) { +c0103cc5: 55 push %ebp +c0103cc6: 89 e5 mov %esp,%ebp + return page->ref; +c0103cc8: 8b 45 08 mov 0x8(%ebp),%eax +c0103ccb: 8b 00 mov (%eax),%eax +} +c0103ccd: 5d pop %ebp +c0103cce: c3 ret + +c0103ccf : +set_page_ref(struct Page *page, int val) { +c0103ccf: 55 push %ebp +c0103cd0: 89 e5 mov %esp,%ebp + page->ref = val; +c0103cd2: 8b 45 08 mov 0x8(%ebp),%eax +c0103cd5: 8b 55 0c mov 0xc(%ebp),%edx +c0103cd8: 89 10 mov %edx,(%eax) +} +c0103cda: 90 nop +c0103cdb: 5d pop %ebp +c0103cdc: c3 ret + +c0103cdd : + +static inline int +page_ref_inc(struct Page *page) { +c0103cdd: 55 push %ebp +c0103cde: 89 e5 mov %esp,%ebp + page->ref += 1; +c0103ce0: 8b 45 08 mov 0x8(%ebp),%eax +c0103ce3: 8b 00 mov (%eax),%eax +c0103ce5: 8d 50 01 lea 0x1(%eax),%edx +c0103ce8: 8b 45 08 mov 0x8(%ebp),%eax +c0103ceb: 89 10 mov %edx,(%eax) + return page->ref; +c0103ced: 8b 45 08 mov 0x8(%ebp),%eax +c0103cf0: 8b 00 mov (%eax),%eax +} +c0103cf2: 5d pop %ebp +c0103cf3: c3 ret + +c0103cf4 : + +static inline int +page_ref_dec(struct Page *page) { +c0103cf4: 55 push %ebp +c0103cf5: 89 e5 mov %esp,%ebp + page->ref -= 1; +c0103cf7: 8b 45 08 mov 0x8(%ebp),%eax +c0103cfa: 8b 00 mov (%eax),%eax +c0103cfc: 8d 50 ff lea -0x1(%eax),%edx +c0103cff: 8b 45 08 mov 0x8(%ebp),%eax +c0103d02: 89 10 mov %edx,(%eax) + return page->ref; +c0103d04: 8b 45 08 mov 0x8(%ebp),%eax +c0103d07: 8b 00 mov (%eax),%eax +} +c0103d09: 5d pop %ebp +c0103d0a: c3 ret + +c0103d0b <__intr_save>: +__intr_save(void) { +c0103d0b: 55 push %ebp +c0103d0c: 89 e5 mov %esp,%ebp +c0103d0e: 83 ec 18 sub $0x18,%esp + asm volatile ("pushfl; popl %0" : "=r" (eflags)); +c0103d11: 9c pushf +c0103d12: 58 pop %eax +c0103d13: 89 45 f4 mov %eax,-0xc(%ebp) + return eflags; +c0103d16: 8b 45 f4 mov -0xc(%ebp),%eax + if (read_eflags() & FL_IF) { +c0103d19: 25 00 02 00 00 and $0x200,%eax +c0103d1e: 85 c0 test %eax,%eax +c0103d20: 74 0c je c0103d2e <__intr_save+0x23> + intr_disable(); +c0103d22: e8 65 d9 ff ff call c010168c + return 1; +c0103d27: b8 01 00 00 00 mov $0x1,%eax +c0103d2c: eb 05 jmp c0103d33 <__intr_save+0x28> + return 0; +c0103d2e: b8 00 00 00 00 mov $0x0,%eax +} +c0103d33: 89 ec mov %ebp,%esp +c0103d35: 5d pop %ebp +c0103d36: c3 ret + +c0103d37 <__intr_restore>: +__intr_restore(bool flag) { +c0103d37: 55 push %ebp +c0103d38: 89 e5 mov %esp,%ebp +c0103d3a: 83 ec 08 sub $0x8,%esp + if (flag) { +c0103d3d: 83 7d 08 00 cmpl $0x0,0x8(%ebp) +c0103d41: 74 05 je c0103d48 <__intr_restore+0x11> + intr_enable(); +c0103d43: e8 3c d9 ff ff call c0101684 +} +c0103d48: 90 nop +c0103d49: 89 ec mov %ebp,%esp +c0103d4b: 5d pop %ebp +c0103d4c: c3 ret + +c0103d4d : + * data/code segement registers for kernel. + * lgdt - 加载全局描述符表寄存器并重置内核的数据/代码段寄存器。 + * */ +//定义了一个静态内联函数 lgdt,接收一个指向伪描述符(struct pseudodesc)的指针 pd +static inline void +lgdt(struct pseudodesc *pd) { +c0103d4d: 55 push %ebp +c0103d4e: 89 e5 mov %esp,%ebp + asm volatile ("lgdt (%0)" :: "r" (pd));//这行汇编代码使用 lgdt 指令加载 GDT。%0 被替换为指向 pd 的指针,告诉处理器 GDT 的地址。 +c0103d50: 8b 45 08 mov 0x8(%ebp),%eax +c0103d53: 0f 01 10 lgdtl (%eax) + asm volatile ("movw %%ax, %%gs" :: "a" (USER_DS));//将 USER_DS(用户数据段)的值移动到 gs 段寄存器。 +c0103d56: b8 23 00 00 00 mov $0x23,%eax +c0103d5b: 8e e8 mov %eax,%gs + asm volatile ("movw %%ax, %%fs" :: "a" (USER_DS));//将 USER_DS 的值移动到 fs 段寄存器。 +c0103d5d: b8 23 00 00 00 mov $0x23,%eax +c0103d62: 8e e0 mov %eax,%fs + asm volatile ("movw %%ax, %%es" :: "a" (KERNEL_DS));//将 KERNEL_DS(内核数据段)的值移动到 es 段寄存器。 +c0103d64: b8 10 00 00 00 mov $0x10,%eax +c0103d69: 8e c0 mov %eax,%es + asm volatile ("movw %%ax, %%ds" :: "a" (KERNEL_DS));//将 KERNEL_DS 的值移动到 ds 段寄存器 +c0103d6b: b8 10 00 00 00 mov $0x10,%eax +c0103d70: 8e d8 mov %eax,%ds + asm volatile ("movw %%ax, %%ss" :: "a" (KERNEL_DS));//将 KERNEL_DS 的值移动到 ss 段寄存器 +c0103d72: b8 10 00 00 00 mov $0x10,%eax +c0103d77: 8e d0 mov %eax,%ss + // reload cs + //通过 ljmp 指令重新加载代码段寄存器 cs,并跳转到标签 1。 + asm volatile ("ljmp %0, $1f\n 1:\n" :: "i" (KERNEL_CS)); +c0103d79: ea 80 3d 10 c0 08 00 ljmp $0x8,$0xc0103d80 +} +c0103d80: 90 nop +c0103d81: 5d pop %ebp +c0103d82: c3 ret + +c0103d83 : + * load_esp0 - 修改默认任务状态段中的 ESP0,以便在从用户态陷入内核态时能够使用不同的内核栈。 + * */ +//uintptr_t esp0:这是新的堆栈指针,通常指向内核栈的顶部。 +//修改当前任务状态段(TSS)中的 ESP0 值。ESP0 是在从用户态切换到内核态时,CPU 使用的内核栈指针。 +void +load_esp0(uintptr_t esp0) { +c0103d83: 55 push %ebp +c0103d84: 89 e5 mov %esp,%ebp + ts.ts_esp0 = esp0; +c0103d86: 8b 45 08 mov 0x8(%ebp),%eax +c0103d89: a3 24 cf 11 c0 mov %eax,0xc011cf24 +} +c0103d8e: 90 nop +c0103d8f: 5d pop %ebp +c0103d90: c3 ret + +c0103d91 : + +/* gdt_init - initialize the default GDT and TSS */ +/* gdt_init - 初始化默认的 GDT 和 TSS */ +static void +gdt_init(void) { +c0103d91: 55 push %ebp +c0103d92: 89 e5 mov %esp,%ebp +c0103d94: 83 ec 14 sub $0x14,%esp + // 设置启动内核栈和默认的 SS0 + // set boot kernel stack and default SS0 + load_esp0((uintptr_t)bootstacktop); +c0103d97: b8 00 90 11 c0 mov $0xc0119000,%eax +c0103d9c: 89 04 24 mov %eax,(%esp) +c0103d9f: e8 df ff ff ff call c0103d83 + ts.ts_ss0 = KERNEL_DS; +c0103da4: 66 c7 05 28 cf 11 c0 movw $0x10,0xc011cf28 +c0103dab: 10 00 + // 初始化 GDT 中的 TSS 字段 + // initialize the TSS filed of the gdt + gdt[SEG_TSS] = SEGTSS(STS_T32A, (uintptr_t)&ts, sizeof(ts), DPL_KERNEL); +c0103dad: 66 c7 05 28 9a 11 c0 movw $0x68,0xc0119a28 +c0103db4: 68 00 +c0103db6: b8 20 cf 11 c0 mov $0xc011cf20,%eax +c0103dbb: 0f b7 c0 movzwl %ax,%eax +c0103dbe: 66 a3 2a 9a 11 c0 mov %ax,0xc0119a2a +c0103dc4: b8 20 cf 11 c0 mov $0xc011cf20,%eax +c0103dc9: c1 e8 10 shr $0x10,%eax +c0103dcc: a2 2c 9a 11 c0 mov %al,0xc0119a2c +c0103dd1: 0f b6 05 2d 9a 11 c0 movzbl 0xc0119a2d,%eax +c0103dd8: 24 f0 and $0xf0,%al +c0103dda: 0c 09 or $0x9,%al +c0103ddc: a2 2d 9a 11 c0 mov %al,0xc0119a2d +c0103de1: 0f b6 05 2d 9a 11 c0 movzbl 0xc0119a2d,%eax +c0103de8: 24 ef and $0xef,%al +c0103dea: a2 2d 9a 11 c0 mov %al,0xc0119a2d +c0103def: 0f b6 05 2d 9a 11 c0 movzbl 0xc0119a2d,%eax +c0103df6: 24 9f and $0x9f,%al +c0103df8: a2 2d 9a 11 c0 mov %al,0xc0119a2d +c0103dfd: 0f b6 05 2d 9a 11 c0 movzbl 0xc0119a2d,%eax +c0103e04: 0c 80 or $0x80,%al +c0103e06: a2 2d 9a 11 c0 mov %al,0xc0119a2d +c0103e0b: 0f b6 05 2e 9a 11 c0 movzbl 0xc0119a2e,%eax +c0103e12: 24 f0 and $0xf0,%al +c0103e14: a2 2e 9a 11 c0 mov %al,0xc0119a2e +c0103e19: 0f b6 05 2e 9a 11 c0 movzbl 0xc0119a2e,%eax +c0103e20: 24 ef and $0xef,%al +c0103e22: a2 2e 9a 11 c0 mov %al,0xc0119a2e +c0103e27: 0f b6 05 2e 9a 11 c0 movzbl 0xc0119a2e,%eax +c0103e2e: 24 df and $0xdf,%al +c0103e30: a2 2e 9a 11 c0 mov %al,0xc0119a2e +c0103e35: 0f b6 05 2e 9a 11 c0 movzbl 0xc0119a2e,%eax +c0103e3c: 0c 40 or $0x40,%al +c0103e3e: a2 2e 9a 11 c0 mov %al,0xc0119a2e +c0103e43: 0f b6 05 2e 9a 11 c0 movzbl 0xc0119a2e,%eax +c0103e4a: 24 7f and $0x7f,%al +c0103e4c: a2 2e 9a 11 c0 mov %al,0xc0119a2e +c0103e51: b8 20 cf 11 c0 mov $0xc011cf20,%eax +c0103e56: c1 e8 18 shr $0x18,%eax +c0103e59: a2 2f 9a 11 c0 mov %al,0xc0119a2f + // 使用lgdt加载全局描述符表,更新所有段寄存器 + // reload all segment registers + lgdt(&gdt_pd); +c0103e5e: c7 04 24 30 9a 11 c0 movl $0xc0119a30,(%esp) +c0103e65: e8 e3 fe ff ff call c0103d4d +c0103e6a: 66 c7 45 fe 28 00 movw $0x28,-0x2(%ebp) + asm volatile ("ltr %0" :: "r" (sel) : "memory"); +c0103e70: 0f b7 45 fe movzwl -0x2(%ebp),%eax +c0103e74: 0f 00 d8 ltr %ax +} +c0103e77: 90 nop + // 加载 TSS,使 CPU 在进行特权级切换时能够正确使用 TSS。 + // load the TSS + ltr(GD_TSS); +} +c0103e78: 90 nop +c0103e79: 89 ec mov %ebp,%esp +c0103e7b: 5d pop %ebp +c0103e7c: c3 ret + +c0103e7d : + +//init_pmm_manager - initialize a pmm_manager instance +//初始化一个 pmm_manager 实例 +static void +init_pmm_manager(void) { +c0103e7d: 55 push %ebp +c0103e7e: 89 e5 mov %esp,%ebp +c0103e80: 83 ec 18 sub $0x18,%esp + //将 pmm_manager 指向默认的 PMM 管理器实例。 + pmm_manager = &default_pmm_manager; +c0103e83: c7 05 0c cf 11 c0 38 movl $0xc0106b38,0xc011cf0c +c0103e8a: 6b 10 c0 + //使用 cprintf 打印当前内存管理器的名称。 + cprintf("memory management: %s\n", pmm_manager->name); +c0103e8d: a1 0c cf 11 c0 mov 0xc011cf0c,%eax +c0103e92: 8b 00 mov (%eax),%eax +c0103e94: 89 44 24 04 mov %eax,0x4(%esp) +c0103e98: c7 04 24 d4 6b 10 c0 movl $0xc0106bd4,(%esp) +c0103e9f: e8 c2 c4 ff ff call c0100366 + //调用 PMM 管理器的初始化函数,以设置和准备内存管理的相关数据结构。 + pmm_manager->init(); +c0103ea4: a1 0c cf 11 c0 mov 0xc011cf0c,%eax +c0103ea9: 8b 40 04 mov 0x4(%eax),%eax +c0103eac: ff d0 call *%eax +} +c0103eae: 90 nop +c0103eaf: 89 ec mov %ebp,%esp +c0103eb1: 5d pop %ebp +c0103eb2: c3 ret + +c0103eb3 : + +//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) { +c0103eb3: 55 push %ebp +c0103eb4: 89 e5 mov %esp,%ebp +c0103eb6: 83 ec 18 sub $0x18,%esp + pmm_manager->init_memmap(base, n); +c0103eb9: a1 0c cf 11 c0 mov 0xc011cf0c,%eax +c0103ebe: 8b 40 08 mov 0x8(%eax),%eax +c0103ec1: 8b 55 0c mov 0xc(%ebp),%edx +c0103ec4: 89 54 24 04 mov %edx,0x4(%esp) +c0103ec8: 8b 55 08 mov 0x8(%ebp),%edx +c0103ecb: 89 14 24 mov %edx,(%esp) +c0103ece: ff d0 call *%eax +} +c0103ed0: 90 nop +c0103ed1: 89 ec mov %ebp,%esp +c0103ed3: 5d pop %ebp +c0103ed4: c3 ret + +c0103ed5 : + +//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) { +c0103ed5: 55 push %ebp +c0103ed6: 89 e5 mov %esp,%ebp +c0103ed8: 83 ec 28 sub $0x28,%esp + struct Page *page=NULL; +c0103edb: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + bool intr_flag; + //使用 local_intr_save 保存当前的中断状态,以避免在分配内存时发生中断。 + local_intr_save(intr_flag); +c0103ee2: e8 24 fe ff ff call c0103d0b <__intr_save> +c0103ee7: 89 45 f0 mov %eax,-0x10(%ebp) + { + //调用物理内存管理器的 alloc_pages 函数分配 n 页的内存。 + page = pmm_manager->alloc_pages(n); +c0103eea: a1 0c cf 11 c0 mov 0xc011cf0c,%eax +c0103eef: 8b 40 0c mov 0xc(%eax),%eax +c0103ef2: 8b 55 08 mov 0x8(%ebp),%edx +c0103ef5: 89 14 24 mov %edx,(%esp) +c0103ef8: ff d0 call *%eax +c0103efa: 89 45 f4 mov %eax,-0xc(%ebp) + } + //恢复之前保存的中断状态。 + local_intr_restore(intr_flag); +c0103efd: 8b 45 f0 mov -0x10(%ebp),%eax +c0103f00: 89 04 24 mov %eax,(%esp) +c0103f03: e8 2f fe ff ff call c0103d37 <__intr_restore> + return page; +c0103f08: 8b 45 f4 mov -0xc(%ebp),%eax +} +c0103f0b: 89 ec mov %ebp,%esp +c0103f0d: 5d pop %ebp +c0103f0e: c3 ret + +c0103f0f : + +//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) { +c0103f0f: 55 push %ebp +c0103f10: 89 e5 mov %esp,%ebp +c0103f12: 83 ec 28 sub $0x28,%esp + bool intr_flag; + //使用 local_intr_save 保存当前的中断状态,以避免在释放内存时发生中断。 + local_intr_save(intr_flag); +c0103f15: e8 f1 fd ff ff call c0103d0b <__intr_save> +c0103f1a: 89 45 f4 mov %eax,-0xc(%ebp) + { + //调用物理内存管理器的 free_pages 函数释放 n 页的内存。 + pmm_manager->free_pages(base, n); +c0103f1d: a1 0c cf 11 c0 mov 0xc011cf0c,%eax +c0103f22: 8b 40 10 mov 0x10(%eax),%eax +c0103f25: 8b 55 0c mov 0xc(%ebp),%edx +c0103f28: 89 54 24 04 mov %edx,0x4(%esp) +c0103f2c: 8b 55 08 mov 0x8(%ebp),%edx +c0103f2f: 89 14 24 mov %edx,(%esp) +c0103f32: ff d0 call *%eax + } + local_intr_restore(intr_flag); +c0103f34: 8b 45 f4 mov -0xc(%ebp),%eax +c0103f37: 89 04 24 mov %eax,(%esp) +c0103f3a: e8 f8 fd ff ff call c0103d37 <__intr_restore> +} +c0103f3f: 90 nop +c0103f40: 89 ec mov %ebp,%esp +c0103f42: 5d pop %ebp +c0103f43: c3 ret + +c0103f44 : + +//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) { +c0103f44: 55 push %ebp +c0103f45: 89 e5 mov %esp,%ebp +c0103f47: 83 ec 28 sub $0x28,%esp + size_t ret;// 定义变量 ret 用于存储返回的空闲内存大小 + bool intr_flag;// 定义变量 intr_flag 用于保存中断状态 + local_intr_save(intr_flag);// 保存当前中断状态,并禁用中断 +c0103f4a: e8 bc fd ff ff call c0103d0b <__intr_save> +c0103f4f: 89 45 f4 mov %eax,-0xc(%ebp) + { + ret = pmm_manager->nr_free_pages();// 调用物理内存管理器的函数获取空闲内存页数 +c0103f52: a1 0c cf 11 c0 mov 0xc011cf0c,%eax +c0103f57: 8b 40 14 mov 0x14(%eax),%eax +c0103f5a: ff d0 call *%eax +c0103f5c: 89 45 f0 mov %eax,-0x10(%ebp) + } + local_intr_restore(intr_flag);// 恢复之前保存的中断状态 +c0103f5f: 8b 45 f4 mov -0xc(%ebp),%eax +c0103f62: 89 04 24 mov %eax,(%esp) +c0103f65: e8 cd fd ff ff call c0103d37 <__intr_restore> + return ret;// 返回空闲内存的大小 +c0103f6a: 8b 45 f0 mov -0x10(%ebp),%eax +} +c0103f6d: 89 ec mov %ebp,%esp +c0103f6f: 5d pop %ebp +c0103f70: c3 ret + +c0103f71 : + +/* pmm_init - initialize the physical memory management */ +/* pmm_init - 初始化物理内存管理 */ +static void +page_init(void) { +c0103f71: 55 push %ebp +c0103f72: 89 e5 mov %esp,%ebp +c0103f74: 57 push %edi +c0103f75: 56 push %esi +c0103f76: 53 push %ebx +c0103f77: 81 ec 9c 00 00 00 sub $0x9c,%esp + // 获取物理内存映射信息,存于特定地址 + struct e820map *memmap = (struct e820map *)(0x8000 + KERNBASE); +c0103f7d: c7 45 c4 00 80 00 c0 movl $0xc0008000,-0x3c(%ebp) + uint64_t maxpa = 0;// 初始化最大物理地址为0 +c0103f84: c7 45 e0 00 00 00 00 movl $0x0,-0x20(%ebp) +c0103f8b: c7 45 e4 00 00 00 00 movl $0x0,-0x1c(%ebp) + + cprintf("e820map:\n");// 打印“e820map”标题 +c0103f92: c7 04 24 eb 6b 10 c0 movl $0xc0106beb,(%esp) +c0103f99: e8 c8 c3 ff ff call c0100366 + int i; + for (i = 0; i < memmap->nr_map; i ++) {// 遍历内存映射数组 +c0103f9e: c7 45 dc 00 00 00 00 movl $0x0,-0x24(%ebp) +c0103fa5: e9 0c 01 00 00 jmp c01040b6 + uint64_t begin = memmap->map[i].addr, end = begin + memmap->map[i].size; // 获取每个区域的起始和结束地址 +c0103faa: 8b 4d c4 mov -0x3c(%ebp),%ecx +c0103fad: 8b 55 dc mov -0x24(%ebp),%edx +c0103fb0: 89 d0 mov %edx,%eax +c0103fb2: c1 e0 02 shl $0x2,%eax +c0103fb5: 01 d0 add %edx,%eax +c0103fb7: c1 e0 02 shl $0x2,%eax +c0103fba: 01 c8 add %ecx,%eax +c0103fbc: 8b 50 08 mov 0x8(%eax),%edx +c0103fbf: 8b 40 04 mov 0x4(%eax),%eax +c0103fc2: 89 45 a0 mov %eax,-0x60(%ebp) +c0103fc5: 89 55 a4 mov %edx,-0x5c(%ebp) +c0103fc8: 8b 4d c4 mov -0x3c(%ebp),%ecx +c0103fcb: 8b 55 dc mov -0x24(%ebp),%edx +c0103fce: 89 d0 mov %edx,%eax +c0103fd0: c1 e0 02 shl $0x2,%eax +c0103fd3: 01 d0 add %edx,%eax +c0103fd5: c1 e0 02 shl $0x2,%eax +c0103fd8: 01 c8 add %ecx,%eax +c0103fda: 8b 48 0c mov 0xc(%eax),%ecx +c0103fdd: 8b 58 10 mov 0x10(%eax),%ebx +c0103fe0: 8b 45 a0 mov -0x60(%ebp),%eax +c0103fe3: 8b 55 a4 mov -0x5c(%ebp),%edx +c0103fe6: 01 c8 add %ecx,%eax +c0103fe8: 11 da adc %ebx,%edx +c0103fea: 89 45 98 mov %eax,-0x68(%ebp) +c0103fed: 89 55 9c mov %edx,-0x64(%ebp) + cprintf(" memory: %08llx, [%08llx, %08llx], type = %d.\n",// 打印内存区域的信息 +c0103ff0: 8b 4d c4 mov -0x3c(%ebp),%ecx +c0103ff3: 8b 55 dc mov -0x24(%ebp),%edx +c0103ff6: 89 d0 mov %edx,%eax +c0103ff8: c1 e0 02 shl $0x2,%eax +c0103ffb: 01 d0 add %edx,%eax +c0103ffd: c1 e0 02 shl $0x2,%eax +c0104000: 01 c8 add %ecx,%eax +c0104002: 83 c0 14 add $0x14,%eax +c0104005: 8b 00 mov (%eax),%eax +c0104007: 89 85 7c ff ff ff mov %eax,-0x84(%ebp) +c010400d: 8b 45 98 mov -0x68(%ebp),%eax +c0104010: 8b 55 9c mov -0x64(%ebp),%edx +c0104013: 83 c0 ff add $0xffffffff,%eax +c0104016: 83 d2 ff adc $0xffffffff,%edx +c0104019: 89 c6 mov %eax,%esi +c010401b: 89 d7 mov %edx,%edi +c010401d: 8b 4d c4 mov -0x3c(%ebp),%ecx +c0104020: 8b 55 dc mov -0x24(%ebp),%edx +c0104023: 89 d0 mov %edx,%eax +c0104025: c1 e0 02 shl $0x2,%eax +c0104028: 01 d0 add %edx,%eax +c010402a: c1 e0 02 shl $0x2,%eax +c010402d: 01 c8 add %ecx,%eax +c010402f: 8b 48 0c mov 0xc(%eax),%ecx +c0104032: 8b 58 10 mov 0x10(%eax),%ebx +c0104035: 8b 85 7c ff ff ff mov -0x84(%ebp),%eax +c010403b: 89 44 24 1c mov %eax,0x1c(%esp) +c010403f: 89 74 24 14 mov %esi,0x14(%esp) +c0104043: 89 7c 24 18 mov %edi,0x18(%esp) +c0104047: 8b 45 a0 mov -0x60(%ebp),%eax +c010404a: 8b 55 a4 mov -0x5c(%ebp),%edx +c010404d: 89 44 24 0c mov %eax,0xc(%esp) +c0104051: 89 54 24 10 mov %edx,0x10(%esp) +c0104055: 89 4c 24 04 mov %ecx,0x4(%esp) +c0104059: 89 5c 24 08 mov %ebx,0x8(%esp) +c010405d: c7 04 24 f8 6b 10 c0 movl $0xc0106bf8,(%esp) +c0104064: e8 fd c2 ff ff call c0100366 + memmap->map[i].size, begin, end - 1, memmap->map[i].type); + if (memmap->map[i].type == E820_ARM) { // 检查内存类型是否为可用内存 +c0104069: 8b 4d c4 mov -0x3c(%ebp),%ecx +c010406c: 8b 55 dc mov -0x24(%ebp),%edx +c010406f: 89 d0 mov %edx,%eax +c0104071: c1 e0 02 shl $0x2,%eax +c0104074: 01 d0 add %edx,%eax +c0104076: c1 e0 02 shl $0x2,%eax +c0104079: 01 c8 add %ecx,%eax +c010407b: 83 c0 14 add $0x14,%eax +c010407e: 8b 00 mov (%eax),%eax +c0104080: 83 f8 01 cmp $0x1,%eax +c0104083: 75 2e jne c01040b3 + if (maxpa < end && begin < KMEMSIZE) {// 检查当前区域是否在有效范围内 +c0104085: 8b 45 e0 mov -0x20(%ebp),%eax +c0104088: 8b 55 e4 mov -0x1c(%ebp),%edx +c010408b: 3b 45 98 cmp -0x68(%ebp),%eax +c010408e: 89 d0 mov %edx,%eax +c0104090: 1b 45 9c sbb -0x64(%ebp),%eax +c0104093: 73 1e jae c01040b3 +c0104095: ba ff ff ff 37 mov $0x37ffffff,%edx +c010409a: b8 00 00 00 00 mov $0x0,%eax +c010409f: 3b 55 a0 cmp -0x60(%ebp),%edx +c01040a2: 1b 45 a4 sbb -0x5c(%ebp),%eax +c01040a5: 72 0c jb c01040b3 + maxpa = end;// 更新最大物理地址 +c01040a7: 8b 45 98 mov -0x68(%ebp),%eax +c01040aa: 8b 55 9c mov -0x64(%ebp),%edx +c01040ad: 89 45 e0 mov %eax,-0x20(%ebp) +c01040b0: 89 55 e4 mov %edx,-0x1c(%ebp) + for (i = 0; i < memmap->nr_map; i ++) {// 遍历内存映射数组 +c01040b3: ff 45 dc incl -0x24(%ebp) +c01040b6: 8b 45 c4 mov -0x3c(%ebp),%eax +c01040b9: 8b 00 mov (%eax),%eax +c01040bb: 39 45 dc cmp %eax,-0x24(%ebp) +c01040be: 0f 8c e6 fe ff ff jl c0103faa + } + } + } + if (maxpa > KMEMSIZE) {// 如果最大物理地址超过了预定义的内存上限 +c01040c4: ba 00 00 00 38 mov $0x38000000,%edx +c01040c9: b8 00 00 00 00 mov $0x0,%eax +c01040ce: 3b 55 e0 cmp -0x20(%ebp),%edx +c01040d1: 1b 45 e4 sbb -0x1c(%ebp),%eax +c01040d4: 73 0e jae c01040e4 + maxpa = KMEMSIZE;// 将其限制为内存上限 +c01040d6: c7 45 e0 00 00 00 38 movl $0x38000000,-0x20(%ebp) +c01040dd: c7 45 e4 00 00 00 00 movl $0x0,-0x1c(%ebp) + } + + extern char end[];// 引入全局变量 end,指向内存的结束位置 + + npage = maxpa / PGSIZE; // 计算可用页数 +c01040e4: 8b 45 e0 mov -0x20(%ebp),%eax +c01040e7: 8b 55 e4 mov -0x1c(%ebp),%edx +c01040ea: 0f ac d0 0c shrd $0xc,%edx,%eax +c01040ee: c1 ea 0c shr $0xc,%edx +c01040f1: a3 04 cf 11 c0 mov %eax,0xc011cf04 + pages = (struct Page *)ROUNDUP((void *)end, PGSIZE);// 将 end 对齐到页边界,指向页结构数组的开头 +c01040f6: c7 45 c0 00 10 00 00 movl $0x1000,-0x40(%ebp) +c01040fd: b8 8c cf 11 c0 mov $0xc011cf8c,%eax +c0104102: 8d 50 ff lea -0x1(%eax),%edx +c0104105: 8b 45 c0 mov -0x40(%ebp),%eax +c0104108: 01 d0 add %edx,%eax +c010410a: 89 45 bc mov %eax,-0x44(%ebp) +c010410d: 8b 45 bc mov -0x44(%ebp),%eax +c0104110: ba 00 00 00 00 mov $0x0,%edx +c0104115: f7 75 c0 divl -0x40(%ebp) +c0104118: 8b 45 bc mov -0x44(%ebp),%eax +c010411b: 29 d0 sub %edx,%eax +c010411d: a3 00 cf 11 c0 mov %eax,0xc011cf00 + + for (i = 0; i < npage; i ++) {// 遍历每一页 +c0104122: c7 45 dc 00 00 00 00 movl $0x0,-0x24(%ebp) +c0104129: eb 2f jmp c010415a + SetPageReserved(pages + i);// 将每一页标记为保留状态 +c010412b: 8b 0d 00 cf 11 c0 mov 0xc011cf00,%ecx +c0104131: 8b 55 dc mov -0x24(%ebp),%edx +c0104134: 89 d0 mov %edx,%eax +c0104136: c1 e0 02 shl $0x2,%eax +c0104139: 01 d0 add %edx,%eax +c010413b: c1 e0 02 shl $0x2,%eax +c010413e: 01 c8 add %ecx,%eax +c0104140: 83 c0 04 add $0x4,%eax +c0104143: c7 45 94 00 00 00 00 movl $0x0,-0x6c(%ebp) +c010414a: 89 45 90 mov %eax,-0x70(%ebp) + asm volatile ("btsl %1, %0" :"=m" (*(volatile long *)addr) : "Ir" (nr)); +c010414d: 8b 45 90 mov -0x70(%ebp),%eax +c0104150: 8b 55 94 mov -0x6c(%ebp),%edx +c0104153: 0f ab 10 bts %edx,(%eax) +} +c0104156: 90 nop + for (i = 0; i < npage; i ++) {// 遍历每一页 +c0104157: ff 45 dc incl -0x24(%ebp) +c010415a: 8b 55 dc mov -0x24(%ebp),%edx +c010415d: a1 04 cf 11 c0 mov 0xc011cf04,%eax +c0104162: 39 c2 cmp %eax,%edx +c0104164: 72 c5 jb c010412b + } + + uintptr_t freemem = PADDR((uintptr_t)pages + sizeof(struct Page) * npage);// 计算可用内存的起始地址 +c0104166: 8b 15 04 cf 11 c0 mov 0xc011cf04,%edx +c010416c: 89 d0 mov %edx,%eax +c010416e: c1 e0 02 shl $0x2,%eax +c0104171: 01 d0 add %edx,%eax +c0104173: c1 e0 02 shl $0x2,%eax +c0104176: 89 c2 mov %eax,%edx +c0104178: a1 00 cf 11 c0 mov 0xc011cf00,%eax +c010417d: 01 d0 add %edx,%eax +c010417f: 89 45 b8 mov %eax,-0x48(%ebp) +c0104182: 81 7d b8 ff ff ff bf cmpl $0xbfffffff,-0x48(%ebp) +c0104189: 77 23 ja c01041ae +c010418b: 8b 45 b8 mov -0x48(%ebp),%eax +c010418e: 89 44 24 0c mov %eax,0xc(%esp) +c0104192: c7 44 24 08 28 6c 10 movl $0xc0106c28,0x8(%esp) +c0104199: c0 +c010419a: c7 44 24 04 0c 01 00 movl $0x10c,0x4(%esp) +c01041a1: 00 +c01041a2: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c01041a9: e8 85 ca ff ff call c0100c33 <__panic> +c01041ae: 8b 45 b8 mov -0x48(%ebp),%eax +c01041b1: 05 00 00 00 40 add $0x40000000,%eax +c01041b6: 89 45 b4 mov %eax,-0x4c(%ebp) + + for (i = 0; i < memmap->nr_map; i ++) {// 再次遍历内存映射 +c01041b9: c7 45 dc 00 00 00 00 movl $0x0,-0x24(%ebp) +c01041c0: e9 53 01 00 00 jmp c0104318 + uint64_t begin = memmap->map[i].addr, end = begin + memmap->map[i].size;// 获取每个区域的起始和结束地址 +c01041c5: 8b 4d c4 mov -0x3c(%ebp),%ecx +c01041c8: 8b 55 dc mov -0x24(%ebp),%edx +c01041cb: 89 d0 mov %edx,%eax +c01041cd: c1 e0 02 shl $0x2,%eax +c01041d0: 01 d0 add %edx,%eax +c01041d2: c1 e0 02 shl $0x2,%eax +c01041d5: 01 c8 add %ecx,%eax +c01041d7: 8b 50 08 mov 0x8(%eax),%edx +c01041da: 8b 40 04 mov 0x4(%eax),%eax +c01041dd: 89 45 d0 mov %eax,-0x30(%ebp) +c01041e0: 89 55 d4 mov %edx,-0x2c(%ebp) +c01041e3: 8b 4d c4 mov -0x3c(%ebp),%ecx +c01041e6: 8b 55 dc mov -0x24(%ebp),%edx +c01041e9: 89 d0 mov %edx,%eax +c01041eb: c1 e0 02 shl $0x2,%eax +c01041ee: 01 d0 add %edx,%eax +c01041f0: c1 e0 02 shl $0x2,%eax +c01041f3: 01 c8 add %ecx,%eax +c01041f5: 8b 48 0c mov 0xc(%eax),%ecx +c01041f8: 8b 58 10 mov 0x10(%eax),%ebx +c01041fb: 8b 45 d0 mov -0x30(%ebp),%eax +c01041fe: 8b 55 d4 mov -0x2c(%ebp),%edx +c0104201: 01 c8 add %ecx,%eax +c0104203: 11 da adc %ebx,%edx +c0104205: 89 45 c8 mov %eax,-0x38(%ebp) +c0104208: 89 55 cc mov %edx,-0x34(%ebp) + if (memmap->map[i].type == E820_ARM) {// 如果区域类型为可用内存 +c010420b: 8b 4d c4 mov -0x3c(%ebp),%ecx +c010420e: 8b 55 dc mov -0x24(%ebp),%edx +c0104211: 89 d0 mov %edx,%eax +c0104213: c1 e0 02 shl $0x2,%eax +c0104216: 01 d0 add %edx,%eax +c0104218: c1 e0 02 shl $0x2,%eax +c010421b: 01 c8 add %ecx,%eax +c010421d: 83 c0 14 add $0x14,%eax +c0104220: 8b 00 mov (%eax),%eax +c0104222: 83 f8 01 cmp $0x1,%eax +c0104225: 0f 85 ea 00 00 00 jne c0104315 + if (begin < freemem) { // 如果起始地址小于可用内存地址 +c010422b: 8b 45 b4 mov -0x4c(%ebp),%eax +c010422e: ba 00 00 00 00 mov $0x0,%edx +c0104233: 8b 4d d4 mov -0x2c(%ebp),%ecx +c0104236: 39 45 d0 cmp %eax,-0x30(%ebp) +c0104239: 19 d1 sbb %edx,%ecx +c010423b: 73 0d jae c010424a + begin = freemem;// 将起始地址设置为可用内存地址 +c010423d: 8b 45 b4 mov -0x4c(%ebp),%eax +c0104240: 89 45 d0 mov %eax,-0x30(%ebp) +c0104243: c7 45 d4 00 00 00 00 movl $0x0,-0x2c(%ebp) + } + if (end > KMEMSIZE) {// 如果结束地址超过内存上限 +c010424a: ba 00 00 00 38 mov $0x38000000,%edx +c010424f: b8 00 00 00 00 mov $0x0,%eax +c0104254: 3b 55 c8 cmp -0x38(%ebp),%edx +c0104257: 1b 45 cc sbb -0x34(%ebp),%eax +c010425a: 73 0e jae c010426a + end = KMEMSIZE;// 将其限制为内存上限 +c010425c: c7 45 c8 00 00 00 38 movl $0x38000000,-0x38(%ebp) +c0104263: c7 45 cc 00 00 00 00 movl $0x0,-0x34(%ebp) + } + if (begin < end) {// 如果起始地址小于结束地址 +c010426a: 8b 45 d0 mov -0x30(%ebp),%eax +c010426d: 8b 55 d4 mov -0x2c(%ebp),%edx +c0104270: 3b 45 c8 cmp -0x38(%ebp),%eax +c0104273: 89 d0 mov %edx,%eax +c0104275: 1b 45 cc sbb -0x34(%ebp),%eax +c0104278: 0f 83 97 00 00 00 jae c0104315 + begin = ROUNDUP(begin, PGSIZE);// 将起始地址对齐到页边界 +c010427e: c7 45 b0 00 10 00 00 movl $0x1000,-0x50(%ebp) +c0104285: 8b 55 d0 mov -0x30(%ebp),%edx +c0104288: 8b 45 b0 mov -0x50(%ebp),%eax +c010428b: 01 d0 add %edx,%eax +c010428d: 48 dec %eax +c010428e: 89 45 ac mov %eax,-0x54(%ebp) +c0104291: 8b 45 ac mov -0x54(%ebp),%eax +c0104294: ba 00 00 00 00 mov $0x0,%edx +c0104299: f7 75 b0 divl -0x50(%ebp) +c010429c: 8b 45 ac mov -0x54(%ebp),%eax +c010429f: 29 d0 sub %edx,%eax +c01042a1: ba 00 00 00 00 mov $0x0,%edx +c01042a6: 89 45 d0 mov %eax,-0x30(%ebp) +c01042a9: 89 55 d4 mov %edx,-0x2c(%ebp) + end = ROUNDDOWN(end, PGSIZE);// 将结束地址对齐到页边界 +c01042ac: 8b 45 c8 mov -0x38(%ebp),%eax +c01042af: 89 45 a8 mov %eax,-0x58(%ebp) +c01042b2: 8b 45 a8 mov -0x58(%ebp),%eax +c01042b5: ba 00 00 00 00 mov $0x0,%edx +c01042ba: 89 c7 mov %eax,%edi +c01042bc: 81 e7 00 f0 ff ff and $0xfffff000,%edi +c01042c2: 89 7d 80 mov %edi,-0x80(%ebp) +c01042c5: 89 d0 mov %edx,%eax +c01042c7: 83 e0 00 and $0x0,%eax +c01042ca: 89 45 84 mov %eax,-0x7c(%ebp) +c01042cd: 8b 45 80 mov -0x80(%ebp),%eax +c01042d0: 8b 55 84 mov -0x7c(%ebp),%edx +c01042d3: 89 45 c8 mov %eax,-0x38(%ebp) +c01042d6: 89 55 cc mov %edx,-0x34(%ebp) + if (begin < end) {// 如果调整后的起始地址仍小于结束地址 +c01042d9: 8b 45 d0 mov -0x30(%ebp),%eax +c01042dc: 8b 55 d4 mov -0x2c(%ebp),%edx +c01042df: 3b 45 c8 cmp -0x38(%ebp),%eax +c01042e2: 89 d0 mov %edx,%eax +c01042e4: 1b 45 cc sbb -0x34(%ebp),%eax +c01042e7: 73 2c jae c0104315 + init_memmap(pa2page(begin), (end - begin) / PGSIZE);// 初始化内存页映射 +c01042e9: 8b 45 c8 mov -0x38(%ebp),%eax +c01042ec: 8b 55 cc mov -0x34(%ebp),%edx +c01042ef: 2b 45 d0 sub -0x30(%ebp),%eax +c01042f2: 1b 55 d4 sbb -0x2c(%ebp),%edx +c01042f5: 0f ac d0 0c shrd $0xc,%edx,%eax +c01042f9: c1 ea 0c shr $0xc,%edx +c01042fc: 89 c3 mov %eax,%ebx +c01042fe: 8b 45 d0 mov -0x30(%ebp),%eax +c0104301: 89 04 24 mov %eax,(%esp) +c0104304: e8 bb f8 ff ff call c0103bc4 +c0104309: 89 5c 24 04 mov %ebx,0x4(%esp) +c010430d: 89 04 24 mov %eax,(%esp) +c0104310: e8 9e fb ff ff call c0103eb3 + for (i = 0; i < memmap->nr_map; i ++) {// 再次遍历内存映射 +c0104315: ff 45 dc incl -0x24(%ebp) +c0104318: 8b 45 c4 mov -0x3c(%ebp),%eax +c010431b: 8b 00 mov (%eax),%eax +c010431d: 39 45 dc cmp %eax,-0x24(%ebp) +c0104320: 0f 8c 9f fe ff ff jl c01041c5 + } + } + } + } +} +c0104326: 90 nop +c0104327: 90 nop +c0104328: 81 c4 9c 00 00 00 add $0x9c,%esp +c010432e: 5b pop %ebx +c010432f: 5e pop %esi +c0104330: 5f pop %edi +c0104331: 5d pop %ebp +c0104332: c3 ret + +c0104333 : +//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) { +c0104333: 55 push %ebp +c0104334: 89 e5 mov %esp,%ebp +c0104336: 83 ec 38 sub $0x38,%esp + // 确保线性地址和物理地址的页偏移相同 + assert(PGOFF(la) == PGOFF(pa)); +c0104339: 8b 45 0c mov 0xc(%ebp),%eax +c010433c: 33 45 14 xor 0x14(%ebp),%eax +c010433f: 25 ff 0f 00 00 and $0xfff,%eax +c0104344: 85 c0 test %eax,%eax +c0104346: 74 24 je c010436c +c0104348: c7 44 24 0c 5a 6c 10 movl $0xc0106c5a,0xc(%esp) +c010434f: c0 +c0104350: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c0104357: c0 +c0104358: c7 44 24 04 2d 01 00 movl $0x12d,0x4(%esp) +c010435f: 00 +c0104360: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c0104367: e8 c7 c8 ff ff call c0100c33 <__panic> + // 计算需要映射的页数,ROUNDUP 将总大小对齐到下一个页大小的边界 + size_t n = ROUNDUP(size + PGOFF(la), PGSIZE) / PGSIZE; +c010436c: c7 45 f0 00 10 00 00 movl $0x1000,-0x10(%ebp) +c0104373: 8b 45 0c mov 0xc(%ebp),%eax +c0104376: 25 ff 0f 00 00 and $0xfff,%eax +c010437b: 89 c2 mov %eax,%edx +c010437d: 8b 45 10 mov 0x10(%ebp),%eax +c0104380: 01 c2 add %eax,%edx +c0104382: 8b 45 f0 mov -0x10(%ebp),%eax +c0104385: 01 d0 add %edx,%eax +c0104387: 48 dec %eax +c0104388: 89 45 ec mov %eax,-0x14(%ebp) +c010438b: 8b 45 ec mov -0x14(%ebp),%eax +c010438e: ba 00 00 00 00 mov $0x0,%edx +c0104393: f7 75 f0 divl -0x10(%ebp) +c0104396: 8b 45 ec mov -0x14(%ebp),%eax +c0104399: 29 d0 sub %edx,%eax +c010439b: c1 e8 0c shr $0xc,%eax +c010439e: 89 45 f4 mov %eax,-0xc(%ebp) + // 将线性地址向下对齐到页边界 + la = ROUNDDOWN(la, PGSIZE); +c01043a1: 8b 45 0c mov 0xc(%ebp),%eax +c01043a4: 89 45 e8 mov %eax,-0x18(%ebp) +c01043a7: 8b 45 e8 mov -0x18(%ebp),%eax +c01043aa: 25 00 f0 ff ff and $0xfffff000,%eax +c01043af: 89 45 0c mov %eax,0xc(%ebp) + // 将物理地址向下对齐到页边界 + pa = ROUNDDOWN(pa, PGSIZE); +c01043b2: 8b 45 14 mov 0x14(%ebp),%eax +c01043b5: 89 45 e4 mov %eax,-0x1c(%ebp) +c01043b8: 8b 45 e4 mov -0x1c(%ebp),%eax +c01043bb: 25 00 f0 ff ff and $0xfffff000,%eax +c01043c0: 89 45 14 mov %eax,0x14(%ebp) + // 循环遍历每一页,直到映射的页数为零 + for (; n > 0; n --, la += PGSIZE, pa += PGSIZE) { +c01043c3: eb 68 jmp c010442d + // 获取当前页的页表项指针,如果不存在则创建新的页表项 + pte_t *ptep = get_pte(pgdir, la, 1); +c01043c5: c7 44 24 08 01 00 00 movl $0x1,0x8(%esp) +c01043cc: 00 +c01043cd: 8b 45 0c mov 0xc(%ebp),%eax +c01043d0: 89 44 24 04 mov %eax,0x4(%esp) +c01043d4: 8b 45 08 mov 0x8(%ebp),%eax +c01043d7: 89 04 24 mov %eax,(%esp) +c01043da: e8 88 01 00 00 call c0104567 +c01043df: 89 45 e0 mov %eax,-0x20(%ebp) + // 确保页表项指针不为空 + assert(ptep != NULL); +c01043e2: 83 7d e0 00 cmpl $0x0,-0x20(%ebp) +c01043e6: 75 24 jne c010440c +c01043e8: c7 44 24 0c 86 6c 10 movl $0xc0106c86,0xc(%esp) +c01043ef: c0 +c01043f0: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c01043f7: c0 +c01043f8: c7 44 24 04 39 01 00 movl $0x139,0x4(%esp) +c01043ff: 00 +c0104400: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c0104407: e8 27 c8 ff ff call c0100c33 <__panic> + // 设置页表项,包含物理地址、存在位和权限 + *ptep = pa | PTE_P | perm; +c010440c: 8b 45 14 mov 0x14(%ebp),%eax +c010440f: 0b 45 18 or 0x18(%ebp),%eax +c0104412: 83 c8 01 or $0x1,%eax +c0104415: 89 c2 mov %eax,%edx +c0104417: 8b 45 e0 mov -0x20(%ebp),%eax +c010441a: 89 10 mov %edx,(%eax) + for (; n > 0; n --, la += PGSIZE, pa += PGSIZE) { +c010441c: ff 4d f4 decl -0xc(%ebp) +c010441f: 81 45 0c 00 10 00 00 addl $0x1000,0xc(%ebp) +c0104426: 81 45 14 00 10 00 00 addl $0x1000,0x14(%ebp) +c010442d: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c0104431: 75 92 jne c01043c5 + } +} +c0104433: 90 nop +c0104434: 90 nop +c0104435: 89 ec mov %ebp,%esp +c0104437: 5d pop %ebp +c0104438: c3 ret + +c0104439 : +// 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) { +c0104439: 55 push %ebp +c010443a: 89 e5 mov %esp,%ebp +c010443c: 83 ec 28 sub $0x28,%esp + struct Page *p = alloc_page();// 调用分配页面的函数 +c010443f: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c0104446: e8 8a fa ff ff call c0103ed5 +c010444b: 89 45 f4 mov %eax,-0xc(%ebp) + if (p == NULL) {// 检查分配是否成功 +c010444e: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c0104452: 75 1c jne c0104470 + panic("boot_alloc_page failed.\n");// 如果分配失败,则触发异常 +c0104454: c7 44 24 08 93 6c 10 movl $0xc0106c93,0x8(%esp) +c010445b: c0 +c010445c: c7 44 24 04 48 01 00 movl $0x148,0x4(%esp) +c0104463: 00 +c0104464: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c010446b: e8 c3 c7 ff ff call c0100c33 <__panic> + } + return page2kva(p);// 返回分配页面的内核虚拟地址 +c0104470: 8b 45 f4 mov -0xc(%ebp),%eax +c0104473: 89 04 24 mov %eax,(%esp) +c0104476: e8 9a f7 ff ff call c0103c15 +} +c010447b: 89 ec mov %ebp,%esp +c010447d: 5d pop %ebp +c010447e: c3 ret + +c010447f : +//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) { +c010447f: 55 push %ebp +c0104480: 89 e5 mov %esp,%ebp +c0104482: 83 ec 38 sub $0x38,%esp + // We've already enabled paging + // 我们已经启用了分页 + boot_cr3 = PADDR(boot_pgdir); +c0104485: a1 e0 99 11 c0 mov 0xc01199e0,%eax +c010448a: 89 45 f4 mov %eax,-0xc(%ebp) +c010448d: 81 7d f4 ff ff ff bf cmpl $0xbfffffff,-0xc(%ebp) +c0104494: 77 23 ja c01044b9 +c0104496: 8b 45 f4 mov -0xc(%ebp),%eax +c0104499: 89 44 24 0c mov %eax,0xc(%esp) +c010449d: c7 44 24 08 28 6c 10 movl $0xc0106c28,0x8(%esp) +c01044a4: c0 +c01044a5: c7 44 24 04 55 01 00 movl $0x155,0x4(%esp) +c01044ac: 00 +c01044ad: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c01044b4: e8 7a c7 ff ff call c0100c33 <__panic> +c01044b9: 8b 45 f4 mov -0xc(%ebp),%eax +c01044bc: 05 00 00 00 40 add $0x40000000,%eax +c01044c1: a3 08 cf 11 c0 mov %eax,0xc011cf08 + // 我们需要分配/释放物理内存(粒度为 4KB 或其他大小)。 + // 因此在 pmm.h 中定义了物理内存管理器的框架(struct pmm_manager)。 + // 首先,我们应该基于该框架初始化一个物理内存管理器(pmm)。 + // 然后 pmm 可以分配/释放物理内存。 + // 现在,first_fit/best_fit/worst_fit/buddy_system 的 pmm 都可用。 + init_pmm_manager();// 初始化物理内存管理器 +c01044c6: e8 b2 f9 ff ff call c0103e7d + + // detect physical memory space, reserve already used memory, + // then use pmm->init_memmap to create free page list + // 检测物理内存空间,保留已经使用的内存, + // 然后使用 pmm->init_memmap 创建空闲页面列表 + page_init();// 初始化页面管理 +c01044cb: e8 a1 fa ff ff call c0103f71 + + //use pmm->check to verify the correctness of the alloc/free function in a pmm + // 使用 pmm->check 验证 pmm 中分配/释放函数的正确性 + check_alloc_page();// 检查页面分配功能 +c01044d0: e8 ed 03 00 00 call c01048c2 + + check_pgdir();// 检查页目录的状态 +c01044d5: e8 09 04 00 00 call c01048e3 + + // 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;// 设置页目录项,映射自身 +c01044da: a1 e0 99 11 c0 mov 0xc01199e0,%eax +c01044df: 89 45 f0 mov %eax,-0x10(%ebp) +c01044e2: 81 7d f0 ff ff ff bf cmpl $0xbfffffff,-0x10(%ebp) +c01044e9: 77 23 ja c010450e +c01044eb: 8b 45 f0 mov -0x10(%ebp),%eax +c01044ee: 89 44 24 0c mov %eax,0xc(%esp) +c01044f2: c7 44 24 08 28 6c 10 movl $0xc0106c28,0x8(%esp) +c01044f9: c0 +c01044fa: c7 44 24 04 75 01 00 movl $0x175,0x4(%esp) +c0104501: 00 +c0104502: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c0104509: e8 25 c7 ff ff call c0100c33 <__panic> +c010450e: 8b 45 f0 mov -0x10(%ebp),%eax +c0104511: 8d 90 00 00 00 40 lea 0x40000000(%eax),%edx +c0104517: a1 e0 99 11 c0 mov 0xc01199e0,%eax +c010451c: 05 ac 0f 00 00 add $0xfac,%eax +c0104521: 83 ca 03 or $0x3,%edx +c0104524: 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);// 映射物理内存 +c0104526: a1 e0 99 11 c0 mov 0xc01199e0,%eax +c010452b: c7 44 24 10 02 00 00 movl $0x2,0x10(%esp) +c0104532: 00 +c0104533: c7 44 24 0c 00 00 00 movl $0x0,0xc(%esp) +c010453a: 00 +c010453b: c7 44 24 08 00 00 00 movl $0x38000000,0x8(%esp) +c0104542: 38 +c0104543: c7 44 24 04 00 00 00 movl $0xc0000000,0x4(%esp) +c010454a: c0 +c010454b: 89 04 24 mov %eax,(%esp) +c010454e: e8 e0 fd ff ff call c0104333 + // 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();// 初始化全局描述符表 +c0104553: e8 39 f8 ff ff call c0103d91 + + //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(); // 检查页目录的正确性 +c0104558: e8 24 0a 00 00 call c0104f81 + + print_pgdir(); // 打印页目录表 +c010455d: e8 a1 0e 00 00 call c0105403 + +} +c0104562: 90 nop +c0104563: 89 ec mov %ebp,%esp +c0104565: 5d pop %ebp +c0104566: c3 ret + +c0104567 : +// pgdir: 页目录的内核虚拟基地址 +// la: 需要映射的线性地址 +// create: 一个逻辑值,决定是否为页表分配一页 +// 返回值:该 PTE 的内核虚拟地址 +pte_t * +get_pte(pde_t *pgdir, uintptr_t la, bool create) { +c0104567: 55 push %ebp +c0104568: 89 e5 mov %esp,%ebp +c010456a: 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 宏获取页目录索引 +c010456d: 8b 45 0c mov 0xc(%ebp),%eax +c0104570: c1 e8 16 shr $0x16,%eax +c0104573: 8d 14 85 00 00 00 00 lea 0x0(,%eax,4),%edx +c010457a: 8b 45 08 mov 0x8(%ebp),%eax +c010457d: 01 d0 add %edx,%eax +c010457f: 89 45 f4 mov %eax,-0xc(%ebp) + // (2) 检查页目录项是否存在 + if (!(*pdep & PTE_P)) {// 如果页目录项的存在位 PTE_P 没有被设置 +c0104582: 8b 45 f4 mov -0xc(%ebp),%eax +c0104585: 8b 00 mov (%eax),%eax +c0104587: 83 e0 01 and $0x1,%eax +c010458a: 85 c0 test %eax,%eax +c010458c: 0f 85 af 00 00 00 jne c0104641 + struct Page *page;// 声明一个指针,用于指向新分配的页面 + // 检查是否允许创建新页表,或者分配页表失败 + if (!create || (page = alloc_page()) == NULL) {// 如果不允许创建或分配失败 +c0104592: 83 7d 10 00 cmpl $0x0,0x10(%ebp) +c0104596: 74 15 je c01045ad +c0104598: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c010459f: e8 31 f9 ff ff call c0103ed5 +c01045a4: 89 45 f0 mov %eax,-0x10(%ebp) +c01045a7: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) +c01045ab: 75 0a jne c01045b7 + return NULL;// 返回 NULL,表示无法获取页表 +c01045ad: b8 00 00 00 00 mov $0x0,%eax +c01045b2: e9 e7 00 00 00 jmp c010469e + } + // 设置新分配页面的引用计数为 1 + set_page_ref(page, 1); +c01045b7: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c01045be: 00 +c01045bf: 8b 45 f0 mov -0x10(%ebp),%eax +c01045c2: 89 04 24 mov %eax,(%esp) +c01045c5: e8 05 f7 ff ff call c0103ccf + uintptr_t pa = page2pa(page);// 获取新分配页面的物理地址 +c01045ca: 8b 45 f0 mov -0x10(%ebp),%eax +c01045cd: 89 04 24 mov %eax,(%esp) +c01045d0: e8 d7 f5 ff ff call c0103bac +c01045d5: 89 45 ec mov %eax,-0x14(%ebp) + memset(KADDR(pa), 0, PGSIZE);// 清空新分配的页表内容,初始化为零 +c01045d8: 8b 45 ec mov -0x14(%ebp),%eax +c01045db: 89 45 e8 mov %eax,-0x18(%ebp) +c01045de: 8b 45 e8 mov -0x18(%ebp),%eax +c01045e1: c1 e8 0c shr $0xc,%eax +c01045e4: 89 45 e4 mov %eax,-0x1c(%ebp) +c01045e7: a1 04 cf 11 c0 mov 0xc011cf04,%eax +c01045ec: 39 45 e4 cmp %eax,-0x1c(%ebp) +c01045ef: 72 23 jb c0104614 +c01045f1: 8b 45 e8 mov -0x18(%ebp),%eax +c01045f4: 89 44 24 0c mov %eax,0xc(%esp) +c01045f8: c7 44 24 08 84 6b 10 movl $0xc0106b84,0x8(%esp) +c01045ff: c0 +c0104600: c7 44 24 04 ce 01 00 movl $0x1ce,0x4(%esp) +c0104607: 00 +c0104608: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c010460f: e8 1f c6 ff ff call c0100c33 <__panic> +c0104614: 8b 45 e8 mov -0x18(%ebp),%eax +c0104617: 2d 00 00 00 40 sub $0x40000000,%eax +c010461c: c7 44 24 08 00 10 00 movl $0x1000,0x8(%esp) +c0104623: 00 +c0104624: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) +c010462b: 00 +c010462c: 89 04 24 mov %eax,(%esp) +c010462f: e8 d4 18 00 00 call c0105f08 + // 更新页目录项,设置物理地址和权限位 + *pdep = pa | PTE_U | PTE_W | PTE_P;// 将物理地址和权限位(用户可访问、可写、有效)合并设置 +c0104634: 8b 45 ec mov -0x14(%ebp),%eax +c0104637: 83 c8 07 or $0x7,%eax +c010463a: 89 c2 mov %eax,%edx +c010463c: 8b 45 f4 mov -0xc(%ebp),%eax +c010463f: 89 10 mov %edx,(%eax) + } + // 返回指定线性地址 la 对应的页表项的内核虚拟地址 + return &((pte_t *)KADDR(PDE_ADDR(*pdep)))[PTX(la)];// 计算并返回页表项的指针 +c0104641: 8b 45 f4 mov -0xc(%ebp),%eax +c0104644: 8b 00 mov (%eax),%eax +c0104646: 25 00 f0 ff ff and $0xfffff000,%eax +c010464b: 89 45 e0 mov %eax,-0x20(%ebp) +c010464e: 8b 45 e0 mov -0x20(%ebp),%eax +c0104651: c1 e8 0c shr $0xc,%eax +c0104654: 89 45 dc mov %eax,-0x24(%ebp) +c0104657: a1 04 cf 11 c0 mov 0xc011cf04,%eax +c010465c: 39 45 dc cmp %eax,-0x24(%ebp) +c010465f: 72 23 jb c0104684 +c0104661: 8b 45 e0 mov -0x20(%ebp),%eax +c0104664: 89 44 24 0c mov %eax,0xc(%esp) +c0104668: c7 44 24 08 84 6b 10 movl $0xc0106b84,0x8(%esp) +c010466f: c0 +c0104670: c7 44 24 04 d3 01 00 movl $0x1d3,0x4(%esp) +c0104677: 00 +c0104678: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c010467f: e8 af c5 ff ff call c0100c33 <__panic> +c0104684: 8b 45 e0 mov -0x20(%ebp),%eax +c0104687: 2d 00 00 00 40 sub $0x40000000,%eax +c010468c: 89 c2 mov %eax,%edx +c010468e: 8b 45 0c mov 0xc(%ebp),%eax +c0104691: c1 e8 0c shr $0xc,%eax +c0104694: 25 ff 03 00 00 and $0x3ff,%eax +c0104699: c1 e0 02 shl $0x2,%eax +c010469c: 01 d0 add %edx,%eax +} +c010469e: 89 ec mov %ebp,%esp +c01046a0: 5d pop %ebp +c01046a1: c3 ret + +c01046a2 : + +//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) { +c01046a2: 55 push %ebp +c01046a3: 89 e5 mov %esp,%ebp +c01046a5: 83 ec 28 sub $0x28,%esp + // 调用 get_pte 函数获取对应线性地址 la 的页表项指针 + pte_t *ptep = get_pte(pgdir, la, 0); +c01046a8: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) +c01046af: 00 +c01046b0: 8b 45 0c mov 0xc(%ebp),%eax +c01046b3: 89 44 24 04 mov %eax,0x4(%esp) +c01046b7: 8b 45 08 mov 0x8(%ebp),%eax +c01046ba: 89 04 24 mov %eax,(%esp) +c01046bd: e8 a5 fe ff ff call c0104567 +c01046c2: 89 45 f4 mov %eax,-0xc(%ebp) + // 如果 ptep_store 指针不为 NULL,将 ptep 存储到 ptep_store 指向的位置 + if (ptep_store != NULL) { +c01046c5: 83 7d 10 00 cmpl $0x0,0x10(%ebp) +c01046c9: 74 08 je c01046d3 + *ptep_store = ptep; // 存储当前页表项的指针 +c01046cb: 8b 45 10 mov 0x10(%ebp),%eax +c01046ce: 8b 55 f4 mov -0xc(%ebp),%edx +c01046d1: 89 10 mov %edx,(%eax) + } + // 检查 ptep 是否有效以及页表项的存在位 PTE_P 是否被设置 + if (ptep != NULL && *ptep & PTE_P) { +c01046d3: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c01046d7: 74 1b je c01046f4 +c01046d9: 8b 45 f4 mov -0xc(%ebp),%eax +c01046dc: 8b 00 mov (%eax),%eax +c01046de: 83 e0 01 and $0x1,%eax +c01046e1: 85 c0 test %eax,%eax +c01046e3: 74 0f je c01046f4 + // 返回与页表项对应的 Page 结构体 + return pte2page(*ptep);// 将页表项转换为对应的 Page 结构 +c01046e5: 8b 45 f4 mov -0xc(%ebp),%eax +c01046e8: 8b 00 mov (%eax),%eax +c01046ea: 89 04 24 mov %eax,(%esp) +c01046ed: e8 79 f5 ff ff call c0103c6b +c01046f2: eb 05 jmp c01046f9 + } + // 如果未找到有效的页,返回 NULL + return NULL; +c01046f4: b8 00 00 00 00 mov $0x0,%eax +} +c01046f9: 89 ec mov %ebp,%esp +c01046fb: 5d pop %ebp +c01046fc: c3 ret + +c01046fd : + +//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) { +c01046fd: 55 push %ebp +c01046fe: 89 e5 mov %esp,%ebp +c0104700: 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) { +c0104703: 8b 45 10 mov 0x10(%ebp),%eax +c0104706: 8b 00 mov (%eax),%eax +c0104708: 83 e0 01 and $0x1,%eax +c010470b: 85 c0 test %eax,%eax +c010470d: 74 4d je c010475c + struct Page *page = pte2page(*ptep);// 找到对应的物理页 +c010470f: 8b 45 10 mov 0x10(%ebp),%eax +c0104712: 8b 00 mov (%eax),%eax +c0104714: 89 04 24 mov %eax,(%esp) +c0104717: e8 4f f5 ff ff call c0103c6b +c010471c: 89 45 f4 mov %eax,-0xc(%ebp) + // 减少物理页的引用计数,如果引用计数为零,释放该物理页 + if (page_ref_dec(page) == 0) { +c010471f: 8b 45 f4 mov -0xc(%ebp),%eax +c0104722: 89 04 24 mov %eax,(%esp) +c0104725: e8 ca f5 ff ff call c0103cf4 +c010472a: 85 c0 test %eax,%eax +c010472c: 75 13 jne c0104741 + free_page(page); +c010472e: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c0104735: 00 +c0104736: 8b 45 f4 mov -0xc(%ebp),%eax +c0104739: 89 04 24 mov %eax,(%esp) +c010473c: e8 ce f7 ff ff call c0103f0f + } + *ptep = 0;// 清除页表项 +c0104741: 8b 45 10 mov 0x10(%ebp),%eax +c0104744: c7 00 00 00 00 00 movl $0x0,(%eax) + tlb_invalidate(pgdir, la);// 刷新 TLB +c010474a: 8b 45 0c mov 0xc(%ebp),%eax +c010474d: 89 44 24 04 mov %eax,0x4(%esp) +c0104751: 8b 45 08 mov 0x8(%ebp),%eax +c0104754: 89 04 24 mov %eax,(%esp) +c0104757: e8 07 01 00 00 call c0104863 + } +} +c010475c: 90 nop +c010475d: 89 ec mov %ebp,%esp +c010475f: 5d pop %ebp +c0104760: c3 ret + +c0104761 : + +//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) { +c0104761: 55 push %ebp +c0104762: 89 e5 mov %esp,%ebp +c0104764: 83 ec 28 sub $0x28,%esp + //调用 get_pte 函数获取给定虚拟地址 la 对应的页表项指针 ptep。 + pte_t *ptep = get_pte(pgdir, la, 0); +c0104767: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) +c010476e: 00 +c010476f: 8b 45 0c mov 0xc(%ebp),%eax +c0104772: 89 44 24 04 mov %eax,0x4(%esp) +c0104776: 8b 45 08 mov 0x8(%ebp),%eax +c0104779: 89 04 24 mov %eax,(%esp) +c010477c: e8 e6 fd ff ff call c0104567 +c0104781: 89 45 f4 mov %eax,-0xc(%ebp) + //如果 ptep 不为 NULL,则调用 page_remove_pte 函数移除该页表项。 + if (ptep != NULL) { +c0104784: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c0104788: 74 19 je c01047a3 + page_remove_pte(pgdir, la, ptep); +c010478a: 8b 45 f4 mov -0xc(%ebp),%eax +c010478d: 89 44 24 08 mov %eax,0x8(%esp) +c0104791: 8b 45 0c mov 0xc(%ebp),%eax +c0104794: 89 44 24 04 mov %eax,0x4(%esp) +c0104798: 8b 45 08 mov 0x8(%ebp),%eax +c010479b: 89 04 24 mov %eax,(%esp) +c010479e: e8 5a ff ff ff call c01046fd + } +} +c01047a3: 90 nop +c01047a4: 89 ec mov %ebp,%esp +c01047a6: 5d pop %ebp +c01047a7: c3 ret + +c01047a8 : +// 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) { +c01047a8: 55 push %ebp +c01047a9: 89 e5 mov %esp,%ebp +c01047ab: 83 ec 28 sub $0x28,%esp + //通过 get_pte 函数获取指定虚拟地址 la 对应的页表项指针 ptep。 + pte_t *ptep = get_pte(pgdir, la, 1); +c01047ae: c7 44 24 08 01 00 00 movl $0x1,0x8(%esp) +c01047b5: 00 +c01047b6: 8b 45 10 mov 0x10(%ebp),%eax +c01047b9: 89 44 24 04 mov %eax,0x4(%esp) +c01047bd: 8b 45 08 mov 0x8(%ebp),%eax +c01047c0: 89 04 24 mov %eax,(%esp) +c01047c3: e8 9f fd ff ff call c0104567 +c01047c8: 89 45 f4 mov %eax,-0xc(%ebp) + //如果 ptep 为 NULL,表示内存分配失败,返回 -E_NO_MEM。 + if (ptep == NULL) { +c01047cb: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c01047cf: 75 0a jne c01047db + return -E_NO_MEM; +c01047d1: b8 fc ff ff ff mov $0xfffffffc,%eax +c01047d6: e9 84 00 00 00 jmp c010485f + } + //调用 page_ref_inc 增加页面的引用计数。 + page_ref_inc(page); +c01047db: 8b 45 0c mov 0xc(%ebp),%eax +c01047de: 89 04 24 mov %eax,(%esp) +c01047e1: e8 f7 f4 ff ff call c0103cdd + //如果页表项已存在且指向当前页面,则减少页面引用计数。 + if (*ptep & PTE_P) { +c01047e6: 8b 45 f4 mov -0xc(%ebp),%eax +c01047e9: 8b 00 mov (%eax),%eax +c01047eb: 83 e0 01 and $0x1,%eax +c01047ee: 85 c0 test %eax,%eax +c01047f0: 74 3e je c0104830 + struct Page *p = pte2page(*ptep); +c01047f2: 8b 45 f4 mov -0xc(%ebp),%eax +c01047f5: 8b 00 mov (%eax),%eax +c01047f7: 89 04 24 mov %eax,(%esp) +c01047fa: e8 6c f4 ff ff call c0103c6b +c01047ff: 89 45 f0 mov %eax,-0x10(%ebp) + if (p == page) { +c0104802: 8b 45 f0 mov -0x10(%ebp),%eax +c0104805: 3b 45 0c cmp 0xc(%ebp),%eax +c0104808: 75 0d jne c0104817 + page_ref_dec(page); +c010480a: 8b 45 0c mov 0xc(%ebp),%eax +c010480d: 89 04 24 mov %eax,(%esp) +c0104810: e8 df f4 ff ff call c0103cf4 +c0104815: eb 19 jmp c0104830 + } + //如果页表项已存在但指向其他页面,则调用 page_remove_pte 移除旧的页表项。 + else { + page_remove_pte(pgdir, la, ptep); +c0104817: 8b 45 f4 mov -0xc(%ebp),%eax +c010481a: 89 44 24 08 mov %eax,0x8(%esp) +c010481e: 8b 45 10 mov 0x10(%ebp),%eax +c0104821: 89 44 24 04 mov %eax,0x4(%esp) +c0104825: 8b 45 08 mov 0x8(%ebp),%eax +c0104828: 89 04 24 mov %eax,(%esp) +c010482b: e8 cd fe ff ff call c01046fd + } + } + *ptep = page2pa(page) | PTE_P | perm; +c0104830: 8b 45 0c mov 0xc(%ebp),%eax +c0104833: 89 04 24 mov %eax,(%esp) +c0104836: e8 71 f3 ff ff call c0103bac +c010483b: 0b 45 14 or 0x14(%ebp),%eax +c010483e: 83 c8 01 or $0x1,%eax +c0104841: 89 c2 mov %eax,%edx +c0104843: 8b 45 f4 mov -0xc(%ebp),%eax +c0104846: 89 10 mov %edx,(%eax) + tlb_invalidate(pgdir, la);//刷新 TLB +c0104848: 8b 45 10 mov 0x10(%ebp),%eax +c010484b: 89 44 24 04 mov %eax,0x4(%esp) +c010484f: 8b 45 08 mov 0x8(%ebp),%eax +c0104852: 89 04 24 mov %eax,(%esp) +c0104855: e8 09 00 00 00 call c0104863 + return 0; +c010485a: b8 00 00 00 00 mov $0x0,%eax +} +c010485f: 89 ec mov %ebp,%esp +c0104861: 5d pop %ebp +c0104862: c3 ret + +c0104863 : + +// 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) { +c0104863: 55 push %ebp +c0104864: 89 e5 mov %esp,%ebp +c0104866: 83 ec 28 sub $0x28,%esp +} + +static inline uintptr_t +rcr3(void) { + uintptr_t cr3; + asm volatile ("mov %%cr3, %0" : "=r" (cr3) :: "memory"); +c0104869: 0f 20 d8 mov %cr3,%eax +c010486c: 89 45 f0 mov %eax,-0x10(%ebp) + return cr3; +c010486f: 8b 55 f0 mov -0x10(%ebp),%edx + //检查当前页目录地址是否与传入的页目录地址相同。 + if (rcr3() == PADDR(pgdir)) { +c0104872: 8b 45 08 mov 0x8(%ebp),%eax +c0104875: 89 45 f4 mov %eax,-0xc(%ebp) +c0104878: 81 7d f4 ff ff ff bf cmpl $0xbfffffff,-0xc(%ebp) +c010487f: 77 23 ja c01048a4 +c0104881: 8b 45 f4 mov -0xc(%ebp),%eax +c0104884: 89 44 24 0c mov %eax,0xc(%esp) +c0104888: c7 44 24 08 28 6c 10 movl $0xc0106c28,0x8(%esp) +c010488f: c0 +c0104890: c7 44 24 04 47 02 00 movl $0x247,0x4(%esp) +c0104897: 00 +c0104898: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c010489f: e8 8f c3 ff ff call c0100c33 <__panic> +c01048a4: 8b 45 f4 mov -0xc(%ebp),%eax +c01048a7: 05 00 00 00 40 add $0x40000000,%eax +c01048ac: 39 d0 cmp %edx,%eax +c01048ae: 75 0d jne c01048bd + //如果相同,则调用 invlpg 函数无效化指定线性地址的TLB条目。 + invlpg((void *)la); +c01048b0: 8b 45 0c mov 0xc(%ebp),%eax +c01048b3: 89 45 ec mov %eax,-0x14(%ebp) +} + +static inline void +invlpg(void *addr) { + asm volatile ("invlpg (%0)" :: "r" (addr) : "memory"); +c01048b6: 8b 45 ec mov -0x14(%ebp),%eax +c01048b9: 0f 01 38 invlpg (%eax) +} +c01048bc: 90 nop + } +} +c01048bd: 90 nop +c01048be: 89 ec mov %ebp,%esp +c01048c0: 5d pop %ebp +c01048c1: c3 ret + +c01048c2 : + +static void +check_alloc_page(void) { +c01048c2: 55 push %ebp +c01048c3: 89 e5 mov %esp,%ebp +c01048c5: 83 ec 18 sub $0x18,%esp + //调用内存管理器的 check 方法,用于检查内存分配是否正常。 + pmm_manager->check(); +c01048c8: a1 0c cf 11 c0 mov 0xc011cf0c,%eax +c01048cd: 8b 40 18 mov 0x18(%eax),%eax +c01048d0: ff d0 call *%eax + cprintf("check_alloc_page() succeeded!\n"); +c01048d2: c7 04 24 ac 6c 10 c0 movl $0xc0106cac,(%esp) +c01048d9: e8 88 ba ff ff call c0100366 +} +c01048de: 90 nop +c01048df: 89 ec mov %ebp,%esp +c01048e1: 5d pop %ebp +c01048e2: c3 ret + +c01048e3 : +//用于验证页目录和页表的正确性。 +static void +check_pgdir(void) { +c01048e3: 55 push %ebp +c01048e4: 89 e5 mov %esp,%ebp +c01048e6: 83 ec 38 sub $0x38,%esp + //确保内存页面数量在合理范围内 + assert(npage <= KMEMSIZE / PGSIZE); +c01048e9: a1 04 cf 11 c0 mov 0xc011cf04,%eax +c01048ee: 3d 00 80 03 00 cmp $0x38000,%eax +c01048f3: 76 24 jbe c0104919 +c01048f5: c7 44 24 0c cb 6c 10 movl $0xc0106ccb,0xc(%esp) +c01048fc: c0 +c01048fd: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c0104904: c0 +c0104905: c7 44 24 04 57 02 00 movl $0x257,0x4(%esp) +c010490c: 00 +c010490d: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c0104914: e8 1a c3 ff ff call c0100c33 <__panic> + //确保页目录不为空且对齐, + assert(boot_pgdir != NULL && (uint32_t)PGOFF(boot_pgdir) == 0); +c0104919: a1 e0 99 11 c0 mov 0xc01199e0,%eax +c010491e: 85 c0 test %eax,%eax +c0104920: 74 0e je c0104930 +c0104922: a1 e0 99 11 c0 mov 0xc01199e0,%eax +c0104927: 25 ff 0f 00 00 and $0xfff,%eax +c010492c: 85 c0 test %eax,%eax +c010492e: 74 24 je c0104954 +c0104930: c7 44 24 0c e8 6c 10 movl $0xc0106ce8,0xc(%esp) +c0104937: c0 +c0104938: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c010493f: c0 +c0104940: c7 44 24 04 59 02 00 movl $0x259,0x4(%esp) +c0104947: 00 +c0104948: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c010494f: e8 df c2 ff ff call c0100c33 <__panic> + //确保虚拟地址 0x0 没有映射任何页面 + assert(get_page(boot_pgdir, 0x0, NULL) == NULL); +c0104954: a1 e0 99 11 c0 mov 0xc01199e0,%eax +c0104959: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) +c0104960: 00 +c0104961: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) +c0104968: 00 +c0104969: 89 04 24 mov %eax,(%esp) +c010496c: e8 31 fd ff ff call c01046a2 +c0104971: 85 c0 test %eax,%eax +c0104973: 74 24 je c0104999 +c0104975: c7 44 24 0c 20 6d 10 movl $0xc0106d20,0xc(%esp) +c010497c: c0 +c010497d: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c0104984: c0 +c0104985: c7 44 24 04 5b 02 00 movl $0x25b,0x4(%esp) +c010498c: 00 +c010498d: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c0104994: e8 9a c2 ff ff call c0100c33 <__panic> + + //定义两个页面指针 p1 和 p2 + struct Page *p1, *p2; + //分配一个页面 p1 + p1 = alloc_page(); +c0104999: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c01049a0: e8 30 f5 ff ff call c0103ed5 +c01049a5: 89 45 f4 mov %eax,-0xc(%ebp) + //将 p1 插入到虚拟地址 0x0 + assert(page_insert(boot_pgdir, p1, 0x0, 0) == 0); +c01049a8: a1 e0 99 11 c0 mov 0xc01199e0,%eax +c01049ad: c7 44 24 0c 00 00 00 movl $0x0,0xc(%esp) +c01049b4: 00 +c01049b5: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) +c01049bc: 00 +c01049bd: 8b 55 f4 mov -0xc(%ebp),%edx +c01049c0: 89 54 24 04 mov %edx,0x4(%esp) +c01049c4: 89 04 24 mov %eax,(%esp) +c01049c7: e8 dc fd ff ff call c01047a8 +c01049cc: 85 c0 test %eax,%eax +c01049ce: 74 24 je c01049f4 +c01049d0: c7 44 24 0c 48 6d 10 movl $0xc0106d48,0xc(%esp) +c01049d7: c0 +c01049d8: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c01049df: c0 +c01049e0: c7 44 24 04 62 02 00 movl $0x262,0x4(%esp) +c01049e7: 00 +c01049e8: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c01049ef: e8 3f c2 ff ff call c0100c33 <__panic> + + // 获取虚拟地址 0x0 对应的页表项指针 + pte_t *ptep; + assert((ptep = get_pte(boot_pgdir, 0x0, 0)) != NULL); +c01049f4: a1 e0 99 11 c0 mov 0xc01199e0,%eax +c01049f9: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) +c0104a00: 00 +c0104a01: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) +c0104a08: 00 +c0104a09: 89 04 24 mov %eax,(%esp) +c0104a0c: e8 56 fb ff ff call c0104567 +c0104a11: 89 45 f0 mov %eax,-0x10(%ebp) +c0104a14: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) +c0104a18: 75 24 jne c0104a3e +c0104a1a: c7 44 24 0c 74 6d 10 movl $0xc0106d74,0xc(%esp) +c0104a21: c0 +c0104a22: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c0104a29: c0 +c0104a2a: c7 44 24 04 66 02 00 movl $0x266,0x4(%esp) +c0104a31: 00 +c0104a32: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c0104a39: e8 f5 c1 ff ff call c0100c33 <__panic> + // 验证页表项对应的页面是 p1 + assert(pte2page(*ptep) == p1); +c0104a3e: 8b 45 f0 mov -0x10(%ebp),%eax +c0104a41: 8b 00 mov (%eax),%eax +c0104a43: 89 04 24 mov %eax,(%esp) +c0104a46: e8 20 f2 ff ff call c0103c6b +c0104a4b: 39 45 f4 cmp %eax,-0xc(%ebp) +c0104a4e: 74 24 je c0104a74 +c0104a50: c7 44 24 0c a1 6d 10 movl $0xc0106da1,0xc(%esp) +c0104a57: c0 +c0104a58: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c0104a5f: c0 +c0104a60: c7 44 24 04 68 02 00 movl $0x268,0x4(%esp) +c0104a67: 00 +c0104a68: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c0104a6f: e8 bf c1 ff ff call c0100c33 <__panic> + // 验证 p1 的引用计数为 1 + assert(page_ref(p1) == 1); +c0104a74: 8b 45 f4 mov -0xc(%ebp),%eax +c0104a77: 89 04 24 mov %eax,(%esp) +c0104a7a: e8 46 f2 ff ff call c0103cc5 +c0104a7f: 83 f8 01 cmp $0x1,%eax +c0104a82: 74 24 je c0104aa8 +c0104a84: c7 44 24 0c b7 6d 10 movl $0xc0106db7,0xc(%esp) +c0104a8b: c0 +c0104a8c: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c0104a93: c0 +c0104a94: c7 44 24 04 6a 02 00 movl $0x26a,0x4(%esp) +c0104a9b: 00 +c0104a9c: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c0104aa3: e8 8b c1 ff ff call c0100c33 <__panic> + // 获取虚拟地址 PGSIZE 对应的页表项指针 + ptep = &((pte_t *)KADDR(PDE_ADDR(boot_pgdir[0])))[1]; +c0104aa8: a1 e0 99 11 c0 mov 0xc01199e0,%eax +c0104aad: 8b 00 mov (%eax),%eax +c0104aaf: 25 00 f0 ff ff and $0xfffff000,%eax +c0104ab4: 89 45 ec mov %eax,-0x14(%ebp) +c0104ab7: 8b 45 ec mov -0x14(%ebp),%eax +c0104aba: c1 e8 0c shr $0xc,%eax +c0104abd: 89 45 e8 mov %eax,-0x18(%ebp) +c0104ac0: a1 04 cf 11 c0 mov 0xc011cf04,%eax +c0104ac5: 39 45 e8 cmp %eax,-0x18(%ebp) +c0104ac8: 72 23 jb c0104aed +c0104aca: 8b 45 ec mov -0x14(%ebp),%eax +c0104acd: 89 44 24 0c mov %eax,0xc(%esp) +c0104ad1: c7 44 24 08 84 6b 10 movl $0xc0106b84,0x8(%esp) +c0104ad8: c0 +c0104ad9: c7 44 24 04 6c 02 00 movl $0x26c,0x4(%esp) +c0104ae0: 00 +c0104ae1: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c0104ae8: e8 46 c1 ff ff call c0100c33 <__panic> +c0104aed: 8b 45 ec mov -0x14(%ebp),%eax +c0104af0: 2d 00 00 00 40 sub $0x40000000,%eax +c0104af5: 83 c0 04 add $0x4,%eax +c0104af8: 89 45 f0 mov %eax,-0x10(%ebp) + assert(get_pte(boot_pgdir, PGSIZE, 0) == ptep); +c0104afb: a1 e0 99 11 c0 mov 0xc01199e0,%eax +c0104b00: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) +c0104b07: 00 +c0104b08: c7 44 24 04 00 10 00 movl $0x1000,0x4(%esp) +c0104b0f: 00 +c0104b10: 89 04 24 mov %eax,(%esp) +c0104b13: e8 4f fa ff ff call c0104567 +c0104b18: 39 45 f0 cmp %eax,-0x10(%ebp) +c0104b1b: 74 24 je c0104b41 +c0104b1d: c7 44 24 0c cc 6d 10 movl $0xc0106dcc,0xc(%esp) +c0104b24: c0 +c0104b25: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c0104b2c: c0 +c0104b2d: c7 44 24 04 6d 02 00 movl $0x26d,0x4(%esp) +c0104b34: 00 +c0104b35: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c0104b3c: e8 f2 c0 ff ff call c0100c33 <__panic> + // 分配一个页面 p2 + p2 = alloc_page(); +c0104b41: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c0104b48: e8 88 f3 ff ff call c0103ed5 +c0104b4d: 89 45 e4 mov %eax,-0x1c(%ebp) + // 将 p2 插入到虚拟地址 PGSIZE,并设置用户和写权限 + assert(page_insert(boot_pgdir, p2, PGSIZE, PTE_U | PTE_W) == 0); +c0104b50: a1 e0 99 11 c0 mov 0xc01199e0,%eax +c0104b55: c7 44 24 0c 06 00 00 movl $0x6,0xc(%esp) +c0104b5c: 00 +c0104b5d: c7 44 24 08 00 10 00 movl $0x1000,0x8(%esp) +c0104b64: 00 +c0104b65: 8b 55 e4 mov -0x1c(%ebp),%edx +c0104b68: 89 54 24 04 mov %edx,0x4(%esp) +c0104b6c: 89 04 24 mov %eax,(%esp) +c0104b6f: e8 34 fc ff ff call c01047a8 +c0104b74: 85 c0 test %eax,%eax +c0104b76: 74 24 je c0104b9c +c0104b78: c7 44 24 0c f4 6d 10 movl $0xc0106df4,0xc(%esp) +c0104b7f: c0 +c0104b80: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c0104b87: c0 +c0104b88: c7 44 24 04 71 02 00 movl $0x271,0x4(%esp) +c0104b8f: 00 +c0104b90: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c0104b97: e8 97 c0 ff ff call c0100c33 <__panic> + // 获取虚拟地址 PGSIZE 对应的页表项指针 + assert((ptep = get_pte(boot_pgdir, PGSIZE, 0)) != NULL); +c0104b9c: a1 e0 99 11 c0 mov 0xc01199e0,%eax +c0104ba1: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) +c0104ba8: 00 +c0104ba9: c7 44 24 04 00 10 00 movl $0x1000,0x4(%esp) +c0104bb0: 00 +c0104bb1: 89 04 24 mov %eax,(%esp) +c0104bb4: e8 ae f9 ff ff call c0104567 +c0104bb9: 89 45 f0 mov %eax,-0x10(%ebp) +c0104bbc: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) +c0104bc0: 75 24 jne c0104be6 +c0104bc2: c7 44 24 0c 2c 6e 10 movl $0xc0106e2c,0xc(%esp) +c0104bc9: c0 +c0104bca: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c0104bd1: c0 +c0104bd2: c7 44 24 04 73 02 00 movl $0x273,0x4(%esp) +c0104bd9: 00 +c0104bda: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c0104be1: e8 4d c0 ff ff call c0100c33 <__panic> + // 验证页表项设置了用户权限 + assert(*ptep & PTE_U); +c0104be6: 8b 45 f0 mov -0x10(%ebp),%eax +c0104be9: 8b 00 mov (%eax),%eax +c0104beb: 83 e0 04 and $0x4,%eax +c0104bee: 85 c0 test %eax,%eax +c0104bf0: 75 24 jne c0104c16 +c0104bf2: c7 44 24 0c 5c 6e 10 movl $0xc0106e5c,0xc(%esp) +c0104bf9: c0 +c0104bfa: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c0104c01: c0 +c0104c02: c7 44 24 04 75 02 00 movl $0x275,0x4(%esp) +c0104c09: 00 +c0104c0a: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c0104c11: e8 1d c0 ff ff call c0100c33 <__panic> + // 验证页表项设置了写权限 + assert(*ptep & PTE_W); +c0104c16: 8b 45 f0 mov -0x10(%ebp),%eax +c0104c19: 8b 00 mov (%eax),%eax +c0104c1b: 83 e0 02 and $0x2,%eax +c0104c1e: 85 c0 test %eax,%eax +c0104c20: 75 24 jne c0104c46 +c0104c22: c7 44 24 0c 6a 6e 10 movl $0xc0106e6a,0xc(%esp) +c0104c29: c0 +c0104c2a: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c0104c31: c0 +c0104c32: c7 44 24 04 77 02 00 movl $0x277,0x4(%esp) +c0104c39: 00 +c0104c3a: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c0104c41: e8 ed bf ff ff call c0100c33 <__panic> + // 验证页目录项设置了用户权限 + assert(boot_pgdir[0] & PTE_U); +c0104c46: a1 e0 99 11 c0 mov 0xc01199e0,%eax +c0104c4b: 8b 00 mov (%eax),%eax +c0104c4d: 83 e0 04 and $0x4,%eax +c0104c50: 85 c0 test %eax,%eax +c0104c52: 75 24 jne c0104c78 +c0104c54: c7 44 24 0c 78 6e 10 movl $0xc0106e78,0xc(%esp) +c0104c5b: c0 +c0104c5c: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c0104c63: c0 +c0104c64: c7 44 24 04 79 02 00 movl $0x279,0x4(%esp) +c0104c6b: 00 +c0104c6c: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c0104c73: e8 bb bf ff ff call c0100c33 <__panic> + // 验证 p2 的引用计数为 1 + assert(page_ref(p2) == 1); +c0104c78: 8b 45 e4 mov -0x1c(%ebp),%eax +c0104c7b: 89 04 24 mov %eax,(%esp) +c0104c7e: e8 42 f0 ff ff call c0103cc5 +c0104c83: 83 f8 01 cmp $0x1,%eax +c0104c86: 74 24 je c0104cac +c0104c88: c7 44 24 0c 8e 6e 10 movl $0xc0106e8e,0xc(%esp) +c0104c8f: c0 +c0104c90: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c0104c97: c0 +c0104c98: c7 44 24 04 7b 02 00 movl $0x27b,0x4(%esp) +c0104c9f: 00 +c0104ca0: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c0104ca7: e8 87 bf ff ff call c0100c33 <__panic> + + // 将 p1 插入到虚拟地址 PGSIZE,替换掉 p2 + assert(page_insert(boot_pgdir, p1, PGSIZE, 0) == 0); +c0104cac: a1 e0 99 11 c0 mov 0xc01199e0,%eax +c0104cb1: c7 44 24 0c 00 00 00 movl $0x0,0xc(%esp) +c0104cb8: 00 +c0104cb9: c7 44 24 08 00 10 00 movl $0x1000,0x8(%esp) +c0104cc0: 00 +c0104cc1: 8b 55 f4 mov -0xc(%ebp),%edx +c0104cc4: 89 54 24 04 mov %edx,0x4(%esp) +c0104cc8: 89 04 24 mov %eax,(%esp) +c0104ccb: e8 d8 fa ff ff call c01047a8 +c0104cd0: 85 c0 test %eax,%eax +c0104cd2: 74 24 je c0104cf8 +c0104cd4: c7 44 24 0c a0 6e 10 movl $0xc0106ea0,0xc(%esp) +c0104cdb: c0 +c0104cdc: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c0104ce3: c0 +c0104ce4: c7 44 24 04 7e 02 00 movl $0x27e,0x4(%esp) +c0104ceb: 00 +c0104cec: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c0104cf3: e8 3b bf ff ff call c0100c33 <__panic> + // 验证 p1 的引用计数增加到 2 + assert(page_ref(p1) == 2); +c0104cf8: 8b 45 f4 mov -0xc(%ebp),%eax +c0104cfb: 89 04 24 mov %eax,(%esp) +c0104cfe: e8 c2 ef ff ff call c0103cc5 +c0104d03: 83 f8 02 cmp $0x2,%eax +c0104d06: 74 24 je c0104d2c +c0104d08: c7 44 24 0c cc 6e 10 movl $0xc0106ecc,0xc(%esp) +c0104d0f: c0 +c0104d10: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c0104d17: c0 +c0104d18: c7 44 24 04 80 02 00 movl $0x280,0x4(%esp) +c0104d1f: 00 +c0104d20: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c0104d27: e8 07 bf ff ff call c0100c33 <__panic> + // 验证 p2 的引用计数减少到 0 + assert(page_ref(p2) == 0); +c0104d2c: 8b 45 e4 mov -0x1c(%ebp),%eax +c0104d2f: 89 04 24 mov %eax,(%esp) +c0104d32: e8 8e ef ff ff call c0103cc5 +c0104d37: 85 c0 test %eax,%eax +c0104d39: 74 24 je c0104d5f +c0104d3b: c7 44 24 0c de 6e 10 movl $0xc0106ede,0xc(%esp) +c0104d42: c0 +c0104d43: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c0104d4a: c0 +c0104d4b: c7 44 24 04 82 02 00 movl $0x282,0x4(%esp) +c0104d52: 00 +c0104d53: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c0104d5a: e8 d4 be ff ff call c0100c33 <__panic> + // 获取虚拟地址 PGSIZE 对应的页表项指针 + assert((ptep = get_pte(boot_pgdir, PGSIZE, 0)) != NULL); +c0104d5f: a1 e0 99 11 c0 mov 0xc01199e0,%eax +c0104d64: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) +c0104d6b: 00 +c0104d6c: c7 44 24 04 00 10 00 movl $0x1000,0x4(%esp) +c0104d73: 00 +c0104d74: 89 04 24 mov %eax,(%esp) +c0104d77: e8 eb f7 ff ff call c0104567 +c0104d7c: 89 45 f0 mov %eax,-0x10(%ebp) +c0104d7f: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) +c0104d83: 75 24 jne c0104da9 +c0104d85: c7 44 24 0c 2c 6e 10 movl $0xc0106e2c,0xc(%esp) +c0104d8c: c0 +c0104d8d: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c0104d94: c0 +c0104d95: c7 44 24 04 84 02 00 movl $0x284,0x4(%esp) +c0104d9c: 00 +c0104d9d: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c0104da4: e8 8a be ff ff call c0100c33 <__panic> + // 验证页表项对应的页面是 p1 + assert(pte2page(*ptep) == p1); +c0104da9: 8b 45 f0 mov -0x10(%ebp),%eax +c0104dac: 8b 00 mov (%eax),%eax +c0104dae: 89 04 24 mov %eax,(%esp) +c0104db1: e8 b5 ee ff ff call c0103c6b +c0104db6: 39 45 f4 cmp %eax,-0xc(%ebp) +c0104db9: 74 24 je c0104ddf +c0104dbb: c7 44 24 0c a1 6d 10 movl $0xc0106da1,0xc(%esp) +c0104dc2: c0 +c0104dc3: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c0104dca: c0 +c0104dcb: c7 44 24 04 86 02 00 movl $0x286,0x4(%esp) +c0104dd2: 00 +c0104dd3: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c0104dda: e8 54 be ff ff call c0100c33 <__panic> + // 验证页表项没有设置用户权限 + assert((*ptep & PTE_U) == 0); +c0104ddf: 8b 45 f0 mov -0x10(%ebp),%eax +c0104de2: 8b 00 mov (%eax),%eax +c0104de4: 83 e0 04 and $0x4,%eax +c0104de7: 85 c0 test %eax,%eax +c0104de9: 74 24 je c0104e0f +c0104deb: c7 44 24 0c f0 6e 10 movl $0xc0106ef0,0xc(%esp) +c0104df2: c0 +c0104df3: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c0104dfa: c0 +c0104dfb: c7 44 24 04 88 02 00 movl $0x288,0x4(%esp) +c0104e02: 00 +c0104e03: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c0104e0a: e8 24 be ff ff call c0100c33 <__panic> + + //移除虚拟地址 0x0 的映射, + page_remove(boot_pgdir, 0x0); +c0104e0f: a1 e0 99 11 c0 mov 0xc01199e0,%eax +c0104e14: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) +c0104e1b: 00 +c0104e1c: 89 04 24 mov %eax,(%esp) +c0104e1f: e8 3d f9 ff ff call c0104761 + //验证 p1 的引用计数减少到 1。 + assert(page_ref(p1) == 1); +c0104e24: 8b 45 f4 mov -0xc(%ebp),%eax +c0104e27: 89 04 24 mov %eax,(%esp) +c0104e2a: e8 96 ee ff ff call c0103cc5 +c0104e2f: 83 f8 01 cmp $0x1,%eax +c0104e32: 74 24 je c0104e58 +c0104e34: c7 44 24 0c b7 6d 10 movl $0xc0106db7,0xc(%esp) +c0104e3b: c0 +c0104e3c: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c0104e43: c0 +c0104e44: c7 44 24 04 8d 02 00 movl $0x28d,0x4(%esp) +c0104e4b: 00 +c0104e4c: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c0104e53: e8 db bd ff ff call c0100c33 <__panic> + //验证 p2 的引用计数减少到 0 + assert(page_ref(p2) == 0); +c0104e58: 8b 45 e4 mov -0x1c(%ebp),%eax +c0104e5b: 89 04 24 mov %eax,(%esp) +c0104e5e: e8 62 ee ff ff call c0103cc5 +c0104e63: 85 c0 test %eax,%eax +c0104e65: 74 24 je c0104e8b +c0104e67: c7 44 24 0c de 6e 10 movl $0xc0106ede,0xc(%esp) +c0104e6e: c0 +c0104e6f: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c0104e76: c0 +c0104e77: c7 44 24 04 8f 02 00 movl $0x28f,0x4(%esp) +c0104e7e: 00 +c0104e7f: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c0104e86: e8 a8 bd ff ff call c0100c33 <__panic> + + //移除虚拟地址 PGSIZE 的映射, + page_remove(boot_pgdir, PGSIZE); +c0104e8b: a1 e0 99 11 c0 mov 0xc01199e0,%eax +c0104e90: c7 44 24 04 00 10 00 movl $0x1000,0x4(%esp) +c0104e97: 00 +c0104e98: 89 04 24 mov %eax,(%esp) +c0104e9b: e8 c1 f8 ff ff call c0104761 + //验证 p1 的引用计数减少到 0 + assert(page_ref(p1) == 0); +c0104ea0: 8b 45 f4 mov -0xc(%ebp),%eax +c0104ea3: 89 04 24 mov %eax,(%esp) +c0104ea6: e8 1a ee ff ff call c0103cc5 +c0104eab: 85 c0 test %eax,%eax +c0104ead: 74 24 je c0104ed3 +c0104eaf: c7 44 24 0c 05 6f 10 movl $0xc0106f05,0xc(%esp) +c0104eb6: c0 +c0104eb7: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c0104ebe: c0 +c0104ebf: c7 44 24 04 94 02 00 movl $0x294,0x4(%esp) +c0104ec6: 00 +c0104ec7: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c0104ece: e8 60 bd ff ff call c0100c33 <__panic> + //验证 p2 的引用计数减少到 0 + assert(page_ref(p2) == 0); +c0104ed3: 8b 45 e4 mov -0x1c(%ebp),%eax +c0104ed6: 89 04 24 mov %eax,(%esp) +c0104ed9: e8 e7 ed ff ff call c0103cc5 +c0104ede: 85 c0 test %eax,%eax +c0104ee0: 74 24 je c0104f06 +c0104ee2: c7 44 24 0c de 6e 10 movl $0xc0106ede,0xc(%esp) +c0104ee9: c0 +c0104eea: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c0104ef1: c0 +c0104ef2: c7 44 24 04 96 02 00 movl $0x296,0x4(%esp) +c0104ef9: 00 +c0104efa: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c0104f01: e8 2d bd ff ff call c0100c33 <__panic> + + //验证页目录的第一页表的引用计数为 1。 + assert(page_ref(pde2page(boot_pgdir[0])) == 1); +c0104f06: a1 e0 99 11 c0 mov 0xc01199e0,%eax +c0104f0b: 8b 00 mov (%eax),%eax +c0104f0d: 89 04 24 mov %eax,(%esp) +c0104f10: e8 96 ed ff ff call c0103cab +c0104f15: 89 04 24 mov %eax,(%esp) +c0104f18: e8 a8 ed ff ff call c0103cc5 +c0104f1d: 83 f8 01 cmp $0x1,%eax +c0104f20: 74 24 je c0104f46 +c0104f22: c7 44 24 0c 18 6f 10 movl $0xc0106f18,0xc(%esp) +c0104f29: c0 +c0104f2a: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c0104f31: c0 +c0104f32: c7 44 24 04 99 02 00 movl $0x299,0x4(%esp) +c0104f39: 00 +c0104f3a: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c0104f41: e8 ed bc ff ff call c0100c33 <__panic> + //释放页目录的第一页表 + free_page(pde2page(boot_pgdir[0])); +c0104f46: a1 e0 99 11 c0 mov 0xc01199e0,%eax +c0104f4b: 8b 00 mov (%eax),%eax +c0104f4d: 89 04 24 mov %eax,(%esp) +c0104f50: e8 56 ed ff ff call c0103cab +c0104f55: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c0104f5c: 00 +c0104f5d: 89 04 24 mov %eax,(%esp) +c0104f60: e8 aa ef ff ff call c0103f0f + //清空页目录的第一页表 + boot_pgdir[0] = 0; +c0104f65: a1 e0 99 11 c0 mov 0xc01199e0,%eax +c0104f6a: c7 00 00 00 00 00 movl $0x0,(%eax) + + cprintf("check_pgdir() succeeded!\n"); +c0104f70: c7 04 24 3f 6f 10 c0 movl $0xc0106f3f,(%esp) +c0104f77: e8 ea b3 ff ff call c0100366 +} +c0104f7c: 90 nop +c0104f7d: 89 ec mov %ebp,%esp +c0104f7f: 5d pop %ebp +c0104f80: c3 ret + +c0104f81 : + +//检查内核页表 boot_pgdir 的正确性 +static void +check_boot_pgdir(void) { +c0104f81: 55 push %ebp +c0104f82: 89 e5 mov %esp,%ebp +c0104f84: 83 ec 38 sub $0x38,%esp + pte_t *ptep;// 定义一个指向页表项的指针 + int i; + for (i = 0; i < npage; i += PGSIZE) {// 遍历所有页面 +c0104f87: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) +c0104f8e: e9 ca 00 00 00 jmp c010505d + // 获取第 i 个页面的页表项,并确保其不为空 + assert((ptep = get_pte(boot_pgdir, (uintptr_t)KADDR(i), 0)) != NULL); +c0104f93: 8b 45 f4 mov -0xc(%ebp),%eax +c0104f96: 89 45 e4 mov %eax,-0x1c(%ebp) +c0104f99: 8b 45 e4 mov -0x1c(%ebp),%eax +c0104f9c: c1 e8 0c shr $0xc,%eax +c0104f9f: 89 45 e0 mov %eax,-0x20(%ebp) +c0104fa2: a1 04 cf 11 c0 mov 0xc011cf04,%eax +c0104fa7: 39 45 e0 cmp %eax,-0x20(%ebp) +c0104faa: 72 23 jb c0104fcf +c0104fac: 8b 45 e4 mov -0x1c(%ebp),%eax +c0104faf: 89 44 24 0c mov %eax,0xc(%esp) +c0104fb3: c7 44 24 08 84 6b 10 movl $0xc0106b84,0x8(%esp) +c0104fba: c0 +c0104fbb: c7 44 24 04 a9 02 00 movl $0x2a9,0x4(%esp) +c0104fc2: 00 +c0104fc3: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c0104fca: e8 64 bc ff ff call c0100c33 <__panic> +c0104fcf: 8b 45 e4 mov -0x1c(%ebp),%eax +c0104fd2: 2d 00 00 00 40 sub $0x40000000,%eax +c0104fd7: 89 c2 mov %eax,%edx +c0104fd9: a1 e0 99 11 c0 mov 0xc01199e0,%eax +c0104fde: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) +c0104fe5: 00 +c0104fe6: 89 54 24 04 mov %edx,0x4(%esp) +c0104fea: 89 04 24 mov %eax,(%esp) +c0104fed: e8 75 f5 ff ff call c0104567 +c0104ff2: 89 45 dc mov %eax,-0x24(%ebp) +c0104ff5: 83 7d dc 00 cmpl $0x0,-0x24(%ebp) +c0104ff9: 75 24 jne c010501f +c0104ffb: c7 44 24 0c 5c 6f 10 movl $0xc0106f5c,0xc(%esp) +c0105002: c0 +c0105003: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c010500a: c0 +c010500b: c7 44 24 04 a9 02 00 movl $0x2a9,0x4(%esp) +c0105012: 00 +c0105013: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c010501a: e8 14 bc ff ff call c0100c33 <__panic> + // 验证页表项的物理地址是否正确 + assert(PTE_ADDR(*ptep) == i); +c010501f: 8b 45 dc mov -0x24(%ebp),%eax +c0105022: 8b 00 mov (%eax),%eax +c0105024: 25 00 f0 ff ff and $0xfffff000,%eax +c0105029: 89 c2 mov %eax,%edx +c010502b: 8b 45 f4 mov -0xc(%ebp),%eax +c010502e: 39 c2 cmp %eax,%edx +c0105030: 74 24 je c0105056 +c0105032: c7 44 24 0c 99 6f 10 movl $0xc0106f99,0xc(%esp) +c0105039: c0 +c010503a: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c0105041: c0 +c0105042: c7 44 24 04 ab 02 00 movl $0x2ab,0x4(%esp) +c0105049: 00 +c010504a: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c0105051: e8 dd bb ff ff call c0100c33 <__panic> + for (i = 0; i < npage; i += PGSIZE) {// 遍历所有页面 +c0105056: 81 45 f4 00 10 00 00 addl $0x1000,-0xc(%ebp) +c010505d: 8b 55 f4 mov -0xc(%ebp),%edx +c0105060: a1 04 cf 11 c0 mov 0xc011cf04,%eax +c0105065: 39 c2 cmp %eax,%edx +c0105067: 0f 82 26 ff ff ff jb c0104f93 + } + // 验证页目录项的物理地址是否正确 + assert(PDE_ADDR(boot_pgdir[PDX(VPT)]) == PADDR(boot_pgdir)); +c010506d: a1 e0 99 11 c0 mov 0xc01199e0,%eax +c0105072: 05 ac 0f 00 00 add $0xfac,%eax +c0105077: 8b 00 mov (%eax),%eax +c0105079: 25 00 f0 ff ff and $0xfffff000,%eax +c010507e: 89 c2 mov %eax,%edx +c0105080: a1 e0 99 11 c0 mov 0xc01199e0,%eax +c0105085: 89 45 f0 mov %eax,-0x10(%ebp) +c0105088: 81 7d f0 ff ff ff bf cmpl $0xbfffffff,-0x10(%ebp) +c010508f: 77 23 ja c01050b4 +c0105091: 8b 45 f0 mov -0x10(%ebp),%eax +c0105094: 89 44 24 0c mov %eax,0xc(%esp) +c0105098: c7 44 24 08 28 6c 10 movl $0xc0106c28,0x8(%esp) +c010509f: c0 +c01050a0: c7 44 24 04 ae 02 00 movl $0x2ae,0x4(%esp) +c01050a7: 00 +c01050a8: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c01050af: e8 7f bb ff ff call c0100c33 <__panic> +c01050b4: 8b 45 f0 mov -0x10(%ebp),%eax +c01050b7: 05 00 00 00 40 add $0x40000000,%eax +c01050bc: 39 d0 cmp %edx,%eax +c01050be: 74 24 je c01050e4 +c01050c0: c7 44 24 0c b0 6f 10 movl $0xc0106fb0,0xc(%esp) +c01050c7: c0 +c01050c8: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c01050cf: c0 +c01050d0: c7 44 24 04 ae 02 00 movl $0x2ae,0x4(%esp) +c01050d7: 00 +c01050d8: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c01050df: e8 4f bb ff ff call c0100c33 <__panic> + + assert(boot_pgdir[0] == 0);// 确保页目录的第一个项为0 +c01050e4: a1 e0 99 11 c0 mov 0xc01199e0,%eax +c01050e9: 8b 00 mov (%eax),%eax +c01050eb: 85 c0 test %eax,%eax +c01050ed: 74 24 je c0105113 +c01050ef: c7 44 24 0c e4 6f 10 movl $0xc0106fe4,0xc(%esp) +c01050f6: c0 +c01050f7: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c01050fe: c0 +c01050ff: c7 44 24 04 b0 02 00 movl $0x2b0,0x4(%esp) +c0105106: 00 +c0105107: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c010510e: e8 20 bb ff ff call c0100c33 <__panic> + + struct Page *p;// 定义一个指向页面的指针 + p = alloc_page();// 分配一个页面 +c0105113: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c010511a: e8 b6 ed ff ff call c0103ed5 +c010511f: 89 45 ec mov %eax,-0x14(%ebp) + // 将页面插入到虚拟地址 0x100,并确保操作成功 + assert(page_insert(boot_pgdir, p, 0x100, PTE_W) == 0); +c0105122: a1 e0 99 11 c0 mov 0xc01199e0,%eax +c0105127: c7 44 24 0c 02 00 00 movl $0x2,0xc(%esp) +c010512e: 00 +c010512f: c7 44 24 08 00 01 00 movl $0x100,0x8(%esp) +c0105136: 00 +c0105137: 8b 55 ec mov -0x14(%ebp),%edx +c010513a: 89 54 24 04 mov %edx,0x4(%esp) +c010513e: 89 04 24 mov %eax,(%esp) +c0105141: e8 62 f6 ff ff call c01047a8 +c0105146: 85 c0 test %eax,%eax +c0105148: 74 24 je c010516e +c010514a: c7 44 24 0c f8 6f 10 movl $0xc0106ff8,0xc(%esp) +c0105151: c0 +c0105152: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c0105159: c0 +c010515a: c7 44 24 04 b5 02 00 movl $0x2b5,0x4(%esp) +c0105161: 00 +c0105162: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c0105169: e8 c5 ba ff ff call c0100c33 <__panic> + assert(page_ref(p) == 1);// 验证页面的引用计数为1 +c010516e: 8b 45 ec mov -0x14(%ebp),%eax +c0105171: 89 04 24 mov %eax,(%esp) +c0105174: e8 4c eb ff ff call c0103cc5 +c0105179: 83 f8 01 cmp $0x1,%eax +c010517c: 74 24 je c01051a2 +c010517e: c7 44 24 0c 26 70 10 movl $0xc0107026,0xc(%esp) +c0105185: c0 +c0105186: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c010518d: c0 +c010518e: c7 44 24 04 b6 02 00 movl $0x2b6,0x4(%esp) +c0105195: 00 +c0105196: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c010519d: e8 91 ba ff ff call c0100c33 <__panic> + // 将页面插入到虚拟地址 0x100 + PGSIZE,并确保操作成功 + assert(page_insert(boot_pgdir, p, 0x100 + PGSIZE, PTE_W) == 0); +c01051a2: a1 e0 99 11 c0 mov 0xc01199e0,%eax +c01051a7: c7 44 24 0c 02 00 00 movl $0x2,0xc(%esp) +c01051ae: 00 +c01051af: c7 44 24 08 00 11 00 movl $0x1100,0x8(%esp) +c01051b6: 00 +c01051b7: 8b 55 ec mov -0x14(%ebp),%edx +c01051ba: 89 54 24 04 mov %edx,0x4(%esp) +c01051be: 89 04 24 mov %eax,(%esp) +c01051c1: e8 e2 f5 ff ff call c01047a8 +c01051c6: 85 c0 test %eax,%eax +c01051c8: 74 24 je c01051ee +c01051ca: c7 44 24 0c 38 70 10 movl $0xc0107038,0xc(%esp) +c01051d1: c0 +c01051d2: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c01051d9: c0 +c01051da: c7 44 24 04 b8 02 00 movl $0x2b8,0x4(%esp) +c01051e1: 00 +c01051e2: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c01051e9: e8 45 ba ff ff call c0100c33 <__panic> + assert(page_ref(p) == 2);// 验证页面的引用计数为2 +c01051ee: 8b 45 ec mov -0x14(%ebp),%eax +c01051f1: 89 04 24 mov %eax,(%esp) +c01051f4: e8 cc ea ff ff call c0103cc5 +c01051f9: 83 f8 02 cmp $0x2,%eax +c01051fc: 74 24 je c0105222 +c01051fe: c7 44 24 0c 6f 70 10 movl $0xc010706f,0xc(%esp) +c0105205: c0 +c0105206: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c010520d: c0 +c010520e: c7 44 24 04 b9 02 00 movl $0x2b9,0x4(%esp) +c0105215: 00 +c0105216: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c010521d: e8 11 ba ff ff call c0100c33 <__panic> + + const char *str = "ucore: Hello world!!";// 定义一个字符串 +c0105222: c7 45 e8 80 70 10 c0 movl $0xc0107080,-0x18(%ebp) + strcpy((void *)0x100, str);// 将字符串复制到虚拟地址 0x100 +c0105229: 8b 45 e8 mov -0x18(%ebp),%eax +c010522c: 89 44 24 04 mov %eax,0x4(%esp) +c0105230: c7 04 24 00 01 00 00 movl $0x100,(%esp) +c0105237: e8 fc 09 00 00 call c0105c38 + // 验证两个映射地址的数据是否一致 + assert(strcmp((void *)0x100, (void *)(0x100 + PGSIZE)) == 0); +c010523c: c7 44 24 04 00 11 00 movl $0x1100,0x4(%esp) +c0105243: 00 +c0105244: c7 04 24 00 01 00 00 movl $0x100,(%esp) +c010524b: e8 60 0a 00 00 call c0105cb0 +c0105250: 85 c0 test %eax,%eax +c0105252: 74 24 je c0105278 +c0105254: c7 44 24 0c 98 70 10 movl $0xc0107098,0xc(%esp) +c010525b: c0 +c010525c: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c0105263: c0 +c0105264: c7 44 24 04 be 02 00 movl $0x2be,0x4(%esp) +c010526b: 00 +c010526c: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c0105273: e8 bb b9 ff ff call c0100c33 <__panic> + // 在页面的 0x100 偏移处设置字符串结束符 + *(char *)(page2kva(p) + 0x100) = '\0'; +c0105278: 8b 45 ec mov -0x14(%ebp),%eax +c010527b: 89 04 24 mov %eax,(%esp) +c010527e: e8 92 e9 ff ff call c0103c15 +c0105283: 05 00 01 00 00 add $0x100,%eax +c0105288: c6 00 00 movb $0x0,(%eax) + assert(strlen((const char *)0x100) == 0);// 验证字符串长度为0 +c010528b: c7 04 24 00 01 00 00 movl $0x100,(%esp) +c0105292: e8 47 09 00 00 call c0105bde +c0105297: 85 c0 test %eax,%eax +c0105299: 74 24 je c01052bf +c010529b: c7 44 24 0c d0 70 10 movl $0xc01070d0,0xc(%esp) +c01052a2: c0 +c01052a3: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c01052aa: c0 +c01052ab: c7 44 24 04 c1 02 00 movl $0x2c1,0x4(%esp) +c01052b2: 00 +c01052b3: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c01052ba: e8 74 b9 ff ff call c0100c33 <__panic> + + free_page(p);// 释放页面 p +c01052bf: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c01052c6: 00 +c01052c7: 8b 45 ec mov -0x14(%ebp),%eax +c01052ca: 89 04 24 mov %eax,(%esp) +c01052cd: e8 3d ec ff ff call c0103f0f + free_page(pde2page(boot_pgdir[0]));// 释放页目录项对应的页面 +c01052d2: a1 e0 99 11 c0 mov 0xc01199e0,%eax +c01052d7: 8b 00 mov (%eax),%eax +c01052d9: 89 04 24 mov %eax,(%esp) +c01052dc: e8 ca e9 ff ff call c0103cab +c01052e1: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c01052e8: 00 +c01052e9: 89 04 24 mov %eax,(%esp) +c01052ec: e8 1e ec ff ff call c0103f0f + boot_pgdir[0] = 0;// 将页目录的第一个项设为0 +c01052f1: a1 e0 99 11 c0 mov 0xc01199e0,%eax +c01052f6: c7 00 00 00 00 00 movl $0x0,(%eax) + + cprintf("check_boot_pgdir() succeeded!\n");// 输出成功信息 +c01052fc: c7 04 24 f4 70 10 c0 movl $0xc01070f4,(%esp) +c0105303: e8 5e b0 ff ff call c0100366 +} +c0105308: 90 nop +c0105309: 89 ec mov %ebp,%esp +c010530b: 5d pop %ebp +c010530c: c3 ret + +c010530d : + +//perm2str - use string 'u,r,w,-' to present the permission +static const char * +perm2str(int perm) { +c010530d: 55 push %ebp +c010530e: 89 e5 mov %esp,%ebp + //定义一个静态字符数组 str,长度为4 + static char str[4]; + //如果 perm 与 PTE_U 按位与的结果不为0,则 str[0] 设置为 'u',否则设置为 '-' + str[0] = (perm & PTE_U) ? 'u' : '-'; +c0105310: 8b 45 08 mov 0x8(%ebp),%eax +c0105313: 83 e0 04 and $0x4,%eax +c0105316: 85 c0 test %eax,%eax +c0105318: 74 04 je c010531e +c010531a: b0 75 mov $0x75,%al +c010531c: eb 02 jmp c0105320 +c010531e: b0 2d mov $0x2d,%al +c0105320: a2 88 cf 11 c0 mov %al,0xc011cf88 + //str[1] 始终设置为 'r' + str[1] = 'r'; +c0105325: c6 05 89 cf 11 c0 72 movb $0x72,0xc011cf89 + //如果 perm 与 PTE_W 按位与的结果不为0,则 str[2] 设置为 'w',否则设置为 '-' + str[2] = (perm & PTE_W) ? 'w' : '-'; +c010532c: 8b 45 08 mov 0x8(%ebp),%eax +c010532f: 83 e0 02 and $0x2,%eax +c0105332: 85 c0 test %eax,%eax +c0105334: 74 04 je c010533a +c0105336: b0 77 mov $0x77,%al +c0105338: eb 02 jmp c010533c +c010533a: b0 2d mov $0x2d,%al +c010533c: a2 8a cf 11 c0 mov %al,0xc011cf8a + //str[3] 设置为字符串结束符 \0 + str[3] = '\0'; +c0105341: c6 05 8b cf 11 c0 00 movb $0x0,0xc011cf8b + return str; +c0105348: b8 88 cf 11 c0 mov $0xc011cf88,%eax +} +c010534d: 5d pop %ebp +c010534e: c3 ret + +c010534f : +// 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) { +c010534f: 55 push %ebp +c0105350: 89 e5 mov %esp,%ebp +c0105352: 83 ec 10 sub $0x10,%esp + if (start >= right) {// 检查起始索引是否超出右边界 +c0105355: 8b 45 10 mov 0x10(%ebp),%eax +c0105358: 3b 45 0c cmp 0xc(%ebp),%eax +c010535b: 72 0d jb c010536a + return 0;// 如果超出右边界,返回0 +c010535d: b8 00 00 00 00 mov $0x0,%eax +c0105362: e9 98 00 00 00 jmp c01053ff + } + while (start < right && !(table[start] & PTE_P)) {// 查找第一个有效项(PTE_P位为1的项) + start ++;// 索引递增 +c0105367: ff 45 10 incl 0x10(%ebp) + while (start < right && !(table[start] & PTE_P)) {// 查找第一个有效项(PTE_P位为1的项) +c010536a: 8b 45 10 mov 0x10(%ebp),%eax +c010536d: 3b 45 0c cmp 0xc(%ebp),%eax +c0105370: 73 18 jae c010538a +c0105372: 8b 45 10 mov 0x10(%ebp),%eax +c0105375: 8d 14 85 00 00 00 00 lea 0x0(,%eax,4),%edx +c010537c: 8b 45 14 mov 0x14(%ebp),%eax +c010537f: 01 d0 add %edx,%eax +c0105381: 8b 00 mov (%eax),%eax +c0105383: 83 e0 01 and $0x1,%eax +c0105386: 85 c0 test %eax,%eax +c0105388: 74 dd je c0105367 + } + if (start < right) {// 检查是否找到有效项 +c010538a: 8b 45 10 mov 0x10(%ebp),%eax +c010538d: 3b 45 0c cmp 0xc(%ebp),%eax +c0105390: 73 68 jae c01053fa + if (left_store != NULL) {// 如果left_store不为NULL +c0105392: 83 7d 18 00 cmpl $0x0,0x18(%ebp) +c0105396: 74 08 je c01053a0 + *left_store = start;// 记录左边界索引 +c0105398: 8b 45 18 mov 0x18(%ebp),%eax +c010539b: 8b 55 10 mov 0x10(%ebp),%edx +c010539e: 89 10 mov %edx,(%eax) + } + int perm = (table[start ++] & PTE_USER);// 获取当前项的用户权限位并递增索引 +c01053a0: 8b 45 10 mov 0x10(%ebp),%eax +c01053a3: 8d 50 01 lea 0x1(%eax),%edx +c01053a6: 89 55 10 mov %edx,0x10(%ebp) +c01053a9: 8d 14 85 00 00 00 00 lea 0x0(,%eax,4),%edx +c01053b0: 8b 45 14 mov 0x14(%ebp),%eax +c01053b3: 01 d0 add %edx,%eax +c01053b5: 8b 00 mov (%eax),%eax +c01053b7: 83 e0 07 and $0x7,%eax +c01053ba: 89 45 fc mov %eax,-0x4(%ebp) + while (start < right && (table[start] & PTE_USER) == perm) {// 查找具有相同用户权限的连续项 +c01053bd: eb 03 jmp c01053c2 + start ++;// 索引递增 +c01053bf: ff 45 10 incl 0x10(%ebp) + while (start < right && (table[start] & PTE_USER) == perm) {// 查找具有相同用户权限的连续项 +c01053c2: 8b 45 10 mov 0x10(%ebp),%eax +c01053c5: 3b 45 0c cmp 0xc(%ebp),%eax +c01053c8: 73 1d jae c01053e7 +c01053ca: 8b 45 10 mov 0x10(%ebp),%eax +c01053cd: 8d 14 85 00 00 00 00 lea 0x0(,%eax,4),%edx +c01053d4: 8b 45 14 mov 0x14(%ebp),%eax +c01053d7: 01 d0 add %edx,%eax +c01053d9: 8b 00 mov (%eax),%eax +c01053db: 83 e0 07 and $0x7,%eax +c01053de: 89 c2 mov %eax,%edx +c01053e0: 8b 45 fc mov -0x4(%ebp),%eax +c01053e3: 39 c2 cmp %eax,%edx +c01053e5: 74 d8 je c01053bf + } + if (right_store != NULL) {// 如果right_store不为NULL +c01053e7: 83 7d 1c 00 cmpl $0x0,0x1c(%ebp) +c01053eb: 74 08 je c01053f5 + *right_store = start;// 记录右边界索引 +c01053ed: 8b 45 1c mov 0x1c(%ebp),%eax +c01053f0: 8b 55 10 mov 0x10(%ebp),%edx +c01053f3: 89 10 mov %edx,(%eax) + } + return perm;// 返回用户权限位 +c01053f5: 8b 45 fc mov -0x4(%ebp),%eax +c01053f8: eb 05 jmp c01053ff + } + return 0;// 如果未找到有效项,返回0 +c01053fa: b8 00 00 00 00 mov $0x0,%eax +} +c01053ff: 89 ec mov %ebp,%esp +c0105401: 5d pop %ebp +c0105402: c3 ret + +c0105403 : + +//print_pgdir - print the PDT&PT +void +print_pgdir(void) { +c0105403: 55 push %ebp +c0105404: 89 e5 mov %esp,%ebp +c0105406: 57 push %edi +c0105407: 56 push %esi +c0105408: 53 push %ebx +c0105409: 83 ec 4c sub $0x4c,%esp + cprintf("-------------------- BEGIN --------------------\n"); +c010540c: c7 04 24 14 71 10 c0 movl $0xc0107114,(%esp) +c0105413: e8 4e af ff ff call c0100366 + // 定义变量 left, right 和 perm + size_t left, right = 0, perm; +c0105418: c7 45 dc 00 00 00 00 movl $0x0,-0x24(%ebp) + // 遍历页目录项 + while ((perm = get_pgtable_items(0, NPDEENTRY, right, vpd, &left, &right)) != 0) { +c010541f: e9 f2 00 00 00 jmp c0105516 + // 打印页目录项的信息 + cprintf("PDE(%03x) %08x-%08x %08x %s\n", right - left, +c0105424: 8b 45 e4 mov -0x1c(%ebp),%eax +c0105427: 89 04 24 mov %eax,(%esp) +c010542a: e8 de fe ff ff call c010530d + left * PTSIZE, right * PTSIZE, (right - left) * PTSIZE, perm2str(perm)); +c010542f: 8b 55 dc mov -0x24(%ebp),%edx +c0105432: 8b 4d e0 mov -0x20(%ebp),%ecx +c0105435: 29 ca sub %ecx,%edx + cprintf("PDE(%03x) %08x-%08x %08x %s\n", right - left, +c0105437: 89 d6 mov %edx,%esi +c0105439: c1 e6 16 shl $0x16,%esi +c010543c: 8b 55 dc mov -0x24(%ebp),%edx +c010543f: 89 d3 mov %edx,%ebx +c0105441: c1 e3 16 shl $0x16,%ebx +c0105444: 8b 55 e0 mov -0x20(%ebp),%edx +c0105447: 89 d1 mov %edx,%ecx +c0105449: c1 e1 16 shl $0x16,%ecx +c010544c: 8b 55 dc mov -0x24(%ebp),%edx +c010544f: 8b 7d e0 mov -0x20(%ebp),%edi +c0105452: 29 fa sub %edi,%edx +c0105454: 89 44 24 14 mov %eax,0x14(%esp) +c0105458: 89 74 24 10 mov %esi,0x10(%esp) +c010545c: 89 5c 24 0c mov %ebx,0xc(%esp) +c0105460: 89 4c 24 08 mov %ecx,0x8(%esp) +c0105464: 89 54 24 04 mov %edx,0x4(%esp) +c0105468: c7 04 24 45 71 10 c0 movl $0xc0107145,(%esp) +c010546f: e8 f2 ae ff ff call c0100366 + // 计算页表项的起始和结束索引 + size_t l, r = left * NPTEENTRY; +c0105474: 8b 45 e0 mov -0x20(%ebp),%eax +c0105477: c1 e0 0a shl $0xa,%eax +c010547a: 89 45 d4 mov %eax,-0x2c(%ebp) + // 遍历页表项 + while ((perm = get_pgtable_items(left * NPTEENTRY, right * NPTEENTRY, r, vpt, &l, &r)) != 0) { +c010547d: eb 50 jmp c01054cf + // 打印页表项的信息 + cprintf(" |-- PTE(%05x) %08x-%08x %08x %s\n", r - l, +c010547f: 8b 45 e4 mov -0x1c(%ebp),%eax +c0105482: 89 04 24 mov %eax,(%esp) +c0105485: e8 83 fe ff ff call c010530d + l * PGSIZE, r * PGSIZE, (r - l) * PGSIZE, perm2str(perm)); +c010548a: 8b 55 d4 mov -0x2c(%ebp),%edx +c010548d: 8b 4d d8 mov -0x28(%ebp),%ecx +c0105490: 29 ca sub %ecx,%edx + cprintf(" |-- PTE(%05x) %08x-%08x %08x %s\n", r - l, +c0105492: 89 d6 mov %edx,%esi +c0105494: c1 e6 0c shl $0xc,%esi +c0105497: 8b 55 d4 mov -0x2c(%ebp),%edx +c010549a: 89 d3 mov %edx,%ebx +c010549c: c1 e3 0c shl $0xc,%ebx +c010549f: 8b 55 d8 mov -0x28(%ebp),%edx +c01054a2: 89 d1 mov %edx,%ecx +c01054a4: c1 e1 0c shl $0xc,%ecx +c01054a7: 8b 55 d4 mov -0x2c(%ebp),%edx +c01054aa: 8b 7d d8 mov -0x28(%ebp),%edi +c01054ad: 29 fa sub %edi,%edx +c01054af: 89 44 24 14 mov %eax,0x14(%esp) +c01054b3: 89 74 24 10 mov %esi,0x10(%esp) +c01054b7: 89 5c 24 0c mov %ebx,0xc(%esp) +c01054bb: 89 4c 24 08 mov %ecx,0x8(%esp) +c01054bf: 89 54 24 04 mov %edx,0x4(%esp) +c01054c3: c7 04 24 64 71 10 c0 movl $0xc0107164,(%esp) +c01054ca: e8 97 ae ff ff call c0100366 + while ((perm = get_pgtable_items(left * NPTEENTRY, right * NPTEENTRY, r, vpt, &l, &r)) != 0) { +c01054cf: be 00 00 c0 fa mov $0xfac00000,%esi +c01054d4: 8b 45 d4 mov -0x2c(%ebp),%eax +c01054d7: 8b 55 dc mov -0x24(%ebp),%edx +c01054da: 89 d3 mov %edx,%ebx +c01054dc: c1 e3 0a shl $0xa,%ebx +c01054df: 8b 55 e0 mov -0x20(%ebp),%edx +c01054e2: 89 d1 mov %edx,%ecx +c01054e4: c1 e1 0a shl $0xa,%ecx +c01054e7: 8d 55 d4 lea -0x2c(%ebp),%edx +c01054ea: 89 54 24 14 mov %edx,0x14(%esp) +c01054ee: 8d 55 d8 lea -0x28(%ebp),%edx +c01054f1: 89 54 24 10 mov %edx,0x10(%esp) +c01054f5: 89 74 24 0c mov %esi,0xc(%esp) +c01054f9: 89 44 24 08 mov %eax,0x8(%esp) +c01054fd: 89 5c 24 04 mov %ebx,0x4(%esp) +c0105501: 89 0c 24 mov %ecx,(%esp) +c0105504: e8 46 fe ff ff call c010534f +c0105509: 89 45 e4 mov %eax,-0x1c(%ebp) +c010550c: 83 7d e4 00 cmpl $0x0,-0x1c(%ebp) +c0105510: 0f 85 69 ff ff ff jne c010547f + while ((perm = get_pgtable_items(0, NPDEENTRY, right, vpd, &left, &right)) != 0) { +c0105516: b9 00 b0 fe fa mov $0xfafeb000,%ecx +c010551b: 8b 45 dc mov -0x24(%ebp),%eax +c010551e: 8d 55 dc lea -0x24(%ebp),%edx +c0105521: 89 54 24 14 mov %edx,0x14(%esp) +c0105525: 8d 55 e0 lea -0x20(%ebp),%edx +c0105528: 89 54 24 10 mov %edx,0x10(%esp) +c010552c: 89 4c 24 0c mov %ecx,0xc(%esp) +c0105530: 89 44 24 08 mov %eax,0x8(%esp) +c0105534: c7 44 24 04 00 04 00 movl $0x400,0x4(%esp) +c010553b: 00 +c010553c: c7 04 24 00 00 00 00 movl $0x0,(%esp) +c0105543: e8 07 fe ff ff call c010534f +c0105548: 89 45 e4 mov %eax,-0x1c(%ebp) +c010554b: 83 7d e4 00 cmpl $0x0,-0x1c(%ebp) +c010554f: 0f 85 cf fe ff ff jne c0105424 + } + } + cprintf("--------------------- END ---------------------\n"); +c0105555: c7 04 24 88 71 10 c0 movl $0xc0107188,(%esp) +c010555c: e8 05 ae ff ff call c0100366 +} +c0105561: 90 nop +c0105562: 83 c4 4c add $0x4c,%esp +c0105565: 5b pop %ebx +c0105566: 5e pop %esi +c0105567: 5f pop %edi +c0105568: 5d pop %ebp +c0105569: c3 ret + +c010556a : + * @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) { +c010556a: 55 push %ebp +c010556b: 89 e5 mov %esp,%ebp +c010556d: 83 ec 58 sub $0x58,%esp +c0105570: 8b 45 10 mov 0x10(%ebp),%eax +c0105573: 89 45 d0 mov %eax,-0x30(%ebp) +c0105576: 8b 45 14 mov 0x14(%ebp),%eax +c0105579: 89 45 d4 mov %eax,-0x2c(%ebp) + unsigned long long result = num; +c010557c: 8b 45 d0 mov -0x30(%ebp),%eax +c010557f: 8b 55 d4 mov -0x2c(%ebp),%edx +c0105582: 89 45 e8 mov %eax,-0x18(%ebp) +c0105585: 89 55 ec mov %edx,-0x14(%ebp) + unsigned mod = do_div(result, base); +c0105588: 8b 45 18 mov 0x18(%ebp),%eax +c010558b: 89 45 e4 mov %eax,-0x1c(%ebp) +c010558e: 8b 45 e8 mov -0x18(%ebp),%eax +c0105591: 8b 55 ec mov -0x14(%ebp),%edx +c0105594: 89 45 e0 mov %eax,-0x20(%ebp) +c0105597: 89 55 f0 mov %edx,-0x10(%ebp) +c010559a: 8b 45 f0 mov -0x10(%ebp),%eax +c010559d: 89 45 f4 mov %eax,-0xc(%ebp) +c01055a0: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) +c01055a4: 74 1c je c01055c2 +c01055a6: 8b 45 f0 mov -0x10(%ebp),%eax +c01055a9: ba 00 00 00 00 mov $0x0,%edx +c01055ae: f7 75 e4 divl -0x1c(%ebp) +c01055b1: 89 55 f4 mov %edx,-0xc(%ebp) +c01055b4: 8b 45 f0 mov -0x10(%ebp),%eax +c01055b7: ba 00 00 00 00 mov $0x0,%edx +c01055bc: f7 75 e4 divl -0x1c(%ebp) +c01055bf: 89 45 f0 mov %eax,-0x10(%ebp) +c01055c2: 8b 45 e0 mov -0x20(%ebp),%eax +c01055c5: 8b 55 f4 mov -0xc(%ebp),%edx +c01055c8: f7 75 e4 divl -0x1c(%ebp) +c01055cb: 89 45 e0 mov %eax,-0x20(%ebp) +c01055ce: 89 55 dc mov %edx,-0x24(%ebp) +c01055d1: 8b 45 e0 mov -0x20(%ebp),%eax +c01055d4: 8b 55 f0 mov -0x10(%ebp),%edx +c01055d7: 89 45 e8 mov %eax,-0x18(%ebp) +c01055da: 89 55 ec mov %edx,-0x14(%ebp) +c01055dd: 8b 45 dc mov -0x24(%ebp),%eax +c01055e0: 89 45 d8 mov %eax,-0x28(%ebp) + + // first recursively print all preceding (more significant) digits + if (num >= base) { +c01055e3: 8b 45 18 mov 0x18(%ebp),%eax +c01055e6: ba 00 00 00 00 mov $0x0,%edx +c01055eb: 8b 4d d4 mov -0x2c(%ebp),%ecx +c01055ee: 39 45 d0 cmp %eax,-0x30(%ebp) +c01055f1: 19 d1 sbb %edx,%ecx +c01055f3: 72 4c jb c0105641 + printnum(putch, putdat, result, base, width - 1, padc); +c01055f5: 8b 45 1c mov 0x1c(%ebp),%eax +c01055f8: 8d 50 ff lea -0x1(%eax),%edx +c01055fb: 8b 45 20 mov 0x20(%ebp),%eax +c01055fe: 89 44 24 18 mov %eax,0x18(%esp) +c0105602: 89 54 24 14 mov %edx,0x14(%esp) +c0105606: 8b 45 18 mov 0x18(%ebp),%eax +c0105609: 89 44 24 10 mov %eax,0x10(%esp) +c010560d: 8b 45 e8 mov -0x18(%ebp),%eax +c0105610: 8b 55 ec mov -0x14(%ebp),%edx +c0105613: 89 44 24 08 mov %eax,0x8(%esp) +c0105617: 89 54 24 0c mov %edx,0xc(%esp) +c010561b: 8b 45 0c mov 0xc(%ebp),%eax +c010561e: 89 44 24 04 mov %eax,0x4(%esp) +c0105622: 8b 45 08 mov 0x8(%ebp),%eax +c0105625: 89 04 24 mov %eax,(%esp) +c0105628: e8 3d ff ff ff call c010556a +c010562d: eb 1b jmp c010564a + } else { + // print any needed pad characters before first digit + while (-- width > 0) + putch(padc, putdat); +c010562f: 8b 45 0c mov 0xc(%ebp),%eax +c0105632: 89 44 24 04 mov %eax,0x4(%esp) +c0105636: 8b 45 20 mov 0x20(%ebp),%eax +c0105639: 89 04 24 mov %eax,(%esp) +c010563c: 8b 45 08 mov 0x8(%ebp),%eax +c010563f: ff d0 call *%eax + while (-- width > 0) +c0105641: ff 4d 1c decl 0x1c(%ebp) +c0105644: 83 7d 1c 00 cmpl $0x0,0x1c(%ebp) +c0105648: 7f e5 jg c010562f + } + // then print this (the least significant) digit + putch("0123456789abcdef"[mod], putdat); +c010564a: 8b 45 d8 mov -0x28(%ebp),%eax +c010564d: 05 3c 72 10 c0 add $0xc010723c,%eax +c0105652: 0f b6 00 movzbl (%eax),%eax +c0105655: 0f be c0 movsbl %al,%eax +c0105658: 8b 55 0c mov 0xc(%ebp),%edx +c010565b: 89 54 24 04 mov %edx,0x4(%esp) +c010565f: 89 04 24 mov %eax,(%esp) +c0105662: 8b 45 08 mov 0x8(%ebp),%eax +c0105665: ff d0 call *%eax +} +c0105667: 90 nop +c0105668: 89 ec mov %ebp,%esp +c010566a: 5d pop %ebp +c010566b: c3 ret + +c010566c : + * 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) { +c010566c: 55 push %ebp +c010566d: 89 e5 mov %esp,%ebp + if (lflag >= 2) { +c010566f: 83 7d 0c 01 cmpl $0x1,0xc(%ebp) +c0105673: 7e 14 jle c0105689 + return va_arg(*ap, unsigned long long); +c0105675: 8b 45 08 mov 0x8(%ebp),%eax +c0105678: 8b 00 mov (%eax),%eax +c010567a: 8d 48 08 lea 0x8(%eax),%ecx +c010567d: 8b 55 08 mov 0x8(%ebp),%edx +c0105680: 89 0a mov %ecx,(%edx) +c0105682: 8b 50 04 mov 0x4(%eax),%edx +c0105685: 8b 00 mov (%eax),%eax +c0105687: eb 30 jmp c01056b9 + } + else if (lflag) { +c0105689: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) +c010568d: 74 16 je c01056a5 + return va_arg(*ap, unsigned long); +c010568f: 8b 45 08 mov 0x8(%ebp),%eax +c0105692: 8b 00 mov (%eax),%eax +c0105694: 8d 48 04 lea 0x4(%eax),%ecx +c0105697: 8b 55 08 mov 0x8(%ebp),%edx +c010569a: 89 0a mov %ecx,(%edx) +c010569c: 8b 00 mov (%eax),%eax +c010569e: ba 00 00 00 00 mov $0x0,%edx +c01056a3: eb 14 jmp c01056b9 + } + else { + return va_arg(*ap, unsigned int); +c01056a5: 8b 45 08 mov 0x8(%ebp),%eax +c01056a8: 8b 00 mov (%eax),%eax +c01056aa: 8d 48 04 lea 0x4(%eax),%ecx +c01056ad: 8b 55 08 mov 0x8(%ebp),%edx +c01056b0: 89 0a mov %ecx,(%edx) +c01056b2: 8b 00 mov (%eax),%eax +c01056b4: ba 00 00 00 00 mov $0x0,%edx + } +} +c01056b9: 5d pop %ebp +c01056ba: c3 ret + +c01056bb : + * 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) { +c01056bb: 55 push %ebp +c01056bc: 89 e5 mov %esp,%ebp + if (lflag >= 2) { +c01056be: 83 7d 0c 01 cmpl $0x1,0xc(%ebp) +c01056c2: 7e 14 jle c01056d8 + return va_arg(*ap, long long); +c01056c4: 8b 45 08 mov 0x8(%ebp),%eax +c01056c7: 8b 00 mov (%eax),%eax +c01056c9: 8d 48 08 lea 0x8(%eax),%ecx +c01056cc: 8b 55 08 mov 0x8(%ebp),%edx +c01056cf: 89 0a mov %ecx,(%edx) +c01056d1: 8b 50 04 mov 0x4(%eax),%edx +c01056d4: 8b 00 mov (%eax),%eax +c01056d6: eb 28 jmp c0105700 + } + else if (lflag) { +c01056d8: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) +c01056dc: 74 12 je c01056f0 + return va_arg(*ap, long); +c01056de: 8b 45 08 mov 0x8(%ebp),%eax +c01056e1: 8b 00 mov (%eax),%eax +c01056e3: 8d 48 04 lea 0x4(%eax),%ecx +c01056e6: 8b 55 08 mov 0x8(%ebp),%edx +c01056e9: 89 0a mov %ecx,(%edx) +c01056eb: 8b 00 mov (%eax),%eax +c01056ed: 99 cltd +c01056ee: eb 10 jmp c0105700 + } + else { + return va_arg(*ap, int); +c01056f0: 8b 45 08 mov 0x8(%ebp),%eax +c01056f3: 8b 00 mov (%eax),%eax +c01056f5: 8d 48 04 lea 0x4(%eax),%ecx +c01056f8: 8b 55 08 mov 0x8(%ebp),%edx +c01056fb: 89 0a mov %ecx,(%edx) +c01056fd: 8b 00 mov (%eax),%eax +c01056ff: 99 cltd + } +} +c0105700: 5d pop %ebp +c0105701: c3 ret + +c0105702 : + * @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, ...) { +c0105702: 55 push %ebp +c0105703: 89 e5 mov %esp,%ebp +c0105705: 83 ec 28 sub $0x28,%esp + va_list ap; + + va_start(ap, fmt); +c0105708: 8d 45 14 lea 0x14(%ebp),%eax +c010570b: 89 45 f4 mov %eax,-0xc(%ebp) + vprintfmt(putch, putdat, fmt, ap); +c010570e: 8b 45 f4 mov -0xc(%ebp),%eax +c0105711: 89 44 24 0c mov %eax,0xc(%esp) +c0105715: 8b 45 10 mov 0x10(%ebp),%eax +c0105718: 89 44 24 08 mov %eax,0x8(%esp) +c010571c: 8b 45 0c mov 0xc(%ebp),%eax +c010571f: 89 44 24 04 mov %eax,0x4(%esp) +c0105723: 8b 45 08 mov 0x8(%ebp),%eax +c0105726: 89 04 24 mov %eax,(%esp) +c0105729: e8 05 00 00 00 call c0105733 + va_end(ap); +} +c010572e: 90 nop +c010572f: 89 ec mov %ebp,%esp +c0105731: 5d pop %ebp +c0105732: c3 ret + +c0105733 : + * + * 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) { +c0105733: 55 push %ebp +c0105734: 89 e5 mov %esp,%ebp +c0105736: 56 push %esi +c0105737: 53 push %ebx +c0105738: 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 ++) != '%') { +c010573b: eb 17 jmp c0105754 + if (ch == '\0') { +c010573d: 85 db test %ebx,%ebx +c010573f: 0f 84 bf 03 00 00 je c0105b04 + return; + } + putch(ch, putdat); +c0105745: 8b 45 0c mov 0xc(%ebp),%eax +c0105748: 89 44 24 04 mov %eax,0x4(%esp) +c010574c: 89 1c 24 mov %ebx,(%esp) +c010574f: 8b 45 08 mov 0x8(%ebp),%eax +c0105752: ff d0 call *%eax + while ((ch = *(unsigned char *)fmt ++) != '%') { +c0105754: 8b 45 10 mov 0x10(%ebp),%eax +c0105757: 8d 50 01 lea 0x1(%eax),%edx +c010575a: 89 55 10 mov %edx,0x10(%ebp) +c010575d: 0f b6 00 movzbl (%eax),%eax +c0105760: 0f b6 d8 movzbl %al,%ebx +c0105763: 83 fb 25 cmp $0x25,%ebx +c0105766: 75 d5 jne c010573d + } + + // Process a %-escape sequence + char padc = ' '; +c0105768: c6 45 db 20 movb $0x20,-0x25(%ebp) + width = precision = -1; +c010576c: c7 45 e4 ff ff ff ff movl $0xffffffff,-0x1c(%ebp) +c0105773: 8b 45 e4 mov -0x1c(%ebp),%eax +c0105776: 89 45 e8 mov %eax,-0x18(%ebp) + lflag = altflag = 0; +c0105779: c7 45 dc 00 00 00 00 movl $0x0,-0x24(%ebp) +c0105780: 8b 45 dc mov -0x24(%ebp),%eax +c0105783: 89 45 e0 mov %eax,-0x20(%ebp) + + reswitch: + switch (ch = *(unsigned char *)fmt ++) { +c0105786: 8b 45 10 mov 0x10(%ebp),%eax +c0105789: 8d 50 01 lea 0x1(%eax),%edx +c010578c: 89 55 10 mov %edx,0x10(%ebp) +c010578f: 0f b6 00 movzbl (%eax),%eax +c0105792: 0f b6 d8 movzbl %al,%ebx +c0105795: 8d 43 dd lea -0x23(%ebx),%eax +c0105798: 83 f8 55 cmp $0x55,%eax +c010579b: 0f 87 37 03 00 00 ja c0105ad8 +c01057a1: 8b 04 85 60 72 10 c0 mov -0x3fef8da0(,%eax,4),%eax +c01057a8: ff e0 jmp *%eax + + // flag to pad on the right + case '-': + padc = '-'; +c01057aa: c6 45 db 2d movb $0x2d,-0x25(%ebp) + goto reswitch; +c01057ae: eb d6 jmp c0105786 + + // flag to pad with 0's instead of spaces + case '0': + padc = '0'; +c01057b0: c6 45 db 30 movb $0x30,-0x25(%ebp) + goto reswitch; +c01057b4: eb d0 jmp c0105786 + + // width field + case '1' ... '9': + for (precision = 0; ; ++ fmt) { +c01057b6: c7 45 e4 00 00 00 00 movl $0x0,-0x1c(%ebp) + precision = precision * 10 + ch - '0'; +c01057bd: 8b 55 e4 mov -0x1c(%ebp),%edx +c01057c0: 89 d0 mov %edx,%eax +c01057c2: c1 e0 02 shl $0x2,%eax +c01057c5: 01 d0 add %edx,%eax +c01057c7: 01 c0 add %eax,%eax +c01057c9: 01 d8 add %ebx,%eax +c01057cb: 83 e8 30 sub $0x30,%eax +c01057ce: 89 45 e4 mov %eax,-0x1c(%ebp) + ch = *fmt; +c01057d1: 8b 45 10 mov 0x10(%ebp),%eax +c01057d4: 0f b6 00 movzbl (%eax),%eax +c01057d7: 0f be d8 movsbl %al,%ebx + if (ch < '0' || ch > '9') { +c01057da: 83 fb 2f cmp $0x2f,%ebx +c01057dd: 7e 38 jle c0105817 +c01057df: 83 fb 39 cmp $0x39,%ebx +c01057e2: 7f 33 jg c0105817 + for (precision = 0; ; ++ fmt) { +c01057e4: ff 45 10 incl 0x10(%ebp) + precision = precision * 10 + ch - '0'; +c01057e7: eb d4 jmp c01057bd + } + } + goto process_precision; + + case '*': + precision = va_arg(ap, int); +c01057e9: 8b 45 14 mov 0x14(%ebp),%eax +c01057ec: 8d 50 04 lea 0x4(%eax),%edx +c01057ef: 89 55 14 mov %edx,0x14(%ebp) +c01057f2: 8b 00 mov (%eax),%eax +c01057f4: 89 45 e4 mov %eax,-0x1c(%ebp) + goto process_precision; +c01057f7: eb 1f jmp c0105818 + + case '.': + if (width < 0) +c01057f9: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) +c01057fd: 79 87 jns c0105786 + width = 0; +c01057ff: c7 45 e8 00 00 00 00 movl $0x0,-0x18(%ebp) + goto reswitch; +c0105806: e9 7b ff ff ff jmp c0105786 + + case '#': + altflag = 1; +c010580b: c7 45 dc 01 00 00 00 movl $0x1,-0x24(%ebp) + goto reswitch; +c0105812: e9 6f ff ff ff jmp c0105786 + goto process_precision; +c0105817: 90 nop + + process_precision: + if (width < 0) +c0105818: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) +c010581c: 0f 89 64 ff ff ff jns c0105786 + width = precision, precision = -1; +c0105822: 8b 45 e4 mov -0x1c(%ebp),%eax +c0105825: 89 45 e8 mov %eax,-0x18(%ebp) +c0105828: c7 45 e4 ff ff ff ff movl $0xffffffff,-0x1c(%ebp) + goto reswitch; +c010582f: e9 52 ff ff ff jmp c0105786 + + // long flag (doubled for long long) + case 'l': + lflag ++; +c0105834: ff 45 e0 incl -0x20(%ebp) + goto reswitch; +c0105837: e9 4a ff ff ff jmp c0105786 + + // character + case 'c': + putch(va_arg(ap, int), putdat); +c010583c: 8b 45 14 mov 0x14(%ebp),%eax +c010583f: 8d 50 04 lea 0x4(%eax),%edx +c0105842: 89 55 14 mov %edx,0x14(%ebp) +c0105845: 8b 00 mov (%eax),%eax +c0105847: 8b 55 0c mov 0xc(%ebp),%edx +c010584a: 89 54 24 04 mov %edx,0x4(%esp) +c010584e: 89 04 24 mov %eax,(%esp) +c0105851: 8b 45 08 mov 0x8(%ebp),%eax +c0105854: ff d0 call *%eax + break; +c0105856: e9 a4 02 00 00 jmp c0105aff + + // error message + case 'e': + err = va_arg(ap, int); +c010585b: 8b 45 14 mov 0x14(%ebp),%eax +c010585e: 8d 50 04 lea 0x4(%eax),%edx +c0105861: 89 55 14 mov %edx,0x14(%ebp) +c0105864: 8b 18 mov (%eax),%ebx + if (err < 0) { +c0105866: 85 db test %ebx,%ebx +c0105868: 79 02 jns c010586c + err = -err; +c010586a: f7 db neg %ebx + } + if (err > MAXERROR || (p = error_string[err]) == NULL) { +c010586c: 83 fb 06 cmp $0x6,%ebx +c010586f: 7f 0b jg c010587c +c0105871: 8b 34 9d 20 72 10 c0 mov -0x3fef8de0(,%ebx,4),%esi +c0105878: 85 f6 test %esi,%esi +c010587a: 75 23 jne c010589f + printfmt(putch, putdat, "error %d", err); +c010587c: 89 5c 24 0c mov %ebx,0xc(%esp) +c0105880: c7 44 24 08 4d 72 10 movl $0xc010724d,0x8(%esp) +c0105887: c0 +c0105888: 8b 45 0c mov 0xc(%ebp),%eax +c010588b: 89 44 24 04 mov %eax,0x4(%esp) +c010588f: 8b 45 08 mov 0x8(%ebp),%eax +c0105892: 89 04 24 mov %eax,(%esp) +c0105895: e8 68 fe ff ff call c0105702 + } + else { + printfmt(putch, putdat, "%s", p); + } + break; +c010589a: e9 60 02 00 00 jmp c0105aff + printfmt(putch, putdat, "%s", p); +c010589f: 89 74 24 0c mov %esi,0xc(%esp) +c01058a3: c7 44 24 08 56 72 10 movl $0xc0107256,0x8(%esp) +c01058aa: c0 +c01058ab: 8b 45 0c mov 0xc(%ebp),%eax +c01058ae: 89 44 24 04 mov %eax,0x4(%esp) +c01058b2: 8b 45 08 mov 0x8(%ebp),%eax +c01058b5: 89 04 24 mov %eax,(%esp) +c01058b8: e8 45 fe ff ff call c0105702 + break; +c01058bd: e9 3d 02 00 00 jmp c0105aff + + // string + case 's': + if ((p = va_arg(ap, char *)) == NULL) { +c01058c2: 8b 45 14 mov 0x14(%ebp),%eax +c01058c5: 8d 50 04 lea 0x4(%eax),%edx +c01058c8: 89 55 14 mov %edx,0x14(%ebp) +c01058cb: 8b 30 mov (%eax),%esi +c01058cd: 85 f6 test %esi,%esi +c01058cf: 75 05 jne c01058d6 + p = "(null)"; +c01058d1: be 59 72 10 c0 mov $0xc0107259,%esi + } + if (width > 0 && padc != '-') { +c01058d6: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) +c01058da: 7e 76 jle c0105952 +c01058dc: 80 7d db 2d cmpb $0x2d,-0x25(%ebp) +c01058e0: 74 70 je c0105952 + for (width -= strnlen(p, precision); width > 0; width --) { +c01058e2: 8b 45 e4 mov -0x1c(%ebp),%eax +c01058e5: 89 44 24 04 mov %eax,0x4(%esp) +c01058e9: 89 34 24 mov %esi,(%esp) +c01058ec: e8 16 03 00 00 call c0105c07 +c01058f1: 89 c2 mov %eax,%edx +c01058f3: 8b 45 e8 mov -0x18(%ebp),%eax +c01058f6: 29 d0 sub %edx,%eax +c01058f8: 89 45 e8 mov %eax,-0x18(%ebp) +c01058fb: eb 16 jmp c0105913 + putch(padc, putdat); +c01058fd: 0f be 45 db movsbl -0x25(%ebp),%eax +c0105901: 8b 55 0c mov 0xc(%ebp),%edx +c0105904: 89 54 24 04 mov %edx,0x4(%esp) +c0105908: 89 04 24 mov %eax,(%esp) +c010590b: 8b 45 08 mov 0x8(%ebp),%eax +c010590e: ff d0 call *%eax + for (width -= strnlen(p, precision); width > 0; width --) { +c0105910: ff 4d e8 decl -0x18(%ebp) +c0105913: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) +c0105917: 7f e4 jg c01058fd + } + } + for (; (ch = *p ++) != '\0' && (precision < 0 || -- precision >= 0); width --) { +c0105919: eb 37 jmp c0105952 + if (altflag && (ch < ' ' || ch > '~')) { +c010591b: 83 7d dc 00 cmpl $0x0,-0x24(%ebp) +c010591f: 74 1f je c0105940 +c0105921: 83 fb 1f cmp $0x1f,%ebx +c0105924: 7e 05 jle c010592b +c0105926: 83 fb 7e cmp $0x7e,%ebx +c0105929: 7e 15 jle c0105940 + putch('?', putdat); +c010592b: 8b 45 0c mov 0xc(%ebp),%eax +c010592e: 89 44 24 04 mov %eax,0x4(%esp) +c0105932: c7 04 24 3f 00 00 00 movl $0x3f,(%esp) +c0105939: 8b 45 08 mov 0x8(%ebp),%eax +c010593c: ff d0 call *%eax +c010593e: eb 0f jmp c010594f + } + else { + putch(ch, putdat); +c0105940: 8b 45 0c mov 0xc(%ebp),%eax +c0105943: 89 44 24 04 mov %eax,0x4(%esp) +c0105947: 89 1c 24 mov %ebx,(%esp) +c010594a: 8b 45 08 mov 0x8(%ebp),%eax +c010594d: ff d0 call *%eax + for (; (ch = *p ++) != '\0' && (precision < 0 || -- precision >= 0); width --) { +c010594f: ff 4d e8 decl -0x18(%ebp) +c0105952: 89 f0 mov %esi,%eax +c0105954: 8d 70 01 lea 0x1(%eax),%esi +c0105957: 0f b6 00 movzbl (%eax),%eax +c010595a: 0f be d8 movsbl %al,%ebx +c010595d: 85 db test %ebx,%ebx +c010595f: 74 27 je c0105988 +c0105961: 83 7d e4 00 cmpl $0x0,-0x1c(%ebp) +c0105965: 78 b4 js c010591b +c0105967: ff 4d e4 decl -0x1c(%ebp) +c010596a: 83 7d e4 00 cmpl $0x0,-0x1c(%ebp) +c010596e: 79 ab jns c010591b + } + } + for (; width > 0; width --) { +c0105970: eb 16 jmp c0105988 + putch(' ', putdat); +c0105972: 8b 45 0c mov 0xc(%ebp),%eax +c0105975: 89 44 24 04 mov %eax,0x4(%esp) +c0105979: c7 04 24 20 00 00 00 movl $0x20,(%esp) +c0105980: 8b 45 08 mov 0x8(%ebp),%eax +c0105983: ff d0 call *%eax + for (; width > 0; width --) { +c0105985: ff 4d e8 decl -0x18(%ebp) +c0105988: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) +c010598c: 7f e4 jg c0105972 + } + break; +c010598e: e9 6c 01 00 00 jmp c0105aff + + // (signed) decimal + case 'd': + num = getint(&ap, lflag); +c0105993: 8b 45 e0 mov -0x20(%ebp),%eax +c0105996: 89 44 24 04 mov %eax,0x4(%esp) +c010599a: 8d 45 14 lea 0x14(%ebp),%eax +c010599d: 89 04 24 mov %eax,(%esp) +c01059a0: e8 16 fd ff ff call c01056bb +c01059a5: 89 45 f0 mov %eax,-0x10(%ebp) +c01059a8: 89 55 f4 mov %edx,-0xc(%ebp) + if ((long long)num < 0) { +c01059ab: 8b 45 f0 mov -0x10(%ebp),%eax +c01059ae: 8b 55 f4 mov -0xc(%ebp),%edx +c01059b1: 85 d2 test %edx,%edx +c01059b3: 79 26 jns c01059db + putch('-', putdat); +c01059b5: 8b 45 0c mov 0xc(%ebp),%eax +c01059b8: 89 44 24 04 mov %eax,0x4(%esp) +c01059bc: c7 04 24 2d 00 00 00 movl $0x2d,(%esp) +c01059c3: 8b 45 08 mov 0x8(%ebp),%eax +c01059c6: ff d0 call *%eax + num = -(long long)num; +c01059c8: 8b 45 f0 mov -0x10(%ebp),%eax +c01059cb: 8b 55 f4 mov -0xc(%ebp),%edx +c01059ce: f7 d8 neg %eax +c01059d0: 83 d2 00 adc $0x0,%edx +c01059d3: f7 da neg %edx +c01059d5: 89 45 f0 mov %eax,-0x10(%ebp) +c01059d8: 89 55 f4 mov %edx,-0xc(%ebp) + } + base = 10; +c01059db: c7 45 ec 0a 00 00 00 movl $0xa,-0x14(%ebp) + goto number; +c01059e2: e9 a8 00 00 00 jmp c0105a8f + + // unsigned decimal + case 'u': + num = getuint(&ap, lflag); +c01059e7: 8b 45 e0 mov -0x20(%ebp),%eax +c01059ea: 89 44 24 04 mov %eax,0x4(%esp) +c01059ee: 8d 45 14 lea 0x14(%ebp),%eax +c01059f1: 89 04 24 mov %eax,(%esp) +c01059f4: e8 73 fc ff ff call c010566c +c01059f9: 89 45 f0 mov %eax,-0x10(%ebp) +c01059fc: 89 55 f4 mov %edx,-0xc(%ebp) + base = 10; +c01059ff: c7 45 ec 0a 00 00 00 movl $0xa,-0x14(%ebp) + goto number; +c0105a06: e9 84 00 00 00 jmp c0105a8f + + // (unsigned) octal + case 'o': + num = getuint(&ap, lflag); +c0105a0b: 8b 45 e0 mov -0x20(%ebp),%eax +c0105a0e: 89 44 24 04 mov %eax,0x4(%esp) +c0105a12: 8d 45 14 lea 0x14(%ebp),%eax +c0105a15: 89 04 24 mov %eax,(%esp) +c0105a18: e8 4f fc ff ff call c010566c +c0105a1d: 89 45 f0 mov %eax,-0x10(%ebp) +c0105a20: 89 55 f4 mov %edx,-0xc(%ebp) + base = 8; +c0105a23: c7 45 ec 08 00 00 00 movl $0x8,-0x14(%ebp) + goto number; +c0105a2a: eb 63 jmp c0105a8f + + // pointer + case 'p': + putch('0', putdat); +c0105a2c: 8b 45 0c mov 0xc(%ebp),%eax +c0105a2f: 89 44 24 04 mov %eax,0x4(%esp) +c0105a33: c7 04 24 30 00 00 00 movl $0x30,(%esp) +c0105a3a: 8b 45 08 mov 0x8(%ebp),%eax +c0105a3d: ff d0 call *%eax + putch('x', putdat); +c0105a3f: 8b 45 0c mov 0xc(%ebp),%eax +c0105a42: 89 44 24 04 mov %eax,0x4(%esp) +c0105a46: c7 04 24 78 00 00 00 movl $0x78,(%esp) +c0105a4d: 8b 45 08 mov 0x8(%ebp),%eax +c0105a50: ff d0 call *%eax + num = (unsigned long long)(uintptr_t)va_arg(ap, void *); +c0105a52: 8b 45 14 mov 0x14(%ebp),%eax +c0105a55: 8d 50 04 lea 0x4(%eax),%edx +c0105a58: 89 55 14 mov %edx,0x14(%ebp) +c0105a5b: 8b 00 mov (%eax),%eax +c0105a5d: 89 45 f0 mov %eax,-0x10(%ebp) +c0105a60: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + base = 16; +c0105a67: c7 45 ec 10 00 00 00 movl $0x10,-0x14(%ebp) + goto number; +c0105a6e: eb 1f jmp c0105a8f + + // (unsigned) hexadecimal + case 'x': + num = getuint(&ap, lflag); +c0105a70: 8b 45 e0 mov -0x20(%ebp),%eax +c0105a73: 89 44 24 04 mov %eax,0x4(%esp) +c0105a77: 8d 45 14 lea 0x14(%ebp),%eax +c0105a7a: 89 04 24 mov %eax,(%esp) +c0105a7d: e8 ea fb ff ff call c010566c +c0105a82: 89 45 f0 mov %eax,-0x10(%ebp) +c0105a85: 89 55 f4 mov %edx,-0xc(%ebp) + base = 16; +c0105a88: c7 45 ec 10 00 00 00 movl $0x10,-0x14(%ebp) + number: + printnum(putch, putdat, num, base, width, padc); +c0105a8f: 0f be 55 db movsbl -0x25(%ebp),%edx +c0105a93: 8b 45 ec mov -0x14(%ebp),%eax +c0105a96: 89 54 24 18 mov %edx,0x18(%esp) +c0105a9a: 8b 55 e8 mov -0x18(%ebp),%edx +c0105a9d: 89 54 24 14 mov %edx,0x14(%esp) +c0105aa1: 89 44 24 10 mov %eax,0x10(%esp) +c0105aa5: 8b 45 f0 mov -0x10(%ebp),%eax +c0105aa8: 8b 55 f4 mov -0xc(%ebp),%edx +c0105aab: 89 44 24 08 mov %eax,0x8(%esp) +c0105aaf: 89 54 24 0c mov %edx,0xc(%esp) +c0105ab3: 8b 45 0c mov 0xc(%ebp),%eax +c0105ab6: 89 44 24 04 mov %eax,0x4(%esp) +c0105aba: 8b 45 08 mov 0x8(%ebp),%eax +c0105abd: 89 04 24 mov %eax,(%esp) +c0105ac0: e8 a5 fa ff ff call c010556a + break; +c0105ac5: eb 38 jmp c0105aff + + // escaped '%' character + case '%': + putch(ch, putdat); +c0105ac7: 8b 45 0c mov 0xc(%ebp),%eax +c0105aca: 89 44 24 04 mov %eax,0x4(%esp) +c0105ace: 89 1c 24 mov %ebx,(%esp) +c0105ad1: 8b 45 08 mov 0x8(%ebp),%eax +c0105ad4: ff d0 call *%eax + break; +c0105ad6: eb 27 jmp c0105aff + + // unrecognized escape sequence - just print it literally + default: + putch('%', putdat); +c0105ad8: 8b 45 0c mov 0xc(%ebp),%eax +c0105adb: 89 44 24 04 mov %eax,0x4(%esp) +c0105adf: c7 04 24 25 00 00 00 movl $0x25,(%esp) +c0105ae6: 8b 45 08 mov 0x8(%ebp),%eax +c0105ae9: ff d0 call *%eax + for (fmt --; fmt[-1] != '%'; fmt --) +c0105aeb: ff 4d 10 decl 0x10(%ebp) +c0105aee: eb 03 jmp c0105af3 +c0105af0: ff 4d 10 decl 0x10(%ebp) +c0105af3: 8b 45 10 mov 0x10(%ebp),%eax +c0105af6: 48 dec %eax +c0105af7: 0f b6 00 movzbl (%eax),%eax +c0105afa: 3c 25 cmp $0x25,%al +c0105afc: 75 f2 jne c0105af0 + /* do nothing */; + break; +c0105afe: 90 nop + while (1) { +c0105aff: e9 37 fc ff ff jmp c010573b + return; +c0105b04: 90 nop + } + } +} +c0105b05: 83 c4 40 add $0x40,%esp +c0105b08: 5b pop %ebx +c0105b09: 5e pop %esi +c0105b0a: 5d pop %ebp +c0105b0b: c3 ret + +c0105b0c : + * 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) { +c0105b0c: 55 push %ebp +c0105b0d: 89 e5 mov %esp,%ebp + b->cnt ++; +c0105b0f: 8b 45 0c mov 0xc(%ebp),%eax +c0105b12: 8b 40 08 mov 0x8(%eax),%eax +c0105b15: 8d 50 01 lea 0x1(%eax),%edx +c0105b18: 8b 45 0c mov 0xc(%ebp),%eax +c0105b1b: 89 50 08 mov %edx,0x8(%eax) + if (b->buf < b->ebuf) { +c0105b1e: 8b 45 0c mov 0xc(%ebp),%eax +c0105b21: 8b 10 mov (%eax),%edx +c0105b23: 8b 45 0c mov 0xc(%ebp),%eax +c0105b26: 8b 40 04 mov 0x4(%eax),%eax +c0105b29: 39 c2 cmp %eax,%edx +c0105b2b: 73 12 jae c0105b3f + *b->buf ++ = ch; +c0105b2d: 8b 45 0c mov 0xc(%ebp),%eax +c0105b30: 8b 00 mov (%eax),%eax +c0105b32: 8d 48 01 lea 0x1(%eax),%ecx +c0105b35: 8b 55 0c mov 0xc(%ebp),%edx +c0105b38: 89 0a mov %ecx,(%edx) +c0105b3a: 8b 55 08 mov 0x8(%ebp),%edx +c0105b3d: 88 10 mov %dl,(%eax) + } +} +c0105b3f: 90 nop +c0105b40: 5d pop %ebp +c0105b41: c3 ret + +c0105b42 : + * @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, ...) { +c0105b42: 55 push %ebp +c0105b43: 89 e5 mov %esp,%ebp +c0105b45: 83 ec 28 sub $0x28,%esp + va_list ap; + int cnt; + va_start(ap, fmt); +c0105b48: 8d 45 14 lea 0x14(%ebp),%eax +c0105b4b: 89 45 f0 mov %eax,-0x10(%ebp) + cnt = vsnprintf(str, size, fmt, ap); +c0105b4e: 8b 45 f0 mov -0x10(%ebp),%eax +c0105b51: 89 44 24 0c mov %eax,0xc(%esp) +c0105b55: 8b 45 10 mov 0x10(%ebp),%eax +c0105b58: 89 44 24 08 mov %eax,0x8(%esp) +c0105b5c: 8b 45 0c mov 0xc(%ebp),%eax +c0105b5f: 89 44 24 04 mov %eax,0x4(%esp) +c0105b63: 8b 45 08 mov 0x8(%ebp),%eax +c0105b66: 89 04 24 mov %eax,(%esp) +c0105b69: e8 0a 00 00 00 call c0105b78 +c0105b6e: 89 45 f4 mov %eax,-0xc(%ebp) + va_end(ap); + return cnt; +c0105b71: 8b 45 f4 mov -0xc(%ebp),%eax +} +c0105b74: 89 ec mov %ebp,%esp +c0105b76: 5d pop %ebp +c0105b77: c3 ret + +c0105b78 : + * + * 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) { +c0105b78: 55 push %ebp +c0105b79: 89 e5 mov %esp,%ebp +c0105b7b: 83 ec 28 sub $0x28,%esp + struct sprintbuf b = {str, str + size - 1, 0}; +c0105b7e: 8b 45 08 mov 0x8(%ebp),%eax +c0105b81: 89 45 ec mov %eax,-0x14(%ebp) +c0105b84: 8b 45 0c mov 0xc(%ebp),%eax +c0105b87: 8d 50 ff lea -0x1(%eax),%edx +c0105b8a: 8b 45 08 mov 0x8(%ebp),%eax +c0105b8d: 01 d0 add %edx,%eax +c0105b8f: 89 45 f0 mov %eax,-0x10(%ebp) +c0105b92: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + if (str == NULL || b.buf > b.ebuf) { +c0105b99: 83 7d 08 00 cmpl $0x0,0x8(%ebp) +c0105b9d: 74 0a je c0105ba9 +c0105b9f: 8b 55 ec mov -0x14(%ebp),%edx +c0105ba2: 8b 45 f0 mov -0x10(%ebp),%eax +c0105ba5: 39 c2 cmp %eax,%edx +c0105ba7: 76 07 jbe c0105bb0 + return -E_INVAL; +c0105ba9: b8 fd ff ff ff mov $0xfffffffd,%eax +c0105bae: eb 2a jmp c0105bda + } + // print the string to the buffer + vprintfmt((void*)sprintputch, &b, fmt, ap); +c0105bb0: 8b 45 14 mov 0x14(%ebp),%eax +c0105bb3: 89 44 24 0c mov %eax,0xc(%esp) +c0105bb7: 8b 45 10 mov 0x10(%ebp),%eax +c0105bba: 89 44 24 08 mov %eax,0x8(%esp) +c0105bbe: 8d 45 ec lea -0x14(%ebp),%eax +c0105bc1: 89 44 24 04 mov %eax,0x4(%esp) +c0105bc5: c7 04 24 0c 5b 10 c0 movl $0xc0105b0c,(%esp) +c0105bcc: e8 62 fb ff ff call c0105733 + // null terminate the buffer + *b.buf = '\0'; +c0105bd1: 8b 45 ec mov -0x14(%ebp),%eax +c0105bd4: c6 00 00 movb $0x0,(%eax) + return b.cnt; +c0105bd7: 8b 45 f4 mov -0xc(%ebp),%eax +} +c0105bda: 89 ec mov %ebp,%esp +c0105bdc: 5d pop %ebp +c0105bdd: c3 ret + +c0105bde : + * @s: the input string + * + * The strlen() function returns the length of string @s. + * */ +size_t +strlen(const char *s) { +c0105bde: 55 push %ebp +c0105bdf: 89 e5 mov %esp,%ebp +c0105be1: 83 ec 10 sub $0x10,%esp + size_t cnt = 0; +c0105be4: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + while (*s ++ != '\0') { +c0105beb: eb 03 jmp c0105bf0 + cnt ++; +c0105bed: ff 45 fc incl -0x4(%ebp) + while (*s ++ != '\0') { +c0105bf0: 8b 45 08 mov 0x8(%ebp),%eax +c0105bf3: 8d 50 01 lea 0x1(%eax),%edx +c0105bf6: 89 55 08 mov %edx,0x8(%ebp) +c0105bf9: 0f b6 00 movzbl (%eax),%eax +c0105bfc: 84 c0 test %al,%al +c0105bfe: 75 ed jne c0105bed + } + return cnt; +c0105c00: 8b 45 fc mov -0x4(%ebp),%eax +} +c0105c03: 89 ec mov %ebp,%esp +c0105c05: 5d pop %ebp +c0105c06: c3 ret + +c0105c07 : + * 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) { +c0105c07: 55 push %ebp +c0105c08: 89 e5 mov %esp,%ebp +c0105c0a: 83 ec 10 sub $0x10,%esp + size_t cnt = 0; +c0105c0d: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + while (cnt < len && *s ++ != '\0') { +c0105c14: eb 03 jmp c0105c19 + cnt ++; +c0105c16: ff 45 fc incl -0x4(%ebp) + while (cnt < len && *s ++ != '\0') { +c0105c19: 8b 45 fc mov -0x4(%ebp),%eax +c0105c1c: 3b 45 0c cmp 0xc(%ebp),%eax +c0105c1f: 73 10 jae c0105c31 +c0105c21: 8b 45 08 mov 0x8(%ebp),%eax +c0105c24: 8d 50 01 lea 0x1(%eax),%edx +c0105c27: 89 55 08 mov %edx,0x8(%ebp) +c0105c2a: 0f b6 00 movzbl (%eax),%eax +c0105c2d: 84 c0 test %al,%al +c0105c2f: 75 e5 jne c0105c16 + } + return cnt; +c0105c31: 8b 45 fc mov -0x4(%ebp),%eax +} +c0105c34: 89 ec mov %ebp,%esp +c0105c36: 5d pop %ebp +c0105c37: c3 ret + +c0105c38 : + * 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) { +c0105c38: 55 push %ebp +c0105c39: 89 e5 mov %esp,%ebp +c0105c3b: 57 push %edi +c0105c3c: 56 push %esi +c0105c3d: 83 ec 20 sub $0x20,%esp +c0105c40: 8b 45 08 mov 0x8(%ebp),%eax +c0105c43: 89 45 f4 mov %eax,-0xc(%ebp) +c0105c46: 8b 45 0c mov 0xc(%ebp),%eax +c0105c49: 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 ( +c0105c4c: 8b 55 f0 mov -0x10(%ebp),%edx +c0105c4f: 8b 45 f4 mov -0xc(%ebp),%eax +c0105c52: 89 d1 mov %edx,%ecx +c0105c54: 89 c2 mov %eax,%edx +c0105c56: 89 ce mov %ecx,%esi +c0105c58: 89 d7 mov %edx,%edi +c0105c5a: ac lods %ds:(%esi),%al +c0105c5b: aa stos %al,%es:(%edi) +c0105c5c: 84 c0 test %al,%al +c0105c5e: 75 fa jne c0105c5a +c0105c60: 89 fa mov %edi,%edx +c0105c62: 89 f1 mov %esi,%ecx +c0105c64: 89 4d ec mov %ecx,-0x14(%ebp) +c0105c67: 89 55 e8 mov %edx,-0x18(%ebp) +c0105c6a: 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; +c0105c6d: 8b 45 f4 mov -0xc(%ebp),%eax + char *p = dst; + while ((*p ++ = *src ++) != '\0') + /* nothing */; + return dst; +#endif /* __HAVE_ARCH_STRCPY */ +} +c0105c70: 83 c4 20 add $0x20,%esp +c0105c73: 5e pop %esi +c0105c74: 5f pop %edi +c0105c75: 5d pop %ebp +c0105c76: c3 ret + +c0105c77 : + * @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) { +c0105c77: 55 push %ebp +c0105c78: 89 e5 mov %esp,%ebp +c0105c7a: 83 ec 10 sub $0x10,%esp + char *p = dst; +c0105c7d: 8b 45 08 mov 0x8(%ebp),%eax +c0105c80: 89 45 fc mov %eax,-0x4(%ebp) + while (len > 0) { +c0105c83: eb 1e jmp c0105ca3 + if ((*p = *src) != '\0') { +c0105c85: 8b 45 0c mov 0xc(%ebp),%eax +c0105c88: 0f b6 10 movzbl (%eax),%edx +c0105c8b: 8b 45 fc mov -0x4(%ebp),%eax +c0105c8e: 88 10 mov %dl,(%eax) +c0105c90: 8b 45 fc mov -0x4(%ebp),%eax +c0105c93: 0f b6 00 movzbl (%eax),%eax +c0105c96: 84 c0 test %al,%al +c0105c98: 74 03 je c0105c9d + src ++; +c0105c9a: ff 45 0c incl 0xc(%ebp) + } + p ++, len --; +c0105c9d: ff 45 fc incl -0x4(%ebp) +c0105ca0: ff 4d 10 decl 0x10(%ebp) + while (len > 0) { +c0105ca3: 83 7d 10 00 cmpl $0x0,0x10(%ebp) +c0105ca7: 75 dc jne c0105c85 + } + return dst; +c0105ca9: 8b 45 08 mov 0x8(%ebp),%eax +} +c0105cac: 89 ec mov %ebp,%esp +c0105cae: 5d pop %ebp +c0105caf: c3 ret + +c0105cb0 : + * - 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) { +c0105cb0: 55 push %ebp +c0105cb1: 89 e5 mov %esp,%ebp +c0105cb3: 57 push %edi +c0105cb4: 56 push %esi +c0105cb5: 83 ec 20 sub $0x20,%esp +c0105cb8: 8b 45 08 mov 0x8(%ebp),%eax +c0105cbb: 89 45 f4 mov %eax,-0xc(%ebp) +c0105cbe: 8b 45 0c mov 0xc(%ebp),%eax +c0105cc1: 89 45 f0 mov %eax,-0x10(%ebp) + asm volatile ( +c0105cc4: 8b 55 f4 mov -0xc(%ebp),%edx +c0105cc7: 8b 45 f0 mov -0x10(%ebp),%eax +c0105cca: 89 d1 mov %edx,%ecx +c0105ccc: 89 c2 mov %eax,%edx +c0105cce: 89 ce mov %ecx,%esi +c0105cd0: 89 d7 mov %edx,%edi +c0105cd2: ac lods %ds:(%esi),%al +c0105cd3: ae scas %es:(%edi),%al +c0105cd4: 75 08 jne c0105cde +c0105cd6: 84 c0 test %al,%al +c0105cd8: 75 f8 jne c0105cd2 +c0105cda: 31 c0 xor %eax,%eax +c0105cdc: eb 04 jmp c0105ce2 +c0105cde: 19 c0 sbb %eax,%eax +c0105ce0: 0c 01 or $0x1,%al +c0105ce2: 89 fa mov %edi,%edx +c0105ce4: 89 f1 mov %esi,%ecx +c0105ce6: 89 45 ec mov %eax,-0x14(%ebp) +c0105ce9: 89 4d e8 mov %ecx,-0x18(%ebp) +c0105cec: 89 55 e4 mov %edx,-0x1c(%ebp) + return ret; +c0105cef: 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 */ +} +c0105cf2: 83 c4 20 add $0x20,%esp +c0105cf5: 5e pop %esi +c0105cf6: 5f pop %edi +c0105cf7: 5d pop %ebp +c0105cf8: c3 ret + +c0105cf9 : + * 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) { +c0105cf9: 55 push %ebp +c0105cfa: 89 e5 mov %esp,%ebp + while (n > 0 && *s1 != '\0' && *s1 == *s2) { +c0105cfc: eb 09 jmp c0105d07 + n --, s1 ++, s2 ++; +c0105cfe: ff 4d 10 decl 0x10(%ebp) +c0105d01: ff 45 08 incl 0x8(%ebp) +c0105d04: ff 45 0c incl 0xc(%ebp) + while (n > 0 && *s1 != '\0' && *s1 == *s2) { +c0105d07: 83 7d 10 00 cmpl $0x0,0x10(%ebp) +c0105d0b: 74 1a je c0105d27 +c0105d0d: 8b 45 08 mov 0x8(%ebp),%eax +c0105d10: 0f b6 00 movzbl (%eax),%eax +c0105d13: 84 c0 test %al,%al +c0105d15: 74 10 je c0105d27 +c0105d17: 8b 45 08 mov 0x8(%ebp),%eax +c0105d1a: 0f b6 10 movzbl (%eax),%edx +c0105d1d: 8b 45 0c mov 0xc(%ebp),%eax +c0105d20: 0f b6 00 movzbl (%eax),%eax +c0105d23: 38 c2 cmp %al,%dl +c0105d25: 74 d7 je c0105cfe + } + return (n == 0) ? 0 : (int)((unsigned char)*s1 - (unsigned char)*s2); +c0105d27: 83 7d 10 00 cmpl $0x0,0x10(%ebp) +c0105d2b: 74 18 je c0105d45 +c0105d2d: 8b 45 08 mov 0x8(%ebp),%eax +c0105d30: 0f b6 00 movzbl (%eax),%eax +c0105d33: 0f b6 d0 movzbl %al,%edx +c0105d36: 8b 45 0c mov 0xc(%ebp),%eax +c0105d39: 0f b6 00 movzbl (%eax),%eax +c0105d3c: 0f b6 c8 movzbl %al,%ecx +c0105d3f: 89 d0 mov %edx,%eax +c0105d41: 29 c8 sub %ecx,%eax +c0105d43: eb 05 jmp c0105d4a +c0105d45: b8 00 00 00 00 mov $0x0,%eax +} +c0105d4a: 5d pop %ebp +c0105d4b: c3 ret + +c0105d4c : + * + * 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) { +c0105d4c: 55 push %ebp +c0105d4d: 89 e5 mov %esp,%ebp +c0105d4f: 83 ec 04 sub $0x4,%esp +c0105d52: 8b 45 0c mov 0xc(%ebp),%eax +c0105d55: 88 45 fc mov %al,-0x4(%ebp) + while (*s != '\0') { +c0105d58: eb 13 jmp c0105d6d + if (*s == c) { +c0105d5a: 8b 45 08 mov 0x8(%ebp),%eax +c0105d5d: 0f b6 00 movzbl (%eax),%eax +c0105d60: 38 45 fc cmp %al,-0x4(%ebp) +c0105d63: 75 05 jne c0105d6a + return (char *)s; +c0105d65: 8b 45 08 mov 0x8(%ebp),%eax +c0105d68: eb 12 jmp c0105d7c + } + s ++; +c0105d6a: ff 45 08 incl 0x8(%ebp) + while (*s != '\0') { +c0105d6d: 8b 45 08 mov 0x8(%ebp),%eax +c0105d70: 0f b6 00 movzbl (%eax),%eax +c0105d73: 84 c0 test %al,%al +c0105d75: 75 e3 jne c0105d5a + } + return NULL; +c0105d77: b8 00 00 00 00 mov $0x0,%eax +} +c0105d7c: 89 ec mov %ebp,%esp +c0105d7e: 5d pop %ebp +c0105d7f: c3 ret + +c0105d80 : + * 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) { +c0105d80: 55 push %ebp +c0105d81: 89 e5 mov %esp,%ebp +c0105d83: 83 ec 04 sub $0x4,%esp +c0105d86: 8b 45 0c mov 0xc(%ebp),%eax +c0105d89: 88 45 fc mov %al,-0x4(%ebp) + while (*s != '\0') { +c0105d8c: eb 0e jmp c0105d9c + if (*s == c) { +c0105d8e: 8b 45 08 mov 0x8(%ebp),%eax +c0105d91: 0f b6 00 movzbl (%eax),%eax +c0105d94: 38 45 fc cmp %al,-0x4(%ebp) +c0105d97: 74 0f je c0105da8 + break; + } + s ++; +c0105d99: ff 45 08 incl 0x8(%ebp) + while (*s != '\0') { +c0105d9c: 8b 45 08 mov 0x8(%ebp),%eax +c0105d9f: 0f b6 00 movzbl (%eax),%eax +c0105da2: 84 c0 test %al,%al +c0105da4: 75 e8 jne c0105d8e +c0105da6: eb 01 jmp c0105da9 + break; +c0105da8: 90 nop + } + return (char *)s; +c0105da9: 8b 45 08 mov 0x8(%ebp),%eax +} +c0105dac: 89 ec mov %ebp,%esp +c0105dae: 5d pop %ebp +c0105daf: c3 ret + +c0105db0 : + * 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) { +c0105db0: 55 push %ebp +c0105db1: 89 e5 mov %esp,%ebp +c0105db3: 83 ec 10 sub $0x10,%esp + int neg = 0; +c0105db6: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + long val = 0; +c0105dbd: c7 45 f8 00 00 00 00 movl $0x0,-0x8(%ebp) + + // gobble initial whitespace + while (*s == ' ' || *s == '\t') { +c0105dc4: eb 03 jmp c0105dc9 + s ++; +c0105dc6: ff 45 08 incl 0x8(%ebp) + while (*s == ' ' || *s == '\t') { +c0105dc9: 8b 45 08 mov 0x8(%ebp),%eax +c0105dcc: 0f b6 00 movzbl (%eax),%eax +c0105dcf: 3c 20 cmp $0x20,%al +c0105dd1: 74 f3 je c0105dc6 +c0105dd3: 8b 45 08 mov 0x8(%ebp),%eax +c0105dd6: 0f b6 00 movzbl (%eax),%eax +c0105dd9: 3c 09 cmp $0x9,%al +c0105ddb: 74 e9 je c0105dc6 + } + + // plus/minus sign + if (*s == '+') { +c0105ddd: 8b 45 08 mov 0x8(%ebp),%eax +c0105de0: 0f b6 00 movzbl (%eax),%eax +c0105de3: 3c 2b cmp $0x2b,%al +c0105de5: 75 05 jne c0105dec + s ++; +c0105de7: ff 45 08 incl 0x8(%ebp) +c0105dea: eb 14 jmp c0105e00 + } + else if (*s == '-') { +c0105dec: 8b 45 08 mov 0x8(%ebp),%eax +c0105def: 0f b6 00 movzbl (%eax),%eax +c0105df2: 3c 2d cmp $0x2d,%al +c0105df4: 75 0a jne c0105e00 + s ++, neg = 1; +c0105df6: ff 45 08 incl 0x8(%ebp) +c0105df9: 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')) { +c0105e00: 83 7d 10 00 cmpl $0x0,0x10(%ebp) +c0105e04: 74 06 je c0105e0c +c0105e06: 83 7d 10 10 cmpl $0x10,0x10(%ebp) +c0105e0a: 75 22 jne c0105e2e +c0105e0c: 8b 45 08 mov 0x8(%ebp),%eax +c0105e0f: 0f b6 00 movzbl (%eax),%eax +c0105e12: 3c 30 cmp $0x30,%al +c0105e14: 75 18 jne c0105e2e +c0105e16: 8b 45 08 mov 0x8(%ebp),%eax +c0105e19: 40 inc %eax +c0105e1a: 0f b6 00 movzbl (%eax),%eax +c0105e1d: 3c 78 cmp $0x78,%al +c0105e1f: 75 0d jne c0105e2e + s += 2, base = 16; +c0105e21: 83 45 08 02 addl $0x2,0x8(%ebp) +c0105e25: c7 45 10 10 00 00 00 movl $0x10,0x10(%ebp) +c0105e2c: eb 29 jmp c0105e57 + } + else if (base == 0 && s[0] == '0') { +c0105e2e: 83 7d 10 00 cmpl $0x0,0x10(%ebp) +c0105e32: 75 16 jne c0105e4a +c0105e34: 8b 45 08 mov 0x8(%ebp),%eax +c0105e37: 0f b6 00 movzbl (%eax),%eax +c0105e3a: 3c 30 cmp $0x30,%al +c0105e3c: 75 0c jne c0105e4a + s ++, base = 8; +c0105e3e: ff 45 08 incl 0x8(%ebp) +c0105e41: c7 45 10 08 00 00 00 movl $0x8,0x10(%ebp) +c0105e48: eb 0d jmp c0105e57 + } + else if (base == 0) { +c0105e4a: 83 7d 10 00 cmpl $0x0,0x10(%ebp) +c0105e4e: 75 07 jne c0105e57 + base = 10; +c0105e50: c7 45 10 0a 00 00 00 movl $0xa,0x10(%ebp) + + // digits + while (1) { + int dig; + + if (*s >= '0' && *s <= '9') { +c0105e57: 8b 45 08 mov 0x8(%ebp),%eax +c0105e5a: 0f b6 00 movzbl (%eax),%eax +c0105e5d: 3c 2f cmp $0x2f,%al +c0105e5f: 7e 1b jle c0105e7c +c0105e61: 8b 45 08 mov 0x8(%ebp),%eax +c0105e64: 0f b6 00 movzbl (%eax),%eax +c0105e67: 3c 39 cmp $0x39,%al +c0105e69: 7f 11 jg c0105e7c + dig = *s - '0'; +c0105e6b: 8b 45 08 mov 0x8(%ebp),%eax +c0105e6e: 0f b6 00 movzbl (%eax),%eax +c0105e71: 0f be c0 movsbl %al,%eax +c0105e74: 83 e8 30 sub $0x30,%eax +c0105e77: 89 45 f4 mov %eax,-0xc(%ebp) +c0105e7a: eb 48 jmp c0105ec4 + } + else if (*s >= 'a' && *s <= 'z') { +c0105e7c: 8b 45 08 mov 0x8(%ebp),%eax +c0105e7f: 0f b6 00 movzbl (%eax),%eax +c0105e82: 3c 60 cmp $0x60,%al +c0105e84: 7e 1b jle c0105ea1 +c0105e86: 8b 45 08 mov 0x8(%ebp),%eax +c0105e89: 0f b6 00 movzbl (%eax),%eax +c0105e8c: 3c 7a cmp $0x7a,%al +c0105e8e: 7f 11 jg c0105ea1 + dig = *s - 'a' + 10; +c0105e90: 8b 45 08 mov 0x8(%ebp),%eax +c0105e93: 0f b6 00 movzbl (%eax),%eax +c0105e96: 0f be c0 movsbl %al,%eax +c0105e99: 83 e8 57 sub $0x57,%eax +c0105e9c: 89 45 f4 mov %eax,-0xc(%ebp) +c0105e9f: eb 23 jmp c0105ec4 + } + else if (*s >= 'A' && *s <= 'Z') { +c0105ea1: 8b 45 08 mov 0x8(%ebp),%eax +c0105ea4: 0f b6 00 movzbl (%eax),%eax +c0105ea7: 3c 40 cmp $0x40,%al +c0105ea9: 7e 3b jle c0105ee6 +c0105eab: 8b 45 08 mov 0x8(%ebp),%eax +c0105eae: 0f b6 00 movzbl (%eax),%eax +c0105eb1: 3c 5a cmp $0x5a,%al +c0105eb3: 7f 31 jg c0105ee6 + dig = *s - 'A' + 10; +c0105eb5: 8b 45 08 mov 0x8(%ebp),%eax +c0105eb8: 0f b6 00 movzbl (%eax),%eax +c0105ebb: 0f be c0 movsbl %al,%eax +c0105ebe: 83 e8 37 sub $0x37,%eax +c0105ec1: 89 45 f4 mov %eax,-0xc(%ebp) + } + else { + break; + } + if (dig >= base) { +c0105ec4: 8b 45 f4 mov -0xc(%ebp),%eax +c0105ec7: 3b 45 10 cmp 0x10(%ebp),%eax +c0105eca: 7d 19 jge c0105ee5 + break; + } + s ++, val = (val * base) + dig; +c0105ecc: ff 45 08 incl 0x8(%ebp) +c0105ecf: 8b 45 f8 mov -0x8(%ebp),%eax +c0105ed2: 0f af 45 10 imul 0x10(%ebp),%eax +c0105ed6: 89 c2 mov %eax,%edx +c0105ed8: 8b 45 f4 mov -0xc(%ebp),%eax +c0105edb: 01 d0 add %edx,%eax +c0105edd: 89 45 f8 mov %eax,-0x8(%ebp) + while (1) { +c0105ee0: e9 72 ff ff ff jmp c0105e57 + break; +c0105ee5: 90 nop + // we don't properly detect overflow! + } + + if (endptr) { +c0105ee6: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) +c0105eea: 74 08 je c0105ef4 + *endptr = (char *) s; +c0105eec: 8b 45 0c mov 0xc(%ebp),%eax +c0105eef: 8b 55 08 mov 0x8(%ebp),%edx +c0105ef2: 89 10 mov %edx,(%eax) + } + return (neg ? -val : val); +c0105ef4: 83 7d fc 00 cmpl $0x0,-0x4(%ebp) +c0105ef8: 74 07 je c0105f01 +c0105efa: 8b 45 f8 mov -0x8(%ebp),%eax +c0105efd: f7 d8 neg %eax +c0105eff: eb 03 jmp c0105f04 +c0105f01: 8b 45 f8 mov -0x8(%ebp),%eax +} +c0105f04: 89 ec mov %ebp,%esp +c0105f06: 5d pop %ebp +c0105f07: c3 ret + +c0105f08 : + * @n: number of bytes to be set to the value + * + * The memset() function returns @s. + * */ +void * +memset(void *s, char c, size_t n) { +c0105f08: 55 push %ebp +c0105f09: 89 e5 mov %esp,%ebp +c0105f0b: 83 ec 28 sub $0x28,%esp +c0105f0e: 89 7d fc mov %edi,-0x4(%ebp) +c0105f11: 8b 45 0c mov 0xc(%ebp),%eax +c0105f14: 88 45 d8 mov %al,-0x28(%ebp) +#ifdef __HAVE_ARCH_MEMSET + return __memset(s, c, n); +c0105f17: 0f be 55 d8 movsbl -0x28(%ebp),%edx +c0105f1b: 8b 45 08 mov 0x8(%ebp),%eax +c0105f1e: 89 45 f8 mov %eax,-0x8(%ebp) +c0105f21: 88 55 f7 mov %dl,-0x9(%ebp) +c0105f24: 8b 45 10 mov 0x10(%ebp),%eax +c0105f27: 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 ( +c0105f2a: 8b 4d f0 mov -0x10(%ebp),%ecx +c0105f2d: 0f b6 45 f7 movzbl -0x9(%ebp),%eax +c0105f31: 8b 55 f8 mov -0x8(%ebp),%edx +c0105f34: 89 d7 mov %edx,%edi +c0105f36: f3 aa rep stos %al,%es:(%edi) +c0105f38: 89 fa mov %edi,%edx +c0105f3a: 89 4d ec mov %ecx,-0x14(%ebp) +c0105f3d: 89 55 e8 mov %edx,-0x18(%ebp) + "rep; stosb;" + : "=&c" (d0), "=&D" (d1) + : "0" (n), "a" (c), "1" (s) + : "memory"); + return s; +c0105f40: 8b 45 f8 mov -0x8(%ebp),%eax + while (n -- > 0) { + *p ++ = c; + } + return s; +#endif /* __HAVE_ARCH_MEMSET */ +} +c0105f43: 8b 7d fc mov -0x4(%ebp),%edi +c0105f46: 89 ec mov %ebp,%esp +c0105f48: 5d pop %ebp +c0105f49: c3 ret + +c0105f4a : + * @n: number of bytes to copy + * + * The memmove() function returns @dst. + * */ +void * +memmove(void *dst, const void *src, size_t n) { +c0105f4a: 55 push %ebp +c0105f4b: 89 e5 mov %esp,%ebp +c0105f4d: 57 push %edi +c0105f4e: 56 push %esi +c0105f4f: 53 push %ebx +c0105f50: 83 ec 30 sub $0x30,%esp +c0105f53: 8b 45 08 mov 0x8(%ebp),%eax +c0105f56: 89 45 f0 mov %eax,-0x10(%ebp) +c0105f59: 8b 45 0c mov 0xc(%ebp),%eax +c0105f5c: 89 45 ec mov %eax,-0x14(%ebp) +c0105f5f: 8b 45 10 mov 0x10(%ebp),%eax +c0105f62: 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) { +c0105f65: 8b 45 f0 mov -0x10(%ebp),%eax +c0105f68: 3b 45 ec cmp -0x14(%ebp),%eax +c0105f6b: 73 42 jae c0105faf +c0105f6d: 8b 45 f0 mov -0x10(%ebp),%eax +c0105f70: 89 45 e4 mov %eax,-0x1c(%ebp) +c0105f73: 8b 45 ec mov -0x14(%ebp),%eax +c0105f76: 89 45 e0 mov %eax,-0x20(%ebp) +c0105f79: 8b 45 e8 mov -0x18(%ebp),%eax +c0105f7c: 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) +c0105f7f: 8b 45 dc mov -0x24(%ebp),%eax +c0105f82: c1 e8 02 shr $0x2,%eax +c0105f85: 89 c1 mov %eax,%ecx + asm volatile ( +c0105f87: 8b 55 e4 mov -0x1c(%ebp),%edx +c0105f8a: 8b 45 e0 mov -0x20(%ebp),%eax +c0105f8d: 89 d7 mov %edx,%edi +c0105f8f: 89 c6 mov %eax,%esi +c0105f91: f3 a5 rep movsl %ds:(%esi),%es:(%edi) +c0105f93: 8b 4d dc mov -0x24(%ebp),%ecx +c0105f96: 83 e1 03 and $0x3,%ecx +c0105f99: 74 02 je c0105f9d +c0105f9b: f3 a4 rep movsb %ds:(%esi),%es:(%edi) +c0105f9d: 89 f0 mov %esi,%eax +c0105f9f: 89 fa mov %edi,%edx +c0105fa1: 89 4d d8 mov %ecx,-0x28(%ebp) +c0105fa4: 89 55 d4 mov %edx,-0x2c(%ebp) +c0105fa7: 89 45 d0 mov %eax,-0x30(%ebp) + : "memory"); + return dst; +c0105faa: 8b 45 e4 mov -0x1c(%ebp),%eax + return __memcpy(dst, src, n); +c0105fad: eb 36 jmp c0105fe5 + : "0" (n), "1" (n - 1 + src), "2" (n - 1 + dst) +c0105faf: 8b 45 e8 mov -0x18(%ebp),%eax +c0105fb2: 8d 50 ff lea -0x1(%eax),%edx +c0105fb5: 8b 45 ec mov -0x14(%ebp),%eax +c0105fb8: 01 c2 add %eax,%edx +c0105fba: 8b 45 e8 mov -0x18(%ebp),%eax +c0105fbd: 8d 48 ff lea -0x1(%eax),%ecx +c0105fc0: 8b 45 f0 mov -0x10(%ebp),%eax +c0105fc3: 8d 1c 01 lea (%ecx,%eax,1),%ebx + asm volatile ( +c0105fc6: 8b 45 e8 mov -0x18(%ebp),%eax +c0105fc9: 89 c1 mov %eax,%ecx +c0105fcb: 89 d8 mov %ebx,%eax +c0105fcd: 89 d6 mov %edx,%esi +c0105fcf: 89 c7 mov %eax,%edi +c0105fd1: fd std +c0105fd2: f3 a4 rep movsb %ds:(%esi),%es:(%edi) +c0105fd4: fc cld +c0105fd5: 89 f8 mov %edi,%eax +c0105fd7: 89 f2 mov %esi,%edx +c0105fd9: 89 4d cc mov %ecx,-0x34(%ebp) +c0105fdc: 89 55 c8 mov %edx,-0x38(%ebp) +c0105fdf: 89 45 c4 mov %eax,-0x3c(%ebp) + return dst; +c0105fe2: 8b 45 f0 mov -0x10(%ebp),%eax + *d ++ = *s ++; + } + } + return dst; +#endif /* __HAVE_ARCH_MEMMOVE */ +} +c0105fe5: 83 c4 30 add $0x30,%esp +c0105fe8: 5b pop %ebx +c0105fe9: 5e pop %esi +c0105fea: 5f pop %edi +c0105feb: 5d pop %ebp +c0105fec: c3 ret + +c0105fed : + * 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) { +c0105fed: 55 push %ebp +c0105fee: 89 e5 mov %esp,%ebp +c0105ff0: 57 push %edi +c0105ff1: 56 push %esi +c0105ff2: 83 ec 20 sub $0x20,%esp +c0105ff5: 8b 45 08 mov 0x8(%ebp),%eax +c0105ff8: 89 45 f4 mov %eax,-0xc(%ebp) +c0105ffb: 8b 45 0c mov 0xc(%ebp),%eax +c0105ffe: 89 45 f0 mov %eax,-0x10(%ebp) +c0106001: 8b 45 10 mov 0x10(%ebp),%eax +c0106004: 89 45 ec mov %eax,-0x14(%ebp) + : "0" (n / 4), "g" (n), "1" (dst), "2" (src) +c0106007: 8b 45 ec mov -0x14(%ebp),%eax +c010600a: c1 e8 02 shr $0x2,%eax +c010600d: 89 c1 mov %eax,%ecx + asm volatile ( +c010600f: 8b 55 f4 mov -0xc(%ebp),%edx +c0106012: 8b 45 f0 mov -0x10(%ebp),%eax +c0106015: 89 d7 mov %edx,%edi +c0106017: 89 c6 mov %eax,%esi +c0106019: f3 a5 rep movsl %ds:(%esi),%es:(%edi) +c010601b: 8b 4d ec mov -0x14(%ebp),%ecx +c010601e: 83 e1 03 and $0x3,%ecx +c0106021: 74 02 je c0106025 +c0106023: f3 a4 rep movsb %ds:(%esi),%es:(%edi) +c0106025: 89 f0 mov %esi,%eax +c0106027: 89 fa mov %edi,%edx +c0106029: 89 4d e8 mov %ecx,-0x18(%ebp) +c010602c: 89 55 e4 mov %edx,-0x1c(%ebp) +c010602f: 89 45 e0 mov %eax,-0x20(%ebp) + return dst; +c0106032: 8b 45 f4 mov -0xc(%ebp),%eax + while (n -- > 0) { + *d ++ = *s ++; + } + return dst; +#endif /* __HAVE_ARCH_MEMCPY */ +} +c0106035: 83 c4 20 add $0x20,%esp +c0106038: 5e pop %esi +c0106039: 5f pop %edi +c010603a: 5d pop %ebp +c010603b: c3 ret + +c010603c : + * 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) { +c010603c: 55 push %ebp +c010603d: 89 e5 mov %esp,%ebp +c010603f: 83 ec 10 sub $0x10,%esp + const char *s1 = (const char *)v1; +c0106042: 8b 45 08 mov 0x8(%ebp),%eax +c0106045: 89 45 fc mov %eax,-0x4(%ebp) + const char *s2 = (const char *)v2; +c0106048: 8b 45 0c mov 0xc(%ebp),%eax +c010604b: 89 45 f8 mov %eax,-0x8(%ebp) + while (n -- > 0) { +c010604e: eb 2e jmp c010607e + if (*s1 != *s2) { +c0106050: 8b 45 fc mov -0x4(%ebp),%eax +c0106053: 0f b6 10 movzbl (%eax),%edx +c0106056: 8b 45 f8 mov -0x8(%ebp),%eax +c0106059: 0f b6 00 movzbl (%eax),%eax +c010605c: 38 c2 cmp %al,%dl +c010605e: 74 18 je c0106078 + return (int)((unsigned char)*s1 - (unsigned char)*s2); +c0106060: 8b 45 fc mov -0x4(%ebp),%eax +c0106063: 0f b6 00 movzbl (%eax),%eax +c0106066: 0f b6 d0 movzbl %al,%edx +c0106069: 8b 45 f8 mov -0x8(%ebp),%eax +c010606c: 0f b6 00 movzbl (%eax),%eax +c010606f: 0f b6 c8 movzbl %al,%ecx +c0106072: 89 d0 mov %edx,%eax +c0106074: 29 c8 sub %ecx,%eax +c0106076: eb 18 jmp c0106090 + } + s1 ++, s2 ++; +c0106078: ff 45 fc incl -0x4(%ebp) +c010607b: ff 45 f8 incl -0x8(%ebp) + while (n -- > 0) { +c010607e: 8b 45 10 mov 0x10(%ebp),%eax +c0106081: 8d 50 ff lea -0x1(%eax),%edx +c0106084: 89 55 10 mov %edx,0x10(%ebp) +c0106087: 85 c0 test %eax,%eax +c0106089: 75 c5 jne c0106050 + } + return 0; +c010608b: b8 00 00 00 00 mov $0x0,%eax +} +c0106090: 89 ec mov %ebp,%esp +c0106092: 5d pop %ebp +c0106093: c3 ret diff --git a/labcodes/lab2/obj/kernel.sym b/labcodes/lab2/obj/kernel.sym new file mode 100644 index 0000000000000000000000000000000000000000..92622bfe96b98d88b0c0eecc3a1c873e19507e39 --- /dev/null +++ b/labcodes/lab2/obj/kernel.sym @@ -0,0 +1,461 @@ +00000000 entry.o +c010001e next +c0100034 spin +c011b000 __boot_pt1 +00000400 i +00000000 init.c +c010021b lab1_switch_test +c0100144 lab1_print_cur_status +c011c000 round.0 +c0100204 lab1_switch_to_user +c0100211 lab1_switch_to_kernel +00000000 readline.c +c011c020 buf +00000000 stdio.c +c010030e cputch +00000000 kdebug.c +c0100411 stab_binsearch +c01009c2 read_eip +00000000 kmonitor.c +c0119000 commands +c01009db parse +c0100a94 runcmd +00000000 panic.c +c011c420 is_panic +00000000 clock.c +00000000 console.c +c0100d6d __intr_save +c0100d99 __intr_restore +c0100daf delay +c011c440 crt_buf +c011c444 crt_pos +c011c446 addr_6845 +c0100dfa cga_init +c011c448 serial_exists +c0100ee2 serial_init +c0100fcf lpt_putc_sub +c010104d lpt_putc +c010108f cga_putc +c0101285 serial_putc_sub +c01012e1 serial_putc +c011c460 cons +c0101323 cons_intr +c0101372 serial_proc_data +c0119040 shiftcode +c0119140 togglecode +c0119240 normalmap +c0119340 shiftmap +c0119440 ctlmap +c0119540 charcode +c01013eb kbd_proc_data +c011c668 shift.0 +c0101572 kbd_intr +c0101589 kbd_init +00000000 intr.c +00000000 picirq.c +c0119550 irq_mask +c011c66c did_init +c0101694 pic_setmask +00000000 trap.c +c0101870 print_ticks +c011c6e0 idt +c0119560 idt_pd +c0101a04 trapname +c0106740 excnames.0 +c0119580 IA32flags +c0101cb7 trap_dispatch +00000000 default_pmm.c +c01029a9 page2ppn +c01029c2 page2pa +c01029da page_ref +c01029e4 set_page_ref +c01029f2 default_init +c0102a23 default_init_memmap +c0102b85 default_alloc_pages +c0102d01 default_free_pages +c0102fb9 default_nr_free_pages +c0102fc3 basic_check +c0103503 default_check +00000000 pmm.c +c0103b93 page2ppn +c0103bac page2pa +c0103bc4 pa2page +c0103c15 page2kva +c0103c6b pte2page +c0103cab pde2page +c0103cc5 page_ref +c0103ccf set_page_ref +c0103cdd page_ref_inc +c0103cf4 page_ref_dec +c0103d0b __intr_save +c0103d37 __intr_restore +c011cf20 ts +c0119a00 gdt +c0119a30 gdt_pd +c0103d4d lgdt +c0103d91 gdt_init +c0103e7d init_pmm_manager +c0103eb3 init_memmap +c0103f71 page_init +c0104333 boot_map_segment +c0104439 boot_alloc_page +c01048c2 check_alloc_page +c01048e3 check_pgdir +c0104f81 check_boot_pgdir +c01046fd page_remove_pte +c010530d perm2str +c011cf88 str.0 +c010534f get_pgtable_items +00000000 printfmt.c +c0107220 error_string +c010556a printnum +c010566c getuint +c01056bb getint +c0105b0c sprintputch +00000000 string.c +c0102901 vector242 +c0102358 vector119 +c0100889 print_kerninfo +c0102238 vector87 +c010222f vector86 +c010296d vector251 +c0105c38 strcpy +c010225c vector91 +c0102052 vector33 +c0102541 vector162 +c01027a5 vector213 +c01022f5 vector108 +c01020ac vector43 +c0100000 kern_entry +c0100c1f mon_backtrace +c0102565 vector165 +c0102655 vector185 +c0102334 vector115 +c0102373 vector122 +c01047a8 page_insert +c01024f9 vector156 +c0102925 vector245 +c0102685 vector189 +c0101f76 vector7 +c010214e vector61 +c0102001 vector24 +c0102310 vector111 +c0102709 vector200 +c0102184 vector67 +c0102421 vector138 +c01021c3 vector74 +c0105f4a memmove +c010212a vector57 +c0105b42 snprintf +c0101a4a print_trapframe +c01027b1 vector214 +c0105733 vprintfmt +c01022a4 vector99 +c01046a2 get_page +c0101f15 __alltraps +c0101613 cons_getc +c0102445 vector141 +c0100cfa is_kernel_panic +c01025b9 vector172 +c01009d5 print_stackframe +c01028f5 vector241 +c0102985 vector253 +c0101f52 vector3 +c0101f49 vector2 +c010284d vector227 +c0102781 vector210 +c0102829 vector224 +c010209a vector41 +c0100366 cprintf +c0101fe6 vector21 +c01025f5 vector177 +c010234f vector118 +c010219f vector70 +c0102196 vector69 +c01028c5 vector237 +c0102169 vector64 +c010201c vector27 +c01023d9 vector132 +c0102661 vector186 +c01027d5 vector217 +c0105fed memcpy +c0101f40 vector1 +c0102601 vector178 +c010207f vector38 +c01028d1 vector238 +c0100257 readline +c01023e5 vector133 +c01021ba vector73 +c0102469 vector144 +c0106bd0 vpd +c0100036 kern_init +c0102991 vector254 +c01022b6 vector101 +c010278d vector211 +c01025d1 vector174 +c010290d vector243 +c01023a9 vector128 +c0102202 vector81 +c0103f0f free_pages +c0101fa4 vector13 +c0105b78 vsnprintf +c01020f4 vector51 +c0101fbb vector16 +c011c000 edata +c01015a5 cons_init +c011cf0c pmm_manager +c01028e9 vector240 +c010210f vector54 +c0101fd4 vector19 +c0112aac __STAB_END__ +c0102265 vector92 +c0102919 vector244 +c0103d83 load_esp0 +c0102439 vector140 +c01020be vector45 +c01021f0 vector79 +c0102865 vector229 +c0102511 vector158 +c01016f1 pic_enable +c0102088 vector39 +c0102589 vector168 +c0102064 vector35 +c0102322 vector113 +c0112aad __STABSTR_BEGIN__ +c010238e vector125 +c0100c33 __panic +c01027c9 vector216 +c0102160 vector63 +c0102013 vector26 +c01013cb serial_intr +c01026b5 vector193 +c01026d9 vector196 +c01000ff grade_backtrace0 +c0102775 vector209 +c0101f5b vector4 +c01025a1 vector170 +c0102409 vector136 +c0101f8f vector10 +c0102751 vector206 +c010299d vector255 +c0102625 vector181 +c010213c vector59 +c010011c grade_backtrace +c0102226 vector85 +c010221d vector84 +c010263d vector183 +c010251d vector159 +c0102799 vector212 +c01020d0 vector47 +c0105db0 strtol +c0102859 vector228 +c01020a3 vector42 +c010232b vector114 +c0105c07 strnlen +c01025dd vector175 +c010245d vector143 +c01023c1 vector130 +c0106b38 default_pmm_manager +c0102931 vector246 +c0101f86 vector9 +c0102451 vector142 +c01022ad vector100 +c0102715 vector201 +c010188f idt_init +c010091d print_debuginfo +c0102145 vector60 +c0101ff8 vector23 +c01028b9 vector236 +c011cf04 npage +c010287d vector231 +c010217b vector66 +c010202e vector29 +c0105403 print_pgdir +c01023fd vector135 +c0100b4c kmonitor +c01021de vector77 +c0102619 vector180 +c0100d04 clock_init +c0102769 vector208 +c010229b vector98 +c0102292 vector97 +c0103f44 nr_free_pages +c01025e9 vector176 +c01026c1 vector194 +c0102049 vector32 +c011cf08 boot_cr3 +c011cf8c end +c01026fd vector199 +c01023cd vector131 +c0102979 vector252 +c0101f37 vector0 +c0105d80 strfind +c01015d4 cons_putc +c0106094 etext +c0102475 vector145 +c01022ec vector107 +c01199e0 boot_pgdir +c0102091 vector40 +c0101684 intr_enable +c01022bf vector102 +c0102121 vector56 +c010218d vector68 +c0101f6d vector6 +c01023b5 vector129 +c01026e5 vector197 +c01024c9 vector152 +c01195e0 __vectors +c0102871 vector230 +c0105cf9 strncmp +c0104567 get_pte +c0102076 vector37 +c0102745 vector205 +c0102535 vector161 +c0105c77 strncpy +c01021a8 vector71 +c0102529 vector160 +c01027bd vector215 +c0102505 vector157 +c010168c intr_disable +c0101bfd print_regs +c0102319 vector112 +c01000a7 grade_backtrace2 +c0102631 vector182 +c0101f9d vector12 +c010603c memcmp +c01022fe vector109 +c0101fdd vector20 +c0102106 vector53 +c0101fcb vector18 +c0102280 vector95 +c0102841 vector226 +c01020e2 vector49 +c01020b5 vector44 +c01021e7 vector78 +c01025c5 vector173 +c0102346 vector117 +c0101a35 trap_in_kernel +c010220b vector82 +c0102811 vector222 +c0101f7f vector8 +c01024a5 vector149 +c010038e cputchar +c0105f08 memset +c0102889 vector232 +c01022e3 vector106 +c01027f9 vector220 +c0102253 vector90 +c010254d vector163 +c01028a1 vector234 +c0102157 vector62 +c010200a vector25 +c01026f1 vector198 +c0102361 vector120 +c01003f5 getchar +c0104761 page_remove +c01020eb vector50 +c0101fb2 vector15 +c0105702 printfmt +c01024bd vector151 +c0102214 vector83 +c010224a vector89 +c0102241 vector88 +c0101eff trap +c010260d vector179 +c010205b vector34 +c0116044 __STABSTR_END__ +c01020c7 vector46 +c0105cb0 strcmp +c01023f1 vector134 +c010281d vector223 +c01027e1 vector218 +c0100561 debuginfo_eip +c0101726 pic_init +c0102835 vector225 +c010266d vector187 +c010447f pmm_init +c0102037 vector30 +c01023a0 vector127 +c011c424 ticks +c01026a9 vector192 +c0102571 vector166 +c01021d5 vector76 +c01021cc vector75 +c01026cd vector195 +c01024b1 vector150 +c0102133 vector58 +c0102949 vector248 +c010237c vector123 +c0102289 vector96 +c0102040 vector31 +c010272d vector203 +c0103ed5 alloc_pages +c010242d vector139 +c01024d5 vector153 +c0102559 vector164 +c010236a vector121 +c011c680 switchk2u +c0101f64 vector5 +c010257d vector167 +c01024ed vector155 +c0102955 vector249 +c0106bcc vpt +c0102961 vector250 +c0102385 vector124 +c0102307 vector110 +c0102739 vector204 +c0101f2c __trapret +c0100331 vcprintf +c0102415 vector137 +c0100cb1 __warn +c010293d vector247 +c0101fef vector22 +c0102721 vector202 +c01021b1 vector72 +c0102118 vector55 +c01003a4 cputs +c0119000 bootstacktop +c0102397 vector126 +c0102172 vector65 +c0102025 vector28 +c0102595 vector169 +c0102895 vector233 +c010248d vector147 +c0117000 bootstack +c011a000 __boot_pgdir +c01022d1 vector104 +c011cee0 free_area +c010233d vector116 +c01073b8 __STAB_BEGIN__ +c01020fd vector52 +c0101fc4 vector17 +c0102649 vector184 +c0105bde strlen +c010275d vector207 +c0102691 vector190 +c01028dd vector239 +c0102277 vector94 +c010226e vector93 +c0102679 vector188 +c0105d4c strchr +c01020d9 vector48 +c01000ce grade_backtrace1 +c01027ed vector219 +c0102499 vector148 +c0102805 vector221 +c01021f9 vector80 +c01025ad vector171 +c01024e1 vector154 +c010206d vector36 +c011c6cc switchu2k +c01028ad vector235 +c01022da vector105 +c0100c0b mon_kerninfo +c011cf00 pages +c0102481 vector146 +c010269d vector191 +c01022c8 vector103 +c0100bae mon_help +c0101f96 vector11 +c0104863 tlb_invalidate +c0101fab vector14 diff --git a/labcodes/lab2/obj/kernel_nopage.asm b/labcodes/lab2/obj/kernel_nopage.asm new file mode 100644 index 0000000000000000000000000000000000000000..adeed7deeefd024df661f03e26db5294c432ca02 --- /dev/null +++ b/labcodes/lab2/obj/kernel_nopage.asm @@ -0,0 +1,12382 @@ + +bin/kernel_nopage: file format elf32-i386 + + +Disassembly of section .text: + +00100000 : + +.text +.globl kern_entry +kern_entry: + # load pa of boot pgdir + movl $REALLOC(__boot_pgdir), %eax + 100000: b8 00 a0 11 40 mov $0x4011a000,%eax + movl %eax, %cr3 + 100005: 0f 22 d8 mov %eax,%cr3 + + # enable paging + movl %cr0, %eax + 100008: 0f 20 c0 mov %cr0,%eax + orl $(CR0_PE | CR0_PG | CR0_AM | CR0_WP | CR0_NE | CR0_TS | CR0_EM | CR0_MP), %eax + 10000b: 0d 2f 00 05 80 or $0x8005002f,%eax + andl $~(CR0_TS | CR0_EM), %eax + 100010: 83 e0 f3 and $0xfffffff3,%eax + movl %eax, %cr0 + 100013: 0f 22 c0 mov %eax,%cr0 + + # update eip + # now, eip = 0x1..... + leal next, %eax + 100016: 8d 05 1e 00 10 00 lea 0x10001e,%eax + # set eip = KERNBASE + 0x1..... + jmp *%eax + 10001c: ff e0 jmp *%eax + +0010001e : +next: + + # unmap va 0 ~ 4M, it's temporary mapping + xorl %eax, %eax + 10001e: 31 c0 xor %eax,%eax + movl %eax, __boot_pgdir + 100020: a3 00 a0 11 00 mov %eax,0x11a000 + + # set ebp, esp + movl $0x0, %ebp + 100025: 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 + 10002a: bc 00 90 11 00 mov $0x119000,%esp + # now kernel stack is ready , call the first C function + call kern_init + 10002f: e8 02 00 00 00 call 100036 + +00100034 : + +# should never get here +spin: + jmp spin + 100034: eb fe jmp 100034 + +00100036 : +int kern_init(void) __attribute__((noreturn)); +void grade_backtrace(void); +static void lab1_switch_test(void); + +int +kern_init(void) { + 100036: 55 push %ebp + 100037: 89 e5 mov %esp,%ebp + 100039: 83 ec 28 sub $0x28,%esp + extern char edata[], end[]; + memset(edata, 0, end - edata); + 10003c: b8 8c cf 11 00 mov $0x11cf8c,%eax + 100041: 2d 36 9a 11 00 sub $0x119a36,%eax + 100046: 89 44 24 08 mov %eax,0x8(%esp) + 10004a: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) + 100051: 00 + 100052: c7 04 24 36 9a 11 00 movl $0x119a36,(%esp) + 100059: e8 aa 5e 00 00 call 105f08 + + cons_init(); // init the console + 10005e: e8 42 15 00 00 call 1015a5 + + const char *message = "(THU.CST) os is loading ..."; + 100063: c7 45 f4 a0 60 10 00 movl $0x1060a0,-0xc(%ebp) + cprintf("%s\n\n", message); + 10006a: 8b 45 f4 mov -0xc(%ebp),%eax + 10006d: 89 44 24 04 mov %eax,0x4(%esp) + 100071: c7 04 24 bc 60 10 00 movl $0x1060bc,(%esp) + 100078: e8 e9 02 00 00 call 100366 + + print_kerninfo(); + 10007d: e8 07 08 00 00 call 100889 + + grade_backtrace(); + 100082: e8 95 00 00 00 call 10011c + + pmm_init(); // init physical memory management + 100087: e8 f3 43 00 00 call 10447f + + pic_init(); // init interrupt controller + 10008c: e8 95 16 00 00 call 101726 + idt_init(); // init interrupt descriptor table + 100091: e8 f9 17 00 00 call 10188f + + clock_init(); // init clock interrupt + 100096: e8 69 0c 00 00 call 100d04 + intr_enable(); // enable irq interrupt + 10009b: e8 e4 15 00 00 call 101684 + + //LAB1: CAHLLENGE 1 If you try to do it, uncomment lab1_switch_test() + // user/kernel mode switch test + lab1_switch_test(); + 1000a0: e8 76 01 00 00 call 10021b + + /* do nothing */ + while (1); + 1000a5: eb fe jmp 1000a5 + +001000a7 : +} + +void __attribute__((noinline)) +grade_backtrace2(int arg0, int arg1, int arg2, int arg3) { + 1000a7: 55 push %ebp + 1000a8: 89 e5 mov %esp,%ebp + 1000aa: 83 ec 18 sub $0x18,%esp + mon_backtrace(0, NULL, NULL); + 1000ad: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) + 1000b4: 00 + 1000b5: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) + 1000bc: 00 + 1000bd: c7 04 24 00 00 00 00 movl $0x0,(%esp) + 1000c4: e8 56 0b 00 00 call 100c1f +} + 1000c9: 90 nop + 1000ca: 89 ec mov %ebp,%esp + 1000cc: 5d pop %ebp + 1000cd: c3 ret + +001000ce : + +void __attribute__((noinline)) +grade_backtrace1(int arg0, int arg1) { + 1000ce: 55 push %ebp + 1000cf: 89 e5 mov %esp,%ebp + 1000d1: 83 ec 18 sub $0x18,%esp + 1000d4: 89 5d fc mov %ebx,-0x4(%ebp) + grade_backtrace2(arg0, (int)&arg0, arg1, (int)&arg1); + 1000d7: 8d 4d 0c lea 0xc(%ebp),%ecx + 1000da: 8b 55 0c mov 0xc(%ebp),%edx + 1000dd: 8d 5d 08 lea 0x8(%ebp),%ebx + 1000e0: 8b 45 08 mov 0x8(%ebp),%eax + 1000e3: 89 4c 24 0c mov %ecx,0xc(%esp) + 1000e7: 89 54 24 08 mov %edx,0x8(%esp) + 1000eb: 89 5c 24 04 mov %ebx,0x4(%esp) + 1000ef: 89 04 24 mov %eax,(%esp) + 1000f2: e8 b0 ff ff ff call 1000a7 +} + 1000f7: 90 nop + 1000f8: 8b 5d fc mov -0x4(%ebp),%ebx + 1000fb: 89 ec mov %ebp,%esp + 1000fd: 5d pop %ebp + 1000fe: c3 ret + +001000ff : + +void __attribute__((noinline)) +grade_backtrace0(int arg0, int arg1, int arg2) { + 1000ff: 55 push %ebp + 100100: 89 e5 mov %esp,%ebp + 100102: 83 ec 18 sub $0x18,%esp + grade_backtrace1(arg0, arg2); + 100105: 8b 45 10 mov 0x10(%ebp),%eax + 100108: 89 44 24 04 mov %eax,0x4(%esp) + 10010c: 8b 45 08 mov 0x8(%ebp),%eax + 10010f: 89 04 24 mov %eax,(%esp) + 100112: e8 b7 ff ff ff call 1000ce +} + 100117: 90 nop + 100118: 89 ec mov %ebp,%esp + 10011a: 5d pop %ebp + 10011b: c3 ret + +0010011c : + +void +grade_backtrace(void) { + 10011c: 55 push %ebp + 10011d: 89 e5 mov %esp,%ebp + 10011f: 83 ec 18 sub $0x18,%esp + grade_backtrace0(0, (int)kern_init, 0xffff0000); + 100122: b8 36 00 10 00 mov $0x100036,%eax + 100127: c7 44 24 08 00 00 ff movl $0xffff0000,0x8(%esp) + 10012e: ff + 10012f: 89 44 24 04 mov %eax,0x4(%esp) + 100133: c7 04 24 00 00 00 00 movl $0x0,(%esp) + 10013a: e8 c0 ff ff ff call 1000ff +} + 10013f: 90 nop + 100140: 89 ec mov %ebp,%esp + 100142: 5d pop %ebp + 100143: c3 ret + +00100144 : + +static void +lab1_print_cur_status(void) { + 100144: 55 push %ebp + 100145: 89 e5 mov %esp,%ebp + 100147: 83 ec 28 sub $0x28,%esp + static int round = 0; + uint16_t reg1, reg2, reg3, reg4; + asm volatile ( + 10014a: 8c 4d f6 mov %cs,-0xa(%ebp) + 10014d: 8c 5d f4 mov %ds,-0xc(%ebp) + 100150: 8c 45 f2 mov %es,-0xe(%ebp) + 100153: 8c 55 f0 mov %ss,-0x10(%ebp) + "mov %%cs, %0;" + "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); + 100156: 0f b7 45 f6 movzwl -0xa(%ebp),%eax + 10015a: 83 e0 03 and $0x3,%eax + 10015d: 89 c2 mov %eax,%edx + 10015f: a1 00 c0 11 00 mov 0x11c000,%eax + 100164: 89 54 24 08 mov %edx,0x8(%esp) + 100168: 89 44 24 04 mov %eax,0x4(%esp) + 10016c: c7 04 24 c1 60 10 00 movl $0x1060c1,(%esp) + 100173: e8 ee 01 00 00 call 100366 + cprintf("%d: cs = %x\n", round, reg1); + 100178: 0f b7 45 f6 movzwl -0xa(%ebp),%eax + 10017c: 89 c2 mov %eax,%edx + 10017e: a1 00 c0 11 00 mov 0x11c000,%eax + 100183: 89 54 24 08 mov %edx,0x8(%esp) + 100187: 89 44 24 04 mov %eax,0x4(%esp) + 10018b: c7 04 24 cf 60 10 00 movl $0x1060cf,(%esp) + 100192: e8 cf 01 00 00 call 100366 + cprintf("%d: ds = %x\n", round, reg2); + 100197: 0f b7 45 f4 movzwl -0xc(%ebp),%eax + 10019b: 89 c2 mov %eax,%edx + 10019d: a1 00 c0 11 00 mov 0x11c000,%eax + 1001a2: 89 54 24 08 mov %edx,0x8(%esp) + 1001a6: 89 44 24 04 mov %eax,0x4(%esp) + 1001aa: c7 04 24 dd 60 10 00 movl $0x1060dd,(%esp) + 1001b1: e8 b0 01 00 00 call 100366 + cprintf("%d: es = %x\n", round, reg3); + 1001b6: 0f b7 45 f2 movzwl -0xe(%ebp),%eax + 1001ba: 89 c2 mov %eax,%edx + 1001bc: a1 00 c0 11 00 mov 0x11c000,%eax + 1001c1: 89 54 24 08 mov %edx,0x8(%esp) + 1001c5: 89 44 24 04 mov %eax,0x4(%esp) + 1001c9: c7 04 24 eb 60 10 00 movl $0x1060eb,(%esp) + 1001d0: e8 91 01 00 00 call 100366 + cprintf("%d: ss = %x\n", round, reg4); + 1001d5: 0f b7 45 f0 movzwl -0x10(%ebp),%eax + 1001d9: 89 c2 mov %eax,%edx + 1001db: a1 00 c0 11 00 mov 0x11c000,%eax + 1001e0: 89 54 24 08 mov %edx,0x8(%esp) + 1001e4: 89 44 24 04 mov %eax,0x4(%esp) + 1001e8: c7 04 24 f9 60 10 00 movl $0x1060f9,(%esp) + 1001ef: e8 72 01 00 00 call 100366 + round ++; + 1001f4: a1 00 c0 11 00 mov 0x11c000,%eax + 1001f9: 40 inc %eax + 1001fa: a3 00 c0 11 00 mov %eax,0x11c000 +} + 1001ff: 90 nop + 100200: 89 ec mov %ebp,%esp + 100202: 5d pop %ebp + 100203: c3 ret + +00100204 : + +static void +lab1_switch_to_user(void) { + 100204: 55 push %ebp + 100205: 89 e5 mov %esp,%ebp + //LAB1 CHALLENGE 1 : TODO + asm volatile ( + 100207: 83 ec 08 sub $0x8,%esp + 10020a: cd 78 int $0x78 + 10020c: 89 ec mov %ebp,%esp + "int %0 \n" + "movl %%ebp, %%esp" + : + : "i"(T_SWITCH_TOU) + ); +} + 10020e: 90 nop + 10020f: 5d pop %ebp + 100210: c3 ret + +00100211 : + +static void +lab1_switch_to_kernel(void) { + 100211: 55 push %ebp + 100212: 89 e5 mov %esp,%ebp + //LAB1 CHALLENGE 1 : TODO + asm volatile ( + 100214: cd 79 int $0x79 + 100216: 89 ec mov %ebp,%esp + "int %0 \n" + "movl %%ebp, %%esp \n" + : + : "i"(T_SWITCH_TOK) + ); +} + 100218: 90 nop + 100219: 5d pop %ebp + 10021a: c3 ret + +0010021b : + +static void +lab1_switch_test(void) { + 10021b: 55 push %ebp + 10021c: 89 e5 mov %esp,%ebp + 10021e: 83 ec 18 sub $0x18,%esp + lab1_print_cur_status(); + 100221: e8 1e ff ff ff call 100144 + cprintf("+++ switch to user mode +++\n"); + 100226: c7 04 24 08 61 10 00 movl $0x106108,(%esp) + 10022d: e8 34 01 00 00 call 100366 + lab1_switch_to_user(); + 100232: e8 cd ff ff ff call 100204 + lab1_print_cur_status(); + 100237: e8 08 ff ff ff call 100144 + cprintf("+++ switch to kernel mode +++\n"); + 10023c: c7 04 24 28 61 10 00 movl $0x106128,(%esp) + 100243: e8 1e 01 00 00 call 100366 + lab1_switch_to_kernel(); + 100248: e8 c4 ff ff ff call 100211 + lab1_print_cur_status(); + 10024d: e8 f2 fe ff ff call 100144 +} + 100252: 90 nop + 100253: 89 ec mov %ebp,%esp + 100255: 5d pop %ebp + 100256: c3 ret + +00100257 : + * 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) { + 100257: 55 push %ebp + 100258: 89 e5 mov %esp,%ebp + 10025a: 83 ec 28 sub $0x28,%esp + if (prompt != NULL) { + 10025d: 83 7d 08 00 cmpl $0x0,0x8(%ebp) + 100261: 74 13 je 100276 + cprintf("%s", prompt); + 100263: 8b 45 08 mov 0x8(%ebp),%eax + 100266: 89 44 24 04 mov %eax,0x4(%esp) + 10026a: c7 04 24 47 61 10 00 movl $0x106147,(%esp) + 100271: e8 f0 00 00 00 call 100366 + } + int i = 0, c; + 100276: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + while (1) { + c = getchar(); + 10027d: e8 73 01 00 00 call 1003f5 + 100282: 89 45 f0 mov %eax,-0x10(%ebp) + if (c < 0) { + 100285: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) + 100289: 79 07 jns 100292 + return NULL; + 10028b: b8 00 00 00 00 mov $0x0,%eax + 100290: eb 78 jmp 10030a + } + else if (c >= ' ' && i < BUFSIZE - 1) { + 100292: 83 7d f0 1f cmpl $0x1f,-0x10(%ebp) + 100296: 7e 28 jle 1002c0 + 100298: 81 7d f4 fe 03 00 00 cmpl $0x3fe,-0xc(%ebp) + 10029f: 7f 1f jg 1002c0 + cputchar(c); + 1002a1: 8b 45 f0 mov -0x10(%ebp),%eax + 1002a4: 89 04 24 mov %eax,(%esp) + 1002a7: e8 e2 00 00 00 call 10038e + buf[i ++] = c; + 1002ac: 8b 45 f4 mov -0xc(%ebp),%eax + 1002af: 8d 50 01 lea 0x1(%eax),%edx + 1002b2: 89 55 f4 mov %edx,-0xc(%ebp) + 1002b5: 8b 55 f0 mov -0x10(%ebp),%edx + 1002b8: 88 90 20 c0 11 00 mov %dl,0x11c020(%eax) + 1002be: eb 45 jmp 100305 + } + else if (c == '\b' && i > 0) { + 1002c0: 83 7d f0 08 cmpl $0x8,-0x10(%ebp) + 1002c4: 75 16 jne 1002dc + 1002c6: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) + 1002ca: 7e 10 jle 1002dc + cputchar(c); + 1002cc: 8b 45 f0 mov -0x10(%ebp),%eax + 1002cf: 89 04 24 mov %eax,(%esp) + 1002d2: e8 b7 00 00 00 call 10038e + i --; + 1002d7: ff 4d f4 decl -0xc(%ebp) + 1002da: eb 29 jmp 100305 + } + else if (c == '\n' || c == '\r') { + 1002dc: 83 7d f0 0a cmpl $0xa,-0x10(%ebp) + 1002e0: 74 06 je 1002e8 + 1002e2: 83 7d f0 0d cmpl $0xd,-0x10(%ebp) + 1002e6: 75 95 jne 10027d + cputchar(c); + 1002e8: 8b 45 f0 mov -0x10(%ebp),%eax + 1002eb: 89 04 24 mov %eax,(%esp) + 1002ee: e8 9b 00 00 00 call 10038e + buf[i] = '\0'; + 1002f3: 8b 45 f4 mov -0xc(%ebp),%eax + 1002f6: 05 20 c0 11 00 add $0x11c020,%eax + 1002fb: c6 00 00 movb $0x0,(%eax) + return buf; + 1002fe: b8 20 c0 11 00 mov $0x11c020,%eax + 100303: eb 05 jmp 10030a + c = getchar(); + 100305: e9 73 ff ff ff jmp 10027d + } + } +} + 10030a: 89 ec mov %ebp,%esp + 10030c: 5d pop %ebp + 10030d: c3 ret + +0010030e : +/* * + * 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) { + 10030e: 55 push %ebp + 10030f: 89 e5 mov %esp,%ebp + 100311: 83 ec 18 sub $0x18,%esp + cons_putc(c); + 100314: 8b 45 08 mov 0x8(%ebp),%eax + 100317: 89 04 24 mov %eax,(%esp) + 10031a: e8 b5 12 00 00 call 1015d4 + (*cnt) ++; + 10031f: 8b 45 0c mov 0xc(%ebp),%eax + 100322: 8b 00 mov (%eax),%eax + 100324: 8d 50 01 lea 0x1(%eax),%edx + 100327: 8b 45 0c mov 0xc(%ebp),%eax + 10032a: 89 10 mov %edx,(%eax) +} + 10032c: 90 nop + 10032d: 89 ec mov %ebp,%esp + 10032f: 5d pop %ebp + 100330: c3 ret + +00100331 : + * + * 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) { + 100331: 55 push %ebp + 100332: 89 e5 mov %esp,%ebp + 100334: 83 ec 28 sub $0x28,%esp + int cnt = 0; + 100337: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + vprintfmt((void*)cputch, &cnt, fmt, ap); + 10033e: 8b 45 0c mov 0xc(%ebp),%eax + 100341: 89 44 24 0c mov %eax,0xc(%esp) + 100345: 8b 45 08 mov 0x8(%ebp),%eax + 100348: 89 44 24 08 mov %eax,0x8(%esp) + 10034c: 8d 45 f4 lea -0xc(%ebp),%eax + 10034f: 89 44 24 04 mov %eax,0x4(%esp) + 100353: c7 04 24 0e 03 10 00 movl $0x10030e,(%esp) + 10035a: e8 d4 53 00 00 call 105733 + return cnt; + 10035f: 8b 45 f4 mov -0xc(%ebp),%eax +} + 100362: 89 ec mov %ebp,%esp + 100364: 5d pop %ebp + 100365: c3 ret + +00100366 : + * + * The return value is the number of characters which would be + * written to stdout. + * */ +int +cprintf(const char *fmt, ...) { + 100366: 55 push %ebp + 100367: 89 e5 mov %esp,%ebp + 100369: 83 ec 28 sub $0x28,%esp + va_list ap; + int cnt; + va_start(ap, fmt); + 10036c: 8d 45 0c lea 0xc(%ebp),%eax + 10036f: 89 45 f0 mov %eax,-0x10(%ebp) + cnt = vcprintf(fmt, ap); + 100372: 8b 45 f0 mov -0x10(%ebp),%eax + 100375: 89 44 24 04 mov %eax,0x4(%esp) + 100379: 8b 45 08 mov 0x8(%ebp),%eax + 10037c: 89 04 24 mov %eax,(%esp) + 10037f: e8 ad ff ff ff call 100331 + 100384: 89 45 f4 mov %eax,-0xc(%ebp) + va_end(ap); + return cnt; + 100387: 8b 45 f4 mov -0xc(%ebp),%eax +} + 10038a: 89 ec mov %ebp,%esp + 10038c: 5d pop %ebp + 10038d: c3 ret + +0010038e : + +/* cputchar - writes a single character to stdout */ +void +cputchar(int c) { + 10038e: 55 push %ebp + 10038f: 89 e5 mov %esp,%ebp + 100391: 83 ec 18 sub $0x18,%esp + cons_putc(c); + 100394: 8b 45 08 mov 0x8(%ebp),%eax + 100397: 89 04 24 mov %eax,(%esp) + 10039a: e8 35 12 00 00 call 1015d4 +} + 10039f: 90 nop + 1003a0: 89 ec mov %ebp,%esp + 1003a2: 5d pop %ebp + 1003a3: c3 ret + +001003a4 : +/* * + * cputs- writes the string pointed by @str to stdout and + * appends a newline character. + * */ +int +cputs(const char *str) { + 1003a4: 55 push %ebp + 1003a5: 89 e5 mov %esp,%ebp + 1003a7: 83 ec 28 sub $0x28,%esp + int cnt = 0; + 1003aa: c7 45 f0 00 00 00 00 movl $0x0,-0x10(%ebp) + char c; + while ((c = *str ++) != '\0') { + 1003b1: eb 13 jmp 1003c6 + cputch(c, &cnt); + 1003b3: 0f be 45 f7 movsbl -0x9(%ebp),%eax + 1003b7: 8d 55 f0 lea -0x10(%ebp),%edx + 1003ba: 89 54 24 04 mov %edx,0x4(%esp) + 1003be: 89 04 24 mov %eax,(%esp) + 1003c1: e8 48 ff ff ff call 10030e + while ((c = *str ++) != '\0') { + 1003c6: 8b 45 08 mov 0x8(%ebp),%eax + 1003c9: 8d 50 01 lea 0x1(%eax),%edx + 1003cc: 89 55 08 mov %edx,0x8(%ebp) + 1003cf: 0f b6 00 movzbl (%eax),%eax + 1003d2: 88 45 f7 mov %al,-0x9(%ebp) + 1003d5: 80 7d f7 00 cmpb $0x0,-0x9(%ebp) + 1003d9: 75 d8 jne 1003b3 + } + cputch('\n', &cnt); + 1003db: 8d 45 f0 lea -0x10(%ebp),%eax + 1003de: 89 44 24 04 mov %eax,0x4(%esp) + 1003e2: c7 04 24 0a 00 00 00 movl $0xa,(%esp) + 1003e9: e8 20 ff ff ff call 10030e + return cnt; + 1003ee: 8b 45 f0 mov -0x10(%ebp),%eax +} + 1003f1: 89 ec mov %ebp,%esp + 1003f3: 5d pop %ebp + 1003f4: c3 ret + +001003f5 : + +/* getchar - reads a single non-zero character from stdin */ +int +getchar(void) { + 1003f5: 55 push %ebp + 1003f6: 89 e5 mov %esp,%ebp + 1003f8: 83 ec 18 sub $0x18,%esp + int c; + while ((c = cons_getc()) == 0) + 1003fb: 90 nop + 1003fc: e8 12 12 00 00 call 101613 + 100401: 89 45 f4 mov %eax,-0xc(%ebp) + 100404: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) + 100408: 74 f2 je 1003fc + /* do nothing */; + return c; + 10040a: 8b 45 f4 mov -0xc(%ebp),%eax +} + 10040d: 89 ec mov %ebp,%esp + 10040f: 5d pop %ebp + 100410: c3 ret + +00100411 : + * 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) { + 100411: 55 push %ebp + 100412: 89 e5 mov %esp,%ebp + 100414: 83 ec 20 sub $0x20,%esp + int l = *region_left, r = *region_right, any_matches = 0; + 100417: 8b 45 0c mov 0xc(%ebp),%eax + 10041a: 8b 00 mov (%eax),%eax + 10041c: 89 45 fc mov %eax,-0x4(%ebp) + 10041f: 8b 45 10 mov 0x10(%ebp),%eax + 100422: 8b 00 mov (%eax),%eax + 100424: 89 45 f8 mov %eax,-0x8(%ebp) + 100427: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + + while (l <= r) { + 10042e: e9 ca 00 00 00 jmp 1004fd + int true_m = (l + r) / 2, m = true_m; + 100433: 8b 55 fc mov -0x4(%ebp),%edx + 100436: 8b 45 f8 mov -0x8(%ebp),%eax + 100439: 01 d0 add %edx,%eax + 10043b: 89 c2 mov %eax,%edx + 10043d: c1 ea 1f shr $0x1f,%edx + 100440: 01 d0 add %edx,%eax + 100442: d1 f8 sar %eax + 100444: 89 45 ec mov %eax,-0x14(%ebp) + 100447: 8b 45 ec mov -0x14(%ebp),%eax + 10044a: 89 45 f0 mov %eax,-0x10(%ebp) + + // search for earliest stab with right type + while (m >= l && stabs[m].n_type != type) { + 10044d: eb 03 jmp 100452 + m --; + 10044f: ff 4d f0 decl -0x10(%ebp) + while (m >= l && stabs[m].n_type != type) { + 100452: 8b 45 f0 mov -0x10(%ebp),%eax + 100455: 3b 45 fc cmp -0x4(%ebp),%eax + 100458: 7c 1f jl 100479 + 10045a: 8b 55 f0 mov -0x10(%ebp),%edx + 10045d: 89 d0 mov %edx,%eax + 10045f: 01 c0 add %eax,%eax + 100461: 01 d0 add %edx,%eax + 100463: c1 e0 02 shl $0x2,%eax + 100466: 89 c2 mov %eax,%edx + 100468: 8b 45 08 mov 0x8(%ebp),%eax + 10046b: 01 d0 add %edx,%eax + 10046d: 0f b6 40 04 movzbl 0x4(%eax),%eax + 100471: 0f b6 c0 movzbl %al,%eax + 100474: 39 45 14 cmp %eax,0x14(%ebp) + 100477: 75 d6 jne 10044f + } + if (m < l) { // no match in [l, m] + 100479: 8b 45 f0 mov -0x10(%ebp),%eax + 10047c: 3b 45 fc cmp -0x4(%ebp),%eax + 10047f: 7d 09 jge 10048a + l = true_m + 1; + 100481: 8b 45 ec mov -0x14(%ebp),%eax + 100484: 40 inc %eax + 100485: 89 45 fc mov %eax,-0x4(%ebp) + continue; + 100488: eb 73 jmp 1004fd + } + + // actual binary search + any_matches = 1; + 10048a: c7 45 f4 01 00 00 00 movl $0x1,-0xc(%ebp) + if (stabs[m].n_value < addr) { + 100491: 8b 55 f0 mov -0x10(%ebp),%edx + 100494: 89 d0 mov %edx,%eax + 100496: 01 c0 add %eax,%eax + 100498: 01 d0 add %edx,%eax + 10049a: c1 e0 02 shl $0x2,%eax + 10049d: 89 c2 mov %eax,%edx + 10049f: 8b 45 08 mov 0x8(%ebp),%eax + 1004a2: 01 d0 add %edx,%eax + 1004a4: 8b 40 08 mov 0x8(%eax),%eax + 1004a7: 39 45 18 cmp %eax,0x18(%ebp) + 1004aa: 76 11 jbe 1004bd + *region_left = m; + 1004ac: 8b 45 0c mov 0xc(%ebp),%eax + 1004af: 8b 55 f0 mov -0x10(%ebp),%edx + 1004b2: 89 10 mov %edx,(%eax) + l = true_m + 1; + 1004b4: 8b 45 ec mov -0x14(%ebp),%eax + 1004b7: 40 inc %eax + 1004b8: 89 45 fc mov %eax,-0x4(%ebp) + 1004bb: eb 40 jmp 1004fd + } else if (stabs[m].n_value > addr) { + 1004bd: 8b 55 f0 mov -0x10(%ebp),%edx + 1004c0: 89 d0 mov %edx,%eax + 1004c2: 01 c0 add %eax,%eax + 1004c4: 01 d0 add %edx,%eax + 1004c6: c1 e0 02 shl $0x2,%eax + 1004c9: 89 c2 mov %eax,%edx + 1004cb: 8b 45 08 mov 0x8(%ebp),%eax + 1004ce: 01 d0 add %edx,%eax + 1004d0: 8b 40 08 mov 0x8(%eax),%eax + 1004d3: 39 45 18 cmp %eax,0x18(%ebp) + 1004d6: 73 14 jae 1004ec + *region_right = m - 1; + 1004d8: 8b 45 f0 mov -0x10(%ebp),%eax + 1004db: 8d 50 ff lea -0x1(%eax),%edx + 1004de: 8b 45 10 mov 0x10(%ebp),%eax + 1004e1: 89 10 mov %edx,(%eax) + r = m - 1; + 1004e3: 8b 45 f0 mov -0x10(%ebp),%eax + 1004e6: 48 dec %eax + 1004e7: 89 45 f8 mov %eax,-0x8(%ebp) + 1004ea: eb 11 jmp 1004fd + } else { + // exact match for 'addr', but continue loop to find + // *region_right + *region_left = m; + 1004ec: 8b 45 0c mov 0xc(%ebp),%eax + 1004ef: 8b 55 f0 mov -0x10(%ebp),%edx + 1004f2: 89 10 mov %edx,(%eax) + l = m; + 1004f4: 8b 45 f0 mov -0x10(%ebp),%eax + 1004f7: 89 45 fc mov %eax,-0x4(%ebp) + addr ++; + 1004fa: ff 45 18 incl 0x18(%ebp) + while (l <= r) { + 1004fd: 8b 45 fc mov -0x4(%ebp),%eax + 100500: 3b 45 f8 cmp -0x8(%ebp),%eax + 100503: 0f 8e 2a ff ff ff jle 100433 + } + } + + if (!any_matches) { + 100509: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) + 10050d: 75 0f jne 10051e + *region_right = *region_left - 1; + 10050f: 8b 45 0c mov 0xc(%ebp),%eax + 100512: 8b 00 mov (%eax),%eax + 100514: 8d 50 ff lea -0x1(%eax),%edx + 100517: 8b 45 10 mov 0x10(%ebp),%eax + 10051a: 89 10 mov %edx,(%eax) + l = *region_right; + for (; l > *region_left && stabs[l].n_type != type; l --) + /* do nothing */; + *region_left = l; + } +} + 10051c: eb 3e jmp 10055c + l = *region_right; + 10051e: 8b 45 10 mov 0x10(%ebp),%eax + 100521: 8b 00 mov (%eax),%eax + 100523: 89 45 fc mov %eax,-0x4(%ebp) + for (; l > *region_left && stabs[l].n_type != type; l --) + 100526: eb 03 jmp 10052b + 100528: ff 4d fc decl -0x4(%ebp) + 10052b: 8b 45 0c mov 0xc(%ebp),%eax + 10052e: 8b 00 mov (%eax),%eax + 100530: 39 45 fc cmp %eax,-0x4(%ebp) + 100533: 7e 1f jle 100554 + 100535: 8b 55 fc mov -0x4(%ebp),%edx + 100538: 89 d0 mov %edx,%eax + 10053a: 01 c0 add %eax,%eax + 10053c: 01 d0 add %edx,%eax + 10053e: c1 e0 02 shl $0x2,%eax + 100541: 89 c2 mov %eax,%edx + 100543: 8b 45 08 mov 0x8(%ebp),%eax + 100546: 01 d0 add %edx,%eax + 100548: 0f b6 40 04 movzbl 0x4(%eax),%eax + 10054c: 0f b6 c0 movzbl %al,%eax + 10054f: 39 45 14 cmp %eax,0x14(%ebp) + 100552: 75 d4 jne 100528 + *region_left = l; + 100554: 8b 45 0c mov 0xc(%ebp),%eax + 100557: 8b 55 fc mov -0x4(%ebp),%edx + 10055a: 89 10 mov %edx,(%eax) +} + 10055c: 90 nop + 10055d: 89 ec mov %ebp,%esp + 10055f: 5d pop %ebp + 100560: c3 ret + +00100561 : + * 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) { + 100561: 55 push %ebp + 100562: 89 e5 mov %esp,%ebp + 100564: 83 ec 58 sub $0x58,%esp + const struct stab *stabs, *stab_end; + const char *stabstr, *stabstr_end; + + info->eip_file = ""; + 100567: 8b 45 0c mov 0xc(%ebp),%eax + 10056a: c7 00 4c 61 10 00 movl $0x10614c,(%eax) + info->eip_line = 0; + 100570: 8b 45 0c mov 0xc(%ebp),%eax + 100573: c7 40 04 00 00 00 00 movl $0x0,0x4(%eax) + info->eip_fn_name = ""; + 10057a: 8b 45 0c mov 0xc(%ebp),%eax + 10057d: c7 40 08 4c 61 10 00 movl $0x10614c,0x8(%eax) + info->eip_fn_namelen = 9; + 100584: 8b 45 0c mov 0xc(%ebp),%eax + 100587: c7 40 0c 09 00 00 00 movl $0x9,0xc(%eax) + info->eip_fn_addr = addr; + 10058e: 8b 45 0c mov 0xc(%ebp),%eax + 100591: 8b 55 08 mov 0x8(%ebp),%edx + 100594: 89 50 10 mov %edx,0x10(%eax) + info->eip_fn_narg = 0; + 100597: 8b 45 0c mov 0xc(%ebp),%eax + 10059a: c7 40 14 00 00 00 00 movl $0x0,0x14(%eax) + + stabs = __STAB_BEGIN__; + 1005a1: c7 45 f4 b8 73 10 00 movl $0x1073b8,-0xc(%ebp) + stab_end = __STAB_END__; + 1005a8: c7 45 f0 ac 2a 11 00 movl $0x112aac,-0x10(%ebp) + stabstr = __STABSTR_BEGIN__; + 1005af: c7 45 ec ad 2a 11 00 movl $0x112aad,-0x14(%ebp) + stabstr_end = __STABSTR_END__; + 1005b6: c7 45 e8 44 60 11 00 movl $0x116044,-0x18(%ebp) + + // String table validity checks + if (stabstr_end <= stabstr || stabstr_end[-1] != 0) { + 1005bd: 8b 45 e8 mov -0x18(%ebp),%eax + 1005c0: 3b 45 ec cmp -0x14(%ebp),%eax + 1005c3: 76 0b jbe 1005d0 + 1005c5: 8b 45 e8 mov -0x18(%ebp),%eax + 1005c8: 48 dec %eax + 1005c9: 0f b6 00 movzbl (%eax),%eax + 1005cc: 84 c0 test %al,%al + 1005ce: 74 0a je 1005da + return -1; + 1005d0: b8 ff ff ff ff mov $0xffffffff,%eax + 1005d5: e9 ab 02 00 00 jmp 100885 + // '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; + 1005da: c7 45 e4 00 00 00 00 movl $0x0,-0x1c(%ebp) + 1005e1: 8b 45 f0 mov -0x10(%ebp),%eax + 1005e4: 2b 45 f4 sub -0xc(%ebp),%eax + 1005e7: c1 f8 02 sar $0x2,%eax + 1005ea: 69 c0 ab aa aa aa imul $0xaaaaaaab,%eax,%eax + 1005f0: 48 dec %eax + 1005f1: 89 45 e0 mov %eax,-0x20(%ebp) + stab_binsearch(stabs, &lfile, &rfile, N_SO, addr); + 1005f4: 8b 45 08 mov 0x8(%ebp),%eax + 1005f7: 89 44 24 10 mov %eax,0x10(%esp) + 1005fb: c7 44 24 0c 64 00 00 movl $0x64,0xc(%esp) + 100602: 00 + 100603: 8d 45 e0 lea -0x20(%ebp),%eax + 100606: 89 44 24 08 mov %eax,0x8(%esp) + 10060a: 8d 45 e4 lea -0x1c(%ebp),%eax + 10060d: 89 44 24 04 mov %eax,0x4(%esp) + 100611: 8b 45 f4 mov -0xc(%ebp),%eax + 100614: 89 04 24 mov %eax,(%esp) + 100617: e8 f5 fd ff ff call 100411 + if (lfile == 0) + 10061c: 8b 45 e4 mov -0x1c(%ebp),%eax + 10061f: 85 c0 test %eax,%eax + 100621: 75 0a jne 10062d + return -1; + 100623: b8 ff ff ff ff mov $0xffffffff,%eax + 100628: e9 58 02 00 00 jmp 100885 + + // Search within that file's stabs for the function definition + // (N_FUN). + int lfun = lfile, rfun = rfile; + 10062d: 8b 45 e4 mov -0x1c(%ebp),%eax + 100630: 89 45 dc mov %eax,-0x24(%ebp) + 100633: 8b 45 e0 mov -0x20(%ebp),%eax + 100636: 89 45 d8 mov %eax,-0x28(%ebp) + int lline, rline; + stab_binsearch(stabs, &lfun, &rfun, N_FUN, addr); + 100639: 8b 45 08 mov 0x8(%ebp),%eax + 10063c: 89 44 24 10 mov %eax,0x10(%esp) + 100640: c7 44 24 0c 24 00 00 movl $0x24,0xc(%esp) + 100647: 00 + 100648: 8d 45 d8 lea -0x28(%ebp),%eax + 10064b: 89 44 24 08 mov %eax,0x8(%esp) + 10064f: 8d 45 dc lea -0x24(%ebp),%eax + 100652: 89 44 24 04 mov %eax,0x4(%esp) + 100656: 8b 45 f4 mov -0xc(%ebp),%eax + 100659: 89 04 24 mov %eax,(%esp) + 10065c: e8 b0 fd ff ff call 100411 + + if (lfun <= rfun) { + 100661: 8b 55 dc mov -0x24(%ebp),%edx + 100664: 8b 45 d8 mov -0x28(%ebp),%eax + 100667: 39 c2 cmp %eax,%edx + 100669: 7f 78 jg 1006e3 + // 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) { + 10066b: 8b 45 dc mov -0x24(%ebp),%eax + 10066e: 89 c2 mov %eax,%edx + 100670: 89 d0 mov %edx,%eax + 100672: 01 c0 add %eax,%eax + 100674: 01 d0 add %edx,%eax + 100676: c1 e0 02 shl $0x2,%eax + 100679: 89 c2 mov %eax,%edx + 10067b: 8b 45 f4 mov -0xc(%ebp),%eax + 10067e: 01 d0 add %edx,%eax + 100680: 8b 10 mov (%eax),%edx + 100682: 8b 45 e8 mov -0x18(%ebp),%eax + 100685: 2b 45 ec sub -0x14(%ebp),%eax + 100688: 39 c2 cmp %eax,%edx + 10068a: 73 22 jae 1006ae + info->eip_fn_name = stabstr + stabs[lfun].n_strx; + 10068c: 8b 45 dc mov -0x24(%ebp),%eax + 10068f: 89 c2 mov %eax,%edx + 100691: 89 d0 mov %edx,%eax + 100693: 01 c0 add %eax,%eax + 100695: 01 d0 add %edx,%eax + 100697: c1 e0 02 shl $0x2,%eax + 10069a: 89 c2 mov %eax,%edx + 10069c: 8b 45 f4 mov -0xc(%ebp),%eax + 10069f: 01 d0 add %edx,%eax + 1006a1: 8b 10 mov (%eax),%edx + 1006a3: 8b 45 ec mov -0x14(%ebp),%eax + 1006a6: 01 c2 add %eax,%edx + 1006a8: 8b 45 0c mov 0xc(%ebp),%eax + 1006ab: 89 50 08 mov %edx,0x8(%eax) + } + info->eip_fn_addr = stabs[lfun].n_value; + 1006ae: 8b 45 dc mov -0x24(%ebp),%eax + 1006b1: 89 c2 mov %eax,%edx + 1006b3: 89 d0 mov %edx,%eax + 1006b5: 01 c0 add %eax,%eax + 1006b7: 01 d0 add %edx,%eax + 1006b9: c1 e0 02 shl $0x2,%eax + 1006bc: 89 c2 mov %eax,%edx + 1006be: 8b 45 f4 mov -0xc(%ebp),%eax + 1006c1: 01 d0 add %edx,%eax + 1006c3: 8b 50 08 mov 0x8(%eax),%edx + 1006c6: 8b 45 0c mov 0xc(%ebp),%eax + 1006c9: 89 50 10 mov %edx,0x10(%eax) + addr -= info->eip_fn_addr; + 1006cc: 8b 45 0c mov 0xc(%ebp),%eax + 1006cf: 8b 40 10 mov 0x10(%eax),%eax + 1006d2: 29 45 08 sub %eax,0x8(%ebp) + // Search within the function definition for the line number. + lline = lfun; + 1006d5: 8b 45 dc mov -0x24(%ebp),%eax + 1006d8: 89 45 d4 mov %eax,-0x2c(%ebp) + rline = rfun; + 1006db: 8b 45 d8 mov -0x28(%ebp),%eax + 1006de: 89 45 d0 mov %eax,-0x30(%ebp) + 1006e1: eb 15 jmp 1006f8 + } 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; + 1006e3: 8b 45 0c mov 0xc(%ebp),%eax + 1006e6: 8b 55 08 mov 0x8(%ebp),%edx + 1006e9: 89 50 10 mov %edx,0x10(%eax) + lline = lfile; + 1006ec: 8b 45 e4 mov -0x1c(%ebp),%eax + 1006ef: 89 45 d4 mov %eax,-0x2c(%ebp) + rline = rfile; + 1006f2: 8b 45 e0 mov -0x20(%ebp),%eax + 1006f5: 89 45 d0 mov %eax,-0x30(%ebp) + } + info->eip_fn_namelen = strfind(info->eip_fn_name, ':') - info->eip_fn_name; + 1006f8: 8b 45 0c mov 0xc(%ebp),%eax + 1006fb: 8b 40 08 mov 0x8(%eax),%eax + 1006fe: c7 44 24 04 3a 00 00 movl $0x3a,0x4(%esp) + 100705: 00 + 100706: 89 04 24 mov %eax,(%esp) + 100709: e8 72 56 00 00 call 105d80 + 10070e: 8b 55 0c mov 0xc(%ebp),%edx + 100711: 8b 4a 08 mov 0x8(%edx),%ecx + 100714: 29 c8 sub %ecx,%eax + 100716: 89 c2 mov %eax,%edx + 100718: 8b 45 0c mov 0xc(%ebp),%eax + 10071b: 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); + 10071e: 8b 45 08 mov 0x8(%ebp),%eax + 100721: 89 44 24 10 mov %eax,0x10(%esp) + 100725: c7 44 24 0c 44 00 00 movl $0x44,0xc(%esp) + 10072c: 00 + 10072d: 8d 45 d0 lea -0x30(%ebp),%eax + 100730: 89 44 24 08 mov %eax,0x8(%esp) + 100734: 8d 45 d4 lea -0x2c(%ebp),%eax + 100737: 89 44 24 04 mov %eax,0x4(%esp) + 10073b: 8b 45 f4 mov -0xc(%ebp),%eax + 10073e: 89 04 24 mov %eax,(%esp) + 100741: e8 cb fc ff ff call 100411 + if (lline <= rline) { + 100746: 8b 55 d4 mov -0x2c(%ebp),%edx + 100749: 8b 45 d0 mov -0x30(%ebp),%eax + 10074c: 39 c2 cmp %eax,%edx + 10074e: 7f 23 jg 100773 + info->eip_line = stabs[rline].n_desc; + 100750: 8b 45 d0 mov -0x30(%ebp),%eax + 100753: 89 c2 mov %eax,%edx + 100755: 89 d0 mov %edx,%eax + 100757: 01 c0 add %eax,%eax + 100759: 01 d0 add %edx,%eax + 10075b: c1 e0 02 shl $0x2,%eax + 10075e: 89 c2 mov %eax,%edx + 100760: 8b 45 f4 mov -0xc(%ebp),%eax + 100763: 01 d0 add %edx,%eax + 100765: 0f b7 40 06 movzwl 0x6(%eax),%eax + 100769: 89 c2 mov %eax,%edx + 10076b: 8b 45 0c mov 0xc(%ebp),%eax + 10076e: 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 + 100771: eb 11 jmp 100784 + return -1; + 100773: b8 ff ff ff ff mov $0xffffffff,%eax + 100778: e9 08 01 00 00 jmp 100885 + && stabs[lline].n_type != N_SOL + && (stabs[lline].n_type != N_SO || !stabs[lline].n_value)) { + lline --; + 10077d: 8b 45 d4 mov -0x2c(%ebp),%eax + 100780: 48 dec %eax + 100781: 89 45 d4 mov %eax,-0x2c(%ebp) + while (lline >= lfile + 100784: 8b 55 d4 mov -0x2c(%ebp),%edx + 100787: 8b 45 e4 mov -0x1c(%ebp),%eax + && (stabs[lline].n_type != N_SO || !stabs[lline].n_value)) { + 10078a: 39 c2 cmp %eax,%edx + 10078c: 7c 56 jl 1007e4 + && stabs[lline].n_type != N_SOL + 10078e: 8b 45 d4 mov -0x2c(%ebp),%eax + 100791: 89 c2 mov %eax,%edx + 100793: 89 d0 mov %edx,%eax + 100795: 01 c0 add %eax,%eax + 100797: 01 d0 add %edx,%eax + 100799: c1 e0 02 shl $0x2,%eax + 10079c: 89 c2 mov %eax,%edx + 10079e: 8b 45 f4 mov -0xc(%ebp),%eax + 1007a1: 01 d0 add %edx,%eax + 1007a3: 0f b6 40 04 movzbl 0x4(%eax),%eax + 1007a7: 3c 84 cmp $0x84,%al + 1007a9: 74 39 je 1007e4 + && (stabs[lline].n_type != N_SO || !stabs[lline].n_value)) { + 1007ab: 8b 45 d4 mov -0x2c(%ebp),%eax + 1007ae: 89 c2 mov %eax,%edx + 1007b0: 89 d0 mov %edx,%eax + 1007b2: 01 c0 add %eax,%eax + 1007b4: 01 d0 add %edx,%eax + 1007b6: c1 e0 02 shl $0x2,%eax + 1007b9: 89 c2 mov %eax,%edx + 1007bb: 8b 45 f4 mov -0xc(%ebp),%eax + 1007be: 01 d0 add %edx,%eax + 1007c0: 0f b6 40 04 movzbl 0x4(%eax),%eax + 1007c4: 3c 64 cmp $0x64,%al + 1007c6: 75 b5 jne 10077d + 1007c8: 8b 45 d4 mov -0x2c(%ebp),%eax + 1007cb: 89 c2 mov %eax,%edx + 1007cd: 89 d0 mov %edx,%eax + 1007cf: 01 c0 add %eax,%eax + 1007d1: 01 d0 add %edx,%eax + 1007d3: c1 e0 02 shl $0x2,%eax + 1007d6: 89 c2 mov %eax,%edx + 1007d8: 8b 45 f4 mov -0xc(%ebp),%eax + 1007db: 01 d0 add %edx,%eax + 1007dd: 8b 40 08 mov 0x8(%eax),%eax + 1007e0: 85 c0 test %eax,%eax + 1007e2: 74 99 je 10077d + } + if (lline >= lfile && stabs[lline].n_strx < stabstr_end - stabstr) { + 1007e4: 8b 55 d4 mov -0x2c(%ebp),%edx + 1007e7: 8b 45 e4 mov -0x1c(%ebp),%eax + 1007ea: 39 c2 cmp %eax,%edx + 1007ec: 7c 42 jl 100830 + 1007ee: 8b 45 d4 mov -0x2c(%ebp),%eax + 1007f1: 89 c2 mov %eax,%edx + 1007f3: 89 d0 mov %edx,%eax + 1007f5: 01 c0 add %eax,%eax + 1007f7: 01 d0 add %edx,%eax + 1007f9: c1 e0 02 shl $0x2,%eax + 1007fc: 89 c2 mov %eax,%edx + 1007fe: 8b 45 f4 mov -0xc(%ebp),%eax + 100801: 01 d0 add %edx,%eax + 100803: 8b 10 mov (%eax),%edx + 100805: 8b 45 e8 mov -0x18(%ebp),%eax + 100808: 2b 45 ec sub -0x14(%ebp),%eax + 10080b: 39 c2 cmp %eax,%edx + 10080d: 73 21 jae 100830 + info->eip_file = stabstr + stabs[lline].n_strx; + 10080f: 8b 45 d4 mov -0x2c(%ebp),%eax + 100812: 89 c2 mov %eax,%edx + 100814: 89 d0 mov %edx,%eax + 100816: 01 c0 add %eax,%eax + 100818: 01 d0 add %edx,%eax + 10081a: c1 e0 02 shl $0x2,%eax + 10081d: 89 c2 mov %eax,%edx + 10081f: 8b 45 f4 mov -0xc(%ebp),%eax + 100822: 01 d0 add %edx,%eax + 100824: 8b 10 mov (%eax),%edx + 100826: 8b 45 ec mov -0x14(%ebp),%eax + 100829: 01 c2 add %eax,%edx + 10082b: 8b 45 0c mov 0xc(%ebp),%eax + 10082e: 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) { + 100830: 8b 55 dc mov -0x24(%ebp),%edx + 100833: 8b 45 d8 mov -0x28(%ebp),%eax + 100836: 39 c2 cmp %eax,%edx + 100838: 7d 46 jge 100880 + for (lline = lfun + 1; + 10083a: 8b 45 dc mov -0x24(%ebp),%eax + 10083d: 40 inc %eax + 10083e: 89 45 d4 mov %eax,-0x2c(%ebp) + 100841: eb 16 jmp 100859 + lline < rfun && stabs[lline].n_type == N_PSYM; + lline ++) { + info->eip_fn_narg ++; + 100843: 8b 45 0c mov 0xc(%ebp),%eax + 100846: 8b 40 14 mov 0x14(%eax),%eax + 100849: 8d 50 01 lea 0x1(%eax),%edx + 10084c: 8b 45 0c mov 0xc(%ebp),%eax + 10084f: 89 50 14 mov %edx,0x14(%eax) + lline ++) { + 100852: 8b 45 d4 mov -0x2c(%ebp),%eax + 100855: 40 inc %eax + 100856: 89 45 d4 mov %eax,-0x2c(%ebp) + lline < rfun && stabs[lline].n_type == N_PSYM; + 100859: 8b 55 d4 mov -0x2c(%ebp),%edx + 10085c: 8b 45 d8 mov -0x28(%ebp),%eax + 10085f: 39 c2 cmp %eax,%edx + 100861: 7d 1d jge 100880 + 100863: 8b 45 d4 mov -0x2c(%ebp),%eax + 100866: 89 c2 mov %eax,%edx + 100868: 89 d0 mov %edx,%eax + 10086a: 01 c0 add %eax,%eax + 10086c: 01 d0 add %edx,%eax + 10086e: c1 e0 02 shl $0x2,%eax + 100871: 89 c2 mov %eax,%edx + 100873: 8b 45 f4 mov -0xc(%ebp),%eax + 100876: 01 d0 add %edx,%eax + 100878: 0f b6 40 04 movzbl 0x4(%eax),%eax + 10087c: 3c a0 cmp $0xa0,%al + 10087e: 74 c3 je 100843 + } + } + return 0; + 100880: b8 00 00 00 00 mov $0x0,%eax +} + 100885: 89 ec mov %ebp,%esp + 100887: 5d pop %ebp + 100888: c3 ret + +00100889 : + * 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) { + 100889: 55 push %ebp + 10088a: 89 e5 mov %esp,%ebp + 10088c: 83 ec 18 sub $0x18,%esp + extern char etext[], edata[], end[], kern_init[]; + cprintf("Special kernel symbols:\n"); + 10088f: c7 04 24 56 61 10 00 movl $0x106156,(%esp) + 100896: e8 cb fa ff ff call 100366 + cprintf(" entry 0x%08x (phys)\n", kern_init); + 10089b: c7 44 24 04 36 00 10 movl $0x100036,0x4(%esp) + 1008a2: 00 + 1008a3: c7 04 24 6f 61 10 00 movl $0x10616f,(%esp) + 1008aa: e8 b7 fa ff ff call 100366 + cprintf(" etext 0x%08x (phys)\n", etext); + 1008af: c7 44 24 04 94 60 10 movl $0x106094,0x4(%esp) + 1008b6: 00 + 1008b7: c7 04 24 87 61 10 00 movl $0x106187,(%esp) + 1008be: e8 a3 fa ff ff call 100366 + cprintf(" edata 0x%08x (phys)\n", edata); + 1008c3: c7 44 24 04 36 9a 11 movl $0x119a36,0x4(%esp) + 1008ca: 00 + 1008cb: c7 04 24 9f 61 10 00 movl $0x10619f,(%esp) + 1008d2: e8 8f fa ff ff call 100366 + cprintf(" end 0x%08x (phys)\n", end); + 1008d7: c7 44 24 04 8c cf 11 movl $0x11cf8c,0x4(%esp) + 1008de: 00 + 1008df: c7 04 24 b7 61 10 00 movl $0x1061b7,(%esp) + 1008e6: e8 7b fa ff ff call 100366 + cprintf("Kernel executable memory footprint: %dKB\n", (end - kern_init + 1023)/1024); + 1008eb: b8 8c cf 11 00 mov $0x11cf8c,%eax + 1008f0: 2d 36 00 10 00 sub $0x100036,%eax + 1008f5: 05 ff 03 00 00 add $0x3ff,%eax + 1008fa: 8d 90 ff 03 00 00 lea 0x3ff(%eax),%edx + 100900: 85 c0 test %eax,%eax + 100902: 0f 48 c2 cmovs %edx,%eax + 100905: c1 f8 0a sar $0xa,%eax + 100908: 89 44 24 04 mov %eax,0x4(%esp) + 10090c: c7 04 24 d0 61 10 00 movl $0x1061d0,(%esp) + 100913: e8 4e fa ff ff call 100366 +} + 100918: 90 nop + 100919: 89 ec mov %ebp,%esp + 10091b: 5d pop %ebp + 10091c: c3 ret + +0010091d : +/* * + * 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) { + 10091d: 55 push %ebp + 10091e: 89 e5 mov %esp,%ebp + 100920: 81 ec 48 01 00 00 sub $0x148,%esp + struct eipdebuginfo info; + if (debuginfo_eip(eip, &info) != 0) { + 100926: 8d 45 dc lea -0x24(%ebp),%eax + 100929: 89 44 24 04 mov %eax,0x4(%esp) + 10092d: 8b 45 08 mov 0x8(%ebp),%eax + 100930: 89 04 24 mov %eax,(%esp) + 100933: e8 29 fc ff ff call 100561 + 100938: 85 c0 test %eax,%eax + 10093a: 74 15 je 100951 + cprintf(" : -- 0x%08x --\n", eip); + 10093c: 8b 45 08 mov 0x8(%ebp),%eax + 10093f: 89 44 24 04 mov %eax,0x4(%esp) + 100943: c7 04 24 fa 61 10 00 movl $0x1061fa,(%esp) + 10094a: e8 17 fa ff ff call 100366 + } + fnname[j] = '\0'; + cprintf(" %s:%d: %s+%d\n", info.eip_file, info.eip_line, + fnname, eip - info.eip_fn_addr); + } +} + 10094f: eb 6c jmp 1009bd + for (j = 0; j < info.eip_fn_namelen; j ++) { + 100951: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + 100958: eb 1b jmp 100975 + fnname[j] = info.eip_fn_name[j]; + 10095a: 8b 55 e4 mov -0x1c(%ebp),%edx + 10095d: 8b 45 f4 mov -0xc(%ebp),%eax + 100960: 01 d0 add %edx,%eax + 100962: 0f b6 10 movzbl (%eax),%edx + 100965: 8d 8d dc fe ff ff lea -0x124(%ebp),%ecx + 10096b: 8b 45 f4 mov -0xc(%ebp),%eax + 10096e: 01 c8 add %ecx,%eax + 100970: 88 10 mov %dl,(%eax) + for (j = 0; j < info.eip_fn_namelen; j ++) { + 100972: ff 45 f4 incl -0xc(%ebp) + 100975: 8b 45 e8 mov -0x18(%ebp),%eax + 100978: 39 45 f4 cmp %eax,-0xc(%ebp) + 10097b: 7c dd jl 10095a + fnname[j] = '\0'; + 10097d: 8d 95 dc fe ff ff lea -0x124(%ebp),%edx + 100983: 8b 45 f4 mov -0xc(%ebp),%eax + 100986: 01 d0 add %edx,%eax + 100988: c6 00 00 movb $0x0,(%eax) + fnname, eip - info.eip_fn_addr); + 10098b: 8b 55 ec mov -0x14(%ebp),%edx + cprintf(" %s:%d: %s+%d\n", info.eip_file, info.eip_line, + 10098e: 8b 45 08 mov 0x8(%ebp),%eax + 100991: 29 d0 sub %edx,%eax + 100993: 89 c1 mov %eax,%ecx + 100995: 8b 55 e0 mov -0x20(%ebp),%edx + 100998: 8b 45 dc mov -0x24(%ebp),%eax + 10099b: 89 4c 24 10 mov %ecx,0x10(%esp) + 10099f: 8d 8d dc fe ff ff lea -0x124(%ebp),%ecx + 1009a5: 89 4c 24 0c mov %ecx,0xc(%esp) + 1009a9: 89 54 24 08 mov %edx,0x8(%esp) + 1009ad: 89 44 24 04 mov %eax,0x4(%esp) + 1009b1: c7 04 24 16 62 10 00 movl $0x106216,(%esp) + 1009b8: e8 a9 f9 ff ff call 100366 +} + 1009bd: 90 nop + 1009be: 89 ec mov %ebp,%esp + 1009c0: 5d pop %ebp + 1009c1: c3 ret + +001009c2 : + +static __noinline uint32_t +read_eip(void) { + 1009c2: 55 push %ebp + 1009c3: 89 e5 mov %esp,%ebp + 1009c5: 83 ec 10 sub $0x10,%esp + uint32_t eip; + asm volatile("movl 4(%%ebp), %0" : "=r" (eip)); + 1009c8: 8b 45 04 mov 0x4(%ebp),%eax + 1009cb: 89 45 fc mov %eax,-0x4(%ebp) + return eip; + 1009ce: 8b 45 fc mov -0x4(%ebp),%eax +} + 1009d1: 89 ec mov %ebp,%esp + 1009d3: 5d pop %ebp + 1009d4: c3 ret + +001009d5 : + * + * 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) { + 1009d5: 55 push %ebp + 1009d6: 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] + */ +} + 1009d8: 90 nop + 1009d9: 5d pop %ebp + 1009da: c3 ret + +001009db : +#define MAXARGS 16 +#define WHITESPACE " \t\n\r" + +/* parse - parse the command buffer into whitespace-separated arguments */ +static int +parse(char *buf, char **argv) { + 1009db: 55 push %ebp + 1009dc: 89 e5 mov %esp,%ebp + 1009de: 83 ec 28 sub $0x28,%esp + int argc = 0; + 1009e1: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + while (1) { + // find global whitespace + while (*buf != '\0' && strchr(WHITESPACE, *buf) != NULL) { + 1009e8: eb 0c jmp 1009f6 + *buf ++ = '\0'; + 1009ea: 8b 45 08 mov 0x8(%ebp),%eax + 1009ed: 8d 50 01 lea 0x1(%eax),%edx + 1009f0: 89 55 08 mov %edx,0x8(%ebp) + 1009f3: c6 00 00 movb $0x0,(%eax) + while (*buf != '\0' && strchr(WHITESPACE, *buf) != NULL) { + 1009f6: 8b 45 08 mov 0x8(%ebp),%eax + 1009f9: 0f b6 00 movzbl (%eax),%eax + 1009fc: 84 c0 test %al,%al + 1009fe: 74 1d je 100a1d + 100a00: 8b 45 08 mov 0x8(%ebp),%eax + 100a03: 0f b6 00 movzbl (%eax),%eax + 100a06: 0f be c0 movsbl %al,%eax + 100a09: 89 44 24 04 mov %eax,0x4(%esp) + 100a0d: c7 04 24 a8 62 10 00 movl $0x1062a8,(%esp) + 100a14: e8 33 53 00 00 call 105d4c + 100a19: 85 c0 test %eax,%eax + 100a1b: 75 cd jne 1009ea + } + if (*buf == '\0') { + 100a1d: 8b 45 08 mov 0x8(%ebp),%eax + 100a20: 0f b6 00 movzbl (%eax),%eax + 100a23: 84 c0 test %al,%al + 100a25: 74 65 je 100a8c + break; + } + + // save and scan past next arg + if (argc == MAXARGS - 1) { + 100a27: 83 7d f4 0f cmpl $0xf,-0xc(%ebp) + 100a2b: 75 14 jne 100a41 + cprintf("Too many arguments (max %d).\n", MAXARGS); + 100a2d: c7 44 24 04 10 00 00 movl $0x10,0x4(%esp) + 100a34: 00 + 100a35: c7 04 24 ad 62 10 00 movl $0x1062ad,(%esp) + 100a3c: e8 25 f9 ff ff call 100366 + } + argv[argc ++] = buf; + 100a41: 8b 45 f4 mov -0xc(%ebp),%eax + 100a44: 8d 50 01 lea 0x1(%eax),%edx + 100a47: 89 55 f4 mov %edx,-0xc(%ebp) + 100a4a: 8d 14 85 00 00 00 00 lea 0x0(,%eax,4),%edx + 100a51: 8b 45 0c mov 0xc(%ebp),%eax + 100a54: 01 c2 add %eax,%edx + 100a56: 8b 45 08 mov 0x8(%ebp),%eax + 100a59: 89 02 mov %eax,(%edx) + while (*buf != '\0' && strchr(WHITESPACE, *buf) == NULL) { + 100a5b: eb 03 jmp 100a60 + buf ++; + 100a5d: ff 45 08 incl 0x8(%ebp) + while (*buf != '\0' && strchr(WHITESPACE, *buf) == NULL) { + 100a60: 8b 45 08 mov 0x8(%ebp),%eax + 100a63: 0f b6 00 movzbl (%eax),%eax + 100a66: 84 c0 test %al,%al + 100a68: 74 8c je 1009f6 + 100a6a: 8b 45 08 mov 0x8(%ebp),%eax + 100a6d: 0f b6 00 movzbl (%eax),%eax + 100a70: 0f be c0 movsbl %al,%eax + 100a73: 89 44 24 04 mov %eax,0x4(%esp) + 100a77: c7 04 24 a8 62 10 00 movl $0x1062a8,(%esp) + 100a7e: e8 c9 52 00 00 call 105d4c + 100a83: 85 c0 test %eax,%eax + 100a85: 74 d6 je 100a5d + while (*buf != '\0' && strchr(WHITESPACE, *buf) != NULL) { + 100a87: e9 6a ff ff ff jmp 1009f6 + break; + 100a8c: 90 nop + } + } + return argc; + 100a8d: 8b 45 f4 mov -0xc(%ebp),%eax +} + 100a90: 89 ec mov %ebp,%esp + 100a92: 5d pop %ebp + 100a93: c3 ret + +00100a94 : +/* * + * 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) { + 100a94: 55 push %ebp + 100a95: 89 e5 mov %esp,%ebp + 100a97: 83 ec 68 sub $0x68,%esp + 100a9a: 89 5d fc mov %ebx,-0x4(%ebp) + char *argv[MAXARGS]; + int argc = parse(buf, argv); + 100a9d: 8d 45 b0 lea -0x50(%ebp),%eax + 100aa0: 89 44 24 04 mov %eax,0x4(%esp) + 100aa4: 8b 45 08 mov 0x8(%ebp),%eax + 100aa7: 89 04 24 mov %eax,(%esp) + 100aaa: e8 2c ff ff ff call 1009db + 100aaf: 89 45 f0 mov %eax,-0x10(%ebp) + if (argc == 0) { + 100ab2: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) + 100ab6: 75 0a jne 100ac2 + return 0; + 100ab8: b8 00 00 00 00 mov $0x0,%eax + 100abd: e9 83 00 00 00 jmp 100b45 + } + int i; + for (i = 0; i < NCOMMANDS; i ++) { + 100ac2: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + 100ac9: eb 5a jmp 100b25 + if (strcmp(commands[i].name, argv[0]) == 0) { + 100acb: 8b 55 b0 mov -0x50(%ebp),%edx + 100ace: 8b 4d f4 mov -0xc(%ebp),%ecx + 100ad1: 89 c8 mov %ecx,%eax + 100ad3: 01 c0 add %eax,%eax + 100ad5: 01 c8 add %ecx,%eax + 100ad7: c1 e0 02 shl $0x2,%eax + 100ada: 05 00 90 11 00 add $0x119000,%eax + 100adf: 8b 00 mov (%eax),%eax + 100ae1: 89 54 24 04 mov %edx,0x4(%esp) + 100ae5: 89 04 24 mov %eax,(%esp) + 100ae8: e8 c3 51 00 00 call 105cb0 + 100aed: 85 c0 test %eax,%eax + 100aef: 75 31 jne 100b22 + return commands[i].func(argc - 1, argv + 1, tf); + 100af1: 8b 55 f4 mov -0xc(%ebp),%edx + 100af4: 89 d0 mov %edx,%eax + 100af6: 01 c0 add %eax,%eax + 100af8: 01 d0 add %edx,%eax + 100afa: c1 e0 02 shl $0x2,%eax + 100afd: 05 08 90 11 00 add $0x119008,%eax + 100b02: 8b 10 mov (%eax),%edx + 100b04: 8d 45 b0 lea -0x50(%ebp),%eax + 100b07: 83 c0 04 add $0x4,%eax + 100b0a: 8b 4d f0 mov -0x10(%ebp),%ecx + 100b0d: 8d 59 ff lea -0x1(%ecx),%ebx + 100b10: 8b 4d 0c mov 0xc(%ebp),%ecx + 100b13: 89 4c 24 08 mov %ecx,0x8(%esp) + 100b17: 89 44 24 04 mov %eax,0x4(%esp) + 100b1b: 89 1c 24 mov %ebx,(%esp) + 100b1e: ff d2 call *%edx + 100b20: eb 23 jmp 100b45 + for (i = 0; i < NCOMMANDS; i ++) { + 100b22: ff 45 f4 incl -0xc(%ebp) + 100b25: 8b 45 f4 mov -0xc(%ebp),%eax + 100b28: 83 f8 02 cmp $0x2,%eax + 100b2b: 76 9e jbe 100acb + } + } + cprintf("Unknown command '%s'\n", argv[0]); + 100b2d: 8b 45 b0 mov -0x50(%ebp),%eax + 100b30: 89 44 24 04 mov %eax,0x4(%esp) + 100b34: c7 04 24 cb 62 10 00 movl $0x1062cb,(%esp) + 100b3b: e8 26 f8 ff ff call 100366 + return 0; + 100b40: b8 00 00 00 00 mov $0x0,%eax +} + 100b45: 8b 5d fc mov -0x4(%ebp),%ebx + 100b48: 89 ec mov %ebp,%esp + 100b4a: 5d pop %ebp + 100b4b: c3 ret + +00100b4c : + +/***** Implementations of basic kernel monitor commands *****/ + +void +kmonitor(struct trapframe *tf) { + 100b4c: 55 push %ebp + 100b4d: 89 e5 mov %esp,%ebp + 100b4f: 83 ec 28 sub $0x28,%esp + cprintf("Welcome to the kernel debug monitor!!\n"); + 100b52: c7 04 24 e4 62 10 00 movl $0x1062e4,(%esp) + 100b59: e8 08 f8 ff ff call 100366 + cprintf("Type 'help' for a list of commands.\n"); + 100b5e: c7 04 24 0c 63 10 00 movl $0x10630c,(%esp) + 100b65: e8 fc f7 ff ff call 100366 + + if (tf != NULL) { + 100b6a: 83 7d 08 00 cmpl $0x0,0x8(%ebp) + 100b6e: 74 0b je 100b7b + print_trapframe(tf); + 100b70: 8b 45 08 mov 0x8(%ebp),%eax + 100b73: 89 04 24 mov %eax,(%esp) + 100b76: e8 cf 0e 00 00 call 101a4a + } + + char *buf; + while (1) { + if ((buf = readline("K> ")) != NULL) { + 100b7b: c7 04 24 31 63 10 00 movl $0x106331,(%esp) + 100b82: e8 d0 f6 ff ff call 100257 + 100b87: 89 45 f4 mov %eax,-0xc(%ebp) + 100b8a: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) + 100b8e: 74 eb je 100b7b + if (runcmd(buf, tf) < 0) { + 100b90: 8b 45 08 mov 0x8(%ebp),%eax + 100b93: 89 44 24 04 mov %eax,0x4(%esp) + 100b97: 8b 45 f4 mov -0xc(%ebp),%eax + 100b9a: 89 04 24 mov %eax,(%esp) + 100b9d: e8 f2 fe ff ff call 100a94 + 100ba2: 85 c0 test %eax,%eax + 100ba4: 78 02 js 100ba8 + if ((buf = readline("K> ")) != NULL) { + 100ba6: eb d3 jmp 100b7b + break; + 100ba8: 90 nop + } + } + } +} + 100ba9: 90 nop + 100baa: 89 ec mov %ebp,%esp + 100bac: 5d pop %ebp + 100bad: c3 ret + +00100bae : + +/* mon_help - print the information about mon_* functions */ +int +mon_help(int argc, char **argv, struct trapframe *tf) { + 100bae: 55 push %ebp + 100baf: 89 e5 mov %esp,%ebp + 100bb1: 83 ec 28 sub $0x28,%esp + int i; + for (i = 0; i < NCOMMANDS; i ++) { + 100bb4: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + 100bbb: eb 3d jmp 100bfa + cprintf("%s - %s\n", commands[i].name, commands[i].desc); + 100bbd: 8b 55 f4 mov -0xc(%ebp),%edx + 100bc0: 89 d0 mov %edx,%eax + 100bc2: 01 c0 add %eax,%eax + 100bc4: 01 d0 add %edx,%eax + 100bc6: c1 e0 02 shl $0x2,%eax + 100bc9: 05 04 90 11 00 add $0x119004,%eax + 100bce: 8b 10 mov (%eax),%edx + 100bd0: 8b 4d f4 mov -0xc(%ebp),%ecx + 100bd3: 89 c8 mov %ecx,%eax + 100bd5: 01 c0 add %eax,%eax + 100bd7: 01 c8 add %ecx,%eax + 100bd9: c1 e0 02 shl $0x2,%eax + 100bdc: 05 00 90 11 00 add $0x119000,%eax + 100be1: 8b 00 mov (%eax),%eax + 100be3: 89 54 24 08 mov %edx,0x8(%esp) + 100be7: 89 44 24 04 mov %eax,0x4(%esp) + 100beb: c7 04 24 35 63 10 00 movl $0x106335,(%esp) + 100bf2: e8 6f f7 ff ff call 100366 + for (i = 0; i < NCOMMANDS; i ++) { + 100bf7: ff 45 f4 incl -0xc(%ebp) + 100bfa: 8b 45 f4 mov -0xc(%ebp),%eax + 100bfd: 83 f8 02 cmp $0x2,%eax + 100c00: 76 bb jbe 100bbd + } + return 0; + 100c02: b8 00 00 00 00 mov $0x0,%eax +} + 100c07: 89 ec mov %ebp,%esp + 100c09: 5d pop %ebp + 100c0a: c3 ret + +00100c0b : +/* * + * 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) { + 100c0b: 55 push %ebp + 100c0c: 89 e5 mov %esp,%ebp + 100c0e: 83 ec 08 sub $0x8,%esp + print_kerninfo(); + 100c11: e8 73 fc ff ff call 100889 + return 0; + 100c16: b8 00 00 00 00 mov $0x0,%eax +} + 100c1b: 89 ec mov %ebp,%esp + 100c1d: 5d pop %ebp + 100c1e: c3 ret + +00100c1f : +/* * + * 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) { + 100c1f: 55 push %ebp + 100c20: 89 e5 mov %esp,%ebp + 100c22: 83 ec 08 sub $0x8,%esp + print_stackframe(); + 100c25: e8 ab fd ff ff call 1009d5 + return 0; + 100c2a: b8 00 00 00 00 mov $0x0,%eax +} + 100c2f: 89 ec mov %ebp,%esp + 100c31: 5d pop %ebp + 100c32: c3 ret + +00100c33 <__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, ...) { + 100c33: 55 push %ebp + 100c34: 89 e5 mov %esp,%ebp + 100c36: 83 ec 28 sub $0x28,%esp + if (is_panic) { + 100c39: a1 20 c4 11 00 mov 0x11c420,%eax + 100c3e: 85 c0 test %eax,%eax + 100c40: 75 5b jne 100c9d <__panic+0x6a> + goto panic_dead; + } + is_panic = 1; + 100c42: c7 05 20 c4 11 00 01 movl $0x1,0x11c420 + 100c49: 00 00 00 + + // print the 'message' + va_list ap; + va_start(ap, fmt); + 100c4c: 8d 45 14 lea 0x14(%ebp),%eax + 100c4f: 89 45 f4 mov %eax,-0xc(%ebp) + cprintf("kernel panic at %s:%d:\n ", file, line); + 100c52: 8b 45 0c mov 0xc(%ebp),%eax + 100c55: 89 44 24 08 mov %eax,0x8(%esp) + 100c59: 8b 45 08 mov 0x8(%ebp),%eax + 100c5c: 89 44 24 04 mov %eax,0x4(%esp) + 100c60: c7 04 24 3e 63 10 00 movl $0x10633e,(%esp) + 100c67: e8 fa f6 ff ff call 100366 + vcprintf(fmt, ap); + 100c6c: 8b 45 f4 mov -0xc(%ebp),%eax + 100c6f: 89 44 24 04 mov %eax,0x4(%esp) + 100c73: 8b 45 10 mov 0x10(%ebp),%eax + 100c76: 89 04 24 mov %eax,(%esp) + 100c79: e8 b3 f6 ff ff call 100331 + cprintf("\n"); + 100c7e: c7 04 24 5a 63 10 00 movl $0x10635a,(%esp) + 100c85: e8 dc f6 ff ff call 100366 + + cprintf("stack trackback:\n"); + 100c8a: c7 04 24 5c 63 10 00 movl $0x10635c,(%esp) + 100c91: e8 d0 f6 ff ff call 100366 + print_stackframe(); + 100c96: e8 3a fd ff ff call 1009d5 + 100c9b: eb 01 jmp 100c9e <__panic+0x6b> + goto panic_dead; + 100c9d: 90 nop + + va_end(ap); + +panic_dead: + intr_disable(); + 100c9e: e8 e9 09 00 00 call 10168c + while (1) { + kmonitor(NULL); + 100ca3: c7 04 24 00 00 00 00 movl $0x0,(%esp) + 100caa: e8 9d fe ff ff call 100b4c + 100caf: eb f2 jmp 100ca3 <__panic+0x70> + +00100cb1 <__warn>: + } +} + +/* __warn - like panic, but don't */ +void +__warn(const char *file, int line, const char *fmt, ...) { + 100cb1: 55 push %ebp + 100cb2: 89 e5 mov %esp,%ebp + 100cb4: 83 ec 28 sub $0x28,%esp + va_list ap; + va_start(ap, fmt); + 100cb7: 8d 45 14 lea 0x14(%ebp),%eax + 100cba: 89 45 f4 mov %eax,-0xc(%ebp) + cprintf("kernel warning at %s:%d:\n ", file, line); + 100cbd: 8b 45 0c mov 0xc(%ebp),%eax + 100cc0: 89 44 24 08 mov %eax,0x8(%esp) + 100cc4: 8b 45 08 mov 0x8(%ebp),%eax + 100cc7: 89 44 24 04 mov %eax,0x4(%esp) + 100ccb: c7 04 24 6e 63 10 00 movl $0x10636e,(%esp) + 100cd2: e8 8f f6 ff ff call 100366 + vcprintf(fmt, ap); + 100cd7: 8b 45 f4 mov -0xc(%ebp),%eax + 100cda: 89 44 24 04 mov %eax,0x4(%esp) + 100cde: 8b 45 10 mov 0x10(%ebp),%eax + 100ce1: 89 04 24 mov %eax,(%esp) + 100ce4: e8 48 f6 ff ff call 100331 + cprintf("\n"); + 100ce9: c7 04 24 5a 63 10 00 movl $0x10635a,(%esp) + 100cf0: e8 71 f6 ff ff call 100366 + va_end(ap); +} + 100cf5: 90 nop + 100cf6: 89 ec mov %ebp,%esp + 100cf8: 5d pop %ebp + 100cf9: c3 ret + +00100cfa : + +bool +is_kernel_panic(void) { + 100cfa: 55 push %ebp + 100cfb: 89 e5 mov %esp,%ebp + return is_panic; + 100cfd: a1 20 c4 11 00 mov 0x11c420,%eax +} + 100d02: 5d pop %ebp + 100d03: c3 ret + +00100d04 : +/* * + * clock_init - initialize 8253 clock to interrupt 100 times per second, + * and then enable IRQ_TIMER. + * */ +void +clock_init(void) { + 100d04: 55 push %ebp + 100d05: 89 e5 mov %esp,%ebp + 100d07: 83 ec 28 sub $0x28,%esp + 100d0a: 66 c7 45 ee 43 00 movw $0x43,-0x12(%ebp) + 100d10: 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"); + 100d14: 0f b6 45 ed movzbl -0x13(%ebp),%eax + 100d18: 0f b7 55 ee movzwl -0x12(%ebp),%edx + 100d1c: ee out %al,(%dx) +} + 100d1d: 90 nop + 100d1e: 66 c7 45 f2 40 00 movw $0x40,-0xe(%ebp) + 100d24: c6 45 f1 9c movb $0x9c,-0xf(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 100d28: 0f b6 45 f1 movzbl -0xf(%ebp),%eax + 100d2c: 0f b7 55 f2 movzwl -0xe(%ebp),%edx + 100d30: ee out %al,(%dx) +} + 100d31: 90 nop + 100d32: 66 c7 45 f6 40 00 movw $0x40,-0xa(%ebp) + 100d38: c6 45 f5 2e movb $0x2e,-0xb(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 100d3c: 0f b6 45 f5 movzbl -0xb(%ebp),%eax + 100d40: 0f b7 55 f6 movzwl -0xa(%ebp),%edx + 100d44: ee out %al,(%dx) +} + 100d45: 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; + 100d46: c7 05 24 c4 11 00 00 movl $0x0,0x11c424 + 100d4d: 00 00 00 + + cprintf("++ setup timer interrupts\n"); + 100d50: c7 04 24 8c 63 10 00 movl $0x10638c,(%esp) + 100d57: e8 0a f6 ff ff call 100366 + pic_enable(IRQ_TIMER); + 100d5c: c7 04 24 00 00 00 00 movl $0x0,(%esp) + 100d63: e8 89 09 00 00 call 1016f1 +} + 100d68: 90 nop + 100d69: 89 ec mov %ebp,%esp + 100d6b: 5d pop %ebp + 100d6c: c3 ret + +00100d6d <__intr_save>: +#include +#include +#include + +static inline bool +__intr_save(void) { + 100d6d: 55 push %ebp + 100d6e: 89 e5 mov %esp,%ebp + 100d70: 83 ec 18 sub $0x18,%esp +} + +static inline uint32_t +read_eflags(void) { + uint32_t eflags; + asm volatile ("pushfl; popl %0" : "=r" (eflags)); + 100d73: 9c pushf + 100d74: 58 pop %eax + 100d75: 89 45 f4 mov %eax,-0xc(%ebp) + return eflags; + 100d78: 8b 45 f4 mov -0xc(%ebp),%eax + if (read_eflags() & FL_IF) { + 100d7b: 25 00 02 00 00 and $0x200,%eax + 100d80: 85 c0 test %eax,%eax + 100d82: 74 0c je 100d90 <__intr_save+0x23> + intr_disable(); + 100d84: e8 03 09 00 00 call 10168c + return 1; + 100d89: b8 01 00 00 00 mov $0x1,%eax + 100d8e: eb 05 jmp 100d95 <__intr_save+0x28> + } + return 0; + 100d90: b8 00 00 00 00 mov $0x0,%eax +} + 100d95: 89 ec mov %ebp,%esp + 100d97: 5d pop %ebp + 100d98: c3 ret + +00100d99 <__intr_restore>: + +static inline void +__intr_restore(bool flag) { + 100d99: 55 push %ebp + 100d9a: 89 e5 mov %esp,%ebp + 100d9c: 83 ec 08 sub $0x8,%esp + if (flag) { + 100d9f: 83 7d 08 00 cmpl $0x0,0x8(%ebp) + 100da3: 74 05 je 100daa <__intr_restore+0x11> + intr_enable(); + 100da5: e8 da 08 00 00 call 101684 + } +} + 100daa: 90 nop + 100dab: 89 ec mov %ebp,%esp + 100dad: 5d pop %ebp + 100dae: c3 ret + +00100daf : +#include +#include + +/* stupid I/O delay routine necessitated by historical PC design flaws */ +static void +delay(void) { + 100daf: 55 push %ebp + 100db0: 89 e5 mov %esp,%ebp + 100db2: 83 ec 10 sub $0x10,%esp + 100db5: 66 c7 45 f2 84 00 movw $0x84,-0xe(%ebp) + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); + 100dbb: 0f b7 45 f2 movzwl -0xe(%ebp),%eax + 100dbf: 89 c2 mov %eax,%edx + 100dc1: ec in (%dx),%al + 100dc2: 88 45 f1 mov %al,-0xf(%ebp) + 100dc5: 66 c7 45 f6 84 00 movw $0x84,-0xa(%ebp) + 100dcb: 0f b7 45 f6 movzwl -0xa(%ebp),%eax + 100dcf: 89 c2 mov %eax,%edx + 100dd1: ec in (%dx),%al + 100dd2: 88 45 f5 mov %al,-0xb(%ebp) + 100dd5: 66 c7 45 fa 84 00 movw $0x84,-0x6(%ebp) + 100ddb: 0f b7 45 fa movzwl -0x6(%ebp),%eax + 100ddf: 89 c2 mov %eax,%edx + 100de1: ec in (%dx),%al + 100de2: 88 45 f9 mov %al,-0x7(%ebp) + 100de5: 66 c7 45 fe 84 00 movw $0x84,-0x2(%ebp) + 100deb: 0f b7 45 fe movzwl -0x2(%ebp),%eax + 100def: 89 c2 mov %eax,%edx + 100df1: ec in (%dx),%al + 100df2: 88 45 fd mov %al,-0x3(%ebp) + inb(0x84); + inb(0x84); + inb(0x84); + inb(0x84); +} + 100df5: 90 nop + 100df6: 89 ec mov %ebp,%esp + 100df8: 5d pop %ebp + 100df9: c3 ret + +00100dfa : +static uint16_t addr_6845; + +/* TEXT-mode CGA/VGA display output */ + +static void +cga_init(void) { + 100dfa: 55 push %ebp + 100dfb: 89 e5 mov %esp,%ebp + 100dfd: 83 ec 20 sub $0x20,%esp + volatile uint16_t *cp = (uint16_t *)(CGA_BUF + KERNBASE); + 100e00: c7 45 fc 00 80 0b c0 movl $0xc00b8000,-0x4(%ebp) + uint16_t was = *cp; + 100e07: 8b 45 fc mov -0x4(%ebp),%eax + 100e0a: 0f b7 00 movzwl (%eax),%eax + 100e0d: 66 89 45 fa mov %ax,-0x6(%ebp) + *cp = (uint16_t) 0xA55A; + 100e11: 8b 45 fc mov -0x4(%ebp),%eax + 100e14: 66 c7 00 5a a5 movw $0xa55a,(%eax) + if (*cp != 0xA55A) { + 100e19: 8b 45 fc mov -0x4(%ebp),%eax + 100e1c: 0f b7 00 movzwl (%eax),%eax + 100e1f: 0f b7 c0 movzwl %ax,%eax + 100e22: 3d 5a a5 00 00 cmp $0xa55a,%eax + 100e27: 74 12 je 100e3b + cp = (uint16_t*)(MONO_BUF + KERNBASE); + 100e29: c7 45 fc 00 00 0b c0 movl $0xc00b0000,-0x4(%ebp) + addr_6845 = MONO_BASE; + 100e30: 66 c7 05 46 c4 11 00 movw $0x3b4,0x11c446 + 100e37: b4 03 + 100e39: eb 13 jmp 100e4e + } else { + *cp = was; + 100e3b: 8b 45 fc mov -0x4(%ebp),%eax + 100e3e: 0f b7 55 fa movzwl -0x6(%ebp),%edx + 100e42: 66 89 10 mov %dx,(%eax) + addr_6845 = CGA_BASE; + 100e45: 66 c7 05 46 c4 11 00 movw $0x3d4,0x11c446 + 100e4c: d4 03 + } + + // Extract cursor location + uint32_t pos; + outb(addr_6845, 14); + 100e4e: 0f b7 05 46 c4 11 00 movzwl 0x11c446,%eax + 100e55: 66 89 45 e6 mov %ax,-0x1a(%ebp) + 100e59: c6 45 e5 0e movb $0xe,-0x1b(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 100e5d: 0f b6 45 e5 movzbl -0x1b(%ebp),%eax + 100e61: 0f b7 55 e6 movzwl -0x1a(%ebp),%edx + 100e65: ee out %al,(%dx) +} + 100e66: 90 nop + pos = inb(addr_6845 + 1) << 8; + 100e67: 0f b7 05 46 c4 11 00 movzwl 0x11c446,%eax + 100e6e: 40 inc %eax + 100e6f: 0f b7 c0 movzwl %ax,%eax + 100e72: 66 89 45 ea mov %ax,-0x16(%ebp) + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); + 100e76: 0f b7 45 ea movzwl -0x16(%ebp),%eax + 100e7a: 89 c2 mov %eax,%edx + 100e7c: ec in (%dx),%al + 100e7d: 88 45 e9 mov %al,-0x17(%ebp) + return data; + 100e80: 0f b6 45 e9 movzbl -0x17(%ebp),%eax + 100e84: 0f b6 c0 movzbl %al,%eax + 100e87: c1 e0 08 shl $0x8,%eax + 100e8a: 89 45 f4 mov %eax,-0xc(%ebp) + outb(addr_6845, 15); + 100e8d: 0f b7 05 46 c4 11 00 movzwl 0x11c446,%eax + 100e94: 66 89 45 ee mov %ax,-0x12(%ebp) + 100e98: c6 45 ed 0f movb $0xf,-0x13(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 100e9c: 0f b6 45 ed movzbl -0x13(%ebp),%eax + 100ea0: 0f b7 55 ee movzwl -0x12(%ebp),%edx + 100ea4: ee out %al,(%dx) +} + 100ea5: 90 nop + pos |= inb(addr_6845 + 1); + 100ea6: 0f b7 05 46 c4 11 00 movzwl 0x11c446,%eax + 100ead: 40 inc %eax + 100eae: 0f b7 c0 movzwl %ax,%eax + 100eb1: 66 89 45 f2 mov %ax,-0xe(%ebp) + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); + 100eb5: 0f b7 45 f2 movzwl -0xe(%ebp),%eax + 100eb9: 89 c2 mov %eax,%edx + 100ebb: ec in (%dx),%al + 100ebc: 88 45 f1 mov %al,-0xf(%ebp) + return data; + 100ebf: 0f b6 45 f1 movzbl -0xf(%ebp),%eax + 100ec3: 0f b6 c0 movzbl %al,%eax + 100ec6: 09 45 f4 or %eax,-0xc(%ebp) + + crt_buf = (uint16_t*) cp; + 100ec9: 8b 45 fc mov -0x4(%ebp),%eax + 100ecc: a3 40 c4 11 00 mov %eax,0x11c440 + crt_pos = pos; + 100ed1: 8b 45 f4 mov -0xc(%ebp),%eax + 100ed4: 0f b7 c0 movzwl %ax,%eax + 100ed7: 66 a3 44 c4 11 00 mov %ax,0x11c444 +} + 100edd: 90 nop + 100ede: 89 ec mov %ebp,%esp + 100ee0: 5d pop %ebp + 100ee1: c3 ret + +00100ee2 : + +static bool serial_exists = 0; + +static void +serial_init(void) { + 100ee2: 55 push %ebp + 100ee3: 89 e5 mov %esp,%ebp + 100ee5: 83 ec 48 sub $0x48,%esp + 100ee8: 66 c7 45 d2 fa 03 movw $0x3fa,-0x2e(%ebp) + 100eee: c6 45 d1 00 movb $0x0,-0x2f(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 100ef2: 0f b6 45 d1 movzbl -0x2f(%ebp),%eax + 100ef6: 0f b7 55 d2 movzwl -0x2e(%ebp),%edx + 100efa: ee out %al,(%dx) +} + 100efb: 90 nop + 100efc: 66 c7 45 d6 fb 03 movw $0x3fb,-0x2a(%ebp) + 100f02: c6 45 d5 80 movb $0x80,-0x2b(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 100f06: 0f b6 45 d5 movzbl -0x2b(%ebp),%eax + 100f0a: 0f b7 55 d6 movzwl -0x2a(%ebp),%edx + 100f0e: ee out %al,(%dx) +} + 100f0f: 90 nop + 100f10: 66 c7 45 da f8 03 movw $0x3f8,-0x26(%ebp) + 100f16: c6 45 d9 0c movb $0xc,-0x27(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 100f1a: 0f b6 45 d9 movzbl -0x27(%ebp),%eax + 100f1e: 0f b7 55 da movzwl -0x26(%ebp),%edx + 100f22: ee out %al,(%dx) +} + 100f23: 90 nop + 100f24: 66 c7 45 de f9 03 movw $0x3f9,-0x22(%ebp) + 100f2a: c6 45 dd 00 movb $0x0,-0x23(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 100f2e: 0f b6 45 dd movzbl -0x23(%ebp),%eax + 100f32: 0f b7 55 de movzwl -0x22(%ebp),%edx + 100f36: ee out %al,(%dx) +} + 100f37: 90 nop + 100f38: 66 c7 45 e2 fb 03 movw $0x3fb,-0x1e(%ebp) + 100f3e: c6 45 e1 03 movb $0x3,-0x1f(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 100f42: 0f b6 45 e1 movzbl -0x1f(%ebp),%eax + 100f46: 0f b7 55 e2 movzwl -0x1e(%ebp),%edx + 100f4a: ee out %al,(%dx) +} + 100f4b: 90 nop + 100f4c: 66 c7 45 e6 fc 03 movw $0x3fc,-0x1a(%ebp) + 100f52: c6 45 e5 00 movb $0x0,-0x1b(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 100f56: 0f b6 45 e5 movzbl -0x1b(%ebp),%eax + 100f5a: 0f b7 55 e6 movzwl -0x1a(%ebp),%edx + 100f5e: ee out %al,(%dx) +} + 100f5f: 90 nop + 100f60: 66 c7 45 ea f9 03 movw $0x3f9,-0x16(%ebp) + 100f66: c6 45 e9 01 movb $0x1,-0x17(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 100f6a: 0f b6 45 e9 movzbl -0x17(%ebp),%eax + 100f6e: 0f b7 55 ea movzwl -0x16(%ebp),%edx + 100f72: ee out %al,(%dx) +} + 100f73: 90 nop + 100f74: 66 c7 45 ee fd 03 movw $0x3fd,-0x12(%ebp) + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); + 100f7a: 0f b7 45 ee movzwl -0x12(%ebp),%eax + 100f7e: 89 c2 mov %eax,%edx + 100f80: ec in (%dx),%al + 100f81: 88 45 ed mov %al,-0x13(%ebp) + return data; + 100f84: 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); + 100f88: 3c ff cmp $0xff,%al + 100f8a: 0f 95 c0 setne %al + 100f8d: 0f b6 c0 movzbl %al,%eax + 100f90: a3 48 c4 11 00 mov %eax,0x11c448 + 100f95: 66 c7 45 f2 fa 03 movw $0x3fa,-0xe(%ebp) + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); + 100f9b: 0f b7 45 f2 movzwl -0xe(%ebp),%eax + 100f9f: 89 c2 mov %eax,%edx + 100fa1: ec in (%dx),%al + 100fa2: 88 45 f1 mov %al,-0xf(%ebp) + 100fa5: 66 c7 45 f6 f8 03 movw $0x3f8,-0xa(%ebp) + 100fab: 0f b7 45 f6 movzwl -0xa(%ebp),%eax + 100faf: 89 c2 mov %eax,%edx + 100fb1: ec in (%dx),%al + 100fb2: 88 45 f5 mov %al,-0xb(%ebp) + (void) inb(COM1+COM_IIR); + (void) inb(COM1+COM_RX); + + if (serial_exists) { + 100fb5: a1 48 c4 11 00 mov 0x11c448,%eax + 100fba: 85 c0 test %eax,%eax + 100fbc: 74 0c je 100fca + pic_enable(IRQ_COM1); + 100fbe: c7 04 24 04 00 00 00 movl $0x4,(%esp) + 100fc5: e8 27 07 00 00 call 1016f1 + } +} + 100fca: 90 nop + 100fcb: 89 ec mov %ebp,%esp + 100fcd: 5d pop %ebp + 100fce: c3 ret + +00100fcf : + +static void +lpt_putc_sub(int c) { + 100fcf: 55 push %ebp + 100fd0: 89 e5 mov %esp,%ebp + 100fd2: 83 ec 20 sub $0x20,%esp + int i; + for (i = 0; !(inb(LPTPORT + 1) & 0x80) && i < 12800; i ++) { + 100fd5: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + 100fdc: eb 08 jmp 100fe6 + delay(); + 100fde: e8 cc fd ff ff call 100daf + for (i = 0; !(inb(LPTPORT + 1) & 0x80) && i < 12800; i ++) { + 100fe3: ff 45 fc incl -0x4(%ebp) + 100fe6: 66 c7 45 fa 79 03 movw $0x379,-0x6(%ebp) + 100fec: 0f b7 45 fa movzwl -0x6(%ebp),%eax + 100ff0: 89 c2 mov %eax,%edx + 100ff2: ec in (%dx),%al + 100ff3: 88 45 f9 mov %al,-0x7(%ebp) + return data; + 100ff6: 0f b6 45 f9 movzbl -0x7(%ebp),%eax + 100ffa: 84 c0 test %al,%al + 100ffc: 78 09 js 101007 + 100ffe: 81 7d fc ff 31 00 00 cmpl $0x31ff,-0x4(%ebp) + 101005: 7e d7 jle 100fde + } + outb(LPTPORT + 0, c); + 101007: 8b 45 08 mov 0x8(%ebp),%eax + 10100a: 0f b6 c0 movzbl %al,%eax + 10100d: 66 c7 45 ee 78 03 movw $0x378,-0x12(%ebp) + 101013: 88 45 ed mov %al,-0x13(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 101016: 0f b6 45 ed movzbl -0x13(%ebp),%eax + 10101a: 0f b7 55 ee movzwl -0x12(%ebp),%edx + 10101e: ee out %al,(%dx) +} + 10101f: 90 nop + 101020: 66 c7 45 f2 7a 03 movw $0x37a,-0xe(%ebp) + 101026: c6 45 f1 0d movb $0xd,-0xf(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 10102a: 0f b6 45 f1 movzbl -0xf(%ebp),%eax + 10102e: 0f b7 55 f2 movzwl -0xe(%ebp),%edx + 101032: ee out %al,(%dx) +} + 101033: 90 nop + 101034: 66 c7 45 f6 7a 03 movw $0x37a,-0xa(%ebp) + 10103a: c6 45 f5 08 movb $0x8,-0xb(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 10103e: 0f b6 45 f5 movzbl -0xb(%ebp),%eax + 101042: 0f b7 55 f6 movzwl -0xa(%ebp),%edx + 101046: ee out %al,(%dx) +} + 101047: 90 nop + outb(LPTPORT + 2, 0x08 | 0x04 | 0x01); + outb(LPTPORT + 2, 0x08); +} + 101048: 90 nop + 101049: 89 ec mov %ebp,%esp + 10104b: 5d pop %ebp + 10104c: c3 ret + +0010104d : + +/* lpt_putc - copy console output to parallel port */ +static void +lpt_putc(int c) { + 10104d: 55 push %ebp + 10104e: 89 e5 mov %esp,%ebp + 101050: 83 ec 04 sub $0x4,%esp + if (c != '\b') { + 101053: 83 7d 08 08 cmpl $0x8,0x8(%ebp) + 101057: 74 0d je 101066 + lpt_putc_sub(c); + 101059: 8b 45 08 mov 0x8(%ebp),%eax + 10105c: 89 04 24 mov %eax,(%esp) + 10105f: e8 6b ff ff ff call 100fcf + else { + lpt_putc_sub('\b'); + lpt_putc_sub(' '); + lpt_putc_sub('\b'); + } +} + 101064: eb 24 jmp 10108a + lpt_putc_sub('\b'); + 101066: c7 04 24 08 00 00 00 movl $0x8,(%esp) + 10106d: e8 5d ff ff ff call 100fcf + lpt_putc_sub(' '); + 101072: c7 04 24 20 00 00 00 movl $0x20,(%esp) + 101079: e8 51 ff ff ff call 100fcf + lpt_putc_sub('\b'); + 10107e: c7 04 24 08 00 00 00 movl $0x8,(%esp) + 101085: e8 45 ff ff ff call 100fcf +} + 10108a: 90 nop + 10108b: 89 ec mov %ebp,%esp + 10108d: 5d pop %ebp + 10108e: c3 ret + +0010108f : + +/* cga_putc - print character to console */ +static void +cga_putc(int c) { + 10108f: 55 push %ebp + 101090: 89 e5 mov %esp,%ebp + 101092: 83 ec 38 sub $0x38,%esp + 101095: 89 5d fc mov %ebx,-0x4(%ebp) + // set black on white + if (!(c & ~0xFF)) { + 101098: 8b 45 08 mov 0x8(%ebp),%eax + 10109b: 25 00 ff ff ff and $0xffffff00,%eax + 1010a0: 85 c0 test %eax,%eax + 1010a2: 75 07 jne 1010ab + c |= 0x0700; + 1010a4: 81 4d 08 00 07 00 00 orl $0x700,0x8(%ebp) + } + + switch (c & 0xff) { + 1010ab: 8b 45 08 mov 0x8(%ebp),%eax + 1010ae: 0f b6 c0 movzbl %al,%eax + 1010b1: 83 f8 0d cmp $0xd,%eax + 1010b4: 74 72 je 101128 + 1010b6: 83 f8 0d cmp $0xd,%eax + 1010b9: 0f 8f a3 00 00 00 jg 101162 + 1010bf: 83 f8 08 cmp $0x8,%eax + 1010c2: 74 0a je 1010ce + 1010c4: 83 f8 0a cmp $0xa,%eax + 1010c7: 74 4c je 101115 + 1010c9: e9 94 00 00 00 jmp 101162 + case '\b': + if (crt_pos > 0) { + 1010ce: 0f b7 05 44 c4 11 00 movzwl 0x11c444,%eax + 1010d5: 85 c0 test %eax,%eax + 1010d7: 0f 84 af 00 00 00 je 10118c + crt_pos --; + 1010dd: 0f b7 05 44 c4 11 00 movzwl 0x11c444,%eax + 1010e4: 48 dec %eax + 1010e5: 0f b7 c0 movzwl %ax,%eax + 1010e8: 66 a3 44 c4 11 00 mov %ax,0x11c444 + crt_buf[crt_pos] = (c & ~0xff) | ' '; + 1010ee: 8b 45 08 mov 0x8(%ebp),%eax + 1010f1: 98 cwtl + 1010f2: 25 00 ff ff ff and $0xffffff00,%eax + 1010f7: 98 cwtl + 1010f8: 83 c8 20 or $0x20,%eax + 1010fb: 98 cwtl + 1010fc: 8b 0d 40 c4 11 00 mov 0x11c440,%ecx + 101102: 0f b7 15 44 c4 11 00 movzwl 0x11c444,%edx + 101109: 01 d2 add %edx,%edx + 10110b: 01 ca add %ecx,%edx + 10110d: 0f b7 c0 movzwl %ax,%eax + 101110: 66 89 02 mov %ax,(%edx) + } + break; + 101113: eb 77 jmp 10118c + case '\n': + crt_pos += CRT_COLS; + 101115: 0f b7 05 44 c4 11 00 movzwl 0x11c444,%eax + 10111c: 83 c0 50 add $0x50,%eax + 10111f: 0f b7 c0 movzwl %ax,%eax + 101122: 66 a3 44 c4 11 00 mov %ax,0x11c444 + case '\r': + crt_pos -= (crt_pos % CRT_COLS); + 101128: 0f b7 1d 44 c4 11 00 movzwl 0x11c444,%ebx + 10112f: 0f b7 0d 44 c4 11 00 movzwl 0x11c444,%ecx + 101136: ba cd cc cc cc mov $0xcccccccd,%edx + 10113b: 89 c8 mov %ecx,%eax + 10113d: f7 e2 mul %edx + 10113f: c1 ea 06 shr $0x6,%edx + 101142: 89 d0 mov %edx,%eax + 101144: c1 e0 02 shl $0x2,%eax + 101147: 01 d0 add %edx,%eax + 101149: c1 e0 04 shl $0x4,%eax + 10114c: 29 c1 sub %eax,%ecx + 10114e: 89 ca mov %ecx,%edx + 101150: 0f b7 d2 movzwl %dx,%edx + 101153: 89 d8 mov %ebx,%eax + 101155: 29 d0 sub %edx,%eax + 101157: 0f b7 c0 movzwl %ax,%eax + 10115a: 66 a3 44 c4 11 00 mov %ax,0x11c444 + break; + 101160: eb 2b jmp 10118d + default: + crt_buf[crt_pos ++] = c; // write the character + 101162: 8b 0d 40 c4 11 00 mov 0x11c440,%ecx + 101168: 0f b7 05 44 c4 11 00 movzwl 0x11c444,%eax + 10116f: 8d 50 01 lea 0x1(%eax),%edx + 101172: 0f b7 d2 movzwl %dx,%edx + 101175: 66 89 15 44 c4 11 00 mov %dx,0x11c444 + 10117c: 01 c0 add %eax,%eax + 10117e: 8d 14 01 lea (%ecx,%eax,1),%edx + 101181: 8b 45 08 mov 0x8(%ebp),%eax + 101184: 0f b7 c0 movzwl %ax,%eax + 101187: 66 89 02 mov %ax,(%edx) + break; + 10118a: eb 01 jmp 10118d + break; + 10118c: 90 nop + } + + // What is the purpose of this? + if (crt_pos >= CRT_SIZE) { + 10118d: 0f b7 05 44 c4 11 00 movzwl 0x11c444,%eax + 101194: 3d cf 07 00 00 cmp $0x7cf,%eax + 101199: 76 5e jbe 1011f9 + int i; + memmove(crt_buf, crt_buf + CRT_COLS, (CRT_SIZE - CRT_COLS) * sizeof(uint16_t)); + 10119b: a1 40 c4 11 00 mov 0x11c440,%eax + 1011a0: 8d 90 a0 00 00 00 lea 0xa0(%eax),%edx + 1011a6: a1 40 c4 11 00 mov 0x11c440,%eax + 1011ab: c7 44 24 08 00 0f 00 movl $0xf00,0x8(%esp) + 1011b2: 00 + 1011b3: 89 54 24 04 mov %edx,0x4(%esp) + 1011b7: 89 04 24 mov %eax,(%esp) + 1011ba: e8 8b 4d 00 00 call 105f4a + for (i = CRT_SIZE - CRT_COLS; i < CRT_SIZE; i ++) { + 1011bf: c7 45 f4 80 07 00 00 movl $0x780,-0xc(%ebp) + 1011c6: eb 15 jmp 1011dd + crt_buf[i] = 0x0700 | ' '; + 1011c8: 8b 15 40 c4 11 00 mov 0x11c440,%edx + 1011ce: 8b 45 f4 mov -0xc(%ebp),%eax + 1011d1: 01 c0 add %eax,%eax + 1011d3: 01 d0 add %edx,%eax + 1011d5: 66 c7 00 20 07 movw $0x720,(%eax) + for (i = CRT_SIZE - CRT_COLS; i < CRT_SIZE; i ++) { + 1011da: ff 45 f4 incl -0xc(%ebp) + 1011dd: 81 7d f4 cf 07 00 00 cmpl $0x7cf,-0xc(%ebp) + 1011e4: 7e e2 jle 1011c8 + } + crt_pos -= CRT_COLS; + 1011e6: 0f b7 05 44 c4 11 00 movzwl 0x11c444,%eax + 1011ed: 83 e8 50 sub $0x50,%eax + 1011f0: 0f b7 c0 movzwl %ax,%eax + 1011f3: 66 a3 44 c4 11 00 mov %ax,0x11c444 + } + + // move that little blinky thing + outb(addr_6845, 14); + 1011f9: 0f b7 05 46 c4 11 00 movzwl 0x11c446,%eax + 101200: 66 89 45 e6 mov %ax,-0x1a(%ebp) + 101204: c6 45 e5 0e movb $0xe,-0x1b(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 101208: 0f b6 45 e5 movzbl -0x1b(%ebp),%eax + 10120c: 0f b7 55 e6 movzwl -0x1a(%ebp),%edx + 101210: ee out %al,(%dx) +} + 101211: 90 nop + outb(addr_6845 + 1, crt_pos >> 8); + 101212: 0f b7 05 44 c4 11 00 movzwl 0x11c444,%eax + 101219: c1 e8 08 shr $0x8,%eax + 10121c: 0f b7 c0 movzwl %ax,%eax + 10121f: 0f b6 c0 movzbl %al,%eax + 101222: 0f b7 15 46 c4 11 00 movzwl 0x11c446,%edx + 101229: 42 inc %edx + 10122a: 0f b7 d2 movzwl %dx,%edx + 10122d: 66 89 55 ea mov %dx,-0x16(%ebp) + 101231: 88 45 e9 mov %al,-0x17(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 101234: 0f b6 45 e9 movzbl -0x17(%ebp),%eax + 101238: 0f b7 55 ea movzwl -0x16(%ebp),%edx + 10123c: ee out %al,(%dx) +} + 10123d: 90 nop + outb(addr_6845, 15); + 10123e: 0f b7 05 46 c4 11 00 movzwl 0x11c446,%eax + 101245: 66 89 45 ee mov %ax,-0x12(%ebp) + 101249: c6 45 ed 0f movb $0xf,-0x13(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 10124d: 0f b6 45 ed movzbl -0x13(%ebp),%eax + 101251: 0f b7 55 ee movzwl -0x12(%ebp),%edx + 101255: ee out %al,(%dx) +} + 101256: 90 nop + outb(addr_6845 + 1, crt_pos); + 101257: 0f b7 05 44 c4 11 00 movzwl 0x11c444,%eax + 10125e: 0f b6 c0 movzbl %al,%eax + 101261: 0f b7 15 46 c4 11 00 movzwl 0x11c446,%edx + 101268: 42 inc %edx + 101269: 0f b7 d2 movzwl %dx,%edx + 10126c: 66 89 55 f2 mov %dx,-0xe(%ebp) + 101270: 88 45 f1 mov %al,-0xf(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 101273: 0f b6 45 f1 movzbl -0xf(%ebp),%eax + 101277: 0f b7 55 f2 movzwl -0xe(%ebp),%edx + 10127b: ee out %al,(%dx) +} + 10127c: 90 nop +} + 10127d: 90 nop + 10127e: 8b 5d fc mov -0x4(%ebp),%ebx + 101281: 89 ec mov %ebp,%esp + 101283: 5d pop %ebp + 101284: c3 ret + +00101285 : + +static void +serial_putc_sub(int c) { + 101285: 55 push %ebp + 101286: 89 e5 mov %esp,%ebp + 101288: 83 ec 10 sub $0x10,%esp + int i; + for (i = 0; !(inb(COM1 + COM_LSR) & COM_LSR_TXRDY) && i < 12800; i ++) { + 10128b: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + 101292: eb 08 jmp 10129c + delay(); + 101294: e8 16 fb ff ff call 100daf + for (i = 0; !(inb(COM1 + COM_LSR) & COM_LSR_TXRDY) && i < 12800; i ++) { + 101299: ff 45 fc incl -0x4(%ebp) + 10129c: 66 c7 45 fa fd 03 movw $0x3fd,-0x6(%ebp) + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); + 1012a2: 0f b7 45 fa movzwl -0x6(%ebp),%eax + 1012a6: 89 c2 mov %eax,%edx + 1012a8: ec in (%dx),%al + 1012a9: 88 45 f9 mov %al,-0x7(%ebp) + return data; + 1012ac: 0f b6 45 f9 movzbl -0x7(%ebp),%eax + 1012b0: 0f b6 c0 movzbl %al,%eax + 1012b3: 83 e0 20 and $0x20,%eax + 1012b6: 85 c0 test %eax,%eax + 1012b8: 75 09 jne 1012c3 + 1012ba: 81 7d fc ff 31 00 00 cmpl $0x31ff,-0x4(%ebp) + 1012c1: 7e d1 jle 101294 + } + outb(COM1 + COM_TX, c); + 1012c3: 8b 45 08 mov 0x8(%ebp),%eax + 1012c6: 0f b6 c0 movzbl %al,%eax + 1012c9: 66 c7 45 f6 f8 03 movw $0x3f8,-0xa(%ebp) + 1012cf: 88 45 f5 mov %al,-0xb(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 1012d2: 0f b6 45 f5 movzbl -0xb(%ebp),%eax + 1012d6: 0f b7 55 f6 movzwl -0xa(%ebp),%edx + 1012da: ee out %al,(%dx) +} + 1012db: 90 nop +} + 1012dc: 90 nop + 1012dd: 89 ec mov %ebp,%esp + 1012df: 5d pop %ebp + 1012e0: c3 ret + +001012e1 : + +/* serial_putc - print character to serial port */ +static void +serial_putc(int c) { + 1012e1: 55 push %ebp + 1012e2: 89 e5 mov %esp,%ebp + 1012e4: 83 ec 04 sub $0x4,%esp + if (c != '\b') { + 1012e7: 83 7d 08 08 cmpl $0x8,0x8(%ebp) + 1012eb: 74 0d je 1012fa + serial_putc_sub(c); + 1012ed: 8b 45 08 mov 0x8(%ebp),%eax + 1012f0: 89 04 24 mov %eax,(%esp) + 1012f3: e8 8d ff ff ff call 101285 + else { + serial_putc_sub('\b'); + serial_putc_sub(' '); + serial_putc_sub('\b'); + } +} + 1012f8: eb 24 jmp 10131e + serial_putc_sub('\b'); + 1012fa: c7 04 24 08 00 00 00 movl $0x8,(%esp) + 101301: e8 7f ff ff ff call 101285 + serial_putc_sub(' '); + 101306: c7 04 24 20 00 00 00 movl $0x20,(%esp) + 10130d: e8 73 ff ff ff call 101285 + serial_putc_sub('\b'); + 101312: c7 04 24 08 00 00 00 movl $0x8,(%esp) + 101319: e8 67 ff ff ff call 101285 +} + 10131e: 90 nop + 10131f: 89 ec mov %ebp,%esp + 101321: 5d pop %ebp + 101322: c3 ret + +00101323 : +/* * + * cons_intr - called by device interrupt routines to feed input + * characters into the circular console input buffer. + * */ +static void +cons_intr(int (*proc)(void)) { + 101323: 55 push %ebp + 101324: 89 e5 mov %esp,%ebp + 101326: 83 ec 18 sub $0x18,%esp + int c; + while ((c = (*proc)()) != -1) { + 101329: eb 33 jmp 10135e + if (c != 0) { + 10132b: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) + 10132f: 74 2d je 10135e + cons.buf[cons.wpos ++] = c; + 101331: a1 64 c6 11 00 mov 0x11c664,%eax + 101336: 8d 50 01 lea 0x1(%eax),%edx + 101339: 89 15 64 c6 11 00 mov %edx,0x11c664 + 10133f: 8b 55 f4 mov -0xc(%ebp),%edx + 101342: 88 90 60 c4 11 00 mov %dl,0x11c460(%eax) + if (cons.wpos == CONSBUFSIZE) { + 101348: a1 64 c6 11 00 mov 0x11c664,%eax + 10134d: 3d 00 02 00 00 cmp $0x200,%eax + 101352: 75 0a jne 10135e + cons.wpos = 0; + 101354: c7 05 64 c6 11 00 00 movl $0x0,0x11c664 + 10135b: 00 00 00 + while ((c = (*proc)()) != -1) { + 10135e: 8b 45 08 mov 0x8(%ebp),%eax + 101361: ff d0 call *%eax + 101363: 89 45 f4 mov %eax,-0xc(%ebp) + 101366: 83 7d f4 ff cmpl $0xffffffff,-0xc(%ebp) + 10136a: 75 bf jne 10132b + } + } + } +} + 10136c: 90 nop + 10136d: 90 nop + 10136e: 89 ec mov %ebp,%esp + 101370: 5d pop %ebp + 101371: c3 ret + +00101372 : + +/* serial_proc_data - get data from serial port */ +static int +serial_proc_data(void) { + 101372: 55 push %ebp + 101373: 89 e5 mov %esp,%ebp + 101375: 83 ec 10 sub $0x10,%esp + 101378: 66 c7 45 fa fd 03 movw $0x3fd,-0x6(%ebp) + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); + 10137e: 0f b7 45 fa movzwl -0x6(%ebp),%eax + 101382: 89 c2 mov %eax,%edx + 101384: ec in (%dx),%al + 101385: 88 45 f9 mov %al,-0x7(%ebp) + return data; + 101388: 0f b6 45 f9 movzbl -0x7(%ebp),%eax + if (!(inb(COM1 + COM_LSR) & COM_LSR_DATA)) { + 10138c: 0f b6 c0 movzbl %al,%eax + 10138f: 83 e0 01 and $0x1,%eax + 101392: 85 c0 test %eax,%eax + 101394: 75 07 jne 10139d + return -1; + 101396: b8 ff ff ff ff mov $0xffffffff,%eax + 10139b: eb 2a jmp 1013c7 + 10139d: 66 c7 45 f6 f8 03 movw $0x3f8,-0xa(%ebp) + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); + 1013a3: 0f b7 45 f6 movzwl -0xa(%ebp),%eax + 1013a7: 89 c2 mov %eax,%edx + 1013a9: ec in (%dx),%al + 1013aa: 88 45 f5 mov %al,-0xb(%ebp) + return data; + 1013ad: 0f b6 45 f5 movzbl -0xb(%ebp),%eax + } + int c = inb(COM1 + COM_RX); + 1013b1: 0f b6 c0 movzbl %al,%eax + 1013b4: 89 45 fc mov %eax,-0x4(%ebp) + if (c == 127) { + 1013b7: 83 7d fc 7f cmpl $0x7f,-0x4(%ebp) + 1013bb: 75 07 jne 1013c4 + c = '\b'; + 1013bd: c7 45 fc 08 00 00 00 movl $0x8,-0x4(%ebp) + } + return c; + 1013c4: 8b 45 fc mov -0x4(%ebp),%eax +} + 1013c7: 89 ec mov %ebp,%esp + 1013c9: 5d pop %ebp + 1013ca: c3 ret + +001013cb : + +/* serial_intr - try to feed input characters from serial port */ +void +serial_intr(void) { + 1013cb: 55 push %ebp + 1013cc: 89 e5 mov %esp,%ebp + 1013ce: 83 ec 18 sub $0x18,%esp + if (serial_exists) { + 1013d1: a1 48 c4 11 00 mov 0x11c448,%eax + 1013d6: 85 c0 test %eax,%eax + 1013d8: 74 0c je 1013e6 + cons_intr(serial_proc_data); + 1013da: c7 04 24 72 13 10 00 movl $0x101372,(%esp) + 1013e1: e8 3d ff ff ff call 101323 + } +} + 1013e6: 90 nop + 1013e7: 89 ec mov %ebp,%esp + 1013e9: 5d pop %ebp + 1013ea: c3 ret + +001013eb : + * + * 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) { + 1013eb: 55 push %ebp + 1013ec: 89 e5 mov %esp,%ebp + 1013ee: 83 ec 38 sub $0x38,%esp + 1013f1: 66 c7 45 f0 64 00 movw $0x64,-0x10(%ebp) + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); + 1013f7: 8b 45 f0 mov -0x10(%ebp),%eax + 1013fa: 89 c2 mov %eax,%edx + 1013fc: ec in (%dx),%al + 1013fd: 88 45 ef mov %al,-0x11(%ebp) + return data; + 101400: 0f b6 45 ef movzbl -0x11(%ebp),%eax + int c; + uint8_t data; + static uint32_t shift; + + if ((inb(KBSTATP) & KBS_DIB) == 0) { + 101404: 0f b6 c0 movzbl %al,%eax + 101407: 83 e0 01 and $0x1,%eax + 10140a: 85 c0 test %eax,%eax + 10140c: 75 0a jne 101418 + return -1; + 10140e: b8 ff ff ff ff mov $0xffffffff,%eax + 101413: e9 56 01 00 00 jmp 10156e + 101418: 66 c7 45 ec 60 00 movw $0x60,-0x14(%ebp) + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); + 10141e: 8b 45 ec mov -0x14(%ebp),%eax + 101421: 89 c2 mov %eax,%edx + 101423: ec in (%dx),%al + 101424: 88 45 eb mov %al,-0x15(%ebp) + return data; + 101427: 0f b6 45 eb movzbl -0x15(%ebp),%eax + } + + data = inb(KBDATAP); + 10142b: 88 45 f3 mov %al,-0xd(%ebp) + + if (data == 0xE0) { + 10142e: 80 7d f3 e0 cmpb $0xe0,-0xd(%ebp) + 101432: 75 17 jne 10144b + // E0 escape character + shift |= E0ESC; + 101434: a1 68 c6 11 00 mov 0x11c668,%eax + 101439: 83 c8 40 or $0x40,%eax + 10143c: a3 68 c6 11 00 mov %eax,0x11c668 + return 0; + 101441: b8 00 00 00 00 mov $0x0,%eax + 101446: e9 23 01 00 00 jmp 10156e + } else if (data & 0x80) { + 10144b: 0f b6 45 f3 movzbl -0xd(%ebp),%eax + 10144f: 84 c0 test %al,%al + 101451: 79 45 jns 101498 + // Key released + data = (shift & E0ESC ? data : data & 0x7F); + 101453: a1 68 c6 11 00 mov 0x11c668,%eax + 101458: 83 e0 40 and $0x40,%eax + 10145b: 85 c0 test %eax,%eax + 10145d: 75 08 jne 101467 + 10145f: 0f b6 45 f3 movzbl -0xd(%ebp),%eax + 101463: 24 7f and $0x7f,%al + 101465: eb 04 jmp 10146b + 101467: 0f b6 45 f3 movzbl -0xd(%ebp),%eax + 10146b: 88 45 f3 mov %al,-0xd(%ebp) + shift &= ~(shiftcode[data] | E0ESC); + 10146e: 0f b6 45 f3 movzbl -0xd(%ebp),%eax + 101472: 0f b6 80 40 90 11 00 movzbl 0x119040(%eax),%eax + 101479: 0c 40 or $0x40,%al + 10147b: 0f b6 c0 movzbl %al,%eax + 10147e: f7 d0 not %eax + 101480: 89 c2 mov %eax,%edx + 101482: a1 68 c6 11 00 mov 0x11c668,%eax + 101487: 21 d0 and %edx,%eax + 101489: a3 68 c6 11 00 mov %eax,0x11c668 + return 0; + 10148e: b8 00 00 00 00 mov $0x0,%eax + 101493: e9 d6 00 00 00 jmp 10156e + } else if (shift & E0ESC) { + 101498: a1 68 c6 11 00 mov 0x11c668,%eax + 10149d: 83 e0 40 and $0x40,%eax + 1014a0: 85 c0 test %eax,%eax + 1014a2: 74 11 je 1014b5 + // Last character was an E0 escape; or with 0x80 + data |= 0x80; + 1014a4: 80 4d f3 80 orb $0x80,-0xd(%ebp) + shift &= ~E0ESC; + 1014a8: a1 68 c6 11 00 mov 0x11c668,%eax + 1014ad: 83 e0 bf and $0xffffffbf,%eax + 1014b0: a3 68 c6 11 00 mov %eax,0x11c668 + } + + shift |= shiftcode[data]; + 1014b5: 0f b6 45 f3 movzbl -0xd(%ebp),%eax + 1014b9: 0f b6 80 40 90 11 00 movzbl 0x119040(%eax),%eax + 1014c0: 0f b6 d0 movzbl %al,%edx + 1014c3: a1 68 c6 11 00 mov 0x11c668,%eax + 1014c8: 09 d0 or %edx,%eax + 1014ca: a3 68 c6 11 00 mov %eax,0x11c668 + shift ^= togglecode[data]; + 1014cf: 0f b6 45 f3 movzbl -0xd(%ebp),%eax + 1014d3: 0f b6 80 40 91 11 00 movzbl 0x119140(%eax),%eax + 1014da: 0f b6 d0 movzbl %al,%edx + 1014dd: a1 68 c6 11 00 mov 0x11c668,%eax + 1014e2: 31 d0 xor %edx,%eax + 1014e4: a3 68 c6 11 00 mov %eax,0x11c668 + + c = charcode[shift & (CTL | SHIFT)][data]; + 1014e9: a1 68 c6 11 00 mov 0x11c668,%eax + 1014ee: 83 e0 03 and $0x3,%eax + 1014f1: 8b 14 85 40 95 11 00 mov 0x119540(,%eax,4),%edx + 1014f8: 0f b6 45 f3 movzbl -0xd(%ebp),%eax + 1014fc: 01 d0 add %edx,%eax + 1014fe: 0f b6 00 movzbl (%eax),%eax + 101501: 0f b6 c0 movzbl %al,%eax + 101504: 89 45 f4 mov %eax,-0xc(%ebp) + if (shift & CAPSLOCK) { + 101507: a1 68 c6 11 00 mov 0x11c668,%eax + 10150c: 83 e0 08 and $0x8,%eax + 10150f: 85 c0 test %eax,%eax + 101511: 74 22 je 101535 + if ('a' <= c && c <= 'z') + 101513: 83 7d f4 60 cmpl $0x60,-0xc(%ebp) + 101517: 7e 0c jle 101525 + 101519: 83 7d f4 7a cmpl $0x7a,-0xc(%ebp) + 10151d: 7f 06 jg 101525 + c += 'A' - 'a'; + 10151f: 83 6d f4 20 subl $0x20,-0xc(%ebp) + 101523: eb 10 jmp 101535 + else if ('A' <= c && c <= 'Z') + 101525: 83 7d f4 40 cmpl $0x40,-0xc(%ebp) + 101529: 7e 0a jle 101535 + 10152b: 83 7d f4 5a cmpl $0x5a,-0xc(%ebp) + 10152f: 7f 04 jg 101535 + c += 'a' - 'A'; + 101531: 83 45 f4 20 addl $0x20,-0xc(%ebp) + } + + // Process special keys + // Ctrl-Alt-Del: reboot + if (!(~shift & (CTL | ALT)) && c == KEY_DEL) { + 101535: a1 68 c6 11 00 mov 0x11c668,%eax + 10153a: f7 d0 not %eax + 10153c: 83 e0 06 and $0x6,%eax + 10153f: 85 c0 test %eax,%eax + 101541: 75 28 jne 10156b + 101543: 81 7d f4 e9 00 00 00 cmpl $0xe9,-0xc(%ebp) + 10154a: 75 1f jne 10156b + cprintf("Rebooting!\n"); + 10154c: c7 04 24 a7 63 10 00 movl $0x1063a7,(%esp) + 101553: e8 0e ee ff ff call 100366 + 101558: 66 c7 45 e8 92 00 movw $0x92,-0x18(%ebp) + 10155e: c6 45 e7 03 movb $0x3,-0x19(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 101562: 0f b6 45 e7 movzbl -0x19(%ebp),%eax + 101566: 8b 55 e8 mov -0x18(%ebp),%edx + 101569: ee out %al,(%dx) +} + 10156a: 90 nop + outb(0x92, 0x3); // courtesy of Chris Frost + } + return c; + 10156b: 8b 45 f4 mov -0xc(%ebp),%eax +} + 10156e: 89 ec mov %ebp,%esp + 101570: 5d pop %ebp + 101571: c3 ret + +00101572 : + +/* kbd_intr - try to feed input characters from keyboard */ +static void +kbd_intr(void) { + 101572: 55 push %ebp + 101573: 89 e5 mov %esp,%ebp + 101575: 83 ec 18 sub $0x18,%esp + cons_intr(kbd_proc_data); + 101578: c7 04 24 eb 13 10 00 movl $0x1013eb,(%esp) + 10157f: e8 9f fd ff ff call 101323 +} + 101584: 90 nop + 101585: 89 ec mov %ebp,%esp + 101587: 5d pop %ebp + 101588: c3 ret + +00101589 : + +static void +kbd_init(void) { + 101589: 55 push %ebp + 10158a: 89 e5 mov %esp,%ebp + 10158c: 83 ec 18 sub $0x18,%esp + // drain the kbd buffer + kbd_intr(); + 10158f: e8 de ff ff ff call 101572 + pic_enable(IRQ_KBD); + 101594: c7 04 24 01 00 00 00 movl $0x1,(%esp) + 10159b: e8 51 01 00 00 call 1016f1 +} + 1015a0: 90 nop + 1015a1: 89 ec mov %ebp,%esp + 1015a3: 5d pop %ebp + 1015a4: c3 ret + +001015a5 : + +/* cons_init - initializes the console devices */ +void +cons_init(void) { + 1015a5: 55 push %ebp + 1015a6: 89 e5 mov %esp,%ebp + 1015a8: 83 ec 18 sub $0x18,%esp + cga_init(); + 1015ab: e8 4a f8 ff ff call 100dfa + serial_init(); + 1015b0: e8 2d f9 ff ff call 100ee2 + kbd_init(); + 1015b5: e8 cf ff ff ff call 101589 + if (!serial_exists) { + 1015ba: a1 48 c4 11 00 mov 0x11c448,%eax + 1015bf: 85 c0 test %eax,%eax + 1015c1: 75 0c jne 1015cf + cprintf("serial port does not exist!!\n"); + 1015c3: c7 04 24 b3 63 10 00 movl $0x1063b3,(%esp) + 1015ca: e8 97 ed ff ff call 100366 + } +} + 1015cf: 90 nop + 1015d0: 89 ec mov %ebp,%esp + 1015d2: 5d pop %ebp + 1015d3: c3 ret + +001015d4 : + +/* cons_putc - print a single character @c to console devices */ +void +cons_putc(int c) { + 1015d4: 55 push %ebp + 1015d5: 89 e5 mov %esp,%ebp + 1015d7: 83 ec 28 sub $0x28,%esp + bool intr_flag; + local_intr_save(intr_flag); + 1015da: e8 8e f7 ff ff call 100d6d <__intr_save> + 1015df: 89 45 f4 mov %eax,-0xc(%ebp) + { + lpt_putc(c); + 1015e2: 8b 45 08 mov 0x8(%ebp),%eax + 1015e5: 89 04 24 mov %eax,(%esp) + 1015e8: e8 60 fa ff ff call 10104d + cga_putc(c); + 1015ed: 8b 45 08 mov 0x8(%ebp),%eax + 1015f0: 89 04 24 mov %eax,(%esp) + 1015f3: e8 97 fa ff ff call 10108f + serial_putc(c); + 1015f8: 8b 45 08 mov 0x8(%ebp),%eax + 1015fb: 89 04 24 mov %eax,(%esp) + 1015fe: e8 de fc ff ff call 1012e1 + } + local_intr_restore(intr_flag); + 101603: 8b 45 f4 mov -0xc(%ebp),%eax + 101606: 89 04 24 mov %eax,(%esp) + 101609: e8 8b f7 ff ff call 100d99 <__intr_restore> +} + 10160e: 90 nop + 10160f: 89 ec mov %ebp,%esp + 101611: 5d pop %ebp + 101612: c3 ret + +00101613 : +/* * + * cons_getc - return the next input character from console, + * or 0 if none waiting. + * */ +int +cons_getc(void) { + 101613: 55 push %ebp + 101614: 89 e5 mov %esp,%ebp + 101616: 83 ec 28 sub $0x28,%esp + int c = 0; + 101619: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + bool intr_flag; + local_intr_save(intr_flag); + 101620: e8 48 f7 ff ff call 100d6d <__intr_save> + 101625: 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(); + 101628: e8 9e fd ff ff call 1013cb + kbd_intr(); + 10162d: e8 40 ff ff ff call 101572 + + // grab the next character from the input buffer. + if (cons.rpos != cons.wpos) { + 101632: 8b 15 60 c6 11 00 mov 0x11c660,%edx + 101638: a1 64 c6 11 00 mov 0x11c664,%eax + 10163d: 39 c2 cmp %eax,%edx + 10163f: 74 31 je 101672 + c = cons.buf[cons.rpos ++]; + 101641: a1 60 c6 11 00 mov 0x11c660,%eax + 101646: 8d 50 01 lea 0x1(%eax),%edx + 101649: 89 15 60 c6 11 00 mov %edx,0x11c660 + 10164f: 0f b6 80 60 c4 11 00 movzbl 0x11c460(%eax),%eax + 101656: 0f b6 c0 movzbl %al,%eax + 101659: 89 45 f4 mov %eax,-0xc(%ebp) + if (cons.rpos == CONSBUFSIZE) { + 10165c: a1 60 c6 11 00 mov 0x11c660,%eax + 101661: 3d 00 02 00 00 cmp $0x200,%eax + 101666: 75 0a jne 101672 + cons.rpos = 0; + 101668: c7 05 60 c6 11 00 00 movl $0x0,0x11c660 + 10166f: 00 00 00 + } + } + } + local_intr_restore(intr_flag); + 101672: 8b 45 f0 mov -0x10(%ebp),%eax + 101675: 89 04 24 mov %eax,(%esp) + 101678: e8 1c f7 ff ff call 100d99 <__intr_restore> + return c; + 10167d: 8b 45 f4 mov -0xc(%ebp),%eax +} + 101680: 89 ec mov %ebp,%esp + 101682: 5d pop %ebp + 101683: c3 ret + +00101684 : +#include +#include + +/* intr_enable - enable irq interrupt */ +void +intr_enable(void) { + 101684: 55 push %ebp + 101685: 89 e5 mov %esp,%ebp + asm volatile ("sti"); + 101687: fb sti +} + 101688: 90 nop + sti(); +} + 101689: 90 nop + 10168a: 5d pop %ebp + 10168b: c3 ret + +0010168c : + +/* intr_disable - disable irq interrupt */ +void +intr_disable(void) { + 10168c: 55 push %ebp + 10168d: 89 e5 mov %esp,%ebp + asm volatile ("cli" ::: "memory"); + 10168f: fa cli +} + 101690: 90 nop + cli(); +} + 101691: 90 nop + 101692: 5d pop %ebp + 101693: c3 ret + +00101694 : +// 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) { + 101694: 55 push %ebp + 101695: 89 e5 mov %esp,%ebp + 101697: 83 ec 14 sub $0x14,%esp + 10169a: 8b 45 08 mov 0x8(%ebp),%eax + 10169d: 66 89 45 ec mov %ax,-0x14(%ebp) + irq_mask = mask; + 1016a1: 8b 45 ec mov -0x14(%ebp),%eax + 1016a4: 66 a3 50 95 11 00 mov %ax,0x119550 + if (did_init) { + 1016aa: a1 6c c6 11 00 mov 0x11c66c,%eax + 1016af: 85 c0 test %eax,%eax + 1016b1: 74 39 je 1016ec + outb(IO_PIC1 + 1, mask); + 1016b3: 8b 45 ec mov -0x14(%ebp),%eax + 1016b6: 0f b6 c0 movzbl %al,%eax + 1016b9: 66 c7 45 fa 21 00 movw $0x21,-0x6(%ebp) + 1016bf: 88 45 f9 mov %al,-0x7(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 1016c2: 0f b6 45 f9 movzbl -0x7(%ebp),%eax + 1016c6: 0f b7 55 fa movzwl -0x6(%ebp),%edx + 1016ca: ee out %al,(%dx) +} + 1016cb: 90 nop + outb(IO_PIC2 + 1, mask >> 8); + 1016cc: 0f b7 45 ec movzwl -0x14(%ebp),%eax + 1016d0: c1 e8 08 shr $0x8,%eax + 1016d3: 0f b7 c0 movzwl %ax,%eax + 1016d6: 0f b6 c0 movzbl %al,%eax + 1016d9: 66 c7 45 fe a1 00 movw $0xa1,-0x2(%ebp) + 1016df: 88 45 fd mov %al,-0x3(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 1016e2: 0f b6 45 fd movzbl -0x3(%ebp),%eax + 1016e6: 0f b7 55 fe movzwl -0x2(%ebp),%edx + 1016ea: ee out %al,(%dx) +} + 1016eb: 90 nop + } +} + 1016ec: 90 nop + 1016ed: 89 ec mov %ebp,%esp + 1016ef: 5d pop %ebp + 1016f0: c3 ret + +001016f1 : + +void +pic_enable(unsigned int irq) { + 1016f1: 55 push %ebp + 1016f2: 89 e5 mov %esp,%ebp + 1016f4: 83 ec 04 sub $0x4,%esp + pic_setmask(irq_mask & ~(1 << irq)); + 1016f7: 8b 45 08 mov 0x8(%ebp),%eax + 1016fa: ba 01 00 00 00 mov $0x1,%edx + 1016ff: 88 c1 mov %al,%cl + 101701: d3 e2 shl %cl,%edx + 101703: 89 d0 mov %edx,%eax + 101705: 98 cwtl + 101706: f7 d0 not %eax + 101708: 0f bf d0 movswl %ax,%edx + 10170b: 0f b7 05 50 95 11 00 movzwl 0x119550,%eax + 101712: 98 cwtl + 101713: 21 d0 and %edx,%eax + 101715: 98 cwtl + 101716: 0f b7 c0 movzwl %ax,%eax + 101719: 89 04 24 mov %eax,(%esp) + 10171c: e8 73 ff ff ff call 101694 +} + 101721: 90 nop + 101722: 89 ec mov %ebp,%esp + 101724: 5d pop %ebp + 101725: c3 ret + +00101726 : + +/* pic_init - initialize the 8259A interrupt controllers */ +void +pic_init(void) { + 101726: 55 push %ebp + 101727: 89 e5 mov %esp,%ebp + 101729: 83 ec 44 sub $0x44,%esp + did_init = 1; + 10172c: c7 05 6c c6 11 00 01 movl $0x1,0x11c66c + 101733: 00 00 00 + 101736: 66 c7 45 ca 21 00 movw $0x21,-0x36(%ebp) + 10173c: c6 45 c9 ff movb $0xff,-0x37(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 101740: 0f b6 45 c9 movzbl -0x37(%ebp),%eax + 101744: 0f b7 55 ca movzwl -0x36(%ebp),%edx + 101748: ee out %al,(%dx) +} + 101749: 90 nop + 10174a: 66 c7 45 ce a1 00 movw $0xa1,-0x32(%ebp) + 101750: c6 45 cd ff movb $0xff,-0x33(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 101754: 0f b6 45 cd movzbl -0x33(%ebp),%eax + 101758: 0f b7 55 ce movzwl -0x32(%ebp),%edx + 10175c: ee out %al,(%dx) +} + 10175d: 90 nop + 10175e: 66 c7 45 d2 20 00 movw $0x20,-0x2e(%ebp) + 101764: c6 45 d1 11 movb $0x11,-0x2f(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 101768: 0f b6 45 d1 movzbl -0x2f(%ebp),%eax + 10176c: 0f b7 55 d2 movzwl -0x2e(%ebp),%edx + 101770: ee out %al,(%dx) +} + 101771: 90 nop + 101772: 66 c7 45 d6 21 00 movw $0x21,-0x2a(%ebp) + 101778: c6 45 d5 20 movb $0x20,-0x2b(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 10177c: 0f b6 45 d5 movzbl -0x2b(%ebp),%eax + 101780: 0f b7 55 d6 movzwl -0x2a(%ebp),%edx + 101784: ee out %al,(%dx) +} + 101785: 90 nop + 101786: 66 c7 45 da 21 00 movw $0x21,-0x26(%ebp) + 10178c: c6 45 d9 04 movb $0x4,-0x27(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 101790: 0f b6 45 d9 movzbl -0x27(%ebp),%eax + 101794: 0f b7 55 da movzwl -0x26(%ebp),%edx + 101798: ee out %al,(%dx) +} + 101799: 90 nop + 10179a: 66 c7 45 de 21 00 movw $0x21,-0x22(%ebp) + 1017a0: c6 45 dd 03 movb $0x3,-0x23(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 1017a4: 0f b6 45 dd movzbl -0x23(%ebp),%eax + 1017a8: 0f b7 55 de movzwl -0x22(%ebp),%edx + 1017ac: ee out %al,(%dx) +} + 1017ad: 90 nop + 1017ae: 66 c7 45 e2 a0 00 movw $0xa0,-0x1e(%ebp) + 1017b4: c6 45 e1 11 movb $0x11,-0x1f(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 1017b8: 0f b6 45 e1 movzbl -0x1f(%ebp),%eax + 1017bc: 0f b7 55 e2 movzwl -0x1e(%ebp),%edx + 1017c0: ee out %al,(%dx) +} + 1017c1: 90 nop + 1017c2: 66 c7 45 e6 a1 00 movw $0xa1,-0x1a(%ebp) + 1017c8: c6 45 e5 28 movb $0x28,-0x1b(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 1017cc: 0f b6 45 e5 movzbl -0x1b(%ebp),%eax + 1017d0: 0f b7 55 e6 movzwl -0x1a(%ebp),%edx + 1017d4: ee out %al,(%dx) +} + 1017d5: 90 nop + 1017d6: 66 c7 45 ea a1 00 movw $0xa1,-0x16(%ebp) + 1017dc: c6 45 e9 02 movb $0x2,-0x17(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 1017e0: 0f b6 45 e9 movzbl -0x17(%ebp),%eax + 1017e4: 0f b7 55 ea movzwl -0x16(%ebp),%edx + 1017e8: ee out %al,(%dx) +} + 1017e9: 90 nop + 1017ea: 66 c7 45 ee a1 00 movw $0xa1,-0x12(%ebp) + 1017f0: c6 45 ed 03 movb $0x3,-0x13(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 1017f4: 0f b6 45 ed movzbl -0x13(%ebp),%eax + 1017f8: 0f b7 55 ee movzwl -0x12(%ebp),%edx + 1017fc: ee out %al,(%dx) +} + 1017fd: 90 nop + 1017fe: 66 c7 45 f2 20 00 movw $0x20,-0xe(%ebp) + 101804: c6 45 f1 68 movb $0x68,-0xf(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 101808: 0f b6 45 f1 movzbl -0xf(%ebp),%eax + 10180c: 0f b7 55 f2 movzwl -0xe(%ebp),%edx + 101810: ee out %al,(%dx) +} + 101811: 90 nop + 101812: 66 c7 45 f6 20 00 movw $0x20,-0xa(%ebp) + 101818: c6 45 f5 0a movb $0xa,-0xb(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 10181c: 0f b6 45 f5 movzbl -0xb(%ebp),%eax + 101820: 0f b7 55 f6 movzwl -0xa(%ebp),%edx + 101824: ee out %al,(%dx) +} + 101825: 90 nop + 101826: 66 c7 45 fa a0 00 movw $0xa0,-0x6(%ebp) + 10182c: c6 45 f9 68 movb $0x68,-0x7(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 101830: 0f b6 45 f9 movzbl -0x7(%ebp),%eax + 101834: 0f b7 55 fa movzwl -0x6(%ebp),%edx + 101838: ee out %al,(%dx) +} + 101839: 90 nop + 10183a: 66 c7 45 fe a0 00 movw $0xa0,-0x2(%ebp) + 101840: c6 45 fd 0a movb $0xa,-0x3(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 101844: 0f b6 45 fd movzbl -0x3(%ebp),%eax + 101848: 0f b7 55 fe movzwl -0x2(%ebp),%edx + 10184c: ee out %al,(%dx) +} + 10184d: 90 nop + outb(IO_PIC1, 0x0a); // read IRR by default + + outb(IO_PIC2, 0x68); // OCW3 + outb(IO_PIC2, 0x0a); // OCW3 + + if (irq_mask != 0xFFFF) { + 10184e: 0f b7 05 50 95 11 00 movzwl 0x119550,%eax + 101855: 3d ff ff 00 00 cmp $0xffff,%eax + 10185a: 74 0f je 10186b + pic_setmask(irq_mask); + 10185c: 0f b7 05 50 95 11 00 movzwl 0x119550,%eax + 101863: 89 04 24 mov %eax,(%esp) + 101866: e8 29 fe ff ff call 101694 + } +} + 10186b: 90 nop + 10186c: 89 ec mov %ebp,%esp + 10186e: 5d pop %ebp + 10186f: c3 ret + +00101870 : +#include +#include + +#define TICK_NUM 100 + +static void print_ticks() { + 101870: 55 push %ebp + 101871: 89 e5 mov %esp,%ebp + 101873: 83 ec 18 sub $0x18,%esp + cprintf("%d ticks\n",TICK_NUM); + 101876: c7 44 24 04 64 00 00 movl $0x64,0x4(%esp) + 10187d: 00 + 10187e: c7 04 24 e0 63 10 00 movl $0x1063e0,(%esp) + 101885: e8 dc ea ff ff call 100366 +#ifdef DEBUG_GRADE + cprintf("End of Test.\n"); + panic("EOT: kernel seems ok."); +#endif +} + 10188a: 90 nop + 10188b: 89 ec mov %ebp,%esp + 10188d: 5d pop %ebp + 10188e: c3 ret + +0010188f : + 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) { + 10188f: 55 push %ebp + 101890: 89 e5 mov %esp,%ebp + 101892: 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 ++) { + 101895: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + 10189c: e9 c4 00 00 00 jmp 101965 + SETGATE(idt[i], 0, GD_KTEXT, __vectors[i], DPL_KERNEL); + 1018a1: 8b 45 fc mov -0x4(%ebp),%eax + 1018a4: 8b 04 85 e0 95 11 00 mov 0x1195e0(,%eax,4),%eax + 1018ab: 0f b7 d0 movzwl %ax,%edx + 1018ae: 8b 45 fc mov -0x4(%ebp),%eax + 1018b1: 66 89 14 c5 e0 c6 11 mov %dx,0x11c6e0(,%eax,8) + 1018b8: 00 + 1018b9: 8b 45 fc mov -0x4(%ebp),%eax + 1018bc: 66 c7 04 c5 e2 c6 11 movw $0x8,0x11c6e2(,%eax,8) + 1018c3: 00 08 00 + 1018c6: 8b 45 fc mov -0x4(%ebp),%eax + 1018c9: 0f b6 14 c5 e4 c6 11 movzbl 0x11c6e4(,%eax,8),%edx + 1018d0: 00 + 1018d1: 80 e2 e0 and $0xe0,%dl + 1018d4: 88 14 c5 e4 c6 11 00 mov %dl,0x11c6e4(,%eax,8) + 1018db: 8b 45 fc mov -0x4(%ebp),%eax + 1018de: 0f b6 14 c5 e4 c6 11 movzbl 0x11c6e4(,%eax,8),%edx + 1018e5: 00 + 1018e6: 80 e2 1f and $0x1f,%dl + 1018e9: 88 14 c5 e4 c6 11 00 mov %dl,0x11c6e4(,%eax,8) + 1018f0: 8b 45 fc mov -0x4(%ebp),%eax + 1018f3: 0f b6 14 c5 e5 c6 11 movzbl 0x11c6e5(,%eax,8),%edx + 1018fa: 00 + 1018fb: 80 e2 f0 and $0xf0,%dl + 1018fe: 80 ca 0e or $0xe,%dl + 101901: 88 14 c5 e5 c6 11 00 mov %dl,0x11c6e5(,%eax,8) + 101908: 8b 45 fc mov -0x4(%ebp),%eax + 10190b: 0f b6 14 c5 e5 c6 11 movzbl 0x11c6e5(,%eax,8),%edx + 101912: 00 + 101913: 80 e2 ef and $0xef,%dl + 101916: 88 14 c5 e5 c6 11 00 mov %dl,0x11c6e5(,%eax,8) + 10191d: 8b 45 fc mov -0x4(%ebp),%eax + 101920: 0f b6 14 c5 e5 c6 11 movzbl 0x11c6e5(,%eax,8),%edx + 101927: 00 + 101928: 80 e2 9f and $0x9f,%dl + 10192b: 88 14 c5 e5 c6 11 00 mov %dl,0x11c6e5(,%eax,8) + 101932: 8b 45 fc mov -0x4(%ebp),%eax + 101935: 0f b6 14 c5 e5 c6 11 movzbl 0x11c6e5(,%eax,8),%edx + 10193c: 00 + 10193d: 80 ca 80 or $0x80,%dl + 101940: 88 14 c5 e5 c6 11 00 mov %dl,0x11c6e5(,%eax,8) + 101947: 8b 45 fc mov -0x4(%ebp),%eax + 10194a: 8b 04 85 e0 95 11 00 mov 0x1195e0(,%eax,4),%eax + 101951: c1 e8 10 shr $0x10,%eax + 101954: 0f b7 d0 movzwl %ax,%edx + 101957: 8b 45 fc mov -0x4(%ebp),%eax + 10195a: 66 89 14 c5 e6 c6 11 mov %dx,0x11c6e6(,%eax,8) + 101961: 00 + for (i = 0; i < sizeof(idt) / sizeof(struct gatedesc); i ++) { + 101962: ff 45 fc incl -0x4(%ebp) + 101965: 8b 45 fc mov -0x4(%ebp),%eax + 101968: 3d ff 00 00 00 cmp $0xff,%eax + 10196d: 0f 86 2e ff ff ff jbe 1018a1 + //宏用于配置每个 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_SWITCH_TOK], 0, GD_KTEXT, __vectors[T_SWITCH_TOK], DPL_USER); + 101973: a1 c4 97 11 00 mov 0x1197c4,%eax + 101978: 0f b7 c0 movzwl %ax,%eax + 10197b: 66 a3 a8 ca 11 00 mov %ax,0x11caa8 + 101981: 66 c7 05 aa ca 11 00 movw $0x8,0x11caaa + 101988: 08 00 + 10198a: 0f b6 05 ac ca 11 00 movzbl 0x11caac,%eax + 101991: 24 e0 and $0xe0,%al + 101993: a2 ac ca 11 00 mov %al,0x11caac + 101998: 0f b6 05 ac ca 11 00 movzbl 0x11caac,%eax + 10199f: 24 1f and $0x1f,%al + 1019a1: a2 ac ca 11 00 mov %al,0x11caac + 1019a6: 0f b6 05 ad ca 11 00 movzbl 0x11caad,%eax + 1019ad: 24 f0 and $0xf0,%al + 1019af: 0c 0e or $0xe,%al + 1019b1: a2 ad ca 11 00 mov %al,0x11caad + 1019b6: 0f b6 05 ad ca 11 00 movzbl 0x11caad,%eax + 1019bd: 24 ef and $0xef,%al + 1019bf: a2 ad ca 11 00 mov %al,0x11caad + 1019c4: 0f b6 05 ad ca 11 00 movzbl 0x11caad,%eax + 1019cb: 0c 60 or $0x60,%al + 1019cd: a2 ad ca 11 00 mov %al,0x11caad + 1019d2: 0f b6 05 ad ca 11 00 movzbl 0x11caad,%eax + 1019d9: 0c 80 or $0x80,%al + 1019db: a2 ad ca 11 00 mov %al,0x11caad + 1019e0: a1 c4 97 11 00 mov 0x1197c4,%eax + 1019e5: c1 e8 10 shr $0x10,%eax + 1019e8: 0f b7 c0 movzwl %ax,%eax + 1019eb: 66 a3 ae ca 11 00 mov %ax,0x11caae + 1019f1: c7 45 f8 60 95 11 00 movl $0x119560,-0x8(%ebp) + asm volatile ("lidt (%0)" :: "r" (pd) : "memory"); + 1019f8: 8b 45 f8 mov -0x8(%ebp),%eax + 1019fb: 0f 01 18 lidtl (%eax) +} + 1019fe: 90 nop + // load the IDT + //使用 lidt 指令将 IDT 描述符加载到 CPU 中 + lidt(&idt_pd); +} + 1019ff: 90 nop + 101a00: 89 ec mov %ebp,%esp + 101a02: 5d pop %ebp + 101a03: c3 ret + +00101a04 : + +static const char * +trapname(int trapno) { + 101a04: 55 push %ebp + 101a05: 89 e5 mov %esp,%ebp + "Alignment Check", + "Machine-Check", + "SIMD Floating-Point Exception" + }; + + if (trapno < sizeof(excnames)/sizeof(const char * const)) { + 101a07: 8b 45 08 mov 0x8(%ebp),%eax + 101a0a: 83 f8 13 cmp $0x13,%eax + 101a0d: 77 0c ja 101a1b + return excnames[trapno]; + 101a0f: 8b 45 08 mov 0x8(%ebp),%eax + 101a12: 8b 04 85 40 67 10 00 mov 0x106740(,%eax,4),%eax + 101a19: eb 18 jmp 101a33 + } + if (trapno >= IRQ_OFFSET && trapno < IRQ_OFFSET + 16) { + 101a1b: 83 7d 08 1f cmpl $0x1f,0x8(%ebp) + 101a1f: 7e 0d jle 101a2e + 101a21: 83 7d 08 2f cmpl $0x2f,0x8(%ebp) + 101a25: 7f 07 jg 101a2e + return "Hardware Interrupt"; + 101a27: b8 ea 63 10 00 mov $0x1063ea,%eax + 101a2c: eb 05 jmp 101a33 + } + return "(unknown trap)"; + 101a2e: b8 fd 63 10 00 mov $0x1063fd,%eax +} + 101a33: 5d pop %ebp + 101a34: c3 ret + +00101a35 : + +/* trap_in_kernel - test if trap happened in kernel */ +bool +trap_in_kernel(struct trapframe *tf) { + 101a35: 55 push %ebp + 101a36: 89 e5 mov %esp,%ebp + return (tf->tf_cs == (uint16_t)KERNEL_CS); + 101a38: 8b 45 08 mov 0x8(%ebp),%eax + 101a3b: 0f b7 40 3c movzwl 0x3c(%eax),%eax + 101a3f: 83 f8 08 cmp $0x8,%eax + 101a42: 0f 94 c0 sete %al + 101a45: 0f b6 c0 movzbl %al,%eax +} + 101a48: 5d pop %ebp + 101a49: c3 ret + +00101a4a : + "TF", "IF", "DF", "OF", NULL, NULL, "NT", NULL, + "RF", "VM", "AC", "VIF", "VIP", "ID", NULL, NULL, +}; + +void +print_trapframe(struct trapframe *tf) { + 101a4a: 55 push %ebp + 101a4b: 89 e5 mov %esp,%ebp + 101a4d: 83 ec 28 sub $0x28,%esp + cprintf("trapframe at %p\n", tf); + 101a50: 8b 45 08 mov 0x8(%ebp),%eax + 101a53: 89 44 24 04 mov %eax,0x4(%esp) + 101a57: c7 04 24 3e 64 10 00 movl $0x10643e,(%esp) + 101a5e: e8 03 e9 ff ff call 100366 + print_regs(&tf->tf_regs); + 101a63: 8b 45 08 mov 0x8(%ebp),%eax + 101a66: 89 04 24 mov %eax,(%esp) + 101a69: e8 8f 01 00 00 call 101bfd + cprintf(" ds 0x----%04x\n", tf->tf_ds); + 101a6e: 8b 45 08 mov 0x8(%ebp),%eax + 101a71: 0f b7 40 2c movzwl 0x2c(%eax),%eax + 101a75: 89 44 24 04 mov %eax,0x4(%esp) + 101a79: c7 04 24 4f 64 10 00 movl $0x10644f,(%esp) + 101a80: e8 e1 e8 ff ff call 100366 + cprintf(" es 0x----%04x\n", tf->tf_es); + 101a85: 8b 45 08 mov 0x8(%ebp),%eax + 101a88: 0f b7 40 28 movzwl 0x28(%eax),%eax + 101a8c: 89 44 24 04 mov %eax,0x4(%esp) + 101a90: c7 04 24 62 64 10 00 movl $0x106462,(%esp) + 101a97: e8 ca e8 ff ff call 100366 + cprintf(" fs 0x----%04x\n", tf->tf_fs); + 101a9c: 8b 45 08 mov 0x8(%ebp),%eax + 101a9f: 0f b7 40 24 movzwl 0x24(%eax),%eax + 101aa3: 89 44 24 04 mov %eax,0x4(%esp) + 101aa7: c7 04 24 75 64 10 00 movl $0x106475,(%esp) + 101aae: e8 b3 e8 ff ff call 100366 + cprintf(" gs 0x----%04x\n", tf->tf_gs); + 101ab3: 8b 45 08 mov 0x8(%ebp),%eax + 101ab6: 0f b7 40 20 movzwl 0x20(%eax),%eax + 101aba: 89 44 24 04 mov %eax,0x4(%esp) + 101abe: c7 04 24 88 64 10 00 movl $0x106488,(%esp) + 101ac5: e8 9c e8 ff ff call 100366 + cprintf(" trap 0x%08x %s\n", tf->tf_trapno, trapname(tf->tf_trapno)); + 101aca: 8b 45 08 mov 0x8(%ebp),%eax + 101acd: 8b 40 30 mov 0x30(%eax),%eax + 101ad0: 89 04 24 mov %eax,(%esp) + 101ad3: e8 2c ff ff ff call 101a04 + 101ad8: 8b 55 08 mov 0x8(%ebp),%edx + 101adb: 8b 52 30 mov 0x30(%edx),%edx + 101ade: 89 44 24 08 mov %eax,0x8(%esp) + 101ae2: 89 54 24 04 mov %edx,0x4(%esp) + 101ae6: c7 04 24 9b 64 10 00 movl $0x10649b,(%esp) + 101aed: e8 74 e8 ff ff call 100366 + cprintf(" err 0x%08x\n", tf->tf_err); + 101af2: 8b 45 08 mov 0x8(%ebp),%eax + 101af5: 8b 40 34 mov 0x34(%eax),%eax + 101af8: 89 44 24 04 mov %eax,0x4(%esp) + 101afc: c7 04 24 ad 64 10 00 movl $0x1064ad,(%esp) + 101b03: e8 5e e8 ff ff call 100366 + cprintf(" eip 0x%08x\n", tf->tf_eip); + 101b08: 8b 45 08 mov 0x8(%ebp),%eax + 101b0b: 8b 40 38 mov 0x38(%eax),%eax + 101b0e: 89 44 24 04 mov %eax,0x4(%esp) + 101b12: c7 04 24 bc 64 10 00 movl $0x1064bc,(%esp) + 101b19: e8 48 e8 ff ff call 100366 + cprintf(" cs 0x----%04x\n", tf->tf_cs); + 101b1e: 8b 45 08 mov 0x8(%ebp),%eax + 101b21: 0f b7 40 3c movzwl 0x3c(%eax),%eax + 101b25: 89 44 24 04 mov %eax,0x4(%esp) + 101b29: c7 04 24 cb 64 10 00 movl $0x1064cb,(%esp) + 101b30: e8 31 e8 ff ff call 100366 + cprintf(" flag 0x%08x ", tf->tf_eflags); + 101b35: 8b 45 08 mov 0x8(%ebp),%eax + 101b38: 8b 40 40 mov 0x40(%eax),%eax + 101b3b: 89 44 24 04 mov %eax,0x4(%esp) + 101b3f: c7 04 24 de 64 10 00 movl $0x1064de,(%esp) + 101b46: e8 1b e8 ff ff call 100366 + + int i, j; + for (i = 0, j = 1; i < sizeof(IA32flags) / sizeof(IA32flags[0]); i ++, j <<= 1) { + 101b4b: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + 101b52: c7 45 f0 01 00 00 00 movl $0x1,-0x10(%ebp) + 101b59: eb 3d jmp 101b98 + if ((tf->tf_eflags & j) && IA32flags[i] != NULL) { + 101b5b: 8b 45 08 mov 0x8(%ebp),%eax + 101b5e: 8b 50 40 mov 0x40(%eax),%edx + 101b61: 8b 45 f0 mov -0x10(%ebp),%eax + 101b64: 21 d0 and %edx,%eax + 101b66: 85 c0 test %eax,%eax + 101b68: 74 28 je 101b92 + 101b6a: 8b 45 f4 mov -0xc(%ebp),%eax + 101b6d: 8b 04 85 80 95 11 00 mov 0x119580(,%eax,4),%eax + 101b74: 85 c0 test %eax,%eax + 101b76: 74 1a je 101b92 + cprintf("%s,", IA32flags[i]); + 101b78: 8b 45 f4 mov -0xc(%ebp),%eax + 101b7b: 8b 04 85 80 95 11 00 mov 0x119580(,%eax,4),%eax + 101b82: 89 44 24 04 mov %eax,0x4(%esp) + 101b86: c7 04 24 ed 64 10 00 movl $0x1064ed,(%esp) + 101b8d: e8 d4 e7 ff ff call 100366 + for (i = 0, j = 1; i < sizeof(IA32flags) / sizeof(IA32flags[0]); i ++, j <<= 1) { + 101b92: ff 45 f4 incl -0xc(%ebp) + 101b95: d1 65 f0 shll -0x10(%ebp) + 101b98: 8b 45 f4 mov -0xc(%ebp),%eax + 101b9b: 83 f8 17 cmp $0x17,%eax + 101b9e: 76 bb jbe 101b5b + } + } + cprintf("IOPL=%d\n", (tf->tf_eflags & FL_IOPL_MASK) >> 12); + 101ba0: 8b 45 08 mov 0x8(%ebp),%eax + 101ba3: 8b 40 40 mov 0x40(%eax),%eax + 101ba6: c1 e8 0c shr $0xc,%eax + 101ba9: 83 e0 03 and $0x3,%eax + 101bac: 89 44 24 04 mov %eax,0x4(%esp) + 101bb0: c7 04 24 f1 64 10 00 movl $0x1064f1,(%esp) + 101bb7: e8 aa e7 ff ff call 100366 + + if (!trap_in_kernel(tf)) { + 101bbc: 8b 45 08 mov 0x8(%ebp),%eax + 101bbf: 89 04 24 mov %eax,(%esp) + 101bc2: e8 6e fe ff ff call 101a35 + 101bc7: 85 c0 test %eax,%eax + 101bc9: 75 2d jne 101bf8 + cprintf(" esp 0x%08x\n", tf->tf_esp); + 101bcb: 8b 45 08 mov 0x8(%ebp),%eax + 101bce: 8b 40 44 mov 0x44(%eax),%eax + 101bd1: 89 44 24 04 mov %eax,0x4(%esp) + 101bd5: c7 04 24 fa 64 10 00 movl $0x1064fa,(%esp) + 101bdc: e8 85 e7 ff ff call 100366 + cprintf(" ss 0x----%04x\n", tf->tf_ss); + 101be1: 8b 45 08 mov 0x8(%ebp),%eax + 101be4: 0f b7 40 48 movzwl 0x48(%eax),%eax + 101be8: 89 44 24 04 mov %eax,0x4(%esp) + 101bec: c7 04 24 09 65 10 00 movl $0x106509,(%esp) + 101bf3: e8 6e e7 ff ff call 100366 + } +} + 101bf8: 90 nop + 101bf9: 89 ec mov %ebp,%esp + 101bfb: 5d pop %ebp + 101bfc: c3 ret + +00101bfd : + +void +print_regs(struct pushregs *regs) { + 101bfd: 55 push %ebp + 101bfe: 89 e5 mov %esp,%ebp + 101c00: 83 ec 18 sub $0x18,%esp + cprintf(" edi 0x%08x\n", regs->reg_edi); + 101c03: 8b 45 08 mov 0x8(%ebp),%eax + 101c06: 8b 00 mov (%eax),%eax + 101c08: 89 44 24 04 mov %eax,0x4(%esp) + 101c0c: c7 04 24 1c 65 10 00 movl $0x10651c,(%esp) + 101c13: e8 4e e7 ff ff call 100366 + cprintf(" esi 0x%08x\n", regs->reg_esi); + 101c18: 8b 45 08 mov 0x8(%ebp),%eax + 101c1b: 8b 40 04 mov 0x4(%eax),%eax + 101c1e: 89 44 24 04 mov %eax,0x4(%esp) + 101c22: c7 04 24 2b 65 10 00 movl $0x10652b,(%esp) + 101c29: e8 38 e7 ff ff call 100366 + cprintf(" ebp 0x%08x\n", regs->reg_ebp); + 101c2e: 8b 45 08 mov 0x8(%ebp),%eax + 101c31: 8b 40 08 mov 0x8(%eax),%eax + 101c34: 89 44 24 04 mov %eax,0x4(%esp) + 101c38: c7 04 24 3a 65 10 00 movl $0x10653a,(%esp) + 101c3f: e8 22 e7 ff ff call 100366 + cprintf(" oesp 0x%08x\n", regs->reg_oesp); + 101c44: 8b 45 08 mov 0x8(%ebp),%eax + 101c47: 8b 40 0c mov 0xc(%eax),%eax + 101c4a: 89 44 24 04 mov %eax,0x4(%esp) + 101c4e: c7 04 24 49 65 10 00 movl $0x106549,(%esp) + 101c55: e8 0c e7 ff ff call 100366 + cprintf(" ebx 0x%08x\n", regs->reg_ebx); + 101c5a: 8b 45 08 mov 0x8(%ebp),%eax + 101c5d: 8b 40 10 mov 0x10(%eax),%eax + 101c60: 89 44 24 04 mov %eax,0x4(%esp) + 101c64: c7 04 24 58 65 10 00 movl $0x106558,(%esp) + 101c6b: e8 f6 e6 ff ff call 100366 + cprintf(" edx 0x%08x\n", regs->reg_edx); + 101c70: 8b 45 08 mov 0x8(%ebp),%eax + 101c73: 8b 40 14 mov 0x14(%eax),%eax + 101c76: 89 44 24 04 mov %eax,0x4(%esp) + 101c7a: c7 04 24 67 65 10 00 movl $0x106567,(%esp) + 101c81: e8 e0 e6 ff ff call 100366 + cprintf(" ecx 0x%08x\n", regs->reg_ecx); + 101c86: 8b 45 08 mov 0x8(%ebp),%eax + 101c89: 8b 40 18 mov 0x18(%eax),%eax + 101c8c: 89 44 24 04 mov %eax,0x4(%esp) + 101c90: c7 04 24 76 65 10 00 movl $0x106576,(%esp) + 101c97: e8 ca e6 ff ff call 100366 + cprintf(" eax 0x%08x\n", regs->reg_eax); + 101c9c: 8b 45 08 mov 0x8(%ebp),%eax + 101c9f: 8b 40 1c mov 0x1c(%eax),%eax + 101ca2: 89 44 24 04 mov %eax,0x4(%esp) + 101ca6: c7 04 24 85 65 10 00 movl $0x106585,(%esp) + 101cad: e8 b4 e6 ff ff call 100366 +} + 101cb2: 90 nop + 101cb3: 89 ec mov %ebp,%esp + 101cb5: 5d pop %ebp + 101cb6: c3 ret + +00101cb7 : + +struct trapframe switchk2u, *switchu2k; +/* trap_dispatch - dispatch based on what type of trap occurred */ +static void +trap_dispatch(struct trapframe *tf) { + 101cb7: 55 push %ebp + 101cb8: 89 e5 mov %esp,%ebp + 101cba: 83 ec 28 sub $0x28,%esp + 101cbd: 89 5d fc mov %ebx,-0x4(%ebp) + char c; + + switch (tf->tf_trapno) { + 101cc0: 8b 45 08 mov 0x8(%ebp),%eax + 101cc3: 8b 40 30 mov 0x30(%eax),%eax + 101cc6: 83 f8 79 cmp $0x79,%eax + 101cc9: 0f 84 6c 01 00 00 je 101e3b + 101ccf: 83 f8 79 cmp $0x79,%eax + 101cd2: 0f 87 e0 01 00 00 ja 101eb8 + 101cd8: 83 f8 78 cmp $0x78,%eax + 101cdb: 0f 84 d0 00 00 00 je 101db1 + 101ce1: 83 f8 78 cmp $0x78,%eax + 101ce4: 0f 87 ce 01 00 00 ja 101eb8 + 101cea: 83 f8 2f cmp $0x2f,%eax + 101ced: 0f 87 c5 01 00 00 ja 101eb8 + 101cf3: 83 f8 2e cmp $0x2e,%eax + 101cf6: 0f 83 f1 01 00 00 jae 101eed + 101cfc: 83 f8 24 cmp $0x24,%eax + 101cff: 74 5e je 101d5f + 101d01: 83 f8 24 cmp $0x24,%eax + 101d04: 0f 87 ae 01 00 00 ja 101eb8 + 101d0a: 83 f8 20 cmp $0x20,%eax + 101d0d: 74 0a je 101d19 + 101d0f: 83 f8 21 cmp $0x21,%eax + 101d12: 74 74 je 101d88 + 101d14: e9 9f 01 00 00 jmp 101eb8 + /* handle the timer interrupt */ + /* (1) After a timer interrupt, you should record this event using a global variable (increase it), such as ticks in kern/driver/clock.c + * (2) Every TICK_NUM cycle, you can print some info using a funciton, such as print_ticks(). + * (3) Too Simple? Yes, I think so! + */ + ticks ++; //记录中断事件 + 101d19: a1 24 c4 11 00 mov 0x11c424,%eax + 101d1e: 40 inc %eax + 101d1f: a3 24 c4 11 00 mov %eax,0x11c424 + if (ticks % TICK_NUM == 0) + 101d24: 8b 0d 24 c4 11 00 mov 0x11c424,%ecx + 101d2a: ba 1f 85 eb 51 mov $0x51eb851f,%edx + 101d2f: 89 c8 mov %ecx,%eax + 101d31: f7 e2 mul %edx + 101d33: c1 ea 05 shr $0x5,%edx + 101d36: 89 d0 mov %edx,%eax + 101d38: c1 e0 02 shl $0x2,%eax + 101d3b: 01 d0 add %edx,%eax + 101d3d: 8d 14 85 00 00 00 00 lea 0x0(,%eax,4),%edx + 101d44: 01 d0 add %edx,%eax + 101d46: c1 e0 02 shl $0x2,%eax + 101d49: 29 c1 sub %eax,%ecx + 101d4b: 89 ca mov %ecx,%edx + 101d4d: 85 d2 test %edx,%edx + 101d4f: 0f 85 9b 01 00 00 jne 101ef0 + { + print_ticks(); + 101d55: e8 16 fb ff ff call 101870 + }//每经过 TICK_NUM 次周期时,调用 print_ticks() 打印信息。 + break; + 101d5a: e9 91 01 00 00 jmp 101ef0 + case IRQ_OFFSET + IRQ_COM1: + c = cons_getc(); + 101d5f: e8 af f8 ff ff call 101613 + 101d64: 88 45 f7 mov %al,-0x9(%ebp) + cprintf("serial [%03d] %c\n", c, c); + 101d67: 0f be 55 f7 movsbl -0x9(%ebp),%edx + 101d6b: 0f be 45 f7 movsbl -0x9(%ebp),%eax + 101d6f: 89 54 24 08 mov %edx,0x8(%esp) + 101d73: 89 44 24 04 mov %eax,0x4(%esp) + 101d77: c7 04 24 94 65 10 00 movl $0x106594,(%esp) + 101d7e: e8 e3 e5 ff ff call 100366 + break; + 101d83: e9 6f 01 00 00 jmp 101ef7 + case IRQ_OFFSET + IRQ_KBD: + c = cons_getc(); + 101d88: e8 86 f8 ff ff call 101613 + 101d8d: 88 45 f7 mov %al,-0x9(%ebp) + cprintf("kbd [%03d] %c\n", c, c); + 101d90: 0f be 55 f7 movsbl -0x9(%ebp),%edx + 101d94: 0f be 45 f7 movsbl -0x9(%ebp),%eax + 101d98: 89 54 24 08 mov %edx,0x8(%esp) + 101d9c: 89 44 24 04 mov %eax,0x4(%esp) + 101da0: c7 04 24 a6 65 10 00 movl $0x1065a6,(%esp) + 101da7: e8 ba e5 ff ff call 100366 + break; + 101dac: e9 46 01 00 00 jmp 101ef7 + //LAB1 CHALLENGE 1 : YOUR CODE you should modify below codes. + case T_SWITCH_TOU://表示发生了从内核模式切换到用户模式的请求。 + if (tf->tf_cs != USER_CS) {//判断当前是否在内核模式下 + 101db1: 8b 45 08 mov 0x8(%ebp),%eax + 101db4: 0f b7 40 3c movzwl 0x3c(%eax),%eax + 101db8: 83 f8 1b cmp $0x1b,%eax + 101dbb: 0f 84 32 01 00 00 je 101ef3 + switchk2u = *tf; //保存当前陷阱框架 + 101dc1: 8b 4d 08 mov 0x8(%ebp),%ecx + 101dc4: b8 4c 00 00 00 mov $0x4c,%eax + 101dc9: 83 e0 fc and $0xfffffffc,%eax + 101dcc: 89 c3 mov %eax,%ebx + 101dce: b8 00 00 00 00 mov $0x0,%eax + 101dd3: 8b 14 01 mov (%ecx,%eax,1),%edx + 101dd6: 89 90 80 c6 11 00 mov %edx,0x11c680(%eax) + 101ddc: 83 c0 04 add $0x4,%eax + 101ddf: 39 d8 cmp %ebx,%eax + 101de1: 72 f0 jb 101dd3 + switchk2u.tf_cs = USER_CS;//设置用户模式的段寄存器 + 101de3: 66 c7 05 bc c6 11 00 movw $0x1b,0x11c6bc + 101dea: 1b 00 + //将数据段和栈段寄存器 都设置为 USER_DS(用户数据段) + switchk2u.tf_ds = switchk2u.tf_es = switchk2u.tf_ss = USER_DS; + 101dec: 66 c7 05 c8 c6 11 00 movw $0x23,0x11c6c8 + 101df3: 23 00 + 101df5: 0f b7 05 c8 c6 11 00 movzwl 0x11c6c8,%eax + 101dfc: 66 a3 a8 c6 11 00 mov %ax,0x11c6a8 + 101e02: 0f b7 05 a8 c6 11 00 movzwl 0x11c6a8,%eax + 101e09: 66 a3 ac c6 11 00 mov %ax,0x11c6ac + switchk2u.tf_esp = (uint32_t)tf + sizeof(struct trapframe) - 8; + 101e0f: 8b 45 08 mov 0x8(%ebp),%eax + 101e12: 83 c0 44 add $0x44,%eax + 101e15: a3 c4 c6 11 00 mov %eax,0x11c6c4 + + // set eflags, make sure ucore can use io under user mode. + // if CPL > IOPL, then cpu will generate a general protection. + switchk2u.tf_eflags |= FL_IOPL_MASK;//允许用户模式下进行 I/O 操作 + 101e1a: a1 c0 c6 11 00 mov 0x11c6c0,%eax + 101e1f: 0d 00 30 00 00 or $0x3000,%eax + 101e24: a3 c0 c6 11 00 mov %eax,0x11c6c0 + + // set temporary stack + // then iret will jump to the right stack + *((uint32_t *)tf - 1) = (uint32_t)&switchk2u; + 101e29: 8b 45 08 mov 0x8(%ebp),%eax + 101e2c: 83 e8 04 sub $0x4,%eax + 101e2f: ba 80 c6 11 00 mov $0x11c680,%edx + 101e34: 89 10 mov %edx,(%eax) + } + break; + 101e36: e9 b8 00 00 00 jmp 101ef3 + case T_SWITCH_TOK: // T_SWITCH_TOK 表示发生了从用户模式切换到内核模式的请求。 + if (tf->tf_cs != KERNEL_CS) { //判断当前是否在用户模式下 + 101e3b: 8b 45 08 mov 0x8(%ebp),%eax + 101e3e: 0f b7 40 3c movzwl 0x3c(%eax),%eax + 101e42: 83 f8 08 cmp $0x8,%eax + 101e45: 0f 84 ab 00 00 00 je 101ef6 + tf->tf_cs = KERNEL_CS; + 101e4b: 8b 45 08 mov 0x8(%ebp),%eax + 101e4e: 66 c7 40 3c 08 00 movw $0x8,0x3c(%eax) + tf->tf_ds = tf->tf_es = KERNEL_DS; + 101e54: 8b 45 08 mov 0x8(%ebp),%eax + 101e57: 66 c7 40 28 10 00 movw $0x10,0x28(%eax) + 101e5d: 8b 45 08 mov 0x8(%ebp),%eax + 101e60: 0f b7 50 28 movzwl 0x28(%eax),%edx + 101e64: 8b 45 08 mov 0x8(%ebp),%eax + 101e67: 66 89 50 2c mov %dx,0x2c(%eax) + //设置内核模式的段寄存器 + tf->tf_eflags &= ~FL_IOPL_MASK; //清除 I/O 权限标志 + 101e6b: 8b 45 08 mov 0x8(%ebp),%eax + 101e6e: 8b 40 40 mov 0x40(%eax),%eax + 101e71: 25 ff cf ff ff and $0xffffcfff,%eax + 101e76: 89 c2 mov %eax,%edx + 101e78: 8b 45 08 mov 0x8(%ebp),%eax + 101e7b: 89 50 40 mov %edx,0x40(%eax) + switchu2k = (struct trapframe *)(tf->tf_esp - (sizeof(struct trapframe) - 8)); + 101e7e: 8b 45 08 mov 0x8(%ebp),%eax + 101e81: 8b 40 44 mov 0x44(%eax),%eax + 101e84: 83 e8 44 sub $0x44,%eax + 101e87: a3 cc c6 11 00 mov %eax,0x11c6cc + //使用 memmove 将当前的陷阱框架(除了最后8个字节)复制到新的陷阱框架位置 switchu2k + memmove(switchu2k, tf, sizeof(struct trapframe) - 8); + 101e8c: a1 cc c6 11 00 mov 0x11c6cc,%eax + 101e91: c7 44 24 08 44 00 00 movl $0x44,0x8(%esp) + 101e98: 00 + 101e99: 8b 55 08 mov 0x8(%ebp),%edx + 101e9c: 89 54 24 04 mov %edx,0x4(%esp) + 101ea0: 89 04 24 mov %eax,(%esp) + 101ea3: e8 a2 40 00 00 call 105f4a + //将新的陷阱框架地址 switchu2k 存储到当前陷阱框架之前的一个栈位置 + *((uint32_t *)tf - 1) = (uint32_t)switchu2k; + 101ea8: 8b 15 cc c6 11 00 mov 0x11c6cc,%edx + 101eae: 8b 45 08 mov 0x8(%ebp),%eax + 101eb1: 83 e8 04 sub $0x4,%eax + 101eb4: 89 10 mov %edx,(%eax) + } + break; + 101eb6: eb 3e jmp 101ef6 + case IRQ_OFFSET + IRQ_IDE2: + /* do nothing */ + break; + default: + // in kernel, it must be a mistake + if ((tf->tf_cs & 3) == 0) { + 101eb8: 8b 45 08 mov 0x8(%ebp),%eax + 101ebb: 0f b7 40 3c movzwl 0x3c(%eax),%eax + 101ebf: 83 e0 03 and $0x3,%eax + 101ec2: 85 c0 test %eax,%eax + 101ec4: 75 31 jne 101ef7 + print_trapframe(tf); + 101ec6: 8b 45 08 mov 0x8(%ebp),%eax + 101ec9: 89 04 24 mov %eax,(%esp) + 101ecc: e8 79 fb ff ff call 101a4a + panic("unexpected trap in kernel.\n"); + 101ed1: c7 44 24 08 b5 65 10 movl $0x1065b5,0x8(%esp) + 101ed8: 00 + 101ed9: c7 44 24 04 dc 00 00 movl $0xdc,0x4(%esp) + 101ee0: 00 + 101ee1: c7 04 24 d1 65 10 00 movl $0x1065d1,(%esp) + 101ee8: e8 46 ed ff ff call 100c33 <__panic> + break; + 101eed: 90 nop + 101eee: eb 07 jmp 101ef7 + break; + 101ef0: 90 nop + 101ef1: eb 04 jmp 101ef7 + break; + 101ef3: 90 nop + 101ef4: eb 01 jmp 101ef7 + break; + 101ef6: 90 nop + } + } +} + 101ef7: 90 nop + 101ef8: 8b 5d fc mov -0x4(%ebp),%ebx + 101efb: 89 ec mov %ebp,%esp + 101efd: 5d pop %ebp + 101efe: c3 ret + +00101eff : + * 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) { + 101eff: 55 push %ebp + 101f00: 89 e5 mov %esp,%ebp + 101f02: 83 ec 18 sub $0x18,%esp + // dispatch based on what type of trap occurred + trap_dispatch(tf); + 101f05: 8b 45 08 mov 0x8(%ebp),%eax + 101f08: 89 04 24 mov %eax,(%esp) + 101f0b: e8 a7 fd ff ff call 101cb7 +} + 101f10: 90 nop + 101f11: 89 ec mov %ebp,%esp + 101f13: 5d pop %ebp + 101f14: c3 ret + +00101f15 <__alltraps>: +.text +.globl __alltraps +__alltraps: + # push registers to build a trap frame + # therefore make the stack look like a struct trapframe + pushl %ds + 101f15: 1e push %ds + pushl %es + 101f16: 06 push %es + pushl %fs + 101f17: 0f a0 push %fs + pushl %gs + 101f19: 0f a8 push %gs + pushal + 101f1b: 60 pusha + + # load GD_KDATA into %ds and %es to set up data segments for kernel + movl $GD_KDATA, %eax + 101f1c: b8 10 00 00 00 mov $0x10,%eax + movw %ax, %ds + 101f21: 8e d8 mov %eax,%ds + movw %ax, %es + 101f23: 8e c0 mov %eax,%es + + # push %esp to pass a pointer to the trapframe as an argument to trap() + pushl %esp + 101f25: 54 push %esp + + # call trap(tf), where tf=%esp + call trap + 101f26: e8 d4 ff ff ff call 101eff + + # pop the pushed stack pointer + popl %esp + 101f2b: 5c pop %esp + +00101f2c <__trapret>: + + # return falls through to trapret... +.globl __trapret +__trapret: + # restore registers from stack + popal + 101f2c: 61 popa + + # restore %ds, %es, %fs and %gs + popl %gs + 101f2d: 0f a9 pop %gs + popl %fs + 101f2f: 0f a1 pop %fs + popl %es + 101f31: 07 pop %es + popl %ds + 101f32: 1f pop %ds + + # get rid of the trap number and error code + addl $0x8, %esp + 101f33: 83 c4 08 add $0x8,%esp + iret + 101f36: cf iret + +00101f37 : +# handler +.text +.globl __alltraps +.globl vector0 +vector0: + pushl $0 + 101f37: 6a 00 push $0x0 + pushl $0 + 101f39: 6a 00 push $0x0 + jmp __alltraps + 101f3b: e9 d5 ff ff ff jmp 101f15 <__alltraps> + +00101f40 : +.globl vector1 +vector1: + pushl $0 + 101f40: 6a 00 push $0x0 + pushl $1 + 101f42: 6a 01 push $0x1 + jmp __alltraps + 101f44: e9 cc ff ff ff jmp 101f15 <__alltraps> + +00101f49 : +.globl vector2 +vector2: + pushl $0 + 101f49: 6a 00 push $0x0 + pushl $2 + 101f4b: 6a 02 push $0x2 + jmp __alltraps + 101f4d: e9 c3 ff ff ff jmp 101f15 <__alltraps> + +00101f52 : +.globl vector3 +vector3: + pushl $0 + 101f52: 6a 00 push $0x0 + pushl $3 + 101f54: 6a 03 push $0x3 + jmp __alltraps + 101f56: e9 ba ff ff ff jmp 101f15 <__alltraps> + +00101f5b : +.globl vector4 +vector4: + pushl $0 + 101f5b: 6a 00 push $0x0 + pushl $4 + 101f5d: 6a 04 push $0x4 + jmp __alltraps + 101f5f: e9 b1 ff ff ff jmp 101f15 <__alltraps> + +00101f64 : +.globl vector5 +vector5: + pushl $0 + 101f64: 6a 00 push $0x0 + pushl $5 + 101f66: 6a 05 push $0x5 + jmp __alltraps + 101f68: e9 a8 ff ff ff jmp 101f15 <__alltraps> + +00101f6d : +.globl vector6 +vector6: + pushl $0 + 101f6d: 6a 00 push $0x0 + pushl $6 + 101f6f: 6a 06 push $0x6 + jmp __alltraps + 101f71: e9 9f ff ff ff jmp 101f15 <__alltraps> + +00101f76 : +.globl vector7 +vector7: + pushl $0 + 101f76: 6a 00 push $0x0 + pushl $7 + 101f78: 6a 07 push $0x7 + jmp __alltraps + 101f7a: e9 96 ff ff ff jmp 101f15 <__alltraps> + +00101f7f : +.globl vector8 +vector8: + pushl $8 + 101f7f: 6a 08 push $0x8 + jmp __alltraps + 101f81: e9 8f ff ff ff jmp 101f15 <__alltraps> + +00101f86 : +.globl vector9 +vector9: + pushl $0 + 101f86: 6a 00 push $0x0 + pushl $9 + 101f88: 6a 09 push $0x9 + jmp __alltraps + 101f8a: e9 86 ff ff ff jmp 101f15 <__alltraps> + +00101f8f : +.globl vector10 +vector10: + pushl $10 + 101f8f: 6a 0a push $0xa + jmp __alltraps + 101f91: e9 7f ff ff ff jmp 101f15 <__alltraps> + +00101f96 : +.globl vector11 +vector11: + pushl $11 + 101f96: 6a 0b push $0xb + jmp __alltraps + 101f98: e9 78 ff ff ff jmp 101f15 <__alltraps> + +00101f9d : +.globl vector12 +vector12: + pushl $12 + 101f9d: 6a 0c push $0xc + jmp __alltraps + 101f9f: e9 71 ff ff ff jmp 101f15 <__alltraps> + +00101fa4 : +.globl vector13 +vector13: + pushl $13 + 101fa4: 6a 0d push $0xd + jmp __alltraps + 101fa6: e9 6a ff ff ff jmp 101f15 <__alltraps> + +00101fab : +.globl vector14 +vector14: + pushl $14 + 101fab: 6a 0e push $0xe + jmp __alltraps + 101fad: e9 63 ff ff ff jmp 101f15 <__alltraps> + +00101fb2 : +.globl vector15 +vector15: + pushl $0 + 101fb2: 6a 00 push $0x0 + pushl $15 + 101fb4: 6a 0f push $0xf + jmp __alltraps + 101fb6: e9 5a ff ff ff jmp 101f15 <__alltraps> + +00101fbb : +.globl vector16 +vector16: + pushl $0 + 101fbb: 6a 00 push $0x0 + pushl $16 + 101fbd: 6a 10 push $0x10 + jmp __alltraps + 101fbf: e9 51 ff ff ff jmp 101f15 <__alltraps> + +00101fc4 : +.globl vector17 +vector17: + pushl $17 + 101fc4: 6a 11 push $0x11 + jmp __alltraps + 101fc6: e9 4a ff ff ff jmp 101f15 <__alltraps> + +00101fcb : +.globl vector18 +vector18: + pushl $0 + 101fcb: 6a 00 push $0x0 + pushl $18 + 101fcd: 6a 12 push $0x12 + jmp __alltraps + 101fcf: e9 41 ff ff ff jmp 101f15 <__alltraps> + +00101fd4 : +.globl vector19 +vector19: + pushl $0 + 101fd4: 6a 00 push $0x0 + pushl $19 + 101fd6: 6a 13 push $0x13 + jmp __alltraps + 101fd8: e9 38 ff ff ff jmp 101f15 <__alltraps> + +00101fdd : +.globl vector20 +vector20: + pushl $0 + 101fdd: 6a 00 push $0x0 + pushl $20 + 101fdf: 6a 14 push $0x14 + jmp __alltraps + 101fe1: e9 2f ff ff ff jmp 101f15 <__alltraps> + +00101fe6 : +.globl vector21 +vector21: + pushl $0 + 101fe6: 6a 00 push $0x0 + pushl $21 + 101fe8: 6a 15 push $0x15 + jmp __alltraps + 101fea: e9 26 ff ff ff jmp 101f15 <__alltraps> + +00101fef : +.globl vector22 +vector22: + pushl $0 + 101fef: 6a 00 push $0x0 + pushl $22 + 101ff1: 6a 16 push $0x16 + jmp __alltraps + 101ff3: e9 1d ff ff ff jmp 101f15 <__alltraps> + +00101ff8 : +.globl vector23 +vector23: + pushl $0 + 101ff8: 6a 00 push $0x0 + pushl $23 + 101ffa: 6a 17 push $0x17 + jmp __alltraps + 101ffc: e9 14 ff ff ff jmp 101f15 <__alltraps> + +00102001 : +.globl vector24 +vector24: + pushl $0 + 102001: 6a 00 push $0x0 + pushl $24 + 102003: 6a 18 push $0x18 + jmp __alltraps + 102005: e9 0b ff ff ff jmp 101f15 <__alltraps> + +0010200a : +.globl vector25 +vector25: + pushl $0 + 10200a: 6a 00 push $0x0 + pushl $25 + 10200c: 6a 19 push $0x19 + jmp __alltraps + 10200e: e9 02 ff ff ff jmp 101f15 <__alltraps> + +00102013 : +.globl vector26 +vector26: + pushl $0 + 102013: 6a 00 push $0x0 + pushl $26 + 102015: 6a 1a push $0x1a + jmp __alltraps + 102017: e9 f9 fe ff ff jmp 101f15 <__alltraps> + +0010201c : +.globl vector27 +vector27: + pushl $0 + 10201c: 6a 00 push $0x0 + pushl $27 + 10201e: 6a 1b push $0x1b + jmp __alltraps + 102020: e9 f0 fe ff ff jmp 101f15 <__alltraps> + +00102025 : +.globl vector28 +vector28: + pushl $0 + 102025: 6a 00 push $0x0 + pushl $28 + 102027: 6a 1c push $0x1c + jmp __alltraps + 102029: e9 e7 fe ff ff jmp 101f15 <__alltraps> + +0010202e : +.globl vector29 +vector29: + pushl $0 + 10202e: 6a 00 push $0x0 + pushl $29 + 102030: 6a 1d push $0x1d + jmp __alltraps + 102032: e9 de fe ff ff jmp 101f15 <__alltraps> + +00102037 : +.globl vector30 +vector30: + pushl $0 + 102037: 6a 00 push $0x0 + pushl $30 + 102039: 6a 1e push $0x1e + jmp __alltraps + 10203b: e9 d5 fe ff ff jmp 101f15 <__alltraps> + +00102040 : +.globl vector31 +vector31: + pushl $0 + 102040: 6a 00 push $0x0 + pushl $31 + 102042: 6a 1f push $0x1f + jmp __alltraps + 102044: e9 cc fe ff ff jmp 101f15 <__alltraps> + +00102049 : +.globl vector32 +vector32: + pushl $0 + 102049: 6a 00 push $0x0 + pushl $32 + 10204b: 6a 20 push $0x20 + jmp __alltraps + 10204d: e9 c3 fe ff ff jmp 101f15 <__alltraps> + +00102052 : +.globl vector33 +vector33: + pushl $0 + 102052: 6a 00 push $0x0 + pushl $33 + 102054: 6a 21 push $0x21 + jmp __alltraps + 102056: e9 ba fe ff ff jmp 101f15 <__alltraps> + +0010205b : +.globl vector34 +vector34: + pushl $0 + 10205b: 6a 00 push $0x0 + pushl $34 + 10205d: 6a 22 push $0x22 + jmp __alltraps + 10205f: e9 b1 fe ff ff jmp 101f15 <__alltraps> + +00102064 : +.globl vector35 +vector35: + pushl $0 + 102064: 6a 00 push $0x0 + pushl $35 + 102066: 6a 23 push $0x23 + jmp __alltraps + 102068: e9 a8 fe ff ff jmp 101f15 <__alltraps> + +0010206d : +.globl vector36 +vector36: + pushl $0 + 10206d: 6a 00 push $0x0 + pushl $36 + 10206f: 6a 24 push $0x24 + jmp __alltraps + 102071: e9 9f fe ff ff jmp 101f15 <__alltraps> + +00102076 : +.globl vector37 +vector37: + pushl $0 + 102076: 6a 00 push $0x0 + pushl $37 + 102078: 6a 25 push $0x25 + jmp __alltraps + 10207a: e9 96 fe ff ff jmp 101f15 <__alltraps> + +0010207f : +.globl vector38 +vector38: + pushl $0 + 10207f: 6a 00 push $0x0 + pushl $38 + 102081: 6a 26 push $0x26 + jmp __alltraps + 102083: e9 8d fe ff ff jmp 101f15 <__alltraps> + +00102088 : +.globl vector39 +vector39: + pushl $0 + 102088: 6a 00 push $0x0 + pushl $39 + 10208a: 6a 27 push $0x27 + jmp __alltraps + 10208c: e9 84 fe ff ff jmp 101f15 <__alltraps> + +00102091 : +.globl vector40 +vector40: + pushl $0 + 102091: 6a 00 push $0x0 + pushl $40 + 102093: 6a 28 push $0x28 + jmp __alltraps + 102095: e9 7b fe ff ff jmp 101f15 <__alltraps> + +0010209a : +.globl vector41 +vector41: + pushl $0 + 10209a: 6a 00 push $0x0 + pushl $41 + 10209c: 6a 29 push $0x29 + jmp __alltraps + 10209e: e9 72 fe ff ff jmp 101f15 <__alltraps> + +001020a3 : +.globl vector42 +vector42: + pushl $0 + 1020a3: 6a 00 push $0x0 + pushl $42 + 1020a5: 6a 2a push $0x2a + jmp __alltraps + 1020a7: e9 69 fe ff ff jmp 101f15 <__alltraps> + +001020ac : +.globl vector43 +vector43: + pushl $0 + 1020ac: 6a 00 push $0x0 + pushl $43 + 1020ae: 6a 2b push $0x2b + jmp __alltraps + 1020b0: e9 60 fe ff ff jmp 101f15 <__alltraps> + +001020b5 : +.globl vector44 +vector44: + pushl $0 + 1020b5: 6a 00 push $0x0 + pushl $44 + 1020b7: 6a 2c push $0x2c + jmp __alltraps + 1020b9: e9 57 fe ff ff jmp 101f15 <__alltraps> + +001020be : +.globl vector45 +vector45: + pushl $0 + 1020be: 6a 00 push $0x0 + pushl $45 + 1020c0: 6a 2d push $0x2d + jmp __alltraps + 1020c2: e9 4e fe ff ff jmp 101f15 <__alltraps> + +001020c7 : +.globl vector46 +vector46: + pushl $0 + 1020c7: 6a 00 push $0x0 + pushl $46 + 1020c9: 6a 2e push $0x2e + jmp __alltraps + 1020cb: e9 45 fe ff ff jmp 101f15 <__alltraps> + +001020d0 : +.globl vector47 +vector47: + pushl $0 + 1020d0: 6a 00 push $0x0 + pushl $47 + 1020d2: 6a 2f push $0x2f + jmp __alltraps + 1020d4: e9 3c fe ff ff jmp 101f15 <__alltraps> + +001020d9 : +.globl vector48 +vector48: + pushl $0 + 1020d9: 6a 00 push $0x0 + pushl $48 + 1020db: 6a 30 push $0x30 + jmp __alltraps + 1020dd: e9 33 fe ff ff jmp 101f15 <__alltraps> + +001020e2 : +.globl vector49 +vector49: + pushl $0 + 1020e2: 6a 00 push $0x0 + pushl $49 + 1020e4: 6a 31 push $0x31 + jmp __alltraps + 1020e6: e9 2a fe ff ff jmp 101f15 <__alltraps> + +001020eb : +.globl vector50 +vector50: + pushl $0 + 1020eb: 6a 00 push $0x0 + pushl $50 + 1020ed: 6a 32 push $0x32 + jmp __alltraps + 1020ef: e9 21 fe ff ff jmp 101f15 <__alltraps> + +001020f4 : +.globl vector51 +vector51: + pushl $0 + 1020f4: 6a 00 push $0x0 + pushl $51 + 1020f6: 6a 33 push $0x33 + jmp __alltraps + 1020f8: e9 18 fe ff ff jmp 101f15 <__alltraps> + +001020fd : +.globl vector52 +vector52: + pushl $0 + 1020fd: 6a 00 push $0x0 + pushl $52 + 1020ff: 6a 34 push $0x34 + jmp __alltraps + 102101: e9 0f fe ff ff jmp 101f15 <__alltraps> + +00102106 : +.globl vector53 +vector53: + pushl $0 + 102106: 6a 00 push $0x0 + pushl $53 + 102108: 6a 35 push $0x35 + jmp __alltraps + 10210a: e9 06 fe ff ff jmp 101f15 <__alltraps> + +0010210f : +.globl vector54 +vector54: + pushl $0 + 10210f: 6a 00 push $0x0 + pushl $54 + 102111: 6a 36 push $0x36 + jmp __alltraps + 102113: e9 fd fd ff ff jmp 101f15 <__alltraps> + +00102118 : +.globl vector55 +vector55: + pushl $0 + 102118: 6a 00 push $0x0 + pushl $55 + 10211a: 6a 37 push $0x37 + jmp __alltraps + 10211c: e9 f4 fd ff ff jmp 101f15 <__alltraps> + +00102121 : +.globl vector56 +vector56: + pushl $0 + 102121: 6a 00 push $0x0 + pushl $56 + 102123: 6a 38 push $0x38 + jmp __alltraps + 102125: e9 eb fd ff ff jmp 101f15 <__alltraps> + +0010212a : +.globl vector57 +vector57: + pushl $0 + 10212a: 6a 00 push $0x0 + pushl $57 + 10212c: 6a 39 push $0x39 + jmp __alltraps + 10212e: e9 e2 fd ff ff jmp 101f15 <__alltraps> + +00102133 : +.globl vector58 +vector58: + pushl $0 + 102133: 6a 00 push $0x0 + pushl $58 + 102135: 6a 3a push $0x3a + jmp __alltraps + 102137: e9 d9 fd ff ff jmp 101f15 <__alltraps> + +0010213c : +.globl vector59 +vector59: + pushl $0 + 10213c: 6a 00 push $0x0 + pushl $59 + 10213e: 6a 3b push $0x3b + jmp __alltraps + 102140: e9 d0 fd ff ff jmp 101f15 <__alltraps> + +00102145 : +.globl vector60 +vector60: + pushl $0 + 102145: 6a 00 push $0x0 + pushl $60 + 102147: 6a 3c push $0x3c + jmp __alltraps + 102149: e9 c7 fd ff ff jmp 101f15 <__alltraps> + +0010214e : +.globl vector61 +vector61: + pushl $0 + 10214e: 6a 00 push $0x0 + pushl $61 + 102150: 6a 3d push $0x3d + jmp __alltraps + 102152: e9 be fd ff ff jmp 101f15 <__alltraps> + +00102157 : +.globl vector62 +vector62: + pushl $0 + 102157: 6a 00 push $0x0 + pushl $62 + 102159: 6a 3e push $0x3e + jmp __alltraps + 10215b: e9 b5 fd ff ff jmp 101f15 <__alltraps> + +00102160 : +.globl vector63 +vector63: + pushl $0 + 102160: 6a 00 push $0x0 + pushl $63 + 102162: 6a 3f push $0x3f + jmp __alltraps + 102164: e9 ac fd ff ff jmp 101f15 <__alltraps> + +00102169 : +.globl vector64 +vector64: + pushl $0 + 102169: 6a 00 push $0x0 + pushl $64 + 10216b: 6a 40 push $0x40 + jmp __alltraps + 10216d: e9 a3 fd ff ff jmp 101f15 <__alltraps> + +00102172 : +.globl vector65 +vector65: + pushl $0 + 102172: 6a 00 push $0x0 + pushl $65 + 102174: 6a 41 push $0x41 + jmp __alltraps + 102176: e9 9a fd ff ff jmp 101f15 <__alltraps> + +0010217b : +.globl vector66 +vector66: + pushl $0 + 10217b: 6a 00 push $0x0 + pushl $66 + 10217d: 6a 42 push $0x42 + jmp __alltraps + 10217f: e9 91 fd ff ff jmp 101f15 <__alltraps> + +00102184 : +.globl vector67 +vector67: + pushl $0 + 102184: 6a 00 push $0x0 + pushl $67 + 102186: 6a 43 push $0x43 + jmp __alltraps + 102188: e9 88 fd ff ff jmp 101f15 <__alltraps> + +0010218d : +.globl vector68 +vector68: + pushl $0 + 10218d: 6a 00 push $0x0 + pushl $68 + 10218f: 6a 44 push $0x44 + jmp __alltraps + 102191: e9 7f fd ff ff jmp 101f15 <__alltraps> + +00102196 : +.globl vector69 +vector69: + pushl $0 + 102196: 6a 00 push $0x0 + pushl $69 + 102198: 6a 45 push $0x45 + jmp __alltraps + 10219a: e9 76 fd ff ff jmp 101f15 <__alltraps> + +0010219f : +.globl vector70 +vector70: + pushl $0 + 10219f: 6a 00 push $0x0 + pushl $70 + 1021a1: 6a 46 push $0x46 + jmp __alltraps + 1021a3: e9 6d fd ff ff jmp 101f15 <__alltraps> + +001021a8 : +.globl vector71 +vector71: + pushl $0 + 1021a8: 6a 00 push $0x0 + pushl $71 + 1021aa: 6a 47 push $0x47 + jmp __alltraps + 1021ac: e9 64 fd ff ff jmp 101f15 <__alltraps> + +001021b1 : +.globl vector72 +vector72: + pushl $0 + 1021b1: 6a 00 push $0x0 + pushl $72 + 1021b3: 6a 48 push $0x48 + jmp __alltraps + 1021b5: e9 5b fd ff ff jmp 101f15 <__alltraps> + +001021ba : +.globl vector73 +vector73: + pushl $0 + 1021ba: 6a 00 push $0x0 + pushl $73 + 1021bc: 6a 49 push $0x49 + jmp __alltraps + 1021be: e9 52 fd ff ff jmp 101f15 <__alltraps> + +001021c3 : +.globl vector74 +vector74: + pushl $0 + 1021c3: 6a 00 push $0x0 + pushl $74 + 1021c5: 6a 4a push $0x4a + jmp __alltraps + 1021c7: e9 49 fd ff ff jmp 101f15 <__alltraps> + +001021cc : +.globl vector75 +vector75: + pushl $0 + 1021cc: 6a 00 push $0x0 + pushl $75 + 1021ce: 6a 4b push $0x4b + jmp __alltraps + 1021d0: e9 40 fd ff ff jmp 101f15 <__alltraps> + +001021d5 : +.globl vector76 +vector76: + pushl $0 + 1021d5: 6a 00 push $0x0 + pushl $76 + 1021d7: 6a 4c push $0x4c + jmp __alltraps + 1021d9: e9 37 fd ff ff jmp 101f15 <__alltraps> + +001021de : +.globl vector77 +vector77: + pushl $0 + 1021de: 6a 00 push $0x0 + pushl $77 + 1021e0: 6a 4d push $0x4d + jmp __alltraps + 1021e2: e9 2e fd ff ff jmp 101f15 <__alltraps> + +001021e7 : +.globl vector78 +vector78: + pushl $0 + 1021e7: 6a 00 push $0x0 + pushl $78 + 1021e9: 6a 4e push $0x4e + jmp __alltraps + 1021eb: e9 25 fd ff ff jmp 101f15 <__alltraps> + +001021f0 : +.globl vector79 +vector79: + pushl $0 + 1021f0: 6a 00 push $0x0 + pushl $79 + 1021f2: 6a 4f push $0x4f + jmp __alltraps + 1021f4: e9 1c fd ff ff jmp 101f15 <__alltraps> + +001021f9 : +.globl vector80 +vector80: + pushl $0 + 1021f9: 6a 00 push $0x0 + pushl $80 + 1021fb: 6a 50 push $0x50 + jmp __alltraps + 1021fd: e9 13 fd ff ff jmp 101f15 <__alltraps> + +00102202 : +.globl vector81 +vector81: + pushl $0 + 102202: 6a 00 push $0x0 + pushl $81 + 102204: 6a 51 push $0x51 + jmp __alltraps + 102206: e9 0a fd ff ff jmp 101f15 <__alltraps> + +0010220b : +.globl vector82 +vector82: + pushl $0 + 10220b: 6a 00 push $0x0 + pushl $82 + 10220d: 6a 52 push $0x52 + jmp __alltraps + 10220f: e9 01 fd ff ff jmp 101f15 <__alltraps> + +00102214 : +.globl vector83 +vector83: + pushl $0 + 102214: 6a 00 push $0x0 + pushl $83 + 102216: 6a 53 push $0x53 + jmp __alltraps + 102218: e9 f8 fc ff ff jmp 101f15 <__alltraps> + +0010221d : +.globl vector84 +vector84: + pushl $0 + 10221d: 6a 00 push $0x0 + pushl $84 + 10221f: 6a 54 push $0x54 + jmp __alltraps + 102221: e9 ef fc ff ff jmp 101f15 <__alltraps> + +00102226 : +.globl vector85 +vector85: + pushl $0 + 102226: 6a 00 push $0x0 + pushl $85 + 102228: 6a 55 push $0x55 + jmp __alltraps + 10222a: e9 e6 fc ff ff jmp 101f15 <__alltraps> + +0010222f : +.globl vector86 +vector86: + pushl $0 + 10222f: 6a 00 push $0x0 + pushl $86 + 102231: 6a 56 push $0x56 + jmp __alltraps + 102233: e9 dd fc ff ff jmp 101f15 <__alltraps> + +00102238 : +.globl vector87 +vector87: + pushl $0 + 102238: 6a 00 push $0x0 + pushl $87 + 10223a: 6a 57 push $0x57 + jmp __alltraps + 10223c: e9 d4 fc ff ff jmp 101f15 <__alltraps> + +00102241 : +.globl vector88 +vector88: + pushl $0 + 102241: 6a 00 push $0x0 + pushl $88 + 102243: 6a 58 push $0x58 + jmp __alltraps + 102245: e9 cb fc ff ff jmp 101f15 <__alltraps> + +0010224a : +.globl vector89 +vector89: + pushl $0 + 10224a: 6a 00 push $0x0 + pushl $89 + 10224c: 6a 59 push $0x59 + jmp __alltraps + 10224e: e9 c2 fc ff ff jmp 101f15 <__alltraps> + +00102253 : +.globl vector90 +vector90: + pushl $0 + 102253: 6a 00 push $0x0 + pushl $90 + 102255: 6a 5a push $0x5a + jmp __alltraps + 102257: e9 b9 fc ff ff jmp 101f15 <__alltraps> + +0010225c : +.globl vector91 +vector91: + pushl $0 + 10225c: 6a 00 push $0x0 + pushl $91 + 10225e: 6a 5b push $0x5b + jmp __alltraps + 102260: e9 b0 fc ff ff jmp 101f15 <__alltraps> + +00102265 : +.globl vector92 +vector92: + pushl $0 + 102265: 6a 00 push $0x0 + pushl $92 + 102267: 6a 5c push $0x5c + jmp __alltraps + 102269: e9 a7 fc ff ff jmp 101f15 <__alltraps> + +0010226e : +.globl vector93 +vector93: + pushl $0 + 10226e: 6a 00 push $0x0 + pushl $93 + 102270: 6a 5d push $0x5d + jmp __alltraps + 102272: e9 9e fc ff ff jmp 101f15 <__alltraps> + +00102277 : +.globl vector94 +vector94: + pushl $0 + 102277: 6a 00 push $0x0 + pushl $94 + 102279: 6a 5e push $0x5e + jmp __alltraps + 10227b: e9 95 fc ff ff jmp 101f15 <__alltraps> + +00102280 : +.globl vector95 +vector95: + pushl $0 + 102280: 6a 00 push $0x0 + pushl $95 + 102282: 6a 5f push $0x5f + jmp __alltraps + 102284: e9 8c fc ff ff jmp 101f15 <__alltraps> + +00102289 : +.globl vector96 +vector96: + pushl $0 + 102289: 6a 00 push $0x0 + pushl $96 + 10228b: 6a 60 push $0x60 + jmp __alltraps + 10228d: e9 83 fc ff ff jmp 101f15 <__alltraps> + +00102292 : +.globl vector97 +vector97: + pushl $0 + 102292: 6a 00 push $0x0 + pushl $97 + 102294: 6a 61 push $0x61 + jmp __alltraps + 102296: e9 7a fc ff ff jmp 101f15 <__alltraps> + +0010229b : +.globl vector98 +vector98: + pushl $0 + 10229b: 6a 00 push $0x0 + pushl $98 + 10229d: 6a 62 push $0x62 + jmp __alltraps + 10229f: e9 71 fc ff ff jmp 101f15 <__alltraps> + +001022a4 : +.globl vector99 +vector99: + pushl $0 + 1022a4: 6a 00 push $0x0 + pushl $99 + 1022a6: 6a 63 push $0x63 + jmp __alltraps + 1022a8: e9 68 fc ff ff jmp 101f15 <__alltraps> + +001022ad : +.globl vector100 +vector100: + pushl $0 + 1022ad: 6a 00 push $0x0 + pushl $100 + 1022af: 6a 64 push $0x64 + jmp __alltraps + 1022b1: e9 5f fc ff ff jmp 101f15 <__alltraps> + +001022b6 : +.globl vector101 +vector101: + pushl $0 + 1022b6: 6a 00 push $0x0 + pushl $101 + 1022b8: 6a 65 push $0x65 + jmp __alltraps + 1022ba: e9 56 fc ff ff jmp 101f15 <__alltraps> + +001022bf : +.globl vector102 +vector102: + pushl $0 + 1022bf: 6a 00 push $0x0 + pushl $102 + 1022c1: 6a 66 push $0x66 + jmp __alltraps + 1022c3: e9 4d fc ff ff jmp 101f15 <__alltraps> + +001022c8 : +.globl vector103 +vector103: + pushl $0 + 1022c8: 6a 00 push $0x0 + pushl $103 + 1022ca: 6a 67 push $0x67 + jmp __alltraps + 1022cc: e9 44 fc ff ff jmp 101f15 <__alltraps> + +001022d1 : +.globl vector104 +vector104: + pushl $0 + 1022d1: 6a 00 push $0x0 + pushl $104 + 1022d3: 6a 68 push $0x68 + jmp __alltraps + 1022d5: e9 3b fc ff ff jmp 101f15 <__alltraps> + +001022da : +.globl vector105 +vector105: + pushl $0 + 1022da: 6a 00 push $0x0 + pushl $105 + 1022dc: 6a 69 push $0x69 + jmp __alltraps + 1022de: e9 32 fc ff ff jmp 101f15 <__alltraps> + +001022e3 : +.globl vector106 +vector106: + pushl $0 + 1022e3: 6a 00 push $0x0 + pushl $106 + 1022e5: 6a 6a push $0x6a + jmp __alltraps + 1022e7: e9 29 fc ff ff jmp 101f15 <__alltraps> + +001022ec : +.globl vector107 +vector107: + pushl $0 + 1022ec: 6a 00 push $0x0 + pushl $107 + 1022ee: 6a 6b push $0x6b + jmp __alltraps + 1022f0: e9 20 fc ff ff jmp 101f15 <__alltraps> + +001022f5 : +.globl vector108 +vector108: + pushl $0 + 1022f5: 6a 00 push $0x0 + pushl $108 + 1022f7: 6a 6c push $0x6c + jmp __alltraps + 1022f9: e9 17 fc ff ff jmp 101f15 <__alltraps> + +001022fe : +.globl vector109 +vector109: + pushl $0 + 1022fe: 6a 00 push $0x0 + pushl $109 + 102300: 6a 6d push $0x6d + jmp __alltraps + 102302: e9 0e fc ff ff jmp 101f15 <__alltraps> + +00102307 : +.globl vector110 +vector110: + pushl $0 + 102307: 6a 00 push $0x0 + pushl $110 + 102309: 6a 6e push $0x6e + jmp __alltraps + 10230b: e9 05 fc ff ff jmp 101f15 <__alltraps> + +00102310 : +.globl vector111 +vector111: + pushl $0 + 102310: 6a 00 push $0x0 + pushl $111 + 102312: 6a 6f push $0x6f + jmp __alltraps + 102314: e9 fc fb ff ff jmp 101f15 <__alltraps> + +00102319 : +.globl vector112 +vector112: + pushl $0 + 102319: 6a 00 push $0x0 + pushl $112 + 10231b: 6a 70 push $0x70 + jmp __alltraps + 10231d: e9 f3 fb ff ff jmp 101f15 <__alltraps> + +00102322 : +.globl vector113 +vector113: + pushl $0 + 102322: 6a 00 push $0x0 + pushl $113 + 102324: 6a 71 push $0x71 + jmp __alltraps + 102326: e9 ea fb ff ff jmp 101f15 <__alltraps> + +0010232b : +.globl vector114 +vector114: + pushl $0 + 10232b: 6a 00 push $0x0 + pushl $114 + 10232d: 6a 72 push $0x72 + jmp __alltraps + 10232f: e9 e1 fb ff ff jmp 101f15 <__alltraps> + +00102334 : +.globl vector115 +vector115: + pushl $0 + 102334: 6a 00 push $0x0 + pushl $115 + 102336: 6a 73 push $0x73 + jmp __alltraps + 102338: e9 d8 fb ff ff jmp 101f15 <__alltraps> + +0010233d : +.globl vector116 +vector116: + pushl $0 + 10233d: 6a 00 push $0x0 + pushl $116 + 10233f: 6a 74 push $0x74 + jmp __alltraps + 102341: e9 cf fb ff ff jmp 101f15 <__alltraps> + +00102346 : +.globl vector117 +vector117: + pushl $0 + 102346: 6a 00 push $0x0 + pushl $117 + 102348: 6a 75 push $0x75 + jmp __alltraps + 10234a: e9 c6 fb ff ff jmp 101f15 <__alltraps> + +0010234f : +.globl vector118 +vector118: + pushl $0 + 10234f: 6a 00 push $0x0 + pushl $118 + 102351: 6a 76 push $0x76 + jmp __alltraps + 102353: e9 bd fb ff ff jmp 101f15 <__alltraps> + +00102358 : +.globl vector119 +vector119: + pushl $0 + 102358: 6a 00 push $0x0 + pushl $119 + 10235a: 6a 77 push $0x77 + jmp __alltraps + 10235c: e9 b4 fb ff ff jmp 101f15 <__alltraps> + +00102361 : +.globl vector120 +vector120: + pushl $0 + 102361: 6a 00 push $0x0 + pushl $120 + 102363: 6a 78 push $0x78 + jmp __alltraps + 102365: e9 ab fb ff ff jmp 101f15 <__alltraps> + +0010236a : +.globl vector121 +vector121: + pushl $0 + 10236a: 6a 00 push $0x0 + pushl $121 + 10236c: 6a 79 push $0x79 + jmp __alltraps + 10236e: e9 a2 fb ff ff jmp 101f15 <__alltraps> + +00102373 : +.globl vector122 +vector122: + pushl $0 + 102373: 6a 00 push $0x0 + pushl $122 + 102375: 6a 7a push $0x7a + jmp __alltraps + 102377: e9 99 fb ff ff jmp 101f15 <__alltraps> + +0010237c : +.globl vector123 +vector123: + pushl $0 + 10237c: 6a 00 push $0x0 + pushl $123 + 10237e: 6a 7b push $0x7b + jmp __alltraps + 102380: e9 90 fb ff ff jmp 101f15 <__alltraps> + +00102385 : +.globl vector124 +vector124: + pushl $0 + 102385: 6a 00 push $0x0 + pushl $124 + 102387: 6a 7c push $0x7c + jmp __alltraps + 102389: e9 87 fb ff ff jmp 101f15 <__alltraps> + +0010238e : +.globl vector125 +vector125: + pushl $0 + 10238e: 6a 00 push $0x0 + pushl $125 + 102390: 6a 7d push $0x7d + jmp __alltraps + 102392: e9 7e fb ff ff jmp 101f15 <__alltraps> + +00102397 : +.globl vector126 +vector126: + pushl $0 + 102397: 6a 00 push $0x0 + pushl $126 + 102399: 6a 7e push $0x7e + jmp __alltraps + 10239b: e9 75 fb ff ff jmp 101f15 <__alltraps> + +001023a0 : +.globl vector127 +vector127: + pushl $0 + 1023a0: 6a 00 push $0x0 + pushl $127 + 1023a2: 6a 7f push $0x7f + jmp __alltraps + 1023a4: e9 6c fb ff ff jmp 101f15 <__alltraps> + +001023a9 : +.globl vector128 +vector128: + pushl $0 + 1023a9: 6a 00 push $0x0 + pushl $128 + 1023ab: 68 80 00 00 00 push $0x80 + jmp __alltraps + 1023b0: e9 60 fb ff ff jmp 101f15 <__alltraps> + +001023b5 : +.globl vector129 +vector129: + pushl $0 + 1023b5: 6a 00 push $0x0 + pushl $129 + 1023b7: 68 81 00 00 00 push $0x81 + jmp __alltraps + 1023bc: e9 54 fb ff ff jmp 101f15 <__alltraps> + +001023c1 : +.globl vector130 +vector130: + pushl $0 + 1023c1: 6a 00 push $0x0 + pushl $130 + 1023c3: 68 82 00 00 00 push $0x82 + jmp __alltraps + 1023c8: e9 48 fb ff ff jmp 101f15 <__alltraps> + +001023cd : +.globl vector131 +vector131: + pushl $0 + 1023cd: 6a 00 push $0x0 + pushl $131 + 1023cf: 68 83 00 00 00 push $0x83 + jmp __alltraps + 1023d4: e9 3c fb ff ff jmp 101f15 <__alltraps> + +001023d9 : +.globl vector132 +vector132: + pushl $0 + 1023d9: 6a 00 push $0x0 + pushl $132 + 1023db: 68 84 00 00 00 push $0x84 + jmp __alltraps + 1023e0: e9 30 fb ff ff jmp 101f15 <__alltraps> + +001023e5 : +.globl vector133 +vector133: + pushl $0 + 1023e5: 6a 00 push $0x0 + pushl $133 + 1023e7: 68 85 00 00 00 push $0x85 + jmp __alltraps + 1023ec: e9 24 fb ff ff jmp 101f15 <__alltraps> + +001023f1 : +.globl vector134 +vector134: + pushl $0 + 1023f1: 6a 00 push $0x0 + pushl $134 + 1023f3: 68 86 00 00 00 push $0x86 + jmp __alltraps + 1023f8: e9 18 fb ff ff jmp 101f15 <__alltraps> + +001023fd : +.globl vector135 +vector135: + pushl $0 + 1023fd: 6a 00 push $0x0 + pushl $135 + 1023ff: 68 87 00 00 00 push $0x87 + jmp __alltraps + 102404: e9 0c fb ff ff jmp 101f15 <__alltraps> + +00102409 : +.globl vector136 +vector136: + pushl $0 + 102409: 6a 00 push $0x0 + pushl $136 + 10240b: 68 88 00 00 00 push $0x88 + jmp __alltraps + 102410: e9 00 fb ff ff jmp 101f15 <__alltraps> + +00102415 : +.globl vector137 +vector137: + pushl $0 + 102415: 6a 00 push $0x0 + pushl $137 + 102417: 68 89 00 00 00 push $0x89 + jmp __alltraps + 10241c: e9 f4 fa ff ff jmp 101f15 <__alltraps> + +00102421 : +.globl vector138 +vector138: + pushl $0 + 102421: 6a 00 push $0x0 + pushl $138 + 102423: 68 8a 00 00 00 push $0x8a + jmp __alltraps + 102428: e9 e8 fa ff ff jmp 101f15 <__alltraps> + +0010242d : +.globl vector139 +vector139: + pushl $0 + 10242d: 6a 00 push $0x0 + pushl $139 + 10242f: 68 8b 00 00 00 push $0x8b + jmp __alltraps + 102434: e9 dc fa ff ff jmp 101f15 <__alltraps> + +00102439 : +.globl vector140 +vector140: + pushl $0 + 102439: 6a 00 push $0x0 + pushl $140 + 10243b: 68 8c 00 00 00 push $0x8c + jmp __alltraps + 102440: e9 d0 fa ff ff jmp 101f15 <__alltraps> + +00102445 : +.globl vector141 +vector141: + pushl $0 + 102445: 6a 00 push $0x0 + pushl $141 + 102447: 68 8d 00 00 00 push $0x8d + jmp __alltraps + 10244c: e9 c4 fa ff ff jmp 101f15 <__alltraps> + +00102451 : +.globl vector142 +vector142: + pushl $0 + 102451: 6a 00 push $0x0 + pushl $142 + 102453: 68 8e 00 00 00 push $0x8e + jmp __alltraps + 102458: e9 b8 fa ff ff jmp 101f15 <__alltraps> + +0010245d : +.globl vector143 +vector143: + pushl $0 + 10245d: 6a 00 push $0x0 + pushl $143 + 10245f: 68 8f 00 00 00 push $0x8f + jmp __alltraps + 102464: e9 ac fa ff ff jmp 101f15 <__alltraps> + +00102469 : +.globl vector144 +vector144: + pushl $0 + 102469: 6a 00 push $0x0 + pushl $144 + 10246b: 68 90 00 00 00 push $0x90 + jmp __alltraps + 102470: e9 a0 fa ff ff jmp 101f15 <__alltraps> + +00102475 : +.globl vector145 +vector145: + pushl $0 + 102475: 6a 00 push $0x0 + pushl $145 + 102477: 68 91 00 00 00 push $0x91 + jmp __alltraps + 10247c: e9 94 fa ff ff jmp 101f15 <__alltraps> + +00102481 : +.globl vector146 +vector146: + pushl $0 + 102481: 6a 00 push $0x0 + pushl $146 + 102483: 68 92 00 00 00 push $0x92 + jmp __alltraps + 102488: e9 88 fa ff ff jmp 101f15 <__alltraps> + +0010248d : +.globl vector147 +vector147: + pushl $0 + 10248d: 6a 00 push $0x0 + pushl $147 + 10248f: 68 93 00 00 00 push $0x93 + jmp __alltraps + 102494: e9 7c fa ff ff jmp 101f15 <__alltraps> + +00102499 : +.globl vector148 +vector148: + pushl $0 + 102499: 6a 00 push $0x0 + pushl $148 + 10249b: 68 94 00 00 00 push $0x94 + jmp __alltraps + 1024a0: e9 70 fa ff ff jmp 101f15 <__alltraps> + +001024a5 : +.globl vector149 +vector149: + pushl $0 + 1024a5: 6a 00 push $0x0 + pushl $149 + 1024a7: 68 95 00 00 00 push $0x95 + jmp __alltraps + 1024ac: e9 64 fa ff ff jmp 101f15 <__alltraps> + +001024b1 : +.globl vector150 +vector150: + pushl $0 + 1024b1: 6a 00 push $0x0 + pushl $150 + 1024b3: 68 96 00 00 00 push $0x96 + jmp __alltraps + 1024b8: e9 58 fa ff ff jmp 101f15 <__alltraps> + +001024bd : +.globl vector151 +vector151: + pushl $0 + 1024bd: 6a 00 push $0x0 + pushl $151 + 1024bf: 68 97 00 00 00 push $0x97 + jmp __alltraps + 1024c4: e9 4c fa ff ff jmp 101f15 <__alltraps> + +001024c9 : +.globl vector152 +vector152: + pushl $0 + 1024c9: 6a 00 push $0x0 + pushl $152 + 1024cb: 68 98 00 00 00 push $0x98 + jmp __alltraps + 1024d0: e9 40 fa ff ff jmp 101f15 <__alltraps> + +001024d5 : +.globl vector153 +vector153: + pushl $0 + 1024d5: 6a 00 push $0x0 + pushl $153 + 1024d7: 68 99 00 00 00 push $0x99 + jmp __alltraps + 1024dc: e9 34 fa ff ff jmp 101f15 <__alltraps> + +001024e1 : +.globl vector154 +vector154: + pushl $0 + 1024e1: 6a 00 push $0x0 + pushl $154 + 1024e3: 68 9a 00 00 00 push $0x9a + jmp __alltraps + 1024e8: e9 28 fa ff ff jmp 101f15 <__alltraps> + +001024ed : +.globl vector155 +vector155: + pushl $0 + 1024ed: 6a 00 push $0x0 + pushl $155 + 1024ef: 68 9b 00 00 00 push $0x9b + jmp __alltraps + 1024f4: e9 1c fa ff ff jmp 101f15 <__alltraps> + +001024f9 : +.globl vector156 +vector156: + pushl $0 + 1024f9: 6a 00 push $0x0 + pushl $156 + 1024fb: 68 9c 00 00 00 push $0x9c + jmp __alltraps + 102500: e9 10 fa ff ff jmp 101f15 <__alltraps> + +00102505 : +.globl vector157 +vector157: + pushl $0 + 102505: 6a 00 push $0x0 + pushl $157 + 102507: 68 9d 00 00 00 push $0x9d + jmp __alltraps + 10250c: e9 04 fa ff ff jmp 101f15 <__alltraps> + +00102511 : +.globl vector158 +vector158: + pushl $0 + 102511: 6a 00 push $0x0 + pushl $158 + 102513: 68 9e 00 00 00 push $0x9e + jmp __alltraps + 102518: e9 f8 f9 ff ff jmp 101f15 <__alltraps> + +0010251d : +.globl vector159 +vector159: + pushl $0 + 10251d: 6a 00 push $0x0 + pushl $159 + 10251f: 68 9f 00 00 00 push $0x9f + jmp __alltraps + 102524: e9 ec f9 ff ff jmp 101f15 <__alltraps> + +00102529 : +.globl vector160 +vector160: + pushl $0 + 102529: 6a 00 push $0x0 + pushl $160 + 10252b: 68 a0 00 00 00 push $0xa0 + jmp __alltraps + 102530: e9 e0 f9 ff ff jmp 101f15 <__alltraps> + +00102535 : +.globl vector161 +vector161: + pushl $0 + 102535: 6a 00 push $0x0 + pushl $161 + 102537: 68 a1 00 00 00 push $0xa1 + jmp __alltraps + 10253c: e9 d4 f9 ff ff jmp 101f15 <__alltraps> + +00102541 : +.globl vector162 +vector162: + pushl $0 + 102541: 6a 00 push $0x0 + pushl $162 + 102543: 68 a2 00 00 00 push $0xa2 + jmp __alltraps + 102548: e9 c8 f9 ff ff jmp 101f15 <__alltraps> + +0010254d : +.globl vector163 +vector163: + pushl $0 + 10254d: 6a 00 push $0x0 + pushl $163 + 10254f: 68 a3 00 00 00 push $0xa3 + jmp __alltraps + 102554: e9 bc f9 ff ff jmp 101f15 <__alltraps> + +00102559 : +.globl vector164 +vector164: + pushl $0 + 102559: 6a 00 push $0x0 + pushl $164 + 10255b: 68 a4 00 00 00 push $0xa4 + jmp __alltraps + 102560: e9 b0 f9 ff ff jmp 101f15 <__alltraps> + +00102565 : +.globl vector165 +vector165: + pushl $0 + 102565: 6a 00 push $0x0 + pushl $165 + 102567: 68 a5 00 00 00 push $0xa5 + jmp __alltraps + 10256c: e9 a4 f9 ff ff jmp 101f15 <__alltraps> + +00102571 : +.globl vector166 +vector166: + pushl $0 + 102571: 6a 00 push $0x0 + pushl $166 + 102573: 68 a6 00 00 00 push $0xa6 + jmp __alltraps + 102578: e9 98 f9 ff ff jmp 101f15 <__alltraps> + +0010257d : +.globl vector167 +vector167: + pushl $0 + 10257d: 6a 00 push $0x0 + pushl $167 + 10257f: 68 a7 00 00 00 push $0xa7 + jmp __alltraps + 102584: e9 8c f9 ff ff jmp 101f15 <__alltraps> + +00102589 : +.globl vector168 +vector168: + pushl $0 + 102589: 6a 00 push $0x0 + pushl $168 + 10258b: 68 a8 00 00 00 push $0xa8 + jmp __alltraps + 102590: e9 80 f9 ff ff jmp 101f15 <__alltraps> + +00102595 : +.globl vector169 +vector169: + pushl $0 + 102595: 6a 00 push $0x0 + pushl $169 + 102597: 68 a9 00 00 00 push $0xa9 + jmp __alltraps + 10259c: e9 74 f9 ff ff jmp 101f15 <__alltraps> + +001025a1 : +.globl vector170 +vector170: + pushl $0 + 1025a1: 6a 00 push $0x0 + pushl $170 + 1025a3: 68 aa 00 00 00 push $0xaa + jmp __alltraps + 1025a8: e9 68 f9 ff ff jmp 101f15 <__alltraps> + +001025ad : +.globl vector171 +vector171: + pushl $0 + 1025ad: 6a 00 push $0x0 + pushl $171 + 1025af: 68 ab 00 00 00 push $0xab + jmp __alltraps + 1025b4: e9 5c f9 ff ff jmp 101f15 <__alltraps> + +001025b9 : +.globl vector172 +vector172: + pushl $0 + 1025b9: 6a 00 push $0x0 + pushl $172 + 1025bb: 68 ac 00 00 00 push $0xac + jmp __alltraps + 1025c0: e9 50 f9 ff ff jmp 101f15 <__alltraps> + +001025c5 : +.globl vector173 +vector173: + pushl $0 + 1025c5: 6a 00 push $0x0 + pushl $173 + 1025c7: 68 ad 00 00 00 push $0xad + jmp __alltraps + 1025cc: e9 44 f9 ff ff jmp 101f15 <__alltraps> + +001025d1 : +.globl vector174 +vector174: + pushl $0 + 1025d1: 6a 00 push $0x0 + pushl $174 + 1025d3: 68 ae 00 00 00 push $0xae + jmp __alltraps + 1025d8: e9 38 f9 ff ff jmp 101f15 <__alltraps> + +001025dd : +.globl vector175 +vector175: + pushl $0 + 1025dd: 6a 00 push $0x0 + pushl $175 + 1025df: 68 af 00 00 00 push $0xaf + jmp __alltraps + 1025e4: e9 2c f9 ff ff jmp 101f15 <__alltraps> + +001025e9 : +.globl vector176 +vector176: + pushl $0 + 1025e9: 6a 00 push $0x0 + pushl $176 + 1025eb: 68 b0 00 00 00 push $0xb0 + jmp __alltraps + 1025f0: e9 20 f9 ff ff jmp 101f15 <__alltraps> + +001025f5 : +.globl vector177 +vector177: + pushl $0 + 1025f5: 6a 00 push $0x0 + pushl $177 + 1025f7: 68 b1 00 00 00 push $0xb1 + jmp __alltraps + 1025fc: e9 14 f9 ff ff jmp 101f15 <__alltraps> + +00102601 : +.globl vector178 +vector178: + pushl $0 + 102601: 6a 00 push $0x0 + pushl $178 + 102603: 68 b2 00 00 00 push $0xb2 + jmp __alltraps + 102608: e9 08 f9 ff ff jmp 101f15 <__alltraps> + +0010260d : +.globl vector179 +vector179: + pushl $0 + 10260d: 6a 00 push $0x0 + pushl $179 + 10260f: 68 b3 00 00 00 push $0xb3 + jmp __alltraps + 102614: e9 fc f8 ff ff jmp 101f15 <__alltraps> + +00102619 : +.globl vector180 +vector180: + pushl $0 + 102619: 6a 00 push $0x0 + pushl $180 + 10261b: 68 b4 00 00 00 push $0xb4 + jmp __alltraps + 102620: e9 f0 f8 ff ff jmp 101f15 <__alltraps> + +00102625 : +.globl vector181 +vector181: + pushl $0 + 102625: 6a 00 push $0x0 + pushl $181 + 102627: 68 b5 00 00 00 push $0xb5 + jmp __alltraps + 10262c: e9 e4 f8 ff ff jmp 101f15 <__alltraps> + +00102631 : +.globl vector182 +vector182: + pushl $0 + 102631: 6a 00 push $0x0 + pushl $182 + 102633: 68 b6 00 00 00 push $0xb6 + jmp __alltraps + 102638: e9 d8 f8 ff ff jmp 101f15 <__alltraps> + +0010263d : +.globl vector183 +vector183: + pushl $0 + 10263d: 6a 00 push $0x0 + pushl $183 + 10263f: 68 b7 00 00 00 push $0xb7 + jmp __alltraps + 102644: e9 cc f8 ff ff jmp 101f15 <__alltraps> + +00102649 : +.globl vector184 +vector184: + pushl $0 + 102649: 6a 00 push $0x0 + pushl $184 + 10264b: 68 b8 00 00 00 push $0xb8 + jmp __alltraps + 102650: e9 c0 f8 ff ff jmp 101f15 <__alltraps> + +00102655 : +.globl vector185 +vector185: + pushl $0 + 102655: 6a 00 push $0x0 + pushl $185 + 102657: 68 b9 00 00 00 push $0xb9 + jmp __alltraps + 10265c: e9 b4 f8 ff ff jmp 101f15 <__alltraps> + +00102661 : +.globl vector186 +vector186: + pushl $0 + 102661: 6a 00 push $0x0 + pushl $186 + 102663: 68 ba 00 00 00 push $0xba + jmp __alltraps + 102668: e9 a8 f8 ff ff jmp 101f15 <__alltraps> + +0010266d : +.globl vector187 +vector187: + pushl $0 + 10266d: 6a 00 push $0x0 + pushl $187 + 10266f: 68 bb 00 00 00 push $0xbb + jmp __alltraps + 102674: e9 9c f8 ff ff jmp 101f15 <__alltraps> + +00102679 : +.globl vector188 +vector188: + pushl $0 + 102679: 6a 00 push $0x0 + pushl $188 + 10267b: 68 bc 00 00 00 push $0xbc + jmp __alltraps + 102680: e9 90 f8 ff ff jmp 101f15 <__alltraps> + +00102685 : +.globl vector189 +vector189: + pushl $0 + 102685: 6a 00 push $0x0 + pushl $189 + 102687: 68 bd 00 00 00 push $0xbd + jmp __alltraps + 10268c: e9 84 f8 ff ff jmp 101f15 <__alltraps> + +00102691 : +.globl vector190 +vector190: + pushl $0 + 102691: 6a 00 push $0x0 + pushl $190 + 102693: 68 be 00 00 00 push $0xbe + jmp __alltraps + 102698: e9 78 f8 ff ff jmp 101f15 <__alltraps> + +0010269d : +.globl vector191 +vector191: + pushl $0 + 10269d: 6a 00 push $0x0 + pushl $191 + 10269f: 68 bf 00 00 00 push $0xbf + jmp __alltraps + 1026a4: e9 6c f8 ff ff jmp 101f15 <__alltraps> + +001026a9 : +.globl vector192 +vector192: + pushl $0 + 1026a9: 6a 00 push $0x0 + pushl $192 + 1026ab: 68 c0 00 00 00 push $0xc0 + jmp __alltraps + 1026b0: e9 60 f8 ff ff jmp 101f15 <__alltraps> + +001026b5 : +.globl vector193 +vector193: + pushl $0 + 1026b5: 6a 00 push $0x0 + pushl $193 + 1026b7: 68 c1 00 00 00 push $0xc1 + jmp __alltraps + 1026bc: e9 54 f8 ff ff jmp 101f15 <__alltraps> + +001026c1 : +.globl vector194 +vector194: + pushl $0 + 1026c1: 6a 00 push $0x0 + pushl $194 + 1026c3: 68 c2 00 00 00 push $0xc2 + jmp __alltraps + 1026c8: e9 48 f8 ff ff jmp 101f15 <__alltraps> + +001026cd : +.globl vector195 +vector195: + pushl $0 + 1026cd: 6a 00 push $0x0 + pushl $195 + 1026cf: 68 c3 00 00 00 push $0xc3 + jmp __alltraps + 1026d4: e9 3c f8 ff ff jmp 101f15 <__alltraps> + +001026d9 : +.globl vector196 +vector196: + pushl $0 + 1026d9: 6a 00 push $0x0 + pushl $196 + 1026db: 68 c4 00 00 00 push $0xc4 + jmp __alltraps + 1026e0: e9 30 f8 ff ff jmp 101f15 <__alltraps> + +001026e5 : +.globl vector197 +vector197: + pushl $0 + 1026e5: 6a 00 push $0x0 + pushl $197 + 1026e7: 68 c5 00 00 00 push $0xc5 + jmp __alltraps + 1026ec: e9 24 f8 ff ff jmp 101f15 <__alltraps> + +001026f1 : +.globl vector198 +vector198: + pushl $0 + 1026f1: 6a 00 push $0x0 + pushl $198 + 1026f3: 68 c6 00 00 00 push $0xc6 + jmp __alltraps + 1026f8: e9 18 f8 ff ff jmp 101f15 <__alltraps> + +001026fd : +.globl vector199 +vector199: + pushl $0 + 1026fd: 6a 00 push $0x0 + pushl $199 + 1026ff: 68 c7 00 00 00 push $0xc7 + jmp __alltraps + 102704: e9 0c f8 ff ff jmp 101f15 <__alltraps> + +00102709 : +.globl vector200 +vector200: + pushl $0 + 102709: 6a 00 push $0x0 + pushl $200 + 10270b: 68 c8 00 00 00 push $0xc8 + jmp __alltraps + 102710: e9 00 f8 ff ff jmp 101f15 <__alltraps> + +00102715 : +.globl vector201 +vector201: + pushl $0 + 102715: 6a 00 push $0x0 + pushl $201 + 102717: 68 c9 00 00 00 push $0xc9 + jmp __alltraps + 10271c: e9 f4 f7 ff ff jmp 101f15 <__alltraps> + +00102721 : +.globl vector202 +vector202: + pushl $0 + 102721: 6a 00 push $0x0 + pushl $202 + 102723: 68 ca 00 00 00 push $0xca + jmp __alltraps + 102728: e9 e8 f7 ff ff jmp 101f15 <__alltraps> + +0010272d : +.globl vector203 +vector203: + pushl $0 + 10272d: 6a 00 push $0x0 + pushl $203 + 10272f: 68 cb 00 00 00 push $0xcb + jmp __alltraps + 102734: e9 dc f7 ff ff jmp 101f15 <__alltraps> + +00102739 : +.globl vector204 +vector204: + pushl $0 + 102739: 6a 00 push $0x0 + pushl $204 + 10273b: 68 cc 00 00 00 push $0xcc + jmp __alltraps + 102740: e9 d0 f7 ff ff jmp 101f15 <__alltraps> + +00102745 : +.globl vector205 +vector205: + pushl $0 + 102745: 6a 00 push $0x0 + pushl $205 + 102747: 68 cd 00 00 00 push $0xcd + jmp __alltraps + 10274c: e9 c4 f7 ff ff jmp 101f15 <__alltraps> + +00102751 : +.globl vector206 +vector206: + pushl $0 + 102751: 6a 00 push $0x0 + pushl $206 + 102753: 68 ce 00 00 00 push $0xce + jmp __alltraps + 102758: e9 b8 f7 ff ff jmp 101f15 <__alltraps> + +0010275d : +.globl vector207 +vector207: + pushl $0 + 10275d: 6a 00 push $0x0 + pushl $207 + 10275f: 68 cf 00 00 00 push $0xcf + jmp __alltraps + 102764: e9 ac f7 ff ff jmp 101f15 <__alltraps> + +00102769 : +.globl vector208 +vector208: + pushl $0 + 102769: 6a 00 push $0x0 + pushl $208 + 10276b: 68 d0 00 00 00 push $0xd0 + jmp __alltraps + 102770: e9 a0 f7 ff ff jmp 101f15 <__alltraps> + +00102775 : +.globl vector209 +vector209: + pushl $0 + 102775: 6a 00 push $0x0 + pushl $209 + 102777: 68 d1 00 00 00 push $0xd1 + jmp __alltraps + 10277c: e9 94 f7 ff ff jmp 101f15 <__alltraps> + +00102781 : +.globl vector210 +vector210: + pushl $0 + 102781: 6a 00 push $0x0 + pushl $210 + 102783: 68 d2 00 00 00 push $0xd2 + jmp __alltraps + 102788: e9 88 f7 ff ff jmp 101f15 <__alltraps> + +0010278d : +.globl vector211 +vector211: + pushl $0 + 10278d: 6a 00 push $0x0 + pushl $211 + 10278f: 68 d3 00 00 00 push $0xd3 + jmp __alltraps + 102794: e9 7c f7 ff ff jmp 101f15 <__alltraps> + +00102799 : +.globl vector212 +vector212: + pushl $0 + 102799: 6a 00 push $0x0 + pushl $212 + 10279b: 68 d4 00 00 00 push $0xd4 + jmp __alltraps + 1027a0: e9 70 f7 ff ff jmp 101f15 <__alltraps> + +001027a5 : +.globl vector213 +vector213: + pushl $0 + 1027a5: 6a 00 push $0x0 + pushl $213 + 1027a7: 68 d5 00 00 00 push $0xd5 + jmp __alltraps + 1027ac: e9 64 f7 ff ff jmp 101f15 <__alltraps> + +001027b1 : +.globl vector214 +vector214: + pushl $0 + 1027b1: 6a 00 push $0x0 + pushl $214 + 1027b3: 68 d6 00 00 00 push $0xd6 + jmp __alltraps + 1027b8: e9 58 f7 ff ff jmp 101f15 <__alltraps> + +001027bd : +.globl vector215 +vector215: + pushl $0 + 1027bd: 6a 00 push $0x0 + pushl $215 + 1027bf: 68 d7 00 00 00 push $0xd7 + jmp __alltraps + 1027c4: e9 4c f7 ff ff jmp 101f15 <__alltraps> + +001027c9 : +.globl vector216 +vector216: + pushl $0 + 1027c9: 6a 00 push $0x0 + pushl $216 + 1027cb: 68 d8 00 00 00 push $0xd8 + jmp __alltraps + 1027d0: e9 40 f7 ff ff jmp 101f15 <__alltraps> + +001027d5 : +.globl vector217 +vector217: + pushl $0 + 1027d5: 6a 00 push $0x0 + pushl $217 + 1027d7: 68 d9 00 00 00 push $0xd9 + jmp __alltraps + 1027dc: e9 34 f7 ff ff jmp 101f15 <__alltraps> + +001027e1 : +.globl vector218 +vector218: + pushl $0 + 1027e1: 6a 00 push $0x0 + pushl $218 + 1027e3: 68 da 00 00 00 push $0xda + jmp __alltraps + 1027e8: e9 28 f7 ff ff jmp 101f15 <__alltraps> + +001027ed : +.globl vector219 +vector219: + pushl $0 + 1027ed: 6a 00 push $0x0 + pushl $219 + 1027ef: 68 db 00 00 00 push $0xdb + jmp __alltraps + 1027f4: e9 1c f7 ff ff jmp 101f15 <__alltraps> + +001027f9 : +.globl vector220 +vector220: + pushl $0 + 1027f9: 6a 00 push $0x0 + pushl $220 + 1027fb: 68 dc 00 00 00 push $0xdc + jmp __alltraps + 102800: e9 10 f7 ff ff jmp 101f15 <__alltraps> + +00102805 : +.globl vector221 +vector221: + pushl $0 + 102805: 6a 00 push $0x0 + pushl $221 + 102807: 68 dd 00 00 00 push $0xdd + jmp __alltraps + 10280c: e9 04 f7 ff ff jmp 101f15 <__alltraps> + +00102811 : +.globl vector222 +vector222: + pushl $0 + 102811: 6a 00 push $0x0 + pushl $222 + 102813: 68 de 00 00 00 push $0xde + jmp __alltraps + 102818: e9 f8 f6 ff ff jmp 101f15 <__alltraps> + +0010281d : +.globl vector223 +vector223: + pushl $0 + 10281d: 6a 00 push $0x0 + pushl $223 + 10281f: 68 df 00 00 00 push $0xdf + jmp __alltraps + 102824: e9 ec f6 ff ff jmp 101f15 <__alltraps> + +00102829 : +.globl vector224 +vector224: + pushl $0 + 102829: 6a 00 push $0x0 + pushl $224 + 10282b: 68 e0 00 00 00 push $0xe0 + jmp __alltraps + 102830: e9 e0 f6 ff ff jmp 101f15 <__alltraps> + +00102835 : +.globl vector225 +vector225: + pushl $0 + 102835: 6a 00 push $0x0 + pushl $225 + 102837: 68 e1 00 00 00 push $0xe1 + jmp __alltraps + 10283c: e9 d4 f6 ff ff jmp 101f15 <__alltraps> + +00102841 : +.globl vector226 +vector226: + pushl $0 + 102841: 6a 00 push $0x0 + pushl $226 + 102843: 68 e2 00 00 00 push $0xe2 + jmp __alltraps + 102848: e9 c8 f6 ff ff jmp 101f15 <__alltraps> + +0010284d : +.globl vector227 +vector227: + pushl $0 + 10284d: 6a 00 push $0x0 + pushl $227 + 10284f: 68 e3 00 00 00 push $0xe3 + jmp __alltraps + 102854: e9 bc f6 ff ff jmp 101f15 <__alltraps> + +00102859 : +.globl vector228 +vector228: + pushl $0 + 102859: 6a 00 push $0x0 + pushl $228 + 10285b: 68 e4 00 00 00 push $0xe4 + jmp __alltraps + 102860: e9 b0 f6 ff ff jmp 101f15 <__alltraps> + +00102865 : +.globl vector229 +vector229: + pushl $0 + 102865: 6a 00 push $0x0 + pushl $229 + 102867: 68 e5 00 00 00 push $0xe5 + jmp __alltraps + 10286c: e9 a4 f6 ff ff jmp 101f15 <__alltraps> + +00102871 : +.globl vector230 +vector230: + pushl $0 + 102871: 6a 00 push $0x0 + pushl $230 + 102873: 68 e6 00 00 00 push $0xe6 + jmp __alltraps + 102878: e9 98 f6 ff ff jmp 101f15 <__alltraps> + +0010287d : +.globl vector231 +vector231: + pushl $0 + 10287d: 6a 00 push $0x0 + pushl $231 + 10287f: 68 e7 00 00 00 push $0xe7 + jmp __alltraps + 102884: e9 8c f6 ff ff jmp 101f15 <__alltraps> + +00102889 : +.globl vector232 +vector232: + pushl $0 + 102889: 6a 00 push $0x0 + pushl $232 + 10288b: 68 e8 00 00 00 push $0xe8 + jmp __alltraps + 102890: e9 80 f6 ff ff jmp 101f15 <__alltraps> + +00102895 : +.globl vector233 +vector233: + pushl $0 + 102895: 6a 00 push $0x0 + pushl $233 + 102897: 68 e9 00 00 00 push $0xe9 + jmp __alltraps + 10289c: e9 74 f6 ff ff jmp 101f15 <__alltraps> + +001028a1 : +.globl vector234 +vector234: + pushl $0 + 1028a1: 6a 00 push $0x0 + pushl $234 + 1028a3: 68 ea 00 00 00 push $0xea + jmp __alltraps + 1028a8: e9 68 f6 ff ff jmp 101f15 <__alltraps> + +001028ad : +.globl vector235 +vector235: + pushl $0 + 1028ad: 6a 00 push $0x0 + pushl $235 + 1028af: 68 eb 00 00 00 push $0xeb + jmp __alltraps + 1028b4: e9 5c f6 ff ff jmp 101f15 <__alltraps> + +001028b9 : +.globl vector236 +vector236: + pushl $0 + 1028b9: 6a 00 push $0x0 + pushl $236 + 1028bb: 68 ec 00 00 00 push $0xec + jmp __alltraps + 1028c0: e9 50 f6 ff ff jmp 101f15 <__alltraps> + +001028c5 : +.globl vector237 +vector237: + pushl $0 + 1028c5: 6a 00 push $0x0 + pushl $237 + 1028c7: 68 ed 00 00 00 push $0xed + jmp __alltraps + 1028cc: e9 44 f6 ff ff jmp 101f15 <__alltraps> + +001028d1 : +.globl vector238 +vector238: + pushl $0 + 1028d1: 6a 00 push $0x0 + pushl $238 + 1028d3: 68 ee 00 00 00 push $0xee + jmp __alltraps + 1028d8: e9 38 f6 ff ff jmp 101f15 <__alltraps> + +001028dd : +.globl vector239 +vector239: + pushl $0 + 1028dd: 6a 00 push $0x0 + pushl $239 + 1028df: 68 ef 00 00 00 push $0xef + jmp __alltraps + 1028e4: e9 2c f6 ff ff jmp 101f15 <__alltraps> + +001028e9 : +.globl vector240 +vector240: + pushl $0 + 1028e9: 6a 00 push $0x0 + pushl $240 + 1028eb: 68 f0 00 00 00 push $0xf0 + jmp __alltraps + 1028f0: e9 20 f6 ff ff jmp 101f15 <__alltraps> + +001028f5 : +.globl vector241 +vector241: + pushl $0 + 1028f5: 6a 00 push $0x0 + pushl $241 + 1028f7: 68 f1 00 00 00 push $0xf1 + jmp __alltraps + 1028fc: e9 14 f6 ff ff jmp 101f15 <__alltraps> + +00102901 : +.globl vector242 +vector242: + pushl $0 + 102901: 6a 00 push $0x0 + pushl $242 + 102903: 68 f2 00 00 00 push $0xf2 + jmp __alltraps + 102908: e9 08 f6 ff ff jmp 101f15 <__alltraps> + +0010290d : +.globl vector243 +vector243: + pushl $0 + 10290d: 6a 00 push $0x0 + pushl $243 + 10290f: 68 f3 00 00 00 push $0xf3 + jmp __alltraps + 102914: e9 fc f5 ff ff jmp 101f15 <__alltraps> + +00102919 : +.globl vector244 +vector244: + pushl $0 + 102919: 6a 00 push $0x0 + pushl $244 + 10291b: 68 f4 00 00 00 push $0xf4 + jmp __alltraps + 102920: e9 f0 f5 ff ff jmp 101f15 <__alltraps> + +00102925 : +.globl vector245 +vector245: + pushl $0 + 102925: 6a 00 push $0x0 + pushl $245 + 102927: 68 f5 00 00 00 push $0xf5 + jmp __alltraps + 10292c: e9 e4 f5 ff ff jmp 101f15 <__alltraps> + +00102931 : +.globl vector246 +vector246: + pushl $0 + 102931: 6a 00 push $0x0 + pushl $246 + 102933: 68 f6 00 00 00 push $0xf6 + jmp __alltraps + 102938: e9 d8 f5 ff ff jmp 101f15 <__alltraps> + +0010293d : +.globl vector247 +vector247: + pushl $0 + 10293d: 6a 00 push $0x0 + pushl $247 + 10293f: 68 f7 00 00 00 push $0xf7 + jmp __alltraps + 102944: e9 cc f5 ff ff jmp 101f15 <__alltraps> + +00102949 : +.globl vector248 +vector248: + pushl $0 + 102949: 6a 00 push $0x0 + pushl $248 + 10294b: 68 f8 00 00 00 push $0xf8 + jmp __alltraps + 102950: e9 c0 f5 ff ff jmp 101f15 <__alltraps> + +00102955 : +.globl vector249 +vector249: + pushl $0 + 102955: 6a 00 push $0x0 + pushl $249 + 102957: 68 f9 00 00 00 push $0xf9 + jmp __alltraps + 10295c: e9 b4 f5 ff ff jmp 101f15 <__alltraps> + +00102961 : +.globl vector250 +vector250: + pushl $0 + 102961: 6a 00 push $0x0 + pushl $250 + 102963: 68 fa 00 00 00 push $0xfa + jmp __alltraps + 102968: e9 a8 f5 ff ff jmp 101f15 <__alltraps> + +0010296d : +.globl vector251 +vector251: + pushl $0 + 10296d: 6a 00 push $0x0 + pushl $251 + 10296f: 68 fb 00 00 00 push $0xfb + jmp __alltraps + 102974: e9 9c f5 ff ff jmp 101f15 <__alltraps> + +00102979 : +.globl vector252 +vector252: + pushl $0 + 102979: 6a 00 push $0x0 + pushl $252 + 10297b: 68 fc 00 00 00 push $0xfc + jmp __alltraps + 102980: e9 90 f5 ff ff jmp 101f15 <__alltraps> + +00102985 : +.globl vector253 +vector253: + pushl $0 + 102985: 6a 00 push $0x0 + pushl $253 + 102987: 68 fd 00 00 00 push $0xfd + jmp __alltraps + 10298c: e9 84 f5 ff ff jmp 101f15 <__alltraps> + +00102991 : +.globl vector254 +vector254: + pushl $0 + 102991: 6a 00 push $0x0 + pushl $254 + 102993: 68 fe 00 00 00 push $0xfe + jmp __alltraps + 102998: e9 78 f5 ff ff jmp 101f15 <__alltraps> + +0010299d : +.globl vector255 +vector255: + pushl $0 + 10299d: 6a 00 push $0x0 + pushl $255 + 10299f: 68 ff 00 00 00 push $0xff + jmp __alltraps + 1029a4: e9 6c f5 ff ff jmp 101f15 <__alltraps> + +001029a9 : + +extern struct Page *pages; +extern size_t npage; + +static inline ppn_t +page2ppn(struct Page *page) { + 1029a9: 55 push %ebp + 1029aa: 89 e5 mov %esp,%ebp + return page - pages; + 1029ac: 8b 15 00 cf 11 00 mov 0x11cf00,%edx + 1029b2: 8b 45 08 mov 0x8(%ebp),%eax + 1029b5: 29 d0 sub %edx,%eax + 1029b7: c1 f8 02 sar $0x2,%eax + 1029ba: 69 c0 cd cc cc cc imul $0xcccccccd,%eax,%eax +} + 1029c0: 5d pop %ebp + 1029c1: c3 ret + +001029c2 : + +static inline uintptr_t +page2pa(struct Page *page) { + 1029c2: 55 push %ebp + 1029c3: 89 e5 mov %esp,%ebp + 1029c5: 83 ec 04 sub $0x4,%esp + return page2ppn(page) << PGSHIFT; + 1029c8: 8b 45 08 mov 0x8(%ebp),%eax + 1029cb: 89 04 24 mov %eax,(%esp) + 1029ce: e8 d6 ff ff ff call 1029a9 + 1029d3: c1 e0 0c shl $0xc,%eax +} + 1029d6: 89 ec mov %ebp,%esp + 1029d8: 5d pop %ebp + 1029d9: c3 ret + +001029da : +pde2page(pde_t pde) { + return pa2page(PDE_ADDR(pde)); +} + +static inline int +page_ref(struct Page *page) { + 1029da: 55 push %ebp + 1029db: 89 e5 mov %esp,%ebp + return page->ref; + 1029dd: 8b 45 08 mov 0x8(%ebp),%eax + 1029e0: 8b 00 mov (%eax),%eax +} + 1029e2: 5d pop %ebp + 1029e3: c3 ret + +001029e4 : + +static inline void +set_page_ref(struct Page *page, int val) { + 1029e4: 55 push %ebp + 1029e5: 89 e5 mov %esp,%ebp + page->ref = val; + 1029e7: 8b 45 08 mov 0x8(%ebp),%eax + 1029ea: 8b 55 0c mov 0xc(%ebp),%edx + 1029ed: 89 10 mov %edx,(%eax) +} + 1029ef: 90 nop + 1029f0: 5d pop %ebp + 1029f1: c3 ret + +001029f2 : +#define nr_free (free_area.nr_free) + +//free_list` 用于记录空闲内存块,nr_free` 是空闲内存块的总数。 +//用default_init函数来初始化 `free_list`,并将 `nr_free` 设置为 0。 +static void +default_init(void) { + 1029f2: 55 push %ebp + 1029f3: 89 e5 mov %esp,%ebp + 1029f5: 83 ec 10 sub $0x10,%esp + 1029f8: c7 45 fc e0 ce 11 00 movl $0x11cee0,-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; + 1029ff: 8b 45 fc mov -0x4(%ebp),%eax + 102a02: 8b 55 fc mov -0x4(%ebp),%edx + 102a05: 89 50 04 mov %edx,0x4(%eax) + 102a08: 8b 45 fc mov -0x4(%ebp),%eax + 102a0b: 8b 50 04 mov 0x4(%eax),%edx + 102a0e: 8b 45 fc mov -0x4(%ebp),%eax + 102a11: 89 10 mov %edx,(%eax) +} + 102a13: 90 nop + list_init(&free_list); + nr_free = 0; + 102a14: c7 05 e8 ce 11 00 00 movl $0x0,0x11cee8 + 102a1b: 00 00 00 +} + 102a1e: 90 nop + 102a1f: 89 ec mov %ebp,%esp + 102a21: 5d pop %ebp + 102a22: c3 ret + +00102a23 : + +//用于初始化一段连续的物理页,并将它们加入到空闲内存管理系统中. +//struct Page *base:指向要初始化的页块的起始地址。size_t n:要初始化的页的数量。 +static void +default_init_memmap(struct Page *base, size_t n) { + 102a23: 55 push %ebp + 102a24: 89 e5 mov %esp,%ebp + 102a26: 83 ec 58 sub $0x58,%esp + assert(n > 0);//// 确保请求的页数大于零 + 102a29: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) + 102a2d: 75 24 jne 102a53 + 102a2f: c7 44 24 0c 90 67 10 movl $0x106790,0xc(%esp) + 102a36: 00 + 102a37: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 102a3e: 00 + 102a3f: c7 44 24 04 94 00 00 movl $0x94,0x4(%esp) + 102a46: 00 + 102a47: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 102a4e: e8 e0 e1 ff ff call 100c33 <__panic> + struct Page *p = base;// 指向当前初始化的页 + 102a53: 8b 45 08 mov 0x8(%ebp),%eax + 102a56: 89 45 f4 mov %eax,-0xc(%ebp) + //// 遍历每一页,设置其状态 + for (; p != base + n; p ++) { + 102a59: eb 7d jmp 102ad8 + assert(PageReserved(p));//检查每个页是否被标记为“保留”。若没有被保留,函数将抛出错误。 + 102a5b: 8b 45 f4 mov -0xc(%ebp),%eax + 102a5e: 83 c0 04 add $0x4,%eax + 102a61: c7 45 f0 00 00 00 00 movl $0x0,-0x10(%ebp) + 102a68: 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)); + 102a6b: 8b 45 ec mov -0x14(%ebp),%eax + 102a6e: 8b 55 f0 mov -0x10(%ebp),%edx + 102a71: 0f a3 10 bt %edx,(%eax) + 102a74: 19 c0 sbb %eax,%eax + 102a76: 89 45 e8 mov %eax,-0x18(%ebp) + return oldbit != 0; + 102a79: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 102a7d: 0f 95 c0 setne %al + 102a80: 0f b6 c0 movzbl %al,%eax + 102a83: 85 c0 test %eax,%eax + 102a85: 75 24 jne 102aab + 102a87: c7 44 24 0c c1 67 10 movl $0x1067c1,0xc(%esp) + 102a8e: 00 + 102a8f: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 102a96: 00 + 102a97: c7 44 24 04 98 00 00 movl $0x98,0x4(%esp) + 102a9e: 00 + 102a9f: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 102aa6: e8 88 e1 ff ff call 100c33 <__panic> + p->flags = p->property = 0;//将页的 flags 和 property 字段设置为 0,表示该页未分配、未使用。 + 102aab: 8b 45 f4 mov -0xc(%ebp),%eax + 102aae: c7 40 08 00 00 00 00 movl $0x0,0x8(%eax) + 102ab5: 8b 45 f4 mov -0xc(%ebp),%eax + 102ab8: 8b 50 08 mov 0x8(%eax),%edx + 102abb: 8b 45 f4 mov -0xc(%ebp),%eax + 102abe: 89 50 04 mov %edx,0x4(%eax) + set_page_ref(p, 0);//将页的引用计数设置为 0,表明没有任何引用指向此页。 + 102ac1: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) + 102ac8: 00 + 102ac9: 8b 45 f4 mov -0xc(%ebp),%eax + 102acc: 89 04 24 mov %eax,(%esp) + 102acf: e8 10 ff ff ff call 1029e4 + for (; p != base + n; p ++) { + 102ad4: 83 45 f4 14 addl $0x14,-0xc(%ebp) + 102ad8: 8b 55 0c mov 0xc(%ebp),%edx + 102adb: 89 d0 mov %edx,%eax + 102add: c1 e0 02 shl $0x2,%eax + 102ae0: 01 d0 add %edx,%eax + 102ae2: c1 e0 02 shl $0x2,%eax + 102ae5: 89 c2 mov %eax,%edx + 102ae7: 8b 45 08 mov 0x8(%ebp),%eax + 102aea: 01 d0 add %edx,%eax + 102aec: 39 45 f4 cmp %eax,-0xc(%ebp) + 102aef: 0f 85 66 ff ff ff jne 102a5b + } + // 设置第一个页的 property 为块的总数 + base->property = n; + 102af5: 8b 45 08 mov 0x8(%ebp),%eax + 102af8: 8b 55 0c mov 0xc(%ebp),%edx + 102afb: 89 50 08 mov %edx,0x8(%eax) + SetPageProperty(base);// 设置当前页的有效标志 + 102afe: 8b 45 08 mov 0x8(%ebp),%eax + 102b01: 83 c0 04 add $0x4,%eax + 102b04: c7 45 c8 01 00 00 00 movl $0x1,-0x38(%ebp) + 102b0b: 89 45 c4 mov %eax,-0x3c(%ebp) + asm volatile ("btsl %1, %0" :"=m" (*(volatile long *)addr) : "Ir" (nr)); + 102b0e: 8b 45 c4 mov -0x3c(%ebp),%eax + 102b11: 8b 55 c8 mov -0x38(%ebp),%edx + 102b14: 0f ab 10 bts %edx,(%eax) +} + 102b17: 90 nop + nr_free += n;// 更新空闲页计数 + 102b18: 8b 15 e8 ce 11 00 mov 0x11cee8,%edx + 102b1e: 8b 45 0c mov 0xc(%ebp),%eax + 102b21: 01 d0 add %edx,%eax + 102b23: a3 e8 ce 11 00 mov %eax,0x11cee8 + list_add(&free_list, &(base->page_link)); // 将该块添加到空闲列表中 + 102b28: 8b 45 08 mov 0x8(%ebp),%eax + 102b2b: 83 c0 0c add $0xc,%eax + 102b2e: c7 45 e4 e0 ce 11 00 movl $0x11cee0,-0x1c(%ebp) + 102b35: 89 45 e0 mov %eax,-0x20(%ebp) + 102b38: 8b 45 e4 mov -0x1c(%ebp),%eax + 102b3b: 89 45 dc mov %eax,-0x24(%ebp) + 102b3e: 8b 45 e0 mov -0x20(%ebp),%eax + 102b41: 89 45 d8 mov %eax,-0x28(%ebp) + * Insert the new element @elm *after* the element @listelm which + * is already in the list. + * */ +static inline void +list_add_after(list_entry_t *listelm, list_entry_t *elm) { + __list_add(elm, listelm, listelm->next); + 102b44: 8b 45 dc mov -0x24(%ebp),%eax + 102b47: 8b 40 04 mov 0x4(%eax),%eax + 102b4a: 8b 55 d8 mov -0x28(%ebp),%edx + 102b4d: 89 55 d4 mov %edx,-0x2c(%ebp) + 102b50: 8b 55 dc mov -0x24(%ebp),%edx + 102b53: 89 55 d0 mov %edx,-0x30(%ebp) + 102b56: 89 45 cc mov %eax,-0x34(%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; + 102b59: 8b 45 cc mov -0x34(%ebp),%eax + 102b5c: 8b 55 d4 mov -0x2c(%ebp),%edx + 102b5f: 89 10 mov %edx,(%eax) + 102b61: 8b 45 cc mov -0x34(%ebp),%eax + 102b64: 8b 10 mov (%eax),%edx + 102b66: 8b 45 d0 mov -0x30(%ebp),%eax + 102b69: 89 50 04 mov %edx,0x4(%eax) + elm->next = next; + 102b6c: 8b 45 d4 mov -0x2c(%ebp),%eax + 102b6f: 8b 55 cc mov -0x34(%ebp),%edx + 102b72: 89 50 04 mov %edx,0x4(%eax) + elm->prev = prev; + 102b75: 8b 45 d4 mov -0x2c(%ebp),%eax + 102b78: 8b 55 d0 mov -0x30(%ebp),%edx + 102b7b: 89 10 mov %edx,(%eax) +} + 102b7d: 90 nop +} + 102b7e: 90 nop +} + 102b7f: 90 nop +} + 102b80: 90 nop + 102b81: 89 ec mov %ebp,%esp + 102b83: 5d pop %ebp + 102b84: c3 ret + +00102b85 : + +//用于分配指定数量的连续物理页。该函数实现了首次适应内存分配算法。 +static struct Page * +default_alloc_pages(size_t n) { + 102b85: 55 push %ebp + 102b86: 89 e5 mov %esp,%ebp + 102b88: 83 ec 68 sub $0x68,%esp + assert(n > 0);// 确保请求的页数大于零 + 102b8b: 83 7d 08 00 cmpl $0x0,0x8(%ebp) + 102b8f: 75 24 jne 102bb5 + 102b91: c7 44 24 0c 90 67 10 movl $0x106790,0xc(%esp) + 102b98: 00 + 102b99: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 102ba0: 00 + 102ba1: c7 44 24 04 a6 00 00 movl $0xa6,0x4(%esp) + 102ba8: 00 + 102ba9: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 102bb0: e8 7e e0 ff ff call 100c33 <__panic> + if (n > nr_free) {// 检查请求的页数是否超过空闲页数 + 102bb5: a1 e8 ce 11 00 mov 0x11cee8,%eax + 102bba: 39 45 08 cmp %eax,0x8(%ebp) + 102bbd: 76 0a jbe 102bc9 + return NULL; + 102bbf: b8 00 00 00 00 mov $0x0,%eax + 102bc4: e9 34 01 00 00 jmp 102cfd + } + struct Page *page = NULL;// 初始化分配的页指针 + 102bc9: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + list_entry_t *le = &free_list; // 初始化链表迭代器 + 102bd0: c7 45 f0 e0 ce 11 00 movl $0x11cee0,-0x10(%ebp) + // 遍历空闲列表,寻找第一个满足条件的块 + while ((le = list_next(le)) != &free_list) { + 102bd7: eb 1c jmp 102bf5 + struct Page *p = le2page(le, page_link);// 将链表节点转换为 Page 结构体 + 102bd9: 8b 45 f0 mov -0x10(%ebp),%eax + 102bdc: 83 e8 0c sub $0xc,%eax + 102bdf: 89 45 ec mov %eax,-0x14(%ebp) + if (p->property >= n) {// 检查当前块的页数是否满足请求 + 102be2: 8b 45 ec mov -0x14(%ebp),%eax + 102be5: 8b 40 08 mov 0x8(%eax),%eax + 102be8: 39 45 08 cmp %eax,0x8(%ebp) + 102beb: 77 08 ja 102bf5 + page = p;// 找到合适的块 + 102bed: 8b 45 ec mov -0x14(%ebp),%eax + 102bf0: 89 45 f4 mov %eax,-0xc(%ebp) + break;// 退出循环 + 102bf3: eb 18 jmp 102c0d + 102bf5: 8b 45 f0 mov -0x10(%ebp),%eax + 102bf8: 89 45 e4 mov %eax,-0x1c(%ebp) + return listelm->next; + 102bfb: 8b 45 e4 mov -0x1c(%ebp),%eax + 102bfe: 8b 40 04 mov 0x4(%eax),%eax + while ((le = list_next(le)) != &free_list) { + 102c01: 89 45 f0 mov %eax,-0x10(%ebp) + 102c04: 81 7d f0 e0 ce 11 00 cmpl $0x11cee0,-0x10(%ebp) + 102c0b: 75 cc jne 102bd9 + } + } + if (page != NULL) {// 如果找到合适的块 + 102c0d: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) + 102c11: 0f 84 e3 00 00 00 je 102cfa + list_del(&(page->page_link));// 从空闲列表中删除该块 + 102c17: 8b 45 f4 mov -0xc(%ebp),%eax + 102c1a: 83 c0 0c add $0xc,%eax + 102c1d: 89 45 e0 mov %eax,-0x20(%ebp) + __list_del(listelm->prev, listelm->next); + 102c20: 8b 45 e0 mov -0x20(%ebp),%eax + 102c23: 8b 40 04 mov 0x4(%eax),%eax + 102c26: 8b 55 e0 mov -0x20(%ebp),%edx + 102c29: 8b 12 mov (%edx),%edx + 102c2b: 89 55 dc mov %edx,-0x24(%ebp) + 102c2e: 89 45 d8 mov %eax,-0x28(%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; + 102c31: 8b 45 dc mov -0x24(%ebp),%eax + 102c34: 8b 55 d8 mov -0x28(%ebp),%edx + 102c37: 89 50 04 mov %edx,0x4(%eax) + next->prev = prev; + 102c3a: 8b 45 d8 mov -0x28(%ebp),%eax + 102c3d: 8b 55 dc mov -0x24(%ebp),%edx + 102c40: 89 10 mov %edx,(%eax) +} + 102c42: 90 nop +} + 102c43: 90 nop + if (page->property > n) { + 102c44: 8b 45 f4 mov -0xc(%ebp),%eax + 102c47: 8b 40 08 mov 0x8(%eax),%eax + 102c4a: 39 45 08 cmp %eax,0x8(%ebp) + 102c4d: 0f 83 80 00 00 00 jae 102cd3 + struct Page *p = page + n; // 指向剩余的页 + 102c53: 8b 55 08 mov 0x8(%ebp),%edx + 102c56: 89 d0 mov %edx,%eax + 102c58: c1 e0 02 shl $0x2,%eax + 102c5b: 01 d0 add %edx,%eax + 102c5d: c1 e0 02 shl $0x2,%eax + 102c60: 89 c2 mov %eax,%edx + 102c62: 8b 45 f4 mov -0xc(%ebp),%eax + 102c65: 01 d0 add %edx,%eax + 102c67: 89 45 e8 mov %eax,-0x18(%ebp) + p->property = page->property - n;// 更新剩余块的页数 + 102c6a: 8b 45 f4 mov -0xc(%ebp),%eax + 102c6d: 8b 40 08 mov 0x8(%eax),%eax + 102c70: 2b 45 08 sub 0x8(%ebp),%eax + 102c73: 89 c2 mov %eax,%edx + 102c75: 8b 45 e8 mov -0x18(%ebp),%eax + 102c78: 89 50 08 mov %edx,0x8(%eax) + list_add(&free_list, &(p->page_link));// 将剩余块添加回空闲列表 + 102c7b: 8b 45 e8 mov -0x18(%ebp),%eax + 102c7e: 83 c0 0c add $0xc,%eax + 102c81: c7 45 d4 e0 ce 11 00 movl $0x11cee0,-0x2c(%ebp) + 102c88: 89 45 d0 mov %eax,-0x30(%ebp) + 102c8b: 8b 45 d4 mov -0x2c(%ebp),%eax + 102c8e: 89 45 cc mov %eax,-0x34(%ebp) + 102c91: 8b 45 d0 mov -0x30(%ebp),%eax + 102c94: 89 45 c8 mov %eax,-0x38(%ebp) + __list_add(elm, listelm, listelm->next); + 102c97: 8b 45 cc mov -0x34(%ebp),%eax + 102c9a: 8b 40 04 mov 0x4(%eax),%eax + 102c9d: 8b 55 c8 mov -0x38(%ebp),%edx + 102ca0: 89 55 c4 mov %edx,-0x3c(%ebp) + 102ca3: 8b 55 cc mov -0x34(%ebp),%edx + 102ca6: 89 55 c0 mov %edx,-0x40(%ebp) + 102ca9: 89 45 bc mov %eax,-0x44(%ebp) + prev->next = next->prev = elm; + 102cac: 8b 45 bc mov -0x44(%ebp),%eax + 102caf: 8b 55 c4 mov -0x3c(%ebp),%edx + 102cb2: 89 10 mov %edx,(%eax) + 102cb4: 8b 45 bc mov -0x44(%ebp),%eax + 102cb7: 8b 10 mov (%eax),%edx + 102cb9: 8b 45 c0 mov -0x40(%ebp),%eax + 102cbc: 89 50 04 mov %edx,0x4(%eax) + elm->next = next; + 102cbf: 8b 45 c4 mov -0x3c(%ebp),%eax + 102cc2: 8b 55 bc mov -0x44(%ebp),%edx + 102cc5: 89 50 04 mov %edx,0x4(%eax) + elm->prev = prev; + 102cc8: 8b 45 c4 mov -0x3c(%ebp),%eax + 102ccb: 8b 55 c0 mov -0x40(%ebp),%edx + 102cce: 89 10 mov %edx,(%eax) +} + 102cd0: 90 nop +} + 102cd1: 90 nop +} + 102cd2: 90 nop + } + nr_free -= n;// 减少空闲页的计数 + 102cd3: a1 e8 ce 11 00 mov 0x11cee8,%eax + 102cd8: 2b 45 08 sub 0x8(%ebp),%eax + 102cdb: a3 e8 ce 11 00 mov %eax,0x11cee8 + ClearPageProperty(page); // 清除已分配页的属性 + 102ce0: 8b 45 f4 mov -0xc(%ebp),%eax + 102ce3: 83 c0 04 add $0x4,%eax + 102ce6: c7 45 b8 01 00 00 00 movl $0x1,-0x48(%ebp) + 102ced: 89 45 b4 mov %eax,-0x4c(%ebp) + asm volatile ("btrl %1, %0" :"=m" (*(volatile long *)addr) : "Ir" (nr)); + 102cf0: 8b 45 b4 mov -0x4c(%ebp),%eax + 102cf3: 8b 55 b8 mov -0x48(%ebp),%edx + 102cf6: 0f b3 10 btr %edx,(%eax) +} + 102cf9: 90 nop + } + return page;// 返回分配的页块 + 102cfa: 8b 45 f4 mov -0xc(%ebp),%eax +} + 102cfd: 89 ec mov %ebp,%esp + 102cff: 5d pop %ebp + 102d00: c3 ret + +00102d01 : + +static void +default_free_pages(struct Page *base, size_t n) { + 102d01: 55 push %ebp + 102d02: 89 e5 mov %esp,%ebp + 102d04: 81 ec 98 00 00 00 sub $0x98,%esp + assert(n > 0);// 确保请求释放的页数大于零 + 102d0a: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) + 102d0e: 75 24 jne 102d34 + 102d10: c7 44 24 0c 90 67 10 movl $0x106790,0xc(%esp) + 102d17: 00 + 102d18: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 102d1f: 00 + 102d20: c7 44 24 04 c3 00 00 movl $0xc3,0x4(%esp) + 102d27: 00 + 102d28: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 102d2f: e8 ff de ff ff call 100c33 <__panic> + struct Page *p = base; + 102d34: 8b 45 08 mov 0x8(%ebp),%eax + 102d37: 89 45 f4 mov %eax,-0xc(%ebp) + // 遍历释放的页,检查状态并重置 + for (; p != base + n; p ++) { + 102d3a: e9 9d 00 00 00 jmp 102ddc + assert(!PageReserved(p) && !PageProperty(p)); // 确保页没有被保留并且没有属性 + 102d3f: 8b 45 f4 mov -0xc(%ebp),%eax + 102d42: 83 c0 04 add $0x4,%eax + 102d45: c7 45 ec 00 00 00 00 movl $0x0,-0x14(%ebp) + 102d4c: 89 45 e8 mov %eax,-0x18(%ebp) + asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr)); + 102d4f: 8b 45 e8 mov -0x18(%ebp),%eax + 102d52: 8b 55 ec mov -0x14(%ebp),%edx + 102d55: 0f a3 10 bt %edx,(%eax) + 102d58: 19 c0 sbb %eax,%eax + 102d5a: 89 45 e4 mov %eax,-0x1c(%ebp) + return oldbit != 0; + 102d5d: 83 7d e4 00 cmpl $0x0,-0x1c(%ebp) + 102d61: 0f 95 c0 setne %al + 102d64: 0f b6 c0 movzbl %al,%eax + 102d67: 85 c0 test %eax,%eax + 102d69: 75 2c jne 102d97 + 102d6b: 8b 45 f4 mov -0xc(%ebp),%eax + 102d6e: 83 c0 04 add $0x4,%eax + 102d71: c7 45 e0 01 00 00 00 movl $0x1,-0x20(%ebp) + 102d78: 89 45 dc mov %eax,-0x24(%ebp) + asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr)); + 102d7b: 8b 45 dc mov -0x24(%ebp),%eax + 102d7e: 8b 55 e0 mov -0x20(%ebp),%edx + 102d81: 0f a3 10 bt %edx,(%eax) + 102d84: 19 c0 sbb %eax,%eax + 102d86: 89 45 d8 mov %eax,-0x28(%ebp) + return oldbit != 0; + 102d89: 83 7d d8 00 cmpl $0x0,-0x28(%ebp) + 102d8d: 0f 95 c0 setne %al + 102d90: 0f b6 c0 movzbl %al,%eax + 102d93: 85 c0 test %eax,%eax + 102d95: 74 24 je 102dbb + 102d97: c7 44 24 0c d4 67 10 movl $0x1067d4,0xc(%esp) + 102d9e: 00 + 102d9f: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 102da6: 00 + 102da7: c7 44 24 04 c7 00 00 movl $0xc7,0x4(%esp) + 102dae: 00 + 102daf: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 102db6: e8 78 de ff ff call 100c33 <__panic> + p->flags = 0;// 清除 flags 字段 + 102dbb: 8b 45 f4 mov -0xc(%ebp),%eax + 102dbe: c7 40 04 00 00 00 00 movl $0x0,0x4(%eax) + set_page_ref(p, 0);// 清除引用计数 + 102dc5: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) + 102dcc: 00 + 102dcd: 8b 45 f4 mov -0xc(%ebp),%eax + 102dd0: 89 04 24 mov %eax,(%esp) + 102dd3: e8 0c fc ff ff call 1029e4 + for (; p != base + n; p ++) { + 102dd8: 83 45 f4 14 addl $0x14,-0xc(%ebp) + 102ddc: 8b 55 0c mov 0xc(%ebp),%edx + 102ddf: 89 d0 mov %edx,%eax + 102de1: c1 e0 02 shl $0x2,%eax + 102de4: 01 d0 add %edx,%eax + 102de6: c1 e0 02 shl $0x2,%eax + 102de9: 89 c2 mov %eax,%edx + 102deb: 8b 45 08 mov 0x8(%ebp),%eax + 102dee: 01 d0 add %edx,%eax + 102df0: 39 45 f4 cmp %eax,-0xc(%ebp) + 102df3: 0f 85 46 ff ff ff jne 102d3f + } + // 设置基页的属性为释放的页数 + base->property = n; + 102df9: 8b 45 08 mov 0x8(%ebp),%eax + 102dfc: 8b 55 0c mov 0xc(%ebp),%edx + 102dff: 89 50 08 mov %edx,0x8(%eax) + SetPageProperty(base);// 设置页的有效标志 + 102e02: 8b 45 08 mov 0x8(%ebp),%eax + 102e05: 83 c0 04 add $0x4,%eax + 102e08: c7 45 d0 01 00 00 00 movl $0x1,-0x30(%ebp) + 102e0f: 89 45 cc mov %eax,-0x34(%ebp) + asm volatile ("btsl %1, %0" :"=m" (*(volatile long *)addr) : "Ir" (nr)); + 102e12: 8b 45 cc mov -0x34(%ebp),%eax + 102e15: 8b 55 d0 mov -0x30(%ebp),%edx + 102e18: 0f ab 10 bts %edx,(%eax) +} + 102e1b: 90 nop + 102e1c: c7 45 d4 e0 ce 11 00 movl $0x11cee0,-0x2c(%ebp) + return listelm->next; + 102e23: 8b 45 d4 mov -0x2c(%ebp),%eax + 102e26: 8b 40 04 mov 0x4(%eax),%eax + // 遍历空闲列表,检查是否需要合并 + list_entry_t *le = list_next(&free_list); + 102e29: 89 45 f0 mov %eax,-0x10(%ebp) + while (le != &free_list) { + 102e2c: e9 0e 01 00 00 jmp 102f3f + p = le2page(le, page_link); + 102e31: 8b 45 f0 mov -0x10(%ebp),%eax + 102e34: 83 e8 0c sub $0xc,%eax + 102e37: 89 45 f4 mov %eax,-0xc(%ebp) + 102e3a: 8b 45 f0 mov -0x10(%ebp),%eax + 102e3d: 89 45 c8 mov %eax,-0x38(%ebp) + 102e40: 8b 45 c8 mov -0x38(%ebp),%eax + 102e43: 8b 40 04 mov 0x4(%eax),%eax + le = list_next(le); + 102e46: 89 45 f0 mov %eax,-0x10(%ebp) + // 如果当前页块与释放的页块相邻,合并 + if (base + base->property == p) { + 102e49: 8b 45 08 mov 0x8(%ebp),%eax + 102e4c: 8b 50 08 mov 0x8(%eax),%edx + 102e4f: 89 d0 mov %edx,%eax + 102e51: c1 e0 02 shl $0x2,%eax + 102e54: 01 d0 add %edx,%eax + 102e56: c1 e0 02 shl $0x2,%eax + 102e59: 89 c2 mov %eax,%edx + 102e5b: 8b 45 08 mov 0x8(%ebp),%eax + 102e5e: 01 d0 add %edx,%eax + 102e60: 39 45 f4 cmp %eax,-0xc(%ebp) + 102e63: 75 5d jne 102ec2 + base->property += p->property;// 合并当前页块 + 102e65: 8b 45 08 mov 0x8(%ebp),%eax + 102e68: 8b 50 08 mov 0x8(%eax),%edx + 102e6b: 8b 45 f4 mov -0xc(%ebp),%eax + 102e6e: 8b 40 08 mov 0x8(%eax),%eax + 102e71: 01 c2 add %eax,%edx + 102e73: 8b 45 08 mov 0x8(%ebp),%eax + 102e76: 89 50 08 mov %edx,0x8(%eax) + ClearPageProperty(p);// 清除合并页的属性 + 102e79: 8b 45 f4 mov -0xc(%ebp),%eax + 102e7c: 83 c0 04 add $0x4,%eax + 102e7f: c7 45 b8 01 00 00 00 movl $0x1,-0x48(%ebp) + 102e86: 89 45 b4 mov %eax,-0x4c(%ebp) + asm volatile ("btrl %1, %0" :"=m" (*(volatile long *)addr) : "Ir" (nr)); + 102e89: 8b 45 b4 mov -0x4c(%ebp),%eax + 102e8c: 8b 55 b8 mov -0x48(%ebp),%edx + 102e8f: 0f b3 10 btr %edx,(%eax) +} + 102e92: 90 nop + list_del(&(p->page_link));// 从空闲列表中删除合并页 + 102e93: 8b 45 f4 mov -0xc(%ebp),%eax + 102e96: 83 c0 0c add $0xc,%eax + 102e99: 89 45 c4 mov %eax,-0x3c(%ebp) + __list_del(listelm->prev, listelm->next); + 102e9c: 8b 45 c4 mov -0x3c(%ebp),%eax + 102e9f: 8b 40 04 mov 0x4(%eax),%eax + 102ea2: 8b 55 c4 mov -0x3c(%ebp),%edx + 102ea5: 8b 12 mov (%edx),%edx + 102ea7: 89 55 c0 mov %edx,-0x40(%ebp) + 102eaa: 89 45 bc mov %eax,-0x44(%ebp) + prev->next = next; + 102ead: 8b 45 c0 mov -0x40(%ebp),%eax + 102eb0: 8b 55 bc mov -0x44(%ebp),%edx + 102eb3: 89 50 04 mov %edx,0x4(%eax) + next->prev = prev; + 102eb6: 8b 45 bc mov -0x44(%ebp),%eax + 102eb9: 8b 55 c0 mov -0x40(%ebp),%edx + 102ebc: 89 10 mov %edx,(%eax) +} + 102ebe: 90 nop +} + 102ebf: 90 nop + 102ec0: eb 7d jmp 102f3f + } + else if (p + p->property == base) { + 102ec2: 8b 45 f4 mov -0xc(%ebp),%eax + 102ec5: 8b 50 08 mov 0x8(%eax),%edx + 102ec8: 89 d0 mov %edx,%eax + 102eca: c1 e0 02 shl $0x2,%eax + 102ecd: 01 d0 add %edx,%eax + 102ecf: c1 e0 02 shl $0x2,%eax + 102ed2: 89 c2 mov %eax,%edx + 102ed4: 8b 45 f4 mov -0xc(%ebp),%eax + 102ed7: 01 d0 add %edx,%eax + 102ed9: 39 45 08 cmp %eax,0x8(%ebp) + 102edc: 75 61 jne 102f3f + p->property += base->property;// 合并前一个页块 + 102ede: 8b 45 f4 mov -0xc(%ebp),%eax + 102ee1: 8b 50 08 mov 0x8(%eax),%edx + 102ee4: 8b 45 08 mov 0x8(%ebp),%eax + 102ee7: 8b 40 08 mov 0x8(%eax),%eax + 102eea: 01 c2 add %eax,%edx + 102eec: 8b 45 f4 mov -0xc(%ebp),%eax + 102eef: 89 50 08 mov %edx,0x8(%eax) + ClearPageProperty(base);// 清除当前页的属性 + 102ef2: 8b 45 08 mov 0x8(%ebp),%eax + 102ef5: 83 c0 04 add $0x4,%eax + 102ef8: c7 45 a4 01 00 00 00 movl $0x1,-0x5c(%ebp) + 102eff: 89 45 a0 mov %eax,-0x60(%ebp) + asm volatile ("btrl %1, %0" :"=m" (*(volatile long *)addr) : "Ir" (nr)); + 102f02: 8b 45 a0 mov -0x60(%ebp),%eax + 102f05: 8b 55 a4 mov -0x5c(%ebp),%edx + 102f08: 0f b3 10 btr %edx,(%eax) +} + 102f0b: 90 nop + base = p;// 更新 base 指针 + 102f0c: 8b 45 f4 mov -0xc(%ebp),%eax + 102f0f: 89 45 08 mov %eax,0x8(%ebp) + list_del(&(p->page_link)); // 从空闲列表中删除当前页 + 102f12: 8b 45 f4 mov -0xc(%ebp),%eax + 102f15: 83 c0 0c add $0xc,%eax + 102f18: 89 45 b0 mov %eax,-0x50(%ebp) + __list_del(listelm->prev, listelm->next); + 102f1b: 8b 45 b0 mov -0x50(%ebp),%eax + 102f1e: 8b 40 04 mov 0x4(%eax),%eax + 102f21: 8b 55 b0 mov -0x50(%ebp),%edx + 102f24: 8b 12 mov (%edx),%edx + 102f26: 89 55 ac mov %edx,-0x54(%ebp) + 102f29: 89 45 a8 mov %eax,-0x58(%ebp) + prev->next = next; + 102f2c: 8b 45 ac mov -0x54(%ebp),%eax + 102f2f: 8b 55 a8 mov -0x58(%ebp),%edx + 102f32: 89 50 04 mov %edx,0x4(%eax) + next->prev = prev; + 102f35: 8b 45 a8 mov -0x58(%ebp),%eax + 102f38: 8b 55 ac mov -0x54(%ebp),%edx + 102f3b: 89 10 mov %edx,(%eax) +} + 102f3d: 90 nop +} + 102f3e: 90 nop + while (le != &free_list) { + 102f3f: 81 7d f0 e0 ce 11 00 cmpl $0x11cee0,-0x10(%ebp) + 102f46: 0f 85 e5 fe ff ff jne 102e31 + } + } + nr_free += n;// 更新空闲页的计数 + 102f4c: 8b 15 e8 ce 11 00 mov 0x11cee8,%edx + 102f52: 8b 45 0c mov 0xc(%ebp),%eax + 102f55: 01 d0 add %edx,%eax + 102f57: a3 e8 ce 11 00 mov %eax,0x11cee8 + list_add(&free_list, &(base->page_link));// 将释放的页块添加到空闲列表中 + 102f5c: 8b 45 08 mov 0x8(%ebp),%eax + 102f5f: 83 c0 0c add $0xc,%eax + 102f62: c7 45 9c e0 ce 11 00 movl $0x11cee0,-0x64(%ebp) + 102f69: 89 45 98 mov %eax,-0x68(%ebp) + 102f6c: 8b 45 9c mov -0x64(%ebp),%eax + 102f6f: 89 45 94 mov %eax,-0x6c(%ebp) + 102f72: 8b 45 98 mov -0x68(%ebp),%eax + 102f75: 89 45 90 mov %eax,-0x70(%ebp) + __list_add(elm, listelm, listelm->next); + 102f78: 8b 45 94 mov -0x6c(%ebp),%eax + 102f7b: 8b 40 04 mov 0x4(%eax),%eax + 102f7e: 8b 55 90 mov -0x70(%ebp),%edx + 102f81: 89 55 8c mov %edx,-0x74(%ebp) + 102f84: 8b 55 94 mov -0x6c(%ebp),%edx + 102f87: 89 55 88 mov %edx,-0x78(%ebp) + 102f8a: 89 45 84 mov %eax,-0x7c(%ebp) + prev->next = next->prev = elm; + 102f8d: 8b 45 84 mov -0x7c(%ebp),%eax + 102f90: 8b 55 8c mov -0x74(%ebp),%edx + 102f93: 89 10 mov %edx,(%eax) + 102f95: 8b 45 84 mov -0x7c(%ebp),%eax + 102f98: 8b 10 mov (%eax),%edx + 102f9a: 8b 45 88 mov -0x78(%ebp),%eax + 102f9d: 89 50 04 mov %edx,0x4(%eax) + elm->next = next; + 102fa0: 8b 45 8c mov -0x74(%ebp),%eax + 102fa3: 8b 55 84 mov -0x7c(%ebp),%edx + 102fa6: 89 50 04 mov %edx,0x4(%eax) + elm->prev = prev; + 102fa9: 8b 45 8c mov -0x74(%ebp),%eax + 102fac: 8b 55 88 mov -0x78(%ebp),%edx + 102faf: 89 10 mov %edx,(%eax) +} + 102fb1: 90 nop +} + 102fb2: 90 nop +} + 102fb3: 90 nop +} + 102fb4: 90 nop + 102fb5: 89 ec mov %ebp,%esp + 102fb7: 5d pop %ebp + 102fb8: c3 ret + +00102fb9 : + +//用于返回当前系统中可用的空闲页的数量。 +static size_t +default_nr_free_pages(void) { + 102fb9: 55 push %ebp + 102fba: 89 e5 mov %esp,%ebp + return nr_free;// 返回当前空闲页的数量 + 102fbc: a1 e8 ce 11 00 mov 0x11cee8,%eax +} + 102fc1: 5d pop %ebp + 102fc2: c3 ret + +00102fc3 : + +//basic_check 函数用于测试内存分配和释放的基本功能, +//确保在不同情况下内存管理系统的正确性,包括分配、释放、合并和引用计数等操作。 +static void +basic_check(void) { + 102fc3: 55 push %ebp + 102fc4: 89 e5 mov %esp,%ebp + 102fc6: 83 ec 48 sub $0x48,%esp + struct Page *p0, *p1, *p2; + p0 = p1 = p2 = NULL; + 102fc9: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + 102fd0: 8b 45 f4 mov -0xc(%ebp),%eax + 102fd3: 89 45 f0 mov %eax,-0x10(%ebp) + 102fd6: 8b 45 f0 mov -0x10(%ebp),%eax + 102fd9: 89 45 ec mov %eax,-0x14(%ebp) + // 分配三个页面 + assert((p0 = alloc_page()) != NULL); + 102fdc: c7 04 24 01 00 00 00 movl $0x1,(%esp) + 102fe3: e8 ed 0e 00 00 call 103ed5 + 102fe8: 89 45 ec mov %eax,-0x14(%ebp) + 102feb: 83 7d ec 00 cmpl $0x0,-0x14(%ebp) + 102fef: 75 24 jne 103015 + 102ff1: c7 44 24 0c f9 67 10 movl $0x1067f9,0xc(%esp) + 102ff8: 00 + 102ff9: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 103000: 00 + 103001: c7 44 24 04 f1 00 00 movl $0xf1,0x4(%esp) + 103008: 00 + 103009: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 103010: e8 1e dc ff ff call 100c33 <__panic> + assert((p1 = alloc_page()) != NULL); + 103015: c7 04 24 01 00 00 00 movl $0x1,(%esp) + 10301c: e8 b4 0e 00 00 call 103ed5 + 103021: 89 45 f0 mov %eax,-0x10(%ebp) + 103024: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) + 103028: 75 24 jne 10304e + 10302a: c7 44 24 0c 15 68 10 movl $0x106815,0xc(%esp) + 103031: 00 + 103032: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 103039: 00 + 10303a: c7 44 24 04 f2 00 00 movl $0xf2,0x4(%esp) + 103041: 00 + 103042: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 103049: e8 e5 db ff ff call 100c33 <__panic> + assert((p2 = alloc_page()) != NULL); + 10304e: c7 04 24 01 00 00 00 movl $0x1,(%esp) + 103055: e8 7b 0e 00 00 call 103ed5 + 10305a: 89 45 f4 mov %eax,-0xc(%ebp) + 10305d: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) + 103061: 75 24 jne 103087 + 103063: c7 44 24 0c 31 68 10 movl $0x106831,0xc(%esp) + 10306a: 00 + 10306b: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 103072: 00 + 103073: c7 44 24 04 f3 00 00 movl $0xf3,0x4(%esp) + 10307a: 00 + 10307b: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 103082: e8 ac db ff ff call 100c33 <__panic> + // 确保所有分配的页面是不同的 + assert(p0 != p1 && p0 != p2 && p1 != p2); + 103087: 8b 45 ec mov -0x14(%ebp),%eax + 10308a: 3b 45 f0 cmp -0x10(%ebp),%eax + 10308d: 74 10 je 10309f + 10308f: 8b 45 ec mov -0x14(%ebp),%eax + 103092: 3b 45 f4 cmp -0xc(%ebp),%eax + 103095: 74 08 je 10309f + 103097: 8b 45 f0 mov -0x10(%ebp),%eax + 10309a: 3b 45 f4 cmp -0xc(%ebp),%eax + 10309d: 75 24 jne 1030c3 + 10309f: c7 44 24 0c 50 68 10 movl $0x106850,0xc(%esp) + 1030a6: 00 + 1030a7: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 1030ae: 00 + 1030af: c7 44 24 04 f5 00 00 movl $0xf5,0x4(%esp) + 1030b6: 00 + 1030b7: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 1030be: e8 70 db ff ff call 100c33 <__panic> + // 确保页面的引用计数为 0 + assert(page_ref(p0) == 0 && page_ref(p1) == 0 && page_ref(p2) == 0); + 1030c3: 8b 45 ec mov -0x14(%ebp),%eax + 1030c6: 89 04 24 mov %eax,(%esp) + 1030c9: e8 0c f9 ff ff call 1029da + 1030ce: 85 c0 test %eax,%eax + 1030d0: 75 1e jne 1030f0 + 1030d2: 8b 45 f0 mov -0x10(%ebp),%eax + 1030d5: 89 04 24 mov %eax,(%esp) + 1030d8: e8 fd f8 ff ff call 1029da + 1030dd: 85 c0 test %eax,%eax + 1030df: 75 0f jne 1030f0 + 1030e1: 8b 45 f4 mov -0xc(%ebp),%eax + 1030e4: 89 04 24 mov %eax,(%esp) + 1030e7: e8 ee f8 ff ff call 1029da + 1030ec: 85 c0 test %eax,%eax + 1030ee: 74 24 je 103114 + 1030f0: c7 44 24 0c 74 68 10 movl $0x106874,0xc(%esp) + 1030f7: 00 + 1030f8: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 1030ff: 00 + 103100: c7 44 24 04 f7 00 00 movl $0xf7,0x4(%esp) + 103107: 00 + 103108: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 10310f: e8 1f db ff ff call 100c33 <__panic> + // 确保页面地址在合法范围内 + assert(page2pa(p0) < npage * PGSIZE); + 103114: 8b 45 ec mov -0x14(%ebp),%eax + 103117: 89 04 24 mov %eax,(%esp) + 10311a: e8 a3 f8 ff ff call 1029c2 + 10311f: 8b 15 04 cf 11 00 mov 0x11cf04,%edx + 103125: c1 e2 0c shl $0xc,%edx + 103128: 39 d0 cmp %edx,%eax + 10312a: 72 24 jb 103150 + 10312c: c7 44 24 0c b0 68 10 movl $0x1068b0,0xc(%esp) + 103133: 00 + 103134: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 10313b: 00 + 10313c: c7 44 24 04 f9 00 00 movl $0xf9,0x4(%esp) + 103143: 00 + 103144: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 10314b: e8 e3 da ff ff call 100c33 <__panic> + assert(page2pa(p1) < npage * PGSIZE); + 103150: 8b 45 f0 mov -0x10(%ebp),%eax + 103153: 89 04 24 mov %eax,(%esp) + 103156: e8 67 f8 ff ff call 1029c2 + 10315b: 8b 15 04 cf 11 00 mov 0x11cf04,%edx + 103161: c1 e2 0c shl $0xc,%edx + 103164: 39 d0 cmp %edx,%eax + 103166: 72 24 jb 10318c + 103168: c7 44 24 0c cd 68 10 movl $0x1068cd,0xc(%esp) + 10316f: 00 + 103170: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 103177: 00 + 103178: c7 44 24 04 fa 00 00 movl $0xfa,0x4(%esp) + 10317f: 00 + 103180: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 103187: e8 a7 da ff ff call 100c33 <__panic> + assert(page2pa(p2) < npage * PGSIZE); + 10318c: 8b 45 f4 mov -0xc(%ebp),%eax + 10318f: 89 04 24 mov %eax,(%esp) + 103192: e8 2b f8 ff ff call 1029c2 + 103197: 8b 15 04 cf 11 00 mov 0x11cf04,%edx + 10319d: c1 e2 0c shl $0xc,%edx + 1031a0: 39 d0 cmp %edx,%eax + 1031a2: 72 24 jb 1031c8 + 1031a4: c7 44 24 0c ea 68 10 movl $0x1068ea,0xc(%esp) + 1031ab: 00 + 1031ac: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 1031b3: 00 + 1031b4: c7 44 24 04 fb 00 00 movl $0xfb,0x4(%esp) + 1031bb: 00 + 1031bc: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 1031c3: e8 6b da ff ff call 100c33 <__panic> + // 保存当前的空闲页面链表和数量 + list_entry_t free_list_store = free_list; + 1031c8: a1 e0 ce 11 00 mov 0x11cee0,%eax + 1031cd: 8b 15 e4 ce 11 00 mov 0x11cee4,%edx + 1031d3: 89 45 d0 mov %eax,-0x30(%ebp) + 1031d6: 89 55 d4 mov %edx,-0x2c(%ebp) + 1031d9: c7 45 dc e0 ce 11 00 movl $0x11cee0,-0x24(%ebp) + elm->prev = elm->next = elm; + 1031e0: 8b 45 dc mov -0x24(%ebp),%eax + 1031e3: 8b 55 dc mov -0x24(%ebp),%edx + 1031e6: 89 50 04 mov %edx,0x4(%eax) + 1031e9: 8b 45 dc mov -0x24(%ebp),%eax + 1031ec: 8b 50 04 mov 0x4(%eax),%edx + 1031ef: 8b 45 dc mov -0x24(%ebp),%eax + 1031f2: 89 10 mov %edx,(%eax) +} + 1031f4: 90 nop + 1031f5: c7 45 e0 e0 ce 11 00 movl $0x11cee0,-0x20(%ebp) + return list->next == list; + 1031fc: 8b 45 e0 mov -0x20(%ebp),%eax + 1031ff: 8b 40 04 mov 0x4(%eax),%eax + 103202: 39 45 e0 cmp %eax,-0x20(%ebp) + 103205: 0f 94 c0 sete %al + 103208: 0f b6 c0 movzbl %al,%eax + list_init(&free_list);// 初始化空闲列表 + assert(list_empty(&free_list));// 确保空闲列表为空 + 10320b: 85 c0 test %eax,%eax + 10320d: 75 24 jne 103233 + 10320f: c7 44 24 0c 07 69 10 movl $0x106907,0xc(%esp) + 103216: 00 + 103217: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 10321e: 00 + 10321f: c7 44 24 04 ff 00 00 movl $0xff,0x4(%esp) + 103226: 00 + 103227: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 10322e: e8 00 da ff ff call 100c33 <__panic> + + unsigned int nr_free_store = nr_free;// 保存当前空闲页数量 + 103233: a1 e8 ce 11 00 mov 0x11cee8,%eax + 103238: 89 45 e8 mov %eax,-0x18(%ebp) + nr_free = 0;// 将空闲页数量设为 0 + 10323b: c7 05 e8 ce 11 00 00 movl $0x0,0x11cee8 + 103242: 00 00 00 + // 请求分配页面,但当前没有空闲页面 + assert(alloc_page() == NULL); + 103245: c7 04 24 01 00 00 00 movl $0x1,(%esp) + 10324c: e8 84 0c 00 00 call 103ed5 + 103251: 85 c0 test %eax,%eax + 103253: 74 24 je 103279 + 103255: c7 44 24 0c 1e 69 10 movl $0x10691e,0xc(%esp) + 10325c: 00 + 10325d: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 103264: 00 + 103265: c7 44 24 04 04 01 00 movl $0x104,0x4(%esp) + 10326c: 00 + 10326d: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 103274: e8 ba d9 ff ff call 100c33 <__panic> + // 释放之前分配的页面 + free_page(p0); + 103279: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) + 103280: 00 + 103281: 8b 45 ec mov -0x14(%ebp),%eax + 103284: 89 04 24 mov %eax,(%esp) + 103287: e8 83 0c 00 00 call 103f0f + free_page(p1); + 10328c: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) + 103293: 00 + 103294: 8b 45 f0 mov -0x10(%ebp),%eax + 103297: 89 04 24 mov %eax,(%esp) + 10329a: e8 70 0c 00 00 call 103f0f + free_page(p2); + 10329f: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) + 1032a6: 00 + 1032a7: 8b 45 f4 mov -0xc(%ebp),%eax + 1032aa: 89 04 24 mov %eax,(%esp) + 1032ad: e8 5d 0c 00 00 call 103f0f + assert(nr_free == 3);// 确保释放后空闲页数量为 3 + 1032b2: a1 e8 ce 11 00 mov 0x11cee8,%eax + 1032b7: 83 f8 03 cmp $0x3,%eax + 1032ba: 74 24 je 1032e0 + 1032bc: c7 44 24 0c 33 69 10 movl $0x106933,0xc(%esp) + 1032c3: 00 + 1032c4: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 1032cb: 00 + 1032cc: c7 44 24 04 09 01 00 movl $0x109,0x4(%esp) + 1032d3: 00 + 1032d4: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 1032db: e8 53 d9 ff ff call 100c33 <__panic> + // 再次分配三个页面 + assert((p0 = alloc_page()) != NULL); + 1032e0: c7 04 24 01 00 00 00 movl $0x1,(%esp) + 1032e7: e8 e9 0b 00 00 call 103ed5 + 1032ec: 89 45 ec mov %eax,-0x14(%ebp) + 1032ef: 83 7d ec 00 cmpl $0x0,-0x14(%ebp) + 1032f3: 75 24 jne 103319 + 1032f5: c7 44 24 0c f9 67 10 movl $0x1067f9,0xc(%esp) + 1032fc: 00 + 1032fd: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 103304: 00 + 103305: c7 44 24 04 0b 01 00 movl $0x10b,0x4(%esp) + 10330c: 00 + 10330d: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 103314: e8 1a d9 ff ff call 100c33 <__panic> + assert((p1 = alloc_page()) != NULL); + 103319: c7 04 24 01 00 00 00 movl $0x1,(%esp) + 103320: e8 b0 0b 00 00 call 103ed5 + 103325: 89 45 f0 mov %eax,-0x10(%ebp) + 103328: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) + 10332c: 75 24 jne 103352 + 10332e: c7 44 24 0c 15 68 10 movl $0x106815,0xc(%esp) + 103335: 00 + 103336: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 10333d: 00 + 10333e: c7 44 24 04 0c 01 00 movl $0x10c,0x4(%esp) + 103345: 00 + 103346: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 10334d: e8 e1 d8 ff ff call 100c33 <__panic> + assert((p2 = alloc_page()) != NULL); + 103352: c7 04 24 01 00 00 00 movl $0x1,(%esp) + 103359: e8 77 0b 00 00 call 103ed5 + 10335e: 89 45 f4 mov %eax,-0xc(%ebp) + 103361: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) + 103365: 75 24 jne 10338b + 103367: c7 44 24 0c 31 68 10 movl $0x106831,0xc(%esp) + 10336e: 00 + 10336f: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 103376: 00 + 103377: c7 44 24 04 0d 01 00 movl $0x10d,0x4(%esp) + 10337e: 00 + 10337f: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 103386: e8 a8 d8 ff ff call 100c33 <__panic> +// 测试空闲页面是否不足 + assert(alloc_page() == NULL); + 10338b: c7 04 24 01 00 00 00 movl $0x1,(%esp) + 103392: e8 3e 0b 00 00 call 103ed5 + 103397: 85 c0 test %eax,%eax + 103399: 74 24 je 1033bf + 10339b: c7 44 24 0c 1e 69 10 movl $0x10691e,0xc(%esp) + 1033a2: 00 + 1033a3: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 1033aa: 00 + 1033ab: c7 44 24 04 0f 01 00 movl $0x10f,0x4(%esp) + 1033b2: 00 + 1033b3: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 1033ba: e8 74 d8 ff ff call 100c33 <__panic> +// 释放 p0,并检查空闲列表 + free_page(p0); + 1033bf: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) + 1033c6: 00 + 1033c7: 8b 45 ec mov -0x14(%ebp),%eax + 1033ca: 89 04 24 mov %eax,(%esp) + 1033cd: e8 3d 0b 00 00 call 103f0f + 1033d2: c7 45 d8 e0 ce 11 00 movl $0x11cee0,-0x28(%ebp) + 1033d9: 8b 45 d8 mov -0x28(%ebp),%eax + 1033dc: 8b 40 04 mov 0x4(%eax),%eax + 1033df: 39 45 d8 cmp %eax,-0x28(%ebp) + 1033e2: 0f 94 c0 sete %al + 1033e5: 0f b6 c0 movzbl %al,%eax + assert(!list_empty(&free_list));// 确保空闲列表不为空 + 1033e8: 85 c0 test %eax,%eax + 1033ea: 74 24 je 103410 + 1033ec: c7 44 24 0c 40 69 10 movl $0x106940,0xc(%esp) + 1033f3: 00 + 1033f4: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 1033fb: 00 + 1033fc: c7 44 24 04 12 01 00 movl $0x112,0x4(%esp) + 103403: 00 + 103404: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 10340b: e8 23 d8 ff ff call 100c33 <__panic> + + struct Page *p; + // 重新分配 p0,确保取回的是相同的页面 + assert((p = alloc_page()) == p0); + 103410: c7 04 24 01 00 00 00 movl $0x1,(%esp) + 103417: e8 b9 0a 00 00 call 103ed5 + 10341c: 89 45 e4 mov %eax,-0x1c(%ebp) + 10341f: 8b 45 e4 mov -0x1c(%ebp),%eax + 103422: 3b 45 ec cmp -0x14(%ebp),%eax + 103425: 74 24 je 10344b + 103427: c7 44 24 0c 58 69 10 movl $0x106958,0xc(%esp) + 10342e: 00 + 10342f: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 103436: 00 + 103437: c7 44 24 04 16 01 00 movl $0x116,0x4(%esp) + 10343e: 00 + 10343f: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 103446: e8 e8 d7 ff ff call 100c33 <__panic> + assert(alloc_page() == NULL); // 确保没有更多的页面可分配 + 10344b: c7 04 24 01 00 00 00 movl $0x1,(%esp) + 103452: e8 7e 0a 00 00 call 103ed5 + 103457: 85 c0 test %eax,%eax + 103459: 74 24 je 10347f + 10345b: c7 44 24 0c 1e 69 10 movl $0x10691e,0xc(%esp) + 103462: 00 + 103463: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 10346a: 00 + 10346b: c7 44 24 04 17 01 00 movl $0x117,0x4(%esp) + 103472: 00 + 103473: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 10347a: e8 b4 d7 ff ff call 100c33 <__panic> + + assert(nr_free == 0);// 确保当前空闲页面数量为 0 + 10347f: a1 e8 ce 11 00 mov 0x11cee8,%eax + 103484: 85 c0 test %eax,%eax + 103486: 74 24 je 1034ac + 103488: c7 44 24 0c 71 69 10 movl $0x106971,0xc(%esp) + 10348f: 00 + 103490: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 103497: 00 + 103498: c7 44 24 04 19 01 00 movl $0x119,0x4(%esp) + 10349f: 00 + 1034a0: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 1034a7: e8 87 d7 ff ff call 100c33 <__panic> + // 恢复之前的空闲页面链表和数量 + free_list = free_list_store; + 1034ac: 8b 45 d0 mov -0x30(%ebp),%eax + 1034af: 8b 55 d4 mov -0x2c(%ebp),%edx + 1034b2: a3 e0 ce 11 00 mov %eax,0x11cee0 + 1034b7: 89 15 e4 ce 11 00 mov %edx,0x11cee4 + nr_free = nr_free_store; + 1034bd: 8b 45 e8 mov -0x18(%ebp),%eax + 1034c0: a3 e8 ce 11 00 mov %eax,0x11cee8 + // 释放最后的页面 + free_page(p); + 1034c5: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) + 1034cc: 00 + 1034cd: 8b 45 e4 mov -0x1c(%ebp),%eax + 1034d0: 89 04 24 mov %eax,(%esp) + 1034d3: e8 37 0a 00 00 call 103f0f + free_page(p1); + 1034d8: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) + 1034df: 00 + 1034e0: 8b 45 f0 mov -0x10(%ebp),%eax + 1034e3: 89 04 24 mov %eax,(%esp) + 1034e6: e8 24 0a 00 00 call 103f0f + free_page(p2); + 1034eb: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) + 1034f2: 00 + 1034f3: 8b 45 f4 mov -0xc(%ebp),%eax + 1034f6: 89 04 24 mov %eax,(%esp) + 1034f9: e8 11 0a 00 00 call 103f0f +} + 1034fe: 90 nop + 1034ff: 89 ec mov %ebp,%esp + 103501: 5d pop %ebp + 103502: c3 ret + +00103503 : + +// 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) { + 103503: 55 push %ebp + 103504: 89 e5 mov %esp,%ebp + 103506: 81 ec 98 00 00 00 sub $0x98,%esp + int count = 0, total = 0; + 10350c: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + 103513: c7 45 f0 00 00 00 00 movl $0x0,-0x10(%ebp) + list_entry_t *le = &free_list; + 10351a: c7 45 ec e0 ce 11 00 movl $0x11cee0,-0x14(%ebp) + // 遍历空闲列表,计算空闲页面的数量和总属性值 + while ((le = list_next(le)) != &free_list) { + 103521: eb 6a jmp 10358d + struct Page *p = le2page(le, page_link); + 103523: 8b 45 ec mov -0x14(%ebp),%eax + 103526: 83 e8 0c sub $0xc,%eax + 103529: 89 45 d4 mov %eax,-0x2c(%ebp) + assert(PageProperty(p));// 确保每个页面的属性是有效的 + 10352c: 8b 45 d4 mov -0x2c(%ebp),%eax + 10352f: 83 c0 04 add $0x4,%eax + 103532: c7 45 d0 01 00 00 00 movl $0x1,-0x30(%ebp) + 103539: 89 45 cc mov %eax,-0x34(%ebp) + asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr)); + 10353c: 8b 45 cc mov -0x34(%ebp),%eax + 10353f: 8b 55 d0 mov -0x30(%ebp),%edx + 103542: 0f a3 10 bt %edx,(%eax) + 103545: 19 c0 sbb %eax,%eax + 103547: 89 45 c8 mov %eax,-0x38(%ebp) + return oldbit != 0; + 10354a: 83 7d c8 00 cmpl $0x0,-0x38(%ebp) + 10354e: 0f 95 c0 setne %al + 103551: 0f b6 c0 movzbl %al,%eax + 103554: 85 c0 test %eax,%eax + 103556: 75 24 jne 10357c + 103558: c7 44 24 0c 7e 69 10 movl $0x10697e,0xc(%esp) + 10355f: 00 + 103560: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 103567: 00 + 103568: c7 44 24 04 2c 01 00 movl $0x12c,0x4(%esp) + 10356f: 00 + 103570: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 103577: e8 b7 d6 ff ff call 100c33 <__panic> + count ++, total += p->property;// 累加页面属性 + 10357c: ff 45 f4 incl -0xc(%ebp) + 10357f: 8b 45 d4 mov -0x2c(%ebp),%eax + 103582: 8b 50 08 mov 0x8(%eax),%edx + 103585: 8b 45 f0 mov -0x10(%ebp),%eax + 103588: 01 d0 add %edx,%eax + 10358a: 89 45 f0 mov %eax,-0x10(%ebp) + 10358d: 8b 45 ec mov -0x14(%ebp),%eax + 103590: 89 45 c4 mov %eax,-0x3c(%ebp) + return listelm->next; + 103593: 8b 45 c4 mov -0x3c(%ebp),%eax + 103596: 8b 40 04 mov 0x4(%eax),%eax + while ((le = list_next(le)) != &free_list) { + 103599: 89 45 ec mov %eax,-0x14(%ebp) + 10359c: 81 7d ec e0 ce 11 00 cmpl $0x11cee0,-0x14(%ebp) + 1035a3: 0f 85 7a ff ff ff jne 103523 + } + // 确保总属性值与空闲页面数量匹配 + assert(total == nr_free_pages()); + 1035a9: e8 96 09 00 00 call 103f44 + 1035ae: 8b 55 f0 mov -0x10(%ebp),%edx + 1035b1: 39 d0 cmp %edx,%eax + 1035b3: 74 24 je 1035d9 + 1035b5: c7 44 24 0c 8e 69 10 movl $0x10698e,0xc(%esp) + 1035bc: 00 + 1035bd: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 1035c4: 00 + 1035c5: c7 44 24 04 30 01 00 movl $0x130,0x4(%esp) + 1035cc: 00 + 1035cd: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 1035d4: e8 5a d6 ff ff call 100c33 <__panic> + // 调用 basic_check 以验证基本的内存管理功能 + basic_check(); + 1035d9: e8 e5 f9 ff ff call 102fc3 + // 分配 5 个页面 + struct Page *p0 = alloc_pages(5), *p1, *p2; + 1035de: c7 04 24 05 00 00 00 movl $0x5,(%esp) + 1035e5: e8 eb 08 00 00 call 103ed5 + 1035ea: 89 45 e8 mov %eax,-0x18(%ebp) + assert(p0 != NULL);// 确保成功分配 + 1035ed: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 1035f1: 75 24 jne 103617 + 1035f3: c7 44 24 0c a7 69 10 movl $0x1069a7,0xc(%esp) + 1035fa: 00 + 1035fb: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 103602: 00 + 103603: c7 44 24 04 35 01 00 movl $0x135,0x4(%esp) + 10360a: 00 + 10360b: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 103612: e8 1c d6 ff ff call 100c33 <__panic> + assert(!PageProperty(p0));// 确保分配的页面不带属性 + 103617: 8b 45 e8 mov -0x18(%ebp),%eax + 10361a: 83 c0 04 add $0x4,%eax + 10361d: c7 45 c0 01 00 00 00 movl $0x1,-0x40(%ebp) + 103624: 89 45 bc mov %eax,-0x44(%ebp) + asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr)); + 103627: 8b 45 bc mov -0x44(%ebp),%eax + 10362a: 8b 55 c0 mov -0x40(%ebp),%edx + 10362d: 0f a3 10 bt %edx,(%eax) + 103630: 19 c0 sbb %eax,%eax + 103632: 89 45 b8 mov %eax,-0x48(%ebp) + return oldbit != 0; + 103635: 83 7d b8 00 cmpl $0x0,-0x48(%ebp) + 103639: 0f 95 c0 setne %al + 10363c: 0f b6 c0 movzbl %al,%eax + 10363f: 85 c0 test %eax,%eax + 103641: 74 24 je 103667 + 103643: c7 44 24 0c b2 69 10 movl $0x1069b2,0xc(%esp) + 10364a: 00 + 10364b: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 103652: 00 + 103653: c7 44 24 04 36 01 00 movl $0x136,0x4(%esp) + 10365a: 00 + 10365b: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 103662: e8 cc d5 ff ff call 100c33 <__panic> + // 初始化并检查空闲列表 + list_entry_t free_list_store = free_list; + 103667: a1 e0 ce 11 00 mov 0x11cee0,%eax + 10366c: 8b 15 e4 ce 11 00 mov 0x11cee4,%edx + 103672: 89 45 80 mov %eax,-0x80(%ebp) + 103675: 89 55 84 mov %edx,-0x7c(%ebp) + 103678: c7 45 b0 e0 ce 11 00 movl $0x11cee0,-0x50(%ebp) + elm->prev = elm->next = elm; + 10367f: 8b 45 b0 mov -0x50(%ebp),%eax + 103682: 8b 55 b0 mov -0x50(%ebp),%edx + 103685: 89 50 04 mov %edx,0x4(%eax) + 103688: 8b 45 b0 mov -0x50(%ebp),%eax + 10368b: 8b 50 04 mov 0x4(%eax),%edx + 10368e: 8b 45 b0 mov -0x50(%ebp),%eax + 103691: 89 10 mov %edx,(%eax) +} + 103693: 90 nop + 103694: c7 45 b4 e0 ce 11 00 movl $0x11cee0,-0x4c(%ebp) + return list->next == list; + 10369b: 8b 45 b4 mov -0x4c(%ebp),%eax + 10369e: 8b 40 04 mov 0x4(%eax),%eax + 1036a1: 39 45 b4 cmp %eax,-0x4c(%ebp) + 1036a4: 0f 94 c0 sete %al + 1036a7: 0f b6 c0 movzbl %al,%eax + list_init(&free_list); + assert(list_empty(&free_list));// 确保空闲列表为空 + 1036aa: 85 c0 test %eax,%eax + 1036ac: 75 24 jne 1036d2 + 1036ae: c7 44 24 0c 07 69 10 movl $0x106907,0xc(%esp) + 1036b5: 00 + 1036b6: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 1036bd: 00 + 1036be: c7 44 24 04 3a 01 00 movl $0x13a,0x4(%esp) + 1036c5: 00 + 1036c6: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 1036cd: e8 61 d5 ff ff call 100c33 <__panic> + assert(alloc_page() == NULL);// 确保没有页面可分配 + 1036d2: c7 04 24 01 00 00 00 movl $0x1,(%esp) + 1036d9: e8 f7 07 00 00 call 103ed5 + 1036de: 85 c0 test %eax,%eax + 1036e0: 74 24 je 103706 + 1036e2: c7 44 24 0c 1e 69 10 movl $0x10691e,0xc(%esp) + 1036e9: 00 + 1036ea: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 1036f1: 00 + 1036f2: c7 44 24 04 3b 01 00 movl $0x13b,0x4(%esp) + 1036f9: 00 + 1036fa: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 103701: e8 2d d5 ff ff call 100c33 <__panic> + + unsigned int nr_free_store = nr_free;// 保存当前空闲页数 + 103706: a1 e8 ce 11 00 mov 0x11cee8,%eax + 10370b: 89 45 e4 mov %eax,-0x1c(%ebp) + nr_free = 0;// 将空闲页数设为 0 + 10370e: c7 05 e8 ce 11 00 00 movl $0x0,0x11cee8 + 103715: 00 00 00 +// 释放 3 个页面并确保分配页面时没有足够的空闲页 + free_pages(p0 + 2, 3); + 103718: 8b 45 e8 mov -0x18(%ebp),%eax + 10371b: 83 c0 28 add $0x28,%eax + 10371e: c7 44 24 04 03 00 00 movl $0x3,0x4(%esp) + 103725: 00 + 103726: 89 04 24 mov %eax,(%esp) + 103729: e8 e1 07 00 00 call 103f0f + assert(alloc_pages(4) == NULL);// 确保无法分配 4 个页面 + 10372e: c7 04 24 04 00 00 00 movl $0x4,(%esp) + 103735: e8 9b 07 00 00 call 103ed5 + 10373a: 85 c0 test %eax,%eax + 10373c: 74 24 je 103762 + 10373e: c7 44 24 0c c4 69 10 movl $0x1069c4,0xc(%esp) + 103745: 00 + 103746: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 10374d: 00 + 10374e: c7 44 24 04 41 01 00 movl $0x141,0x4(%esp) + 103755: 00 + 103756: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 10375d: e8 d1 d4 ff ff call 100c33 <__panic> + assert(PageProperty(p0 + 2) && p0[2].property == 3);// 检查页面属性 + 103762: 8b 45 e8 mov -0x18(%ebp),%eax + 103765: 83 c0 28 add $0x28,%eax + 103768: 83 c0 04 add $0x4,%eax + 10376b: c7 45 ac 01 00 00 00 movl $0x1,-0x54(%ebp) + 103772: 89 45 a8 mov %eax,-0x58(%ebp) + asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr)); + 103775: 8b 45 a8 mov -0x58(%ebp),%eax + 103778: 8b 55 ac mov -0x54(%ebp),%edx + 10377b: 0f a3 10 bt %edx,(%eax) + 10377e: 19 c0 sbb %eax,%eax + 103780: 89 45 a4 mov %eax,-0x5c(%ebp) + return oldbit != 0; + 103783: 83 7d a4 00 cmpl $0x0,-0x5c(%ebp) + 103787: 0f 95 c0 setne %al + 10378a: 0f b6 c0 movzbl %al,%eax + 10378d: 85 c0 test %eax,%eax + 10378f: 74 0e je 10379f + 103791: 8b 45 e8 mov -0x18(%ebp),%eax + 103794: 83 c0 28 add $0x28,%eax + 103797: 8b 40 08 mov 0x8(%eax),%eax + 10379a: 83 f8 03 cmp $0x3,%eax + 10379d: 74 24 je 1037c3 + 10379f: c7 44 24 0c dc 69 10 movl $0x1069dc,0xc(%esp) + 1037a6: 00 + 1037a7: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 1037ae: 00 + 1037af: c7 44 24 04 42 01 00 movl $0x142,0x4(%esp) + 1037b6: 00 + 1037b7: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 1037be: e8 70 d4 ff ff call 100c33 <__panic> + assert((p1 = alloc_pages(3)) != NULL);// 再次分配 3 个页面 + 1037c3: c7 04 24 03 00 00 00 movl $0x3,(%esp) + 1037ca: e8 06 07 00 00 call 103ed5 + 1037cf: 89 45 e0 mov %eax,-0x20(%ebp) + 1037d2: 83 7d e0 00 cmpl $0x0,-0x20(%ebp) + 1037d6: 75 24 jne 1037fc + 1037d8: c7 44 24 0c 08 6a 10 movl $0x106a08,0xc(%esp) + 1037df: 00 + 1037e0: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 1037e7: 00 + 1037e8: c7 44 24 04 43 01 00 movl $0x143,0x4(%esp) + 1037ef: 00 + 1037f0: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 1037f7: e8 37 d4 ff ff call 100c33 <__panic> + assert(alloc_page() == NULL);// 确保没有页面可分配 + 1037fc: c7 04 24 01 00 00 00 movl $0x1,(%esp) + 103803: e8 cd 06 00 00 call 103ed5 + 103808: 85 c0 test %eax,%eax + 10380a: 74 24 je 103830 + 10380c: c7 44 24 0c 1e 69 10 movl $0x10691e,0xc(%esp) + 103813: 00 + 103814: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 10381b: 00 + 10381c: c7 44 24 04 44 01 00 movl $0x144,0x4(%esp) + 103823: 00 + 103824: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 10382b: e8 03 d4 ff ff call 100c33 <__panic> + assert(p0 + 2 == p1);// 确保分配的页面是释放的页面 + 103830: 8b 45 e8 mov -0x18(%ebp),%eax + 103833: 83 c0 28 add $0x28,%eax + 103836: 39 45 e0 cmp %eax,-0x20(%ebp) + 103839: 74 24 je 10385f + 10383b: c7 44 24 0c 26 6a 10 movl $0x106a26,0xc(%esp) + 103842: 00 + 103843: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 10384a: 00 + 10384b: c7 44 24 04 45 01 00 movl $0x145,0x4(%esp) + 103852: 00 + 103853: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 10385a: e8 d4 d3 ff ff call 100c33 <__panic> + + p2 = p0 + 1; // 设置 p2 为 p0 的下一个页面 + 10385f: 8b 45 e8 mov -0x18(%ebp),%eax + 103862: 83 c0 14 add $0x14,%eax + 103865: 89 45 dc mov %eax,-0x24(%ebp) + free_page(p0);// 释放 p0 页面 + 103868: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) + 10386f: 00 + 103870: 8b 45 e8 mov -0x18(%ebp),%eax + 103873: 89 04 24 mov %eax,(%esp) + 103876: e8 94 06 00 00 call 103f0f + free_pages(p1, 3);// 释放 p1 指向的页面 + 10387b: c7 44 24 04 03 00 00 movl $0x3,0x4(%esp) + 103882: 00 + 103883: 8b 45 e0 mov -0x20(%ebp),%eax + 103886: 89 04 24 mov %eax,(%esp) + 103889: e8 81 06 00 00 call 103f0f + assert(PageProperty(p0) && p0->property == 1); // 检查 p0 属性 + 10388e: 8b 45 e8 mov -0x18(%ebp),%eax + 103891: 83 c0 04 add $0x4,%eax + 103894: c7 45 a0 01 00 00 00 movl $0x1,-0x60(%ebp) + 10389b: 89 45 9c mov %eax,-0x64(%ebp) + asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr)); + 10389e: 8b 45 9c mov -0x64(%ebp),%eax + 1038a1: 8b 55 a0 mov -0x60(%ebp),%edx + 1038a4: 0f a3 10 bt %edx,(%eax) + 1038a7: 19 c0 sbb %eax,%eax + 1038a9: 89 45 98 mov %eax,-0x68(%ebp) + return oldbit != 0; + 1038ac: 83 7d 98 00 cmpl $0x0,-0x68(%ebp) + 1038b0: 0f 95 c0 setne %al + 1038b3: 0f b6 c0 movzbl %al,%eax + 1038b6: 85 c0 test %eax,%eax + 1038b8: 74 0b je 1038c5 + 1038ba: 8b 45 e8 mov -0x18(%ebp),%eax + 1038bd: 8b 40 08 mov 0x8(%eax),%eax + 1038c0: 83 f8 01 cmp $0x1,%eax + 1038c3: 74 24 je 1038e9 + 1038c5: c7 44 24 0c 34 6a 10 movl $0x106a34,0xc(%esp) + 1038cc: 00 + 1038cd: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 1038d4: 00 + 1038d5: c7 44 24 04 4a 01 00 movl $0x14a,0x4(%esp) + 1038dc: 00 + 1038dd: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 1038e4: e8 4a d3 ff ff call 100c33 <__panic> + assert(PageProperty(p1) && p1->property == 3); // 检查 p1 属性 + 1038e9: 8b 45 e0 mov -0x20(%ebp),%eax + 1038ec: 83 c0 04 add $0x4,%eax + 1038ef: c7 45 94 01 00 00 00 movl $0x1,-0x6c(%ebp) + 1038f6: 89 45 90 mov %eax,-0x70(%ebp) + asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr)); + 1038f9: 8b 45 90 mov -0x70(%ebp),%eax + 1038fc: 8b 55 94 mov -0x6c(%ebp),%edx + 1038ff: 0f a3 10 bt %edx,(%eax) + 103902: 19 c0 sbb %eax,%eax + 103904: 89 45 8c mov %eax,-0x74(%ebp) + return oldbit != 0; + 103907: 83 7d 8c 00 cmpl $0x0,-0x74(%ebp) + 10390b: 0f 95 c0 setne %al + 10390e: 0f b6 c0 movzbl %al,%eax + 103911: 85 c0 test %eax,%eax + 103913: 74 0b je 103920 + 103915: 8b 45 e0 mov -0x20(%ebp),%eax + 103918: 8b 40 08 mov 0x8(%eax),%eax + 10391b: 83 f8 03 cmp $0x3,%eax + 10391e: 74 24 je 103944 + 103920: c7 44 24 0c 5c 6a 10 movl $0x106a5c,0xc(%esp) + 103927: 00 + 103928: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 10392f: 00 + 103930: c7 44 24 04 4b 01 00 movl $0x14b,0x4(%esp) + 103937: 00 + 103938: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 10393f: e8 ef d2 ff ff call 100c33 <__panic> +// 确保重分配的页面是之前释放的页面 + assert((p0 = alloc_page()) == p2 - 1); + 103944: c7 04 24 01 00 00 00 movl $0x1,(%esp) + 10394b: e8 85 05 00 00 call 103ed5 + 103950: 89 45 e8 mov %eax,-0x18(%ebp) + 103953: 8b 45 dc mov -0x24(%ebp),%eax + 103956: 83 e8 14 sub $0x14,%eax + 103959: 39 45 e8 cmp %eax,-0x18(%ebp) + 10395c: 74 24 je 103982 + 10395e: c7 44 24 0c 82 6a 10 movl $0x106a82,0xc(%esp) + 103965: 00 + 103966: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 10396d: 00 + 10396e: c7 44 24 04 4d 01 00 movl $0x14d,0x4(%esp) + 103975: 00 + 103976: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 10397d: e8 b1 d2 ff ff call 100c33 <__panic> + free_page(p0);// 释放分配的页面 + 103982: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) + 103989: 00 + 10398a: 8b 45 e8 mov -0x18(%ebp),%eax + 10398d: 89 04 24 mov %eax,(%esp) + 103990: e8 7a 05 00 00 call 103f0f + assert((p0 = alloc_pages(2)) == p2 + 1);// 分配 2 个页面并检查 + 103995: c7 04 24 02 00 00 00 movl $0x2,(%esp) + 10399c: e8 34 05 00 00 call 103ed5 + 1039a1: 89 45 e8 mov %eax,-0x18(%ebp) + 1039a4: 8b 45 dc mov -0x24(%ebp),%eax + 1039a7: 83 c0 14 add $0x14,%eax + 1039aa: 39 45 e8 cmp %eax,-0x18(%ebp) + 1039ad: 74 24 je 1039d3 + 1039af: c7 44 24 0c a0 6a 10 movl $0x106aa0,0xc(%esp) + 1039b6: 00 + 1039b7: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 1039be: 00 + 1039bf: c7 44 24 04 4f 01 00 movl $0x14f,0x4(%esp) + 1039c6: 00 + 1039c7: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 1039ce: e8 60 d2 ff ff call 100c33 <__panic> +// 释放页面并检查空闲状态 + free_pages(p0, 2); + 1039d3: c7 44 24 04 02 00 00 movl $0x2,0x4(%esp) + 1039da: 00 + 1039db: 8b 45 e8 mov -0x18(%ebp),%eax + 1039de: 89 04 24 mov %eax,(%esp) + 1039e1: e8 29 05 00 00 call 103f0f + free_page(p2); + 1039e6: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) + 1039ed: 00 + 1039ee: 8b 45 dc mov -0x24(%ebp),%eax + 1039f1: 89 04 24 mov %eax,(%esp) + 1039f4: e8 16 05 00 00 call 103f0f +// 再次分配 5 个页面 + assert((p0 = alloc_pages(5)) != NULL); + 1039f9: c7 04 24 05 00 00 00 movl $0x5,(%esp) + 103a00: e8 d0 04 00 00 call 103ed5 + 103a05: 89 45 e8 mov %eax,-0x18(%ebp) + 103a08: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 103a0c: 75 24 jne 103a32 + 103a0e: c7 44 24 0c c0 6a 10 movl $0x106ac0,0xc(%esp) + 103a15: 00 + 103a16: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 103a1d: 00 + 103a1e: c7 44 24 04 54 01 00 movl $0x154,0x4(%esp) + 103a25: 00 + 103a26: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 103a2d: e8 01 d2 ff ff call 100c33 <__panic> + assert(alloc_page() == NULL);// 确保没有额外页面可分配 + 103a32: c7 04 24 01 00 00 00 movl $0x1,(%esp) + 103a39: e8 97 04 00 00 call 103ed5 + 103a3e: 85 c0 test %eax,%eax + 103a40: 74 24 je 103a66 + 103a42: c7 44 24 0c 1e 69 10 movl $0x10691e,0xc(%esp) + 103a49: 00 + 103a4a: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 103a51: 00 + 103a52: c7 44 24 04 55 01 00 movl $0x155,0x4(%esp) + 103a59: 00 + 103a5a: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 103a61: e8 cd d1 ff ff call 100c33 <__panic> + + assert(nr_free == 0);// 确保空闲页数为 0 + 103a66: a1 e8 ce 11 00 mov 0x11cee8,%eax + 103a6b: 85 c0 test %eax,%eax + 103a6d: 74 24 je 103a93 + 103a6f: c7 44 24 0c 71 69 10 movl $0x106971,0xc(%esp) + 103a76: 00 + 103a77: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 103a7e: 00 + 103a7f: c7 44 24 04 57 01 00 movl $0x157,0x4(%esp) + 103a86: 00 + 103a87: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 103a8e: e8 a0 d1 ff ff call 100c33 <__panic> + nr_free = nr_free_store;// 恢复空闲页数 + 103a93: 8b 45 e4 mov -0x1c(%ebp),%eax + 103a96: a3 e8 ce 11 00 mov %eax,0x11cee8 +// 恢复空闲列表状态 + free_list = free_list_store; + 103a9b: 8b 45 80 mov -0x80(%ebp),%eax + 103a9e: 8b 55 84 mov -0x7c(%ebp),%edx + 103aa1: a3 e0 ce 11 00 mov %eax,0x11cee0 + 103aa6: 89 15 e4 ce 11 00 mov %edx,0x11cee4 + free_pages(p0, 5);// 释放所有分配的页面 + 103aac: c7 44 24 04 05 00 00 movl $0x5,0x4(%esp) + 103ab3: 00 + 103ab4: 8b 45 e8 mov -0x18(%ebp),%eax + 103ab7: 89 04 24 mov %eax,(%esp) + 103aba: e8 50 04 00 00 call 103f0f + // 验证空闲列表的一致性 + le = &free_list; + 103abf: c7 45 ec e0 ce 11 00 movl $0x11cee0,-0x14(%ebp) + while ((le = list_next(le)) != &free_list) { + 103ac6: eb 5a jmp 103b22 + assert(le->next->prev == le && le->prev->next == le);// 验证双向链表 + 103ac8: 8b 45 ec mov -0x14(%ebp),%eax + 103acb: 8b 40 04 mov 0x4(%eax),%eax + 103ace: 8b 00 mov (%eax),%eax + 103ad0: 39 45 ec cmp %eax,-0x14(%ebp) + 103ad3: 75 0d jne 103ae2 + 103ad5: 8b 45 ec mov -0x14(%ebp),%eax + 103ad8: 8b 00 mov (%eax),%eax + 103ada: 8b 40 04 mov 0x4(%eax),%eax + 103add: 39 45 ec cmp %eax,-0x14(%ebp) + 103ae0: 74 24 je 103b06 + 103ae2: c7 44 24 0c e0 6a 10 movl $0x106ae0,0xc(%esp) + 103ae9: 00 + 103aea: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 103af1: 00 + 103af2: c7 44 24 04 5f 01 00 movl $0x15f,0x4(%esp) + 103af9: 00 + 103afa: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 103b01: e8 2d d1 ff ff call 100c33 <__panic> + struct Page *p = le2page(le, page_link);// 更新计数和总属性值 + 103b06: 8b 45 ec mov -0x14(%ebp),%eax + 103b09: 83 e8 0c sub $0xc,%eax + 103b0c: 89 45 d8 mov %eax,-0x28(%ebp) + count --, total -= p->property; + 103b0f: ff 4d f4 decl -0xc(%ebp) + 103b12: 8b 55 f0 mov -0x10(%ebp),%edx + 103b15: 8b 45 d8 mov -0x28(%ebp),%eax + 103b18: 8b 48 08 mov 0x8(%eax),%ecx + 103b1b: 89 d0 mov %edx,%eax + 103b1d: 29 c8 sub %ecx,%eax + 103b1f: 89 45 f0 mov %eax,-0x10(%ebp) + 103b22: 8b 45 ec mov -0x14(%ebp),%eax + 103b25: 89 45 88 mov %eax,-0x78(%ebp) + return listelm->next; + 103b28: 8b 45 88 mov -0x78(%ebp),%eax + 103b2b: 8b 40 04 mov 0x4(%eax),%eax + while ((le = list_next(le)) != &free_list) { + 103b2e: 89 45 ec mov %eax,-0x14(%ebp) + 103b31: 81 7d ec e0 ce 11 00 cmpl $0x11cee0,-0x14(%ebp) + 103b38: 75 8e jne 103ac8 + } + assert(count == 0);// 确保所有页面都已处理 + 103b3a: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) + 103b3e: 74 24 je 103b64 + 103b40: c7 44 24 0c 0d 6b 10 movl $0x106b0d,0xc(%esp) + 103b47: 00 + 103b48: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 103b4f: 00 + 103b50: c7 44 24 04 63 01 00 movl $0x163,0x4(%esp) + 103b57: 00 + 103b58: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 103b5f: e8 cf d0 ff ff call 100c33 <__panic> + assert(total == 0);// 确保总属性值为 0 + 103b64: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) + 103b68: 74 24 je 103b8e + 103b6a: c7 44 24 0c 18 6b 10 movl $0x106b18,0xc(%esp) + 103b71: 00 + 103b72: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 103b79: 00 + 103b7a: c7 44 24 04 64 01 00 movl $0x164,0x4(%esp) + 103b81: 00 + 103b82: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 103b89: e8 a5 d0 ff ff call 100c33 <__panic> +} + 103b8e: 90 nop + 103b8f: 89 ec mov %ebp,%esp + 103b91: 5d pop %ebp + 103b92: c3 ret + +00103b93 : +page2ppn(struct Page *page) { + 103b93: 55 push %ebp + 103b94: 89 e5 mov %esp,%ebp + return page - pages; + 103b96: 8b 15 00 cf 11 00 mov 0x11cf00,%edx + 103b9c: 8b 45 08 mov 0x8(%ebp),%eax + 103b9f: 29 d0 sub %edx,%eax + 103ba1: c1 f8 02 sar $0x2,%eax + 103ba4: 69 c0 cd cc cc cc imul $0xcccccccd,%eax,%eax +} + 103baa: 5d pop %ebp + 103bab: c3 ret + +00103bac : +page2pa(struct Page *page) { + 103bac: 55 push %ebp + 103bad: 89 e5 mov %esp,%ebp + 103baf: 83 ec 04 sub $0x4,%esp + return page2ppn(page) << PGSHIFT; + 103bb2: 8b 45 08 mov 0x8(%ebp),%eax + 103bb5: 89 04 24 mov %eax,(%esp) + 103bb8: e8 d6 ff ff ff call 103b93 + 103bbd: c1 e0 0c shl $0xc,%eax +} + 103bc0: 89 ec mov %ebp,%esp + 103bc2: 5d pop %ebp + 103bc3: c3 ret + +00103bc4 : +pa2page(uintptr_t pa) { + 103bc4: 55 push %ebp + 103bc5: 89 e5 mov %esp,%ebp + 103bc7: 83 ec 18 sub $0x18,%esp + if (PPN(pa) >= npage) { + 103bca: 8b 45 08 mov 0x8(%ebp),%eax + 103bcd: c1 e8 0c shr $0xc,%eax + 103bd0: 89 c2 mov %eax,%edx + 103bd2: a1 04 cf 11 00 mov 0x11cf04,%eax + 103bd7: 39 c2 cmp %eax,%edx + 103bd9: 72 1c jb 103bf7 + panic("pa2page called with invalid pa"); + 103bdb: c7 44 24 08 54 6b 10 movl $0x106b54,0x8(%esp) + 103be2: 00 + 103be3: c7 44 24 04 5a 00 00 movl $0x5a,0x4(%esp) + 103bea: 00 + 103beb: c7 04 24 73 6b 10 00 movl $0x106b73,(%esp) + 103bf2: e8 3c d0 ff ff call 100c33 <__panic> + return &pages[PPN(pa)]; + 103bf7: 8b 0d 00 cf 11 00 mov 0x11cf00,%ecx + 103bfd: 8b 45 08 mov 0x8(%ebp),%eax + 103c00: c1 e8 0c shr $0xc,%eax + 103c03: 89 c2 mov %eax,%edx + 103c05: 89 d0 mov %edx,%eax + 103c07: c1 e0 02 shl $0x2,%eax + 103c0a: 01 d0 add %edx,%eax + 103c0c: c1 e0 02 shl $0x2,%eax + 103c0f: 01 c8 add %ecx,%eax +} + 103c11: 89 ec mov %ebp,%esp + 103c13: 5d pop %ebp + 103c14: c3 ret + +00103c15 : +page2kva(struct Page *page) { + 103c15: 55 push %ebp + 103c16: 89 e5 mov %esp,%ebp + 103c18: 83 ec 28 sub $0x28,%esp + return KADDR(page2pa(page)); + 103c1b: 8b 45 08 mov 0x8(%ebp),%eax + 103c1e: 89 04 24 mov %eax,(%esp) + 103c21: e8 86 ff ff ff call 103bac + 103c26: 89 45 f4 mov %eax,-0xc(%ebp) + 103c29: 8b 45 f4 mov -0xc(%ebp),%eax + 103c2c: c1 e8 0c shr $0xc,%eax + 103c2f: 89 45 f0 mov %eax,-0x10(%ebp) + 103c32: a1 04 cf 11 00 mov 0x11cf04,%eax + 103c37: 39 45 f0 cmp %eax,-0x10(%ebp) + 103c3a: 72 23 jb 103c5f + 103c3c: 8b 45 f4 mov -0xc(%ebp),%eax + 103c3f: 89 44 24 0c mov %eax,0xc(%esp) + 103c43: c7 44 24 08 84 6b 10 movl $0x106b84,0x8(%esp) + 103c4a: 00 + 103c4b: c7 44 24 04 61 00 00 movl $0x61,0x4(%esp) + 103c52: 00 + 103c53: c7 04 24 73 6b 10 00 movl $0x106b73,(%esp) + 103c5a: e8 d4 cf ff ff call 100c33 <__panic> + 103c5f: 8b 45 f4 mov -0xc(%ebp),%eax + 103c62: 2d 00 00 00 40 sub $0x40000000,%eax +} + 103c67: 89 ec mov %ebp,%esp + 103c69: 5d pop %ebp + 103c6a: c3 ret + +00103c6b : +pte2page(pte_t pte) { + 103c6b: 55 push %ebp + 103c6c: 89 e5 mov %esp,%ebp + 103c6e: 83 ec 18 sub $0x18,%esp + if (!(pte & PTE_P)) { + 103c71: 8b 45 08 mov 0x8(%ebp),%eax + 103c74: 83 e0 01 and $0x1,%eax + 103c77: 85 c0 test %eax,%eax + 103c79: 75 1c jne 103c97 + panic("pte2page called with invalid pte"); + 103c7b: c7 44 24 08 a8 6b 10 movl $0x106ba8,0x8(%esp) + 103c82: 00 + 103c83: c7 44 24 04 6c 00 00 movl $0x6c,0x4(%esp) + 103c8a: 00 + 103c8b: c7 04 24 73 6b 10 00 movl $0x106b73,(%esp) + 103c92: e8 9c cf ff ff call 100c33 <__panic> + return pa2page(PTE_ADDR(pte)); + 103c97: 8b 45 08 mov 0x8(%ebp),%eax + 103c9a: 25 00 f0 ff ff and $0xfffff000,%eax + 103c9f: 89 04 24 mov %eax,(%esp) + 103ca2: e8 1d ff ff ff call 103bc4 +} + 103ca7: 89 ec mov %ebp,%esp + 103ca9: 5d pop %ebp + 103caa: c3 ret + +00103cab : +pde2page(pde_t pde) { + 103cab: 55 push %ebp + 103cac: 89 e5 mov %esp,%ebp + 103cae: 83 ec 18 sub $0x18,%esp + return pa2page(PDE_ADDR(pde)); + 103cb1: 8b 45 08 mov 0x8(%ebp),%eax + 103cb4: 25 00 f0 ff ff and $0xfffff000,%eax + 103cb9: 89 04 24 mov %eax,(%esp) + 103cbc: e8 03 ff ff ff call 103bc4 +} + 103cc1: 89 ec mov %ebp,%esp + 103cc3: 5d pop %ebp + 103cc4: c3 ret + +00103cc5 : +page_ref(struct Page *page) { + 103cc5: 55 push %ebp + 103cc6: 89 e5 mov %esp,%ebp + return page->ref; + 103cc8: 8b 45 08 mov 0x8(%ebp),%eax + 103ccb: 8b 00 mov (%eax),%eax +} + 103ccd: 5d pop %ebp + 103cce: c3 ret + +00103ccf : +set_page_ref(struct Page *page, int val) { + 103ccf: 55 push %ebp + 103cd0: 89 e5 mov %esp,%ebp + page->ref = val; + 103cd2: 8b 45 08 mov 0x8(%ebp),%eax + 103cd5: 8b 55 0c mov 0xc(%ebp),%edx + 103cd8: 89 10 mov %edx,(%eax) +} + 103cda: 90 nop + 103cdb: 5d pop %ebp + 103cdc: c3 ret + +00103cdd : + +static inline int +page_ref_inc(struct Page *page) { + 103cdd: 55 push %ebp + 103cde: 89 e5 mov %esp,%ebp + page->ref += 1; + 103ce0: 8b 45 08 mov 0x8(%ebp),%eax + 103ce3: 8b 00 mov (%eax),%eax + 103ce5: 8d 50 01 lea 0x1(%eax),%edx + 103ce8: 8b 45 08 mov 0x8(%ebp),%eax + 103ceb: 89 10 mov %edx,(%eax) + return page->ref; + 103ced: 8b 45 08 mov 0x8(%ebp),%eax + 103cf0: 8b 00 mov (%eax),%eax +} + 103cf2: 5d pop %ebp + 103cf3: c3 ret + +00103cf4 : + +static inline int +page_ref_dec(struct Page *page) { + 103cf4: 55 push %ebp + 103cf5: 89 e5 mov %esp,%ebp + page->ref -= 1; + 103cf7: 8b 45 08 mov 0x8(%ebp),%eax + 103cfa: 8b 00 mov (%eax),%eax + 103cfc: 8d 50 ff lea -0x1(%eax),%edx + 103cff: 8b 45 08 mov 0x8(%ebp),%eax + 103d02: 89 10 mov %edx,(%eax) + return page->ref; + 103d04: 8b 45 08 mov 0x8(%ebp),%eax + 103d07: 8b 00 mov (%eax),%eax +} + 103d09: 5d pop %ebp + 103d0a: c3 ret + +00103d0b <__intr_save>: +__intr_save(void) { + 103d0b: 55 push %ebp + 103d0c: 89 e5 mov %esp,%ebp + 103d0e: 83 ec 18 sub $0x18,%esp + asm volatile ("pushfl; popl %0" : "=r" (eflags)); + 103d11: 9c pushf + 103d12: 58 pop %eax + 103d13: 89 45 f4 mov %eax,-0xc(%ebp) + return eflags; + 103d16: 8b 45 f4 mov -0xc(%ebp),%eax + if (read_eflags() & FL_IF) { + 103d19: 25 00 02 00 00 and $0x200,%eax + 103d1e: 85 c0 test %eax,%eax + 103d20: 74 0c je 103d2e <__intr_save+0x23> + intr_disable(); + 103d22: e8 65 d9 ff ff call 10168c + return 1; + 103d27: b8 01 00 00 00 mov $0x1,%eax + 103d2c: eb 05 jmp 103d33 <__intr_save+0x28> + return 0; + 103d2e: b8 00 00 00 00 mov $0x0,%eax +} + 103d33: 89 ec mov %ebp,%esp + 103d35: 5d pop %ebp + 103d36: c3 ret + +00103d37 <__intr_restore>: +__intr_restore(bool flag) { + 103d37: 55 push %ebp + 103d38: 89 e5 mov %esp,%ebp + 103d3a: 83 ec 08 sub $0x8,%esp + if (flag) { + 103d3d: 83 7d 08 00 cmpl $0x0,0x8(%ebp) + 103d41: 74 05 je 103d48 <__intr_restore+0x11> + intr_enable(); + 103d43: e8 3c d9 ff ff call 101684 +} + 103d48: 90 nop + 103d49: 89 ec mov %ebp,%esp + 103d4b: 5d pop %ebp + 103d4c: c3 ret + +00103d4d : + * data/code segement registers for kernel. + * lgdt - 加载全局描述符表寄存器并重置内核的数据/代码段寄存器。 + * */ +//定义了一个静态内联函数 lgdt,接收一个指向伪描述符(struct pseudodesc)的指针 pd +static inline void +lgdt(struct pseudodesc *pd) { + 103d4d: 55 push %ebp + 103d4e: 89 e5 mov %esp,%ebp + asm volatile ("lgdt (%0)" :: "r" (pd));//这行汇编代码使用 lgdt 指令加载 GDT。%0 被替换为指向 pd 的指针,告诉处理器 GDT 的地址。 + 103d50: 8b 45 08 mov 0x8(%ebp),%eax + 103d53: 0f 01 10 lgdtl (%eax) + asm volatile ("movw %%ax, %%gs" :: "a" (USER_DS));//将 USER_DS(用户数据段)的值移动到 gs 段寄存器。 + 103d56: b8 23 00 00 00 mov $0x23,%eax + 103d5b: 8e e8 mov %eax,%gs + asm volatile ("movw %%ax, %%fs" :: "a" (USER_DS));//将 USER_DS 的值移动到 fs 段寄存器。 + 103d5d: b8 23 00 00 00 mov $0x23,%eax + 103d62: 8e e0 mov %eax,%fs + asm volatile ("movw %%ax, %%es" :: "a" (KERNEL_DS));//将 KERNEL_DS(内核数据段)的值移动到 es 段寄存器。 + 103d64: b8 10 00 00 00 mov $0x10,%eax + 103d69: 8e c0 mov %eax,%es + asm volatile ("movw %%ax, %%ds" :: "a" (KERNEL_DS));//将 KERNEL_DS 的值移动到 ds 段寄存器 + 103d6b: b8 10 00 00 00 mov $0x10,%eax + 103d70: 8e d8 mov %eax,%ds + asm volatile ("movw %%ax, %%ss" :: "a" (KERNEL_DS));//将 KERNEL_DS 的值移动到 ss 段寄存器 + 103d72: b8 10 00 00 00 mov $0x10,%eax + 103d77: 8e d0 mov %eax,%ss + // reload cs + //通过 ljmp 指令重新加载代码段寄存器 cs,并跳转到标签 1。 + asm volatile ("ljmp %0, $1f\n 1:\n" :: "i" (KERNEL_CS)); + 103d79: ea 80 3d 10 00 08 00 ljmp $0x8,$0x103d80 +} + 103d80: 90 nop + 103d81: 5d pop %ebp + 103d82: c3 ret + +00103d83 : + * load_esp0 - 修改默认任务状态段中的 ESP0,以便在从用户态陷入内核态时能够使用不同的内核栈。 + * */ +//uintptr_t esp0:这是新的堆栈指针,通常指向内核栈的顶部。 +//修改当前任务状态段(TSS)中的 ESP0 值。ESP0 是在从用户态切换到内核态时,CPU 使用的内核栈指针。 +void +load_esp0(uintptr_t esp0) { + 103d83: 55 push %ebp + 103d84: 89 e5 mov %esp,%ebp + ts.ts_esp0 = esp0; + 103d86: 8b 45 08 mov 0x8(%ebp),%eax + 103d89: a3 24 cf 11 00 mov %eax,0x11cf24 +} + 103d8e: 90 nop + 103d8f: 5d pop %ebp + 103d90: c3 ret + +00103d91 : + +/* gdt_init - initialize the default GDT and TSS */ +/* gdt_init - 初始化默认的 GDT 和 TSS */ +static void +gdt_init(void) { + 103d91: 55 push %ebp + 103d92: 89 e5 mov %esp,%ebp + 103d94: 83 ec 14 sub $0x14,%esp + // 设置启动内核栈和默认的 SS0 + // set boot kernel stack and default SS0 + load_esp0((uintptr_t)bootstacktop); + 103d97: b8 00 90 11 00 mov $0x119000,%eax + 103d9c: 89 04 24 mov %eax,(%esp) + 103d9f: e8 df ff ff ff call 103d83 + ts.ts_ss0 = KERNEL_DS; + 103da4: 66 c7 05 28 cf 11 00 movw $0x10,0x11cf28 + 103dab: 10 00 + // 初始化 GDT 中的 TSS 字段 + // initialize the TSS filed of the gdt + gdt[SEG_TSS] = SEGTSS(STS_T32A, (uintptr_t)&ts, sizeof(ts), DPL_KERNEL); + 103dad: 66 c7 05 28 9a 11 00 movw $0x68,0x119a28 + 103db4: 68 00 + 103db6: b8 20 cf 11 00 mov $0x11cf20,%eax + 103dbb: 0f b7 c0 movzwl %ax,%eax + 103dbe: 66 a3 2a 9a 11 00 mov %ax,0x119a2a + 103dc4: b8 20 cf 11 00 mov $0x11cf20,%eax + 103dc9: c1 e8 10 shr $0x10,%eax + 103dcc: a2 2c 9a 11 00 mov %al,0x119a2c + 103dd1: 0f b6 05 2d 9a 11 00 movzbl 0x119a2d,%eax + 103dd8: 24 f0 and $0xf0,%al + 103dda: 0c 09 or $0x9,%al + 103ddc: a2 2d 9a 11 00 mov %al,0x119a2d + 103de1: 0f b6 05 2d 9a 11 00 movzbl 0x119a2d,%eax + 103de8: 24 ef and $0xef,%al + 103dea: a2 2d 9a 11 00 mov %al,0x119a2d + 103def: 0f b6 05 2d 9a 11 00 movzbl 0x119a2d,%eax + 103df6: 24 9f and $0x9f,%al + 103df8: a2 2d 9a 11 00 mov %al,0x119a2d + 103dfd: 0f b6 05 2d 9a 11 00 movzbl 0x119a2d,%eax + 103e04: 0c 80 or $0x80,%al + 103e06: a2 2d 9a 11 00 mov %al,0x119a2d + 103e0b: 0f b6 05 2e 9a 11 00 movzbl 0x119a2e,%eax + 103e12: 24 f0 and $0xf0,%al + 103e14: a2 2e 9a 11 00 mov %al,0x119a2e + 103e19: 0f b6 05 2e 9a 11 00 movzbl 0x119a2e,%eax + 103e20: 24 ef and $0xef,%al + 103e22: a2 2e 9a 11 00 mov %al,0x119a2e + 103e27: 0f b6 05 2e 9a 11 00 movzbl 0x119a2e,%eax + 103e2e: 24 df and $0xdf,%al + 103e30: a2 2e 9a 11 00 mov %al,0x119a2e + 103e35: 0f b6 05 2e 9a 11 00 movzbl 0x119a2e,%eax + 103e3c: 0c 40 or $0x40,%al + 103e3e: a2 2e 9a 11 00 mov %al,0x119a2e + 103e43: 0f b6 05 2e 9a 11 00 movzbl 0x119a2e,%eax + 103e4a: 24 7f and $0x7f,%al + 103e4c: a2 2e 9a 11 00 mov %al,0x119a2e + 103e51: b8 20 cf 11 00 mov $0x11cf20,%eax + 103e56: c1 e8 18 shr $0x18,%eax + 103e59: a2 2f 9a 11 00 mov %al,0x119a2f + // 使用lgdt加载全局描述符表,更新所有段寄存器 + // reload all segment registers + lgdt(&gdt_pd); + 103e5e: c7 04 24 30 9a 11 00 movl $0x119a30,(%esp) + 103e65: e8 e3 fe ff ff call 103d4d + 103e6a: 66 c7 45 fe 28 00 movw $0x28,-0x2(%ebp) + asm volatile ("ltr %0" :: "r" (sel) : "memory"); + 103e70: 0f b7 45 fe movzwl -0x2(%ebp),%eax + 103e74: 0f 00 d8 ltr %ax +} + 103e77: 90 nop + // 加载 TSS,使 CPU 在进行特权级切换时能够正确使用 TSS。 + // load the TSS + ltr(GD_TSS); +} + 103e78: 90 nop + 103e79: 89 ec mov %ebp,%esp + 103e7b: 5d pop %ebp + 103e7c: c3 ret + +00103e7d : + +//init_pmm_manager - initialize a pmm_manager instance +//初始化一个 pmm_manager 实例 +static void +init_pmm_manager(void) { + 103e7d: 55 push %ebp + 103e7e: 89 e5 mov %esp,%ebp + 103e80: 83 ec 18 sub $0x18,%esp + //将 pmm_manager 指向默认的 PMM 管理器实例。 + pmm_manager = &default_pmm_manager; + 103e83: c7 05 0c cf 11 00 38 movl $0x106b38,0x11cf0c + 103e8a: 6b 10 00 + //使用 cprintf 打印当前内存管理器的名称。 + cprintf("memory management: %s\n", pmm_manager->name); + 103e8d: a1 0c cf 11 00 mov 0x11cf0c,%eax + 103e92: 8b 00 mov (%eax),%eax + 103e94: 89 44 24 04 mov %eax,0x4(%esp) + 103e98: c7 04 24 d4 6b 10 00 movl $0x106bd4,(%esp) + 103e9f: e8 c2 c4 ff ff call 100366 + //调用 PMM 管理器的初始化函数,以设置和准备内存管理的相关数据结构。 + pmm_manager->init(); + 103ea4: a1 0c cf 11 00 mov 0x11cf0c,%eax + 103ea9: 8b 40 04 mov 0x4(%eax),%eax + 103eac: ff d0 call *%eax +} + 103eae: 90 nop + 103eaf: 89 ec mov %ebp,%esp + 103eb1: 5d pop %ebp + 103eb2: c3 ret + +00103eb3 : + +//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) { + 103eb3: 55 push %ebp + 103eb4: 89 e5 mov %esp,%ebp + 103eb6: 83 ec 18 sub $0x18,%esp + pmm_manager->init_memmap(base, n); + 103eb9: a1 0c cf 11 00 mov 0x11cf0c,%eax + 103ebe: 8b 40 08 mov 0x8(%eax),%eax + 103ec1: 8b 55 0c mov 0xc(%ebp),%edx + 103ec4: 89 54 24 04 mov %edx,0x4(%esp) + 103ec8: 8b 55 08 mov 0x8(%ebp),%edx + 103ecb: 89 14 24 mov %edx,(%esp) + 103ece: ff d0 call *%eax +} + 103ed0: 90 nop + 103ed1: 89 ec mov %ebp,%esp + 103ed3: 5d pop %ebp + 103ed4: c3 ret + +00103ed5 : + +//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) { + 103ed5: 55 push %ebp + 103ed6: 89 e5 mov %esp,%ebp + 103ed8: 83 ec 28 sub $0x28,%esp + struct Page *page=NULL; + 103edb: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + bool intr_flag; + //使用 local_intr_save 保存当前的中断状态,以避免在分配内存时发生中断。 + local_intr_save(intr_flag); + 103ee2: e8 24 fe ff ff call 103d0b <__intr_save> + 103ee7: 89 45 f0 mov %eax,-0x10(%ebp) + { + //调用物理内存管理器的 alloc_pages 函数分配 n 页的内存。 + page = pmm_manager->alloc_pages(n); + 103eea: a1 0c cf 11 00 mov 0x11cf0c,%eax + 103eef: 8b 40 0c mov 0xc(%eax),%eax + 103ef2: 8b 55 08 mov 0x8(%ebp),%edx + 103ef5: 89 14 24 mov %edx,(%esp) + 103ef8: ff d0 call *%eax + 103efa: 89 45 f4 mov %eax,-0xc(%ebp) + } + //恢复之前保存的中断状态。 + local_intr_restore(intr_flag); + 103efd: 8b 45 f0 mov -0x10(%ebp),%eax + 103f00: 89 04 24 mov %eax,(%esp) + 103f03: e8 2f fe ff ff call 103d37 <__intr_restore> + return page; + 103f08: 8b 45 f4 mov -0xc(%ebp),%eax +} + 103f0b: 89 ec mov %ebp,%esp + 103f0d: 5d pop %ebp + 103f0e: c3 ret + +00103f0f : + +//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) { + 103f0f: 55 push %ebp + 103f10: 89 e5 mov %esp,%ebp + 103f12: 83 ec 28 sub $0x28,%esp + bool intr_flag; + //使用 local_intr_save 保存当前的中断状态,以避免在释放内存时发生中断。 + local_intr_save(intr_flag); + 103f15: e8 f1 fd ff ff call 103d0b <__intr_save> + 103f1a: 89 45 f4 mov %eax,-0xc(%ebp) + { + //调用物理内存管理器的 free_pages 函数释放 n 页的内存。 + pmm_manager->free_pages(base, n); + 103f1d: a1 0c cf 11 00 mov 0x11cf0c,%eax + 103f22: 8b 40 10 mov 0x10(%eax),%eax + 103f25: 8b 55 0c mov 0xc(%ebp),%edx + 103f28: 89 54 24 04 mov %edx,0x4(%esp) + 103f2c: 8b 55 08 mov 0x8(%ebp),%edx + 103f2f: 89 14 24 mov %edx,(%esp) + 103f32: ff d0 call *%eax + } + local_intr_restore(intr_flag); + 103f34: 8b 45 f4 mov -0xc(%ebp),%eax + 103f37: 89 04 24 mov %eax,(%esp) + 103f3a: e8 f8 fd ff ff call 103d37 <__intr_restore> +} + 103f3f: 90 nop + 103f40: 89 ec mov %ebp,%esp + 103f42: 5d pop %ebp + 103f43: c3 ret + +00103f44 : + +//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) { + 103f44: 55 push %ebp + 103f45: 89 e5 mov %esp,%ebp + 103f47: 83 ec 28 sub $0x28,%esp + size_t ret;// 定义变量 ret 用于存储返回的空闲内存大小 + bool intr_flag;// 定义变量 intr_flag 用于保存中断状态 + local_intr_save(intr_flag);// 保存当前中断状态,并禁用中断 + 103f4a: e8 bc fd ff ff call 103d0b <__intr_save> + 103f4f: 89 45 f4 mov %eax,-0xc(%ebp) + { + ret = pmm_manager->nr_free_pages();// 调用物理内存管理器的函数获取空闲内存页数 + 103f52: a1 0c cf 11 00 mov 0x11cf0c,%eax + 103f57: 8b 40 14 mov 0x14(%eax),%eax + 103f5a: ff d0 call *%eax + 103f5c: 89 45 f0 mov %eax,-0x10(%ebp) + } + local_intr_restore(intr_flag);// 恢复之前保存的中断状态 + 103f5f: 8b 45 f4 mov -0xc(%ebp),%eax + 103f62: 89 04 24 mov %eax,(%esp) + 103f65: e8 cd fd ff ff call 103d37 <__intr_restore> + return ret;// 返回空闲内存的大小 + 103f6a: 8b 45 f0 mov -0x10(%ebp),%eax +} + 103f6d: 89 ec mov %ebp,%esp + 103f6f: 5d pop %ebp + 103f70: c3 ret + +00103f71 : + +/* pmm_init - initialize the physical memory management */ +/* pmm_init - 初始化物理内存管理 */ +static void +page_init(void) { + 103f71: 55 push %ebp + 103f72: 89 e5 mov %esp,%ebp + 103f74: 57 push %edi + 103f75: 56 push %esi + 103f76: 53 push %ebx + 103f77: 81 ec 9c 00 00 00 sub $0x9c,%esp + // 获取物理内存映射信息,存于特定地址 + struct e820map *memmap = (struct e820map *)(0x8000 + KERNBASE); + 103f7d: c7 45 c4 00 80 00 c0 movl $0xc0008000,-0x3c(%ebp) + uint64_t maxpa = 0;// 初始化最大物理地址为0 + 103f84: c7 45 e0 00 00 00 00 movl $0x0,-0x20(%ebp) + 103f8b: c7 45 e4 00 00 00 00 movl $0x0,-0x1c(%ebp) + + cprintf("e820map:\n");// 打印“e820map”标题 + 103f92: c7 04 24 eb 6b 10 00 movl $0x106beb,(%esp) + 103f99: e8 c8 c3 ff ff call 100366 + int i; + for (i = 0; i < memmap->nr_map; i ++) {// 遍历内存映射数组 + 103f9e: c7 45 dc 00 00 00 00 movl $0x0,-0x24(%ebp) + 103fa5: e9 0c 01 00 00 jmp 1040b6 + uint64_t begin = memmap->map[i].addr, end = begin + memmap->map[i].size; // 获取每个区域的起始和结束地址 + 103faa: 8b 4d c4 mov -0x3c(%ebp),%ecx + 103fad: 8b 55 dc mov -0x24(%ebp),%edx + 103fb0: 89 d0 mov %edx,%eax + 103fb2: c1 e0 02 shl $0x2,%eax + 103fb5: 01 d0 add %edx,%eax + 103fb7: c1 e0 02 shl $0x2,%eax + 103fba: 01 c8 add %ecx,%eax + 103fbc: 8b 50 08 mov 0x8(%eax),%edx + 103fbf: 8b 40 04 mov 0x4(%eax),%eax + 103fc2: 89 45 a0 mov %eax,-0x60(%ebp) + 103fc5: 89 55 a4 mov %edx,-0x5c(%ebp) + 103fc8: 8b 4d c4 mov -0x3c(%ebp),%ecx + 103fcb: 8b 55 dc mov -0x24(%ebp),%edx + 103fce: 89 d0 mov %edx,%eax + 103fd0: c1 e0 02 shl $0x2,%eax + 103fd3: 01 d0 add %edx,%eax + 103fd5: c1 e0 02 shl $0x2,%eax + 103fd8: 01 c8 add %ecx,%eax + 103fda: 8b 48 0c mov 0xc(%eax),%ecx + 103fdd: 8b 58 10 mov 0x10(%eax),%ebx + 103fe0: 8b 45 a0 mov -0x60(%ebp),%eax + 103fe3: 8b 55 a4 mov -0x5c(%ebp),%edx + 103fe6: 01 c8 add %ecx,%eax + 103fe8: 11 da adc %ebx,%edx + 103fea: 89 45 98 mov %eax,-0x68(%ebp) + 103fed: 89 55 9c mov %edx,-0x64(%ebp) + cprintf(" memory: %08llx, [%08llx, %08llx], type = %d.\n",// 打印内存区域的信息 + 103ff0: 8b 4d c4 mov -0x3c(%ebp),%ecx + 103ff3: 8b 55 dc mov -0x24(%ebp),%edx + 103ff6: 89 d0 mov %edx,%eax + 103ff8: c1 e0 02 shl $0x2,%eax + 103ffb: 01 d0 add %edx,%eax + 103ffd: c1 e0 02 shl $0x2,%eax + 104000: 01 c8 add %ecx,%eax + 104002: 83 c0 14 add $0x14,%eax + 104005: 8b 00 mov (%eax),%eax + 104007: 89 85 7c ff ff ff mov %eax,-0x84(%ebp) + 10400d: 8b 45 98 mov -0x68(%ebp),%eax + 104010: 8b 55 9c mov -0x64(%ebp),%edx + 104013: 83 c0 ff add $0xffffffff,%eax + 104016: 83 d2 ff adc $0xffffffff,%edx + 104019: 89 c6 mov %eax,%esi + 10401b: 89 d7 mov %edx,%edi + 10401d: 8b 4d c4 mov -0x3c(%ebp),%ecx + 104020: 8b 55 dc mov -0x24(%ebp),%edx + 104023: 89 d0 mov %edx,%eax + 104025: c1 e0 02 shl $0x2,%eax + 104028: 01 d0 add %edx,%eax + 10402a: c1 e0 02 shl $0x2,%eax + 10402d: 01 c8 add %ecx,%eax + 10402f: 8b 48 0c mov 0xc(%eax),%ecx + 104032: 8b 58 10 mov 0x10(%eax),%ebx + 104035: 8b 85 7c ff ff ff mov -0x84(%ebp),%eax + 10403b: 89 44 24 1c mov %eax,0x1c(%esp) + 10403f: 89 74 24 14 mov %esi,0x14(%esp) + 104043: 89 7c 24 18 mov %edi,0x18(%esp) + 104047: 8b 45 a0 mov -0x60(%ebp),%eax + 10404a: 8b 55 a4 mov -0x5c(%ebp),%edx + 10404d: 89 44 24 0c mov %eax,0xc(%esp) + 104051: 89 54 24 10 mov %edx,0x10(%esp) + 104055: 89 4c 24 04 mov %ecx,0x4(%esp) + 104059: 89 5c 24 08 mov %ebx,0x8(%esp) + 10405d: c7 04 24 f8 6b 10 00 movl $0x106bf8,(%esp) + 104064: e8 fd c2 ff ff call 100366 + memmap->map[i].size, begin, end - 1, memmap->map[i].type); + if (memmap->map[i].type == E820_ARM) { // 检查内存类型是否为可用内存 + 104069: 8b 4d c4 mov -0x3c(%ebp),%ecx + 10406c: 8b 55 dc mov -0x24(%ebp),%edx + 10406f: 89 d0 mov %edx,%eax + 104071: c1 e0 02 shl $0x2,%eax + 104074: 01 d0 add %edx,%eax + 104076: c1 e0 02 shl $0x2,%eax + 104079: 01 c8 add %ecx,%eax + 10407b: 83 c0 14 add $0x14,%eax + 10407e: 8b 00 mov (%eax),%eax + 104080: 83 f8 01 cmp $0x1,%eax + 104083: 75 2e jne 1040b3 + if (maxpa < end && begin < KMEMSIZE) {// 检查当前区域是否在有效范围内 + 104085: 8b 45 e0 mov -0x20(%ebp),%eax + 104088: 8b 55 e4 mov -0x1c(%ebp),%edx + 10408b: 3b 45 98 cmp -0x68(%ebp),%eax + 10408e: 89 d0 mov %edx,%eax + 104090: 1b 45 9c sbb -0x64(%ebp),%eax + 104093: 73 1e jae 1040b3 + 104095: ba ff ff ff 37 mov $0x37ffffff,%edx + 10409a: b8 00 00 00 00 mov $0x0,%eax + 10409f: 3b 55 a0 cmp -0x60(%ebp),%edx + 1040a2: 1b 45 a4 sbb -0x5c(%ebp),%eax + 1040a5: 72 0c jb 1040b3 + maxpa = end;// 更新最大物理地址 + 1040a7: 8b 45 98 mov -0x68(%ebp),%eax + 1040aa: 8b 55 9c mov -0x64(%ebp),%edx + 1040ad: 89 45 e0 mov %eax,-0x20(%ebp) + 1040b0: 89 55 e4 mov %edx,-0x1c(%ebp) + for (i = 0; i < memmap->nr_map; i ++) {// 遍历内存映射数组 + 1040b3: ff 45 dc incl -0x24(%ebp) + 1040b6: 8b 45 c4 mov -0x3c(%ebp),%eax + 1040b9: 8b 00 mov (%eax),%eax + 1040bb: 39 45 dc cmp %eax,-0x24(%ebp) + 1040be: 0f 8c e6 fe ff ff jl 103faa + } + } + } + if (maxpa > KMEMSIZE) {// 如果最大物理地址超过了预定义的内存上限 + 1040c4: ba 00 00 00 38 mov $0x38000000,%edx + 1040c9: b8 00 00 00 00 mov $0x0,%eax + 1040ce: 3b 55 e0 cmp -0x20(%ebp),%edx + 1040d1: 1b 45 e4 sbb -0x1c(%ebp),%eax + 1040d4: 73 0e jae 1040e4 + maxpa = KMEMSIZE;// 将其限制为内存上限 + 1040d6: c7 45 e0 00 00 00 38 movl $0x38000000,-0x20(%ebp) + 1040dd: c7 45 e4 00 00 00 00 movl $0x0,-0x1c(%ebp) + } + + extern char end[];// 引入全局变量 end,指向内存的结束位置 + + npage = maxpa / PGSIZE; // 计算可用页数 + 1040e4: 8b 45 e0 mov -0x20(%ebp),%eax + 1040e7: 8b 55 e4 mov -0x1c(%ebp),%edx + 1040ea: 0f ac d0 0c shrd $0xc,%edx,%eax + 1040ee: c1 ea 0c shr $0xc,%edx + 1040f1: a3 04 cf 11 00 mov %eax,0x11cf04 + pages = (struct Page *)ROUNDUP((void *)end, PGSIZE);// 将 end 对齐到页边界,指向页结构数组的开头 + 1040f6: c7 45 c0 00 10 00 00 movl $0x1000,-0x40(%ebp) + 1040fd: b8 8c cf 11 00 mov $0x11cf8c,%eax + 104102: 8d 50 ff lea -0x1(%eax),%edx + 104105: 8b 45 c0 mov -0x40(%ebp),%eax + 104108: 01 d0 add %edx,%eax + 10410a: 89 45 bc mov %eax,-0x44(%ebp) + 10410d: 8b 45 bc mov -0x44(%ebp),%eax + 104110: ba 00 00 00 00 mov $0x0,%edx + 104115: f7 75 c0 divl -0x40(%ebp) + 104118: 8b 45 bc mov -0x44(%ebp),%eax + 10411b: 29 d0 sub %edx,%eax + 10411d: a3 00 cf 11 00 mov %eax,0x11cf00 + + for (i = 0; i < npage; i ++) {// 遍历每一页 + 104122: c7 45 dc 00 00 00 00 movl $0x0,-0x24(%ebp) + 104129: eb 2f jmp 10415a + SetPageReserved(pages + i);// 将每一页标记为保留状态 + 10412b: 8b 0d 00 cf 11 00 mov 0x11cf00,%ecx + 104131: 8b 55 dc mov -0x24(%ebp),%edx + 104134: 89 d0 mov %edx,%eax + 104136: c1 e0 02 shl $0x2,%eax + 104139: 01 d0 add %edx,%eax + 10413b: c1 e0 02 shl $0x2,%eax + 10413e: 01 c8 add %ecx,%eax + 104140: 83 c0 04 add $0x4,%eax + 104143: c7 45 94 00 00 00 00 movl $0x0,-0x6c(%ebp) + 10414a: 89 45 90 mov %eax,-0x70(%ebp) + asm volatile ("btsl %1, %0" :"=m" (*(volatile long *)addr) : "Ir" (nr)); + 10414d: 8b 45 90 mov -0x70(%ebp),%eax + 104150: 8b 55 94 mov -0x6c(%ebp),%edx + 104153: 0f ab 10 bts %edx,(%eax) +} + 104156: 90 nop + for (i = 0; i < npage; i ++) {// 遍历每一页 + 104157: ff 45 dc incl -0x24(%ebp) + 10415a: 8b 55 dc mov -0x24(%ebp),%edx + 10415d: a1 04 cf 11 00 mov 0x11cf04,%eax + 104162: 39 c2 cmp %eax,%edx + 104164: 72 c5 jb 10412b + } + + uintptr_t freemem = PADDR((uintptr_t)pages + sizeof(struct Page) * npage);// 计算可用内存的起始地址 + 104166: 8b 15 04 cf 11 00 mov 0x11cf04,%edx + 10416c: 89 d0 mov %edx,%eax + 10416e: c1 e0 02 shl $0x2,%eax + 104171: 01 d0 add %edx,%eax + 104173: c1 e0 02 shl $0x2,%eax + 104176: 89 c2 mov %eax,%edx + 104178: a1 00 cf 11 00 mov 0x11cf00,%eax + 10417d: 01 d0 add %edx,%eax + 10417f: 89 45 b8 mov %eax,-0x48(%ebp) + 104182: 81 7d b8 ff ff ff bf cmpl $0xbfffffff,-0x48(%ebp) + 104189: 77 23 ja 1041ae + 10418b: 8b 45 b8 mov -0x48(%ebp),%eax + 10418e: 89 44 24 0c mov %eax,0xc(%esp) + 104192: c7 44 24 08 28 6c 10 movl $0x106c28,0x8(%esp) + 104199: 00 + 10419a: c7 44 24 04 0c 01 00 movl $0x10c,0x4(%esp) + 1041a1: 00 + 1041a2: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 1041a9: e8 85 ca ff ff call 100c33 <__panic> + 1041ae: 8b 45 b8 mov -0x48(%ebp),%eax + 1041b1: 05 00 00 00 40 add $0x40000000,%eax + 1041b6: 89 45 b4 mov %eax,-0x4c(%ebp) + + for (i = 0; i < memmap->nr_map; i ++) {// 再次遍历内存映射 + 1041b9: c7 45 dc 00 00 00 00 movl $0x0,-0x24(%ebp) + 1041c0: e9 53 01 00 00 jmp 104318 + uint64_t begin = memmap->map[i].addr, end = begin + memmap->map[i].size;// 获取每个区域的起始和结束地址 + 1041c5: 8b 4d c4 mov -0x3c(%ebp),%ecx + 1041c8: 8b 55 dc mov -0x24(%ebp),%edx + 1041cb: 89 d0 mov %edx,%eax + 1041cd: c1 e0 02 shl $0x2,%eax + 1041d0: 01 d0 add %edx,%eax + 1041d2: c1 e0 02 shl $0x2,%eax + 1041d5: 01 c8 add %ecx,%eax + 1041d7: 8b 50 08 mov 0x8(%eax),%edx + 1041da: 8b 40 04 mov 0x4(%eax),%eax + 1041dd: 89 45 d0 mov %eax,-0x30(%ebp) + 1041e0: 89 55 d4 mov %edx,-0x2c(%ebp) + 1041e3: 8b 4d c4 mov -0x3c(%ebp),%ecx + 1041e6: 8b 55 dc mov -0x24(%ebp),%edx + 1041e9: 89 d0 mov %edx,%eax + 1041eb: c1 e0 02 shl $0x2,%eax + 1041ee: 01 d0 add %edx,%eax + 1041f0: c1 e0 02 shl $0x2,%eax + 1041f3: 01 c8 add %ecx,%eax + 1041f5: 8b 48 0c mov 0xc(%eax),%ecx + 1041f8: 8b 58 10 mov 0x10(%eax),%ebx + 1041fb: 8b 45 d0 mov -0x30(%ebp),%eax + 1041fe: 8b 55 d4 mov -0x2c(%ebp),%edx + 104201: 01 c8 add %ecx,%eax + 104203: 11 da adc %ebx,%edx + 104205: 89 45 c8 mov %eax,-0x38(%ebp) + 104208: 89 55 cc mov %edx,-0x34(%ebp) + if (memmap->map[i].type == E820_ARM) {// 如果区域类型为可用内存 + 10420b: 8b 4d c4 mov -0x3c(%ebp),%ecx + 10420e: 8b 55 dc mov -0x24(%ebp),%edx + 104211: 89 d0 mov %edx,%eax + 104213: c1 e0 02 shl $0x2,%eax + 104216: 01 d0 add %edx,%eax + 104218: c1 e0 02 shl $0x2,%eax + 10421b: 01 c8 add %ecx,%eax + 10421d: 83 c0 14 add $0x14,%eax + 104220: 8b 00 mov (%eax),%eax + 104222: 83 f8 01 cmp $0x1,%eax + 104225: 0f 85 ea 00 00 00 jne 104315 + if (begin < freemem) { // 如果起始地址小于可用内存地址 + 10422b: 8b 45 b4 mov -0x4c(%ebp),%eax + 10422e: ba 00 00 00 00 mov $0x0,%edx + 104233: 8b 4d d4 mov -0x2c(%ebp),%ecx + 104236: 39 45 d0 cmp %eax,-0x30(%ebp) + 104239: 19 d1 sbb %edx,%ecx + 10423b: 73 0d jae 10424a + begin = freemem;// 将起始地址设置为可用内存地址 + 10423d: 8b 45 b4 mov -0x4c(%ebp),%eax + 104240: 89 45 d0 mov %eax,-0x30(%ebp) + 104243: c7 45 d4 00 00 00 00 movl $0x0,-0x2c(%ebp) + } + if (end > KMEMSIZE) {// 如果结束地址超过内存上限 + 10424a: ba 00 00 00 38 mov $0x38000000,%edx + 10424f: b8 00 00 00 00 mov $0x0,%eax + 104254: 3b 55 c8 cmp -0x38(%ebp),%edx + 104257: 1b 45 cc sbb -0x34(%ebp),%eax + 10425a: 73 0e jae 10426a + end = KMEMSIZE;// 将其限制为内存上限 + 10425c: c7 45 c8 00 00 00 38 movl $0x38000000,-0x38(%ebp) + 104263: c7 45 cc 00 00 00 00 movl $0x0,-0x34(%ebp) + } + if (begin < end) {// 如果起始地址小于结束地址 + 10426a: 8b 45 d0 mov -0x30(%ebp),%eax + 10426d: 8b 55 d4 mov -0x2c(%ebp),%edx + 104270: 3b 45 c8 cmp -0x38(%ebp),%eax + 104273: 89 d0 mov %edx,%eax + 104275: 1b 45 cc sbb -0x34(%ebp),%eax + 104278: 0f 83 97 00 00 00 jae 104315 + begin = ROUNDUP(begin, PGSIZE);// 将起始地址对齐到页边界 + 10427e: c7 45 b0 00 10 00 00 movl $0x1000,-0x50(%ebp) + 104285: 8b 55 d0 mov -0x30(%ebp),%edx + 104288: 8b 45 b0 mov -0x50(%ebp),%eax + 10428b: 01 d0 add %edx,%eax + 10428d: 48 dec %eax + 10428e: 89 45 ac mov %eax,-0x54(%ebp) + 104291: 8b 45 ac mov -0x54(%ebp),%eax + 104294: ba 00 00 00 00 mov $0x0,%edx + 104299: f7 75 b0 divl -0x50(%ebp) + 10429c: 8b 45 ac mov -0x54(%ebp),%eax + 10429f: 29 d0 sub %edx,%eax + 1042a1: ba 00 00 00 00 mov $0x0,%edx + 1042a6: 89 45 d0 mov %eax,-0x30(%ebp) + 1042a9: 89 55 d4 mov %edx,-0x2c(%ebp) + end = ROUNDDOWN(end, PGSIZE);// 将结束地址对齐到页边界 + 1042ac: 8b 45 c8 mov -0x38(%ebp),%eax + 1042af: 89 45 a8 mov %eax,-0x58(%ebp) + 1042b2: 8b 45 a8 mov -0x58(%ebp),%eax + 1042b5: ba 00 00 00 00 mov $0x0,%edx + 1042ba: 89 c7 mov %eax,%edi + 1042bc: 81 e7 00 f0 ff ff and $0xfffff000,%edi + 1042c2: 89 7d 80 mov %edi,-0x80(%ebp) + 1042c5: 89 d0 mov %edx,%eax + 1042c7: 83 e0 00 and $0x0,%eax + 1042ca: 89 45 84 mov %eax,-0x7c(%ebp) + 1042cd: 8b 45 80 mov -0x80(%ebp),%eax + 1042d0: 8b 55 84 mov -0x7c(%ebp),%edx + 1042d3: 89 45 c8 mov %eax,-0x38(%ebp) + 1042d6: 89 55 cc mov %edx,-0x34(%ebp) + if (begin < end) {// 如果调整后的起始地址仍小于结束地址 + 1042d9: 8b 45 d0 mov -0x30(%ebp),%eax + 1042dc: 8b 55 d4 mov -0x2c(%ebp),%edx + 1042df: 3b 45 c8 cmp -0x38(%ebp),%eax + 1042e2: 89 d0 mov %edx,%eax + 1042e4: 1b 45 cc sbb -0x34(%ebp),%eax + 1042e7: 73 2c jae 104315 + init_memmap(pa2page(begin), (end - begin) / PGSIZE);// 初始化内存页映射 + 1042e9: 8b 45 c8 mov -0x38(%ebp),%eax + 1042ec: 8b 55 cc mov -0x34(%ebp),%edx + 1042ef: 2b 45 d0 sub -0x30(%ebp),%eax + 1042f2: 1b 55 d4 sbb -0x2c(%ebp),%edx + 1042f5: 0f ac d0 0c shrd $0xc,%edx,%eax + 1042f9: c1 ea 0c shr $0xc,%edx + 1042fc: 89 c3 mov %eax,%ebx + 1042fe: 8b 45 d0 mov -0x30(%ebp),%eax + 104301: 89 04 24 mov %eax,(%esp) + 104304: e8 bb f8 ff ff call 103bc4 + 104309: 89 5c 24 04 mov %ebx,0x4(%esp) + 10430d: 89 04 24 mov %eax,(%esp) + 104310: e8 9e fb ff ff call 103eb3 + for (i = 0; i < memmap->nr_map; i ++) {// 再次遍历内存映射 + 104315: ff 45 dc incl -0x24(%ebp) + 104318: 8b 45 c4 mov -0x3c(%ebp),%eax + 10431b: 8b 00 mov (%eax),%eax + 10431d: 39 45 dc cmp %eax,-0x24(%ebp) + 104320: 0f 8c 9f fe ff ff jl 1041c5 + } + } + } + } +} + 104326: 90 nop + 104327: 90 nop + 104328: 81 c4 9c 00 00 00 add $0x9c,%esp + 10432e: 5b pop %ebx + 10432f: 5e pop %esi + 104330: 5f pop %edi + 104331: 5d pop %ebp + 104332: c3 ret + +00104333 : +//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) { + 104333: 55 push %ebp + 104334: 89 e5 mov %esp,%ebp + 104336: 83 ec 38 sub $0x38,%esp + // 确保线性地址和物理地址的页偏移相同 + assert(PGOFF(la) == PGOFF(pa)); + 104339: 8b 45 0c mov 0xc(%ebp),%eax + 10433c: 33 45 14 xor 0x14(%ebp),%eax + 10433f: 25 ff 0f 00 00 and $0xfff,%eax + 104344: 85 c0 test %eax,%eax + 104346: 74 24 je 10436c + 104348: c7 44 24 0c 5a 6c 10 movl $0x106c5a,0xc(%esp) + 10434f: 00 + 104350: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 104357: 00 + 104358: c7 44 24 04 2d 01 00 movl $0x12d,0x4(%esp) + 10435f: 00 + 104360: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 104367: e8 c7 c8 ff ff call 100c33 <__panic> + // 计算需要映射的页数,ROUNDUP 将总大小对齐到下一个页大小的边界 + size_t n = ROUNDUP(size + PGOFF(la), PGSIZE) / PGSIZE; + 10436c: c7 45 f0 00 10 00 00 movl $0x1000,-0x10(%ebp) + 104373: 8b 45 0c mov 0xc(%ebp),%eax + 104376: 25 ff 0f 00 00 and $0xfff,%eax + 10437b: 89 c2 mov %eax,%edx + 10437d: 8b 45 10 mov 0x10(%ebp),%eax + 104380: 01 c2 add %eax,%edx + 104382: 8b 45 f0 mov -0x10(%ebp),%eax + 104385: 01 d0 add %edx,%eax + 104387: 48 dec %eax + 104388: 89 45 ec mov %eax,-0x14(%ebp) + 10438b: 8b 45 ec mov -0x14(%ebp),%eax + 10438e: ba 00 00 00 00 mov $0x0,%edx + 104393: f7 75 f0 divl -0x10(%ebp) + 104396: 8b 45 ec mov -0x14(%ebp),%eax + 104399: 29 d0 sub %edx,%eax + 10439b: c1 e8 0c shr $0xc,%eax + 10439e: 89 45 f4 mov %eax,-0xc(%ebp) + // 将线性地址向下对齐到页边界 + la = ROUNDDOWN(la, PGSIZE); + 1043a1: 8b 45 0c mov 0xc(%ebp),%eax + 1043a4: 89 45 e8 mov %eax,-0x18(%ebp) + 1043a7: 8b 45 e8 mov -0x18(%ebp),%eax + 1043aa: 25 00 f0 ff ff and $0xfffff000,%eax + 1043af: 89 45 0c mov %eax,0xc(%ebp) + // 将物理地址向下对齐到页边界 + pa = ROUNDDOWN(pa, PGSIZE); + 1043b2: 8b 45 14 mov 0x14(%ebp),%eax + 1043b5: 89 45 e4 mov %eax,-0x1c(%ebp) + 1043b8: 8b 45 e4 mov -0x1c(%ebp),%eax + 1043bb: 25 00 f0 ff ff and $0xfffff000,%eax + 1043c0: 89 45 14 mov %eax,0x14(%ebp) + // 循环遍历每一页,直到映射的页数为零 + for (; n > 0; n --, la += PGSIZE, pa += PGSIZE) { + 1043c3: eb 68 jmp 10442d + // 获取当前页的页表项指针,如果不存在则创建新的页表项 + pte_t *ptep = get_pte(pgdir, la, 1); + 1043c5: c7 44 24 08 01 00 00 movl $0x1,0x8(%esp) + 1043cc: 00 + 1043cd: 8b 45 0c mov 0xc(%ebp),%eax + 1043d0: 89 44 24 04 mov %eax,0x4(%esp) + 1043d4: 8b 45 08 mov 0x8(%ebp),%eax + 1043d7: 89 04 24 mov %eax,(%esp) + 1043da: e8 88 01 00 00 call 104567 + 1043df: 89 45 e0 mov %eax,-0x20(%ebp) + // 确保页表项指针不为空 + assert(ptep != NULL); + 1043e2: 83 7d e0 00 cmpl $0x0,-0x20(%ebp) + 1043e6: 75 24 jne 10440c + 1043e8: c7 44 24 0c 86 6c 10 movl $0x106c86,0xc(%esp) + 1043ef: 00 + 1043f0: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 1043f7: 00 + 1043f8: c7 44 24 04 39 01 00 movl $0x139,0x4(%esp) + 1043ff: 00 + 104400: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 104407: e8 27 c8 ff ff call 100c33 <__panic> + // 设置页表项,包含物理地址、存在位和权限 + *ptep = pa | PTE_P | perm; + 10440c: 8b 45 14 mov 0x14(%ebp),%eax + 10440f: 0b 45 18 or 0x18(%ebp),%eax + 104412: 83 c8 01 or $0x1,%eax + 104415: 89 c2 mov %eax,%edx + 104417: 8b 45 e0 mov -0x20(%ebp),%eax + 10441a: 89 10 mov %edx,(%eax) + for (; n > 0; n --, la += PGSIZE, pa += PGSIZE) { + 10441c: ff 4d f4 decl -0xc(%ebp) + 10441f: 81 45 0c 00 10 00 00 addl $0x1000,0xc(%ebp) + 104426: 81 45 14 00 10 00 00 addl $0x1000,0x14(%ebp) + 10442d: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) + 104431: 75 92 jne 1043c5 + } +} + 104433: 90 nop + 104434: 90 nop + 104435: 89 ec mov %ebp,%esp + 104437: 5d pop %ebp + 104438: c3 ret + +00104439 : +// 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) { + 104439: 55 push %ebp + 10443a: 89 e5 mov %esp,%ebp + 10443c: 83 ec 28 sub $0x28,%esp + struct Page *p = alloc_page();// 调用分配页面的函数 + 10443f: c7 04 24 01 00 00 00 movl $0x1,(%esp) + 104446: e8 8a fa ff ff call 103ed5 + 10444b: 89 45 f4 mov %eax,-0xc(%ebp) + if (p == NULL) {// 检查分配是否成功 + 10444e: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) + 104452: 75 1c jne 104470 + panic("boot_alloc_page failed.\n");// 如果分配失败,则触发异常 + 104454: c7 44 24 08 93 6c 10 movl $0x106c93,0x8(%esp) + 10445b: 00 + 10445c: c7 44 24 04 48 01 00 movl $0x148,0x4(%esp) + 104463: 00 + 104464: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 10446b: e8 c3 c7 ff ff call 100c33 <__panic> + } + return page2kva(p);// 返回分配页面的内核虚拟地址 + 104470: 8b 45 f4 mov -0xc(%ebp),%eax + 104473: 89 04 24 mov %eax,(%esp) + 104476: e8 9a f7 ff ff call 103c15 +} + 10447b: 89 ec mov %ebp,%esp + 10447d: 5d pop %ebp + 10447e: c3 ret + +0010447f : +//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) { + 10447f: 55 push %ebp + 104480: 89 e5 mov %esp,%ebp + 104482: 83 ec 38 sub $0x38,%esp + // We've already enabled paging + // 我们已经启用了分页 + boot_cr3 = PADDR(boot_pgdir); + 104485: a1 e0 99 11 00 mov 0x1199e0,%eax + 10448a: 89 45 f4 mov %eax,-0xc(%ebp) + 10448d: 81 7d f4 ff ff ff bf cmpl $0xbfffffff,-0xc(%ebp) + 104494: 77 23 ja 1044b9 + 104496: 8b 45 f4 mov -0xc(%ebp),%eax + 104499: 89 44 24 0c mov %eax,0xc(%esp) + 10449d: c7 44 24 08 28 6c 10 movl $0x106c28,0x8(%esp) + 1044a4: 00 + 1044a5: c7 44 24 04 55 01 00 movl $0x155,0x4(%esp) + 1044ac: 00 + 1044ad: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 1044b4: e8 7a c7 ff ff call 100c33 <__panic> + 1044b9: 8b 45 f4 mov -0xc(%ebp),%eax + 1044bc: 05 00 00 00 40 add $0x40000000,%eax + 1044c1: a3 08 cf 11 00 mov %eax,0x11cf08 + // 我们需要分配/释放物理内存(粒度为 4KB 或其他大小)。 + // 因此在 pmm.h 中定义了物理内存管理器的框架(struct pmm_manager)。 + // 首先,我们应该基于该框架初始化一个物理内存管理器(pmm)。 + // 然后 pmm 可以分配/释放物理内存。 + // 现在,first_fit/best_fit/worst_fit/buddy_system 的 pmm 都可用。 + init_pmm_manager();// 初始化物理内存管理器 + 1044c6: e8 b2 f9 ff ff call 103e7d + + // detect physical memory space, reserve already used memory, + // then use pmm->init_memmap to create free page list + // 检测物理内存空间,保留已经使用的内存, + // 然后使用 pmm->init_memmap 创建空闲页面列表 + page_init();// 初始化页面管理 + 1044cb: e8 a1 fa ff ff call 103f71 + + //use pmm->check to verify the correctness of the alloc/free function in a pmm + // 使用 pmm->check 验证 pmm 中分配/释放函数的正确性 + check_alloc_page();// 检查页面分配功能 + 1044d0: e8 ed 03 00 00 call 1048c2 + + check_pgdir();// 检查页目录的状态 + 1044d5: e8 09 04 00 00 call 1048e3 + + // 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;// 设置页目录项,映射自身 + 1044da: a1 e0 99 11 00 mov 0x1199e0,%eax + 1044df: 89 45 f0 mov %eax,-0x10(%ebp) + 1044e2: 81 7d f0 ff ff ff bf cmpl $0xbfffffff,-0x10(%ebp) + 1044e9: 77 23 ja 10450e + 1044eb: 8b 45 f0 mov -0x10(%ebp),%eax + 1044ee: 89 44 24 0c mov %eax,0xc(%esp) + 1044f2: c7 44 24 08 28 6c 10 movl $0x106c28,0x8(%esp) + 1044f9: 00 + 1044fa: c7 44 24 04 75 01 00 movl $0x175,0x4(%esp) + 104501: 00 + 104502: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 104509: e8 25 c7 ff ff call 100c33 <__panic> + 10450e: 8b 45 f0 mov -0x10(%ebp),%eax + 104511: 8d 90 00 00 00 40 lea 0x40000000(%eax),%edx + 104517: a1 e0 99 11 00 mov 0x1199e0,%eax + 10451c: 05 ac 0f 00 00 add $0xfac,%eax + 104521: 83 ca 03 or $0x3,%edx + 104524: 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);// 映射物理内存 + 104526: a1 e0 99 11 00 mov 0x1199e0,%eax + 10452b: c7 44 24 10 02 00 00 movl $0x2,0x10(%esp) + 104532: 00 + 104533: c7 44 24 0c 00 00 00 movl $0x0,0xc(%esp) + 10453a: 00 + 10453b: c7 44 24 08 00 00 00 movl $0x38000000,0x8(%esp) + 104542: 38 + 104543: c7 44 24 04 00 00 00 movl $0xc0000000,0x4(%esp) + 10454a: c0 + 10454b: 89 04 24 mov %eax,(%esp) + 10454e: e8 e0 fd ff ff call 104333 + // 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();// 初始化全局描述符表 + 104553: e8 39 f8 ff ff call 103d91 + + //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(); // 检查页目录的正确性 + 104558: e8 24 0a 00 00 call 104f81 + + print_pgdir(); // 打印页目录表 + 10455d: e8 a1 0e 00 00 call 105403 + +} + 104562: 90 nop + 104563: 89 ec mov %ebp,%esp + 104565: 5d pop %ebp + 104566: c3 ret + +00104567 : +// pgdir: 页目录的内核虚拟基地址 +// la: 需要映射的线性地址 +// create: 一个逻辑值,决定是否为页表分配一页 +// 返回值:该 PTE 的内核虚拟地址 +pte_t * +get_pte(pde_t *pgdir, uintptr_t la, bool create) { + 104567: 55 push %ebp + 104568: 89 e5 mov %esp,%ebp + 10456a: 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 宏获取页目录索引 + 10456d: 8b 45 0c mov 0xc(%ebp),%eax + 104570: c1 e8 16 shr $0x16,%eax + 104573: 8d 14 85 00 00 00 00 lea 0x0(,%eax,4),%edx + 10457a: 8b 45 08 mov 0x8(%ebp),%eax + 10457d: 01 d0 add %edx,%eax + 10457f: 89 45 f4 mov %eax,-0xc(%ebp) + // (2) 检查页目录项是否存在 + if (!(*pdep & PTE_P)) {// 如果页目录项的存在位 PTE_P 没有被设置 + 104582: 8b 45 f4 mov -0xc(%ebp),%eax + 104585: 8b 00 mov (%eax),%eax + 104587: 83 e0 01 and $0x1,%eax + 10458a: 85 c0 test %eax,%eax + 10458c: 0f 85 af 00 00 00 jne 104641 + struct Page *page;// 声明一个指针,用于指向新分配的页面 + // 检查是否允许创建新页表,或者分配页表失败 + if (!create || (page = alloc_page()) == NULL) {// 如果不允许创建或分配失败 + 104592: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 104596: 74 15 je 1045ad + 104598: c7 04 24 01 00 00 00 movl $0x1,(%esp) + 10459f: e8 31 f9 ff ff call 103ed5 + 1045a4: 89 45 f0 mov %eax,-0x10(%ebp) + 1045a7: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) + 1045ab: 75 0a jne 1045b7 + return NULL;// 返回 NULL,表示无法获取页表 + 1045ad: b8 00 00 00 00 mov $0x0,%eax + 1045b2: e9 e7 00 00 00 jmp 10469e + } + // 设置新分配页面的引用计数为 1 + set_page_ref(page, 1); + 1045b7: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) + 1045be: 00 + 1045bf: 8b 45 f0 mov -0x10(%ebp),%eax + 1045c2: 89 04 24 mov %eax,(%esp) + 1045c5: e8 05 f7 ff ff call 103ccf + uintptr_t pa = page2pa(page);// 获取新分配页面的物理地址 + 1045ca: 8b 45 f0 mov -0x10(%ebp),%eax + 1045cd: 89 04 24 mov %eax,(%esp) + 1045d0: e8 d7 f5 ff ff call 103bac + 1045d5: 89 45 ec mov %eax,-0x14(%ebp) + memset(KADDR(pa), 0, PGSIZE);// 清空新分配的页表内容,初始化为零 + 1045d8: 8b 45 ec mov -0x14(%ebp),%eax + 1045db: 89 45 e8 mov %eax,-0x18(%ebp) + 1045de: 8b 45 e8 mov -0x18(%ebp),%eax + 1045e1: c1 e8 0c shr $0xc,%eax + 1045e4: 89 45 e4 mov %eax,-0x1c(%ebp) + 1045e7: a1 04 cf 11 00 mov 0x11cf04,%eax + 1045ec: 39 45 e4 cmp %eax,-0x1c(%ebp) + 1045ef: 72 23 jb 104614 + 1045f1: 8b 45 e8 mov -0x18(%ebp),%eax + 1045f4: 89 44 24 0c mov %eax,0xc(%esp) + 1045f8: c7 44 24 08 84 6b 10 movl $0x106b84,0x8(%esp) + 1045ff: 00 + 104600: c7 44 24 04 ce 01 00 movl $0x1ce,0x4(%esp) + 104607: 00 + 104608: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 10460f: e8 1f c6 ff ff call 100c33 <__panic> + 104614: 8b 45 e8 mov -0x18(%ebp),%eax + 104617: 2d 00 00 00 40 sub $0x40000000,%eax + 10461c: c7 44 24 08 00 10 00 movl $0x1000,0x8(%esp) + 104623: 00 + 104624: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) + 10462b: 00 + 10462c: 89 04 24 mov %eax,(%esp) + 10462f: e8 d4 18 00 00 call 105f08 + // 更新页目录项,设置物理地址和权限位 + *pdep = pa | PTE_U | PTE_W | PTE_P;// 将物理地址和权限位(用户可访问、可写、有效)合并设置 + 104634: 8b 45 ec mov -0x14(%ebp),%eax + 104637: 83 c8 07 or $0x7,%eax + 10463a: 89 c2 mov %eax,%edx + 10463c: 8b 45 f4 mov -0xc(%ebp),%eax + 10463f: 89 10 mov %edx,(%eax) + } + // 返回指定线性地址 la 对应的页表项的内核虚拟地址 + return &((pte_t *)KADDR(PDE_ADDR(*pdep)))[PTX(la)];// 计算并返回页表项的指针 + 104641: 8b 45 f4 mov -0xc(%ebp),%eax + 104644: 8b 00 mov (%eax),%eax + 104646: 25 00 f0 ff ff and $0xfffff000,%eax + 10464b: 89 45 e0 mov %eax,-0x20(%ebp) + 10464e: 8b 45 e0 mov -0x20(%ebp),%eax + 104651: c1 e8 0c shr $0xc,%eax + 104654: 89 45 dc mov %eax,-0x24(%ebp) + 104657: a1 04 cf 11 00 mov 0x11cf04,%eax + 10465c: 39 45 dc cmp %eax,-0x24(%ebp) + 10465f: 72 23 jb 104684 + 104661: 8b 45 e0 mov -0x20(%ebp),%eax + 104664: 89 44 24 0c mov %eax,0xc(%esp) + 104668: c7 44 24 08 84 6b 10 movl $0x106b84,0x8(%esp) + 10466f: 00 + 104670: c7 44 24 04 d3 01 00 movl $0x1d3,0x4(%esp) + 104677: 00 + 104678: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 10467f: e8 af c5 ff ff call 100c33 <__panic> + 104684: 8b 45 e0 mov -0x20(%ebp),%eax + 104687: 2d 00 00 00 40 sub $0x40000000,%eax + 10468c: 89 c2 mov %eax,%edx + 10468e: 8b 45 0c mov 0xc(%ebp),%eax + 104691: c1 e8 0c shr $0xc,%eax + 104694: 25 ff 03 00 00 and $0x3ff,%eax + 104699: c1 e0 02 shl $0x2,%eax + 10469c: 01 d0 add %edx,%eax +} + 10469e: 89 ec mov %ebp,%esp + 1046a0: 5d pop %ebp + 1046a1: c3 ret + +001046a2 : + +//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) { + 1046a2: 55 push %ebp + 1046a3: 89 e5 mov %esp,%ebp + 1046a5: 83 ec 28 sub $0x28,%esp + // 调用 get_pte 函数获取对应线性地址 la 的页表项指针 + pte_t *ptep = get_pte(pgdir, la, 0); + 1046a8: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) + 1046af: 00 + 1046b0: 8b 45 0c mov 0xc(%ebp),%eax + 1046b3: 89 44 24 04 mov %eax,0x4(%esp) + 1046b7: 8b 45 08 mov 0x8(%ebp),%eax + 1046ba: 89 04 24 mov %eax,(%esp) + 1046bd: e8 a5 fe ff ff call 104567 + 1046c2: 89 45 f4 mov %eax,-0xc(%ebp) + // 如果 ptep_store 指针不为 NULL,将 ptep 存储到 ptep_store 指向的位置 + if (ptep_store != NULL) { + 1046c5: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 1046c9: 74 08 je 1046d3 + *ptep_store = ptep; // 存储当前页表项的指针 + 1046cb: 8b 45 10 mov 0x10(%ebp),%eax + 1046ce: 8b 55 f4 mov -0xc(%ebp),%edx + 1046d1: 89 10 mov %edx,(%eax) + } + // 检查 ptep 是否有效以及页表项的存在位 PTE_P 是否被设置 + if (ptep != NULL && *ptep & PTE_P) { + 1046d3: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) + 1046d7: 74 1b je 1046f4 + 1046d9: 8b 45 f4 mov -0xc(%ebp),%eax + 1046dc: 8b 00 mov (%eax),%eax + 1046de: 83 e0 01 and $0x1,%eax + 1046e1: 85 c0 test %eax,%eax + 1046e3: 74 0f je 1046f4 + // 返回与页表项对应的 Page 结构体 + return pte2page(*ptep);// 将页表项转换为对应的 Page 结构 + 1046e5: 8b 45 f4 mov -0xc(%ebp),%eax + 1046e8: 8b 00 mov (%eax),%eax + 1046ea: 89 04 24 mov %eax,(%esp) + 1046ed: e8 79 f5 ff ff call 103c6b + 1046f2: eb 05 jmp 1046f9 + } + // 如果未找到有效的页,返回 NULL + return NULL; + 1046f4: b8 00 00 00 00 mov $0x0,%eax +} + 1046f9: 89 ec mov %ebp,%esp + 1046fb: 5d pop %ebp + 1046fc: c3 ret + +001046fd : + +//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) { + 1046fd: 55 push %ebp + 1046fe: 89 e5 mov %esp,%ebp + 104700: 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) { + 104703: 8b 45 10 mov 0x10(%ebp),%eax + 104706: 8b 00 mov (%eax),%eax + 104708: 83 e0 01 and $0x1,%eax + 10470b: 85 c0 test %eax,%eax + 10470d: 74 4d je 10475c + struct Page *page = pte2page(*ptep);// 找到对应的物理页 + 10470f: 8b 45 10 mov 0x10(%ebp),%eax + 104712: 8b 00 mov (%eax),%eax + 104714: 89 04 24 mov %eax,(%esp) + 104717: e8 4f f5 ff ff call 103c6b + 10471c: 89 45 f4 mov %eax,-0xc(%ebp) + // 减少物理页的引用计数,如果引用计数为零,释放该物理页 + if (page_ref_dec(page) == 0) { + 10471f: 8b 45 f4 mov -0xc(%ebp),%eax + 104722: 89 04 24 mov %eax,(%esp) + 104725: e8 ca f5 ff ff call 103cf4 + 10472a: 85 c0 test %eax,%eax + 10472c: 75 13 jne 104741 + free_page(page); + 10472e: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) + 104735: 00 + 104736: 8b 45 f4 mov -0xc(%ebp),%eax + 104739: 89 04 24 mov %eax,(%esp) + 10473c: e8 ce f7 ff ff call 103f0f + } + *ptep = 0;// 清除页表项 + 104741: 8b 45 10 mov 0x10(%ebp),%eax + 104744: c7 00 00 00 00 00 movl $0x0,(%eax) + tlb_invalidate(pgdir, la);// 刷新 TLB + 10474a: 8b 45 0c mov 0xc(%ebp),%eax + 10474d: 89 44 24 04 mov %eax,0x4(%esp) + 104751: 8b 45 08 mov 0x8(%ebp),%eax + 104754: 89 04 24 mov %eax,(%esp) + 104757: e8 07 01 00 00 call 104863 + } +} + 10475c: 90 nop + 10475d: 89 ec mov %ebp,%esp + 10475f: 5d pop %ebp + 104760: c3 ret + +00104761 : + +//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) { + 104761: 55 push %ebp + 104762: 89 e5 mov %esp,%ebp + 104764: 83 ec 28 sub $0x28,%esp + //调用 get_pte 函数获取给定虚拟地址 la 对应的页表项指针 ptep。 + pte_t *ptep = get_pte(pgdir, la, 0); + 104767: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) + 10476e: 00 + 10476f: 8b 45 0c mov 0xc(%ebp),%eax + 104772: 89 44 24 04 mov %eax,0x4(%esp) + 104776: 8b 45 08 mov 0x8(%ebp),%eax + 104779: 89 04 24 mov %eax,(%esp) + 10477c: e8 e6 fd ff ff call 104567 + 104781: 89 45 f4 mov %eax,-0xc(%ebp) + //如果 ptep 不为 NULL,则调用 page_remove_pte 函数移除该页表项。 + if (ptep != NULL) { + 104784: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) + 104788: 74 19 je 1047a3 + page_remove_pte(pgdir, la, ptep); + 10478a: 8b 45 f4 mov -0xc(%ebp),%eax + 10478d: 89 44 24 08 mov %eax,0x8(%esp) + 104791: 8b 45 0c mov 0xc(%ebp),%eax + 104794: 89 44 24 04 mov %eax,0x4(%esp) + 104798: 8b 45 08 mov 0x8(%ebp),%eax + 10479b: 89 04 24 mov %eax,(%esp) + 10479e: e8 5a ff ff ff call 1046fd + } +} + 1047a3: 90 nop + 1047a4: 89 ec mov %ebp,%esp + 1047a6: 5d pop %ebp + 1047a7: c3 ret + +001047a8 : +// 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) { + 1047a8: 55 push %ebp + 1047a9: 89 e5 mov %esp,%ebp + 1047ab: 83 ec 28 sub $0x28,%esp + //通过 get_pte 函数获取指定虚拟地址 la 对应的页表项指针 ptep。 + pte_t *ptep = get_pte(pgdir, la, 1); + 1047ae: c7 44 24 08 01 00 00 movl $0x1,0x8(%esp) + 1047b5: 00 + 1047b6: 8b 45 10 mov 0x10(%ebp),%eax + 1047b9: 89 44 24 04 mov %eax,0x4(%esp) + 1047bd: 8b 45 08 mov 0x8(%ebp),%eax + 1047c0: 89 04 24 mov %eax,(%esp) + 1047c3: e8 9f fd ff ff call 104567 + 1047c8: 89 45 f4 mov %eax,-0xc(%ebp) + //如果 ptep 为 NULL,表示内存分配失败,返回 -E_NO_MEM。 + if (ptep == NULL) { + 1047cb: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) + 1047cf: 75 0a jne 1047db + return -E_NO_MEM; + 1047d1: b8 fc ff ff ff mov $0xfffffffc,%eax + 1047d6: e9 84 00 00 00 jmp 10485f + } + //调用 page_ref_inc 增加页面的引用计数。 + page_ref_inc(page); + 1047db: 8b 45 0c mov 0xc(%ebp),%eax + 1047de: 89 04 24 mov %eax,(%esp) + 1047e1: e8 f7 f4 ff ff call 103cdd + //如果页表项已存在且指向当前页面,则减少页面引用计数。 + if (*ptep & PTE_P) { + 1047e6: 8b 45 f4 mov -0xc(%ebp),%eax + 1047e9: 8b 00 mov (%eax),%eax + 1047eb: 83 e0 01 and $0x1,%eax + 1047ee: 85 c0 test %eax,%eax + 1047f0: 74 3e je 104830 + struct Page *p = pte2page(*ptep); + 1047f2: 8b 45 f4 mov -0xc(%ebp),%eax + 1047f5: 8b 00 mov (%eax),%eax + 1047f7: 89 04 24 mov %eax,(%esp) + 1047fa: e8 6c f4 ff ff call 103c6b + 1047ff: 89 45 f0 mov %eax,-0x10(%ebp) + if (p == page) { + 104802: 8b 45 f0 mov -0x10(%ebp),%eax + 104805: 3b 45 0c cmp 0xc(%ebp),%eax + 104808: 75 0d jne 104817 + page_ref_dec(page); + 10480a: 8b 45 0c mov 0xc(%ebp),%eax + 10480d: 89 04 24 mov %eax,(%esp) + 104810: e8 df f4 ff ff call 103cf4 + 104815: eb 19 jmp 104830 + } + //如果页表项已存在但指向其他页面,则调用 page_remove_pte 移除旧的页表项。 + else { + page_remove_pte(pgdir, la, ptep); + 104817: 8b 45 f4 mov -0xc(%ebp),%eax + 10481a: 89 44 24 08 mov %eax,0x8(%esp) + 10481e: 8b 45 10 mov 0x10(%ebp),%eax + 104821: 89 44 24 04 mov %eax,0x4(%esp) + 104825: 8b 45 08 mov 0x8(%ebp),%eax + 104828: 89 04 24 mov %eax,(%esp) + 10482b: e8 cd fe ff ff call 1046fd + } + } + *ptep = page2pa(page) | PTE_P | perm; + 104830: 8b 45 0c mov 0xc(%ebp),%eax + 104833: 89 04 24 mov %eax,(%esp) + 104836: e8 71 f3 ff ff call 103bac + 10483b: 0b 45 14 or 0x14(%ebp),%eax + 10483e: 83 c8 01 or $0x1,%eax + 104841: 89 c2 mov %eax,%edx + 104843: 8b 45 f4 mov -0xc(%ebp),%eax + 104846: 89 10 mov %edx,(%eax) + tlb_invalidate(pgdir, la);//刷新 TLB + 104848: 8b 45 10 mov 0x10(%ebp),%eax + 10484b: 89 44 24 04 mov %eax,0x4(%esp) + 10484f: 8b 45 08 mov 0x8(%ebp),%eax + 104852: 89 04 24 mov %eax,(%esp) + 104855: e8 09 00 00 00 call 104863 + return 0; + 10485a: b8 00 00 00 00 mov $0x0,%eax +} + 10485f: 89 ec mov %ebp,%esp + 104861: 5d pop %ebp + 104862: c3 ret + +00104863 : + +// 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) { + 104863: 55 push %ebp + 104864: 89 e5 mov %esp,%ebp + 104866: 83 ec 28 sub $0x28,%esp +} + +static inline uintptr_t +rcr3(void) { + uintptr_t cr3; + asm volatile ("mov %%cr3, %0" : "=r" (cr3) :: "memory"); + 104869: 0f 20 d8 mov %cr3,%eax + 10486c: 89 45 f0 mov %eax,-0x10(%ebp) + return cr3; + 10486f: 8b 55 f0 mov -0x10(%ebp),%edx + //检查当前页目录地址是否与传入的页目录地址相同。 + if (rcr3() == PADDR(pgdir)) { + 104872: 8b 45 08 mov 0x8(%ebp),%eax + 104875: 89 45 f4 mov %eax,-0xc(%ebp) + 104878: 81 7d f4 ff ff ff bf cmpl $0xbfffffff,-0xc(%ebp) + 10487f: 77 23 ja 1048a4 + 104881: 8b 45 f4 mov -0xc(%ebp),%eax + 104884: 89 44 24 0c mov %eax,0xc(%esp) + 104888: c7 44 24 08 28 6c 10 movl $0x106c28,0x8(%esp) + 10488f: 00 + 104890: c7 44 24 04 47 02 00 movl $0x247,0x4(%esp) + 104897: 00 + 104898: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 10489f: e8 8f c3 ff ff call 100c33 <__panic> + 1048a4: 8b 45 f4 mov -0xc(%ebp),%eax + 1048a7: 05 00 00 00 40 add $0x40000000,%eax + 1048ac: 39 d0 cmp %edx,%eax + 1048ae: 75 0d jne 1048bd + //如果相同,则调用 invlpg 函数无效化指定线性地址的TLB条目。 + invlpg((void *)la); + 1048b0: 8b 45 0c mov 0xc(%ebp),%eax + 1048b3: 89 45 ec mov %eax,-0x14(%ebp) +} + +static inline void +invlpg(void *addr) { + asm volatile ("invlpg (%0)" :: "r" (addr) : "memory"); + 1048b6: 8b 45 ec mov -0x14(%ebp),%eax + 1048b9: 0f 01 38 invlpg (%eax) +} + 1048bc: 90 nop + } +} + 1048bd: 90 nop + 1048be: 89 ec mov %ebp,%esp + 1048c0: 5d pop %ebp + 1048c1: c3 ret + +001048c2 : + +static void +check_alloc_page(void) { + 1048c2: 55 push %ebp + 1048c3: 89 e5 mov %esp,%ebp + 1048c5: 83 ec 18 sub $0x18,%esp + //调用内存管理器的 check 方法,用于检查内存分配是否正常。 + pmm_manager->check(); + 1048c8: a1 0c cf 11 00 mov 0x11cf0c,%eax + 1048cd: 8b 40 18 mov 0x18(%eax),%eax + 1048d0: ff d0 call *%eax + cprintf("check_alloc_page() succeeded!\n"); + 1048d2: c7 04 24 ac 6c 10 00 movl $0x106cac,(%esp) + 1048d9: e8 88 ba ff ff call 100366 +} + 1048de: 90 nop + 1048df: 89 ec mov %ebp,%esp + 1048e1: 5d pop %ebp + 1048e2: c3 ret + +001048e3 : +//用于验证页目录和页表的正确性。 +static void +check_pgdir(void) { + 1048e3: 55 push %ebp + 1048e4: 89 e5 mov %esp,%ebp + 1048e6: 83 ec 38 sub $0x38,%esp + //确保内存页面数量在合理范围内 + assert(npage <= KMEMSIZE / PGSIZE); + 1048e9: a1 04 cf 11 00 mov 0x11cf04,%eax + 1048ee: 3d 00 80 03 00 cmp $0x38000,%eax + 1048f3: 76 24 jbe 104919 + 1048f5: c7 44 24 0c cb 6c 10 movl $0x106ccb,0xc(%esp) + 1048fc: 00 + 1048fd: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 104904: 00 + 104905: c7 44 24 04 57 02 00 movl $0x257,0x4(%esp) + 10490c: 00 + 10490d: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 104914: e8 1a c3 ff ff call 100c33 <__panic> + //确保页目录不为空且对齐, + assert(boot_pgdir != NULL && (uint32_t)PGOFF(boot_pgdir) == 0); + 104919: a1 e0 99 11 00 mov 0x1199e0,%eax + 10491e: 85 c0 test %eax,%eax + 104920: 74 0e je 104930 + 104922: a1 e0 99 11 00 mov 0x1199e0,%eax + 104927: 25 ff 0f 00 00 and $0xfff,%eax + 10492c: 85 c0 test %eax,%eax + 10492e: 74 24 je 104954 + 104930: c7 44 24 0c e8 6c 10 movl $0x106ce8,0xc(%esp) + 104937: 00 + 104938: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 10493f: 00 + 104940: c7 44 24 04 59 02 00 movl $0x259,0x4(%esp) + 104947: 00 + 104948: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 10494f: e8 df c2 ff ff call 100c33 <__panic> + //确保虚拟地址 0x0 没有映射任何页面 + assert(get_page(boot_pgdir, 0x0, NULL) == NULL); + 104954: a1 e0 99 11 00 mov 0x1199e0,%eax + 104959: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) + 104960: 00 + 104961: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) + 104968: 00 + 104969: 89 04 24 mov %eax,(%esp) + 10496c: e8 31 fd ff ff call 1046a2 + 104971: 85 c0 test %eax,%eax + 104973: 74 24 je 104999 + 104975: c7 44 24 0c 20 6d 10 movl $0x106d20,0xc(%esp) + 10497c: 00 + 10497d: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 104984: 00 + 104985: c7 44 24 04 5b 02 00 movl $0x25b,0x4(%esp) + 10498c: 00 + 10498d: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 104994: e8 9a c2 ff ff call 100c33 <__panic> + + //定义两个页面指针 p1 和 p2 + struct Page *p1, *p2; + //分配一个页面 p1 + p1 = alloc_page(); + 104999: c7 04 24 01 00 00 00 movl $0x1,(%esp) + 1049a0: e8 30 f5 ff ff call 103ed5 + 1049a5: 89 45 f4 mov %eax,-0xc(%ebp) + //将 p1 插入到虚拟地址 0x0 + assert(page_insert(boot_pgdir, p1, 0x0, 0) == 0); + 1049a8: a1 e0 99 11 00 mov 0x1199e0,%eax + 1049ad: c7 44 24 0c 00 00 00 movl $0x0,0xc(%esp) + 1049b4: 00 + 1049b5: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) + 1049bc: 00 + 1049bd: 8b 55 f4 mov -0xc(%ebp),%edx + 1049c0: 89 54 24 04 mov %edx,0x4(%esp) + 1049c4: 89 04 24 mov %eax,(%esp) + 1049c7: e8 dc fd ff ff call 1047a8 + 1049cc: 85 c0 test %eax,%eax + 1049ce: 74 24 je 1049f4 + 1049d0: c7 44 24 0c 48 6d 10 movl $0x106d48,0xc(%esp) + 1049d7: 00 + 1049d8: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 1049df: 00 + 1049e0: c7 44 24 04 62 02 00 movl $0x262,0x4(%esp) + 1049e7: 00 + 1049e8: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 1049ef: e8 3f c2 ff ff call 100c33 <__panic> + + // 获取虚拟地址 0x0 对应的页表项指针 + pte_t *ptep; + assert((ptep = get_pte(boot_pgdir, 0x0, 0)) != NULL); + 1049f4: a1 e0 99 11 00 mov 0x1199e0,%eax + 1049f9: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) + 104a00: 00 + 104a01: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) + 104a08: 00 + 104a09: 89 04 24 mov %eax,(%esp) + 104a0c: e8 56 fb ff ff call 104567 + 104a11: 89 45 f0 mov %eax,-0x10(%ebp) + 104a14: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) + 104a18: 75 24 jne 104a3e + 104a1a: c7 44 24 0c 74 6d 10 movl $0x106d74,0xc(%esp) + 104a21: 00 + 104a22: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 104a29: 00 + 104a2a: c7 44 24 04 66 02 00 movl $0x266,0x4(%esp) + 104a31: 00 + 104a32: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 104a39: e8 f5 c1 ff ff call 100c33 <__panic> + // 验证页表项对应的页面是 p1 + assert(pte2page(*ptep) == p1); + 104a3e: 8b 45 f0 mov -0x10(%ebp),%eax + 104a41: 8b 00 mov (%eax),%eax + 104a43: 89 04 24 mov %eax,(%esp) + 104a46: e8 20 f2 ff ff call 103c6b + 104a4b: 39 45 f4 cmp %eax,-0xc(%ebp) + 104a4e: 74 24 je 104a74 + 104a50: c7 44 24 0c a1 6d 10 movl $0x106da1,0xc(%esp) + 104a57: 00 + 104a58: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 104a5f: 00 + 104a60: c7 44 24 04 68 02 00 movl $0x268,0x4(%esp) + 104a67: 00 + 104a68: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 104a6f: e8 bf c1 ff ff call 100c33 <__panic> + // 验证 p1 的引用计数为 1 + assert(page_ref(p1) == 1); + 104a74: 8b 45 f4 mov -0xc(%ebp),%eax + 104a77: 89 04 24 mov %eax,(%esp) + 104a7a: e8 46 f2 ff ff call 103cc5 + 104a7f: 83 f8 01 cmp $0x1,%eax + 104a82: 74 24 je 104aa8 + 104a84: c7 44 24 0c b7 6d 10 movl $0x106db7,0xc(%esp) + 104a8b: 00 + 104a8c: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 104a93: 00 + 104a94: c7 44 24 04 6a 02 00 movl $0x26a,0x4(%esp) + 104a9b: 00 + 104a9c: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 104aa3: e8 8b c1 ff ff call 100c33 <__panic> + // 获取虚拟地址 PGSIZE 对应的页表项指针 + ptep = &((pte_t *)KADDR(PDE_ADDR(boot_pgdir[0])))[1]; + 104aa8: a1 e0 99 11 00 mov 0x1199e0,%eax + 104aad: 8b 00 mov (%eax),%eax + 104aaf: 25 00 f0 ff ff and $0xfffff000,%eax + 104ab4: 89 45 ec mov %eax,-0x14(%ebp) + 104ab7: 8b 45 ec mov -0x14(%ebp),%eax + 104aba: c1 e8 0c shr $0xc,%eax + 104abd: 89 45 e8 mov %eax,-0x18(%ebp) + 104ac0: a1 04 cf 11 00 mov 0x11cf04,%eax + 104ac5: 39 45 e8 cmp %eax,-0x18(%ebp) + 104ac8: 72 23 jb 104aed + 104aca: 8b 45 ec mov -0x14(%ebp),%eax + 104acd: 89 44 24 0c mov %eax,0xc(%esp) + 104ad1: c7 44 24 08 84 6b 10 movl $0x106b84,0x8(%esp) + 104ad8: 00 + 104ad9: c7 44 24 04 6c 02 00 movl $0x26c,0x4(%esp) + 104ae0: 00 + 104ae1: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 104ae8: e8 46 c1 ff ff call 100c33 <__panic> + 104aed: 8b 45 ec mov -0x14(%ebp),%eax + 104af0: 2d 00 00 00 40 sub $0x40000000,%eax + 104af5: 83 c0 04 add $0x4,%eax + 104af8: 89 45 f0 mov %eax,-0x10(%ebp) + assert(get_pte(boot_pgdir, PGSIZE, 0) == ptep); + 104afb: a1 e0 99 11 00 mov 0x1199e0,%eax + 104b00: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) + 104b07: 00 + 104b08: c7 44 24 04 00 10 00 movl $0x1000,0x4(%esp) + 104b0f: 00 + 104b10: 89 04 24 mov %eax,(%esp) + 104b13: e8 4f fa ff ff call 104567 + 104b18: 39 45 f0 cmp %eax,-0x10(%ebp) + 104b1b: 74 24 je 104b41 + 104b1d: c7 44 24 0c cc 6d 10 movl $0x106dcc,0xc(%esp) + 104b24: 00 + 104b25: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 104b2c: 00 + 104b2d: c7 44 24 04 6d 02 00 movl $0x26d,0x4(%esp) + 104b34: 00 + 104b35: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 104b3c: e8 f2 c0 ff ff call 100c33 <__panic> + // 分配一个页面 p2 + p2 = alloc_page(); + 104b41: c7 04 24 01 00 00 00 movl $0x1,(%esp) + 104b48: e8 88 f3 ff ff call 103ed5 + 104b4d: 89 45 e4 mov %eax,-0x1c(%ebp) + // 将 p2 插入到虚拟地址 PGSIZE,并设置用户和写权限 + assert(page_insert(boot_pgdir, p2, PGSIZE, PTE_U | PTE_W) == 0); + 104b50: a1 e0 99 11 00 mov 0x1199e0,%eax + 104b55: c7 44 24 0c 06 00 00 movl $0x6,0xc(%esp) + 104b5c: 00 + 104b5d: c7 44 24 08 00 10 00 movl $0x1000,0x8(%esp) + 104b64: 00 + 104b65: 8b 55 e4 mov -0x1c(%ebp),%edx + 104b68: 89 54 24 04 mov %edx,0x4(%esp) + 104b6c: 89 04 24 mov %eax,(%esp) + 104b6f: e8 34 fc ff ff call 1047a8 + 104b74: 85 c0 test %eax,%eax + 104b76: 74 24 je 104b9c + 104b78: c7 44 24 0c f4 6d 10 movl $0x106df4,0xc(%esp) + 104b7f: 00 + 104b80: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 104b87: 00 + 104b88: c7 44 24 04 71 02 00 movl $0x271,0x4(%esp) + 104b8f: 00 + 104b90: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 104b97: e8 97 c0 ff ff call 100c33 <__panic> + // 获取虚拟地址 PGSIZE 对应的页表项指针 + assert((ptep = get_pte(boot_pgdir, PGSIZE, 0)) != NULL); + 104b9c: a1 e0 99 11 00 mov 0x1199e0,%eax + 104ba1: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) + 104ba8: 00 + 104ba9: c7 44 24 04 00 10 00 movl $0x1000,0x4(%esp) + 104bb0: 00 + 104bb1: 89 04 24 mov %eax,(%esp) + 104bb4: e8 ae f9 ff ff call 104567 + 104bb9: 89 45 f0 mov %eax,-0x10(%ebp) + 104bbc: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) + 104bc0: 75 24 jne 104be6 + 104bc2: c7 44 24 0c 2c 6e 10 movl $0x106e2c,0xc(%esp) + 104bc9: 00 + 104bca: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 104bd1: 00 + 104bd2: c7 44 24 04 73 02 00 movl $0x273,0x4(%esp) + 104bd9: 00 + 104bda: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 104be1: e8 4d c0 ff ff call 100c33 <__panic> + // 验证页表项设置了用户权限 + assert(*ptep & PTE_U); + 104be6: 8b 45 f0 mov -0x10(%ebp),%eax + 104be9: 8b 00 mov (%eax),%eax + 104beb: 83 e0 04 and $0x4,%eax + 104bee: 85 c0 test %eax,%eax + 104bf0: 75 24 jne 104c16 + 104bf2: c7 44 24 0c 5c 6e 10 movl $0x106e5c,0xc(%esp) + 104bf9: 00 + 104bfa: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 104c01: 00 + 104c02: c7 44 24 04 75 02 00 movl $0x275,0x4(%esp) + 104c09: 00 + 104c0a: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 104c11: e8 1d c0 ff ff call 100c33 <__panic> + // 验证页表项设置了写权限 + assert(*ptep & PTE_W); + 104c16: 8b 45 f0 mov -0x10(%ebp),%eax + 104c19: 8b 00 mov (%eax),%eax + 104c1b: 83 e0 02 and $0x2,%eax + 104c1e: 85 c0 test %eax,%eax + 104c20: 75 24 jne 104c46 + 104c22: c7 44 24 0c 6a 6e 10 movl $0x106e6a,0xc(%esp) + 104c29: 00 + 104c2a: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 104c31: 00 + 104c32: c7 44 24 04 77 02 00 movl $0x277,0x4(%esp) + 104c39: 00 + 104c3a: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 104c41: e8 ed bf ff ff call 100c33 <__panic> + // 验证页目录项设置了用户权限 + assert(boot_pgdir[0] & PTE_U); + 104c46: a1 e0 99 11 00 mov 0x1199e0,%eax + 104c4b: 8b 00 mov (%eax),%eax + 104c4d: 83 e0 04 and $0x4,%eax + 104c50: 85 c0 test %eax,%eax + 104c52: 75 24 jne 104c78 + 104c54: c7 44 24 0c 78 6e 10 movl $0x106e78,0xc(%esp) + 104c5b: 00 + 104c5c: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 104c63: 00 + 104c64: c7 44 24 04 79 02 00 movl $0x279,0x4(%esp) + 104c6b: 00 + 104c6c: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 104c73: e8 bb bf ff ff call 100c33 <__panic> + // 验证 p2 的引用计数为 1 + assert(page_ref(p2) == 1); + 104c78: 8b 45 e4 mov -0x1c(%ebp),%eax + 104c7b: 89 04 24 mov %eax,(%esp) + 104c7e: e8 42 f0 ff ff call 103cc5 + 104c83: 83 f8 01 cmp $0x1,%eax + 104c86: 74 24 je 104cac + 104c88: c7 44 24 0c 8e 6e 10 movl $0x106e8e,0xc(%esp) + 104c8f: 00 + 104c90: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 104c97: 00 + 104c98: c7 44 24 04 7b 02 00 movl $0x27b,0x4(%esp) + 104c9f: 00 + 104ca0: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 104ca7: e8 87 bf ff ff call 100c33 <__panic> + + // 将 p1 插入到虚拟地址 PGSIZE,替换掉 p2 + assert(page_insert(boot_pgdir, p1, PGSIZE, 0) == 0); + 104cac: a1 e0 99 11 00 mov 0x1199e0,%eax + 104cb1: c7 44 24 0c 00 00 00 movl $0x0,0xc(%esp) + 104cb8: 00 + 104cb9: c7 44 24 08 00 10 00 movl $0x1000,0x8(%esp) + 104cc0: 00 + 104cc1: 8b 55 f4 mov -0xc(%ebp),%edx + 104cc4: 89 54 24 04 mov %edx,0x4(%esp) + 104cc8: 89 04 24 mov %eax,(%esp) + 104ccb: e8 d8 fa ff ff call 1047a8 + 104cd0: 85 c0 test %eax,%eax + 104cd2: 74 24 je 104cf8 + 104cd4: c7 44 24 0c a0 6e 10 movl $0x106ea0,0xc(%esp) + 104cdb: 00 + 104cdc: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 104ce3: 00 + 104ce4: c7 44 24 04 7e 02 00 movl $0x27e,0x4(%esp) + 104ceb: 00 + 104cec: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 104cf3: e8 3b bf ff ff call 100c33 <__panic> + // 验证 p1 的引用计数增加到 2 + assert(page_ref(p1) == 2); + 104cf8: 8b 45 f4 mov -0xc(%ebp),%eax + 104cfb: 89 04 24 mov %eax,(%esp) + 104cfe: e8 c2 ef ff ff call 103cc5 + 104d03: 83 f8 02 cmp $0x2,%eax + 104d06: 74 24 je 104d2c + 104d08: c7 44 24 0c cc 6e 10 movl $0x106ecc,0xc(%esp) + 104d0f: 00 + 104d10: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 104d17: 00 + 104d18: c7 44 24 04 80 02 00 movl $0x280,0x4(%esp) + 104d1f: 00 + 104d20: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 104d27: e8 07 bf ff ff call 100c33 <__panic> + // 验证 p2 的引用计数减少到 0 + assert(page_ref(p2) == 0); + 104d2c: 8b 45 e4 mov -0x1c(%ebp),%eax + 104d2f: 89 04 24 mov %eax,(%esp) + 104d32: e8 8e ef ff ff call 103cc5 + 104d37: 85 c0 test %eax,%eax + 104d39: 74 24 je 104d5f + 104d3b: c7 44 24 0c de 6e 10 movl $0x106ede,0xc(%esp) + 104d42: 00 + 104d43: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 104d4a: 00 + 104d4b: c7 44 24 04 82 02 00 movl $0x282,0x4(%esp) + 104d52: 00 + 104d53: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 104d5a: e8 d4 be ff ff call 100c33 <__panic> + // 获取虚拟地址 PGSIZE 对应的页表项指针 + assert((ptep = get_pte(boot_pgdir, PGSIZE, 0)) != NULL); + 104d5f: a1 e0 99 11 00 mov 0x1199e0,%eax + 104d64: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) + 104d6b: 00 + 104d6c: c7 44 24 04 00 10 00 movl $0x1000,0x4(%esp) + 104d73: 00 + 104d74: 89 04 24 mov %eax,(%esp) + 104d77: e8 eb f7 ff ff call 104567 + 104d7c: 89 45 f0 mov %eax,-0x10(%ebp) + 104d7f: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) + 104d83: 75 24 jne 104da9 + 104d85: c7 44 24 0c 2c 6e 10 movl $0x106e2c,0xc(%esp) + 104d8c: 00 + 104d8d: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 104d94: 00 + 104d95: c7 44 24 04 84 02 00 movl $0x284,0x4(%esp) + 104d9c: 00 + 104d9d: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 104da4: e8 8a be ff ff call 100c33 <__panic> + // 验证页表项对应的页面是 p1 + assert(pte2page(*ptep) == p1); + 104da9: 8b 45 f0 mov -0x10(%ebp),%eax + 104dac: 8b 00 mov (%eax),%eax + 104dae: 89 04 24 mov %eax,(%esp) + 104db1: e8 b5 ee ff ff call 103c6b + 104db6: 39 45 f4 cmp %eax,-0xc(%ebp) + 104db9: 74 24 je 104ddf + 104dbb: c7 44 24 0c a1 6d 10 movl $0x106da1,0xc(%esp) + 104dc2: 00 + 104dc3: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 104dca: 00 + 104dcb: c7 44 24 04 86 02 00 movl $0x286,0x4(%esp) + 104dd2: 00 + 104dd3: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 104dda: e8 54 be ff ff call 100c33 <__panic> + // 验证页表项没有设置用户权限 + assert((*ptep & PTE_U) == 0); + 104ddf: 8b 45 f0 mov -0x10(%ebp),%eax + 104de2: 8b 00 mov (%eax),%eax + 104de4: 83 e0 04 and $0x4,%eax + 104de7: 85 c0 test %eax,%eax + 104de9: 74 24 je 104e0f + 104deb: c7 44 24 0c f0 6e 10 movl $0x106ef0,0xc(%esp) + 104df2: 00 + 104df3: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 104dfa: 00 + 104dfb: c7 44 24 04 88 02 00 movl $0x288,0x4(%esp) + 104e02: 00 + 104e03: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 104e0a: e8 24 be ff ff call 100c33 <__panic> + + //移除虚拟地址 0x0 的映射, + page_remove(boot_pgdir, 0x0); + 104e0f: a1 e0 99 11 00 mov 0x1199e0,%eax + 104e14: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) + 104e1b: 00 + 104e1c: 89 04 24 mov %eax,(%esp) + 104e1f: e8 3d f9 ff ff call 104761 + //验证 p1 的引用计数减少到 1。 + assert(page_ref(p1) == 1); + 104e24: 8b 45 f4 mov -0xc(%ebp),%eax + 104e27: 89 04 24 mov %eax,(%esp) + 104e2a: e8 96 ee ff ff call 103cc5 + 104e2f: 83 f8 01 cmp $0x1,%eax + 104e32: 74 24 je 104e58 + 104e34: c7 44 24 0c b7 6d 10 movl $0x106db7,0xc(%esp) + 104e3b: 00 + 104e3c: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 104e43: 00 + 104e44: c7 44 24 04 8d 02 00 movl $0x28d,0x4(%esp) + 104e4b: 00 + 104e4c: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 104e53: e8 db bd ff ff call 100c33 <__panic> + //验证 p2 的引用计数减少到 0 + assert(page_ref(p2) == 0); + 104e58: 8b 45 e4 mov -0x1c(%ebp),%eax + 104e5b: 89 04 24 mov %eax,(%esp) + 104e5e: e8 62 ee ff ff call 103cc5 + 104e63: 85 c0 test %eax,%eax + 104e65: 74 24 je 104e8b + 104e67: c7 44 24 0c de 6e 10 movl $0x106ede,0xc(%esp) + 104e6e: 00 + 104e6f: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 104e76: 00 + 104e77: c7 44 24 04 8f 02 00 movl $0x28f,0x4(%esp) + 104e7e: 00 + 104e7f: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 104e86: e8 a8 bd ff ff call 100c33 <__panic> + + //移除虚拟地址 PGSIZE 的映射, + page_remove(boot_pgdir, PGSIZE); + 104e8b: a1 e0 99 11 00 mov 0x1199e0,%eax + 104e90: c7 44 24 04 00 10 00 movl $0x1000,0x4(%esp) + 104e97: 00 + 104e98: 89 04 24 mov %eax,(%esp) + 104e9b: e8 c1 f8 ff ff call 104761 + //验证 p1 的引用计数减少到 0 + assert(page_ref(p1) == 0); + 104ea0: 8b 45 f4 mov -0xc(%ebp),%eax + 104ea3: 89 04 24 mov %eax,(%esp) + 104ea6: e8 1a ee ff ff call 103cc5 + 104eab: 85 c0 test %eax,%eax + 104ead: 74 24 je 104ed3 + 104eaf: c7 44 24 0c 05 6f 10 movl $0x106f05,0xc(%esp) + 104eb6: 00 + 104eb7: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 104ebe: 00 + 104ebf: c7 44 24 04 94 02 00 movl $0x294,0x4(%esp) + 104ec6: 00 + 104ec7: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 104ece: e8 60 bd ff ff call 100c33 <__panic> + //验证 p2 的引用计数减少到 0 + assert(page_ref(p2) == 0); + 104ed3: 8b 45 e4 mov -0x1c(%ebp),%eax + 104ed6: 89 04 24 mov %eax,(%esp) + 104ed9: e8 e7 ed ff ff call 103cc5 + 104ede: 85 c0 test %eax,%eax + 104ee0: 74 24 je 104f06 + 104ee2: c7 44 24 0c de 6e 10 movl $0x106ede,0xc(%esp) + 104ee9: 00 + 104eea: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 104ef1: 00 + 104ef2: c7 44 24 04 96 02 00 movl $0x296,0x4(%esp) + 104ef9: 00 + 104efa: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 104f01: e8 2d bd ff ff call 100c33 <__panic> + + //验证页目录的第一页表的引用计数为 1。 + assert(page_ref(pde2page(boot_pgdir[0])) == 1); + 104f06: a1 e0 99 11 00 mov 0x1199e0,%eax + 104f0b: 8b 00 mov (%eax),%eax + 104f0d: 89 04 24 mov %eax,(%esp) + 104f10: e8 96 ed ff ff call 103cab + 104f15: 89 04 24 mov %eax,(%esp) + 104f18: e8 a8 ed ff ff call 103cc5 + 104f1d: 83 f8 01 cmp $0x1,%eax + 104f20: 74 24 je 104f46 + 104f22: c7 44 24 0c 18 6f 10 movl $0x106f18,0xc(%esp) + 104f29: 00 + 104f2a: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 104f31: 00 + 104f32: c7 44 24 04 99 02 00 movl $0x299,0x4(%esp) + 104f39: 00 + 104f3a: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 104f41: e8 ed bc ff ff call 100c33 <__panic> + //释放页目录的第一页表 + free_page(pde2page(boot_pgdir[0])); + 104f46: a1 e0 99 11 00 mov 0x1199e0,%eax + 104f4b: 8b 00 mov (%eax),%eax + 104f4d: 89 04 24 mov %eax,(%esp) + 104f50: e8 56 ed ff ff call 103cab + 104f55: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) + 104f5c: 00 + 104f5d: 89 04 24 mov %eax,(%esp) + 104f60: e8 aa ef ff ff call 103f0f + //清空页目录的第一页表 + boot_pgdir[0] = 0; + 104f65: a1 e0 99 11 00 mov 0x1199e0,%eax + 104f6a: c7 00 00 00 00 00 movl $0x0,(%eax) + + cprintf("check_pgdir() succeeded!\n"); + 104f70: c7 04 24 3f 6f 10 00 movl $0x106f3f,(%esp) + 104f77: e8 ea b3 ff ff call 100366 +} + 104f7c: 90 nop + 104f7d: 89 ec mov %ebp,%esp + 104f7f: 5d pop %ebp + 104f80: c3 ret + +00104f81 : + +//检查内核页表 boot_pgdir 的正确性 +static void +check_boot_pgdir(void) { + 104f81: 55 push %ebp + 104f82: 89 e5 mov %esp,%ebp + 104f84: 83 ec 38 sub $0x38,%esp + pte_t *ptep;// 定义一个指向页表项的指针 + int i; + for (i = 0; i < npage; i += PGSIZE) {// 遍历所有页面 + 104f87: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + 104f8e: e9 ca 00 00 00 jmp 10505d + // 获取第 i 个页面的页表项,并确保其不为空 + assert((ptep = get_pte(boot_pgdir, (uintptr_t)KADDR(i), 0)) != NULL); + 104f93: 8b 45 f4 mov -0xc(%ebp),%eax + 104f96: 89 45 e4 mov %eax,-0x1c(%ebp) + 104f99: 8b 45 e4 mov -0x1c(%ebp),%eax + 104f9c: c1 e8 0c shr $0xc,%eax + 104f9f: 89 45 e0 mov %eax,-0x20(%ebp) + 104fa2: a1 04 cf 11 00 mov 0x11cf04,%eax + 104fa7: 39 45 e0 cmp %eax,-0x20(%ebp) + 104faa: 72 23 jb 104fcf + 104fac: 8b 45 e4 mov -0x1c(%ebp),%eax + 104faf: 89 44 24 0c mov %eax,0xc(%esp) + 104fb3: c7 44 24 08 84 6b 10 movl $0x106b84,0x8(%esp) + 104fba: 00 + 104fbb: c7 44 24 04 a9 02 00 movl $0x2a9,0x4(%esp) + 104fc2: 00 + 104fc3: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 104fca: e8 64 bc ff ff call 100c33 <__panic> + 104fcf: 8b 45 e4 mov -0x1c(%ebp),%eax + 104fd2: 2d 00 00 00 40 sub $0x40000000,%eax + 104fd7: 89 c2 mov %eax,%edx + 104fd9: a1 e0 99 11 00 mov 0x1199e0,%eax + 104fde: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) + 104fe5: 00 + 104fe6: 89 54 24 04 mov %edx,0x4(%esp) + 104fea: 89 04 24 mov %eax,(%esp) + 104fed: e8 75 f5 ff ff call 104567 + 104ff2: 89 45 dc mov %eax,-0x24(%ebp) + 104ff5: 83 7d dc 00 cmpl $0x0,-0x24(%ebp) + 104ff9: 75 24 jne 10501f + 104ffb: c7 44 24 0c 5c 6f 10 movl $0x106f5c,0xc(%esp) + 105002: 00 + 105003: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 10500a: 00 + 10500b: c7 44 24 04 a9 02 00 movl $0x2a9,0x4(%esp) + 105012: 00 + 105013: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 10501a: e8 14 bc ff ff call 100c33 <__panic> + // 验证页表项的物理地址是否正确 + assert(PTE_ADDR(*ptep) == i); + 10501f: 8b 45 dc mov -0x24(%ebp),%eax + 105022: 8b 00 mov (%eax),%eax + 105024: 25 00 f0 ff ff and $0xfffff000,%eax + 105029: 89 c2 mov %eax,%edx + 10502b: 8b 45 f4 mov -0xc(%ebp),%eax + 10502e: 39 c2 cmp %eax,%edx + 105030: 74 24 je 105056 + 105032: c7 44 24 0c 99 6f 10 movl $0x106f99,0xc(%esp) + 105039: 00 + 10503a: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 105041: 00 + 105042: c7 44 24 04 ab 02 00 movl $0x2ab,0x4(%esp) + 105049: 00 + 10504a: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 105051: e8 dd bb ff ff call 100c33 <__panic> + for (i = 0; i < npage; i += PGSIZE) {// 遍历所有页面 + 105056: 81 45 f4 00 10 00 00 addl $0x1000,-0xc(%ebp) + 10505d: 8b 55 f4 mov -0xc(%ebp),%edx + 105060: a1 04 cf 11 00 mov 0x11cf04,%eax + 105065: 39 c2 cmp %eax,%edx + 105067: 0f 82 26 ff ff ff jb 104f93 + } + // 验证页目录项的物理地址是否正确 + assert(PDE_ADDR(boot_pgdir[PDX(VPT)]) == PADDR(boot_pgdir)); + 10506d: a1 e0 99 11 00 mov 0x1199e0,%eax + 105072: 05 ac 0f 00 00 add $0xfac,%eax + 105077: 8b 00 mov (%eax),%eax + 105079: 25 00 f0 ff ff and $0xfffff000,%eax + 10507e: 89 c2 mov %eax,%edx + 105080: a1 e0 99 11 00 mov 0x1199e0,%eax + 105085: 89 45 f0 mov %eax,-0x10(%ebp) + 105088: 81 7d f0 ff ff ff bf cmpl $0xbfffffff,-0x10(%ebp) + 10508f: 77 23 ja 1050b4 + 105091: 8b 45 f0 mov -0x10(%ebp),%eax + 105094: 89 44 24 0c mov %eax,0xc(%esp) + 105098: c7 44 24 08 28 6c 10 movl $0x106c28,0x8(%esp) + 10509f: 00 + 1050a0: c7 44 24 04 ae 02 00 movl $0x2ae,0x4(%esp) + 1050a7: 00 + 1050a8: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 1050af: e8 7f bb ff ff call 100c33 <__panic> + 1050b4: 8b 45 f0 mov -0x10(%ebp),%eax + 1050b7: 05 00 00 00 40 add $0x40000000,%eax + 1050bc: 39 d0 cmp %edx,%eax + 1050be: 74 24 je 1050e4 + 1050c0: c7 44 24 0c b0 6f 10 movl $0x106fb0,0xc(%esp) + 1050c7: 00 + 1050c8: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 1050cf: 00 + 1050d0: c7 44 24 04 ae 02 00 movl $0x2ae,0x4(%esp) + 1050d7: 00 + 1050d8: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 1050df: e8 4f bb ff ff call 100c33 <__panic> + + assert(boot_pgdir[0] == 0);// 确保页目录的第一个项为0 + 1050e4: a1 e0 99 11 00 mov 0x1199e0,%eax + 1050e9: 8b 00 mov (%eax),%eax + 1050eb: 85 c0 test %eax,%eax + 1050ed: 74 24 je 105113 + 1050ef: c7 44 24 0c e4 6f 10 movl $0x106fe4,0xc(%esp) + 1050f6: 00 + 1050f7: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 1050fe: 00 + 1050ff: c7 44 24 04 b0 02 00 movl $0x2b0,0x4(%esp) + 105106: 00 + 105107: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 10510e: e8 20 bb ff ff call 100c33 <__panic> + + struct Page *p;// 定义一个指向页面的指针 + p = alloc_page();// 分配一个页面 + 105113: c7 04 24 01 00 00 00 movl $0x1,(%esp) + 10511a: e8 b6 ed ff ff call 103ed5 + 10511f: 89 45 ec mov %eax,-0x14(%ebp) + // 将页面插入到虚拟地址 0x100,并确保操作成功 + assert(page_insert(boot_pgdir, p, 0x100, PTE_W) == 0); + 105122: a1 e0 99 11 00 mov 0x1199e0,%eax + 105127: c7 44 24 0c 02 00 00 movl $0x2,0xc(%esp) + 10512e: 00 + 10512f: c7 44 24 08 00 01 00 movl $0x100,0x8(%esp) + 105136: 00 + 105137: 8b 55 ec mov -0x14(%ebp),%edx + 10513a: 89 54 24 04 mov %edx,0x4(%esp) + 10513e: 89 04 24 mov %eax,(%esp) + 105141: e8 62 f6 ff ff call 1047a8 + 105146: 85 c0 test %eax,%eax + 105148: 74 24 je 10516e + 10514a: c7 44 24 0c f8 6f 10 movl $0x106ff8,0xc(%esp) + 105151: 00 + 105152: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 105159: 00 + 10515a: c7 44 24 04 b5 02 00 movl $0x2b5,0x4(%esp) + 105161: 00 + 105162: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 105169: e8 c5 ba ff ff call 100c33 <__panic> + assert(page_ref(p) == 1);// 验证页面的引用计数为1 + 10516e: 8b 45 ec mov -0x14(%ebp),%eax + 105171: 89 04 24 mov %eax,(%esp) + 105174: e8 4c eb ff ff call 103cc5 + 105179: 83 f8 01 cmp $0x1,%eax + 10517c: 74 24 je 1051a2 + 10517e: c7 44 24 0c 26 70 10 movl $0x107026,0xc(%esp) + 105185: 00 + 105186: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 10518d: 00 + 10518e: c7 44 24 04 b6 02 00 movl $0x2b6,0x4(%esp) + 105195: 00 + 105196: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 10519d: e8 91 ba ff ff call 100c33 <__panic> + // 将页面插入到虚拟地址 0x100 + PGSIZE,并确保操作成功 + assert(page_insert(boot_pgdir, p, 0x100 + PGSIZE, PTE_W) == 0); + 1051a2: a1 e0 99 11 00 mov 0x1199e0,%eax + 1051a7: c7 44 24 0c 02 00 00 movl $0x2,0xc(%esp) + 1051ae: 00 + 1051af: c7 44 24 08 00 11 00 movl $0x1100,0x8(%esp) + 1051b6: 00 + 1051b7: 8b 55 ec mov -0x14(%ebp),%edx + 1051ba: 89 54 24 04 mov %edx,0x4(%esp) + 1051be: 89 04 24 mov %eax,(%esp) + 1051c1: e8 e2 f5 ff ff call 1047a8 + 1051c6: 85 c0 test %eax,%eax + 1051c8: 74 24 je 1051ee + 1051ca: c7 44 24 0c 38 70 10 movl $0x107038,0xc(%esp) + 1051d1: 00 + 1051d2: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 1051d9: 00 + 1051da: c7 44 24 04 b8 02 00 movl $0x2b8,0x4(%esp) + 1051e1: 00 + 1051e2: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 1051e9: e8 45 ba ff ff call 100c33 <__panic> + assert(page_ref(p) == 2);// 验证页面的引用计数为2 + 1051ee: 8b 45 ec mov -0x14(%ebp),%eax + 1051f1: 89 04 24 mov %eax,(%esp) + 1051f4: e8 cc ea ff ff call 103cc5 + 1051f9: 83 f8 02 cmp $0x2,%eax + 1051fc: 74 24 je 105222 + 1051fe: c7 44 24 0c 6f 70 10 movl $0x10706f,0xc(%esp) + 105205: 00 + 105206: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 10520d: 00 + 10520e: c7 44 24 04 b9 02 00 movl $0x2b9,0x4(%esp) + 105215: 00 + 105216: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 10521d: e8 11 ba ff ff call 100c33 <__panic> + + const char *str = "ucore: Hello world!!";// 定义一个字符串 + 105222: c7 45 e8 80 70 10 00 movl $0x107080,-0x18(%ebp) + strcpy((void *)0x100, str);// 将字符串复制到虚拟地址 0x100 + 105229: 8b 45 e8 mov -0x18(%ebp),%eax + 10522c: 89 44 24 04 mov %eax,0x4(%esp) + 105230: c7 04 24 00 01 00 00 movl $0x100,(%esp) + 105237: e8 fc 09 00 00 call 105c38 + // 验证两个映射地址的数据是否一致 + assert(strcmp((void *)0x100, (void *)(0x100 + PGSIZE)) == 0); + 10523c: c7 44 24 04 00 11 00 movl $0x1100,0x4(%esp) + 105243: 00 + 105244: c7 04 24 00 01 00 00 movl $0x100,(%esp) + 10524b: e8 60 0a 00 00 call 105cb0 + 105250: 85 c0 test %eax,%eax + 105252: 74 24 je 105278 + 105254: c7 44 24 0c 98 70 10 movl $0x107098,0xc(%esp) + 10525b: 00 + 10525c: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 105263: 00 + 105264: c7 44 24 04 be 02 00 movl $0x2be,0x4(%esp) + 10526b: 00 + 10526c: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 105273: e8 bb b9 ff ff call 100c33 <__panic> + // 在页面的 0x100 偏移处设置字符串结束符 + *(char *)(page2kva(p) + 0x100) = '\0'; + 105278: 8b 45 ec mov -0x14(%ebp),%eax + 10527b: 89 04 24 mov %eax,(%esp) + 10527e: e8 92 e9 ff ff call 103c15 + 105283: 05 00 01 00 00 add $0x100,%eax + 105288: c6 00 00 movb $0x0,(%eax) + assert(strlen((const char *)0x100) == 0);// 验证字符串长度为0 + 10528b: c7 04 24 00 01 00 00 movl $0x100,(%esp) + 105292: e8 47 09 00 00 call 105bde + 105297: 85 c0 test %eax,%eax + 105299: 74 24 je 1052bf + 10529b: c7 44 24 0c d0 70 10 movl $0x1070d0,0xc(%esp) + 1052a2: 00 + 1052a3: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 1052aa: 00 + 1052ab: c7 44 24 04 c1 02 00 movl $0x2c1,0x4(%esp) + 1052b2: 00 + 1052b3: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 1052ba: e8 74 b9 ff ff call 100c33 <__panic> + + free_page(p);// 释放页面 p + 1052bf: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) + 1052c6: 00 + 1052c7: 8b 45 ec mov -0x14(%ebp),%eax + 1052ca: 89 04 24 mov %eax,(%esp) + 1052cd: e8 3d ec ff ff call 103f0f + free_page(pde2page(boot_pgdir[0]));// 释放页目录项对应的页面 + 1052d2: a1 e0 99 11 00 mov 0x1199e0,%eax + 1052d7: 8b 00 mov (%eax),%eax + 1052d9: 89 04 24 mov %eax,(%esp) + 1052dc: e8 ca e9 ff ff call 103cab + 1052e1: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) + 1052e8: 00 + 1052e9: 89 04 24 mov %eax,(%esp) + 1052ec: e8 1e ec ff ff call 103f0f + boot_pgdir[0] = 0;// 将页目录的第一个项设为0 + 1052f1: a1 e0 99 11 00 mov 0x1199e0,%eax + 1052f6: c7 00 00 00 00 00 movl $0x0,(%eax) + + cprintf("check_boot_pgdir() succeeded!\n");// 输出成功信息 + 1052fc: c7 04 24 f4 70 10 00 movl $0x1070f4,(%esp) + 105303: e8 5e b0 ff ff call 100366 +} + 105308: 90 nop + 105309: 89 ec mov %ebp,%esp + 10530b: 5d pop %ebp + 10530c: c3 ret + +0010530d : + +//perm2str - use string 'u,r,w,-' to present the permission +static const char * +perm2str(int perm) { + 10530d: 55 push %ebp + 10530e: 89 e5 mov %esp,%ebp + //定义一个静态字符数组 str,长度为4 + static char str[4]; + //如果 perm 与 PTE_U 按位与的结果不为0,则 str[0] 设置为 'u',否则设置为 '-' + str[0] = (perm & PTE_U) ? 'u' : '-'; + 105310: 8b 45 08 mov 0x8(%ebp),%eax + 105313: 83 e0 04 and $0x4,%eax + 105316: 85 c0 test %eax,%eax + 105318: 74 04 je 10531e + 10531a: b0 75 mov $0x75,%al + 10531c: eb 02 jmp 105320 + 10531e: b0 2d mov $0x2d,%al + 105320: a2 88 cf 11 00 mov %al,0x11cf88 + //str[1] 始终设置为 'r' + str[1] = 'r'; + 105325: c6 05 89 cf 11 00 72 movb $0x72,0x11cf89 + //如果 perm 与 PTE_W 按位与的结果不为0,则 str[2] 设置为 'w',否则设置为 '-' + str[2] = (perm & PTE_W) ? 'w' : '-'; + 10532c: 8b 45 08 mov 0x8(%ebp),%eax + 10532f: 83 e0 02 and $0x2,%eax + 105332: 85 c0 test %eax,%eax + 105334: 74 04 je 10533a + 105336: b0 77 mov $0x77,%al + 105338: eb 02 jmp 10533c + 10533a: b0 2d mov $0x2d,%al + 10533c: a2 8a cf 11 00 mov %al,0x11cf8a + //str[3] 设置为字符串结束符 \0 + str[3] = '\0'; + 105341: c6 05 8b cf 11 00 00 movb $0x0,0x11cf8b + return str; + 105348: b8 88 cf 11 00 mov $0x11cf88,%eax +} + 10534d: 5d pop %ebp + 10534e: c3 ret + +0010534f : +// 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) { + 10534f: 55 push %ebp + 105350: 89 e5 mov %esp,%ebp + 105352: 83 ec 10 sub $0x10,%esp + if (start >= right) {// 检查起始索引是否超出右边界 + 105355: 8b 45 10 mov 0x10(%ebp),%eax + 105358: 3b 45 0c cmp 0xc(%ebp),%eax + 10535b: 72 0d jb 10536a + return 0;// 如果超出右边界,返回0 + 10535d: b8 00 00 00 00 mov $0x0,%eax + 105362: e9 98 00 00 00 jmp 1053ff + } + while (start < right && !(table[start] & PTE_P)) {// 查找第一个有效项(PTE_P位为1的项) + start ++;// 索引递增 + 105367: ff 45 10 incl 0x10(%ebp) + while (start < right && !(table[start] & PTE_P)) {// 查找第一个有效项(PTE_P位为1的项) + 10536a: 8b 45 10 mov 0x10(%ebp),%eax + 10536d: 3b 45 0c cmp 0xc(%ebp),%eax + 105370: 73 18 jae 10538a + 105372: 8b 45 10 mov 0x10(%ebp),%eax + 105375: 8d 14 85 00 00 00 00 lea 0x0(,%eax,4),%edx + 10537c: 8b 45 14 mov 0x14(%ebp),%eax + 10537f: 01 d0 add %edx,%eax + 105381: 8b 00 mov (%eax),%eax + 105383: 83 e0 01 and $0x1,%eax + 105386: 85 c0 test %eax,%eax + 105388: 74 dd je 105367 + } + if (start < right) {// 检查是否找到有效项 + 10538a: 8b 45 10 mov 0x10(%ebp),%eax + 10538d: 3b 45 0c cmp 0xc(%ebp),%eax + 105390: 73 68 jae 1053fa + if (left_store != NULL) {// 如果left_store不为NULL + 105392: 83 7d 18 00 cmpl $0x0,0x18(%ebp) + 105396: 74 08 je 1053a0 + *left_store = start;// 记录左边界索引 + 105398: 8b 45 18 mov 0x18(%ebp),%eax + 10539b: 8b 55 10 mov 0x10(%ebp),%edx + 10539e: 89 10 mov %edx,(%eax) + } + int perm = (table[start ++] & PTE_USER);// 获取当前项的用户权限位并递增索引 + 1053a0: 8b 45 10 mov 0x10(%ebp),%eax + 1053a3: 8d 50 01 lea 0x1(%eax),%edx + 1053a6: 89 55 10 mov %edx,0x10(%ebp) + 1053a9: 8d 14 85 00 00 00 00 lea 0x0(,%eax,4),%edx + 1053b0: 8b 45 14 mov 0x14(%ebp),%eax + 1053b3: 01 d0 add %edx,%eax + 1053b5: 8b 00 mov (%eax),%eax + 1053b7: 83 e0 07 and $0x7,%eax + 1053ba: 89 45 fc mov %eax,-0x4(%ebp) + while (start < right && (table[start] & PTE_USER) == perm) {// 查找具有相同用户权限的连续项 + 1053bd: eb 03 jmp 1053c2 + start ++;// 索引递增 + 1053bf: ff 45 10 incl 0x10(%ebp) + while (start < right && (table[start] & PTE_USER) == perm) {// 查找具有相同用户权限的连续项 + 1053c2: 8b 45 10 mov 0x10(%ebp),%eax + 1053c5: 3b 45 0c cmp 0xc(%ebp),%eax + 1053c8: 73 1d jae 1053e7 + 1053ca: 8b 45 10 mov 0x10(%ebp),%eax + 1053cd: 8d 14 85 00 00 00 00 lea 0x0(,%eax,4),%edx + 1053d4: 8b 45 14 mov 0x14(%ebp),%eax + 1053d7: 01 d0 add %edx,%eax + 1053d9: 8b 00 mov (%eax),%eax + 1053db: 83 e0 07 and $0x7,%eax + 1053de: 89 c2 mov %eax,%edx + 1053e0: 8b 45 fc mov -0x4(%ebp),%eax + 1053e3: 39 c2 cmp %eax,%edx + 1053e5: 74 d8 je 1053bf + } + if (right_store != NULL) {// 如果right_store不为NULL + 1053e7: 83 7d 1c 00 cmpl $0x0,0x1c(%ebp) + 1053eb: 74 08 je 1053f5 + *right_store = start;// 记录右边界索引 + 1053ed: 8b 45 1c mov 0x1c(%ebp),%eax + 1053f0: 8b 55 10 mov 0x10(%ebp),%edx + 1053f3: 89 10 mov %edx,(%eax) + } + return perm;// 返回用户权限位 + 1053f5: 8b 45 fc mov -0x4(%ebp),%eax + 1053f8: eb 05 jmp 1053ff + } + return 0;// 如果未找到有效项,返回0 + 1053fa: b8 00 00 00 00 mov $0x0,%eax +} + 1053ff: 89 ec mov %ebp,%esp + 105401: 5d pop %ebp + 105402: c3 ret + +00105403 : + +//print_pgdir - print the PDT&PT +void +print_pgdir(void) { + 105403: 55 push %ebp + 105404: 89 e5 mov %esp,%ebp + 105406: 57 push %edi + 105407: 56 push %esi + 105408: 53 push %ebx + 105409: 83 ec 4c sub $0x4c,%esp + cprintf("-------------------- BEGIN --------------------\n"); + 10540c: c7 04 24 14 71 10 00 movl $0x107114,(%esp) + 105413: e8 4e af ff ff call 100366 + // 定义变量 left, right 和 perm + size_t left, right = 0, perm; + 105418: c7 45 dc 00 00 00 00 movl $0x0,-0x24(%ebp) + // 遍历页目录项 + while ((perm = get_pgtable_items(0, NPDEENTRY, right, vpd, &left, &right)) != 0) { + 10541f: e9 f2 00 00 00 jmp 105516 + // 打印页目录项的信息 + cprintf("PDE(%03x) %08x-%08x %08x %s\n", right - left, + 105424: 8b 45 e4 mov -0x1c(%ebp),%eax + 105427: 89 04 24 mov %eax,(%esp) + 10542a: e8 de fe ff ff call 10530d + left * PTSIZE, right * PTSIZE, (right - left) * PTSIZE, perm2str(perm)); + 10542f: 8b 55 dc mov -0x24(%ebp),%edx + 105432: 8b 4d e0 mov -0x20(%ebp),%ecx + 105435: 29 ca sub %ecx,%edx + cprintf("PDE(%03x) %08x-%08x %08x %s\n", right - left, + 105437: 89 d6 mov %edx,%esi + 105439: c1 e6 16 shl $0x16,%esi + 10543c: 8b 55 dc mov -0x24(%ebp),%edx + 10543f: 89 d3 mov %edx,%ebx + 105441: c1 e3 16 shl $0x16,%ebx + 105444: 8b 55 e0 mov -0x20(%ebp),%edx + 105447: 89 d1 mov %edx,%ecx + 105449: c1 e1 16 shl $0x16,%ecx + 10544c: 8b 55 dc mov -0x24(%ebp),%edx + 10544f: 8b 7d e0 mov -0x20(%ebp),%edi + 105452: 29 fa sub %edi,%edx + 105454: 89 44 24 14 mov %eax,0x14(%esp) + 105458: 89 74 24 10 mov %esi,0x10(%esp) + 10545c: 89 5c 24 0c mov %ebx,0xc(%esp) + 105460: 89 4c 24 08 mov %ecx,0x8(%esp) + 105464: 89 54 24 04 mov %edx,0x4(%esp) + 105468: c7 04 24 45 71 10 00 movl $0x107145,(%esp) + 10546f: e8 f2 ae ff ff call 100366 + // 计算页表项的起始和结束索引 + size_t l, r = left * NPTEENTRY; + 105474: 8b 45 e0 mov -0x20(%ebp),%eax + 105477: c1 e0 0a shl $0xa,%eax + 10547a: 89 45 d4 mov %eax,-0x2c(%ebp) + // 遍历页表项 + while ((perm = get_pgtable_items(left * NPTEENTRY, right * NPTEENTRY, r, vpt, &l, &r)) != 0) { + 10547d: eb 50 jmp 1054cf + // 打印页表项的信息 + cprintf(" |-- PTE(%05x) %08x-%08x %08x %s\n", r - l, + 10547f: 8b 45 e4 mov -0x1c(%ebp),%eax + 105482: 89 04 24 mov %eax,(%esp) + 105485: e8 83 fe ff ff call 10530d + l * PGSIZE, r * PGSIZE, (r - l) * PGSIZE, perm2str(perm)); + 10548a: 8b 55 d4 mov -0x2c(%ebp),%edx + 10548d: 8b 4d d8 mov -0x28(%ebp),%ecx + 105490: 29 ca sub %ecx,%edx + cprintf(" |-- PTE(%05x) %08x-%08x %08x %s\n", r - l, + 105492: 89 d6 mov %edx,%esi + 105494: c1 e6 0c shl $0xc,%esi + 105497: 8b 55 d4 mov -0x2c(%ebp),%edx + 10549a: 89 d3 mov %edx,%ebx + 10549c: c1 e3 0c shl $0xc,%ebx + 10549f: 8b 55 d8 mov -0x28(%ebp),%edx + 1054a2: 89 d1 mov %edx,%ecx + 1054a4: c1 e1 0c shl $0xc,%ecx + 1054a7: 8b 55 d4 mov -0x2c(%ebp),%edx + 1054aa: 8b 7d d8 mov -0x28(%ebp),%edi + 1054ad: 29 fa sub %edi,%edx + 1054af: 89 44 24 14 mov %eax,0x14(%esp) + 1054b3: 89 74 24 10 mov %esi,0x10(%esp) + 1054b7: 89 5c 24 0c mov %ebx,0xc(%esp) + 1054bb: 89 4c 24 08 mov %ecx,0x8(%esp) + 1054bf: 89 54 24 04 mov %edx,0x4(%esp) + 1054c3: c7 04 24 64 71 10 00 movl $0x107164,(%esp) + 1054ca: e8 97 ae ff ff call 100366 + while ((perm = get_pgtable_items(left * NPTEENTRY, right * NPTEENTRY, r, vpt, &l, &r)) != 0) { + 1054cf: be 00 00 c0 fa mov $0xfac00000,%esi + 1054d4: 8b 45 d4 mov -0x2c(%ebp),%eax + 1054d7: 8b 55 dc mov -0x24(%ebp),%edx + 1054da: 89 d3 mov %edx,%ebx + 1054dc: c1 e3 0a shl $0xa,%ebx + 1054df: 8b 55 e0 mov -0x20(%ebp),%edx + 1054e2: 89 d1 mov %edx,%ecx + 1054e4: c1 e1 0a shl $0xa,%ecx + 1054e7: 8d 55 d4 lea -0x2c(%ebp),%edx + 1054ea: 89 54 24 14 mov %edx,0x14(%esp) + 1054ee: 8d 55 d8 lea -0x28(%ebp),%edx + 1054f1: 89 54 24 10 mov %edx,0x10(%esp) + 1054f5: 89 74 24 0c mov %esi,0xc(%esp) + 1054f9: 89 44 24 08 mov %eax,0x8(%esp) + 1054fd: 89 5c 24 04 mov %ebx,0x4(%esp) + 105501: 89 0c 24 mov %ecx,(%esp) + 105504: e8 46 fe ff ff call 10534f + 105509: 89 45 e4 mov %eax,-0x1c(%ebp) + 10550c: 83 7d e4 00 cmpl $0x0,-0x1c(%ebp) + 105510: 0f 85 69 ff ff ff jne 10547f + while ((perm = get_pgtable_items(0, NPDEENTRY, right, vpd, &left, &right)) != 0) { + 105516: b9 00 b0 fe fa mov $0xfafeb000,%ecx + 10551b: 8b 45 dc mov -0x24(%ebp),%eax + 10551e: 8d 55 dc lea -0x24(%ebp),%edx + 105521: 89 54 24 14 mov %edx,0x14(%esp) + 105525: 8d 55 e0 lea -0x20(%ebp),%edx + 105528: 89 54 24 10 mov %edx,0x10(%esp) + 10552c: 89 4c 24 0c mov %ecx,0xc(%esp) + 105530: 89 44 24 08 mov %eax,0x8(%esp) + 105534: c7 44 24 04 00 04 00 movl $0x400,0x4(%esp) + 10553b: 00 + 10553c: c7 04 24 00 00 00 00 movl $0x0,(%esp) + 105543: e8 07 fe ff ff call 10534f + 105548: 89 45 e4 mov %eax,-0x1c(%ebp) + 10554b: 83 7d e4 00 cmpl $0x0,-0x1c(%ebp) + 10554f: 0f 85 cf fe ff ff jne 105424 + } + } + cprintf("--------------------- END ---------------------\n"); + 105555: c7 04 24 88 71 10 00 movl $0x107188,(%esp) + 10555c: e8 05 ae ff ff call 100366 +} + 105561: 90 nop + 105562: 83 c4 4c add $0x4c,%esp + 105565: 5b pop %ebx + 105566: 5e pop %esi + 105567: 5f pop %edi + 105568: 5d pop %ebp + 105569: c3 ret + +0010556a : + * @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) { + 10556a: 55 push %ebp + 10556b: 89 e5 mov %esp,%ebp + 10556d: 83 ec 58 sub $0x58,%esp + 105570: 8b 45 10 mov 0x10(%ebp),%eax + 105573: 89 45 d0 mov %eax,-0x30(%ebp) + 105576: 8b 45 14 mov 0x14(%ebp),%eax + 105579: 89 45 d4 mov %eax,-0x2c(%ebp) + unsigned long long result = num; + 10557c: 8b 45 d0 mov -0x30(%ebp),%eax + 10557f: 8b 55 d4 mov -0x2c(%ebp),%edx + 105582: 89 45 e8 mov %eax,-0x18(%ebp) + 105585: 89 55 ec mov %edx,-0x14(%ebp) + unsigned mod = do_div(result, base); + 105588: 8b 45 18 mov 0x18(%ebp),%eax + 10558b: 89 45 e4 mov %eax,-0x1c(%ebp) + 10558e: 8b 45 e8 mov -0x18(%ebp),%eax + 105591: 8b 55 ec mov -0x14(%ebp),%edx + 105594: 89 45 e0 mov %eax,-0x20(%ebp) + 105597: 89 55 f0 mov %edx,-0x10(%ebp) + 10559a: 8b 45 f0 mov -0x10(%ebp),%eax + 10559d: 89 45 f4 mov %eax,-0xc(%ebp) + 1055a0: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) + 1055a4: 74 1c je 1055c2 + 1055a6: 8b 45 f0 mov -0x10(%ebp),%eax + 1055a9: ba 00 00 00 00 mov $0x0,%edx + 1055ae: f7 75 e4 divl -0x1c(%ebp) + 1055b1: 89 55 f4 mov %edx,-0xc(%ebp) + 1055b4: 8b 45 f0 mov -0x10(%ebp),%eax + 1055b7: ba 00 00 00 00 mov $0x0,%edx + 1055bc: f7 75 e4 divl -0x1c(%ebp) + 1055bf: 89 45 f0 mov %eax,-0x10(%ebp) + 1055c2: 8b 45 e0 mov -0x20(%ebp),%eax + 1055c5: 8b 55 f4 mov -0xc(%ebp),%edx + 1055c8: f7 75 e4 divl -0x1c(%ebp) + 1055cb: 89 45 e0 mov %eax,-0x20(%ebp) + 1055ce: 89 55 dc mov %edx,-0x24(%ebp) + 1055d1: 8b 45 e0 mov -0x20(%ebp),%eax + 1055d4: 8b 55 f0 mov -0x10(%ebp),%edx + 1055d7: 89 45 e8 mov %eax,-0x18(%ebp) + 1055da: 89 55 ec mov %edx,-0x14(%ebp) + 1055dd: 8b 45 dc mov -0x24(%ebp),%eax + 1055e0: 89 45 d8 mov %eax,-0x28(%ebp) + + // first recursively print all preceding (more significant) digits + if (num >= base) { + 1055e3: 8b 45 18 mov 0x18(%ebp),%eax + 1055e6: ba 00 00 00 00 mov $0x0,%edx + 1055eb: 8b 4d d4 mov -0x2c(%ebp),%ecx + 1055ee: 39 45 d0 cmp %eax,-0x30(%ebp) + 1055f1: 19 d1 sbb %edx,%ecx + 1055f3: 72 4c jb 105641 + printnum(putch, putdat, result, base, width - 1, padc); + 1055f5: 8b 45 1c mov 0x1c(%ebp),%eax + 1055f8: 8d 50 ff lea -0x1(%eax),%edx + 1055fb: 8b 45 20 mov 0x20(%ebp),%eax + 1055fe: 89 44 24 18 mov %eax,0x18(%esp) + 105602: 89 54 24 14 mov %edx,0x14(%esp) + 105606: 8b 45 18 mov 0x18(%ebp),%eax + 105609: 89 44 24 10 mov %eax,0x10(%esp) + 10560d: 8b 45 e8 mov -0x18(%ebp),%eax + 105610: 8b 55 ec mov -0x14(%ebp),%edx + 105613: 89 44 24 08 mov %eax,0x8(%esp) + 105617: 89 54 24 0c mov %edx,0xc(%esp) + 10561b: 8b 45 0c mov 0xc(%ebp),%eax + 10561e: 89 44 24 04 mov %eax,0x4(%esp) + 105622: 8b 45 08 mov 0x8(%ebp),%eax + 105625: 89 04 24 mov %eax,(%esp) + 105628: e8 3d ff ff ff call 10556a + 10562d: eb 1b jmp 10564a + } else { + // print any needed pad characters before first digit + while (-- width > 0) + putch(padc, putdat); + 10562f: 8b 45 0c mov 0xc(%ebp),%eax + 105632: 89 44 24 04 mov %eax,0x4(%esp) + 105636: 8b 45 20 mov 0x20(%ebp),%eax + 105639: 89 04 24 mov %eax,(%esp) + 10563c: 8b 45 08 mov 0x8(%ebp),%eax + 10563f: ff d0 call *%eax + while (-- width > 0) + 105641: ff 4d 1c decl 0x1c(%ebp) + 105644: 83 7d 1c 00 cmpl $0x0,0x1c(%ebp) + 105648: 7f e5 jg 10562f + } + // then print this (the least significant) digit + putch("0123456789abcdef"[mod], putdat); + 10564a: 8b 45 d8 mov -0x28(%ebp),%eax + 10564d: 05 3c 72 10 00 add $0x10723c,%eax + 105652: 0f b6 00 movzbl (%eax),%eax + 105655: 0f be c0 movsbl %al,%eax + 105658: 8b 55 0c mov 0xc(%ebp),%edx + 10565b: 89 54 24 04 mov %edx,0x4(%esp) + 10565f: 89 04 24 mov %eax,(%esp) + 105662: 8b 45 08 mov 0x8(%ebp),%eax + 105665: ff d0 call *%eax +} + 105667: 90 nop + 105668: 89 ec mov %ebp,%esp + 10566a: 5d pop %ebp + 10566b: c3 ret + +0010566c : + * 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) { + 10566c: 55 push %ebp + 10566d: 89 e5 mov %esp,%ebp + if (lflag >= 2) { + 10566f: 83 7d 0c 01 cmpl $0x1,0xc(%ebp) + 105673: 7e 14 jle 105689 + return va_arg(*ap, unsigned long long); + 105675: 8b 45 08 mov 0x8(%ebp),%eax + 105678: 8b 00 mov (%eax),%eax + 10567a: 8d 48 08 lea 0x8(%eax),%ecx + 10567d: 8b 55 08 mov 0x8(%ebp),%edx + 105680: 89 0a mov %ecx,(%edx) + 105682: 8b 50 04 mov 0x4(%eax),%edx + 105685: 8b 00 mov (%eax),%eax + 105687: eb 30 jmp 1056b9 + } + else if (lflag) { + 105689: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) + 10568d: 74 16 je 1056a5 + return va_arg(*ap, unsigned long); + 10568f: 8b 45 08 mov 0x8(%ebp),%eax + 105692: 8b 00 mov (%eax),%eax + 105694: 8d 48 04 lea 0x4(%eax),%ecx + 105697: 8b 55 08 mov 0x8(%ebp),%edx + 10569a: 89 0a mov %ecx,(%edx) + 10569c: 8b 00 mov (%eax),%eax + 10569e: ba 00 00 00 00 mov $0x0,%edx + 1056a3: eb 14 jmp 1056b9 + } + else { + return va_arg(*ap, unsigned int); + 1056a5: 8b 45 08 mov 0x8(%ebp),%eax + 1056a8: 8b 00 mov (%eax),%eax + 1056aa: 8d 48 04 lea 0x4(%eax),%ecx + 1056ad: 8b 55 08 mov 0x8(%ebp),%edx + 1056b0: 89 0a mov %ecx,(%edx) + 1056b2: 8b 00 mov (%eax),%eax + 1056b4: ba 00 00 00 00 mov $0x0,%edx + } +} + 1056b9: 5d pop %ebp + 1056ba: c3 ret + +001056bb : + * 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) { + 1056bb: 55 push %ebp + 1056bc: 89 e5 mov %esp,%ebp + if (lflag >= 2) { + 1056be: 83 7d 0c 01 cmpl $0x1,0xc(%ebp) + 1056c2: 7e 14 jle 1056d8 + return va_arg(*ap, long long); + 1056c4: 8b 45 08 mov 0x8(%ebp),%eax + 1056c7: 8b 00 mov (%eax),%eax + 1056c9: 8d 48 08 lea 0x8(%eax),%ecx + 1056cc: 8b 55 08 mov 0x8(%ebp),%edx + 1056cf: 89 0a mov %ecx,(%edx) + 1056d1: 8b 50 04 mov 0x4(%eax),%edx + 1056d4: 8b 00 mov (%eax),%eax + 1056d6: eb 28 jmp 105700 + } + else if (lflag) { + 1056d8: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) + 1056dc: 74 12 je 1056f0 + return va_arg(*ap, long); + 1056de: 8b 45 08 mov 0x8(%ebp),%eax + 1056e1: 8b 00 mov (%eax),%eax + 1056e3: 8d 48 04 lea 0x4(%eax),%ecx + 1056e6: 8b 55 08 mov 0x8(%ebp),%edx + 1056e9: 89 0a mov %ecx,(%edx) + 1056eb: 8b 00 mov (%eax),%eax + 1056ed: 99 cltd + 1056ee: eb 10 jmp 105700 + } + else { + return va_arg(*ap, int); + 1056f0: 8b 45 08 mov 0x8(%ebp),%eax + 1056f3: 8b 00 mov (%eax),%eax + 1056f5: 8d 48 04 lea 0x4(%eax),%ecx + 1056f8: 8b 55 08 mov 0x8(%ebp),%edx + 1056fb: 89 0a mov %ecx,(%edx) + 1056fd: 8b 00 mov (%eax),%eax + 1056ff: 99 cltd + } +} + 105700: 5d pop %ebp + 105701: c3 ret + +00105702 : + * @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, ...) { + 105702: 55 push %ebp + 105703: 89 e5 mov %esp,%ebp + 105705: 83 ec 28 sub $0x28,%esp + va_list ap; + + va_start(ap, fmt); + 105708: 8d 45 14 lea 0x14(%ebp),%eax + 10570b: 89 45 f4 mov %eax,-0xc(%ebp) + vprintfmt(putch, putdat, fmt, ap); + 10570e: 8b 45 f4 mov -0xc(%ebp),%eax + 105711: 89 44 24 0c mov %eax,0xc(%esp) + 105715: 8b 45 10 mov 0x10(%ebp),%eax + 105718: 89 44 24 08 mov %eax,0x8(%esp) + 10571c: 8b 45 0c mov 0xc(%ebp),%eax + 10571f: 89 44 24 04 mov %eax,0x4(%esp) + 105723: 8b 45 08 mov 0x8(%ebp),%eax + 105726: 89 04 24 mov %eax,(%esp) + 105729: e8 05 00 00 00 call 105733 + va_end(ap); +} + 10572e: 90 nop + 10572f: 89 ec mov %ebp,%esp + 105731: 5d pop %ebp + 105732: c3 ret + +00105733 : + * + * 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) { + 105733: 55 push %ebp + 105734: 89 e5 mov %esp,%ebp + 105736: 56 push %esi + 105737: 53 push %ebx + 105738: 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 ++) != '%') { + 10573b: eb 17 jmp 105754 + if (ch == '\0') { + 10573d: 85 db test %ebx,%ebx + 10573f: 0f 84 bf 03 00 00 je 105b04 + return; + } + putch(ch, putdat); + 105745: 8b 45 0c mov 0xc(%ebp),%eax + 105748: 89 44 24 04 mov %eax,0x4(%esp) + 10574c: 89 1c 24 mov %ebx,(%esp) + 10574f: 8b 45 08 mov 0x8(%ebp),%eax + 105752: ff d0 call *%eax + while ((ch = *(unsigned char *)fmt ++) != '%') { + 105754: 8b 45 10 mov 0x10(%ebp),%eax + 105757: 8d 50 01 lea 0x1(%eax),%edx + 10575a: 89 55 10 mov %edx,0x10(%ebp) + 10575d: 0f b6 00 movzbl (%eax),%eax + 105760: 0f b6 d8 movzbl %al,%ebx + 105763: 83 fb 25 cmp $0x25,%ebx + 105766: 75 d5 jne 10573d + } + + // Process a %-escape sequence + char padc = ' '; + 105768: c6 45 db 20 movb $0x20,-0x25(%ebp) + width = precision = -1; + 10576c: c7 45 e4 ff ff ff ff movl $0xffffffff,-0x1c(%ebp) + 105773: 8b 45 e4 mov -0x1c(%ebp),%eax + 105776: 89 45 e8 mov %eax,-0x18(%ebp) + lflag = altflag = 0; + 105779: c7 45 dc 00 00 00 00 movl $0x0,-0x24(%ebp) + 105780: 8b 45 dc mov -0x24(%ebp),%eax + 105783: 89 45 e0 mov %eax,-0x20(%ebp) + + reswitch: + switch (ch = *(unsigned char *)fmt ++) { + 105786: 8b 45 10 mov 0x10(%ebp),%eax + 105789: 8d 50 01 lea 0x1(%eax),%edx + 10578c: 89 55 10 mov %edx,0x10(%ebp) + 10578f: 0f b6 00 movzbl (%eax),%eax + 105792: 0f b6 d8 movzbl %al,%ebx + 105795: 8d 43 dd lea -0x23(%ebx),%eax + 105798: 83 f8 55 cmp $0x55,%eax + 10579b: 0f 87 37 03 00 00 ja 105ad8 + 1057a1: 8b 04 85 60 72 10 00 mov 0x107260(,%eax,4),%eax + 1057a8: ff e0 jmp *%eax + + // flag to pad on the right + case '-': + padc = '-'; + 1057aa: c6 45 db 2d movb $0x2d,-0x25(%ebp) + goto reswitch; + 1057ae: eb d6 jmp 105786 + + // flag to pad with 0's instead of spaces + case '0': + padc = '0'; + 1057b0: c6 45 db 30 movb $0x30,-0x25(%ebp) + goto reswitch; + 1057b4: eb d0 jmp 105786 + + // width field + case '1' ... '9': + for (precision = 0; ; ++ fmt) { + 1057b6: c7 45 e4 00 00 00 00 movl $0x0,-0x1c(%ebp) + precision = precision * 10 + ch - '0'; + 1057bd: 8b 55 e4 mov -0x1c(%ebp),%edx + 1057c0: 89 d0 mov %edx,%eax + 1057c2: c1 e0 02 shl $0x2,%eax + 1057c5: 01 d0 add %edx,%eax + 1057c7: 01 c0 add %eax,%eax + 1057c9: 01 d8 add %ebx,%eax + 1057cb: 83 e8 30 sub $0x30,%eax + 1057ce: 89 45 e4 mov %eax,-0x1c(%ebp) + ch = *fmt; + 1057d1: 8b 45 10 mov 0x10(%ebp),%eax + 1057d4: 0f b6 00 movzbl (%eax),%eax + 1057d7: 0f be d8 movsbl %al,%ebx + if (ch < '0' || ch > '9') { + 1057da: 83 fb 2f cmp $0x2f,%ebx + 1057dd: 7e 38 jle 105817 + 1057df: 83 fb 39 cmp $0x39,%ebx + 1057e2: 7f 33 jg 105817 + for (precision = 0; ; ++ fmt) { + 1057e4: ff 45 10 incl 0x10(%ebp) + precision = precision * 10 + ch - '0'; + 1057e7: eb d4 jmp 1057bd + } + } + goto process_precision; + + case '*': + precision = va_arg(ap, int); + 1057e9: 8b 45 14 mov 0x14(%ebp),%eax + 1057ec: 8d 50 04 lea 0x4(%eax),%edx + 1057ef: 89 55 14 mov %edx,0x14(%ebp) + 1057f2: 8b 00 mov (%eax),%eax + 1057f4: 89 45 e4 mov %eax,-0x1c(%ebp) + goto process_precision; + 1057f7: eb 1f jmp 105818 + + case '.': + if (width < 0) + 1057f9: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 1057fd: 79 87 jns 105786 + width = 0; + 1057ff: c7 45 e8 00 00 00 00 movl $0x0,-0x18(%ebp) + goto reswitch; + 105806: e9 7b ff ff ff jmp 105786 + + case '#': + altflag = 1; + 10580b: c7 45 dc 01 00 00 00 movl $0x1,-0x24(%ebp) + goto reswitch; + 105812: e9 6f ff ff ff jmp 105786 + goto process_precision; + 105817: 90 nop + + process_precision: + if (width < 0) + 105818: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 10581c: 0f 89 64 ff ff ff jns 105786 + width = precision, precision = -1; + 105822: 8b 45 e4 mov -0x1c(%ebp),%eax + 105825: 89 45 e8 mov %eax,-0x18(%ebp) + 105828: c7 45 e4 ff ff ff ff movl $0xffffffff,-0x1c(%ebp) + goto reswitch; + 10582f: e9 52 ff ff ff jmp 105786 + + // long flag (doubled for long long) + case 'l': + lflag ++; + 105834: ff 45 e0 incl -0x20(%ebp) + goto reswitch; + 105837: e9 4a ff ff ff jmp 105786 + + // character + case 'c': + putch(va_arg(ap, int), putdat); + 10583c: 8b 45 14 mov 0x14(%ebp),%eax + 10583f: 8d 50 04 lea 0x4(%eax),%edx + 105842: 89 55 14 mov %edx,0x14(%ebp) + 105845: 8b 00 mov (%eax),%eax + 105847: 8b 55 0c mov 0xc(%ebp),%edx + 10584a: 89 54 24 04 mov %edx,0x4(%esp) + 10584e: 89 04 24 mov %eax,(%esp) + 105851: 8b 45 08 mov 0x8(%ebp),%eax + 105854: ff d0 call *%eax + break; + 105856: e9 a4 02 00 00 jmp 105aff + + // error message + case 'e': + err = va_arg(ap, int); + 10585b: 8b 45 14 mov 0x14(%ebp),%eax + 10585e: 8d 50 04 lea 0x4(%eax),%edx + 105861: 89 55 14 mov %edx,0x14(%ebp) + 105864: 8b 18 mov (%eax),%ebx + if (err < 0) { + 105866: 85 db test %ebx,%ebx + 105868: 79 02 jns 10586c + err = -err; + 10586a: f7 db neg %ebx + } + if (err > MAXERROR || (p = error_string[err]) == NULL) { + 10586c: 83 fb 06 cmp $0x6,%ebx + 10586f: 7f 0b jg 10587c + 105871: 8b 34 9d 20 72 10 00 mov 0x107220(,%ebx,4),%esi + 105878: 85 f6 test %esi,%esi + 10587a: 75 23 jne 10589f + printfmt(putch, putdat, "error %d", err); + 10587c: 89 5c 24 0c mov %ebx,0xc(%esp) + 105880: c7 44 24 08 4d 72 10 movl $0x10724d,0x8(%esp) + 105887: 00 + 105888: 8b 45 0c mov 0xc(%ebp),%eax + 10588b: 89 44 24 04 mov %eax,0x4(%esp) + 10588f: 8b 45 08 mov 0x8(%ebp),%eax + 105892: 89 04 24 mov %eax,(%esp) + 105895: e8 68 fe ff ff call 105702 + } + else { + printfmt(putch, putdat, "%s", p); + } + break; + 10589a: e9 60 02 00 00 jmp 105aff + printfmt(putch, putdat, "%s", p); + 10589f: 89 74 24 0c mov %esi,0xc(%esp) + 1058a3: c7 44 24 08 56 72 10 movl $0x107256,0x8(%esp) + 1058aa: 00 + 1058ab: 8b 45 0c mov 0xc(%ebp),%eax + 1058ae: 89 44 24 04 mov %eax,0x4(%esp) + 1058b2: 8b 45 08 mov 0x8(%ebp),%eax + 1058b5: 89 04 24 mov %eax,(%esp) + 1058b8: e8 45 fe ff ff call 105702 + break; + 1058bd: e9 3d 02 00 00 jmp 105aff + + // string + case 's': + if ((p = va_arg(ap, char *)) == NULL) { + 1058c2: 8b 45 14 mov 0x14(%ebp),%eax + 1058c5: 8d 50 04 lea 0x4(%eax),%edx + 1058c8: 89 55 14 mov %edx,0x14(%ebp) + 1058cb: 8b 30 mov (%eax),%esi + 1058cd: 85 f6 test %esi,%esi + 1058cf: 75 05 jne 1058d6 + p = "(null)"; + 1058d1: be 59 72 10 00 mov $0x107259,%esi + } + if (width > 0 && padc != '-') { + 1058d6: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 1058da: 7e 76 jle 105952 + 1058dc: 80 7d db 2d cmpb $0x2d,-0x25(%ebp) + 1058e0: 74 70 je 105952 + for (width -= strnlen(p, precision); width > 0; width --) { + 1058e2: 8b 45 e4 mov -0x1c(%ebp),%eax + 1058e5: 89 44 24 04 mov %eax,0x4(%esp) + 1058e9: 89 34 24 mov %esi,(%esp) + 1058ec: e8 16 03 00 00 call 105c07 + 1058f1: 89 c2 mov %eax,%edx + 1058f3: 8b 45 e8 mov -0x18(%ebp),%eax + 1058f6: 29 d0 sub %edx,%eax + 1058f8: 89 45 e8 mov %eax,-0x18(%ebp) + 1058fb: eb 16 jmp 105913 + putch(padc, putdat); + 1058fd: 0f be 45 db movsbl -0x25(%ebp),%eax + 105901: 8b 55 0c mov 0xc(%ebp),%edx + 105904: 89 54 24 04 mov %edx,0x4(%esp) + 105908: 89 04 24 mov %eax,(%esp) + 10590b: 8b 45 08 mov 0x8(%ebp),%eax + 10590e: ff d0 call *%eax + for (width -= strnlen(p, precision); width > 0; width --) { + 105910: ff 4d e8 decl -0x18(%ebp) + 105913: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 105917: 7f e4 jg 1058fd + } + } + for (; (ch = *p ++) != '\0' && (precision < 0 || -- precision >= 0); width --) { + 105919: eb 37 jmp 105952 + if (altflag && (ch < ' ' || ch > '~')) { + 10591b: 83 7d dc 00 cmpl $0x0,-0x24(%ebp) + 10591f: 74 1f je 105940 + 105921: 83 fb 1f cmp $0x1f,%ebx + 105924: 7e 05 jle 10592b + 105926: 83 fb 7e cmp $0x7e,%ebx + 105929: 7e 15 jle 105940 + putch('?', putdat); + 10592b: 8b 45 0c mov 0xc(%ebp),%eax + 10592e: 89 44 24 04 mov %eax,0x4(%esp) + 105932: c7 04 24 3f 00 00 00 movl $0x3f,(%esp) + 105939: 8b 45 08 mov 0x8(%ebp),%eax + 10593c: ff d0 call *%eax + 10593e: eb 0f jmp 10594f + } + else { + putch(ch, putdat); + 105940: 8b 45 0c mov 0xc(%ebp),%eax + 105943: 89 44 24 04 mov %eax,0x4(%esp) + 105947: 89 1c 24 mov %ebx,(%esp) + 10594a: 8b 45 08 mov 0x8(%ebp),%eax + 10594d: ff d0 call *%eax + for (; (ch = *p ++) != '\0' && (precision < 0 || -- precision >= 0); width --) { + 10594f: ff 4d e8 decl -0x18(%ebp) + 105952: 89 f0 mov %esi,%eax + 105954: 8d 70 01 lea 0x1(%eax),%esi + 105957: 0f b6 00 movzbl (%eax),%eax + 10595a: 0f be d8 movsbl %al,%ebx + 10595d: 85 db test %ebx,%ebx + 10595f: 74 27 je 105988 + 105961: 83 7d e4 00 cmpl $0x0,-0x1c(%ebp) + 105965: 78 b4 js 10591b + 105967: ff 4d e4 decl -0x1c(%ebp) + 10596a: 83 7d e4 00 cmpl $0x0,-0x1c(%ebp) + 10596e: 79 ab jns 10591b + } + } + for (; width > 0; width --) { + 105970: eb 16 jmp 105988 + putch(' ', putdat); + 105972: 8b 45 0c mov 0xc(%ebp),%eax + 105975: 89 44 24 04 mov %eax,0x4(%esp) + 105979: c7 04 24 20 00 00 00 movl $0x20,(%esp) + 105980: 8b 45 08 mov 0x8(%ebp),%eax + 105983: ff d0 call *%eax + for (; width > 0; width --) { + 105985: ff 4d e8 decl -0x18(%ebp) + 105988: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 10598c: 7f e4 jg 105972 + } + break; + 10598e: e9 6c 01 00 00 jmp 105aff + + // (signed) decimal + case 'd': + num = getint(&ap, lflag); + 105993: 8b 45 e0 mov -0x20(%ebp),%eax + 105996: 89 44 24 04 mov %eax,0x4(%esp) + 10599a: 8d 45 14 lea 0x14(%ebp),%eax + 10599d: 89 04 24 mov %eax,(%esp) + 1059a0: e8 16 fd ff ff call 1056bb + 1059a5: 89 45 f0 mov %eax,-0x10(%ebp) + 1059a8: 89 55 f4 mov %edx,-0xc(%ebp) + if ((long long)num < 0) { + 1059ab: 8b 45 f0 mov -0x10(%ebp),%eax + 1059ae: 8b 55 f4 mov -0xc(%ebp),%edx + 1059b1: 85 d2 test %edx,%edx + 1059b3: 79 26 jns 1059db + putch('-', putdat); + 1059b5: 8b 45 0c mov 0xc(%ebp),%eax + 1059b8: 89 44 24 04 mov %eax,0x4(%esp) + 1059bc: c7 04 24 2d 00 00 00 movl $0x2d,(%esp) + 1059c3: 8b 45 08 mov 0x8(%ebp),%eax + 1059c6: ff d0 call *%eax + num = -(long long)num; + 1059c8: 8b 45 f0 mov -0x10(%ebp),%eax + 1059cb: 8b 55 f4 mov -0xc(%ebp),%edx + 1059ce: f7 d8 neg %eax + 1059d0: 83 d2 00 adc $0x0,%edx + 1059d3: f7 da neg %edx + 1059d5: 89 45 f0 mov %eax,-0x10(%ebp) + 1059d8: 89 55 f4 mov %edx,-0xc(%ebp) + } + base = 10; + 1059db: c7 45 ec 0a 00 00 00 movl $0xa,-0x14(%ebp) + goto number; + 1059e2: e9 a8 00 00 00 jmp 105a8f + + // unsigned decimal + case 'u': + num = getuint(&ap, lflag); + 1059e7: 8b 45 e0 mov -0x20(%ebp),%eax + 1059ea: 89 44 24 04 mov %eax,0x4(%esp) + 1059ee: 8d 45 14 lea 0x14(%ebp),%eax + 1059f1: 89 04 24 mov %eax,(%esp) + 1059f4: e8 73 fc ff ff call 10566c + 1059f9: 89 45 f0 mov %eax,-0x10(%ebp) + 1059fc: 89 55 f4 mov %edx,-0xc(%ebp) + base = 10; + 1059ff: c7 45 ec 0a 00 00 00 movl $0xa,-0x14(%ebp) + goto number; + 105a06: e9 84 00 00 00 jmp 105a8f + + // (unsigned) octal + case 'o': + num = getuint(&ap, lflag); + 105a0b: 8b 45 e0 mov -0x20(%ebp),%eax + 105a0e: 89 44 24 04 mov %eax,0x4(%esp) + 105a12: 8d 45 14 lea 0x14(%ebp),%eax + 105a15: 89 04 24 mov %eax,(%esp) + 105a18: e8 4f fc ff ff call 10566c + 105a1d: 89 45 f0 mov %eax,-0x10(%ebp) + 105a20: 89 55 f4 mov %edx,-0xc(%ebp) + base = 8; + 105a23: c7 45 ec 08 00 00 00 movl $0x8,-0x14(%ebp) + goto number; + 105a2a: eb 63 jmp 105a8f + + // pointer + case 'p': + putch('0', putdat); + 105a2c: 8b 45 0c mov 0xc(%ebp),%eax + 105a2f: 89 44 24 04 mov %eax,0x4(%esp) + 105a33: c7 04 24 30 00 00 00 movl $0x30,(%esp) + 105a3a: 8b 45 08 mov 0x8(%ebp),%eax + 105a3d: ff d0 call *%eax + putch('x', putdat); + 105a3f: 8b 45 0c mov 0xc(%ebp),%eax + 105a42: 89 44 24 04 mov %eax,0x4(%esp) + 105a46: c7 04 24 78 00 00 00 movl $0x78,(%esp) + 105a4d: 8b 45 08 mov 0x8(%ebp),%eax + 105a50: ff d0 call *%eax + num = (unsigned long long)(uintptr_t)va_arg(ap, void *); + 105a52: 8b 45 14 mov 0x14(%ebp),%eax + 105a55: 8d 50 04 lea 0x4(%eax),%edx + 105a58: 89 55 14 mov %edx,0x14(%ebp) + 105a5b: 8b 00 mov (%eax),%eax + 105a5d: 89 45 f0 mov %eax,-0x10(%ebp) + 105a60: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + base = 16; + 105a67: c7 45 ec 10 00 00 00 movl $0x10,-0x14(%ebp) + goto number; + 105a6e: eb 1f jmp 105a8f + + // (unsigned) hexadecimal + case 'x': + num = getuint(&ap, lflag); + 105a70: 8b 45 e0 mov -0x20(%ebp),%eax + 105a73: 89 44 24 04 mov %eax,0x4(%esp) + 105a77: 8d 45 14 lea 0x14(%ebp),%eax + 105a7a: 89 04 24 mov %eax,(%esp) + 105a7d: e8 ea fb ff ff call 10566c + 105a82: 89 45 f0 mov %eax,-0x10(%ebp) + 105a85: 89 55 f4 mov %edx,-0xc(%ebp) + base = 16; + 105a88: c7 45 ec 10 00 00 00 movl $0x10,-0x14(%ebp) + number: + printnum(putch, putdat, num, base, width, padc); + 105a8f: 0f be 55 db movsbl -0x25(%ebp),%edx + 105a93: 8b 45 ec mov -0x14(%ebp),%eax + 105a96: 89 54 24 18 mov %edx,0x18(%esp) + 105a9a: 8b 55 e8 mov -0x18(%ebp),%edx + 105a9d: 89 54 24 14 mov %edx,0x14(%esp) + 105aa1: 89 44 24 10 mov %eax,0x10(%esp) + 105aa5: 8b 45 f0 mov -0x10(%ebp),%eax + 105aa8: 8b 55 f4 mov -0xc(%ebp),%edx + 105aab: 89 44 24 08 mov %eax,0x8(%esp) + 105aaf: 89 54 24 0c mov %edx,0xc(%esp) + 105ab3: 8b 45 0c mov 0xc(%ebp),%eax + 105ab6: 89 44 24 04 mov %eax,0x4(%esp) + 105aba: 8b 45 08 mov 0x8(%ebp),%eax + 105abd: 89 04 24 mov %eax,(%esp) + 105ac0: e8 a5 fa ff ff call 10556a + break; + 105ac5: eb 38 jmp 105aff + + // escaped '%' character + case '%': + putch(ch, putdat); + 105ac7: 8b 45 0c mov 0xc(%ebp),%eax + 105aca: 89 44 24 04 mov %eax,0x4(%esp) + 105ace: 89 1c 24 mov %ebx,(%esp) + 105ad1: 8b 45 08 mov 0x8(%ebp),%eax + 105ad4: ff d0 call *%eax + break; + 105ad6: eb 27 jmp 105aff + + // unrecognized escape sequence - just print it literally + default: + putch('%', putdat); + 105ad8: 8b 45 0c mov 0xc(%ebp),%eax + 105adb: 89 44 24 04 mov %eax,0x4(%esp) + 105adf: c7 04 24 25 00 00 00 movl $0x25,(%esp) + 105ae6: 8b 45 08 mov 0x8(%ebp),%eax + 105ae9: ff d0 call *%eax + for (fmt --; fmt[-1] != '%'; fmt --) + 105aeb: ff 4d 10 decl 0x10(%ebp) + 105aee: eb 03 jmp 105af3 + 105af0: ff 4d 10 decl 0x10(%ebp) + 105af3: 8b 45 10 mov 0x10(%ebp),%eax + 105af6: 48 dec %eax + 105af7: 0f b6 00 movzbl (%eax),%eax + 105afa: 3c 25 cmp $0x25,%al + 105afc: 75 f2 jne 105af0 + /* do nothing */; + break; + 105afe: 90 nop + while (1) { + 105aff: e9 37 fc ff ff jmp 10573b + return; + 105b04: 90 nop + } + } +} + 105b05: 83 c4 40 add $0x40,%esp + 105b08: 5b pop %ebx + 105b09: 5e pop %esi + 105b0a: 5d pop %ebp + 105b0b: c3 ret + +00105b0c : + * 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) { + 105b0c: 55 push %ebp + 105b0d: 89 e5 mov %esp,%ebp + b->cnt ++; + 105b0f: 8b 45 0c mov 0xc(%ebp),%eax + 105b12: 8b 40 08 mov 0x8(%eax),%eax + 105b15: 8d 50 01 lea 0x1(%eax),%edx + 105b18: 8b 45 0c mov 0xc(%ebp),%eax + 105b1b: 89 50 08 mov %edx,0x8(%eax) + if (b->buf < b->ebuf) { + 105b1e: 8b 45 0c mov 0xc(%ebp),%eax + 105b21: 8b 10 mov (%eax),%edx + 105b23: 8b 45 0c mov 0xc(%ebp),%eax + 105b26: 8b 40 04 mov 0x4(%eax),%eax + 105b29: 39 c2 cmp %eax,%edx + 105b2b: 73 12 jae 105b3f + *b->buf ++ = ch; + 105b2d: 8b 45 0c mov 0xc(%ebp),%eax + 105b30: 8b 00 mov (%eax),%eax + 105b32: 8d 48 01 lea 0x1(%eax),%ecx + 105b35: 8b 55 0c mov 0xc(%ebp),%edx + 105b38: 89 0a mov %ecx,(%edx) + 105b3a: 8b 55 08 mov 0x8(%ebp),%edx + 105b3d: 88 10 mov %dl,(%eax) + } +} + 105b3f: 90 nop + 105b40: 5d pop %ebp + 105b41: c3 ret + +00105b42 : + * @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, ...) { + 105b42: 55 push %ebp + 105b43: 89 e5 mov %esp,%ebp + 105b45: 83 ec 28 sub $0x28,%esp + va_list ap; + int cnt; + va_start(ap, fmt); + 105b48: 8d 45 14 lea 0x14(%ebp),%eax + 105b4b: 89 45 f0 mov %eax,-0x10(%ebp) + cnt = vsnprintf(str, size, fmt, ap); + 105b4e: 8b 45 f0 mov -0x10(%ebp),%eax + 105b51: 89 44 24 0c mov %eax,0xc(%esp) + 105b55: 8b 45 10 mov 0x10(%ebp),%eax + 105b58: 89 44 24 08 mov %eax,0x8(%esp) + 105b5c: 8b 45 0c mov 0xc(%ebp),%eax + 105b5f: 89 44 24 04 mov %eax,0x4(%esp) + 105b63: 8b 45 08 mov 0x8(%ebp),%eax + 105b66: 89 04 24 mov %eax,(%esp) + 105b69: e8 0a 00 00 00 call 105b78 + 105b6e: 89 45 f4 mov %eax,-0xc(%ebp) + va_end(ap); + return cnt; + 105b71: 8b 45 f4 mov -0xc(%ebp),%eax +} + 105b74: 89 ec mov %ebp,%esp + 105b76: 5d pop %ebp + 105b77: c3 ret + +00105b78 : + * + * 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) { + 105b78: 55 push %ebp + 105b79: 89 e5 mov %esp,%ebp + 105b7b: 83 ec 28 sub $0x28,%esp + struct sprintbuf b = {str, str + size - 1, 0}; + 105b7e: 8b 45 08 mov 0x8(%ebp),%eax + 105b81: 89 45 ec mov %eax,-0x14(%ebp) + 105b84: 8b 45 0c mov 0xc(%ebp),%eax + 105b87: 8d 50 ff lea -0x1(%eax),%edx + 105b8a: 8b 45 08 mov 0x8(%ebp),%eax + 105b8d: 01 d0 add %edx,%eax + 105b8f: 89 45 f0 mov %eax,-0x10(%ebp) + 105b92: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + if (str == NULL || b.buf > b.ebuf) { + 105b99: 83 7d 08 00 cmpl $0x0,0x8(%ebp) + 105b9d: 74 0a je 105ba9 + 105b9f: 8b 55 ec mov -0x14(%ebp),%edx + 105ba2: 8b 45 f0 mov -0x10(%ebp),%eax + 105ba5: 39 c2 cmp %eax,%edx + 105ba7: 76 07 jbe 105bb0 + return -E_INVAL; + 105ba9: b8 fd ff ff ff mov $0xfffffffd,%eax + 105bae: eb 2a jmp 105bda + } + // print the string to the buffer + vprintfmt((void*)sprintputch, &b, fmt, ap); + 105bb0: 8b 45 14 mov 0x14(%ebp),%eax + 105bb3: 89 44 24 0c mov %eax,0xc(%esp) + 105bb7: 8b 45 10 mov 0x10(%ebp),%eax + 105bba: 89 44 24 08 mov %eax,0x8(%esp) + 105bbe: 8d 45 ec lea -0x14(%ebp),%eax + 105bc1: 89 44 24 04 mov %eax,0x4(%esp) + 105bc5: c7 04 24 0c 5b 10 00 movl $0x105b0c,(%esp) + 105bcc: e8 62 fb ff ff call 105733 + // null terminate the buffer + *b.buf = '\0'; + 105bd1: 8b 45 ec mov -0x14(%ebp),%eax + 105bd4: c6 00 00 movb $0x0,(%eax) + return b.cnt; + 105bd7: 8b 45 f4 mov -0xc(%ebp),%eax +} + 105bda: 89 ec mov %ebp,%esp + 105bdc: 5d pop %ebp + 105bdd: c3 ret + +00105bde : + * @s: the input string + * + * The strlen() function returns the length of string @s. + * */ +size_t +strlen(const char *s) { + 105bde: 55 push %ebp + 105bdf: 89 e5 mov %esp,%ebp + 105be1: 83 ec 10 sub $0x10,%esp + size_t cnt = 0; + 105be4: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + while (*s ++ != '\0') { + 105beb: eb 03 jmp 105bf0 + cnt ++; + 105bed: ff 45 fc incl -0x4(%ebp) + while (*s ++ != '\0') { + 105bf0: 8b 45 08 mov 0x8(%ebp),%eax + 105bf3: 8d 50 01 lea 0x1(%eax),%edx + 105bf6: 89 55 08 mov %edx,0x8(%ebp) + 105bf9: 0f b6 00 movzbl (%eax),%eax + 105bfc: 84 c0 test %al,%al + 105bfe: 75 ed jne 105bed + } + return cnt; + 105c00: 8b 45 fc mov -0x4(%ebp),%eax +} + 105c03: 89 ec mov %ebp,%esp + 105c05: 5d pop %ebp + 105c06: c3 ret + +00105c07 : + * 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) { + 105c07: 55 push %ebp + 105c08: 89 e5 mov %esp,%ebp + 105c0a: 83 ec 10 sub $0x10,%esp + size_t cnt = 0; + 105c0d: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + while (cnt < len && *s ++ != '\0') { + 105c14: eb 03 jmp 105c19 + cnt ++; + 105c16: ff 45 fc incl -0x4(%ebp) + while (cnt < len && *s ++ != '\0') { + 105c19: 8b 45 fc mov -0x4(%ebp),%eax + 105c1c: 3b 45 0c cmp 0xc(%ebp),%eax + 105c1f: 73 10 jae 105c31 + 105c21: 8b 45 08 mov 0x8(%ebp),%eax + 105c24: 8d 50 01 lea 0x1(%eax),%edx + 105c27: 89 55 08 mov %edx,0x8(%ebp) + 105c2a: 0f b6 00 movzbl (%eax),%eax + 105c2d: 84 c0 test %al,%al + 105c2f: 75 e5 jne 105c16 + } + return cnt; + 105c31: 8b 45 fc mov -0x4(%ebp),%eax +} + 105c34: 89 ec mov %ebp,%esp + 105c36: 5d pop %ebp + 105c37: c3 ret + +00105c38 : + * 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) { + 105c38: 55 push %ebp + 105c39: 89 e5 mov %esp,%ebp + 105c3b: 57 push %edi + 105c3c: 56 push %esi + 105c3d: 83 ec 20 sub $0x20,%esp + 105c40: 8b 45 08 mov 0x8(%ebp),%eax + 105c43: 89 45 f4 mov %eax,-0xc(%ebp) + 105c46: 8b 45 0c mov 0xc(%ebp),%eax + 105c49: 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 ( + 105c4c: 8b 55 f0 mov -0x10(%ebp),%edx + 105c4f: 8b 45 f4 mov -0xc(%ebp),%eax + 105c52: 89 d1 mov %edx,%ecx + 105c54: 89 c2 mov %eax,%edx + 105c56: 89 ce mov %ecx,%esi + 105c58: 89 d7 mov %edx,%edi + 105c5a: ac lods %ds:(%esi),%al + 105c5b: aa stos %al,%es:(%edi) + 105c5c: 84 c0 test %al,%al + 105c5e: 75 fa jne 105c5a + 105c60: 89 fa mov %edi,%edx + 105c62: 89 f1 mov %esi,%ecx + 105c64: 89 4d ec mov %ecx,-0x14(%ebp) + 105c67: 89 55 e8 mov %edx,-0x18(%ebp) + 105c6a: 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; + 105c6d: 8b 45 f4 mov -0xc(%ebp),%eax + char *p = dst; + while ((*p ++ = *src ++) != '\0') + /* nothing */; + return dst; +#endif /* __HAVE_ARCH_STRCPY */ +} + 105c70: 83 c4 20 add $0x20,%esp + 105c73: 5e pop %esi + 105c74: 5f pop %edi + 105c75: 5d pop %ebp + 105c76: c3 ret + +00105c77 : + * @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) { + 105c77: 55 push %ebp + 105c78: 89 e5 mov %esp,%ebp + 105c7a: 83 ec 10 sub $0x10,%esp + char *p = dst; + 105c7d: 8b 45 08 mov 0x8(%ebp),%eax + 105c80: 89 45 fc mov %eax,-0x4(%ebp) + while (len > 0) { + 105c83: eb 1e jmp 105ca3 + if ((*p = *src) != '\0') { + 105c85: 8b 45 0c mov 0xc(%ebp),%eax + 105c88: 0f b6 10 movzbl (%eax),%edx + 105c8b: 8b 45 fc mov -0x4(%ebp),%eax + 105c8e: 88 10 mov %dl,(%eax) + 105c90: 8b 45 fc mov -0x4(%ebp),%eax + 105c93: 0f b6 00 movzbl (%eax),%eax + 105c96: 84 c0 test %al,%al + 105c98: 74 03 je 105c9d + src ++; + 105c9a: ff 45 0c incl 0xc(%ebp) + } + p ++, len --; + 105c9d: ff 45 fc incl -0x4(%ebp) + 105ca0: ff 4d 10 decl 0x10(%ebp) + while (len > 0) { + 105ca3: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 105ca7: 75 dc jne 105c85 + } + return dst; + 105ca9: 8b 45 08 mov 0x8(%ebp),%eax +} + 105cac: 89 ec mov %ebp,%esp + 105cae: 5d pop %ebp + 105caf: c3 ret + +00105cb0 : + * - 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) { + 105cb0: 55 push %ebp + 105cb1: 89 e5 mov %esp,%ebp + 105cb3: 57 push %edi + 105cb4: 56 push %esi + 105cb5: 83 ec 20 sub $0x20,%esp + 105cb8: 8b 45 08 mov 0x8(%ebp),%eax + 105cbb: 89 45 f4 mov %eax,-0xc(%ebp) + 105cbe: 8b 45 0c mov 0xc(%ebp),%eax + 105cc1: 89 45 f0 mov %eax,-0x10(%ebp) + asm volatile ( + 105cc4: 8b 55 f4 mov -0xc(%ebp),%edx + 105cc7: 8b 45 f0 mov -0x10(%ebp),%eax + 105cca: 89 d1 mov %edx,%ecx + 105ccc: 89 c2 mov %eax,%edx + 105cce: 89 ce mov %ecx,%esi + 105cd0: 89 d7 mov %edx,%edi + 105cd2: ac lods %ds:(%esi),%al + 105cd3: ae scas %es:(%edi),%al + 105cd4: 75 08 jne 105cde + 105cd6: 84 c0 test %al,%al + 105cd8: 75 f8 jne 105cd2 + 105cda: 31 c0 xor %eax,%eax + 105cdc: eb 04 jmp 105ce2 + 105cde: 19 c0 sbb %eax,%eax + 105ce0: 0c 01 or $0x1,%al + 105ce2: 89 fa mov %edi,%edx + 105ce4: 89 f1 mov %esi,%ecx + 105ce6: 89 45 ec mov %eax,-0x14(%ebp) + 105ce9: 89 4d e8 mov %ecx,-0x18(%ebp) + 105cec: 89 55 e4 mov %edx,-0x1c(%ebp) + return ret; + 105cef: 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 */ +} + 105cf2: 83 c4 20 add $0x20,%esp + 105cf5: 5e pop %esi + 105cf6: 5f pop %edi + 105cf7: 5d pop %ebp + 105cf8: c3 ret + +00105cf9 : + * 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) { + 105cf9: 55 push %ebp + 105cfa: 89 e5 mov %esp,%ebp + while (n > 0 && *s1 != '\0' && *s1 == *s2) { + 105cfc: eb 09 jmp 105d07 + n --, s1 ++, s2 ++; + 105cfe: ff 4d 10 decl 0x10(%ebp) + 105d01: ff 45 08 incl 0x8(%ebp) + 105d04: ff 45 0c incl 0xc(%ebp) + while (n > 0 && *s1 != '\0' && *s1 == *s2) { + 105d07: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 105d0b: 74 1a je 105d27 + 105d0d: 8b 45 08 mov 0x8(%ebp),%eax + 105d10: 0f b6 00 movzbl (%eax),%eax + 105d13: 84 c0 test %al,%al + 105d15: 74 10 je 105d27 + 105d17: 8b 45 08 mov 0x8(%ebp),%eax + 105d1a: 0f b6 10 movzbl (%eax),%edx + 105d1d: 8b 45 0c mov 0xc(%ebp),%eax + 105d20: 0f b6 00 movzbl (%eax),%eax + 105d23: 38 c2 cmp %al,%dl + 105d25: 74 d7 je 105cfe + } + return (n == 0) ? 0 : (int)((unsigned char)*s1 - (unsigned char)*s2); + 105d27: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 105d2b: 74 18 je 105d45 + 105d2d: 8b 45 08 mov 0x8(%ebp),%eax + 105d30: 0f b6 00 movzbl (%eax),%eax + 105d33: 0f b6 d0 movzbl %al,%edx + 105d36: 8b 45 0c mov 0xc(%ebp),%eax + 105d39: 0f b6 00 movzbl (%eax),%eax + 105d3c: 0f b6 c8 movzbl %al,%ecx + 105d3f: 89 d0 mov %edx,%eax + 105d41: 29 c8 sub %ecx,%eax + 105d43: eb 05 jmp 105d4a + 105d45: b8 00 00 00 00 mov $0x0,%eax +} + 105d4a: 5d pop %ebp + 105d4b: c3 ret + +00105d4c : + * + * 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) { + 105d4c: 55 push %ebp + 105d4d: 89 e5 mov %esp,%ebp + 105d4f: 83 ec 04 sub $0x4,%esp + 105d52: 8b 45 0c mov 0xc(%ebp),%eax + 105d55: 88 45 fc mov %al,-0x4(%ebp) + while (*s != '\0') { + 105d58: eb 13 jmp 105d6d + if (*s == c) { + 105d5a: 8b 45 08 mov 0x8(%ebp),%eax + 105d5d: 0f b6 00 movzbl (%eax),%eax + 105d60: 38 45 fc cmp %al,-0x4(%ebp) + 105d63: 75 05 jne 105d6a + return (char *)s; + 105d65: 8b 45 08 mov 0x8(%ebp),%eax + 105d68: eb 12 jmp 105d7c + } + s ++; + 105d6a: ff 45 08 incl 0x8(%ebp) + while (*s != '\0') { + 105d6d: 8b 45 08 mov 0x8(%ebp),%eax + 105d70: 0f b6 00 movzbl (%eax),%eax + 105d73: 84 c0 test %al,%al + 105d75: 75 e3 jne 105d5a + } + return NULL; + 105d77: b8 00 00 00 00 mov $0x0,%eax +} + 105d7c: 89 ec mov %ebp,%esp + 105d7e: 5d pop %ebp + 105d7f: c3 ret + +00105d80 : + * 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) { + 105d80: 55 push %ebp + 105d81: 89 e5 mov %esp,%ebp + 105d83: 83 ec 04 sub $0x4,%esp + 105d86: 8b 45 0c mov 0xc(%ebp),%eax + 105d89: 88 45 fc mov %al,-0x4(%ebp) + while (*s != '\0') { + 105d8c: eb 0e jmp 105d9c + if (*s == c) { + 105d8e: 8b 45 08 mov 0x8(%ebp),%eax + 105d91: 0f b6 00 movzbl (%eax),%eax + 105d94: 38 45 fc cmp %al,-0x4(%ebp) + 105d97: 74 0f je 105da8 + break; + } + s ++; + 105d99: ff 45 08 incl 0x8(%ebp) + while (*s != '\0') { + 105d9c: 8b 45 08 mov 0x8(%ebp),%eax + 105d9f: 0f b6 00 movzbl (%eax),%eax + 105da2: 84 c0 test %al,%al + 105da4: 75 e8 jne 105d8e + 105da6: eb 01 jmp 105da9 + break; + 105da8: 90 nop + } + return (char *)s; + 105da9: 8b 45 08 mov 0x8(%ebp),%eax +} + 105dac: 89 ec mov %ebp,%esp + 105dae: 5d pop %ebp + 105daf: c3 ret + +00105db0 : + * 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) { + 105db0: 55 push %ebp + 105db1: 89 e5 mov %esp,%ebp + 105db3: 83 ec 10 sub $0x10,%esp + int neg = 0; + 105db6: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + long val = 0; + 105dbd: c7 45 f8 00 00 00 00 movl $0x0,-0x8(%ebp) + + // gobble initial whitespace + while (*s == ' ' || *s == '\t') { + 105dc4: eb 03 jmp 105dc9 + s ++; + 105dc6: ff 45 08 incl 0x8(%ebp) + while (*s == ' ' || *s == '\t') { + 105dc9: 8b 45 08 mov 0x8(%ebp),%eax + 105dcc: 0f b6 00 movzbl (%eax),%eax + 105dcf: 3c 20 cmp $0x20,%al + 105dd1: 74 f3 je 105dc6 + 105dd3: 8b 45 08 mov 0x8(%ebp),%eax + 105dd6: 0f b6 00 movzbl (%eax),%eax + 105dd9: 3c 09 cmp $0x9,%al + 105ddb: 74 e9 je 105dc6 + } + + // plus/minus sign + if (*s == '+') { + 105ddd: 8b 45 08 mov 0x8(%ebp),%eax + 105de0: 0f b6 00 movzbl (%eax),%eax + 105de3: 3c 2b cmp $0x2b,%al + 105de5: 75 05 jne 105dec + s ++; + 105de7: ff 45 08 incl 0x8(%ebp) + 105dea: eb 14 jmp 105e00 + } + else if (*s == '-') { + 105dec: 8b 45 08 mov 0x8(%ebp),%eax + 105def: 0f b6 00 movzbl (%eax),%eax + 105df2: 3c 2d cmp $0x2d,%al + 105df4: 75 0a jne 105e00 + s ++, neg = 1; + 105df6: ff 45 08 incl 0x8(%ebp) + 105df9: 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')) { + 105e00: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 105e04: 74 06 je 105e0c + 105e06: 83 7d 10 10 cmpl $0x10,0x10(%ebp) + 105e0a: 75 22 jne 105e2e + 105e0c: 8b 45 08 mov 0x8(%ebp),%eax + 105e0f: 0f b6 00 movzbl (%eax),%eax + 105e12: 3c 30 cmp $0x30,%al + 105e14: 75 18 jne 105e2e + 105e16: 8b 45 08 mov 0x8(%ebp),%eax + 105e19: 40 inc %eax + 105e1a: 0f b6 00 movzbl (%eax),%eax + 105e1d: 3c 78 cmp $0x78,%al + 105e1f: 75 0d jne 105e2e + s += 2, base = 16; + 105e21: 83 45 08 02 addl $0x2,0x8(%ebp) + 105e25: c7 45 10 10 00 00 00 movl $0x10,0x10(%ebp) + 105e2c: eb 29 jmp 105e57 + } + else if (base == 0 && s[0] == '0') { + 105e2e: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 105e32: 75 16 jne 105e4a + 105e34: 8b 45 08 mov 0x8(%ebp),%eax + 105e37: 0f b6 00 movzbl (%eax),%eax + 105e3a: 3c 30 cmp $0x30,%al + 105e3c: 75 0c jne 105e4a + s ++, base = 8; + 105e3e: ff 45 08 incl 0x8(%ebp) + 105e41: c7 45 10 08 00 00 00 movl $0x8,0x10(%ebp) + 105e48: eb 0d jmp 105e57 + } + else if (base == 0) { + 105e4a: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 105e4e: 75 07 jne 105e57 + base = 10; + 105e50: c7 45 10 0a 00 00 00 movl $0xa,0x10(%ebp) + + // digits + while (1) { + int dig; + + if (*s >= '0' && *s <= '9') { + 105e57: 8b 45 08 mov 0x8(%ebp),%eax + 105e5a: 0f b6 00 movzbl (%eax),%eax + 105e5d: 3c 2f cmp $0x2f,%al + 105e5f: 7e 1b jle 105e7c + 105e61: 8b 45 08 mov 0x8(%ebp),%eax + 105e64: 0f b6 00 movzbl (%eax),%eax + 105e67: 3c 39 cmp $0x39,%al + 105e69: 7f 11 jg 105e7c + dig = *s - '0'; + 105e6b: 8b 45 08 mov 0x8(%ebp),%eax + 105e6e: 0f b6 00 movzbl (%eax),%eax + 105e71: 0f be c0 movsbl %al,%eax + 105e74: 83 e8 30 sub $0x30,%eax + 105e77: 89 45 f4 mov %eax,-0xc(%ebp) + 105e7a: eb 48 jmp 105ec4 + } + else if (*s >= 'a' && *s <= 'z') { + 105e7c: 8b 45 08 mov 0x8(%ebp),%eax + 105e7f: 0f b6 00 movzbl (%eax),%eax + 105e82: 3c 60 cmp $0x60,%al + 105e84: 7e 1b jle 105ea1 + 105e86: 8b 45 08 mov 0x8(%ebp),%eax + 105e89: 0f b6 00 movzbl (%eax),%eax + 105e8c: 3c 7a cmp $0x7a,%al + 105e8e: 7f 11 jg 105ea1 + dig = *s - 'a' + 10; + 105e90: 8b 45 08 mov 0x8(%ebp),%eax + 105e93: 0f b6 00 movzbl (%eax),%eax + 105e96: 0f be c0 movsbl %al,%eax + 105e99: 83 e8 57 sub $0x57,%eax + 105e9c: 89 45 f4 mov %eax,-0xc(%ebp) + 105e9f: eb 23 jmp 105ec4 + } + else if (*s >= 'A' && *s <= 'Z') { + 105ea1: 8b 45 08 mov 0x8(%ebp),%eax + 105ea4: 0f b6 00 movzbl (%eax),%eax + 105ea7: 3c 40 cmp $0x40,%al + 105ea9: 7e 3b jle 105ee6 + 105eab: 8b 45 08 mov 0x8(%ebp),%eax + 105eae: 0f b6 00 movzbl (%eax),%eax + 105eb1: 3c 5a cmp $0x5a,%al + 105eb3: 7f 31 jg 105ee6 + dig = *s - 'A' + 10; + 105eb5: 8b 45 08 mov 0x8(%ebp),%eax + 105eb8: 0f b6 00 movzbl (%eax),%eax + 105ebb: 0f be c0 movsbl %al,%eax + 105ebe: 83 e8 37 sub $0x37,%eax + 105ec1: 89 45 f4 mov %eax,-0xc(%ebp) + } + else { + break; + } + if (dig >= base) { + 105ec4: 8b 45 f4 mov -0xc(%ebp),%eax + 105ec7: 3b 45 10 cmp 0x10(%ebp),%eax + 105eca: 7d 19 jge 105ee5 + break; + } + s ++, val = (val * base) + dig; + 105ecc: ff 45 08 incl 0x8(%ebp) + 105ecf: 8b 45 f8 mov -0x8(%ebp),%eax + 105ed2: 0f af 45 10 imul 0x10(%ebp),%eax + 105ed6: 89 c2 mov %eax,%edx + 105ed8: 8b 45 f4 mov -0xc(%ebp),%eax + 105edb: 01 d0 add %edx,%eax + 105edd: 89 45 f8 mov %eax,-0x8(%ebp) + while (1) { + 105ee0: e9 72 ff ff ff jmp 105e57 + break; + 105ee5: 90 nop + // we don't properly detect overflow! + } + + if (endptr) { + 105ee6: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) + 105eea: 74 08 je 105ef4 + *endptr = (char *) s; + 105eec: 8b 45 0c mov 0xc(%ebp),%eax + 105eef: 8b 55 08 mov 0x8(%ebp),%edx + 105ef2: 89 10 mov %edx,(%eax) + } + return (neg ? -val : val); + 105ef4: 83 7d fc 00 cmpl $0x0,-0x4(%ebp) + 105ef8: 74 07 je 105f01 + 105efa: 8b 45 f8 mov -0x8(%ebp),%eax + 105efd: f7 d8 neg %eax + 105eff: eb 03 jmp 105f04 + 105f01: 8b 45 f8 mov -0x8(%ebp),%eax +} + 105f04: 89 ec mov %ebp,%esp + 105f06: 5d pop %ebp + 105f07: c3 ret + +00105f08 : + * @n: number of bytes to be set to the value + * + * The memset() function returns @s. + * */ +void * +memset(void *s, char c, size_t n) { + 105f08: 55 push %ebp + 105f09: 89 e5 mov %esp,%ebp + 105f0b: 83 ec 28 sub $0x28,%esp + 105f0e: 89 7d fc mov %edi,-0x4(%ebp) + 105f11: 8b 45 0c mov 0xc(%ebp),%eax + 105f14: 88 45 d8 mov %al,-0x28(%ebp) +#ifdef __HAVE_ARCH_MEMSET + return __memset(s, c, n); + 105f17: 0f be 55 d8 movsbl -0x28(%ebp),%edx + 105f1b: 8b 45 08 mov 0x8(%ebp),%eax + 105f1e: 89 45 f8 mov %eax,-0x8(%ebp) + 105f21: 88 55 f7 mov %dl,-0x9(%ebp) + 105f24: 8b 45 10 mov 0x10(%ebp),%eax + 105f27: 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 ( + 105f2a: 8b 4d f0 mov -0x10(%ebp),%ecx + 105f2d: 0f b6 45 f7 movzbl -0x9(%ebp),%eax + 105f31: 8b 55 f8 mov -0x8(%ebp),%edx + 105f34: 89 d7 mov %edx,%edi + 105f36: f3 aa rep stos %al,%es:(%edi) + 105f38: 89 fa mov %edi,%edx + 105f3a: 89 4d ec mov %ecx,-0x14(%ebp) + 105f3d: 89 55 e8 mov %edx,-0x18(%ebp) + "rep; stosb;" + : "=&c" (d0), "=&D" (d1) + : "0" (n), "a" (c), "1" (s) + : "memory"); + return s; + 105f40: 8b 45 f8 mov -0x8(%ebp),%eax + while (n -- > 0) { + *p ++ = c; + } + return s; +#endif /* __HAVE_ARCH_MEMSET */ +} + 105f43: 8b 7d fc mov -0x4(%ebp),%edi + 105f46: 89 ec mov %ebp,%esp + 105f48: 5d pop %ebp + 105f49: c3 ret + +00105f4a : + * @n: number of bytes to copy + * + * The memmove() function returns @dst. + * */ +void * +memmove(void *dst, const void *src, size_t n) { + 105f4a: 55 push %ebp + 105f4b: 89 e5 mov %esp,%ebp + 105f4d: 57 push %edi + 105f4e: 56 push %esi + 105f4f: 53 push %ebx + 105f50: 83 ec 30 sub $0x30,%esp + 105f53: 8b 45 08 mov 0x8(%ebp),%eax + 105f56: 89 45 f0 mov %eax,-0x10(%ebp) + 105f59: 8b 45 0c mov 0xc(%ebp),%eax + 105f5c: 89 45 ec mov %eax,-0x14(%ebp) + 105f5f: 8b 45 10 mov 0x10(%ebp),%eax + 105f62: 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) { + 105f65: 8b 45 f0 mov -0x10(%ebp),%eax + 105f68: 3b 45 ec cmp -0x14(%ebp),%eax + 105f6b: 73 42 jae 105faf + 105f6d: 8b 45 f0 mov -0x10(%ebp),%eax + 105f70: 89 45 e4 mov %eax,-0x1c(%ebp) + 105f73: 8b 45 ec mov -0x14(%ebp),%eax + 105f76: 89 45 e0 mov %eax,-0x20(%ebp) + 105f79: 8b 45 e8 mov -0x18(%ebp),%eax + 105f7c: 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) + 105f7f: 8b 45 dc mov -0x24(%ebp),%eax + 105f82: c1 e8 02 shr $0x2,%eax + 105f85: 89 c1 mov %eax,%ecx + asm volatile ( + 105f87: 8b 55 e4 mov -0x1c(%ebp),%edx + 105f8a: 8b 45 e0 mov -0x20(%ebp),%eax + 105f8d: 89 d7 mov %edx,%edi + 105f8f: 89 c6 mov %eax,%esi + 105f91: f3 a5 rep movsl %ds:(%esi),%es:(%edi) + 105f93: 8b 4d dc mov -0x24(%ebp),%ecx + 105f96: 83 e1 03 and $0x3,%ecx + 105f99: 74 02 je 105f9d + 105f9b: f3 a4 rep movsb %ds:(%esi),%es:(%edi) + 105f9d: 89 f0 mov %esi,%eax + 105f9f: 89 fa mov %edi,%edx + 105fa1: 89 4d d8 mov %ecx,-0x28(%ebp) + 105fa4: 89 55 d4 mov %edx,-0x2c(%ebp) + 105fa7: 89 45 d0 mov %eax,-0x30(%ebp) + : "memory"); + return dst; + 105faa: 8b 45 e4 mov -0x1c(%ebp),%eax + return __memcpy(dst, src, n); + 105fad: eb 36 jmp 105fe5 + : "0" (n), "1" (n - 1 + src), "2" (n - 1 + dst) + 105faf: 8b 45 e8 mov -0x18(%ebp),%eax + 105fb2: 8d 50 ff lea -0x1(%eax),%edx + 105fb5: 8b 45 ec mov -0x14(%ebp),%eax + 105fb8: 01 c2 add %eax,%edx + 105fba: 8b 45 e8 mov -0x18(%ebp),%eax + 105fbd: 8d 48 ff lea -0x1(%eax),%ecx + 105fc0: 8b 45 f0 mov -0x10(%ebp),%eax + 105fc3: 8d 1c 01 lea (%ecx,%eax,1),%ebx + asm volatile ( + 105fc6: 8b 45 e8 mov -0x18(%ebp),%eax + 105fc9: 89 c1 mov %eax,%ecx + 105fcb: 89 d8 mov %ebx,%eax + 105fcd: 89 d6 mov %edx,%esi + 105fcf: 89 c7 mov %eax,%edi + 105fd1: fd std + 105fd2: f3 a4 rep movsb %ds:(%esi),%es:(%edi) + 105fd4: fc cld + 105fd5: 89 f8 mov %edi,%eax + 105fd7: 89 f2 mov %esi,%edx + 105fd9: 89 4d cc mov %ecx,-0x34(%ebp) + 105fdc: 89 55 c8 mov %edx,-0x38(%ebp) + 105fdf: 89 45 c4 mov %eax,-0x3c(%ebp) + return dst; + 105fe2: 8b 45 f0 mov -0x10(%ebp),%eax + *d ++ = *s ++; + } + } + return dst; +#endif /* __HAVE_ARCH_MEMMOVE */ +} + 105fe5: 83 c4 30 add $0x30,%esp + 105fe8: 5b pop %ebx + 105fe9: 5e pop %esi + 105fea: 5f pop %edi + 105feb: 5d pop %ebp + 105fec: c3 ret + +00105fed : + * 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) { + 105fed: 55 push %ebp + 105fee: 89 e5 mov %esp,%ebp + 105ff0: 57 push %edi + 105ff1: 56 push %esi + 105ff2: 83 ec 20 sub $0x20,%esp + 105ff5: 8b 45 08 mov 0x8(%ebp),%eax + 105ff8: 89 45 f4 mov %eax,-0xc(%ebp) + 105ffb: 8b 45 0c mov 0xc(%ebp),%eax + 105ffe: 89 45 f0 mov %eax,-0x10(%ebp) + 106001: 8b 45 10 mov 0x10(%ebp),%eax + 106004: 89 45 ec mov %eax,-0x14(%ebp) + : "0" (n / 4), "g" (n), "1" (dst), "2" (src) + 106007: 8b 45 ec mov -0x14(%ebp),%eax + 10600a: c1 e8 02 shr $0x2,%eax + 10600d: 89 c1 mov %eax,%ecx + asm volatile ( + 10600f: 8b 55 f4 mov -0xc(%ebp),%edx + 106012: 8b 45 f0 mov -0x10(%ebp),%eax + 106015: 89 d7 mov %edx,%edi + 106017: 89 c6 mov %eax,%esi + 106019: f3 a5 rep movsl %ds:(%esi),%es:(%edi) + 10601b: 8b 4d ec mov -0x14(%ebp),%ecx + 10601e: 83 e1 03 and $0x3,%ecx + 106021: 74 02 je 106025 + 106023: f3 a4 rep movsb %ds:(%esi),%es:(%edi) + 106025: 89 f0 mov %esi,%eax + 106027: 89 fa mov %edi,%edx + 106029: 89 4d e8 mov %ecx,-0x18(%ebp) + 10602c: 89 55 e4 mov %edx,-0x1c(%ebp) + 10602f: 89 45 e0 mov %eax,-0x20(%ebp) + return dst; + 106032: 8b 45 f4 mov -0xc(%ebp),%eax + while (n -- > 0) { + *d ++ = *s ++; + } + return dst; +#endif /* __HAVE_ARCH_MEMCPY */ +} + 106035: 83 c4 20 add $0x20,%esp + 106038: 5e pop %esi + 106039: 5f pop %edi + 10603a: 5d pop %ebp + 10603b: c3 ret + +0010603c : + * 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) { + 10603c: 55 push %ebp + 10603d: 89 e5 mov %esp,%ebp + 10603f: 83 ec 10 sub $0x10,%esp + const char *s1 = (const char *)v1; + 106042: 8b 45 08 mov 0x8(%ebp),%eax + 106045: 89 45 fc mov %eax,-0x4(%ebp) + const char *s2 = (const char *)v2; + 106048: 8b 45 0c mov 0xc(%ebp),%eax + 10604b: 89 45 f8 mov %eax,-0x8(%ebp) + while (n -- > 0) { + 10604e: eb 2e jmp 10607e + if (*s1 != *s2) { + 106050: 8b 45 fc mov -0x4(%ebp),%eax + 106053: 0f b6 10 movzbl (%eax),%edx + 106056: 8b 45 f8 mov -0x8(%ebp),%eax + 106059: 0f b6 00 movzbl (%eax),%eax + 10605c: 38 c2 cmp %al,%dl + 10605e: 74 18 je 106078 + return (int)((unsigned char)*s1 - (unsigned char)*s2); + 106060: 8b 45 fc mov -0x4(%ebp),%eax + 106063: 0f b6 00 movzbl (%eax),%eax + 106066: 0f b6 d0 movzbl %al,%edx + 106069: 8b 45 f8 mov -0x8(%ebp),%eax + 10606c: 0f b6 00 movzbl (%eax),%eax + 10606f: 0f b6 c8 movzbl %al,%ecx + 106072: 89 d0 mov %edx,%eax + 106074: 29 c8 sub %ecx,%eax + 106076: eb 18 jmp 106090 + } + s1 ++, s2 ++; + 106078: ff 45 fc incl -0x4(%ebp) + 10607b: ff 45 f8 incl -0x8(%ebp) + while (n -- > 0) { + 10607e: 8b 45 10 mov 0x10(%ebp),%eax + 106081: 8d 50 ff lea -0x1(%eax),%edx + 106084: 89 55 10 mov %edx,0x10(%ebp) + 106087: 85 c0 test %eax,%eax + 106089: 75 c5 jne 106050 + } + return 0; + 10608b: b8 00 00 00 00 mov $0x0,%eax +} + 106090: 89 ec mov %ebp,%esp + 106092: 5d pop %ebp + 106093: c3 ret diff --git a/labcodes/lab2/obj/kernel_nopage.sym b/labcodes/lab2/obj/kernel_nopage.sym new file mode 100644 index 0000000000000000000000000000000000000000..54c2aa6e118d4f2ac41e8cf92673b18cc89861c0 --- /dev/null +++ b/labcodes/lab2/obj/kernel_nopage.sym @@ -0,0 +1,461 @@ +00000000 entry.o +0010001e next +00100034 spin +0011b000 __boot_pt1 +00000400 i +00000000 init.c +0010021b lab1_switch_test +00100144 lab1_print_cur_status +0011c000 round.0 +00100204 lab1_switch_to_user +00100211 lab1_switch_to_kernel +00000000 readline.c +0011c020 buf +00000000 stdio.c +0010030e cputch +00000000 kdebug.c +00100411 stab_binsearch +001009c2 read_eip +00000000 kmonitor.c +00119000 commands +001009db parse +00100a94 runcmd +00000000 panic.c +0011c420 is_panic +00000000 clock.c +00000000 console.c +00100d6d __intr_save +00100d99 __intr_restore +00100daf delay +0011c440 crt_buf +0011c444 crt_pos +0011c446 addr_6845 +00100dfa cga_init +0011c448 serial_exists +00100ee2 serial_init +00100fcf lpt_putc_sub +0010104d lpt_putc +0010108f cga_putc +00101285 serial_putc_sub +001012e1 serial_putc +0011c460 cons +00101323 cons_intr +00101372 serial_proc_data +00119040 shiftcode +00119140 togglecode +00119240 normalmap +00119340 shiftmap +00119440 ctlmap +00119540 charcode +001013eb kbd_proc_data +0011c668 shift.0 +00101572 kbd_intr +00101589 kbd_init +00000000 intr.c +00000000 picirq.c +00119550 irq_mask +0011c66c did_init +00101694 pic_setmask +00000000 trap.c +00101870 print_ticks +0011c6e0 idt +00119560 idt_pd +00101a04 trapname +00106740 excnames.0 +00119580 IA32flags +00101cb7 trap_dispatch +00000000 default_pmm.c +001029a9 page2ppn +001029c2 page2pa +001029da page_ref +001029e4 set_page_ref +001029f2 default_init +00102a23 default_init_memmap +00102b85 default_alloc_pages +00102d01 default_free_pages +00102fb9 default_nr_free_pages +00102fc3 basic_check +00103503 default_check +00000000 pmm.c +00103b93 page2ppn +00103bac page2pa +00103bc4 pa2page +00103c15 page2kva +00103c6b pte2page +00103cab pde2page +00103cc5 page_ref +00103ccf set_page_ref +00103cdd page_ref_inc +00103cf4 page_ref_dec +00103d0b __intr_save +00103d37 __intr_restore +0011cf20 ts +00119a00 gdt +00119a30 gdt_pd +00103d4d lgdt +00103d91 gdt_init +00103e7d init_pmm_manager +00103eb3 init_memmap +00103f71 page_init +00104333 boot_map_segment +00104439 boot_alloc_page +001048c2 check_alloc_page +001048e3 check_pgdir +00104f81 check_boot_pgdir +001046fd page_remove_pte +0010530d perm2str +0011cf88 str.0 +0010534f get_pgtable_items +00000000 printfmt.c +00107220 error_string +0010556a printnum +0010566c getuint +001056bb getint +00105b0c sprintputch +00000000 string.c +00102901 vector242 +00102358 vector119 +00100889 print_kerninfo +00102238 vector87 +0010222f vector86 +0010296d vector251 +00105c38 strcpy +0010225c vector91 +00102052 vector33 +00102541 vector162 +001027a5 vector213 +001022f5 vector108 +001020ac vector43 +00100000 kern_entry +00100c1f mon_backtrace +00102565 vector165 +00102655 vector185 +00102334 vector115 +00102373 vector122 +001047a8 page_insert +001024f9 vector156 +00102925 vector245 +00102685 vector189 +00101f76 vector7 +0010214e vector61 +00102001 vector24 +00102310 vector111 +00102709 vector200 +00102184 vector67 +00102421 vector138 +001021c3 vector74 +00105f4a memmove +0010212a vector57 +00105b42 snprintf +00101a4a print_trapframe +001027b1 vector214 +00105733 vprintfmt +001022a4 vector99 +001046a2 get_page +00101f15 __alltraps +00101613 cons_getc +00102445 vector141 +00100cfa is_kernel_panic +001025b9 vector172 +001009d5 print_stackframe +001028f5 vector241 +00102985 vector253 +00101f52 vector3 +00101f49 vector2 +0010284d vector227 +00102781 vector210 +00102829 vector224 +0010209a vector41 +00100366 cprintf +00101fe6 vector21 +001025f5 vector177 +0010234f vector118 +0010219f vector70 +00102196 vector69 +001028c5 vector237 +00102169 vector64 +0010201c vector27 +001023d9 vector132 +00102661 vector186 +001027d5 vector217 +00105fed memcpy +00101f40 vector1 +00102601 vector178 +0010207f vector38 +001028d1 vector238 +00100257 readline +001023e5 vector133 +001021ba vector73 +00102469 vector144 +00106bd0 vpd +00100036 kern_init +00102991 vector254 +001022b6 vector101 +0010278d vector211 +001025d1 vector174 +0010290d vector243 +001023a9 vector128 +00102202 vector81 +00103f0f free_pages +00101fa4 vector13 +00105b78 vsnprintf +001020f4 vector51 +00101fbb vector16 +00119a36 edata +001015a5 cons_init +0011cf0c pmm_manager +001028e9 vector240 +0010210f vector54 +00101fd4 vector19 +00112aac __STAB_END__ +00102265 vector92 +00102919 vector244 +00103d83 load_esp0 +00102439 vector140 +001020be vector45 +001021f0 vector79 +00102865 vector229 +00102511 vector158 +001016f1 pic_enable +00102088 vector39 +00102589 vector168 +00102064 vector35 +00102322 vector113 +00112aad __STABSTR_BEGIN__ +0010238e vector125 +00100c33 __panic +001027c9 vector216 +00102160 vector63 +00102013 vector26 +001013cb serial_intr +001026b5 vector193 +001026d9 vector196 +001000ff grade_backtrace0 +00102775 vector209 +00101f5b vector4 +001025a1 vector170 +00102409 vector136 +00101f8f vector10 +00102751 vector206 +0010299d vector255 +00102625 vector181 +0010213c vector59 +0010011c grade_backtrace +00102226 vector85 +0010221d vector84 +0010263d vector183 +0010251d vector159 +00102799 vector212 +001020d0 vector47 +00105db0 strtol +00102859 vector228 +001020a3 vector42 +0010232b vector114 +00105c07 strnlen +001025dd vector175 +0010245d vector143 +001023c1 vector130 +00106b38 default_pmm_manager +00102931 vector246 +00101f86 vector9 +00102451 vector142 +001022ad vector100 +00102715 vector201 +0010188f idt_init +0010091d print_debuginfo +00102145 vector60 +00101ff8 vector23 +001028b9 vector236 +0011cf04 npage +0010287d vector231 +0010217b vector66 +0010202e vector29 +00105403 print_pgdir +001023fd vector135 +00100b4c kmonitor +001021de vector77 +00102619 vector180 +00100d04 clock_init +00102769 vector208 +0010229b vector98 +00102292 vector97 +00103f44 nr_free_pages +001025e9 vector176 +001026c1 vector194 +00102049 vector32 +0011cf08 boot_cr3 +0011cf8c end +001026fd vector199 +001023cd vector131 +00102979 vector252 +00101f37 vector0 +00105d80 strfind +001015d4 cons_putc +00106094 etext +00102475 vector145 +001022ec vector107 +001199e0 boot_pgdir +00102091 vector40 +00101684 intr_enable +001022bf vector102 +00102121 vector56 +0010218d vector68 +00101f6d vector6 +001023b5 vector129 +001026e5 vector197 +001024c9 vector152 +001195e0 __vectors +00102871 vector230 +00105cf9 strncmp +00104567 get_pte +00102076 vector37 +00102745 vector205 +00102535 vector161 +00105c77 strncpy +001021a8 vector71 +00102529 vector160 +001027bd vector215 +00102505 vector157 +0010168c intr_disable +00101bfd print_regs +00102319 vector112 +001000a7 grade_backtrace2 +00102631 vector182 +00101f9d vector12 +0010603c memcmp +001022fe vector109 +00101fdd vector20 +00102106 vector53 +00101fcb vector18 +00102280 vector95 +00102841 vector226 +001020e2 vector49 +001020b5 vector44 +001021e7 vector78 +001025c5 vector173 +00102346 vector117 +00101a35 trap_in_kernel +0010220b vector82 +00102811 vector222 +00101f7f vector8 +001024a5 vector149 +0010038e cputchar +00105f08 memset +00102889 vector232 +001022e3 vector106 +001027f9 vector220 +00102253 vector90 +0010254d vector163 +001028a1 vector234 +00102157 vector62 +0010200a vector25 +001026f1 vector198 +00102361 vector120 +001003f5 getchar +00104761 page_remove +001020eb vector50 +00101fb2 vector15 +00105702 printfmt +001024bd vector151 +00102214 vector83 +0010224a vector89 +00102241 vector88 +00101eff trap +0010260d vector179 +0010205b vector34 +00116044 __STABSTR_END__ +001020c7 vector46 +00105cb0 strcmp +001023f1 vector134 +0010281d vector223 +001027e1 vector218 +00100561 debuginfo_eip +00101726 pic_init +00102835 vector225 +0010266d vector187 +0010447f pmm_init +00102037 vector30 +001023a0 vector127 +0011c424 ticks +001026a9 vector192 +00102571 vector166 +001021d5 vector76 +001021cc vector75 +001026cd vector195 +001024b1 vector150 +00102133 vector58 +00102949 vector248 +0010237c vector123 +00102289 vector96 +00102040 vector31 +0010272d vector203 +00103ed5 alloc_pages +0010242d vector139 +001024d5 vector153 +00102559 vector164 +0010236a vector121 +0011c680 switchk2u +00101f64 vector5 +0010257d vector167 +001024ed vector155 +00102955 vector249 +00106bcc vpt +00102961 vector250 +00102385 vector124 +00102307 vector110 +00102739 vector204 +00101f2c __trapret +00100331 vcprintf +00102415 vector137 +00100cb1 __warn +0010293d vector247 +00101fef vector22 +00102721 vector202 +001021b1 vector72 +00102118 vector55 +001003a4 cputs +00119000 bootstacktop +00102397 vector126 +00102172 vector65 +00102025 vector28 +00102595 vector169 +00102895 vector233 +0010248d vector147 +00117000 bootstack +0011a000 __boot_pgdir +001022d1 vector104 +0011cee0 free_area +0010233d vector116 +001073b8 __STAB_BEGIN__ +001020fd vector52 +00101fc4 vector17 +00102649 vector184 +00105bde strlen +0010275d vector207 +00102691 vector190 +001028dd vector239 +00102277 vector94 +0010226e vector93 +00102679 vector188 +00105d4c strchr +001020d9 vector48 +001000ce grade_backtrace1 +001027ed vector219 +00102499 vector148 +00102805 vector221 +001021f9 vector80 +001025ad vector171 +001024e1 vector154 +0010206d vector36 +0011c6cc switchu2k +001028ad vector235 +001022da vector105 +00100c0b mon_kerninfo +0011cf00 pages +00102481 vector146 +0010269d vector191 +001022c8 vector103 +00100bae mon_help +00101f96 vector11 +00104863 tlb_invalidate +00101fab vector14 diff --git a/labcodes/lab2/obj/libs/printfmt.d b/labcodes/lab2/obj/libs/printfmt.d new file mode 100644 index 0000000000000000000000000000000000000000..7f093e2c5c51f8fe66f4042d3156c2cdb20748d9 --- /dev/null +++ b/labcodes/lab2/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/lab2/obj/libs/printfmt.o b/labcodes/lab2/obj/libs/printfmt.o new file mode 100644 index 0000000000000000000000000000000000000000..41a9c32cc965f862c9cc3ae6f994003b4da58691 Binary files /dev/null and b/labcodes/lab2/obj/libs/printfmt.o differ diff --git a/labcodes/lab2/obj/libs/string.d b/labcodes/lab2/obj/libs/string.d new file mode 100644 index 0000000000000000000000000000000000000000..dd7b1bae04cf9987465c430bc7f27da31336fc79 --- /dev/null +++ b/labcodes/lab2/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/lab2/obj/libs/string.o b/labcodes/lab2/obj/libs/string.o new file mode 100644 index 0000000000000000000000000000000000000000..1e3bf53a07d3ded3268b428698b7a04ae324ab42 Binary files /dev/null and b/labcodes/lab2/obj/libs/string.o differ diff --git a/labcodes/lab2/obj/sign/tools/sign.d b/labcodes/lab2/obj/sign/tools/sign.d new file mode 100644 index 0000000000000000000000000000000000000000..c988243d10c66a835d03e66608f80a6996f2cde4 --- /dev/null +++ b/labcodes/lab2/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/lab2/obj/sign/tools/sign.o b/labcodes/lab2/obj/sign/tools/sign.o new file mode 100644 index 0000000000000000000000000000000000000000..d4583e5ee05bc80566637a2bd339454555428ddf Binary files /dev/null and b/labcodes/lab2/obj/sign/tools/sign.o differ diff --git a/labcodes/lab2/tools/gdbinit b/labcodes/lab2/tools/gdbinit index df5df85be4fc6cbcedb1c6f1547ab92a7fbc1cac..c4e9e61248240624275acbaf1982ce153454aedf 100644 --- a/labcodes/lab2/tools/gdbinit +++ b/labcodes/lab2/tools/gdbinit @@ -1,3 +1,4 @@ file bin/kernel target remote :1234 -break kern_init +break pmm_init +continue