========================================
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
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