由于注释的时候不想中英文切换,所以就
ORG 7C00H
; init
MOV AX, 0
MOV SS, AX
MOV SP, 7C00H
MOV DS, AX
MOV [DriverLetter], DL
; --------------- main ---------------
; print start message
MOV AX, startMsg
MOV CX, 13
CALL printText
; read disk
MOV AX, 0800H
MOV ES, AX ; set ES
MOV CH, 00H ; cylinder 0
MOV DH, 00H ; recording head 0 (obverse)
MOV CL, 05H ; (sector 2 in ISO) = (sector 5 by CHS address)
readLoop:
MOV SI, 0
retry:
MOV BX, 0 ; ES:BX -> buffer address
MOV AX, 0201H ; AH=02H (read disk), AL(the num of sectors)
MOV DL, [DriverLetter] ; (DL=9FH)Driver letter
INT 013H
; read end
JNC next ; if success, solve directly
; is failed, restore diriver(but try 5 at most)
ADD SI, 1
CMP SI, 5 ; failed 5, show error msg
JNL error
MOV AH, 000H ; set param
MOV DL, [DriverLetter]
INT 013H ; restore it
JMP retry
next: ; prepare for next read
MOV AX, ES
ADD AX, 020H
MOV ES, AX ; add 200H to address
ADD CL, 1 ; next sector
CMP CL, 8
JNG readLoop ; if CL<=18, read continue, else solve it
JMP success
; if success, CF==0 and AH == 0
; if false, CF == 1 and AH is error code
; reset ES, because it is changed
error: ; set error message
MOV AX, errorMsg
MOV CX, 13
JMP printResultMsg
success: ; set success message
MOV AX, successMsg
MOV CX, 15
printResultMsg: ; show result
MOV BX, 0
MOV ES, BX
MOV DH, 01H ; to set new msg new line, avoid coverage old msg
CALL printText
CALL debug ; show memory
JMP 08000H ; invoke it
; ------------- main end ---------------
; before call it, should set (string address -> AX) and (string length -> CX)
printText:
MOV BP, AX ; ES:BP is the address of output string
MOV AX, 01301H ; AH(print string) AL(=1)(point follow)
MOV BL, 0FH ; BH(PageNum) BL(0CH)(red word and black bg)
MOV DL, 00H
INT 10H ; BIOS I/O
RET
; show the memory (0800H)
debug:
MOV AX, 0800H
MOV DS, AX
MOV SI, 0000H
MOV CX, 200H
loop1:
CALL printNum
ADD SI, 1
loop loop1
RET
; before call it, set SI point to the content you want show
; if AX is useful, must store it in stack, printNum will change it
printNum: ; print a byte
MOV AL, [SI]
SHR AL, 4
AND AL, 0x0f
CALL printSingleNum
MOV AL, [SI]
AND AL, 0x0f
CALL printSingleNum
MOV AL, 20H
INT 10H ; print space
RET
printSingleNum: ; print a single hex num
CMP AL, 0AH ; adjust AL according its value
JNL letter
ADD AL, 030H
JMP exit
letter:
SUB AL, 0AH
ADD AL, 'A'
exit:
MOV AH, 0EH ; show it
INT 10H
RET
startMsg DB "Start Load!", 0DH, 0AH
errorMsg DB "Load Error!", 0DH, 0AH
successMsg DB "Load Success!", 0DH, 0AH
DriverLetter DB 12H
TIMES 512-($-$$) DB 0 ; fill file
DW 0xAA55 ; end tag
网友评论