0

我正在尝试在实模式下学习汇编。我想读取硬盘的引导扇区,所以下面是代码

org 100h

start:
xor ax, ax
mov es, ax    ; ES <- 0
mov cx, 1     ; cylinder 0, sector 1
mov dx, 0080h ; DH = 0 (head), drive = 80h (0th hard disk)
mov bx, buff ; segment offset of the buffer
mov ax, 0201h ; AH = 02 (disk read), AL = 01 (number of sectors to read)
int 13h

jnc .read

 .read:
  mov     ax, cs ; set up segments
  mov     ds, ax
  mov     es, ax
  mov     al, 03h
  mov     ah, 0
  int 10h

 mov     si, buff
 call    print_string

.done:
 jmp     .done


print_string:
lodsb        ; grab a byte from SI

test    al, al  ; logical or AL by itself
jz      .done   ; if the result is zero, get out

mov     ah, 0x0E
int 0x10      ; otherwise, print out the character!
jmp     print_string
.done:
 ret

buff dw 512

我的执行环境是DosBox0.70,exe文件是.COM。我希望在屏幕上看到 512 字节,但是当我运行我的 .COM 文件时,它只是空白屏幕。我可以看到它背后的几个原因

1)给出的代码没有从 Bios 中断正确返回(int 13h)。2)字符串应该以 null 终止,这不会发生在这里。

但不确定是否是上述原因导致它发生,如果是,我该如何应对这些问题?

4

2 回答 2

3

磁盘的引导扇区包含的不是 ASCII 数据,而是代码。很有可能,第一个字节将是 NULL 并且剩余的可能是不可打印的代码(例如 CR、LF 等)。

尝试通过打印 ascii 代码的 INT 10h 打印缓冲区并以 0 结尾可能会导致根本不显示任何内容。

您应该将缓冲区的每个字节转换为十六进制字符串,然后将这些字符串打印到显示器上。这样,您将获得引导扇区的简单十六进制转储。

于 2013-07-17T08:25:12.913 回答
1

Dos 将 .com 文件加载到它自己选择的某个段,并设置dses该段。您buff在该段中,而不是段 0!您正在读取第 0 段的第一个扇区,这可能会破坏您的 IVT。es独自离开。

读取一个扇区后,检查进位标志(指示错误),但检查.read它是否已设置。如果错误,您可能需要重置驱动器并再次尝试读取。您可能需要一个“重试计数器”,这样您就不会陷入无限循环。

buff不保留 512 个字节,而是保留两个值为 512 的字节。由于它位于文件的末尾,这可能不会造成任何伤害,但它不是“正确的”。

成功读取一个扇区后,您可以将其打印为 ascii 字符,但您希望打印所有 512 个字节,而不是在遇到的第一个 0 处停止。十六进制转储可能更具可读性。

如果您的 MBR 的第一个字节为零,那么我们就陷入了泥潭!有效引导扇区的第一个字节应该是 shortjmp后跟 anop或 near jmp。我们对以这种方式启动引导扇区有点随意,大多数 BIOS 不检查,但这就是“应该”存在的。如果 CPU 将 0 视为第一个字节,它会执行什么?(提示:这是一个add

我认为您的两个主要问题是设置es为零,如果遇到零则停止打印。再试一遍。FFS,在读取工作可靠之前,不要尝试向驱动器写入任何内容!

于 2013-07-17T12:04:43.317 回答