书籍:《Linux内核设计的艺术》
第一章:从开机加电到执行main函数之前的过程
1.2.2 加载第二部分代码----setup
1.bootsect对内存你的规划
2.复制bootsect
各字段的值
SETUPLEN = 4
BOOTSEG = 0x07c0
INITSEG = 0x9000
SETUPSEG = 0x9020
SYSSEG = 0x1000
ENDSEG = SYSSEG + SYSSIZE
代码如下:
mov ax,#BOOTSEG
mov ds,ax
mov ax,#INITSEG ;将es段寄存器置为0x9000
mov es,ax
mov cx,#256 ;将cx的值置为256个字,每个字占用两个字节
sub si,si ;si为源变址寄存器可用来存放相对于DS段之源变址指针,源地址为ds:si = 0x07c0:0000
sub di,di ;di为目的变址寄存器可用来存放相对于 ES 段之目的变址指针,目的地址为es:di = 0x9000:0000
rep ;重复执行,直到cx = 0
;指令的基本功能:① (CX)=0时,串指令执行完毕,否则执行② ~ ④
② (CX)←(CX)-1③ 执行串指令(MOVS或STOS)④ 重复执行①
movw ;将ds:si的内容送至es:di,movw是字传送,每次传送一个字的大小
;movw同Intel语法的MOVSW,即 Move word DS:[(E)SI] to ES:[(E)DI]
;rep和movw也可以写在同一行
;至此已经将0x07c0位置的512字节的内容复制到0x9000
jmpi go,INITSEG ;jmpi是段间跳转指令,jmp是段内。执行这条指令之后,CS = INITSEG,IP = go,执行完此句
;跳转到INITSEG:go处执行,即为0x9000:go
go:mov ax,cs ;重置ax为0x9000
;到此已经调整了cs,现在对ds,es,ss,sp进行调整
mov ds,ax ;重置ds为0x9000
mov es,ax
mov ss,ax
mov sp,#0xff00 ;将栈顶指针sp指向偏移地址为0xff00处,物理地址为ss:sp = 0x9ff00
;至此bootsect的第一步操作:规划内容并把自身从0x07c00的位置复制到0x90000的位置的动作已经完成了