最简单的BootSector

本文档提供了一个使用 NASM 编写的引导扇区最简单教程。介绍了 BIOS 加载引导扇区的基本规则,并通过实例展示了如何创建能显示字符或加载程序的引导扇区。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

          ========================================
              Daniels NASM bootstraps tutorial
               用nasm编写引导扇区的最简单教程
          ========================================

author: Daniel Marjamaki (daniel.marjamaki@home.se)

(这篇文档是一篇非常简单的引导区编写程序,采用比较常见的
  nasm编写。但是,对于一个操作系统新手来说,了解引导区
  是非常好的入门方式,真的)
Preface
-------
This tutorial is a guide for those who want to create
their own bootstraps.


The basics
----------
These are the rules that you must follow:
  - The BIOS will load your bootstrap to address 07C00h.
    Sadly, the segment and offset varies.
  - Bootstraps must be compiled as plain binary files.
  - The filesize for the plain binary file must be 512
    bytes.
  - The file must end with AA55h.

这里有一些你必须遵守的规则(这些都是编写操作系统时的约定)
  -BIOS将把你的引导区程序装再到0:07c00h的位置
  -引导区程序要被编译成为二进制(用 nasm -f bin xxx.asm
  可以将程序编译为二进制)
  -引导区程序必须是512byte的(512byte是一个扇区)
  -引导区程序要用AA55h作为最后2个byte.

(计算机引导的过程是这样的)
At the completion of your system's Power On Self Test (POST), INT
19 is called.  Usually INT 19 tries to read a boot sector from
the first floppy drive.  If a boot sector is found on the floppy
disk, the that boot sector is read into memory at location
0000:7C00 and INT 19 jumps to memory location 0000:7C00.

在计算机的自检阶段(这个时候,就是一开机的时候,什么都不干,由硬件
来自检),int 19被call. 一般的int 19 要首先看看软盘呀,光盘呀,硬盘呀
(顺序在BIOS中已经被设定过了)里面有没有引导区。(如果0面0道1扇区的结尾为
0xAA55h,BIOS认为这个扇区是引导扇区而不管这个扇区里面写的是什么东西)。如果
在软盘(floppy)上发现了引导扇区,而bios将这个boot sector(引导 扇区)读到内存
0:7c00的地方。


A minimal bootstrap
最简单的一个bootsector,它可以当启动扇区,但是只是效果是引导完了后就死机
;=========================================代码开始=========================
This bootstrap just hangs:

    ; HANG.ASM
    ; A minimal bootstrap

    hang:                   ; Hang! 死循环
            jmp hang

    times 510-($-$$) db 0   ; Fill the file with 0's  填充到510个 byte
    dw 0AA55h               ; End the file with AA55  最后用aa55结束

;==========================================代码结束==============================

The line starting with "times" is a command that only
NASM understands. The line will insert 0's until the
filesize is 510 bytes. The whole file will therefore be
512 bytes.
The last instruction puts AA55 at the end of the file.

times是nasm的关键字,times  x db  0 ,就是填充x个0,这里x=510-($-$$) 就是
                                                    x=510-(目前地址-本段开始地址)的意思
To compile the bootstrap, use this command:
 以二进制编码,输出文件名为hang.bin
 (nasm xxxx.asm -o 编译后的文件名)
    nasm hang.asm -o hang.bin

If you want to test the bootstrap, you must first put it
on the first sector on a floppy disk. You can for example
use 'dd' or 'rawrite'.
When the bootstrap is on the floppy, test it by
restarting your computer with the floppy inserted. The
computer should hang then.
他这里告诉我们可以用 dd或者  rawrite 这两个软件将我们编好的二进制文件写到
一个软盘(floppy disk)中,然后用这个软盘来启动机器就可以了。
现在我们一般都用虚拟机了。


The memory problem
------------------
There is a memory problem.
As I've written bootstraps are always loaded to address
07C00. We don't know what segment and offset the BIOS has
put us in. The segment can be anything between 0000 and
07C0. This is a problem when we want to use variables.
The solution is simple. Begin your bootstrap by jumping
to your bootstrap, but jump to a known segment.

我们现在写的是引导区程序,我们知道bios将我们的引导区区loade
到07c00h,但是我们不知道这个07c00是怎么组成的(比如可能是
07c0:0000=07c0*10h+0=07c00h;也可能是0:07c00,还有其它许多可能)
所以作者这里强制定义了一下。我认为意义不到,也可能是我看的太少了
还体会不到。
;========================================代码开始====================================
    ;Here is an example:

    ; JUMP.ASM
    ; Make a jump and then hang

    ; Tell the compiler that this is offset 0.
    ; It isn't offset 0, but it will be after the jump.
    [ORG 0]

            jmp 07C0h:start         ; Goto segment 07C0

    start:
            ; Update the segment registers
            mov ax, cs
            mov ds, ax
            mov es, ax

    hang:                           ; Hang!
            jmp hang

    times 510-($-$$) db 0
    dw 0AA55h
;========================================代码结束====================================
If you compile and test this bootstrap, there will be no
visible difference to the minimal bootstrap presented
earlier. The computer will just hang.
这段代码和上面的那段代码的结果是没有区别的

Some exercises
--------------
1. Create a bootstrap that outputs "====" on the screen,
   and then hangs. Tip: modify the jump.asm program.
   这里需要用到的是BIOS--API int10
2. Create a bootstrap that outputs "Hello Cyberspace!"
   and hangs.
   一样的东西。
3. Create a bootstrap that loads a program off the floppy
   disk and jumps to it.
   调用BIOS--API int10,这需要拷一些代码过来。


Solutions to the exercises
--------------------------
代码不错的。
1.

    ; 1.ASM
    ; Print "====" on the screen and hang

    ; Tell the compiler that this is offset 0.
    ; It isn't offset 0, but it will be after the jump.
    [ORG 0]

            jmp 07C0h:start     ; Goto segment 07C0

    start:
            ; Update the segment registers
            mov ax, cs
            mov ds, ax
            mov es, ax

            mov ah, 9           ; Print "===="
            mov al, '='         ;
            mov bx, 7           ;
            mov cx, 4           ;
            int 10h             ;

    hang:                       ; Hang!
            jmp hang

    times 510-($-$$) db 0
    dw 0AA55h


2.

    ; 2.ASM
    ; Print "Hello Cyberspace!" on the screen and hang

    ; Tell the compiler that this is offset 0.
    ; It isn't offset 0, but it will be after the jump.
    [ORG 0]

            jmp 07C0h:start     ; Goto segment 07C0

    ; Declare the string that will be printed
    msg     db  'Hello Cyberspace!'


    start:
            ; Update the segment registers
            mov ax, cs
            mov ds, ax
            mov es, ax


            mov si, msg     ; Print msg
    print:
            lodsb           ; AL=memory contents at DS:SI

            cmp al, 0       ; If AL=0 then hang
            je hang

            mov ah, 0Eh     ; Print AL
            mov bx, 7
            int 10h

            jmp print       ; Print next character


    hang:                   ; Hang!
            jmp hang


    times 510-($-$$) db 0
    dw 0AA55h


3.

    ; 3.ASM
    ; Load a program off the disk and jump to it

    ; Tell the compiler that this is offset 0.
    ; It isn't offset 0, but it will be after the jump.
    [ORG 0]

            jmp 07C0h:start     ; Goto segment 07C0

    start:
            ; Update the segment registers
            mov ax, cs
            mov ds, ax
            mov es, ax


    reset:                      ; Reset the floppy drive
            mov ax, 0           ;
            mov dl, 0           ; Drive=0 (=A)
            int 13h             ;
            jc reset            ; ERROR => reset again


    read:
            mov ax, 1000h       ; ES:BX = 1000:0000
            mov es, ax          ;
            mov bx, 0           ;

            mov ah, 2           ; Load disk data to ES:BX
            mov al, 5           ; Load 5 sectors
            mov ch, 0           ; Cylinder=0
            mov cl, 2           ; Sector=2
            mov dh, 0           ; Head=0
            mov dl, 0           ; Drive=0
            int 13h             ; Read!

            jc read             ; ERROR => Try again


            jmp 1000h:0000      ; Jump to the program


    times 510-($-$$) db 0
    dw 0AA55h



This is a small loadable program.

    ; PROG.ASM

            mov ah, 9
            mov al, '='
            mov bx, 7
            mov cx, 10
            int 10h

    hang:
            jmp hang


This program creates a disk image file that contains both
the bootstrap and the small loadable program.

    ; IMAGE.ASM
    ; Disk image

    %include '3.asm'
    %include 'prog.asm'




Finally
-------
Thanks for reading.
Email me any suggestions, comments, questions, ...
If you don't use NASM and are having problems with the
code, you should contact me. Together we can solve it.
这篇的确是最简单教程。告诉我们在引导区我们的确可以完成一些 “显示” “读,写文件”的操作,不是
吗?只是要用汇编和BIOS--API而已,也许BIOS API开始来说比较麻烦,但只是调用而已,熟悉就好了。
关于nasm汇编和BIOS--API,可以看看我的blog上面其它的文章。
禾路(HeLU)  http://blog.csdn.net/jsxyhelu                       2008/2/23
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值