Int 13h 扩展的 readDisk 例程不运行

Int 13h extended readDisk routine not functioning

我一直在尝试使用扩展读取功能 AH = 42HINT 13H
读取引导加载程序代码 (MBR) 中的几个扇区 但是没有显示错误,也没有读取扇区。
到目前为止,在使用 Bochs 和 Qemu 进行调试时,我注意到的是:
(我相应地设置了 dl 寄存器)

没有设置进位标志,所以没有报错 没有读入第二个扇区,即 0x7e00 填充为 0
这也意味着 jmp sect2 之后的任何代码都不会被执行。
我在这里做错了什么?

这是 readDisk 例程的代码:

readDisk:

    pusha
    push ds
    push si

    mov word [DAP_START_SECTOR] , cx
    mov word [DAP_NUM_SECTORS] , ax
    mov word [DAP_OFFSET], di
    mov word [DAP_SEGMENT], es
    xor ax,ax
    mov ds, ax
    mov si, DAP

    mov dl, 0x80
    ;0x80 for hard drive
    ;0x00 for first floppy
    mov ax, 0x42
    int 13h
    jc fail

    pop si
    pop ds
    popa
    ret
align 4
DAP:
    DAP_SIZE:           db 0x10
    DAP_UNUSED:         db 0x00
    DAP_NUM_SECTORS:    dw 0x00
    DAP_PTR_TO_SECTOR: 
        DAP_OFFSET:     dw 0x00
        DAP_SEGMENT:    dw 0x00

    DAP_START_SECTOR:   dq 0x00

fail:
 mov si,DISKFAILMSG
 call printf
 mov dx,ax
 call printh
 jmp $
DISKFAILMSG db "disk read ERROR",0

这是引导加载程序的代码:

[org 0x7c00]  ;start at 0x7c00
[bits 16]

section .data ; constants, put under the magic number, at the end
section .bss  ; variables, similarly at the end
section .text ; code

global main   ;main is global and is our entry point

main:
            ;clear the seg registers, to prevent any offset buffer

cli         ;clear interrupts

jmp 0x0000:ZeroSeg

ZeroSeg:
    xor ax,ax   ; clear ax
    mov ss,ax
    mov ds,ax
    mov es,ax
    mov fs,ax
    mov gs,ax

    ;cleared the seg

    mov sp, 0x7c00      ;0x7c00 = main?
    cld         ; clear the direction flag, which controlls the order of reading
                ; string
    sti         ; set interrupt
    push ax
    xor ax,ax
    ;mov dl, 10000000b
    int 13h
    jc fail
    pop ax






;mov al,2       ; read 2 sectors
;mov cl,2       ; sectors start from 1, sector 1 is bootloader, so read sector 2

mov ax,0x07e0
mov es,ax
xor di,di

mov ax, 0x0002      ; number of sectors read
mov cx, 0x0001  ;absolute number (not addr of start sector (sector 0 is bootloader here))


call readDisk


call loadE820
mov dx,ax       ;trial 1: received 6 entries
call printh

;TODO Configure Proper video modes
;call videoMode









jmp sect2       ; works if sect2 is read

%include "./printf.asm"
%include "./readDisk.asm"
%include "./printh.asm"
%include "./loadE820.asm"
;%include "./videoMode.asm"

%include "./gdt.asm"
;
;
;
times 510 - ($-$$) db 0 ;padding
dw 0xaa55               ;Magic number


;sector 2  

sect2:
    call EnableA20

    mov si, MESSAGE
    call printf

    call checklm

    mov si,DISKSUCCESSMSG
    call printf

    ;call keyb



;call videoMode
call enterProtected
;
;
;;*******************************TEST CODE********************************
;
;
;;call testvid32
;
mov si,DISKSUCCESSMSG
call printf


jmp $

%include "./TestA20.asm"
%include "./EnableA20.asm"

%include "./checklm.asm"
;
;
;
;
;
MESSAGE db "Hello, World!",0x0a,0x0d,0
DISKSUCCESSMSG db "Welcome to my first OS!",0ah,0dh,0



times 512-($-sect2) db 0

sect3:
%include "./enterProtected.asm"
keyb:
        mov ah,00h
        int 16h
        cmp ah,0
        je keyb
        ret
%include "./testvid32.asm"

虽然这可能是引导映像的问题以及您如何创建它或与您未显示的代码相关的问题,但我怀疑真正的问题可能是这个错误:

mov ax, 0x42
int 13h

BIOS 调用号 0x42 应该在 AH,而不是 AX。它应该是:

mov ah, 0x42
int 13h

虽然这不是您的问题,但在调用磁盘函数时硬编码引导驱动器号通常不是一个好主意。您可以简单地使用 BIOS 传递给引导加载程序的 DL 中的值,而不是强制将 DL 设置为 0x80。您的磁盘重置 Int 13h/AH=0h call does this correctly, but your Int 13/AH=42h 扩展磁盘读取没有。