《一个操作系统的实现》(一):不到20行的操作系统代码的解释

最开始的一段操作系统代码:

	org 07c00h		;告诉编译器程序加载到7c00处
	mov ax, cs
	mov ds, ax
	mov es, ax
	call DispStr		;调用显示字符串例程
	jmp $			;无限循环
DispStr:
	mov ax, BootMessage
	mov bp, ax		;ES:BP = 串地址
	mov cx, 16		;CX = 串长度
	mov ax, 01301h		;AH = 13, AL = 01h
	mov bx, 000ch		;页号为0(BH=0)黑底红字(BL=0Ch,高亮)
	mov dl, 0
	int 10h			;10h号中断
	ret
BootMessage:			db "Hello, OS world!"
	times 510-($-$$)	db 0	;填充剩下的空间,使生成的二进制代码恰好为512字节
	dw 0xaa55		;结束标志


org规定程序的起始地址

cs:代码段寄存器,一般用于存放代码;ds:数据段寄存器,一般用于存放数据;es:扩展段寄存器,使用时可以看作ds的扩展寄存器;(ss:栈段寄存器,一般作为栈使用)。段寄存器是为了对内存进行分段管理。

ax:通用寄存器。通用寄存器有AX,BX,CX,DX,BP,SP,SI,DI,均可做普通数据寄存器使用。此外,AX为累加器,CX为计数器,BX,BP为基址寄存器,SI,DI为变址寄存器,BP还可以是基指针,SP为堆栈指针。

2-4行的作用就是令ds和es两个段寄存器指向与cs相同的段,以便在以后进行数据操作的时候能定位到正确位置。段寄存器都指向了相同的段,但并不代表内容重叠,只是概念上的重叠。虽然放到一个段中,但是相互可以区分开。比如某一段既有数据也有代码,则代码在执行到数据之前,需要用户在编程时加上一个跳转指令以跳过此段中的代码。段寄存器一共有四个,为什么只将ds、es、cs指向同一段,ss呢?栈段寄存器比较特殊,不仅用户会用,系统也会自动使用,而且用户也许在不知道系统使用的情况下使用ss,这样就会导致冲突。避免这种冲突的方法是采用逆向的栈段。

在网上查了一下,X86有实模式和保护模式两种模式(书上第三章讲保护模式,学习这章时我再写篇以这两种模式为内容的文章),现在“Hello, OS world!”是实模式。

第五行所call的就是显示字符串的代码了,8-15行都是。jmp $ 代表无限循环,其中$代表当前行被汇编之后的地址。

8-9行将BootMessage的首地址赋给bp(前面说过啦 是基址寄存器,还可以是基指针)。对于DispStr中为什么要给ax、bx、dl赋值,BL=0Ch代表黑底红字等问题,参见此材料此博文,这些在我看来应该算是int 10h的规定吧

下面说一下16-18行。db代表后面的数据以字节存放(dw代表以字存放,dd代表以双字存放)。 db即“分配一片连续的字节单元并初始化”。而times 510-($-$$)代表以0填充剩余空间。这里times可以理解为循环(PS:times、db、dw均属于伪指令——用于告诉汇编程序如何进行汇编的指令,它既不控制机器的操作也不被汇编成机器代码,只能为汇编程序所识别并指导汇编如何进行)。而$$表示一个节的开始处被汇编后的地址,这里程序只有1个节,所以$$实际上表示程序被编译后的开始地址。所以$-$$表示本行距离程序开始处的相对距离。times循环过后程序有510字节,为什么不是512字节呢?因为还要给结束标志0xaa55留两个字节。而dw基本含义与db相同,不同的是dw定义16位数据,高8位数据字节先存入低地址字节中,而低8位数据字节则再存入高地址字节中。


书上还说明了关于[]的使用问题,如下:

在NASM中,任何不被方括号[]括起来的标签或变量名都被认为是地址,访问标签中的内容必须使用[]。所以mov ax, BootMessage会把“Hello, OS world!”这个字符串的首地址传给寄存器ax。又比如,如果有foo dw 1,则mov ax, foo将把foo的地址传给ax,而mov bx, [foo]将把bx的值赋为1.实际上NASM中变量和标签一样,即foo dw 1等价于foo: dw 1,而且Offset这个关键字在NASM中也是不需要的,因为不加方括号时表示的就是Offset。总结为NASM的一大优点:要地址就不加方括号,也无需额外用什么Offset,想要访问地址中的内容就必须加上方括号,代码规则非常鲜明,一目了然。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
对x86架构的处理器,业界一向是褒贬不一。但是毫无疑问的是,x86架构的处理器是迄今为止在市场上最成功的处理器。它既催生了Intel、微软这样的业界巨头,也改变了普通人们的生活。到今天,虽然有arm的异军突起,但是大部分程序员所编写的程序依然在运在x86架构上。 虽然很多上层的程序员绕过了对CPU架构本身的理解,而直接使用高级语言进编程,但是对CPU本身的熟悉,其实依然是所有想被称为优秀的程序员所难以绕过的一道坎。对CPU的不熟悉,实际上限制了程序员的思维方式、对程序的理解和实际解决问题的能力。 对于普通的芯片,阅读几页的说明书就可以大致理解如何让它工作。CPU是比较复杂的一种,对于比较简单的CPU架构,阅读几十页的文档也能大致熟悉。然而 x86架构的CPU的说明可不是这么简单,其手册估计有一共有四、五千页之巨。不要说理解透彻,就是从头到尾翻一遍也不是一件简单的事情。并非Intel 有意将它做得复杂,这里有历史的原因。因为这个架构的应用实在太广了,全世界有无数的软件都在它的基础之上工作。为此它自身的升级也就变得举步维艰。每次升级都不得不要兼容之前的特性。这也就导致了新旧指令层层堆积,种种特性互相兼顾,最终变成如今的一团乱麻了。 对于入门级的选手,读完那些手册可不是一件容易的事情。但是于渊的这本《orange's:一个操作系统实现》却是一条难得的终南捷径。因为要理解如何让一个芯片正常工作,最简单的办法就是从头开始去写程序让它运起来,然后操作它做自己想做的事情。如果是平时的编程,这些下层的工作都已经有操作系统帮你做了,对理解x86架构的帮助就大为有限。如果去读那几千页的文档,不但读起来很痛苦,中间又没有多少可以实际操作的工作来帮助你温故而知新,这其中的枯燥乏味,绝对不是一般人可以忍受的了。而且更重要的手册中虽然包含了x86所有的特性,然而其中有些特性是现代操作系统根本就没有用到的。努力的去理解的话,又是吃力不讨好了。如果每个读者都可以随着这本书的介绍,去逐步的实现一个操作系统,不但这中间其乐无穷,而且实现到最后,对x86架构的理解也就不在话下。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值