1

我正在软盘上以 x86-16 程序集编写引导加载程序,这意味着我必须从磁盘读取才能加载更多代码,但是,每次我尝试读取磁盘并检查磁盘状态代码时,我总是0x04 - sector not found.尝试使用CX设置为0x00000x0001和来阅读0x0101,但我真的不知道该怎么做,或者我做错了什么。
INT 13,1- 磁盘状态代码
INT 13,2- 读取磁盘扇区

BITS 16

%include "C:\x86asm\nasm\nasm.asm"
    ;%macro pad 1-2 0
    ;   times %1 - ($ - $$) db %2
    ;%endmacro
    ;%idefine PUSHW PUSH STRICT WORD
    ;%idefine PUSHD PUSH STRICT DWORD
[org 0x7C00]

; https://stanislavs.org/helppc/        ;; BIOS
; https://c9x.me/x86/                   ;; Instruction Set
; https://wiki.osdev.org/               ;; OS Development

; absolute address = (segment << 4) + address
; to simulate NES/SNES style memory mapping (banks), only use bits[9..15] ($x000)
            
            JMP 0x0000:_start           ; ensure CS = $0000
_start:
            CLI                         ; clear interrupt flag (disable
                                        ;   interrupts, opposite of 6502)
            CLD                         ; clear direction flag
            
            PUSH CS
            POP DS                      ; prepare for puts / puthexbyte
            PUSH CS
            POP SS                      ; set up stack segment
            MOV SP, 0x7C00
            
            ;; set graphics ;;
            
            MOV AX, 0x0012              ; set screen mode
            INT 0x10
            
            MOV AH, 0x0B
            MOV BX, 0x0201
            INT 0x10
            
            MOV DX, 0x0D22              ; display "LOADING..."
            MOV BX, 0x0007
            MOV SI, loadstr
            CALL putsl
            
            MOV AH, 0x86                ; wait a moment...
            MOV CX, 0x000F
            INT 0x15
            
            ;; load floppy disk ;;
            
            MOV BP, 0x0800              ; if fail, read x times
.loadfailure:
                SUB BP, 0x0100          ; decrement # of tries left
                
                MOV AH, 0x02            ; print # of tries left
                XOR DX, DX
                INT 0x10
                MOV DX, BP
                CALL puthexbyte
                
                MOV AH, 0x00            ; reset disk system
                MOV DL, 0x00
                INT 0x13
                
                MOV AX, 0x0201          ; read
                MOV CX, 0x0101
                XOR DX, DX
                PUSHW 0x1800            ; write to $18000 ~ $1FFFF
                POP ES
                XOR BX, BX
                INT 0x13
                
                PUSHF
                
                MOV DH, AH              ; show error code
                CALL puthexbyte
                
                POPF
                
                JNC .loadsuccess
                    TEST BP, BP
                    JNE .loadfailure
                        MOV DX, 0x0D0F      ; read fail;
                        MOV SI, badload     ;   print msg
                        CALL putsl
                        
                        MOV AH, 0x86        ; wait
                        MOV CX, 0x001E
                        INT 0x15
                        
                        INT 0x18        ; boot windows
.loadsuccess:
            
            MOV DX, 0x0D0F          ; read success;
            MOV SI, nosystem        ;   DOS not finished,
            CALL putsl              ;   tell user
            
            MOV AH, 0x86            ; wait
            MOV CX, 0x001E
            INT 0x15
            
            JMP 0x1000:0x8000       ; boot test
            
            
putsl:
    ; [DX]    : (Y,X)
    ; (AH)
            MOV AH, 0x02
            INT 0x10                ; set cursor position
puts:
    ; [DS:SI] : String
    ; (AX, BX, SI)
            MOV AH, 0x0E            ; teletype mode
            MOV BX, 0x000F          ; set white text attribute
.putsloop:
                LODSB               ; load character from [DS:SI++]
                TEST AL, AL         ; check if NULL (x86 MOV does not
                JE .endputs         ;   change zero-flag unlike 6502 LDA/LDX/LDY)
                    INT 0x10        ; print character
                    JMP .putsloop   ; loop until NULL
.endputs:
            RET
            
            
puthexbyte:
    ; [DH] : Value
    ; (AX, DH, BX)
            MOV AH, 0x0E
            
            MOV BX, asciihex
            MOV AL, DH
            SHR AL, 4
            XLAT
            MOV BX, 0x000F
            INT 0x10                ; print character
            
            MOV BX, asciihex
            MOV AL, DH
            AND AL, 0x0F
            XLAT
            MOV BX, 0x000F
            INT 0x10
            
            RET
asciihex:
    db "0123456789ABCDEF", 0
            
            
loadstr:
    db "LOADING...", 0
badload:
    db "Unable to load disk. Attempting to load Windows...", 0
nosystem:
    db "Operating System is incomplete. Loading Windows...", 0
tststr:
    db "Disk read success. INT 0x20 set success. Jump success.", 0

    
    pad 0x01FE                          ; pad to end of boot sector
    dw 0xAA55                           ; floppy disk boot sector signature
    
    ; code
            
            PUSHW 0x0000                ; test setting INT
            POP DS                      ;   (tested; works when in
            MOV [4 * 0x20], DWORD putsl ;   boot sector)
            
            MOV DX, 0x0D0D              ; test INT by
            MOV SI, tststr              ;   printing
            INT 0x20                    ;   string
            
            MOV AH, 0x86                ; wait
            MOV CX, 0x001E
            INT 0x15
            
            INT 0x18                    ; boot windows
    
    pad 0x0400                          ; pad to end of sector 1
    
    ;incbin "os.bin"
    
    pad 0x00167FFF                      ; pad to disk end
    db 0x00

编辑:
关于如何将磁盘扇区和磁道(即CXin INT 13,2)转换为“线性地址”的解释将不胜感激,因为我用来将代码放到软盘上的方法让我打开程序 HxD 并手动将我的二进制文件复制并粘贴到磁盘上。
此外,我使用的磁盘是“未格式化的”(就 Windows 而言)。此外,如果这有任何改变,我的 PC 的 BIOS 是 (msinfo32)“American Megatrends Inc. 5.35, 2008-12-16”。

4

0 回答 0