2014-03-04 68 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個字節長。沒有不同。