Skip to content

Instantly share code, notes, and snippets.

@BebeSparkelSparkel
Last active December 20, 2025 22:51
Show Gist options
  • Select an option

  • Save BebeSparkelSparkel/fa582e2fa2381f81b324baf75f211a6f to your computer and use it in GitHub Desktop.

Select an option

Save BebeSparkelSparkel/fa582e2fa2381f81b324baf75f211a6f to your computer and use it in GitHub Desktop.
x86 Real Mode Memory Map Cheat Sheet

x86 Real Mode Memory Map Cheat Sheet

Summary Memory Map (0x00000 - 0xFFFFF)

Address Range Size Type Purpose
0x00000 - 0x003FF 1 KB IVT Interrupt Vector Table (256 vectors)
0x00400 - 0x004FF 256 B BDA BIOS Data Area (hardware config, EBDA pointer)
0x00500 - 0x007FF 768 B Mixed DOS/BIOS communication (often free pre-DOS)
0x00800 - 0x07BFF 30,208 B Free Conventional memory (stack, bootloader data)
0x07C00 - 0x07DFF 512 B MBR Boot sector (code + partition table)
0x07E00 - 0x7FFFF 491,520 B Free Conventional memory (stage 2, kernel, DOS)
0x80000 - 0x9FFFF 128 KB Mixed EBDA (if present) or free conventional memory
0xA0000 - 0xBFFFF 128 KB VRAM Video memory (graphics/text buffers)
0xC0000 - 0xFFFFF 256 KB ROM BIOS and option ROMs (read-only)

Useful Memory Regions for Boot Code

Safe Stack Locations

Address Stack Space Grows Into Best For Notes
0x7BFF ~30 KB 0x00500 - 0x07BFF (free memory) MBR/Stage 1 bootloaders Just below MBR; simple and safe for minimal stack usage
0x9000 ~33 KB 0x07E00 - 0x9000 (free memory) Stage 2 bootloaders More space; standard convention; check EBDA location first

Verifying EBDA location (to ensure 0x9000 is safe):

MOV AX, [0x040E]  ; Read EBDA segment from BDA (at 0x40E, not 0x408!)
SHL AX, 4         ; Convert to physical address
CMP AX, 0x9000    ; Is EBDA above 0x9000?
JA .safe          ; Yes, 0x9000 is safe
; Otherwise use 0x7BFF or another location
.safe:
MOV SP, 0x9000

Memory Regions for Bootloader Use

Address Range Size Purpose Safety Notes
0x00500 - 0x007FF 768 B Temp data, small buffers Often free pre-DOS; safe for temporary storage
0x00800 - 0x07BFF 30,208 B Stack (if SP=0x7BFF), temp data Free conventional memory; ideal for stage 1
0x07C00 - 0x07DFF 512 B MBR code (loaded by BIOS) Contains your bootloader; do not overwrite
0x07E00 - 0x0FFFF 33,280 B Stage 2 bootloader, kernel loading Directly after MBR; excellent for stage 2 code
0x10000 - 0x7FFFF 458,752 B Kernel, large stage 2 bootloaders Large free region; DOS programs load here

Critical Regions to Avoid

Address Range Purpose Why to Avoid
0x00000 - 0x003FF Interrupt Vector Table (IVT) Critical for BIOS interrupts; corruption causes system failure
0x00400 - 0x004FF BIOS Data Area (BDA) Contains BIOS variables; corruption breaks hardware access
0xA0000 - 0xBFFFF Video RAM (VRAM) Memory-mapped I/O; writing here affects display, not general memory
0xC0000 - 0xFFFFF BIOS/Option ROMs Read-only firmware; cannot be used for writable memory

MBR Layout (0x07C00 - 0x07DFF)

Offset from 0x7C00 Size Purpose
0x000 - 0x1BD 446 bytes Bootloader code
0x1BE - 0x1CD 16 bytes Partition entry 1
0x1CE - 0x1DD 16 bytes Partition entry 2
0x1DE - 0x1ED 16 bytes Partition entry 3
0x1EE - 0x1FD 16 bytes Partition entry 4
0x1FE - 0x1FF 2 bytes Boot signature (0x55AA in little-endian)

Typical Bootloader Memory Usage

Stack (grows down from 0x7BFF or 0x9000)
         
    [Free Memory]
         
Stage 2 Code/Data (0x07E00+)
    [MBR Code] (0x7C00 - 0x7DFF)
    [Free Memory] (0x00500 - 0x07BFF)
    [BDA] (0x00400 - 0x004FF)
    [IVT] (0x00000 - 0x003FF)

Detailed Memory Map

0x00000 - 0x003FF (1 KB): Real Mode Interrupt Vector Table (IVT)

The IVT contains 256 interrupt vectors (4 bytes each: 2-byte offset + 2-byte segment).

Address Range Vector(s) Purpose
0x00000 - 0x00003 INT 0x00 Divide by zero exception
0x00004 - 0x00007 INT 0x01 Single-step interrupt (debugging)
0x00008 - 0x0000B INT 0x02 Non-maskable interrupt (NMI)
0x0000C - 0x0000F INT 0x03 Breakpoint (INT 3)
0x00010 - 0x00013 INT 0x04 Overflow (INTO instruction)
0x00014 - 0x00017 INT 0x05 BOUND range exceeded / Print screen
0x00018 - 0x0001B INT 0x06 Invalid opcode
0x0001C - 0x0001F INT 0x07 Coprocessor not available
0x00020 - 0x0003F INT 0x08-0x0F Hardware interrupts (PIC)
INT 0x08 System timer (IRQ 0)
INT 0x09 Keyboard (IRQ 1)
INT 0x0E Floppy disk controller (IRQ 6)
INT 0x0F Parallel port (IRQ 7)
0x00040 - 0x0007F INT 0x10-0x1F BIOS services
INT 0x10 Video services
INT 0x11 Equipment check
INT 0x12 Memory size
INT 0x13 Disk services
INT 0x14 Serial port services
INT 0x15 System services / Extended memory
INT 0x16 Keyboard services
INT 0x17 Printer services
INT 0x18 Boot failure / ROM BASIC
INT 0x19 Bootstrap loader
INT 0x1A Real-time clock / time services
INT 0x1B Ctrl+Break handler
INT 0x1C User timer tick
INT 0x1D Pointer to video parameter table
INT 0x1E Pointer to disk parameter table
INT 0x1F Pointer to graphics character table (8x8 font)
0x00080 - 0x000FF INT 0x20-0x3F DOS services (if DOS loaded)
INT 0x20 Program terminate
INT 0x21 DOS services (file I/O, etc.)
INT 0x22-0x2F DOS internals and TSRs
0x00100 - 0x003FF INT 0x40-0xFF User interrupts / free (often unused or for applications)

0x00400 - 0x004FF (256 bytes): BIOS Data Area (BDA) - CORRECTED

The BDA contains BIOS variables used during boot and runtime. Key entries:

Address Size Purpose
0x00400 - 0x00407 8 bytes COM1-COM4 port addresses (2 bytes each: COM1 typically 0x3F8, COM2 0x2F8, etc.)
0x00408 - 0x0040D 6 bytes LPT1-LPT3 printer port addresses (2 bytes each: LPT1 typically 0x378, etc.)
0x0040E - 0x0040F 2 bytes EBDA segment address (extended BIOS data area base) ** CRITICAL for stack safety!**
0x00410 - 0x00411 2 bytes Equipment list (bit flags from INT 0x11: floppies, video, math coprocessor, etc.)
0x00412 1 byte Initialization flag / Manufacturing test
0x00413 - 0x00414 2 bytes Base memory size in KB (typically 640; from INT 0x12)
0x00415 - 0x00416 2 bytes Extended memory / Manufacturing scratch
0x00417 1 byte Keyboard shift flags byte 1 (Right Shift, Left Shift, Ctrl, Alt, Scroll Lock, Num Lock, Caps Lock, Insert)
0x00418 1 byte Keyboard shift flags byte 2 (Left Ctrl, Left Alt, SysRq pressed, Pause active, etc.)
0x00419 1 byte Alternate keypad entry storage
0x0041A - 0x0041B 2 bytes Keyboard buffer head pointer (offset into buffer at 0x41E)
0x0041C - 0x0041D 2 bytes Keyboard buffer tail pointer (offset into buffer at 0x41E)
0x0041E - 0x0043D 32 bytes Keyboard buffer (16 entries × 2 bytes: scan code + ASCII; circular buffer)
0x0043E 1 byte Floppy disk drive calibration status
0x0043F 1 byte Floppy disk motor status
0x00440 1 byte Floppy disk motor timeout counter
0x00441 1 byte Floppy disk last operation status
0x00442 - 0x00448 7 bytes Floppy disk controller status bytes
0x00449 1 byte Current video mode
0x0044A - 0x0044B 2 bytes Number of columns in text mode
0x0044C - 0x0044D 2 bytes Video page size in bytes (regen buffer size)
0x0044E - 0x0044F 2 bytes Current video page offset (start address)
0x00450 - 0x0045F 16 bytes Cursor positions for 8 video pages (2 bytes per page: column, row)
0x00460 - 0x00461 2 bytes Cursor shape (start/end scan lines)
0x00462 1 byte Active video page number
0x00463 - 0x00464 2 bytes Video controller I/O port base (0x3D4 for CGA, 0x3B4 for MDA)
0x00465 1 byte Video mode register current setting
0x00466 1 byte CGA color palette
0x00467 - 0x0046B 5 bytes Cassette data / POST work area
0x0046C - 0x0046F 4 bytes Timer ticks since midnight (updated by INT 0x08, ~18.2065 Hz)
0x00470 1 byte Timer overflow flag (24-hour day rollover)
0x00471 1 byte Ctrl+Break flag
0x00472 - 0x00473 2 bytes POST reset flag (0x1234 = warm boot/skip memory test, 0x0000 = cold boot)
0x00474 1 byte Hard disk last operation status
0x00475 1 byte Number of hard disks detected
0x00476 1 byte Hard disk control byte
0x00477 1 byte Hard disk I/O port offset
0x00478 - 0x0047B 4 bytes LPT1-LPT4 timeout counters (1 byte each)
0x0047C - 0x0047F 4 bytes COM1-COM4 timeout counters (1 byte each)
0x00480 - 0x00481 2 bytes Keyboard buffer start offset (typically 0x001E)
0x00482 - 0x00483 2 bytes Keyboard buffer end offset (typically 0x003E)
0x00484 1 byte Video rows minus 1 (EGA/VGA: typically 24 for 25 rows)
0x00485 - 0x00486 2 bytes Character height in scan lines (VGA: 16 for 9x16 font)
0x00487 1 byte Video display data area (VGA mode control)
0x00488 1 byte Video display data area (VGA switches)
0x00489 1 byte Video display combination code
0x0048A 1 byte Last diskette data rate selected
0x0048B 1 byte Hard disk status register
0x0048C 1 byte Hard disk error register
0x0048D 1 byte Hard disk interrupt control flag
0x0048E 1 byte Combination hard disk/floppy card control
0x0048F - 0x00493 5 bytes Floppy disk controller information
0x00494 1 byte Keyboard mode state and type flags
0x00495 1 byte Keyboard LED flags
0x00496 - 0x00497 2 bytes Offset to user wait flag pointer
0x00498 - 0x0049B 4 bytes User wait timeout value
0x0049C - 0x0049D 2 bytes RTC wait flag
0x0049E - 0x004A7 10 bytes Network adapter data area
0x004A8 - 0x004FF 88 bytes Extended keyboard/video/miscellaneous BIOS data

Key takeaway: Address 0x0040E (not 0x00408!) holds the EBDA segmentcritical for determining safe stack locations!

0x00500 - 0x007FF (768 bytes): DOS/BIOS Communication Area

This area is used by DOS (if loaded) and some BIOS implementations:

Address Range Purpose
0x00500 - 0x005FF Print screen status, DOS kernel data (if DOS loaded)
0x00600 - 0x007FF Often free or used for temporary data by bootloaders

Note: In many systems, 0x00500 - 0x007FF is effectively free during early boot (before DOS loads).

0x00800 - 0x07BFF (30,208 bytes): Free Conventional Memory

This is general-purpose free memory in most systems:

  • Safe for bootloader stack, temporary data, or stage 2 code.
  • 0x7BFF is at the top of this region, making it ideal for a stack base.

0x07C00 - 0x07DFF (512 bytes): MBR Boot Sector

  • Loaded by BIOS from the first sector of the boot device.
  • Contains bootloader code + partition table + signature (0xAA55).

Layout:

Offset Size Purpose
0x000 - 0x1BD 446 bytes Bootloader code
0x1BE - 0x1FD 64 bytes Partition table (4 entries × 16 bytes)
0x1FE - 0x1FF 2 bytes Boot signature (0x55AA in little-endian)

0x07E00 - 0x7FFFF (491,520 bytes): Free Conventional Memory

This is the largest free region in real mode:

Subdivisions Purpose
0x07E00 - 0x0FFFF Often used for stage 2 bootloader or kernel loading (33,280 bytes)
0x10000 - 0x7FFFF Conventional memory (DOS loads here; OS kernels often loaded here) (458,752 bytes)

Key points:

  • 0x9000 is in this regionsafe for a larger stack.
  • DOS traditionally uses 0x10000 - 0x9FFFF for programs.

0x80000 - 0x9FFFF (128 KB): Extended BIOS Data Area (EBDA) / Upper Conventional Memory

This region's usage varies by BIOS:

Scenario Address Range Purpose
EBDA present 0x9FC00 - 0x9FFFF (typical 1 KB) Extended BIOS data (typically 1-18 KB; varies by system)
No EBDA 0x80000 - 0x9FFFF Free conventional memory (rare on post-1980s systems)

How to detect EBDA:

MOV AX, [0x040E]  ; Read EBDA segment from BDA (correct offset!)
SHL AX, 4         ; Convert to physical address (AX = EBDA base)

Typical EBDA contents:

  • Additional BIOS variables (e.g., ACPI tables, disk parameters).
  • PnP BIOS structures.
  • Runtime data for BIOS interrupts.
  • On PS/2 systems, EBDA is always present (typically 1 KB starting at 0x9FC00).

0xA0000 - 0xBFFFF (128 KB): Video RAM (VGA Memory-Mapped I/O)

This region is reserved for video hardware:

Address Range Mode Purpose
0xA0000 - 0xAFFFF EGA/VGA graphics 64 KB graphics buffer (planar modes)
0xB0000 - 0xB7FFF Monochrome text 32 KB text buffer (MDA, Hercules)
0xB8000 - 0xBFFFF Color text 32 KB text buffer (CGA, VGA text mode)

Example: In 80×25 text mode, 0xB8000 is the start of the screen buffer (2 bytes per character: ASCII + attribute).

** Do NOT use for stack or general memory!**

0xC0000 - 0xFFFFF (256 KB): BIOS ROM and Option ROMs

This region contains read-only firmware:

Address Range Purpose
0xC0000 - 0xC7FFF VGA BIOS ROM (32 KB typical)
0xC8000 - 0xEFFFF Other option ROMs (network cards, SCSI controllers, etc.)
0xF0000 - 0xFFFFF System BIOS ROM (64 KB)
0xFFFF0 - 0xFFFFF BIOS entry point (16 bytes, includes reset vector at 0xFFFF0)

Reset vector (at power-on):

  • CPU starts at CS:IP = 0xF000:0xFFF0 (physical 0xFFFF0).
  • First instruction is typically a far jump to the main BIOS code.

Notes and Disclaimers

  • This cheat sheet applies to legacy BIOS systems (IBM PC/AT standard), not UEFI. UEFI uses completely different boot mechanisms (GPT, ESP, .efi executables).
  • BDA offsets are IBM PC/AT standard; minor variants exist in clones (e.g., PS/2 systems always have EBDA present). Use tools like DEBUG.COM to inspect actual BDA contents on target hardware.
  • Memory layout can vary slightly between BIOS implementationsalways test on target hardware or emulators (QEMU, Bochs, VirtualBox).
  • Always verify EBDA location before using addresses near 0x9FFFF (use the code snippet provided).
  • Stack grows downward (toward lower addresses) in x86 architecture.
  • For extended memory detection (>1 MB), use INT 0x15, EAX=0xE820 (E820 memory map) in protected mode or during boot.
  • For hybrid boot setups (legacy + UEFI), consider integration with modern bootloaders like GRUB2 or systemd-boot.

Accuracy: This corrected edition fixes critical errors in the BDA layout (especially EBDA pointer location) and provides precise byte counts for memory regions. Based on IBM PC Technical Reference and OSDev Wiki documentation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment