2

I'm debugging an old PC BIOS and see a lot of what I assume are delay sequences, using 0-byte jump instructions (EB 00 = jmp short $+2).

perform some I/O and three "pointless" jumps

Why this particular instruction? I'm guessing it must have some desirable timing properties.

The CPU in question is a 386SX clocked at 16MHz.

3

Here's a fragment from the leaked AWARD BIOS source code (file 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  

So apparently this was intended specifically as a delay after I/O operations, presumably to give the potentially slow hardware time to process the request from the CPU.

I also found this in the OS/2 programming FAQ:

Question: I looked at some code in ddk\src\dev\mouse\bus.asm which diddles with the interrupt controller, and it calls MyIODelay in between IN and OUT instructions. I'm not clear why these are required. It says something about letting the bus catch up - is this brain dead hardware or what?

Answer: You were right first time - brain dead hardware. "Some" (not all) IO devices cannot do:

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

as the CPU is faster than the IO peripherals, received wisdom is that you should put an arbitrary small delay between IO access to the same IO device. And most people use:

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

The jump op has the additional "benefit" of flushing the CPUs instruction pipeline and thereby slowing down processing even more.

It's not quite the pattern in your snippet so could be just an instance of cargo-cult copypasting.

  • Cool, thanks, that helps. The part about flushing the pipeline actually confirms what I suspected. Though I still wonder how the proper reasoning would go, rather than "everybody does this and it seems to work". – pesco Aug 5 '18 at 21:56
  • 1
    you could try asking on retrocomputing, maybe people there know more about early hardware – Igor Skochinsky Aug 6 '18 at 15:47
  • I remember that I used to nop my way through and that worked fine for me. My only guess is that jmp flushes cache, plus, it takes many more clock ticks per bytes that just a single nop. They probably want to save ROM bytes yet still have lots of cycles spared. It only seems a mystery because you know there are better ways than jmp+$2 :) – gilm Aug 6 '18 at 16:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.