操作系统实践-2 从硬盘中读取代码并跳转执行
1.从硬盘中读取数据的中断介绍
使用0x13号中断时,寄存器作用见下表
寄存器 | 数字 | 作用 |
---|---|---|
AH | 0x02 | 方向:磁盘 > 内存 |
AL | Num | 读入Num个扇区 |
CH | Num | 第Num个柱面 |
CL | Num | 第Num号扇区 |
DH | Num | 磁头号 |
DL | Num | 驱动器号 |
ES | 段 | |
BX | 偏移 | |
标志寄存器 | 成功则jnc |
2.从硬盘中读取next.s并跳转至其执行,显示"Now we are in next."
2.1改写bootsect.s
!从bootsect.s跳转至next.s
NEXT_LEN = 2!目标程序占几个扇区,这里其实是1个,手滑写成了2,不过无所谓
NEXT_SEG = 0x07e0!目标程序被读入后在内存的地址
entry _start
_start:
mov ah,#0x03
xor bh,bh
int 0x10
mov cx,#27
mov bx,#0x0007
mov bp,#msg1
mov ax,#0x07c0
mov es,ax
mov ax,#0x1301
int 0x10
load_next:
mov dx,#0x0000
!DH:磁头 DL:驱动器号
mov cx,#0x0002
mov bx,#0x0200
!读取磁盘所得放在es:bx后面
mov ax,#0x0200 + NEXT_LEN
!AH=02参数,表示方向是从磁盘读取至内存
int 0x13
jnc ok_load_next!如果读取成功
mov dx,#0x0000
mov ax,#0x0000
int 0x13
jmp load_next
ok_load_next:
jmpi 0,NEXT_SEG
msg1:
.byte 13,10
.ascii "My os is Loading--LMC"
.byte 13,10,13,10
.org 510
boot_flag:
.word 0xAA55!硬盘标志位,表示可以用
2.2创建next.s
entry _start
_start:
mov ah,#0x03
xor bh,bh
int 0x10
mov cx,#25
mov bx,#0x0007
mov bp,#msg2
mov ax,cs
mov es,ax
mov ax,#0x1301
int 0x10
inf_loop:
jmp inf_loop
msg2:
.byte 13,10
.ascii "Now We are in Next."
.byte 13,10,13,10
.org 510
boot_flag:
.word 0xAA55!硬盘标志位,表示可以用
2.3编写Makefile文件
由于有两个文件需要编译,链接,写个Makefile方便一些,这里用Python写了个build.py用来生成镜像
all:Image
Image : bootsect next
python build.py
bootsect : bootsect.o
ld86 -0 -s -o bootsect bootsect.o
next : next.o
ld86 -0 -s -o next next.o
bootsect.o : bootsect.s
as86 -0 -o bootsect.o bootsect.s
next.o : next.s
as86 -0 -o next.o next.s
2.4用Python编写build.py
bootsect = open("bootsect","rb")
bin_sect = bootsect.read(32)
bin_sect = bootsect.read(512)#binsect为512字节的引导扇区
bootsect.close()
next_s = open("next","rb")#不用next,因为next是python关键字
bin_next = next_s.read(32)#去除头
bin_next = next_s.read()
next_.close()
f = open("Image","wb+")
f.write(bin_sect + bin_next)#合成
f.close()
2.5执行make命令
2.6加载到Bochs中执行
3.总结
从内存中的A.s跳到硬盘中的B.s执行要经历以下步骤:
- 在A.s中把B.s读到内存中一个精确的位置,记为C
- 在A.s中用jmp命令把PC指向C即可