8 ms·
8086 Microcode Disassembled
- viler 6y agoOutstanding work - never fails to amaze me when people unearth little secrets like that 4 decades after the fact. That MUL/IMUL/IDIV status bit hack is one for the ages.
- drfuchs 6y agoAnd he found it by “reading the code”!
- ajenner 6y agoAuthor here if anyone has any questions.
- soufron 6y agoYup. Who did write the microcode at the time? And for how long?
- ajenner 6y agoAccording to https://en.wikipedia.org/wiki/Intel_8086 https://en.wikipedia.org/wiki/Intel_8086: "The architecture was defined by Stephen P. Morse with some help and assistance by Bruce Ravenel (the architect of the 8087) in refining the final revisions. Logic designer Jim McKevitt and John Bayliss were the lead engineers of the hardware-level development team and Bill Pohlman the manager for the project." I expect the microcode was developed in tandem with the rest of the chip, so probably took about 2 years.
- schoen 6y agoWhat's "random logic"? From context, it sounds like circuitry that explicitly implements the functionality of an opcode, as opposed to circuitry that can be used by the microcode, or something?
- ajenner 6y agoYes, exactly - the logic that implements the simpler instructions directly as special-purpose gates rather than microcode.
- kens 6y agoTo expand on that, "random logic" means that it looks random; it's not actually random. This is in contrast to circuits that have an underlying structure to them, like a PLA or ROM.
- derefr 6y ago> While most of the unused parts of the ROM (64 instructions) are filled with zeroes, there are a few parts which aren't. The following instructions appear right at the end of the ROM [...] Given that they're right at the end — and seemingly intentionally written there after the rest of the unused space before them was zeroed — might those bytes be a checksum of the ROM?
- ajenner 6y agoI don't think there's anything on the chip that could compute a checksum of the microcode ROM contents. It could be some kind of copyright message perhaps, though I don't know how it's encoded and it's only 42 bits long so there isn't much space for anything meaningful.
- derefr 6y agoI would guess that it’s not a runtime-verified checksum, but rather a simple embedded “sum complement” value, used for ROM-mastering-time integrity verification. A sum-complement value is a value computed from some data, such that, when the data is checksummed with the sum-complement value now embedded into it, the data will sum to zero. This approach to checksumming is useful, as any potential verifier just has to throw the image-as-a-whole through the checksumming algorithm, and ensure that the output is zero. It doesn’t need one iota of knowledge about what it’s verifying. It doesn’t even need an extra machine-register to hold the expected checksum. These “blind” checksums allow ROM production hardware (programmers, copiers) to both pre-verify the integrity of the input image, and to post-verify that it has programmed the image onto a chip successfully. No special container format for the ROM image is required, nor is the ROM image required to be structured in any particular way (which is good, because ROMs are used for all sorts of things, not just code.) The ROM image can be any opaque blob, just as long as it sums to zero. In fact, you don’t even need a ROM “image” at all. It’s possible to integrity-verify a programmed ROM “against itself”; and thus, a hand-programmed ROM (e.g. an EEPROM you programmed in your office) can be sent to the duplication facility to serve as the reference from which mask-ROM masks will be generated. The data on the EEPROM can be trusted, because it sums to zero. And the mask ROMs themselves can be checked for flaws by seeing whether they sum to zero. For smaller-scale ROM distribution, ROM-to-PROM bulk copiers are used. These copiers can be made to both pre-verify the source, and to post-verify the programmed copies. Using this approach to checksumming, the copier can avoid having to verify the source “against” the destination, instead only needing to verify the source once, and then verify the destinations against themselves. This both speeds up verification; and allows for the use of simpler microcontrollers in these copiers, which reduces their design cost. (By quite a lot, back in the 1970s, when all this was most relevant.) You can see this approach to checksumming in practice in early-generation game cartridge ROMs, which almost always have these embedded sum-complement values (and so presumably were integrity-verified during mastering/duplication.) These sum-complement value fields get referred to by emulators as “the checksum” of the ROM image—but technically, they’re not; if you’re following along, you’ll realize that “the checksum” of such ROM images is zero! :)
- mkup 6y agoDoes MUL/IMUL/IDIV result negation trick (via REP prefix) work on later 8086-compatible Intel CPUs (e.g. 80286, 80386 etc)?
- ajenner 6y agoI have just learned from dreNorteR on VCF that it no effect on a 286 but has a different, unexpected, and useful effect on a 186! http://www.vcfed.org/forum/showthread.php?76657-8088-8086-microcode-disassembly&p=635234#post635234 http://www.vcfed.org/forum/showthread.php?76657-8088-8086-mi...
- dm319 6y agoI wonder if you could do a version of this article for a lay person like me? I really enjoyed Ken's articles because it assumed very little knowledge.
- userbinator 6y agoDoes the microcode give any hints on why the general PUSH and POP are in completely different places in the opcode map (push is FF/6, pop is in its own group in 8F/0 with 8F/1-7 invalid, while FF/7 is unused)? It almost looks like FF/7 was supposed to be the pop. I've always wondered what 8F/1-7 and FF/7 do on an 8086/8 too, but it's very hard to find that information.
- Akababa 6y agoIf ROM space is so valuable, why is ASCII text (which I imagine is relatively large) stored on it?
- pkphilip 6y agoAmazing work! Can't say I understood half of what you have written, but sure is some top quality work!
- derefr 6y agoOne thing I've always wondered: in what ways is the design of microcode instruction-sets for CISC-ISA CPUs, different from the design of outward-presenting RISC ISAs? For example, does microcode tend to have instructions that "half complete" a transfer-level operation, leaving some registers in an indeterminate state, under the assumption (which is, in practice, a guarantee) that they'll always have another ucode op executed after them that does "the rest of" the operation and so puts things right? Or, for another example, on CISC CPUs that have a small set of system-visible registers, and use register renaming to map them to a larger register file (e.g. x86_64), do the user-visible register names make it into the microcode; or do the microcode ops function directly on register-file offsets? To answer these questions, though, we'd probably need a survey of microcode for various CPUs, including modern ones. So I'm not holding my breath. Unless an engineer from Intel or the like wants to jump in! ------ I've also been curious whether there are any lessons in the design of microcode ISAs, that can be applied in the design of abstract-machine bytecode ISAs. Right now, most bytecode ISAs are semi-idealized RISC ISAs, with some load-time specialization of bytecode into VM-specific ops; but rarely is there recompilation of bytecode into VM-specific microcode. I'm curious why that is.
- ChuckMcM 6y agoIn my experience, CISC instruction sets are primarily a way to create compact representations of fairly long instruction words. That arises from the way in which the register file, the ALU, the flags, and various counters (instruction, stack, Etc) are laid out in logic and the buses between them. Something that I find really fun to do is to experiment with compute architectures. I first started playing around with this with an Altera DE2 board, then the Spartan III dev board from Xilinx, and these days with a Lattice Ice40K board (Icebreaker, and soon ULX3S board). There are a number of "soft" CPUs where you can play around with this to your hearts content (given you have enough gates in your FPGA, which is getting easier and easier these days). CISC instructions are, as the name suggests, are simply "subroutine calls" or "macro calls" (depending you what era of computing you were introduced to) into an underlying machine that can move bits around each "clock". RISC is essentially making that level of instruction available directly to the compiler. The most infamous version of exposing what is essentially microcode to the compiler was, in my opinion, the Itanium which has a really flexible native instruction set that the compiler mixed and matched into pseudo instructions which it used to compile code into. A more elegant version of this was the Xerox PARC "D" machines which allowed you to load an instruction set prior to booting into your actual applications. This made Mesa[1] development interesting because you needed the appropriate instruction set to go with the Mesa compiler you were using. [1] Mesa was Xerox's modular development language that inspired Wirth's Modula 2 (I believe that was the ordering, Wirth might claim it went the other way)
- dylan604 6y agoIt seems like there have been a few disassembly write ups on the 8086 lately. Are the tools getting to the point where this is possible, or just enough people with enough serious interest in this? Coincidence? Am I seeing a pattern that isn't really there?
- ajenner 6y agoProbably not entirely a coincidence - Ken Shirriff is doing a series on the 8086 which may account for at least one of the other articles you've noticed. My disassembly was only possible because of Ken's high-resolution photos of the die with the metal layer removed - that's why it took me until now to do it.
- dylan604 6y agoso it's turtles all the way down? someone makes a break through that gets used by someone else to make a different break through kind of a thing. this is why science needs to be open. no one person/group can do it all. i just wish that research didn't have to be done in secret to protect potential patent ability. Let the work be published and the let the people responsible receive whatever credit/recognition/awards deserved. kudos for your efforts!
- procd 6y agoAmazing!
- rkagerer 6y agoChris Gerlinsky did a talk last year on the process he uses to decap chips and extract their ROM bits with a microscope: https://youtu.be/4YpSevQWCX8 https://youtu.be/4YpSevQWCX8 My favorite line was when he described how one hint you've got the decoding right might be stumbling upon a recognizable ASCII string, and said "sometimes the only ASCII text you find is a copyright notice... keep putting those in, that's great!"
- kevbin 6y agoThe link to https://www.righto.com/2020/06/a-look-at-die-of-8086-processor.html https://www.righto.com/2020/06/a-look-at-die-of-8086-process... is worth clicking
- surfsvammel 6y agoAwesome stuff. Really nostalgic. An 8086 with yellow monochrome screen was my first computer. It ran Police Quest I, I think.
- ksaj 6y agoHave you used a green monochrome screen? I still remember the first time I got one, because it was cheaper than those newfangled amber screens. At first I thought it was a little stupid because of how slow the fade was when the cursor blinked, and it wasn't nearly as sharp or vivid. But within the first few hours of hacking around, I recognized how much easier on the eyes it was without the flickery amber that wobbled when you clacked your teeth together, and the weird random "snow" when refreshing the screen in a text "animation." If only fractals didn't take an hour or so to render back then, an animated one at modern speeds would have been quite soothing to watch that way. Fractint - I'm shocked I actually remember the name. Downloading it from a BBS is how I got my second computer virus! Exciting times. Nostalgic is right.
- dm319 6y agoHave you come across coolretroterm? It simulates the snow and wobble of those screens, and I think, does a reasonable job. Not sure if it would work with a graphical program though.
- ksaj 6y agoI remember seeing it, I think from HN when I was still a lurker. I bookmarked it, but never got around to trying it. Some things are best left to the fond memories. I got an sdf.org account a few months ago, and that quickly demonstrated to me that nostalgia occurs when things happened so long ago that you forgot about all the not-great things like lag, terms that don't agree on what a backspace is, newsgroup spam, every program having completely different idioms, etc. My newsfeed config randomly disappeared after the third day, which was a very accurate representation of "back in the day" that I had forgotten about until that moment.
- thristian 6y ago
- bogomipz 6y agoI apologize if this is a naive question but how do I make sense of microcode_8086.txt in the zip file? Just using line 1 or 000. I understand from the final column(s) that this concerns a MOV instruction and Mod R/M byte is that correct? How do I understand what everything to the left of that means? 000 A CD F H J L OPQR U R -> tmpb 4 none WB,NX 0100010??.00 MOV rm<->r Similarly how do I understand what each of the different files in the zip file represents? The authors states: >"I used bitract to extract the bits from the two main microcode ROMs, and also from the translation ROM which maps opcode bit patterns onto positions within the main microcode ROM." Is the the translation ROM the translation.txt file then? Is that the key to understanding these files? If so why wouldn't there be more than the 38 or so Op codes listed?
- ajenner 6y agoThe translation.txt file is the contents of the translation ROM which tells the CPU where in the microcode to go for long jumps, calls and EA decoding. The key.txt file has the details of all the mnemonics. "000" - this is just a line number "A CD F H J L OPQR U" - these are the actual bits from the ROM. "R -> tmpb" - this is a move operation (each microcode instruction can do a move as well as something else) copying the value from "R" (a register described by the word length bit and either the R field or the RM field of the modrm byte depending on the direction bit) to "tmpb" (an internal register not accessible from the user-level ISA). "4 none WB,NX" - a type 4 instruction (bookkeeping) that tells the CPU that the next instruction is the last one in the microcode burst (NX) unless a write back (WB) to memory is needed. "0100010??.00" - this is the bit pattern by which this line of microcode is addressed. This one means opcodes 0x88-0x8b. "MOV rm<->r" - a comment added to say what this set of opcodes actually corresponds to x86 assembler, or what it does if it's a subroutine.
- bogomipz 6y agoThank you this really helps. One last question do the individual files. There seems to be 3 distinct file groups: 0b.txt - 8t.txt l0.txt - l3.txt r0.txt-r3.txt Do each of these represent different ROMs or different logical parts of the two ROMs? Or am I reading too much into the naming convention? By the way - brilliant work. This is really a fascinating read.