改写load_system

前面提到过我们装载system的时候有问题,当system还很小的时候可以应付,后面如果变大我们没办法把它全部读入内存,下面我们就来修改启动扇区中的load_system将全部的system读入内存。

 

load_system:
		movb $0x00,%dl
  	mov $0x0800,%ax  
  	int $0x13
  	movb $0x00,%ch 
  	
  	mov %cx,(sectors)
  	mov $SYSSEG,%ax
  	mov %ax,%es
  	call read_it
  	call kill_motor
ok_load_system:
		jmpl $SETUPSEG,$0 	
sread:.word 1+SETUPLEN
head: .word 0
track:.word 0
sectors:
	.word 0
read_it:
	mov %es,%ax
	test $0x0fff,%ax//es值必须位于64KB地址边界(ax&0xfff)
die:jne die
	xor %bx,%bx     //bx为段内偏移,清零
	
rp_read:
	mov %es,%ax
	cmp $ENDSEG,%ax //ax - ENDSEG //如果ax小于ENDSEG,则跳到ok1_read去执行
	jb ok1_read //JB是无符号数比较测试指令,条件是小于则转移,而CPU是通过测试CF是否等于1,如果等于1表示有借位,则说明前面这个数小于后面这个数
	ret
	
ok1_read:
	//seg %cs
	mov (sectors),%ax //将磁道扇区数sectors的值放到ax中
	sub (sread),%ax   //剩余扇区数 = 磁道扇区数(sectors) - 已读扇区数(sread)
	mov %ax,%cx       //剩余扇区数放到cx寄存器
	shl $9,%cx				//剩余扇区数*512字节+当前段内偏移值(bx)
	add %bx,%cx
	//可用于两个数的判断!jnc是进位位为0则转移!而两个数的比较就是想减,例如X-Y,X小于Y,X就要借位,这样进位位就为1,如果X大于Y,X就不需要借位,这样进位位为0
	jnc ok2_read//jnc是一条跳转指令,当进位标记C为0时跳转,为1时执行后面的指令,如果小于0x10000(64KB),跳转到ok2_read执行
	je ok2_read //刚好等于64KB时,0标志为1,跳转
	
	//计算最多能读取的扇区数
	xor %ax,%ax //ax清零
	sub %bx,%ax //ax - bx即0 - bx即取bx对64KB的补值,
	shr $9,%ax  //除以512得到扇区数,计算出需要读取的扇区数
	
ok2_read:
	call read_track
	mov %ax,%cx				//cx = 该次操作读取的扇区数
	add (sread),%ax   //加上当前磁道已读扇区数
	//seg %cs
	cmp (sectors),%ax	//如果当前磁道还有未读扇区,跳到ok3_read执行
	jne ok3_read
	
	mov $1,%ax
	sub (head),%ax		//判断当前磁头号,ax=ax-head
	jne ok4_read			//如果是0磁头,再去读1磁头上扇区的数据
	//inc (track)				//否则去读下一磁道
	add $1,(track)
	
ok4_read:
	mov %ax,(head)		//保存当前磁头号
	xor %ax,%ax				//清当前磁道已读扇区数

ok3_read:
//如果当前磁道上还有未读扇区,则先保存当前磁道已读扇区数,然后调整存放数据处的开始位置
//若小于64KB边界,则跳转到rp_read处,继续读数据。
	mov %ax,(sread)		//保存当前磁道已读扇区数
	shl $9,%cx				//已读扇区数*512字节
	add %cx,%bx				//调整当前段内数据开始位置
	jnc rp_read
	//否则说明已经读取64KB数据。调整当前段,为读下一段数据做准备。
	mov %es,%ax
	add $0x1000,%ax
	mov %ax,%es
	xor %bx,%bx
	jmp rp_read
//读取当前磁道上指定开始扇区	需要读的扇区数的数据到es:bx处
read_track:
	push %ax
	push %bx
	push %cx
	push %dx
	mov (track),%dx//取当前磁道号
	mov (sread),%cx//取此磁道上已读扇区数
	inc %cx        //cl = 开始读的扇区号
	mov %dl,%ch    //ch = 当前磁头号
	mov (head),%dx //取当前磁头号
	mov %dl,%dh    //dh = 磁头号
	mov $0,%dl		 //dl = 驱动器号(0表示A驱动器)
	and $0x0100,%dx//磁头号不大于1
	mov $2,%ah		 //ah = 2,读取磁盘扇区功能号
	int $0x13			 //0x13中断
	jc bad_rt			 //若出错,则跳转至bad_rt
	pop %dx
	pop %cx
	pop %bx
	pop %ax
	ret

//若出错,则复位驱动器,重新读取	
bad_rt:
	mov $0,%ax
	mov $0,%dx
	int $0x13
	pop %dx
	pop %cx
	pop %bx
	pop %ax
	jmp read_track
	
kill_motor:
	push %dx
	mov $0x3f2,%dx
	mov $0,%al
	outb %al,$0x3f2
	pop %dx
	ret


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值