19 lines
1.5 KiB
Plaintext
19 lines
1.5 KiB
Plaintext
在xv6中,当执行到地址 `0x3ffffff11c` 处的 `sret` 指令时,特权级和执行流程的变化如下:
|
||
|
||
1. **特权级变化**
|
||
- **执行前**:核心态(S模式,特权级 `1`)
|
||
- **执行后**:用户态(U模式,特权级 `0`)
|
||
`sret` 指令会从 `sstatus` 寄存器中恢复之前的特权级(由 `SPP` 位决定)。在进入陷阱处理时,处理器已自动将用户态的特权级(`0`)保存到 `sstatus.SPP`,因此 `sret` 会将特权级切换回用户态。
|
||
|
||
2. **恢复点地址**
|
||
恢复点地址由 `sepc` 寄存器指定。在进入陷阱处理时,`sepc` 被设置为触发 `ecall` 的下一条指令地址(即 `0x14`)。因此,`sret` 执行后,程序会跳转到 `0x14` 处继续执行用户代码。
|
||
|
||
3. **执行的函数**
|
||
`sret` 返回后,用户程序会从 `0x14` 处继续执行。根据 `initcode.S` 的代码,`0x14` 是 `ecall` 指令的下一条地址。若 `exec` 系统调用成功,用户地址空间会被替换为新程序(如 `init`),此时 `sret` 返回后直接进入新程序的入口点。若 `exec` 失败(理论上不会发生),则会继续执行 `initcode.S` 中 `ecall` 后的代码(但实际代码中 `ecall` 后无其他指令)。
|
||
|
||
**总结**
|
||
- **特权级**:核心态(`1`)→ 用户态(`0`)
|
||
- **恢复点地址**:`0x14`(用户代码中 `ecall` 的下一条指令)
|
||
- **执行函数**:若 `exec` 成功,执行新程序(如 `init`);否则继续 `initcode.S` 的后续代码(实际无后续指令)。
|
||
|