I actually cut my teeth on TI's TMS34010 asm. Simple RISC (lot's of registers), flat address space, and bit addressable. I loved it.
Then again, I admittedly learned 8080 and then Z80 and x86 first, so any RISC feels too simple; but those who learned any RISC first probably feel the exact opposite.
modern MIPS has "ext" and "ins", which are probably an improvement in that regard.
> plentiful-yet-unhelpfully-named registers
what's wrong with MIPS register names? my only comparison is x86 and that has been awful. I'm constantly looking up which registers are what.
They're not really names, just "addresses" of a different form --- and of course, 0 is not really a register. x86 register names are supposed to be mnemonic, because certain instructions are only usable with, or have shorter forms when used with, the "right" register: Accumulator, Count, Base, Data/Divide, Stack Pointer, Base Pointer, Source Index, Destination Index.
To me the MIPS registers seem pretty logical too, though: $zr for zero, $sp for stack pointer, $a0-3 for arguments, $t0-7 for temporaries and $s0-7 for saved registers. Much better than the plain numbered registers on some assembly flavors.
When I did my undergrad, Ada was the primary language of instruction for first year, with x86 assembler taught as a subject in the second semester.
The idea being to get us thinking about programming correctness from the beginning, then to teach how the machine worked once we had a good foundation.
By second year we were just expected to know C, and coming from assembler, things like pointers were something I never had a problem understanding.
Start high to get a good grounding, go low to understand how everything works, then return high to write code that has a good grounding in how it will be executed on the machine.
If the only goal. The OP listed four.
#2 is a great reason to learn Latin but the "influence of C" is identical to the influence of Fortran or Pascal or Algol and of equivalent magnitude to (what evolved into) Common Lisp or Scheme.
And #4 is true eventually but it only matters when the software is broken.
Here wa my roadmap:
(1) I first learned assembly by learning computer architecture from Tanenbaum's book -- Structured Computer Organization -- and related course at the Vrije Universiteit Amsterdam. This taught me a toy architecture (Mic1) but it give me a rough idea of how assembly worked.
(2) Then, later I took a course in binary and malware analysis and all that we were required to do was to read x86 assembly in IDA and interact with it via GDB -- and using the command: layout asm, which gives a layout for all the register values and upcoming instructions.
And once I have a debugger available and understand it well enough, I can learn quite well since I can make little predictions and check if they are right or wrong, and so on.
In my experience young devs using C get very confused about wtf pointers are really about and what's the deal with the heap, stack, etc. Whereas they understand the concepts better in assembly despite the verbosity.
I'm not arguing for a deep understanding of assembly but if the goal is to "think like a computer" than at least a basic understanding is incredibly helpful. Or at least less confusing than C.