Я пишу загрузочный сектор для загрузки моего 16-битного клона DOS реального режима, и я застрял на чем-то, что может быть совершенно очевидно, но я потратил часы времени, пытаясь понять, почему это не сработает .
В основном я пытаюсь установить DS
, CS
, SS
на ноль, но держу ES
установленным прямо после 7C00 для загрузки системы.
Но при запуске моего кода через отладчик он говорит, что ничего не было прочитано в память, то есть: root, FATs и т. д. c (???)
По сути, я пытаюсь сравнить DS:SI
(0000: 7C00 + ФАЙЛ) ДО ES:DI
(07E0: 0000), но безрезультатно. Я слышал, кто-то сказал мне, что на самом деле он проверяет DS:SI
с DS:DI
, и поэтому я попробовал, но это тоже не сработало. Не должно ли 07E0: 0000 быть сразу после 0000: 7C00? cmpsb
требует, чтобы ES
& DS
были одинаковыми?
Я смотрел в руководствах Intel, но там говорится, что cmpsb
сравнивает DS:SI
с ES:DI
, но я не думай, что я слишком неправильно понимаю. 07E0: 0000 - это 0x7E00, нет?
В любом случае, спасибо за любую помощь. Я ценю это.
РЕДАКТИРОВАТЬ: я забыл упомянуть, что если я обнуляю ES
и помещаю адрес загрузки в BX
, все работает. Но когда это перевернуто, ES=07E0
, BX=0
, ничего не работает или даже не читается. Не знаю почему, поскольку ES:BX
должно быть одинаковым независимо от того, по какому маршруту вы идете.
Мой код:
ORG 7C00H
USE16
BPBBEG:
JMP SHORT BPBPEND
NOP
DB "PEDOS1.0"
BYTSPERSEC: DW 512 ; total bytes per sector on this volume
SECPERCLUS: DB 1 ; total sectors per cluster on this volume
RSVDSECCNT: DW 1 ; unused
NUMFATS: DB 2 ; total FATs on this volume
ROOTENTCNT: DW 224 ; total entries in the Root Directory
DW 80 * 36
DB 240
FATSZ16: DW 9 ; total sectors per FAT on this volume
SECPERTRK: DW 18 ; total sectors per track on this idks
NUMHEADS: DW 2 ; total heads per cyliner on this idks
DD 0
DD 0
DB 0
DB 0
DB 41
DD 0
DB " "
DB "FAT12 "
;
; PEDOS MEMORY MAP
;
; - -- ROM / VIDEO -- A000:0
; - -----------------
; - -- BIOS DATA -- 8000:0
; - -----------------
; - -- FREE -- ????:?
; - -----------------
; - -- BOOT / FREE -- 0000:7C00
; - -----------------
; - -- FREE -- ????:?
; - -----------------
; - -- DRIVERS -- ????:?
; - -----------------
; - -- SYSTEM -- 0050:0
; - -----------------
; - -- BIOS BATA -- 0000:400
; - -----------------
; - -- IVT -- 0000:0
;
;
; INITIALIZE SEGMENT REGISTERS
;
BPBPEND:
XOR AX, AX
MOV DS, AX
CLI
PUSH DS
POP SS
MOV SP, 7C00H
PUSH DS
PUSH CHKDSK
STI
RETF ; SET CS TO KNOWN VALUE
;
; LOAD ROOT DIRECTORY AND CHECK FOR
; SYSTEM FILE
;
CHKDSK:
MOV AX, WORD BUFFER
SHR AX, 4
MOV ES, AX ; ES = 07E0
XOR AX, AX
MOV AX, WORD [FATSZ16]
MUL WORD [NUMFATS]
ADD AL, BYTE [RSVDSECCNT]
;mov bx, 0x7e00
MOV DI, 1
CALL READSEC
; mov ah, 14
; mov al, '/'
; int 16
; jmp $
LEA SI, [FILE] ; ADDRESS OF FILENAME
MOV DI, 0
MOV CX, 11 ; 11 BYTES PER FAT FILENAME
CLD
REPZ CMPSB
JZ LOADFILE
JMP ERROR
; DOSBIOS.SYS CONFIRMED: LOAD THE
; FILE INTO MEMORY.
LOADFILE:
mov ah, 14
mov al, '.'
int 16
jmp $
MOV AX, 32
MOV BX, WORD [ROOTENTCNT] ; TOTAL FATS ON DISK
MUL BX
MOV BX, WORD [BYTSPERSEC] ; FAT SIZE IN SECTORS
DIV BX
;
; AX = SIZE OF ROOT DIRECTORY
; IN SECTORS
;
ADD AX, BP ; SIZE + LOCATION = DATA REGION
POP BX
PUSH BX
MOV DI, 1 ; DOS SIZE IS HARD CODED FOR NOW - MAY
CALL READSEC ; CHANGE IN THE FUTURE
RUNDOS:
POP BX
PUSH 0
PUSH BX
RETF
;
; READ THE SPECIFIED SECTORS INTO MEMORY
; AT LOGICAL ES:BX
;
; IN: DX:AX = HEAD, TRACK, SECTOR NUMBER
; DI = SECTOR COUNT
;
READSEC:
PUSHA
DIV WORD [SECPERTRK]
;
; AX = LBA / SECPERTRACK
; DX = LBA % SECPERTRACK
;
MOV CX, DX
INC CX ; CX = LBA 1
XOR DX, DX
DIV WORD [NUMHEADS]
;
; AX = (LBA / SECPERTRACK) / CYLHEADCNT = CYLINDER
; DX = (LBA / SECPERTRACK) % CYLHEADCNT = HEAD
;
MOV CH, AL
SHL AH, 6
OR CL, AH
MOV DH, DL
MOV DL, 0
;
; DH = HEAD HUMBER
; DL = DRIVE
;
MOV AH, 2
MOV AL, 1
INT 19
JNC NEXTSEC ; IN CASE OF ERRORS, FOLLOW
ERROR:
LEA SI, [ERRMSG] ; SOMETHING WENT WRONG, SO THROW AN ERROR
;
; WRITE SPECIFIED STRING TO VIDEO
; MEMORY
;
; DS:SI = ADDRESS OF STRING
;
PRINT:
LODSB
OR AL, 0
JZ HALT
MOV AH, 14
MOV BX, 7
INT 16
JMP PRINT
HALT:
MOV AX, 0
INT 22
INT 25
;
; CONTINUE 'READSEC'
;
NEXTSEC:
POPA
DEC DI
JZ RETURN ; SKIP PRINT SUBROUTINE
ADD BX, WORD [BYTSPERSEC]
ADD AX, 1
ADC DX, 0
JMP READSEC
RETURN:
RET
;
; KEEP DATA BELOW CODE, UNTIL SECTOR
; MARKER
;
ERRMSG: DB 10, "Disk Error or DOSBIOS.SYS is missing.", 13
DB 10, "Press any key to restart.", 13, 10, 10, 0
FILE: DB "DOSBIOS SYS"
TIMES (512 - 2) - ($ - $$) DB 0
MARKER: DW 0AA55H
BUFFER:
;
; THE SYSTEM IS LOADED DIRECTLY AFTER
; BOOTSTRAP
;