Hacker News new | ask | show | jobs
by woodruffw 1578 days ago
I remember seeing a copy of this Usenet post years ago! It's one of my favorite "secrets" about x86's encoding.

The "core" (non-E/VEX, non-SSE, etc.) x86 encoding is wonderfully clever and terrible by modern standards, and Volume 2 of Intel's SDM is a great reference for how x86 manages to pack remarkably complicated addressing, operand, etc. semantics into just a handful of bytes. The result is a format that's remarkably hard to decode correctly, meaning that just about every software decoder for x86 is saturated with bugs[1] (FD: my project).

[1]: https://github.com/trailofbits/mishegos

4 comments

Not sure if x86-64 REX prefixes count as "core" by your definition, but REX prefixes are incredibly wasteful and basically throw away all the code size gains that x86 would otherwise get over competing instruction sets. For most instructions, 4 bits are wasted to signal REX, and usually at least 1 more bit is wasted on register extensions not used by the instruction, particularly the SIB index extension. If you limit yourself to 32-bit x86, then yeah, x86 is pretty compact.
Yeah, I was talking about 32-bit x86. REX is indeed very wasteful :-)

(Even then, there's a lot of waste in the "legacy" prefix bytes, and I've always wondered who hacked those into the ISA instead of designing something more compact.)

I've always thought x86-64 was a very weird "not quite 64-bit" extension of x86 that was done awkwardly, unlike the 16- to 32-bit transition. The fact that AMD designed it and not Intel may have been one of the reasons. Then again, "full 64-bit" wasn't really necessary (and even now, a lot of code is fine with 32-bit ints).
Seeing that reminds me of one of the projects I want to do: the "World's Worst x86 Decoder". The basic idea is you toss most of the x86 manual, and just consider all of the prefixes as part of the opcode, so you say that x86 has (numbers are top of head, may be inaccurate) N opcodes, where N = 256 * 4 opcode maps * 4 group 1 prefix possibilities * 7 group 2 prefix * 2 group 3 * 2 group 4 * {REX/VEX/EVEX prefix counting is hard to do). It's the "world's worst" decoder, because not only does it not try to actually give a human-readable name for the opcode, it is also going to give patently wrong results for cases where "we packed 8 different instructions into this opcode, because they each take a memory argument, so the other R field in the ModR/M byte chooses a different instruction".
In my experience it's the "second page" of opcodes (0f xx) where the difficulty lies; the first page has been thoroughly explored and documented by now.

Historical note: the 286 was the first to have the second page.

I haven't seen the FD abbreviation, is it "full disclosure" ?
FD, or 375 octal. :)
Yes, that's "full disclosure."