【发布时间】:2020-05-23 07:21:17
【问题描述】:
我正在编写一个引导扇区来加载我的 16 位实模式 DOS 克隆,但我遇到了一些可能非常明显的问题,但我花了几个小时试图理解为什么它不起作用.
基本上,我正在尝试将DS、CS、SS 设置为零,但将ES 设置为直接超过 7C00 以加载系统。
但是当通过调试器运行我的代码时,它说没有任何东西被读入内存,即:root、FAT 等 (???)
基本上,我正在尝试将 DS:SI (0000:7C00+FILE) 与 ES:DI (07E0:0000) 进行比较,但无济于事。我听说有人告诉我它实际上检查了DS:SI 和DS:DI,所以我尝试了它,但这也没有用。
07E0:0000 不应该直接在 0000:7C00 之后吗? cmpsb 是否要求 ES 和 DS 相同?
我查看了英特尔手册,但它说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
;
【问题讨论】:
-
Does Cmpsb require ES & DS to be the same?否 -
07E0:0 is 0x7E00,no?是 -
Shouldn't 07E0:0 be directly after 0000:7c00?有 512 个字节“紧接在”是。 -
你不应该在堆栈建立之前 push 任何东西(首先 "push ds" 在 "BPBPEND" 之后)
-
@Tommylee2k:为什么不呢?在某处肯定有是一个有效的堆栈,不与你的代码的 512 字节或任何 BIOS 认为有价值的东西重叠。 (否则这将是一个大量错误的 BIOS)。否则
int无法工作,跳转到引导扇区时启用中断。
标签: assembly nasm x86-16 bootloader memory-segmentation