|
| 1 | +# uCore 和 rCore的阅读笔记 |
| 2 | + |
| 3 | +## 应用程序与基本执行环境 |
| 4 | + |
| 5 | +系统的链接脚本(kernel.ld)决定了elf程序的内存地址的虚拟映射,__程序中的绝对地址在链接时确定__。我们需要把系统放置在物理地址0x80200000处,需要进行这步操作的原因是在这个运行时刚进入S态,并没有激活虚存机制。~~我还不知道为什么是这个地址~~。 |
| 6 | + |
| 7 | +啊啊啊啊啊啊啊啊啊啊啊啊汇编好难难难难难难难难难难啊啊啊啊啊啊啊啊啊啊啊 |
| 8 | + |
| 9 | +### entry.s |
| 10 | + |
| 11 | +``` assembly |
| 12 | + .section .text.entry #在下一个新的部分结束,即.section .bss.stack |
| 13 | + .globl _entry #声明全局符号_entry |
| 14 | +_entry: |
| 15 | + la sp, boot_stack_top # (sp) = (boot_stack_top) |
| 16 | + call main # 调用main函数,进入Cの世界 ^_^ |
| 17 | +
|
| 18 | + .section .bss.stack |
| 19 | + .globl boot_stack |
| 20 | +boot_stack: |
| 21 | + .space 4096 * 16 # 2^16B == 4KB * 16 == 64KB |
| 22 | + # 定义堆栈空间大小需要满足大小是4KB的整数倍。 |
| 23 | + .globl boot_stack_top |
| 24 | +boot_stack_top: |
| 25 | +
|
| 26 | +``` |
| 27 | + |
| 28 | +这是chatgpt的回答 |
| 29 | + |
| 30 | +> 这是一个汇编语言源文件,可以作为可执行程序的启动代码。下面是逐行解释: |
| 31 | +> |
| 32 | +> 1. `.section .text.entry`: 这行代码表示将下面的代码放置在名为 ".text.entry" 的代码段中。 |
| 33 | +> 2. `.globl _entry`: 这行代码定义了一个全局符号 "_entry",该符号是程序的入口点,在程序启动时执行。 |
| 34 | +> 3. `_entry:`: 这行代码是 _entry 符号的标签,代表程序的入口点。 |
| 35 | +> 4. `la sp, boot_stack_top`: 这行代码使用 la 命令生成代码,将 boot_stack_top 符号的地址加载到 sp 寄存器中,将栈指针设置为堆栈的顶部。 |
| 36 | +> 5. `call main`: 这行代码通过 call 指令调用名为 "main" 的函数。 |
| 37 | +> 6. `.section .bss.stack`: 这行代码将下面的代码放置在名为 ".bss.stack" 的未初始化数据段中。 |
| 38 | +> 7. `.globl boot_stack`: 这行代码定义了一个全局符号 "boot_stack",用于表示堆栈的起始位置。 |
| 39 | +> 8. `boot_stack:`: 这行代码是 boot_stack 符号的标签,表示变量存储在此处。 |
| 40 | +> 9. `.space 4096 * 16`: 这行代码使用 space 命令在内存中分配 4096 * 16 字节的空间。这是堆栈的空间大小。 |
| 41 | +> 10. `.globl boot_stack_top`: 这行代码定义了一个全局符号 "boot_stack_top",该符号用于表示堆栈的顶部位置,即栈指针初始值。 |
| 42 | +> 11. `boot_stack_top:`: 这行代码是 boot_stack_top 符号的标签,表示指针存储在此处。 |
| 43 | +
|
| 44 | +#### 小知识点 |
| 45 | + |
| 46 | +* `.globl`是什么? |
| 47 | + |
| 48 | +`.globl`指示符表示一个全局符号/标签;例:`.globl _entry`: 这行代码定义了一个全局符号 "_entry" |
| 49 | + |
| 50 | +* 以下代码中`la`是什么意思? |
| 51 | + |
| 52 | +``` assembly |
| 53 | +la sp, boot_stack_top # (sp) = (boot_stack_top) |
| 54 | +``` |
| 55 | + |
| 56 | +"la"是RISC-V指令集中的一个伪指令(pseudo-instruction),它的全称为“load address”,通常用于将地址加载到寄存器中。 |
| 57 | + |
| 58 | +下面是"la"伪指令的语法格式: |
| 59 | + |
| 60 | +```assembly |
| 61 | +la rd, symbol |
| 62 | +``` |
| 63 | + |
| 64 | +其中,"rd"表示目标寄存器,"symbol"表示要加载的地址符号。 |
| 65 | + |
| 66 | +例如,下面的代码将符号"array"的地址加载到寄存器x1中: |
| 67 | + |
| 68 | +```assembly |
| 69 | +la x1, array |
| 70 | +``` |
| 71 | + |
| 72 | +当汇编器处理这个伪指令时,它将使用类似于以下实际指令的指令序列来替代它: |
| 73 | + |
| 74 | +```assembly |
| 75 | +auipc x1, %pcrel_hi(array) |
| 76 | +addi x1, x1, %pcrel_lo(array) |
| 77 | +``` |
| 78 | + |
| 79 | +这个指令序列使用了两个新的伪指令:%pcrel_hi和%pcrel_lo。这两个伪指令用于计算符号的高位和低位偏移,在这个例子中,将符号"array"的地址作为立即数加载到寄存器x1中。 |
0 commit comments