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

来源:互联网 发布:ubuntu安装空闲不可用 编辑:程序博客网 时间:2024/05/17 22:34

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格式org07c00h;告诉编译器程序将被加载到7c00处section .textglobal _start_start:;汇编程序的入口点mov ax, cs;将代码段的段基址传给ax,cs段寄存器存放段基址mov ds, axmov es, axcall DispStrjmp $;无限循环DispStr:mov ax, BootMessagemov 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, 05hmov dl, 05h;DH, DL=字符输出坐标的行和列int 10h;选择10号中断retsection .dataBootMessage:db"Hello world!"times 510 - ($ - $$)db0dw0xaa55;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)经过一些小修改之后得到的运行界面

 

 

此次笔记记录完毕。

 

原创粉丝点击