2026-04-25
Stack Overflow: View Question
Tags: debugging, assembly, operating-system, gdb, x86-64
Score: 2 | Views: 72
The asker is writing a bare-metal OS that enumerates PCIe devices by walking the ECAM (Enhanced Configuration Access Mechanism) memory space. Their function reads the vendor ID at each possible bus/device/function address and saves valid ones. The problem: GDB's x (examine) command shows a different value at the same memory address than what the CPU actually loaded into a register. This is deeply confusing and suggests something fundamental is going on beneath the debugger.
This is a genuinely interesting problem because it sits at the intersection of several tricky x86 concepts:
movzx ax, word [addr]) but GDB does a 32-bit or 64-bit read, MMIO devices can respond differently. Some PCIe implementations are strict about access size.x command is reading the raw physical address that your virtual address maps to — but it does so without triggering MMIO side effects the same way a real CPU access would.The debugging approach should be:
x/1hx (halfword) to match a 16-bit vendor ID read.info registers) with the examine output — if the register is correct but x disagrees, it's almost certainly a GDB stub vs. MMIO semantics issue.A common gotcha: for non-existent PCIe functions, the hardware returns 0xFFFF for the vendor ID. If you're seeing valid-looking values where there should be none, your address calculation is likely hitting a real device's config space repeatedly rather than walking to empty slots.
