簡體   English   中英

在QEmu中使用簡單引導扇區從磁盤讀取不正確的字節

[英]Incorrect Bytes Being Read from disk using a Simple Boot sector, in QEmu

所以我正在嘗試學習如何制作一個小操作系統,主要是使用教程的東西。

我在該教程的第28頁,試圖做一些小磁盤加載器。

但是,當我運行qemu-system-i386 boot_sector.bin ,它對前面的引導扇區示例0xDADA 0xZRWV ,我得到的十六進制輸出是0xDADA 0xZRWV ,第一個是正確的,而第二個不是。

我的代碼如下。

Boot_sector.asm

; Very simple boot sector to read sectors from disk

jmp main        ; ensures that we start where we want to

%include "disk_load.asm"

BOOT_DRIVE:
  db 0

[org 0x7c00]    ; tell the assembler where this code will be loaded

main:
  mov   bp, 0x8000        ; Make sure the stack is out of our way
  mov   sp, bp

  mov   bx, 0x9000
  mov   dh, 2             ; Want to read 2 sectors
  call  disk_load

  mov   dx, [0x9000]
  call  hex_print         ; Should output 0xDADA

  mov   dx, [0x9000 + 512]; Should output 0xFACE 
  call  hex_print

  hang:
    jmp   hang  ; Continually jump to current location

; Add padding and magic BIOS number (to let BIOS know this is a boot sector)

times 510-($-$$) db 0 ; pad with zeroes
dw    0xaa55          ; magic number

times 256 dw 0xdada   ; second sector
times 256 dw 0xface   ; third sector

disk_load.asm:

%include "bios_print.asm"

ERROR_MSG:
  db "Disk read error!", 0

SECTOR_ERROR_MSG:
  db "Wrong number of sectors read!", 0

disk_load:
  push  dx            ; Store the number of sectors we wanted to read
  mov   ah, 0x02      ; BIOS read sector function
  mov   al, dh        ; Number of sectors to be read

  mov   ch, 0x00      ; Cylinder 0
  mov   dh, 0x00      ; Head 0
  mov   cl, 0x02      ; Sector 2 (just after the boot sector)

  int   0x13

  jc    disk_error    ; if carry flag is set, report an error

  pop   dx
  cmp   dh, al
  jne   sector_error  ; if we didn't read as many sectors as we wanted.
  ret

disk_error:
  mov   bx, ERROR_MSG
  call  bios_print
  jmp   $

sector_error:
  mov   bx, SECTOR_ERROR_MSG
  call  bios_print
  jmp   $

然后bios_print.asm只具有打印十六進制的功能,依此類推:

bios_print:
  pusha
  mov   si, bx

  loop:
    lodsb
    or    al, al
    jz    done
    mov   ah, 0x0e
    int   0x10
    jmp   loop

  done:
    popa
    ret

HEX_OUT:
  db '0x0000', 0

hex_print:
  pusha
  mov   cx, 4 ; Counter

  char_loop:
    dec   cx
    mov   ax, dx
    shr   dx, 4
    and   ax, 0xf     ; Mask to get the last part of ax
    mov   bx, HEX_OUT
    add   bx, 2       ; Skip the '0x' in HEX_OUT
    add   bx, cx

    ; If the character is a number, we just plop that out, but if it
    ; is a letter, we have to convert it to ASCII by adding 7 (because
    ; ASCII starts at 17, and the numbers end at 10)
    cmp   ax, 0xa
    jl    set_char
    add   byte [bx], 7
    jl    set_char

    set_char:
      add   byte [bx], al ; Add the value of the byte to the char stored at bx
      cmp   cx, 0
      je    finished
      jmp   char_loop

    finished:
      mov   bx, HEX_OUT
      call  bios_print

      popa
      ret

我也嘗試使用-fda標志運行QEmu,這是在一些地方建議的,但沒有運氣。 另外,如果我將要讀取的扇區數更改為5(如教程中所示),則會出現Drive read錯誤(從disk_load函數引發)。

這讓我非常生氣。 在此先感謝您的幫助。

-_-我剛剛解決了問題所在。

在調用hex_print ,我沒有重置HEX_STRING

我通過簡單地將HEX_STRING的位置復制回BX,然后通過BX迭代,間接地將HEX_STRING每個字節設置為ASCII 0來解決這個問題。

這解決了這個問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM