我正在编写一个16位实模式汇编x86例程来读取磁盘,但它无法正常工作

问题描述 投票:0回答:1

我正在编写一个16位实模式Assembly x86例程来读取磁盘,但它无法正常工作。 它适用于我的操作系统,如果有帮助的话。

这是我的代码,你可以粘贴,用NASM编译并模拟:

mov bl, dl

mov ah, 0x2
mov al, 0xa
mov ch, 0
mov cl, 2
mov dh, 0
mov dl, bl

mov bx, 0x0
mov es, bx
mov bx, 0x7e00

int 0x13
jc __end

mov bx, 0x7e00

__loop:
    mov ah, 0x0e
    mov al, [bx]
    
    int 0x10
    
    cmp bx, 0x7e00+0xa
    je __end
    
    inc bx
    jmp __loop

__end:
    mov ah, 0x0e
    mov al, "!"
    int 0x10
    
    jmp $

    times 510 - ( $ - $$ ) db 0x0
    dw 0xaa55

times 2048 db 'A'

正如您在代码中看到的,我正在尝试读取 10 个扇区 (0xa)。为了测试这一点,我想打印出 0x7e00 处的骑行字节,并在最后打印一个感叹号

!
来注意函数的结束。在第一个测试中,它只给我写了几个空格和我的
!
。为了确定是否一切正常,我用
A
填充了 4 个部分。我重新尝试了,Bochs 只打印了几个
A
,所以
!
。输出适合在一行中,以便为您提供一个想法。所以它看起来不像是在读取 10 个扇区。

我错过了什么? 谢谢您的回答。

assembly x86 nasm x86-16 disk
1个回答
0
投票

字节的问题

输出内容在一行中,以便为您提供一个想法。所以看起来不像是读取10个扇区。

这个结论有点仓促。无论数据来自哪里,输出本身都可能出现错误。

确实是这样,但与迄今为止所有相关人员(包括您自己)所说的您打印了 10 个字符相反,我看到您的努力实际上是打印了 11 个字符!你说不重要?这是著名的一次性错误,任何编程人员都知道。

mov bx, 0x7e00
__loop:
  mov ah, 0x0e
  mov al, [bx]
  int 0x10
  cmp bx, 0x7e00+0xa
  je __end
  inc bx
  jmp __loop
__end:

当循环看到地址 0x7E0A 时,该特定地址处的字符已被打印。这确实是 0x7E00 .. 0x7E0A 范围内的第 11 个字节。 解决方案在于您放置

inc bx

指令的位置。如果你做得正确,你也将删除其中一个跳跃:

  mov  bx, 0x7E00
__loop:
  mov  al, [bx]
  mov  ah, 0x0E     ; BIOS.Teletype
  int  0x10
  inc  bx
  cmp  bx, 0x7E00 + 0x000A
  jb   __loop       ; For as long as we stay BELOW 0x7E0A
__end:

部门问题

既然一次性错误已经消失,打印整个扇区就变得轻而易举了。只需应用因子

512

(扇区的大小):

  mov  bx, 0x7E00
__loop:
  mov  al, [bx]
  mov  ah, 0x0E     ; BIOS.Teletype
  int  0x10
  inc  bx
  cmp  bx, 0x7E00 + 0x000A * 512
  jb   __loop       ; For as long as we stay BELOW 0x9200
__end:

    不要忘记初始化 DS,以便
  • mov al, [bx]

    指令正常工作:

    xor  bx, bx
    mov  ds, bx
    mov  es, bx
    mov  bx, 0x7E00
    int  0x13
    

    
        
© www.soinside.com 2019 - 2024. All rights reserved.