Linux0.11源码学习笔记_0

开始:

电脑开机后,cpu会指向主板上的BIOS程序,BIOS会将硬盘上0盘0道1扇区的那512字节的数据复制到内存中0x7c00这个位置。

硬盘的一个扇区的大小就为512字节。这512字节的数据是预先写在硬盘中的程序。

从0x7c00开始,共512字节,也就是说,要一直到0x7dff结束。0x100是256,0xff是255,再加上0x7c00这个地址,就是256,两个256加起来就是512。

硬盘上的这第一扇区的512字节的空间,是启动区。只要这512字节的最后两个字节分别是0x55和0xaa,BIOS就会认为这个区域是启动区,从而读取这个区域到内存中。

复制之后,会跳转到0x7c00这个地址开始执行程序。当然,是cpu跳转到的这个地址,并执行的程序。

Linux0.11最开始的代码,是用汇编写的bootsect.s,boot是引导,sect是sector的缩写,所以bootsect是引导扇区的意思。此文件编译后会被存在第一扇区,然后就是由BIOS搬运,cpu执行。

汇编指令mov:

mov是move的缩写,所以,mov指令的作用就是将数据从一个地址,移动到另一个地址;或者是一个寄存器移动到另一个寄存器中;或者从一个寄存器移动到一个内存地址中;或者从一个内存地址移动到一个寄存器中。反正意思都是从一个存储空间中移动到另一个存储空间中。寄存器是cpu中用于存储和处理数据的组件,主打一个快。

ax寄存器和ds寄存器:

accumulate:积累,accumulator:累加器。ax中的x似乎没有具体含义,只是命名是这样命名的。但默认还有一个register:寄存器。

所以,ax是累加器寄存器,用于存储算术和逻辑运算的结果。反正寄存器基本都是用来存储和处理数据的。

ds中的d是data的意思,s是segment的意思,所以它叫数据段寄存器。用来存储数据段的基址,也就是起始地址。数据段是程序存储数据的段,而访问一段数据,自然要从起始地址开始。

bootsect.s开始的几句:

一开始,定义了一些常量和段什么的。具体如下:

SYSSIZE = 0x3000
.globl begtext, begdata, begbss, endtext, enddata, endbss
.text
begtext:
.data
begdata:
.bss
begbss:
.text
SETUPLEN = 4
BOOTSEG  = 0x07c0
INITSEG  = 0x9000
SETUPSEG = 0x9020
SYSSEG   = 0x1000
ENDSEG   = SYSSEG + SYSSIZE

当然,还有一些注释,代码写于1991年,作者是Linux Torvalds。他说,SYS_SIZE是以clicks为单位的,这个滴答数或点击数具体想表达啥,不清楚,反正一个clicks是16bytes,也就是16字节。

那么16字节就是0x10字节,0x3000个clicks就是0x30000字节,0x30000转成二进制的话,是11后面还有16个0,也就是:2^{16},而:2^{10}个字节,叫做1kb,那么剩下的:3\times 2^{6},结果是192。最后,也就是说,0x3000个clicks有多大呢?欸!就是192kb。这个系统大小,是完全够用滴。

.globl指令可以标记符号为全局符号,这意味着符号可以被程序中的其他文件访问,也就是说,

begtext, begdata, begbss, endtext, enddata, endbss

这些符号是可以在其他文件里访问到的。

.text是指定代码段,.data是指定数据段,.bss是指定未初始化的数据段。使用这些指令的逻辑是这样的:

.text
begtext:
//一些代码

也就是说,先用.text指定下面的指令为代码段中的内容,而begtext:则是一个入口,代表了代码段的开始。也就是说,在接下来的代码中,可以写begtext:,然后在它的下面写的代码,就会被指定为代码段中的内容。

后面的.data和.bss也是这个逻辑。

那么现在所知的就是:SYSSIZE(system size)的值是0x3000,SETUPLEN(number of setup sectors 设置扇区数量)的值是4,BOOTSEG(boot segment)的值是0x07c0,INITSEG(initial segment)的值是0x9000,SETUPSEG(setup segmen)的值是0x9020,SYSSEG(system segment)的值是0x1000,ENDSEG(end segment)的值是SYSSEG+SYSSIZE,也就是0x1000+0x3000=0x4000。至于为什么都是十六进制的四位数,大概是因为系统是16位的吧。

程序的正式开始:

mov	ax,#BOOTSEG
mov	ds,ax

#代表后面的变量是个立即数。BOOTSEG的值是0x07c0,mov指令的作用是移动数据,手段就是复制地址,所以说第一句的意思就是把ax中的值变成0x07c0,第二句就是把ds中的值变成0x07c0。

ds寄存器用于指定许多数据传输指令的默认数据段地址。也就是说,之后要把某个地址传给某个寄存器,都要默认加上ds中的地址,这个寻址方式是汇编中特意规定的。比如:

mov ax, [0x0001]

0x0001只是偏移地址,还要加上ds中的值,才是真正复制到ax中的地址。注意,#BOOTSEG是个立即数,[0x0001]是个地址,二者是不一样的。

而在复制时,ds中的值会默认左移四位,也就是十六进制的一位,那么0x07c0就会变成0x7c00,也就是最开始的那512字节数据被移动到内存中的起始地址。那么,以这个地址为基本点,加上不同的值,就可以访问后面的不同的地址了,在后面的代码中就可以看到,不同的代码是放在不同的区域的。

总之就是方便了寻址。

  • 8
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值