【问题标题】:What would cause a disk read error in Int 13h?什么会导致 Int 13h 中的磁盘读取错误?
【发布时间】: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,ax mov 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


【解决方案1】:

我在 Qemu 中运行您的代码时遇到了同样的问题,直到我将扇区负载计数减少到 1(从您的 5 个):

mov al, 0x01                    ; read 1 sector

由于您的映像只有一个额外的扇区,并且模拟器将映像视为整个磁盘,因此您只能读取一个扇区。通过此更改,您的代码“工作”(不打印错误消息)。

【讨论】:

  • 减少到 1 或增加磁盘映像以填充到 3072 就足够了。这就是为什么我在答案下的评论建议 times 5*256 dw 'D' 。但是超过磁盘映像的读取扇区数是他问题的真正原因。我是赞成票。
  • 我没有再收到错误消息,看来工作了,谢谢你们。
猜你喜欢
  • 2013-02-01
  • 2010-12-31
  • 2013-11-20
  • 2018-05-09
  • 2021-12-20
  • 1970-01-01
  • 2013-01-09
  • 2021-09-26
  • 2012-01-31
相关资源
最近更新 更多