功能:读写磁盘的中断调用,将指定扇区的代码加载到内存的指定位置
- AH=0x02----要读磁盘内容到内存
-
- AL=0x04----要读4个扇区
-
- CL=0x02----要读的磁盘扇区从2号扇区开始.
-
- CH=0x00----要读的磁盘扇区所在的柱面号为0
-
- DH=0x00----要读的磁盘扇区所在的磁头号为0
-
- DL=0x00----要读扇区所在的驱动号为0
-
- AH=0x08----可以获得每个磁道的扇区个数
-
- CL低6位----存放每个磁道的扇区个数
如何把第二个扇区及后续扇区的内容加载入内存并执行?不能是只在第一扇区进行操作了。
采用如下代码加载第二扇区的代码pmtest2.S。
- 1 [BITS 16]
- 2 org 0x7C00
- 3 start:
- 4 ; This section of code is added based on Michael Petch's bootloader tips
- 5 xor ax,ax ; 为 DS 置 0 准备
- 6 mov ds,ax
- 7 mov bx,0x8000 ; 栈段可以是可用内存的任意一段
- 8 mov ss,bx ; 栈顶位于 0x80000.
- 9 mov sp,ax ; 设置 SP=0 ,使栈底位于 0x90000 下
- 10 cld ; 设置 DF 位为正向
- 11 mov ah, 0x02
- 12 mov al, 1
- 13 mov ch, 0
- 14 mov cl, 2
- 15 mov dh, 0
- 16 mov bx, new
- 17 mov es, bx
- 18 xor bx, bx
- 19 int 0x13
- 20 jmp new:0
- 21 data:
- 22 new equ 0x0500
- 23 times 510-($-$$) db 0
- 24 dw 0xaa55
- 25 sect2:
- 26 mov ax, cs
- 27 mov ds, ax ; 设置 CS=DS. CS=0x0500, 因此 DS=0x500
- 28 ; 如果变量已经在代码中设置,则要求
- 29 ; 正确地引用其内存地址
- 30 mov ax, 0xB800
- 31 mov es, ax
- 32 mov byte [es:420], 'H'
- 33 mov byte [es:421], 0x48
- 34 mov byte [es:422], 'E'
- 35 mov byte [es:423], 0x68
- 36 mov byte [es:424], 'L'
- 37 mov byte [es:425], 0x28
- 38 mov byte [es:426], 'L'
- 39 mov byte [es:427], 0x38
- 40 mov byte [es:428], 'O'
- 41 mov byte [es:429], 0x18
- 42 mov byte [es:430], '!'
- 43 mov byte [es:431], 0x58
- 44 hlt
在sect2中,也就是第二扇区中编写了部分演示代码。前两个扇区的二进制文件如下所示。
shell脚本如下所示runboot.sh,生成两个扇区的虚拟硬盘镜像
- 1 #!/bin/bash
- 2 rm os.raw
- 3 nasm -o boot pmtest2.S
- 4 bximage -mode=create -hd=60 -q os.raw
- 5 dd if=boot of=os.raw bs=1024 count=1
- 6 qemu-system-i386 os.raw
最终运行结果如下所示,显示了第二扇区的彩色的HELLO!