【发布时间】:2017-08-10 14:11:47
【问题描述】:
我一直在 NASM 中为一个函数编写一个测试程序,该函数使用int 13h 从引导磁盘读取扇区,除非每次我使用 sudo qemu-system-i386 load_disk.bin 它给了我这个输出:
磁盘读取错误!磁盘读取错误! 磁盘读取错误!* 磁盘读取错误!* 磁盘读取错误!*
如果设置了进位标志 (CF),这是预期的。几天来我一直在寻找这个问题的答案并尝试了许多不同的解决方案(在jc test 之后跳转到ES:BX,将启动驱动器保存在DL...)但似乎没有任何效果。
这是我的程序:
[bits 16] ;real mode
[org 0x7c00]
mov [DISK], dl ;save boot drive value
xor ax, ax ;setting up stack
cli
mov ss, ax
mov sp, 0x7c00
sti
mov di, 5 ` ;counter for number of tries
read_disk:
mov ah, 0x00 ;resetting disk
int 0x13
mov bx, 0x9000 ;data buffer
mov es, bx
mov bx ,0x0000
mov ah, 0x02 ; function number 2 of int 13h
mov al, 0x05 ; read 5 sectors
mov ch, 0x00 ; cylinder 0
mov cl, 0x02 ; sector 2 (1 is boot sector)
mov dh, 0x00 ; head 1
mov dl, [DISK] ; give dl value
int 0x13 ; call interrupt
jc disk_error ;if carry flag is set
jmp 9000h:0000h
mov bx, [0x9000+512] ;print bytes as if they were strings
call print_string
print_string: ; print_string function
push bx
push ax
loop_one:
mov ah, 0x0e
mov al, [bx]
int 0x10
cmp al, 0
je end
inc bx
jmp loop_one
end:
pop ax
pop bx
ret
disk_error:
cmp di, 0 ; if number of tries=0 jump to loop
je loop
push bx ;print out the error message
mov bx, MSG
call print_string
pop bx
dec di ;decrementing di
jmp read_disk
loop:
jmp $
MSG:
db 'disk read error!', 0
DISK:
db 0
times 510-($-$$) db 0 ; boot sector padding and BIOS trigger
dw 0xaa55
times 256 dw 'D' ; sectors supposed to be read
感谢您考虑这个问题。我真的已经有一段时间了。
【问题讨论】:
-
您创建的图像文件有多大?您尝试读取 5 个扇区加上第一个 512 字节的引导扇区,因此您至少需要一个 6*512 = 3072 字节的磁盘映像。在某些模拟器上,如果您读取超出磁盘映像的边缘,则会出错。这里只是猜测。您确实应该将 DS 设置为零,因为您使用的是
org 0x7c00,因为不能保证 DS 将设置为零。因此,在保存磁盘号之前,在顶部执行xor ax,axmov ds, ax,将times 256 dw 'D'更改为times 5*256 dw 'D'应该会给你一个 3072 字节的图像。 -
在
INT 13h, 2之后磁盘状态为AH- 该值可能提供诊断线索 - 毕竟这就是它的用途!您至少应该在错误消息中输出它。 stanislavs.org/helppc/int_13-1.html -
来自@MichaelPetch 的好提示。另外,AH 中的返回码和 AL 中的读取扇区数是多少?
-
无法理解这种纠结的意大利面。您应该学会在适当的情况下使用
call而不是jmp。 -
我以为我的显示器脏了,但事实证明在
mov di, 5指令和它右边的注释之间有一个杂散的反引号。那么,这段代码真的会汇编吗?
标签: assembly nasm x86-16 bootloader bios