2014-03-04 70 views
0

我需要一些帮助来理解使用BrokenThorn的引导加载程序加载内核的逻辑。引导程序加载图像文件

代码:

LOAD_IMAGE: 

      mov  ax, WORD [cluster]     ; cluster to read 
      pop  bx         ; buffer to read into 
      call ClusterLBA       ; convert cluster to LBA 
      ;xor  cx, cx 
      ;mov  cl, BYTE [bpbSectorsPerCluster]  ; sectors to read (commenting out has same result? 
      call ReadSectors       ;(ES:BX from above) 
      push bx 

    ; compute next cluster 

      mov  ax, WORD [cluster]     ; identify current cluster 
      mov  cx, ax        ; copy current cluster 
      mov  dx, ax        ; copy current cluster 
      shr  dx, 0x0001       ; divide by two 
      add  cx, dx        ; sum for (3/2) 
      mov  bx, 0x0200       ; location of FAT in memory 
      add  bx, cx        ; index into FAT 
      mov  dx, WORD [bx]      ; read two bytes from FAT 
      test ax, 0x0001 
      jnz  .ODD_CLUSTER 

    .EVEN_CLUSTER: 

      and  dx, 0000111111111111b    ; take low twelve bits 
     jmp  .DONE 

    .ODD_CLUSTER: 

      shr  dx, 0x0004       ; take high twelve bits 

    .DONE: 

      mov  WORD [cluster], dx     ; store new cluster 
      cmp  dx, 0x0FF0       ; test for end of file 
      jb  LOAD_IMAGE 

    DONE: 

      mov  si, msgCRLF 
      call Print 
      push WORD 0x0050 
      push WORD 0x0000 
      retf 

我为什么要CHS转换为LBA?在函数中,好像LBA存储在AX寄存器中。但它没有在ReadSectors中使用?之后,当前群集将被复制到AX中。

ClusterLBA: 
      sub  ax, 0x0002       ; zero base cluster number 
      xor  cx, cx 
      mov  cl, BYTE [bpbSectorsPerCluster]  ; convert byte to word 
      mul  cx 
      add  ax, WORD [datasector]    ; base data sector 

      ret 

此外,引导程序加载内核到内存位置0x0050:0×0000

我为什么不能jmp 0x0050:0x0000和启动代码的执行?是什么

push WORD 0x0050 push WORD 0x0000

吗?这在教程中没有解释。

回答

1

为什么我需要将CHS转换为LBA?

你不这样做,代码没有在我能看到的任何地方做。我假定代码做的是将(FAT)“簇号”转换为LBA号。请注意,FAT文件系统使用群集(可能是512字节,1024字节,...),其中群集数字相对于分区的起始位置(而不是磁盘的起始位置)。

在函数中,好像LBA存储在AX寄存器中。但它没有在ReadSectors中使用?

您没有发布ReadSectors的代码,并且没有提供该代码可能的任何位置的链接。我只能假设你错了,并且ReadSectors确实在AX中使用了LBA(例如,在使用int0x13加载扇区之前立即进行CHS转换的快速LBA)。

为什么我不能jmp 0x0050:0x0000并开始执行代码?

你可以。不幸的是,很多编写汇编语言代码的人不是汇编语言程序员(例如,他们可能是懂C语言的C程序员)。更可悲的是,一些有硬度的旧装配工不是很好,让人们很难找出如何做远程跳跃。基本上,“push,push,retf”就在那里,因为谁写的都没有或者不知道如何正确地做。

2

ClusterLBA将群集#(在AX中)转换为扇区#(在AX中)以便能够通过int 13h读取这些扇区。
ReadSectors似乎将AX,ES:BX作为参数。
push,push,retf相当于jmp far。两种变体都是5个字节长。没有不同。