Assembly 什么会导致Int 13h中的磁盘读取错误?
我一直在用NASM为一个函数编写一个测试程序,该函数使用Assembly 什么会导致Int 13h中的磁盘读取错误?,assembly,nasm,x86-16,bootloader,bios,Assembly,Nasm,X86 16,Bootloader,Bios,我一直在用NASM为一个函数编写一个测试程序,该函数使用int 13h从引导磁盘读取扇区,但每次使用sudo qemu-system-i386 load_disk.bin运行汇编程序时,它都会给我以下输出: 磁盘读取错误!磁盘读取错误!磁盘读取错误!*磁盘读取错误!*磁盘读取错误!* 如果设置进位标志(CF),则为预期值。几天来我一直在寻找这个问题的答案,并尝试了许多不同的解决方案(在jc测试之后跳到ES:BX,在DL中保存引导驱动器),但似乎没有任何效果。 这是我的节目: [bits 16]
int 13h
从引导磁盘读取扇区,但每次使用sudo qemu-system-i386 load_disk.bin运行汇编程序时,它都会给我以下输出:
磁盘读取错误!磁盘读取错误!磁盘读取错误!*磁盘读取错误!*磁盘读取错误!*
如果设置进位标志(CF),则为预期值。几天来我一直在寻找这个问题的答案,并尝试了许多不同的解决方案(在jc测试之后跳到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
谢谢你考虑这个问题。我已经做了一段时间了。在Qemu中运行您的代码时,我遇到了同样的问题,直到我将扇区负载计数减少到1(从您的5个):
由于映像只有一个附加扇区,并且仿真器将映像视为整个磁盘,因此只能读取一个扇区。通过此更改,您的代码“工作”(不打印错误消息)。创建的图像文件有多大?您尝试读取5个扇区加上第一个512字节的引导扇区,因此至少需要一个6*512=3072字节的磁盘映像。在某些模拟器上,如果读取的内容超出磁盘映像的边缘,则会出错。我猜一下。由于您使用的是org 0x7c00
,因此确实应该将DS设置为零,因为不能保证DS将被设置为零。因此,在顶部执行一个xor ax,ax
mov ds,ax
在保存磁盘号之前,将乘以256 dw'D'
更改为乘以5*256 dw'D'
这应该给您3072字节的imae。在INT 13h之后,2
磁盘状态为AH
-该值可能提供诊断线索-毕竟这就是它的用途!您至少应该在错误消息中输出该信息。@MichaelPetch的好提示。另外,AH中的返回码和AL中的读取扇区数是多少?不可能理解这个混乱的意大利面。你应该学会在适当的地方使用call
而不是jmp
。我原以为我的显示器脏了,但结果是mov di,5
指令和它右边的注释之间有一个错误的反勾号。那么,这段代码真的汇编了吗?减少到1或增加磁盘映像以填充到3072就足够了。这就是为什么我在回答下的评论建议乘以5*256 dw'D'
。但读取的扇区数超过了磁盘映像,这才是他出现问题的真正原因。我是投票人。我再也没有收到错误信息了,似乎有效。谢谢你们。
mov al, 0x01 ; read 1 sector