《一个操作系统的实现》书中的一处思考_P129页84行_and_di_0fff0h
本文个人原创,2011年于电子科技大学
这学期在上嵌入式课程,老师在讲boot loader的时候让看于渊的那本《一个操作系统的实现》(第一版叫自己动手写操作系统),买了一本,翻看了下果然是宝贝,一口气读了2章,在看第4,5章的时候关于laoder问题的时候,也就是在第四章就出现的那个寻找文件,然后拷贝文件的时候,代码如下:
and di, 0FFF0h ; di -> 当前条目的开始
push eax
mov eax, [es : di + 01Ch] ;01ch=26---->DIR
mov dword [dwKernelSize], eax ; / 保存 KERNEL.BIN 文件大小
pop eax
add di, 01Ah ; di -> 首 Sector //1Ah = 26---->DIR_frsclus
mov cx, word [es:di]
push cx ; 保存此 Sector 在 FAT 中的序号
add cx, ax
add cx, DeltaSectorNo ; cl <- KERNEL.BIN 的起始扇区号(0-based)
mov ax, BaseOfKernelFile
mov es, ax ; es <- BaseOfKernelFile
mov bx, OffsetOfKernelFile ; bx <- OffsetOfKernelFile
mov ax, cx ; ax <- Sector 号
LABEL_GOON_LOADING_FILE:
push ax ; `.
push bx ; |
mov ah, 0Eh ; | 每读一个扇区就在 "Loading " 后面
mov al, '.' ; | 打一个点, 形成这样的效果:
mov bl, 0Fh ; | Loading ......
int 10h ; |
pop bx ; |
pop ax ; /
mov cl, 1
call ReadSector ;//读扇区函数
pop ax ; 取出此 Sector 在 FAT 中的序号
call GetFATEntry
cmp ax, 0FFFh ;//判断有没有别的扇区了 0xfffh
jz LABEL_FILE_LOADED
push ax ; 保存 Sector 在 FAT 中的序号
mov dx, RootDirSectors
add ax, dx
add ax, DeltaSectorNo
add bx, [BPB_BytsPerSec]
jmp LABEL_GOON_LOADING_FILE
LABEL_FILE_LOADED:
call KillMotor ; 关闭软驱马达
mov dh, 1 ; "Ready."
call DispStr ; 显示字符串
jmp $
网上有很多代码的争论:and di,0fff0h;
的争论,我也争论下:
首先我们看这句话什么意思,读起来很简单就是 di低5位置0,这样子就使di是32的整数倍了,为什么是32?因为我们在寻找kernel.bin的时候,是从根目录一项项寻找的,而一项就是32byte;
那么我们看下是怎么寻找kernel.bin, 首先到根目录区第一项比对前11个字节,为什么是11字节?因为前11字节是DIR_Name,顾名思义,8个字节文件名,扩展民3个字节;
那么我们寻找,首先我们让di指向根目录的首项(要不,就把它想成指针吧),然后比对11个字节,如果是了,那就找到了,如果不是呢?那就让di加32?不是,我们首先应该让di指回开始的位置,然后呢再加32就到了下个目录区:
and di,0ffe0h;
add di,20h;
第一句话就把之前比对的11字节对di的影响而消除了,然后再加32,就这样的找法,知道之后就跳到上面的很多代码的地方了。
好,那我们来看关于争议的地方:and di,0fff0h;和and di ,0ffe0h;
0fff0h: 1111 1111 1111 0000; offe0h:1111 1111 1110 0000;
它们之间的区别就在倒数第五位,一个是保持,一个是置零;
而之前我们分析了di的操作:也就是那个11和32;
我们可以认为;di =32n+x; 0<=x<=11;
11: 0000 1011;di在一个目录项中,最多是di+11,而11根本不会影响倒数第5位,
如果没找到,and di ,offe0;又把之前的加的x又消除了,同样倒数第5位没变化;
加32的过程,实际上就是加 100 0000;对倒数第5位也是没有影响;
那么到这里,我或许可以下个结论,如果开始时执行了倒数第5位清零的操作,后面这个位一直是0;
结论:执行and di,0fff0h,和 and di ,0ffe0h;实际上没有区别的;