2017-06-30 17 views
3

私はちょっとしたOSを作る方法を学んでいますが、主にthisチュートリアルのことを使っています。QEmuでシンプルブートセクタを使用してディスクから不正なバイトを読み取っています

私はこのチュートリアルの28ページで、小さなディスクローダーを実行しようとしています。

しかし、以前のブートセクタの例で働いていたqemu-system-i386 boot_sector.binを実行すると、最初に得られた16進数は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 

をQEmuを-fdaフラグを使って実行しようとしましたが、これはいくつかの場所で提案されていましたが、運はありません。また、セクタ数を5に変更した場合(チュートリアルのように)、ドライブの読み込みエラー(disk_load関数から発生)が発生します。

これは私に非常に迷惑をかける。助けを前にありがとう。

答えて

3

-_-問題の内容を整理しました。

hex_printを呼び出した後、私はHEX_STRINGをリセットしませんでした。

Iは間接的この問題を修正したASCII 0

HEX_STRINGの各バイトを設定し、単にBXのアウトバックHEX_STRINGの場所をコピーし、その後、BXを反復することによって、これを固定しました。