"The only proper way to understand 80x86 coding is to realize that ALL 80x86 OPCODES ARE CODED IN OCTAL. [...] For some reason absolutely everybody misses all of this, even the Intel people who wrote the reference on the 8086 (and even the 8080)."
To a certain extent that's true of the 68000 too. Octal becomes convenient whenever you have a bunch of 3-bit fields. To me, the thing that's kind of gross about x86 are all the exceptions.
Outside of 64-bit mode you can't do byte operations on [e]si, [e]di, [e]bp or [e]sp (though for the last of those, there is little reason you would want to). In 64-bit mode, you can do that with a REX prefix, but then you can't access the ah, bh, ch and dh. There's only one size bit in the main opcode byte so they had to add a prefix byte when they added 32-bit support and another one when they extended to 64-bit. Unsigned multiply instructions have a fixed destination register/register pair. Numerous instructions have special shorter encodings you can use for certain registers.
All of this makes a lot of sense in the context of the 8086. It needed to be easy to port assembly from the 8080 and memory was incredibly limited. As a product of its time it seems like a pretty good design, but it wasn't a forward thinking design. The 68000 by contrast was a (mostly) 16-bit implementation of a 32-bit, forward-looking, ISA. It's a shame x86 survived while 68K is mostly dead.
The problem is that for x86 the way the opcodes are defined (both Intel and AT&T syntax) suggests a much more orthogonal instruction set than it is (in x86-64 it is even worse). So I consider the problem that you tell in your second paragraph as the classical problem of hitting the walls of a leaky abstraction (full disclosure: for some private side project that I work on I try to develop a way to mitigate this problem; don't ask me about details yet).
reply