今天先搞清楚电脑的启动过程:
1、电脑通电启动后,CPU 马上就从绝对内存地址 FFFF:0000H 处开始执行指令。放在这里的只是一条跳转指令,跳到固化在主板 ROM(Read Only Memory,只读存储器)中的系统 BIOS(Basic Input/Output System,基本输入输出系统)中的启动代码处。
2、系统 BIOS 的启动代码首先进行硬件检查,并加载相关硬件设备。
3、检查完成后,系统 BIOS 的启动代码按照 CMOS(Complementary Metal Oxide Semiconductor,互补金属氧化物半导体,就是保存计算机硬件配置和参数设定的可读写芯片) 中对启动设备的设置顺序,检测可用的启动设备。检测到可用的启动设备后,比较其第一个扇区的最后 2 位(结束标志位)是否等于 0xAA55,若等于 BIOS 就把该设备的第一个扇区读入绝对内存地址 0000:7C00H 处,然后将控制权交给该处。
4、操作系统就从内存 0x7C00 处开始接管电脑。
照猫画虎,对着书抄代码:
org 07C00h ; org 指令告诉编译器本程序将要被加载到内存的起始地址,编译器会把本程序
; 中所有用到的段内偏移地址自动加上 org 后跟随的数值。
; org 指令指示地址偏移调整是编译期概念,只影响内存寻址指令的编译,编译
; 产生的程序已经加上偏移量。
; 初始化寄存器
mov ax, cs
mov ds, ax
mov es, ax
; 显示一个字符串
mov ax, 1301h ; ah = 功能号(13h,在Teletype模式下显示字符串),
; al = 显示方式(01h,显示属性在BL中,光标跟随移动)
mov bx, 000Ch ; bh = 页号(0h), bl =(AL = 0、1时)显示属性(0Ch,黑底红字)
mov bp, BootMessage ; es:bp = 字符串地址,变量和标签无区别,无[]为地址,有[]为值
mov cx, 25 ; cx = 字符串长度
mov dx, 0 ; DH、DL = 屏幕行、列
int 10h
jmp $
BootMessage db 'Hello, First OS World!', 0
; 空白部分填 0
times 510 - ($ - $$) db 0 ; $ = 编译后本行的地址,$$ = 编译后本节的起始地址
; times = 重复
; Boot Sector 最后2个字节为 0xAA55,表示这是启动程序
dw 0xAA55
编译,用昨天写的小程序覆写,虚拟机加载启动。。。。。。成功!