Main's profile我的Domain,我做主PhotosBlogListsMore Tools Help

Blog


    February 19

    菜鸟学写操作系统(1)——Boot Sector

    我的Domain 我的Domain
    我的Domain
          一直都想自己写一个操作系统,可惜入门的书不多,大多是讲理论的,正好现在有本《自己动手写操作系统》,号称最好的入门书,因此想认真看看。鉴于以前看书都是“不求甚解”,很多东西只是“知其然而不知其所以然”,所以这次决定写一下读书笔记,但是书不是自己的,只好写在这里了。
          这本书的确是入门的好书,不过依然需要一些汇编和操作系统的基础。虽然汇编以前学过,但是用的太少,现在也忘得差不错了,需要重新看看。我这里的读书笔记主要是对里面的程序进行注释,每一行都不放过,做到完全理解才行。
          下面就对第一章最简单的引导扇区程序进行注释:

     
    ;%define _BOOT_DEBUG_ ; 做 Boot Sector 时一定将此行注释掉!

    %ifdef _BOOT_DEBUG_
       org  0100h   ; 调试状态, 做成 .COM 文件, 可调试
                    ; COM文件必须开始于0100H。EXE和COM的区别下面再讲(1)
    %else
       org  07c00h   ; Boot 状态,
                     ; Bios 将把 Boot Sector 加载到 0:7C00 处并开始执行
                     ; 引导扇区必须开始于07C00H
    %endif
       mov ax, cs    ; 代码段地址-->AX寄存器
       mov ds, ax    ; 把代码段地址复制到数据段和附加段中
       mov es, ax    ; 这是因为COM程序只有一个段,
                     ; 因此代码、数据和堆栈都是一样的地址(2)
       call DispStr   ; 调用显示字符串例程
       jmp $   ; 无限循环,$在NASM中表示当前行的内存地址
    DispStr:
       mov ax, BootMessage  ; 把要显示的字符串地址复制到AX中,
                            ; NASM中不需要OFFSET
       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   ; int 10h,调用BIOS的10H中断,
                 ; 前面的BP、CX、AX、BX、DL都是参数(3)
       ret
    BootMessage:  db "Hello, OS world!"
    times  510-($-$$) db 0 ; 填充剩下的空间,使生成的二进制代码恰好为512字节
                           ; times是NASM的专用指令,
                           ; 表示把后面定义的0填充当前位置510-($-$$)次
    dw  0xaa55    ; 结束标志,引导扇区必须以0XAA55结尾
     
          (1)COM程序的出现主要是因为当时的内存太小,为了高效利用内存,COM文件都不会超过64K大小。因为80x86中段的大小为64K,因此COM文件就只能拥有一个段,所以代码、数据和附加段都在同一个位置。EXE文件和COM文件的对比如下:
    EXE文件 COM文件
    不限大小 最大64K
    有堆栈段 没有堆栈段
    有数据段 数据段定义在代码段中
    代码段和数据段可以定义在任何偏移地址 代码段和数据段必须开始于0100H
    文件更大(占用更多内存) 文件更小(占用更少内存)
    有文件头(512字节) 没有文件头
          
          (2)前面说道COM文件只有一个段,所以这里CS、DS、SS都有相同的地址,至于为什么不是mov ds, cs之类呢?因为汇编中源操作数和目的操作数不能同时为段寄存器!
          (3)BIOS的10H中断的功能很多,主要是实现视频功能(Video Function)。根据AH的值不同,可以实现多种不同的功能。

    AH 功能
     00 设置视频模式 
    附加寄存器 结果寄存器
    AL=视频模式 没有

    详细视频模式请参考相关资料 

     01 设置光标类型
    附加寄存器 结果寄存器
    CH=光标开始行(0-4比特位) 没有
    CL=光标结束行(0-4比特位)

    其他位必须设置为0,光标的闪烁由硬件控制

    ……
    13 输出字符串 
    附加寄存器 结果寄存器
    AL=输出模式 没有
    ES:BP=字符串地址
    CX=字符数
    DH=开始行位置 
    DL=开始列位置
    BH=页面

    AL=00H,属性在BL中,光标不移动
    AL=01H,属性在BL中,光标移动
    AL=02H,属性在字符后面,光标不移动
    AL=03H,属性在字符后面,光标移动

    对于AL=00或者01,字符属性在BL中定义;
    对于AL=02或者03,字符属性紧跟在字符后面(字符,属性,字符,属性,……)

     

    更详细的中断请参考相关资料吧,太多了,写着累……

    (参考资料:The 80x86 IBM PC and Compatible Computers, Volumes I & II, Fourth Edition)

     
    我的Domain
    我的Domain 我的Domain