读取CD INT 13h AH=42H扇区时出现故障



我一直在尝试写一个BootLoader,它从CD而不是软盘上读取扇区,我一开始只读取第一个扇区,但当我运行它时,Carry标志仍然设置,并且根据这里的文档:http://en.wikipedia.org/wiki/INT_13H#INT_13h_AH.3D42h%3a_Extended_Read_Sectors_From_Drive这意味着它无法从图像中读取扇区这是我的完整启动代码:

BITS   16
ORG  0x00
Start: jmp main

;Colors for text
%DEFINE TEAL 0x03
%DEFINE RED 0x04
%DEFINE PURPLE 0x05
COL: db 0
ROW:  db 0
;macro for print
%macro Print 2
    xor dx, dx
    mov dh, BYTE[ROW];puts the row into the dh register
    xor bx, bx
    mov bl, %2
    mov si, %1
    call cPrint

    mov ah, 0x02            ;set cursor pos
    mov bh, 0x00            ;page 00
    inc dh                  ;row 00
    mov dl, 0x00            ;col. 00    
    int 0x10
    mov BYTE[ROW], dh;saves the rows for the next time we need to print
%endmacro

cPrint:                   ; Routine: output string in SI to screen

 .top:
    ;Paramaters for Input 
    mov ah, 09h             ; Must be 9 to print color
    mov cx, 0x01            ;x position
    lodsb                   ; Get character from string
    test al, al
    je .done                ; If char is zero, end of string
    int 0x10                 ; Otherwise, print it
    mov ah, 0x02            ;set cursor position
    mov bh, 0x00            ;page
    inc dl      ;column
    int 0x10                ;changes the cursor position so the next char can be written at the new location
    jmp .top
 .done:
    ret
;clears the screen and sets the cursor position to the top left 
 clear:
    mov ah, 0x0F            ;get current video mode
    mov al, 0x00            ;reset register
    int 0x10                ;get video mode
    mov ah, 0x00            ;set video mode
    int 0x10                ;reset screen
    mov ah, 0x02            ;set cursor pos
    mov bh, 0x00            ;page 00
    mov dh, 0x00            ;row 00
    mov dl, 0x00            ;col. 00
    int 0x10                ;set pos
ret


Read_Extended_Sector:
    pusha
    xor ax, ax
    xor dx, dx
    xor bx, bx
    ;read in the sector

    .ForLoop:
        MOV DL,BYTE[CDDriveNumber]              ; Set it up again 
        MOV AH,42h                          ; Read from drive function 
        MOV SI,DiskAddressPacket            ; Load SI with address of the Disk Address Packet 
        INT 13h    
        jnc .Success

        Print Read_Sector_Error_MSG, PURPLE
        cli
        hlt
    .Success:
        Print READ_SUCCESS, TEAL
        cmp ah, Stage2
        jz .DONE
        Print FILE_NOT_FOUND, RED
        cli
        hlt
    .DONE:
    popa
ret

main:
    cli; disable interrupts
    mov ax, 0x07c0  ;adjust the segment registers
    mov ds, ax
    mov gs, ax
    mov fs, ax

Create_Stack:
    xor ax, ax
    mov es, ax
    mov ss, ax
    mov sp ,0x0FFFE
    sti ; enable interrupts
    call clear

    Print W_MSG, TEAL;prints the loading message in colour

    call Read_Extended_Sector; Reads the first sector of the drive 
    ;the read in data is stored in AH







cd_signature: db "CD001"        
cd_Version:   db 0x01
CDDriveNumber: db 80h
;Disk Address Packet

DiskAddressPacket:          db 16,0 
.SectorsToRead:             dw 1                              ; Number of sectors to read (read size of OS) 
.Offset:                    dw 0                              ; Offset :0000 
.Segment:                   dw 0200h                          ; Segment 0200
.End:                       dq 16                             ; Sector 16 or 10h on CD-ROM 

W_MSG: db "Loading Z-Boot...........", 0
Stage2: db "STAGE2 BIN"
Read_Sector_Error_MSG: db "Failed to read sector ......",0
READ_SUCCESS: db "Reading the first sector was a success .......",0
FILE_NOT_FOUND: db "Error, File not found......."
times 2046 - ($ - $$) db 0; padd out the rest of the file to 0
DW 0xAA55

编辑:

显然,我在这里设置分段后忘记保存驱动器号:

Create_Stack:
    xor ax, ax
    mov es, ax
    mov ss, ax
    mov sp ,0x0FFFE
    sti
    mov     [CDDriveNumber],dl

如果没有驱动器号,该功能将无法工作。我还是个新手,所以也许其他人可以深入解释一下?

BIOS在DL寄存器中提供其启动的驱动器编号。驱动器00h是第一个软盘驱动器,驱动器01h是第二个软盘驱动器。驱动器80h是第一个硬盘,随后是后续的硬盘。当从CD-ROM启动时,并且只有当从CD-ROM引导时,BIOS才会将CD-ROM模拟为硬盘。这就是为什么您可以使用INT 13h, AX=42 Extended Read BIOS调用来读取它。BIOS为模拟CD-ROM分配的驱动器号因系统而异,因此您无法对其进行硬编码。

最新更新