抄写Linux源码(Day6:读闪客文章第一回 “最开始的两行代码”)

按照 Day1 完成了 Linux0.11 的运行之后,可以在 ~/oslab/linux-0.11 找到 linux0.11 的源码

根据闪客的文章第一回:https://mp.weixin.qq.com/s/LIsqRX51W7d_yw-HN-s2DA

Linux0.11 的启动代码程序入点在 ./boot/bootsect.s 里,总共 512 个字节,如下:

这个 bootsect.s 会被编译成二进制文件,存放在启动区的第一扇区。

skip掉前面那些宏,bootsect.s 最开始的两行汇编代码如下:

mov ax, 0x07c0
mov ds, ax

含义是把 0x07c0 这个值复制到 ax 寄存器里,再将 ax 寄存器里的值复制到 ds 寄存器里。

ds 是一个 16 位的段寄存器,具体表示数据段寄存器,在内存寻址时充当段基址的作用。啥意思呢?就是当我们之后用汇编语言写一个内存地址时,实际上仅仅是写了偏移地址,比如:

mov ax, [0x0001]

实际上相当于

mov ax, [ds:0x0001]

ds 是默认加上的,表示在 ds 这个段基址处,往后再偏移 0x0001 单位,将这个位置的内存数据,复制到 ax 寄存器中。

形象地比喻一下就是,你和朋友商量去哪玩比较好,你说天安门、南锣鼓巷、颐和园等等,实际上都是偏移地址,省略了北京市这个基址。

当然你完全可以说北京天安门、北京南锣鼓巷这样,每次都加上北京这个前缀。不过如果你事先和朋友说好,以下我说的地方都是北京市里的哈,之后你就不用每次都带着北京市这个词了,是不是很方便?

那 ds 这个数据段寄存器的作用就是如此,方便了描述一个内存地址时,可以省略一个基址,没什么神奇之处。

ds : 0x0001

北京市 : 南锣鼓巷

再看,这个 ds 被赋值为了 0x07c0,由于 x86 为了让自己在 16 位这个实模式下能访问到 20 位的地址线这个历史因素(不了解这个的就先别纠结为啥了),所以段基址要先左移四位。那 0x07c0 左移四位就是 0x7c00,那这就刚好和这段代码被 BIOS 加载到的内存地址 0x7c00 一样了。

把 ds 赋值为 0x07c0 最核心的原因是,我们在链接 这段代码的时候是使用 0x7c00 作为代码段起始地址的,所以为了汇编代码能够顺利执行,必须把 ds 赋值为 0x07c0。

也就是说,之后再写的代码,里面访问的数据的内存地址,都先默认加上 0x7c00,再去内存中寻址。

为啥统一加上 0x7c00 这个数呢?这很好解释,BIOS 规定死了把操作系统代码 (实际上是磁盘第一个扇区启动区的内容,MBR) 加载到内存 0x7c00,那么里面的各种数据自然就全都被偏移了这么多,所以把数据段寄存器 ds 设置为这个值,方便了以后通过这种基址的方式访问内存里的数据。

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值