MIT6.828 Exercise1.9 实验报告
Exercise 9. Determine where the kernel initializes its stack, and exactly where in memory its stack is located. How does the kernel reserve space for its stack? And at which "end" of this reserved area is the stack pointer initialized to point to?
1.内核是在哪初始化堆栈的;2.堆栈的实际地址在哪呢;3.内核是怎么为栈预留空间的;4.esp是怎么指向这批内存空间的“末尾”呢?
个人猜测,这里的end加引号,应该是因为堆栈是从高地址向下生长的
x86 堆栈指针(esp 寄存器)指向当前正在使用的堆栈的最低位置。 该位置以下的所有内容都是非堆栈区。 将一个值压入堆栈涉及减少堆栈指针,然后将值写入堆栈指针指向的位置。 从堆栈中弹出一个值涉及读取堆栈指针指向的值,然后增加堆栈指针。 在 32 位模式下,堆栈只能保存 32 位的值,而 esp 总是能被 4 整除。
相比之下,ebp(基指针)寄存器主要通过软件与堆栈相关联。在进入 C 函数时,通常通过将前一个函数的基指针压入堆栈来保存它,然后在函数执行期间将当前 esp 值复制到 ebp 中。
# Entry.S文件
# Clear the frame pointer register (EBP)
# so that once we get into debugging C code,
# stack backtraces will be terminated properly.
movl $0x0,%ebp # nuke frame pointer
# Set the stack pointer
movl $(bootstacktop),%esp
# now to C code
call i386_init
这两个指令分别设置了%ebp,%esp两个寄存器的值。其中%ebp被修改为0。%esp则被修改为bootstacktop的值。这个值为0xf0110000。另外在entry.S的末尾的代码段中还定义了一个值,bootstack。注意,在数据段中定义栈顶bootstacktop之前,首先分配了KSTKSIZE这么多的存储空间,专门用于堆栈,这个KSTKSIZE = 8 PGSIZE = 8 4096 = 32KB。所以用于堆栈的地址空间为 0xf0108000-0xf0110000,其中栈顶指针指向0xf0110000. 那么这个堆栈实际坐落在内存的 0x00108000-0x00110000物理地址空间中。
补充知识
1.控制寄存器CR0中的位0用PE标记,位31用PG标记,这两个位控制分段和分页管理机制的操作,所以把它们称为保护控制位。其中PE位是启用保护标识位,如果被置1代表将会运行在保护模式下,PG控制分页管理机制。PG=0,禁用分页管理机制,此时分段管理机制产生的线性地址直接作为物理地址使 用;PG=1,启用分页管理机制,此时线性地址经分页管理机制转换位物理地址。由此可知,如果要启用分页机制,那么PE和PG标志都要置位。
2.CR2用于发生页异常时报告出错信息。当发生页异常时,处理器把引起页异常的线性地址保存在CR2中。操作系统中的页异常处理程序可以检查CR2的内容,从而查出线性地址空间中的哪一页引起本次异常。
3.CR3 用于保存页目录表页面的物理地址,因此被称为PDBR。