为什么将这些 0 字节跳转用作延迟?

逆向工程 拆卸 x86 BIOS
2021-06-13 21:06:50

我正在调试一个旧的 PC BIOS,看到很多我认为是延迟序列的东西,使用 0 字节跳转指令 ( EB 00= jmp short $+2)。

执行一些 I/O 和三个“毫无意义”的跳转

为什么会有这个特殊的指令?我猜它必须有一些理想的计时属性。

有问题的 CPU 是主频为 16MHz 的 386SX。

1个回答

这是泄露的 AWARD BIOS 源代码(文件COMMON.MAC)中的一个片段

SIODELAY    MACRO               ; SHORT IODELAY
        jmp short $+2
        ENDM

IODELAY     MACRO               ; NORMAL IODELAY
        siodelay
        siodelay
        ENDM

WAFORIO     MACRO               ; NORMAL IODELAY
        siodelay
        siodelay
        siodelay
        siodelay
        siodelay
        siodelay
        ENDM

NEWIODELAY      MACRO
        out 0ebh,al              
            ENDM  

很明显,这是专门作为 I/O 操作之后的延迟,大概是为了给潜在的缓慢硬件时间来处理来自 CPU 的请求。

我还在OS/2 编程常见问题解答中找到了这个

问题:我查看了 ddk\src\dev\mouse\bus.asm 中的一些代码,这些代码与中断控制器有关,它在 IN 和 OUT 指令之间调用 MyIODelay。我不清楚为什么需要这些。它说明了让总线赶上的事情 - 这是脑死硬件还是什么?

:你第一次是对的 - 脑死硬件。“某些”(不是全部)IO 设备不能:

  in al,dx
  or al,MASK
  out dx,al

由于 CPU 比 IO 外设快,因此公认的观点是,您应该在对同一 IO 设备的 IO 访问之间放置任意的小延迟。大多数人使用:

  in al,dx
  or al,MASK
     jmp next_instruction
next_instruction:
  out dx,al

跳转操作具有刷新 CPU 指令管道的额外“好处”,从而进一步减慢处理速度。

这不是您的代码片段中的模式,因此可能只是货物崇拜复制粘贴的一个实例。