目前,我一直关注OS Dev上的BrokenThorn系列,我遇到了一些问题。现在,作为我的教程之旅的一部分,我正在编写在第二阶段引导加载程序中加载的部分,但不幸的是,代码崩溃了。以下是我认为很麻烦的部分代码:
代码:
;browse root directory for binary image
mov ax, WORD [bpbRootEntries]; load loop counter, bpbRootEntries is the number of entries in the FAT table
mov di, 0x0000 ; because rep cmpsb compares the string in es:di to ds:si, and es holds 0x7e00 (the location of the FAT Table), I decided to set di to 0x0000
mov cx, 0x000B; eleven character name
lea si, [ImageName] ;set si to the memory location of ImageName so ds:si points to ImageName
.LOOP:
rep cmpsb
jz LOAD_FAT
add di, 32 ; queue next directory entry
dec ax
cmp ax, 0x0
jne .LOOP
jmp FAILURE
这部分代码在FAT表中查找文件。但是,它无法找到它,所以崩溃了。 在此代码中,ImageName是一个值为“KRNLDR SYS”的变量。在我的软盘驱动器中,我的软盘驱动器中有一个名为“KRNLDR SYS”的文件(带有空格,而不是“KRNLDR.SYS”)。如果有人能提供任何建议,那将是一个很大的帮助。
注意:我目前正在运行64位Windows 7 PC
更新
在所有有用的评论之后,我更新了代码:
mov ax, WORD [bpbRootEntries] ; load loop counter
mov di, 0x0000 ; locate first root entry
mov cx, 0x000B ; eleven character name
lea si, [ImageName] ; image name to find
.LOOP:
push di
push si
repe cmpsb
pop di
pop si
jz LOAD_FAT
add di, 32 ; queue next directory entry
dec ax
or ax, ax
jne .LOOP
jmp FAILURE
不幸的是,操作系统仍然无法找到该文件。
更新2
以下是我用于加载根目录表的代码:
LOAD_ROOT:
; compute size of root directory and store in "cx"
xor si, si
mov ax, 0x0020 ; 32 byte directory entry
mul WORD [bpbRootEntries] ; total size of directory
div WORD [bpbBytesPerSector] ; sectors used by directory
xchg ax, cx
; compute location of root directory and store in "ax"
mov al, BYTE [bpbNumberOfFATs] ; number of FATs
mul WORD [bpbSectorsPerFAT] ; sectors used by FATs
add ax, WORD [bpbReservedSectors] ; adjust for bootsector
mov WORD [datasector], ax ; base of root directory
add WORD [datasector], cx
; read root directory into memory (7C00:0200)
mov dx, 0x7e00
mov es, dx
mov bx, 0x0 ; copy root dir above bootcode
call ReadSectors
谢谢!
答案 0 :(得分:0)
REP
上的CMPSB
将重复CMPSB
CX
次,而ZF
将设置为最后一次比较的结果。< / p>
REPE
此处即使使用REPE
,REPE CMPSB
也会同时修改DI
和SI
,以便它们每个都指向比较最后一个字节后的字节(让我们假设{ {1}}设置为UP)因此,向DF
CERTAINLY 添加32将不会指向下一个FAT条目。
DI
之前PUSH
和DI
之前SI
和REPE CMPSB
之后需要POP
{这不会影响{{1} }})这样,FLAGS
和DI
似乎都没有改变,32的添加也是有效的。
通过技巧,SI
会将OR AX,AX
设置为与ZF
相同,但它是更小,更快的指令。
答案 1 :(得分:0)
我想我已经修好了(有点)。我使用名为WinHex的Hex编辑器,将文件的位置定位在内存中,并将其硬编码到程序中。它是临时的,但只要我能在C中为我的内核开始编程就足够了,我认为它比Assembly更简单。感谢大家的帮助!
答案 2 :(得分:0)
我和你一样,但在Bochs的Linux(Brokenthorn OS教程)上。 我创建了一张软盘图像并将其与Bochs一起使用。 对我来说,Demo1.zip(Stage2)中的代码可以正常工作。 它从Fat12读取第二阶段加载器。 但是一开始它没有用,因为当我将bootsector复制到软盘映像时,软盘映像被截断了。 请注意,我只将文本更改为在Stage2.asm中打印出来。