2

问题是:我需要从 BIOS 内存中获取“计算机”类型。我知道,我可以在 fasm 中这样做(我的程序和所有段都是 16 位):

mov al, [0xF000FFFE]

但这会返回零,这是不对的,因为 turbo c++ 3.1 中的等效代码

UCHAR pcType = *((UCHAR*)0xF000FFFE);

使用 LARGE 模型(在代码生成设置中)时,返回我计算机的正确“类型” 。那么如何在 fasm 中修复它?(例如我知道,masm 有 .model 指令,但 fasm 中没有这样的东西)。请帮忙...

4

2 回答 2

2

Turbo-C 正在执行从地址 0xF000FFFE 读取的指令。段是地址的高 16 位,偏移量是地址的低 16 位。在大内存模型中,指针 0xF000FFFE 指向段 0xF000,偏移量 = 0xFFFE。实模式段:偏移(逻辑)地址通过计算转换为物理地址(segment<<4)+offset,在这种情况下是物理地址 (0xF000<<4)+0xFFFE = 0xFFFFE,它是内存的 1MiB 标记以下的倒数第二个字节在系统 ID 字节所在的 ROM BIOS 中。

您将需要创建等效的 FASM 代码以将段寄存器之一设置为 0xF000,然后检索偏移量 0xFFFE 处的值。以下代码只是通过Int 21h/AH=4Ch返回的错误级别(代码)将系统 ID 返回给 DOS 。返回值在AL中:

format mz                      ; Create a DOS EXE program

    mov ax, 0xf000
    mov es, ax                 ; ES = 0xf000
    mov al, [es:0xfffe]        ; Read byte at 0xF000:0xFFFE

    mov ah, 4Ch                ; DOS Exit and Return with error code function
    int 21h                    ; Exit and return System ID in AL
于 2019-08-29T22:41:23.490 回答
1

它在 Turbo C 中工作,因为它将 32 位值解释为段:偏移量对而不是平面指针。如果要使用平面指针,则应使用地址 0xFFFFFFFE(如果 BIOS 未禁用闪存映射),或 0xFFFFE,即与指针 F000:FFFE 对应的线性内存地址。这两个都只在虚幻模式下工作,因为它们使用大于 64K 的偏移量,这在纯实模式下是不可能的。最简单的可能是使用普通的 16 位段:偏移地址,就像您在评论中提到的那样,因为这将始终有效。

于 2013-02-18T15:52:43.637 回答