INT 13h AH=2h throws the error AH=9h, but the offset is 0

2026-06-15

Stack Overflow: View Question

Tags: assembly, x86, x86-16, bios

Score: 1 | Views: 134

The asker has two seemingly equivalent calls to INT 13h (BIOS disk service, AH=2 = read sectors). Both target offset 0 in a segment, but only the second fails with AH=09h. The difference is the destination segment: ES=0x1000 works, ES=0x1ff0 fails — even though the offset is the same and only one sector (512 bytes) is being read.

Why this is interesting: the error code is the giveaway, but it's only obvious if you know your legacy hardware. AH=09h from INT 13h is "DMA boundary error: attempt to DMA across 64K boundary". This isn't a BIOS quirk — it's a hardware limitation of the original IBM PC's Intel 8237 DMA controller, which uses a 16-bit address register plus a separate 8-bit page register. The controller can't increment from 0xFFFF to 0x10000; it would just wrap inside the current 64KB page.

The arithmetic:

The DMA controller physically cannot do that transfer, so the BIOS floppy driver returns AH=09h before touching the disk.

Can you read to physical 0x20000? Yes — but the buffer has to be entirely within a single 64KB-aligned page. Pick an ES:BX whose linear address starts at 0x20000 (or any address such that start and start+count−1 share the same top 8 bits of the 20-bit physical address). Examples that work:

Gotchas:

The challenge: Recognizing that a BIOS error code is really an artifact of 1981-era 8237 DMA hardware that still constrains buffer placement four decades later.

All newsletters