读取 CD 扇区时出现问题 INT 13h AH=42H

Ano*_*ser 0 assembly bootloader

我一直在尝试编写一个引导加载程序,它可以从 CD 而不是软盘上读取扇区,并且我一开始只是读取第一个扇区,但是当我运行它时,进位标志仍然设置,并且根据此处的文档: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
Run Code Online (Sandbox Code Playgroud)

编辑:

显然,我在此处设置段后忘记保存驱动器号:

Create_Stack:
    xor ax, ax
    mov es, ax
    mov ss, ax
    mov sp ,0x0FFFE
    sti

    mov     [CDDriveNumber],dl
Run Code Online (Sandbox Code Playgroud)

如果没有驱动器号,该功能将无法工作。我对此仍然陌生,所以也许其他人可以深入解释这一点?

Ros*_*dge 5

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