bootsect.S

博客探讨了在磁盘读写过程中,bootsect.S汇编文件中的指令jae no_reg的理解,以及.S与.s文件在汇编语言编程中的不同。.s文件不进行预处理,通常用于.c文件汇编后的输出,而.S文件则允许预处理指令,常用于大型项目如Linux和u-boot中。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

读写磁盘时是上下两个磁头是固定在一起的,为了速度是读写完一个磁道后在接着读里一个磁头对应的磁道。

其中jae no_reg这条指令我没明白

 

还有就是bootsect.S为什么是大S呢

.s 汇编语言源程序; 操作: 汇编

.S 汇编语言源程序; 操作: 预处理 + 汇编

-------------------------------------------------------------------------------------------------------------------------------------------------

1.小写的 s文件,在后期阶段不会再进行预处理操作了,所以我们不能在其内写上预处理语句.

一般是 .c 文件进过汇编器处理后的输出. 如 GCC 编译器就可以指定 -S 选项进行输出. 且是经过预处理器处理后 的了.

<think>好的,我现在需要帮助用户查找关于bootsect.s文件的详细注释。用户对汇编引导扇区代码感兴趣,可能是在学习操作系统启动过程或进行底层开发。首先,我得回忆一下bootsect.s的作用,它是Linux早期启动过程中的一部分,负责加载操作系统的其他部分。 根据用户提到的引用[2],用户正在分析boot目录中的汇编源码,想了解如何加载内核。这说明用户需要具体的代码注释解释。我需要确保提供的注释准确,并且符合用户的需求。 首先,我需要确认bootsect.s的基本功能:它是引导扇区代码,由BIOS加载到内存0x7C00处,然后将自己移动到0x90000,设置堆栈,加载setup模块系统模块。接下来,我需要分段解释代码,包括各个寄存器的使用、中断调用以及关键指令的作用。 用户提供的引用中提到了int 0x13的AH=0x02功能用于读取磁盘扇区,这在bootsect.s中会有应用。同时,用户可能对movw指令有疑问,引用[3]提到了相关的博文,但用户现在需要的是bootsect.s的注释,因此需要详细解释代码中的每个步骤。 接下来,我需要检查是否有常见的代码结构,比如移动自身代码、加载setup模块、打印信息等。对于每个关键指令,如mov、jmp、int等,都需要解释其参数作用。此外,需要指出如何通过BIOS中断读取磁盘,以及如何跳转到setup模块执行。 还要注意代码中的一些细节,比如ORG指令的作用、如何计算扇区数、如何设置段寄存器等。可能用户对这些底层细节不太熟悉,所以需要用简单的中文解释清楚。 最后,生成相关问题时要围绕bootsect.s的功能、汇编指令、启动流程调试方法,确保问题能够帮助用户进一步深入理解。</think>### `bootsect.s` 文件详细注释与解释 `bootsect.s` 是 Linux 0.11 内核引导阶段的核心汇编代码,负责从磁盘加载操作系统内核到内存,并移交控制权。以下是对其关键代码段的逐行注释: ```assembly ! bootsect.s 引导扇区代码,由 BIOS 自动加载到 0x7C00 处 .globl begtext, begdata, begbss, endtext, enddata, endbss .text begtext: .data begdata: .bss begbss: .text SETUPLEN = 4 ! setup 模块占用的扇区数 BOOTSEG = 0x07C0 ! BIOS 加载引导扇区的原始段地址 INITSEG = 0x9000 ! 将引导扇区移动到此段地址 SETUPSEG = 0x9020 ! setup 模块加载地址 SYSSEG = 0x1000 ! 系统模块加载地址 SYSSIZE = 0x3000 ! 系统模块最大长度(单位:16字节) entry start start: mov ax,#BOOTSEG ! 将原始段地址 0x07C0 存入 AX mov ds,ax ! 设置数据段寄存器 DS mov ax,#INITSEG ! 目标段地址 0x9000 mov es,ax ! 设置附加段寄存器 ES mov cx,#256 ! 移动 256 字(512 字节) sub si,si ! SI = 0 sub di,di ! DI = 0 rep movsw ! 重复执行 movsw,将代码从 0x7C00 移动到 0x90000 jmpi go,INITSEG ! 段间跳转到新地址 0x9000:go [^1] ``` **代码作用**:将自身从 `0x7C00` 移动到 `0x90000`,避免被后续加载的 setup 模块覆盖。 --- ```assembly go: mov ax,cs ! 设置各个段寄存器为新的位置 mov ds,ax ! DS = CS = 0x9000 mov es,ax ! ES = 0x9000 mov ss,ax ! SS = 0x9000 mov sp,#0xFF00 ! 设置堆栈指针 SP(约 64KB 空间) ! 加载 setup 模块到内存 0x90200 处 load_setup: mov dx,#0x0000 ! DH=0(磁头号),DL=0(驱动器号) mov cx,#0x0002 ! CH=0(磁道号低8位),CL=2(起始扇区号) mov bx,#0x0200 ! ES:BX=0x9000:0x0200(目标地址 0x90200) mov ax,#0x0200+SETUPLEN! AH=0x02(读磁盘功能),AL=4(读取4个扇区) int 0x13 ! 调用 BIOS 磁盘中断 [^1] jnc ok_load_setup ! 若未出错(CF=0)则跳转 mov dx,#0x0000 ! 出错则复位磁盘 int 0x13 jmp load_setup ! 重试 ``` **关键点**: 1. 使用 `int 0x13` 的 `AH=0x02` 功能读取磁盘扇区 2. 参数说明:`CL` 寄存器低6位表示扇区号(1-based),`CH` `CL` 高2位组成10位磁道号 3. 错误处理通过检查进位标志 `CF` 实现 --- ```assembly ! 打印加载信息 ok_load_setup: mov ah,#0x03 ! 获取光标位置 xor bh,bh ! 页号=0 int 0x10 mov cx,#24 ! 消息长度 mov bx,#0x0007 ! 显示属性(黑底白字) mov bp,#msg1 ! 消息地址 mov ax,#0x1301 ! AH=0x13(显示字符串),AL=1(更新光标) int 0x10 ! 调用 BIOS 视频中断 ! 加载系统模块到 0x10000 处 load_system: mov dx,#0x0000 ! 驱动器号=0,磁头号=0 mov cx,#0x0006 ! 起始扇区=6,磁道=0 mov bx,#0x0000 ! ES:BX=0x1000:0x0000 mov ax,#0x1000 mov es,ax mov ax,#0x0230+SYSSIZE ! 读取 0x3000*16=192KB int 0x13 jnc ok_load_system ... ! 错误处理(省略) ! 跳转到 setup 模块 ok_load_system: jmpi 0,SETUPSEG ! 跳转到 0x9020:0x0000 执行 setup.s ``` **系统加载逻辑**: 1. 系统模块从磁盘第6个扇区开始加载 2. 目标地址为 `0x10000`(实模式下 64KB 边界) 3. 最终通过 `jmpi` 跳转到 setup 模块继续执行 --- ### 相关技术细节 1. **磁盘寻址**:使用 CHS(柱面-磁头-扇区)模式,最大支持 8GB 磁盘 2. **内存布局**: - `0x7C00-0x7DFF`:BIOS 加载引导扇区原始位置 - `0x90000-0x901FF`:移动后的引导程序 - `0x90200`:setup 模块加载位置 3. **段寄存器计算**:实模式下物理地址 = `段寄存器 << 4 + 偏移量`
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

fulinux

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值