【发布时间】:2016-11-03 18:42:07
【问题描述】:
我正在大学学习装配。我正在尝试编写个人格式例程,但遇到了一些问题。该例程在启动时启动,但在第一次中断 (INT 13h/AH=7) 后进入错误流。打印AH status 值表明错误是:
检测到0Eh控制数据地址标记(硬盘)
这是我的引导加载程序代码:
[BITS 16]
[ORG 0x7C00]
init:
call main
ret
main:
xor ax, ax
mov ds, ax
mov si, string0
call print
call delay
mov si, string1
call print
call delay
mov si, string2
call print
call delay
mov si, string3
call print
call delay
mov si, string4
call print
call delay
mov si, string5
call print
call delay
mov si, string6
call print
call delay
mov si, string7
call print
call delay
mov si, string8
call print
call delay
mov si, string9
call print
call delay
mov si, string10
call print
call delay
mov si, string11
call print
call delay
mov si, string12
call print
call delay
mov si, string13
call print
call delay
mov si, string14
call print
call delay
mov si, string15
call print
call delay
mov si, string16
call print
call delay
mov si, string17
call print
call delay
mov si, string18
call print
call delay
mov si, string19
call print
call delay
mov si, string20
call print
call delay
mov si, string21
call print
call delay
mov si, string22
call print
call delay
mov si, string23
call print
call delay
mov si, string24
call print
call delay
mov si,string25
call print
call delay
call read_and_print
cmp al,'A'
jne error
call read_and_print
cmp al,'P'
jne error
call read_and_print
cmp al,'O'
jne error
call read_and_print
cmp al,'C'
jne error
call read_and_print
cmp al,'A'
jne error
call read_and_print
cmp al,'L'
jne error
call read_and_print
cmp al,'Y'
jne error
call read_and_print
cmp al,'P'
jne error
call read_and_print
cmp al,'S'
jne error
call read_and_print
cmp al,'E'
jne error
mov si,String27
call print
call menu
mov si,String35
call print
jmp $
menu:
mov si,String30
call print
call only_read
cmp al, 'A'
je zero_routine
cmp al, 'B'
je exit_routine
jmp menu
exit_routine:
mov si, String29
call print
ret
zero_routine: ;Command Shell;
mov si,String31
call print
call only_read
cmp al, 'A'
je A_Command
cmp al, 'B'
je B_Command
cmp al, 'C'
je exit_routine
A_Command:
xor eax,eax
mov ah,0x00 ; Reset the disk ;
mov dl, 0x80; First Disk ;
int 13h
mov ah,0x01 ; Get Disk Status ;
mov dl, 0x80; First Disk ;
int 13h
cmp ah, 0x00
jne f_error
mov si,String36
call print
;;;;;;;;;;;;;;;;;;;;;
; AH 07h ;
; AL Interleave ;
; CH Track ;
; CL Sector ;
; DH Head ;
; DL Drive ;
;;;;;;;;;;;;;;;;;;;;;
mov ah, 0x07
mov al, 0x00
mov ch, 0x00
mov dl, 0x80
mov dh, 0x00
call format
jmp zero_routine
B_Command:
xor eax,eax
mov ah,0x00 ; Reset the disk ;
mov dl, 0x81; Second Disk ;
int 13h
mov ah,0x01 ; Get Disk Status ;
mov dl, 0x81; Second Disk ;
int 13h
cmp ah, 0x00
jne f_error
mov si,String36
call print
;;;;;;;;;;;;;;;;;;;;;
; AH 07h ;
; AL Interleave ;
; CH Track ;
; CL Sector ;
; DH Head ;
; DL Drive ;
;;;;;;;;;;;;;;;;;;;;;
mov ah, 0x07
mov al, 0x00
mov cl, 0x00
mov ch, 0x00
mov dl, 0x81
mov dh, 0x00
call format
jmp zero_routine
format:
mov si, String32
call print
int 13h ; Format Drive ;
cmp ah, 0x00
jne f_error
mov si, String33
call print
ret
f_error:
mov si, String34
call print
xor al,al
add al,ah
mov ah, 0Ah ; Write Character
mov bh, 00h ; Page = 0
mov cx, 01h ; Times = 1
int 10h
jmp $
error:
mov si,String26
call print
jmp $
print:
mov bl,0x0A
mov ah, 0x0E
mov bh, 0x00
nextchar:
lodsb
or al, al
jz return
int 0x10
jmp nextchar
return:
ret
delay:
mov ah, 86h
mov cx, 0x00
mov dx, 0x8000
int 15h
ret
only_read:
mov ah, 00h ; Read Character
int 16h
ret
read_and_print:
mov ah, 00h ; Read Character
int 16h
push ax ; Save the current character
mov ah, 0Ah ; Write Character
mov bh, 00h ; Page = 0
mov cx, 01h ; Times = 1
int 10h
cursor_forward:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;AX = 0, CH = Start scan line, CL = End scan line, DH = Row, DL = Column;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mov ah, 03h ; Read cursor position
mov bh, 00h ; Page = 0;
int 10h
mov ah,02h ; Set Cursor Position
mov bh,00h ; Page = 0
add dl,01h ; Column++
int 10h
pop ax
ret
string0 db "MEMORY Check 0401B + 204R81B OK",`\n`,`\r`,0
string1 db "JA Hi-SYS BOOT!",`\n`,`\r`,0
string2 db "Copyright (C) 2014,2015",`\n`,`\r`,0
string3 db "CO-CPU Check 256seg OK",`\n`,`\r`,0
string4 db "I/O VECTORS Check OK",`\n`,`\r`,0
string5 db "ROOTING TABLES Check OK",`\n`,`\r`,0
string6 db "STATUS ANALYZER Check SLAVE OK",`\n`,`\r`,0
string7 db "VIRUS PROTECTION Check GREEN OK",`\n`,`\r`,0
string8 db "----- SYSTEM CONFIGURATION -----",`\n`,`\r`,0
string9 db "addr PSP blks size owner/parameters",`\n`,`\r`,0
string10 db "---- ---- ---- ------- ----------------------",`\n`,`\r`,0
string11 db "D0E0 sys 1 5296 kozaic",`\n`,`\r`,0
string12 db "D22C sys 1 2416 ersdrv",`\n`,`\r`,0
string13 db "D2C4 2081 1 16384 smalldrv",`\n`,`\r`,0
string14 db "D6C5-DBFE 1 21392 <free>",`\n`,`\r`,0
string15 db "DE02-E000 1 8160 <free>",`\n`,`\r`,0
string16 db "--- UMB total: 53 TB ---",`\n`,`\r`,0
string17 db "0586 sys 1 2144 shimem",`\n`,`\r`,0
string18 db "060D sys 1 3968 hemm386",`\n`,`\r`,0
string19 db "0706 sys 1 3312 smalldrv",`\n`,`\r`,0
string20 db "07ED sys 1 13568 adam8b CON",`\n`,`\r`,0
string21 db "0C18 sys 4 65424 <config>",`\n`,`\r`,0
string22 db "1CD6 <-- 1 15008 share 7L:500",`\n`,`\r`,0
string23 db "2081 <-- 1 13712 smalldrv",`\n`,`\r`,0
string24 db "23DB-9FFF 1 508464 <free>",`\n`,`\n`,`\r`,0
string25 db "---- Insert Password ----",`\n`,`\r`,0
String26 db " ---- Error... Please Reboot----",`\n`,`\r`,0
String27 db " ---- OK ----",`\n`,`\r`,0
String28 db "---- Error... No Such Subroutine ----",`\n`,`\r`,0
String29 db `\n`,`\r`,"---- Exiting----",`\n`,`\r`,0
String30 db "---- Menu: A = Command Shell, B = Exit ----",0
String31 db `\n`,`\r`,"---- Menu: A = Format Disk 1, B = Format Disk 2, C = Exit ----",0
String32 db `\n`,`\r`,"---- Formatting Disk - Please Wait... ---- ",`\n`,`\r`,0
String33 db "---- Disk Formatted ----",`\n`,`\r`,0
String34 db `\n`,`\r`,"---- Error While Formatting ---- ",0
String35 db "---- You Can Now Reboot Your Computer ---- ",0
String36 db `\n`,`\n`,`\r`,"---- Disk Resetted ----",`\n`,`\r`,0
【问题讨论】:
-
您能否发布完整的代码以便我们运行和调试它?我认为您的错误可能在您的实模式输入中。但从您提供的样品中无法判断。另外,请告诉我们您正在使用什么平台,以及您使用的汇编程序。
-
编辑:发布了完整的代码 :) 我使用 NASM 在 Windows 上工作 :) 谢谢你的帮助 :)
-
首先,您在初始引导扇区中存储了大量信息。您的第一个引导扇区限制为 512 字节。 - 其次,引导扇区应该正好是 512 并以 AA55 结尾。您可以通过以下方式结束代码来实现此目的: times 510-($-$$) db 0 ; dw 0xAA55
-
@slowvomit 实际上,El Torito CD-ROM 引导规范在使用“无仿真”引导时确实允许引导加载程序的长度超过一个(512 字节)扇区。事实上,它们通常有 4 个扇区长,因为这与物理 CD-ROM 扇区(2048 字节)的大小相同。如果长度不是 2048 字节物理扇区大小的倍数,某些 BIOS 显然会遇到问题。
-
您还需要显示用于制作可启动映像的命令,并描述启动它所采取的步骤。
标签: assembly x86 x86-16 bootloader bios