- ...
- sread: .word 1+SETUPLEN ! sectors read of current track
- head: .word 0 ! current head
- track: .word 0 ! current track
- read_it:
- mov ax,es
- test ax,#0x0fff
- die: jne die ! es must be at 64kB boundary
- xor bx,bx ! bx is starting address within segment
- rp_read:
- mov ax,es
- cmp ax,#ENDSEG ! have we loaded all yet?
- jb ok1_read
- ret
- ok1_read:
- seg cs
- mov ax,sectors
- sub ax,sread
- mov cx,ax
- shl cx,#9
- add cx,bx
- jnc ok2_read
- je ok2_read
- xor ax,ax
- sub ax,bx
- shr ax,#9
- ok2_read:
- call read_track
- mov cx,ax
- add ax,sread
- seg cs
- cmp ax,sectors
- jne ok3_read
- mov ax,#1
- sub ax,head
- jne ok4_read
- inc track
- ok4_read:
- mov head,ax
- xor ax,ax
- ok3_read:
- mov sread,ax
- shl cx,#9
- add bx,cx
- jnc rp_read
- mov ax,es
- add ax,#0x1000
- mov es,ax
- xor bx,bx
- jmp rp_read
- read_track:
- push ax
- push bx
- push cx
- push dx
- mov dx,track
- mov cx,sread
- inc cx
- mov ch,dl
- mov dx,head
- mov dh,dl
- mov dl,#0
- and dx,#0x0100
- mov ah,#2
- int 0x13
- jc bad_rt
- pop dx
- pop cx
- pop bx
- pop ax
- ret
- ...
第2行:sread 表示在0磁道内已经读过的sector。我们知道之前已经从磁道0读取过两部分代码:
init segment和setup segment。其中init是512字节即1个sector长度,setup segment是4个sector长度。
所以内核数据要从磁道0的5个sector之后读起。
第8行:test ax, #0x0fff 这里会拿ax与#0x0fff做位与。所以如果是64KB为边界的话结果就是0.
第13行:读到ENDSEG = SYSSEG + SYSSIZE为止。而SYSSEG = 0x1000, SYSSIZE = 0x3000. 所以从0x1000:0x0000读到0x4000:0x0000为止,即192KB。
第19~22行,第58~67行:
int 0x13的用法 - ah: 0x02表示把磁盘扇区数据读到内存 al: 需要读的扇区数量
ch: 磁道号的低8位 cl: 开始扇区(0~5位), 磁道号高两位(6~7)
dh: 磁头号 dl: 驱动器号
es:bx -> 指向数据缓冲区. 读取出错的话CF置位
所以第一次读的时候al = ax - sread. 表示读取磁道0从init seg和setup seg后面开始的内核数据。
bx这时候=0.所以数据读到0x1000:0x0000.
阅读(662) | 评论(0) | 转发(0) |