On Fri, Jul 5, 2024 at 5:47 PM John Levine <johnl(a)taugh.com> wrote:
It appears that Peter Yardley
<peter.martin.yardley(a)gmail.com> said:
The DG Nova had a pretty nice architecture. 2
accumulators, 2 index registers, program counter, status register. No stack register tho.
There was a micro processor version by Fairchild.
It did, but it was word addressed which makes it an historical
curiosity like its spiritual predecessors PDP-4/5/7/8/9.
I also have a mental model of a PDP-11 but these days it's more a simplified 386
leaving out the dumb or useless stuff. I ignore the segments which are useless
other than for 286 emulation, and some of the strange instructions like decimal
adjust and the warty 8 and 16 bit registers.
What's important is the memory model which on a 386 the way it was
invariably set up was a flat 32 bit consistent little-endian byte
addressed memory with a stack and reasonable addressing modes, and 4K
pages for virtual memory.
It is important to ask, "what does one want to learn about
architecture by going through this study exercise?" If one just wants
to study the unprivileged instruction set at the level of assembler
mnemonics, then x86_64 isn't completely awful. Some of the registers
are oddly named, and some instructions have odd implicit operands
(e.g., `inc %rax`, but if you're just looking at assembler syntax,
perhaps one doesn't care. Of course, the instruction encoding is a
huge mess, but most work-a-day programmers don't have to care about
that.
Where it gets really ugly, in my opinion, is in the privileged
instruction set, and there you can't get away from history: there's no
escaping descriptor tables or segmentation there! The interrupt stack
table in the TSS must be set up properly or you're bound for a triple
fault. This implies the GDT, IDT, TR, and TSS --- all 286-era goo ---
are all properly set up, and you can't get away from that stuff, even
in a modern operating system (you have to reload the TSS _or_ replace
RSP0 on every thread switch: there's no other way; that's just how the
hardware works). And then there's the matter that you _have_ to enable
paging before switching into 64-bit mode on x86...it's not hard, but
it's annoying (and the x86S proposal doubles down on it). It'd be
more rational to allow execution against a flat 64-bit physical
address space; for x86S, I'd rather be able to specify a reset vector
in the physical address space by some sort of external strap.
Both RISC-V and ARM seem much more rational in this world by comparison.
I don't like the RISC-V page table format, though: it doesn't permit
you to pun the root of the paging radix tree for other levels, meaning
you can't use the "recursive page table" trick to get access to page
tables themselves: this, in turn, has effects on the rest of the
design of a virtual memory system. I think I've found a way around
that involving a dedicated temporary mapping region, but it's kind of
a pain and takes a non-trivial chunk of virtual address _space_ (if
not fully realized memory) that I don't care for. How to handle
cached vs uncached mappings, e.g., for MMIO, is still a bit mysterious
to me. Honestly, this is something that x86 got largely right.
ARM is ok, but has grown a lot of complexity; most of which can be
ignored until needed, I suspect; saturating arithmetic, for example.
Understanding it is not critical to understanding more or less how the
computer works.
ARM should be OK too but I have to ask which ARM?
There have been so
many generations often not backward compatible.
I'd start with ARMv8 at this point. It has less confusing, more
rational stack push/pop semantics and I think they did away with the
conditional execution stuff, which is easier to reason about.
My 2c.
- Dan C.