[OS] 用汇编语言编写一个Boot Sector显示"Hello world!" [李园7舍_404]

1 Boot Sector

           当计算机电源被打开时,它会先进行加点自检(POST),然后寻找启动盘,如果是选择从软盘启动,计算机就会检查软盘的00磁道1扇区,如果发现它0xAA55结束,则BIOS认为它是一个引导扇区即Boot Sector。一个正确的Boot Sector除了包含0xAA55结束外,还有一段少于512B的执行码。

         一旦BIOS发现了Boot Sector,就会将这段512B的内容装载到内存的0000:7c00处,然后跳转到此处将控制权彻底交给这段引导代码(Boot Sector中那512B的执行码)。在这个时候,计算机不再由BIOS中固有的程序来控制,而变成由操作系统的一部分(这里指Boot Sector执行码)来控制。

       这是Boot Sector程序的特征。

 

2 用汇编程序输出“Hello World!”的中断知识 

        如果要用汇编语言在屏幕上显示一个字符串,则需要使用int 10H中断的13h功能号。在这个状态下:

       中断int 10H下:

       入口参数:AH=13H

       功能:在Teletype模式下显示字符串
       BH=页码
       BL=属性(若AL=00H或01H)
       CX=显示字符串长度
       (DH、DL)=坐标(行、列)
       ES:BP=显示字符串的地址 AL= 显示输出方式
       0—字符串中只含显示字符,其显示属性在BL中。显示后,光标位置不变
       1—字符串中只含显示字符,其显示属性在BL中。显示后,光标位置改变
       2—字符串中含显示字符和显示属性。显示后,光标位置不变
       3—字符串中含显示字符和显示属性。显示后,光标位置改变

在int  10H中断下,还有其它的功能号,详见http://www.programfan.com/blog/article.asp?id=16290

 

3 源程序

汇编程序格式:intel格式

汇编编译器:nasm

intel格式汇编代码:

;汇编程序之intel格式
org	07c00h			;告诉编译器程序将被加载到7c00处


section .text
global _start
_start:				;汇编程序的入口点
	mov ax, cs		;将代码段的段基址传给ax,cs段寄存器存放段基址
	mov ds, ax
	mov es, ax

	call DispStr
	jmp $			;无限循环


DispStr:
	mov ax, BootMessage
	mov bp, ax		;ES:BP显示字符串的地址,AL=显示输出方式
	mov cx, 12		;CX显示字符串长度
	mov ax, 01301h		;10h下中断,ah=13h功能为在Teletype模式下显示字符串
	mov bx, 000ah		;bh=页码,BL=属性(若al=00h或01h)
	
	mov dh, 05h
	mov dl, 05h		;DH, DL=字符输出坐标的行和列

	int 10h			;选择10号中断
	
	ret

section .data
	BootMessage:		db	"Hello world!"
	
times 510 - ($ - $$)	db	0

dw	0xaa55			;Boot Sector结束标志


         这段代码是于渊大哥10分钟完成一个操作系统里的源代码。在我了解了一点关于 int  10h  中断及intel汇编源程序结构的知识之后将程序稍微修改了一下。使输出的字符串风格发生了点变化,不过没有改变于渊大哥代码的实质。其实能改写这段代码也是花了不少时间的,加上回顾汇编基础知识,明白这是intel汇编格式还是花了一个星期左右,感觉自己弱爆了~_~。

 

4 源代码解释

         现在还没有打算、也没有相应的知识基础能力对源代码执行的原理进行解释。主要是对Boot Sector程序编写和"Hello World!"字符串显示做个简要的解释,这算是一个思路,供以后深究。

4.1Boot Sector

就像笔记最开头提到的那样,Boot Sector 具有一个重要特征是其内还有512B的执行码和一个0xAA55结束符。只要一段汇编代码具有这样的特征之后,如果计算机以软盘的方式启动,则这段汇编代码就能运行在裸机之上,就像操作系统一样!

 

4.2汇编程序

(1)汇编程序的入口点

汇编程序的入口点位于代码段,即程序中的"_start:"

(2)$和$$

在nasm编译器下:

$表示表示当前行被汇编后的地址。所以程序中的jmp $表示程序跳转到当前地址,所以这条指令就一直被执行,故而形成死循环。

$$表示一个节(section)的开始处被汇编的地址。就是表示程序被编译后的开始地址。所以程序中($ - $$)就表示当前地址到程序起始地址的地址大小,级本段程序所占内存大小。

 

(3)DispStr函数

根据在屏幕之上显示字符串要求,在中断int 10H下,ES:BP指定显示字符串的地址即用mov指令让bp指向显示的字符串。

寄存器cx存储显示字符串“hello world!”的长度。

mov ax, o1301h立即寻址让ah = 13h就决定了能在Teletype模式下输出字符串的功能。al = 01h表示字符串中只含显示字符,其显示属性在BL中。显示后,光标位置改变。

当然接下来的mov bx, 000ah    mov dh, 05h    mov dl, 05h语句就是相应的设置。

 

(4)section .text代码段

 

(5)经过一些小修改之后得到的运行界面

 

 

此次笔记记录完毕。

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值