Intel 8086 有
20
条地址线,故其可以访问
1MB
的内存空间,即
2
的
20 次方=1048576=1MB,地址范围若按十六进制来表示,是
0x00000
到
0xFFFFF
。
地址 0
~
0x9FFFF
处是
DRAM
(
Dynamic Random Access Memory
),即动态随机访问
内存,我们所装的物理内存就是
DRAM
,如
DDR
、
DDR2 等。
顶部的 0xF0000
~
0xFFFFF
,这
64KB
的内存是 ROM
。这里面存的就是
BIOS
的代码。
BIOS
的主要工作是检测、初始化硬件,建立中断向量表等。
在开机的一瞬间,即接电的一瞬间,CPU
的
cs
:
ip
寄存器被强制初始化为
0xF000:0xFFF0,等效地址将是
0xFFFF0。此地址便是
BIOS 的入口地址。而地址
0xFFFF0
距
1MB
只有
16 个字节,说明 BIOS 真正的代码不在这,那此处的代码只能是个跳转指令(
jmp far f000
:
e05b)。
即跳向了
0xfe05b
处,这是
BIOS 代码真正开始的地方。
接下来 BIOS
便马不停蹄地检测内存、显卡等外设信息,当检测通过,并初始化好硬件后,开始在内 存中 0x000
~
0x3FF
处建立数据结构,中断向量表
IVT
并填写中断例程。
BIOS
最后一项工作校验启动盘中位于
0
盘
0
道
1 扇区的内容。如果此扇区末尾的两个字节分别是魔数 0x55 和 0xaa,BIOS 便认为此扇区中确实存在可执行的程序(即主引导记录MBR),便加载到物理地址 0x7c00,随后跳转到此地址,继续执行。
为什么选0x7c00?按 DOS 1.0 要求的最小内存 32KB 来说,MBR 希望给其他程序尽可能多的预留空间,这样也是为了保护自己,免得过早被覆盖。所以 MBR 只能放在 32KB 的末尾。MBR 本身只有 512 字节,但还要为其所用的栈分配点空间,所以其实际所用的内存空间要大于 512 字节,估计 1KB 内存够用了。综上,
选择
32KB
中的最后
1KB最为合适,32KB换算为十六进制为0x8000,减去 1KB(0x400)的话,等于 0x7c00。
可见,加载
MBR 的位置取决于操作系统本身所占内存大小和内存布局。
代码mbr.S如下:
SECTION MBR vstart=0x7c00
mov ax,cs
mov ds,ax
mov es,ax
mov ss,ax
mov fs,ax
mov sp,0x7c00
mov ax, 0x600
mov bx, 0x700
mov cx, 0
mov dx, 0x184f ;0x18=24,0x4f=79
int 0x10
mov ah, 3
mov bh, 0
int 0x10
mov ax, message
mov bp, ax
mov cx, 11
mov ax, 0x1301
mov bx, 0x2
int 0x10
jmp $ ;stay in here
message db "Hello Vinux"
times 510-($-$$) db 0
db 0x55,0xaa
运行结果:

参考自:《操作系统真象还原》