【问题标题】:Bootloader loading image file引导加载程序加载图像文件
【发布时间】:2014-03-04 05:34:35
【问题描述】:

我需要一些帮助来理解使用 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:0x0000

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

push WORD 0x0050 push WORD 0x0000

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

【问题讨论】:

    标签: assembly bootloader


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

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

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

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

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

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

      你可以。

      遗憾的是,很多编写汇编语言代码的人并不是汇编语言程序员(例如,他们可能是懂一点汇编语言的 C 程序员)。更可悲的是,一些顽固的旧汇编器不是很好,使人们很难弄清楚如何进行远跳。基本上,“push;push;retf”之所以存在,是因为编写它的人没有或无法弄清楚如何正确地做到这一点。

      【讨论】:

        猜你喜欢
        • 2012-04-09
        • 1970-01-01
        • 2014-10-03
        • 1970-01-01
        • 2021-04-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-09-10
        相关资源
        最近更新 更多