BIOS Int 13h 08 DBT 问题字节数每个扇区代码 returns 0xF0 而不是 0x00 - 0x04
BIOS Int 13h 08 DBT issue Bytes per sector code returns 0xF0 instead of 0x00 - 0x04
我正在使用 int 13h 08 加载磁盘参数,但从磁盘基数 table (dbt) 中得到了一个无效值。
有问题的值是 0xF0。
注意:dbt 在 es:di
中返回
对 int 13h 08 的引用:https://stanislavs.org/helppc/int_13-8.html
参考 dbt:https://stanislavs.org/helppc/dbt.html
回购 link:https://github.com/The3Null4Player613310/RealOS
有问题的代码:
disk_get_params: ; get primary disk params
push es
push es
mov dl, [addr_svs_pdv]
mov ah, 0x08
int 13h
push ds ; get dbt
push es
pop ds
mov si, di
pop ax ; set es
pop es
push ax
shr dx, 0x08 ; set total head count
inc dx
mov [addr_svs_thc], dx
call disk_get_sector ; set sectors per track
inc ax
mov [addr_svs_spt], ax
call disk_get_cylindar ; set tracks per head
mov [addr_svs_tph], ax
;add si, 0x03
xor ah, ah ; set bytes per sector
lodsb
lodsb
lodsb
lodsb
mov cx, ax
mov bx, 0x80
shl bx, cl
mov [addr_svs_bps], bx
pop ds
pop es
jmp disk_return
问题中的代码片段在使用段寄存器的方式上是错误的。不可能从中得出关于 F0 问题的任何结论。但是,您的 GitHub 存储库中的相同代码似乎没问题。
BIOS.ReturnDiskDriveParameters 函数 08h 只会 return 在 ES:DI
一个指向 DisketteParameterTable 的远指针,前提是您在 DL
中指定的驱动器号在条目中引用了一个软盘驱动器 (DL < 128
).
我看过你在 GitHub 上的项目,相信这里发生的是,这个 BIOS 函数既没有触及 ES
也没有触及 DI
,因为两者恰好包含0 在条目 (*) 上,后面的代码将使用 NULL-pointer。因此,像 mov cl, [es:di+3]
(或类似的)这样的指令将读取线性存储器的第 4 个字节,而恰好保存了 F0。 InterruptVectorTable 的第一个向量是 DivideException 并指向 BIOS 代码中的某处。典型值为 F000:EF6F (6F, EF, 00, F0).
(*) 在 GitHub 上的 boot.asm 中,您通过 DS
和 ES
段寄存器设置 push cs
push cs
pop es
pop ds
。这很危险!绝对不能保证 CS
段寄存器将根据您的 ORG 7C00h
指令保存您需要的 0。 BIOS 可以通过 CS:IP = 07C0h:0000h
访问您的引导加载程序。唯一有效的设置方法是:
xor ax, ax
mov ds, ax
mov es, ax
下一步做什么?
经常检查系统功能报告的状态。如果出现问题,BIOS.ReturnDiskDriveParameters 函数 08h 设置进位标志。不要忽略这种情况的检查!
存在一个更新的 BIOS 函数,它将专门报告硬盘驱动器的驱动器参数。
阅读 this wikipedia article.
中的 BIOS.GetDriveParameters 函数 48h
仅考虑 BytesPerSector = 512 将是一个非常安全的假设。许多人从未见过任何其他东西,对于业余爱好 OS 这可能是您需要的简化...
我正在使用 int 13h 08 加载磁盘参数,但从磁盘基数 table (dbt) 中得到了一个无效值。
有问题的值是 0xF0。
注意:dbt 在 es:di
对 int 13h 08 的引用:https://stanislavs.org/helppc/int_13-8.html
参考 dbt:https://stanislavs.org/helppc/dbt.html
回购 link:https://github.com/The3Null4Player613310/RealOS
有问题的代码:
disk_get_params: ; get primary disk params
push es
push es
mov dl, [addr_svs_pdv]
mov ah, 0x08
int 13h
push ds ; get dbt
push es
pop ds
mov si, di
pop ax ; set es
pop es
push ax
shr dx, 0x08 ; set total head count
inc dx
mov [addr_svs_thc], dx
call disk_get_sector ; set sectors per track
inc ax
mov [addr_svs_spt], ax
call disk_get_cylindar ; set tracks per head
mov [addr_svs_tph], ax
;add si, 0x03
xor ah, ah ; set bytes per sector
lodsb
lodsb
lodsb
lodsb
mov cx, ax
mov bx, 0x80
shl bx, cl
mov [addr_svs_bps], bx
pop ds
pop es
jmp disk_return
问题中的代码片段在使用段寄存器的方式上是错误的。不可能从中得出关于 F0 问题的任何结论。但是,您的 GitHub 存储库中的相同代码似乎没问题。
BIOS.ReturnDiskDriveParameters 函数 08h 只会 return 在 ES:DI
一个指向 DisketteParameterTable 的远指针,前提是您在 DL
中指定的驱动器号在条目中引用了一个软盘驱动器 (DL < 128
).
我看过你在 GitHub 上的项目,相信这里发生的是,这个 BIOS 函数既没有触及 ES
也没有触及 DI
,因为两者恰好包含0 在条目 (*) 上,后面的代码将使用 NULL-pointer。因此,像 mov cl, [es:di+3]
(或类似的)这样的指令将读取线性存储器的第 4 个字节,而恰好保存了 F0。 InterruptVectorTable 的第一个向量是 DivideException 并指向 BIOS 代码中的某处。典型值为 F000:EF6F (6F, EF, 00, F0).
(*) 在 GitHub 上的 boot.asm 中,您通过 DS
和 ES
段寄存器设置 push cs
push cs
pop es
pop ds
。这很危险!绝对不能保证 CS
段寄存器将根据您的 ORG 7C00h
指令保存您需要的 0。 BIOS 可以通过 CS:IP = 07C0h:0000h
访问您的引导加载程序。唯一有效的设置方法是:
xor ax, ax
mov ds, ax
mov es, ax
下一步做什么?
经常检查系统功能报告的状态。如果出现问题,BIOS.ReturnDiskDriveParameters 函数 08h 设置进位标志。不要忽略这种情况的检查!
存在一个更新的 BIOS 函数,它将专门报告硬盘驱动器的驱动器参数。
中的 BIOS.GetDriveParameters 函数 48h
阅读 this wikipedia article.仅考虑 BytesPerSector = 512 将是一个非常安全的假设。许多人从未见过任何其他东西,对于业余爱好 OS 这可能是您需要的简化...