我正在编写一个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 个扇区。
我错过了什么? 谢谢您的回答。
输出内容在一行中,以便为您提供一个想法。所以看起来不像是读取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:
mov al, [bx]
指令正常工作:
xor bx, bx
mov ds, bx
mov es, bx
mov bx, 0x7E00
int 0x13