转载:http://sleepycat.org/tech/os/nasm-boot-sector
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
org 0x7c00
mov ax, cs
mov es, ax
call DisplayString
cli
hlt
DisplayString:
mov ax, BootMessage
mov bp, ax ; es:bp = Offset of String(BootMessage)
mov cx, 16 ; cs = String Length(BootMessage)
mov ax, 1301h ; ah = 13h, al = 01h(Write mode)
mov bx, 000ch ; Page Number = 0(bh = 0), 黑底红字(bl = 0Ch,高亮)
mov dl, 0
int 10h
ret
BootMessage: db "Hello, OS World!"
times 510 - ($ -$$) db 0
dw 0xaa55
|
控制BIOS,将代码起始位置放置于: 0x7c00 处。(CS = 0x0,IP = 0x7c00, 结合起来,代码所在的内存地址为:0x0:0x7c00 = 0x7c00)
然而,有的BIOS对此的处理稍有不同,即:CS = 0x7c0,IP = 0x0, 结合起来,代码所在的内存地址为:0x7c0:0x0 = 0x7c00,内存位置结果不变。此种情况稍后讨论。)
The BIOS does not load the boot sector to a random spot in memory. The BIOS will always load the boot sector starting at the memory location 0x7C00. After loading the boot sector into memory the BIOS sets the IP register to 0x7C00 and sets the CS register to 0x0 (or just 0). Together this memory address looks like 0x0:0x7C00. We use a colon to denote that the left side is the segment and the right side is the offset. The IP register points to the next instruction to be executed so the first thing our boot sector must contain is an instruction that we want to be executed right away. However, not all BIOSs will load our boot sector using the address 0x0:0x7C00. Some BIOSs will load the boot sector to 0x7C0:0x0 which means the CS register is set to 0x7C0 and the offset is 0x0. Remembering that the first four bits of the segment are implicitly set to zeros, this memory address is the same address as 0x0:0x7C00 so no matter which way the BIOS loads your boot sector, it is in the same physical location in memory. Because not knowing the exact way the BIOS loaded our boot sector, we will force our boot sector to use the 0x0:0x7C00 address.
1
2
|
mov ax, cs
mov es, ax
|
es:bp 用于指向中断 int 10h 中用于显示的字符串的地址。参考 DisplayString 调用。
mov es, cs 非法。故通过 ax 中转。
调用 BIOS 中断 int 10h, 显示字符串到屏幕。详解:
http://en.wikipedia.org/wiki/INT_10H
填充510个字符,剩余的部分为0
Boot Sector 必须有一个扇区大,即512 bytes, 且最后两个字节必须为 0xAA55.
Remember that our boot sector must be one sector large, which is 512 bytes, and it must contain 0xAA55 in the last two bytes.
有的程序用 jmp $ 代替此处。但 jmp $ 会使 CPU 不停地进行忙碌死循环。
cli 指令,表示 Clear Interrupts,关闭所有的硬件中断。
hlt 指令,表示停止 CPU 运行。
The cli instruction stands for CLear Interrupts. It disables all hardware interrupts from occurring. The second instruction, hlt, causes the CPU to completely stop processing. The only way for the processor to begin processing after the hlt instruction is called is if a hardware interrupt occurs. By calling cli before hlt we are ensured that no hardware interrupts will be accepted and the CPU will be halted until reboot.
创建启动配置文件: bochsrc, 内容如下:
1
2
3
4
5
6
7
8
9
10
11
|
# how much memory the emulated machine will have
megs: 32
romimage: file=/usr/local/share/bochs/BIOS-bochs-latest
vgaromimage: file=/usr/share/vgabios/vgabios.bin
boot: floppy
floppya: 1_44="a.img", status=inserted
log: bochsout.txt
|
写入软盘命令: $ dd if=boot.bin of=a.img bs=512 count=1 conv=notrunc 注: bs=字节 强迫 ibs=<字节> 及 obs=<字节> cbs=字节 每次转换指定的<字节> conv=关键字 根据以逗号分隔的关键字表示的方式来转换文件 count=块数目 只复制指定量<块数目>的输入数据 ibs=字节 每次读取指定的<字节> if=文件 读取<文件>内容而非标准输入的数据 iflag=标记 以指定标记取代逗号作为读入符号列表的分隔符 obs=字节 每次写入指定的<字节> of=文件 将数据写入<文件>而不在标准输出显示 notrunc 不截断输出文件 http://blog.csdn.net/littlehedgehog/article/details/2647846 启动命令: $ bochs -f bochsrc ======================================================================== Bochs x86 Emulator 2.5.1 Built from SVN snapshot on January 6, 2012 Compiled on Jul 3 2012 at 22:20:20 ======================================================================== 00000000000i[ ] reading configuration from bochsrc ------------------------------ Bochs Configuration: Main Menu ------------------------------ This is the Bochs Configuration Interface, where you can describe the machine that you want to simulate. Bochs has already searched for a configuration file (typically called bochsrc.txt) and loaded it if it could be found. When you are satisfied with the configuration, go ahead and start the simulation. You can also start bochs with the -q option to skip these menus. 1. Restore factory default configuration 2. Read options from... 3. Edit options 4. Save options to... 5. Restore the Bochs state from... 6. Begin simulation 7. Quit now Please choose one: [6] 默认选择 6, 然后开始调试。 n => 单步执行。遇函数跳过。 s => 单步执行。遇函数进入。 c => 执行,直到断点。 b 0x30400 => 在 0x30400 处设断点。 info break => break info info cpu => cpu info
http://www.supernovah.com/Tutorials/BootSector2.php