It hid CPU/architecture differences
That's not a binary thing. If you hide too many differences you're internalizing limitations of the worst contemporary architecture.Also, I think it would be odd if someone, who as you carefully summarized had written assembler for a half dozen different architectures, didn't have in mind some loose notion of portability. And, FWIW, I remember reading at some point that Ritchie and/or Thompson felt some sort of vindication when they discovered how easy it was to write a C compiler for other machines.
"C as a portable assembler" is something of a straw man. I don't think anybody with even a passing familiarity of the actual history believes that Ritchie and Thompson had such specific and directed goals.
Another way to spin the history is to argue that you had two engineers who had programmed on a wide variety of architectures, and who were familiar with a wide variety of languages, create a new language that was simple to compile and made pragmatic assumptions about architectural dependencies. For sure they weren't trying to create a universal assembler. Rather, they were driven by pragmatic needs.
Allowing yourself to be directed by actual, manifest requirements without foreclosing future opportunities is arguably one of the best approaches to engineering.
Did C succeed despite it's conceptual shortcomings, or _because_ of them? I think your essay presumes the former without giving enough consideration to the latter.
Or drop down to microcode, were things like eval and the garbage collector tended to live, along with graphics primitives and the usual things at that level. The first widely produced Lisp Machine could be outfitted with a very large bank of this vertical microcode if you were willing to pay for the static RAM to populate it. There was also a Lisp to microcode compiler of some level of utility.
That's not in the docs I cited from the inventors. The original goal was ALGOL's benefits. Too hard on an EDSAC. So, chop off anything until you have fastest, most minimal language for an EDSAC. Thompson preferred BCPL over anything else at the time & wanted to do an OS in it on a PDP-7/11. Ritchie too. Mods needed to do that became the earliest C.
Portability across CPU's is never mentioned. UNIX and C were specifically designed for those hardware with holdovers in there to this day. A portable, assembly language from back then that was successful was P-code. It hid CPU/architecture differences, stayed efficient, and was backend of the compiler. Later, they wrote OS's in a mix of HLL's and P-code variant. Exactly the kind of thing you do if designing for portability.
C was ported because it barely had any features. These ports often had to be kludgingly forced into the machines. Quite different.
"If you code in assembly, you eventually need to begin writing your own routines for copying, appending strings/memory, etc. It begins to look suspiciously like the stdlib as it evolves. And consequently, your code begins to look like C with assembly mixed in for the control logic."
You might evolve a stdlib. What it looks like, how safe it is, how efficient it is, and whether it's auto-customized per CPU via macros, etc are totally different depending on your foundation. Most of Oberon System's OS is done like you would ordinary programs with function calls, type-checked arguments, and even garbage collection in later ones. The LISP machines were incredibly different with one able to use macros for API's or bottom layers. The Smalltalk approach was more high-level than most 3GL's with its OOP philosophy. House hid what little unsafe stuff it had in the H-Layer with rest of OS coded in Haskell with type-system & functional benefits.
So, C's style is neither inevitable nor the best. It was a byproduct of its inventors development style on two, specific machines starting with a typeless, low-level language designed for a worse machine. On other extreme, today there's people coding OS kernels, drivers, etc in theorem provers that automatically extract code in C or assembly with safety and/or termination proofs. The only C compiler, CompCert, that passed fuzz testing bug-free in middle-end used such a method whereas those written in C had tons of bugs despite years of bug-hunting. Drat.