Cracking the Black Box: Disassembling the Intel 80386 Microcode
For decades, the Intel 80386 was a cornerstone of modern computing, introducing the 32-bit architecture that powered the transition to protected mode and memory paging. Yet, while its external behavior was well-documented, its internal microcode—the low-level instructions that tell the hardware how to execute complex x86 instructions—remained a complete black box.
Recently, a collaborative effort involving researchers and enthusiasts has successfully disassembled the 80386 microcode. This achievement is not merely a historical curiosity; it is a masterclass in reverse engineering, combining image processing, neural networks, and painstaking manual analysis to uncover the inner workings of a legendary processor.
From Silicon to Binary: The Extraction Process
Unlike the 8086, where patents provided a roadmap for disassembly, the 80386 offered no such clues. The process began with high-resolution images of the 80386 die, provided by Ken Shirriff. However, converting a visual representation of a ROM into a binary blob is a monumental task. The microcode ROM of the 80386 is approximately 94,720 bits—nearly nine times larger than that of the 8086.
To overcome this, the team employed a combination of:
- Image Processing: To isolate the ROM structures from the die image.
- Neural Networks: To automate the recognition of bit patterns within the silicon.
- Human-Aided Automation: To cross-check and verify the extracted binary data.
Once the binary blob was secured, the real challenge began: turning a sequence of bits into intelligible micro-operations (\u03bc-ops).
Decoding the Micro-Operations
Disassembling the binary required identifying patterns and deducing the structure of the \u03bc-ops. The researchers had to determine the axis of the \u03bc-ops, the order in which they were read, and how the bits were divided into functional fields.
Several key insights guided the process:
- ALU Cycle Analysis: Knowing the 80386 could perform ALU operations in two cycles suggested a specific field for a second ALU input, allowing operands to be loaded in the first cycle and the result stored in the second.
- Register Mapping: Based on previous work with the 8086, the team assumed certain fields corresponded to source and destination registers.
- Instruction End-Markers: The team identified recurring patterns that signaled the end of a specific instruction routine.
- Hardware Tracing: Ken Shirriff assisted by tracing physical logic lines on the die to confirm how components were interconnected.
Architectural Insights: Hardware Acceleration
One of the most striking findings is the difference in implementation between the 8086 and the 80386. While the 8086 relied heavily on microcode to implement algorithms, the 80386 is significantly faster because it "hardware accelerates" many of these processes.
In the 80386, the microcode often acts as a controller, setting up specialized hardware accelerators—such as the barrel shifter, the multiply/divide hardware, and the protection test unit—rather than embodying the algorithms directly in software-like micro-steps.
Key Findings from the Disassembly
- Instruction Volume: The microcode contains 215 entry points from the decoding ROM, a massive increase from the 60 found in the 8086. This increase is due to new instructions and the need for different routines based on operand types (register vs. memory) and CPU modes (real vs. protected).
- Universal Microcode: Surprisingly, every single instruction in the 80386 is handled by microcode. Unlike modern CPUs, which often have "fast paths" for simple instructions that bypass microcode, the 80386 always executes a \u03bc-op.
- Potential Security Flaw: The disassembly revealed a possible bug in the IO permission bitmap handling. In 4-byte port accesses, the microcode may only check permission bits for the first three addresses. If an access occurs at the edge of a permitted IO-port space, the final byte might erroneously succeed, potentially granting unauthorized access to hardware registers.
The Complexity of the 386
The transition from the 8086 to the 80386 represented a leap in complexity. As one community observer noted, while the 8086 felt like an "approachable individual adventure," the 80386 feels like an "industrial machine," reflecting the explosion of complexity brought about by virtual 86 modes, floating point units, and memory paging.
This project underscores the importance of low-level architectural knowledge. For those interested in exploring these findings further, the disassembly and supporting files (including fields.txt and microcode_10.txt) are available in the x86 microcode repository on GitHub.
"The black box analysis needed to decode this is incredibly hard but also incredibly fun and rewarding to pull off."
By peeling back the layers of the 80386, researchers have not only preserved a piece of computing history but have also provided a tangible example of how the most fundamental layers of hardware and software intersect.