Skip to content

Instantly share code, notes, and snippets.

@sudocurse
Created July 23, 2026 22:30
Show Gist options
  • Select an option

  • Save sudocurse/20787d09a8e36a00b0a5cf0692c4e7a7 to your computer and use it in GitHub Desktop.

Select an option

Save sudocurse/20787d09a8e36a00b0a5cf0692c4e7a7 to your computer and use it in GitHub Desktop.
real mode
#!/usr/bin/env python3
import argparse
import subprocess
import tempfile
import pathlib
import sys
PRESETS = {
"ivt_int0": (0x0000, 0x0000, "IVT: int 0 (divide-by-zero) handler offset"),
"ivt_int0_seg": (0x0000, 0x0002, "IVT: int 0 handler segment"),
"ivt_int10": (0x0000, 0x0040, "IVT: int 0x10 (video) handler offset"),
"ivt_int13": (0x0000, 0x004C, "IVT: int 0x13 (disk) handler offset"),
"bios_equip": (0x0000, 0x0410, "BIOS Data Area: equipment word"),
"bios_memkb": (0x0000, 0x0413, "BIOS Data Area: base memory size (KB)"),
"bios_tick": (0x0000, 0x006C, "BIOS Data Area: timer tick counter (live!)"),
"video_mem": (0xB800, 0x0000, "Video memory: char+attr of top-left screen cell"),
}
def build_asm(seg: int, off: int, label: str) -> str:
live = (label == PRESETS["bios_tick"][2])
return f"""
BITS 16
ORG 0x7C00
mov ax, {seg:#06x}
mov ds, ax
{ '.watch:' if live else '' }
mov bx, [{off:#06x}]
mov cx, 4
.loop:
rol bx, 4
mov al, bl
and al, 0x0F
add al, '0'
cmp al, '9'
jbe .p
add al, 7
.p:
mov ah, 0x0E
int 0x10
loop .loop
{ 'mov ah, 0x0E' if live else '' }
{ "mov al, 13" if live else '' }
{ "int 0x10" if live else '' }
{ "jmp .watch" if live else "hlt" }
times 510 - ($ - $$) db 0
dw 0xAA55
"""
def main():
parser = argparse.ArgumentParser(
description="Boot a tiny NASM stub in QEMU that dumps a real-mode memory location to the screen."
)
parser.add_argument(
"preset",
nargs="?",
choices=sorted(PRESETS.keys()),
help="Which memory location to peek at.",
)
parser.add_argument(
"-l", "--list",
action="store_true",
help="List available presets and exit.",
)
args = parser.parse_args()
if args.list or not args.preset:
print("Available presets:\n")
for name, (seg, off, label) in PRESETS.items():
print(f" {name:14s} {seg:04x}:{off:04x} {label}")
if not args.preset:
print("\nUsage: python3 peek.py <preset>")
sys.exit(0 if args.list else 1)
return
seg, off, label = PRESETS[args.preset]
asm_src = build_asm(seg, off, label)
with tempfile.TemporaryDirectory() as tmp:
asm_path = pathlib.Path(tmp, "b.asm")
img_path = pathlib.Path(tmp, "b.img")
asm_path.write_text(asm_src)
print(f"Peeking at {seg:04x}:{off:04x} — {label}")
subprocess.run(["nasm", "-f", "bin", str(asm_path), "-o", str(img_path)], check=True)
subprocess.run(["qemu-system-i386", "-fda", str(img_path), "-boot", "a"], check=True)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment