p6dis - Disassembler for Intel P6 Microcode
p6dis is a disassembler for Intel P6 family microcode. It processes microcode stored in triplet format (3 microoperations per line) and produces human-readable assembly-like output with labels, branch targets, and flow analysis.
Input files are "hex triad" files (.tri) produced by p6scrambler -d. Each line represents one triad (3 microcode slots) at a specific address.
- -t [type] - Required. Specify CPU type: pentiumpro, pentium2, pentium3, pentiumm, core, core2
- -b [addr] - Set base address (hex format)
- -a - Generate assembly format with .org directives
- -L [arg] - Add label: LABEL=addr or load label file: @file.lbl
- -C [file] - Load constant ROM definitions
- -B [addr] - Forward flow trace: Disassemble only code reachable from [addr]
- -E [addr] - Backward flow trace: Disassemble only code that leads to [addr]
- -e [addr] - Complete flow trace: Find all predecessors of [addr], then show everything those paths can reach
Addresses can be specified as:
- Label name: my_label (must be defined via -L)
- UROM format: UROM_1234
- Hex number: 0x1234 or 1234
Important notice: This set of functions is very very very very inefficient (and no, I am not paying your electricity bill). Someone should rewrite it, but it likely requires starting p6dis from scratch.
Use case: "Show me all code paths starting from this entry point"
p6dis -t pentium2 -B 0x1000 input.tri
Marks and disassembles only microcode reachable by following branches forward from address 0x1000.
Use case: "How did execution reach this point?"
p6dis -t pentium2 -E 0x2000 input.tri
Marks and disassembles only microcode that can lead to address 0x2000 by tracing predecessors backward.
Use case: "Show me all possible execution paths that could end at this point, including their side branches"
p6dis -t pentium2 -e 0x2000 input.tri
Two-phase analysis:
- Find all predecessors that reach 0x2000 (backward)
- From each predecessor, trace forward to show all branches they might take
This is extremely useful for finding all code branches that may terminate at a specific point.
Label file format (.lbl):
# Comments start with # 1234 entry_point 5678 error_handler
Load with: [email protected]
Constant ROM files (.cst) define microcode constant values referenced as CONSTROM.XXX in disassembly output.
Format:
: <64-bit hex value> # Comments start with # 000: FFFFFFFFFFFFFE40 001: 0000000000000001 0EE: DEADBEEF12345678
- Index: 3 hex digits (000-1FF), represents CONSTROM offset
- Value: Up to 16 hex digits (64-bit constant)
- Whitespace and comments are ignored
- Values can optionally have 0x prefix
Load with: -C constants.cst
When loaded, disassembly will show:
TMP5 = LOAD.SC1.DSZ8 (TMP0, TMP7, CONSTROM.0EE /* 0xDEADBEEF12345678 / ... */, ...)
p6scrambler -d -t pentium2 msrom.hex | p6dis -t pentium2 -
p6scrambler -d -t pentium2 msrom.hex | p6dis -t pentium2 [email protected] -
p6dis -t pentiumpro [email protected] -B entry_point input.tri > output.asm
Advanced: Backtrace All EOM Flow Markers
This pipeline generates complete backtraces for every End-Of-Microcode (EOM) flow marker:
p6scrambler -d -t pentiumpro msrom.hex | \ p6dis -t pentiumpro - | \ grep EOM | cut -c 6-9 | \ while read addr ; do # Full backtrace (backward only) p6scrambler -d -t pentiumpro msrom.hex | \ p6dis -t pentiumpro [email protected] - -E 0x$addr > full/$addr.full.asm # Complete flow (backward + forward from all predecessors) p6scrambler -d -t pentiumpro msrom.hex | \ p6dis -t pentiumpro [email protected] - -e 0x$addr > full/$addr.back.asm echo $addr done
Explanation:
- Descramble MSROM and disassemble to find all EOM flow markers
- Extract each EOM address
- For each EOM:
- Generate backward-only trace (.full.asm)
- Generate complete flow trace showing all code paths (.back.asm)
./p6microcode-tools/p6scrambler -dt pentiumpro msrom-612.hex | ./p6microcode-tools/p6dis -t pentiumpro - | grep EOM | cut -c 6-9 | while read addr ; do ./p6microcode-tools/p6scrambler -dt pentiumpro msrom-612.hex | ./p6microcode-tools/p6dis -t pentiumpro -L @msrom-612.lbl - -E 0x$addr > full/msrom-612-$addr.full.asm ; ./p6microcode-tools/p6scrambler -dt pentiumpro msrom-612.hex | ./p6microcode-tools/p6dis -t pentiumpro -L @msrom-612.lbl - -e 0x$addr > full/msrom-612-$addr.back.asm ; echo $addr ; done