Okay, time for me to bite on this thread.
Jay wrote (in part):
"...the lack of any assembler understanding by most of todays modern
programmers just slays me. I have seen many kids graduate from college today
that haven't the foggiest idea of what an interrupt is, how a status
register works, or even what an 8250 UART is..."
Jay came close, but somewhat missed the mark, because it's completely
possible to write nontrivial programs in assembler and still not have
any notion of what is _really_ going on with the underlying machine.
I've written three operating systems in _nothing_ but assembly
language -- a simple disk monitor for the DG Nova, a BASIC timesharing
system on the Nova, and a chunk of the OS for the BTI 8000.
I've also written them in BCPL, C, and MSL with requisite bits cobbled
together in assembler. Regardless of the level of abstraction
presented by the language, building a system that worked well
required an understanding of the underlying machine at a level
_below_ that presented by the instruction set architecture.
Certainly, slinging assembly language for a given machine always
gave me a better understanding of what a code generator for the
architecture in question would probably be doing (although I
was frequently annoyed to find that it had done something suboptimal),
but by the same token I watched _many_ people write assembly language
code that was semantically correct but which took poor advantage
of the machine because they didn't understand the implications
of the implementation decisions they were making.
Understanding what's going on in the underlying machine -- not
just the CPU, but the way the CPU transfers data to memory, the
way the I/O bus (or busses) behave and what's going on with the TLB
(if you've got one) is what's critical to making the machine
"sing". To put it in a slightly different perspective, there are
machines out there that I'd be nuts to write assembly code for,
save for very, very specific cases. Even a modestly competent
compiler will do a _far_ better job on generating code for
a superscaler machine, especially if the machine can do multiple
issue. Scheduling instructions by hand to avoid slips and stalls
on anything but very small hunks of code (say on the order
of maybe twice the number of pipeline stages) is generally
nuts, and it goes directly to insane when you thrown in
speculative execution, TBCs and other weirdness -- but that
doesn't relieve me of the responsibility to understand the
underlying machine when it comes to building my code.
<rant>
Sometime in the early-to-mid 80's things started going to hell.
I had to chastise a CPU architect because he'd come up with a
scheme that would have required 1.2 seconds to purge the TLB.
When I told him that such a latency was insane he countered
by informing me that they'd analyzed the source of the current
version of the system and found only two occurrences of the
purge instruction -- one in the initialization code and one
in the (duh) scheduler. His rational was simple: Since the
frequency of the instruction in a very large body of code
was _two_ it must not be executed very often. Later I
turned down the lead for Sun's trusted OS project when
I met the existing team of four and found that one of them
was a former database engineer and another had worked in
diagnostics but "...transferred to operating systems because
[she] didn't like working close to the hardware...".
"Hi, I don't like talking to hardware, but I want to work
on operating systems." It was enough to stagger the mind.
The situation hasn't improved. When working on the PlayStation II
core I was amazed to find that I had sixty-odd people on staff
and only _two_ of them understood the significance or purpose
of an address translation unit or why a PTE would need to have
a valid bit and why the _software_ would like that valid bit
to be stuffed somewhere on one end or the other of the PTE.
Most of the ones who had received their (usually advanced) degrees
in the prior two years didn't even understand the concept
of demand paging -- virtual memory was just some sort of magic
mojo that allowed code and data to occupy more space than
was available in physical memory. One guy thought that it
was done with on-the-fly data compression.
I'd love to see everyone take a course in assembly language,
but by the same token I'd like to see them do it on
bare hardware and have the course of instruction include
a discussion of what's going on with the underlying
hardware -- and then followed up with a CPU architecture
course. Berkeley did this in the 70's -- the assembly
course was part of the lower-division weeder series which
was followed by an upper-division architecture class
whenin one had to design and build a machine that
implemented a subset of the PDP-11 ISA (SSI and MSI
when I did it, 2901/2910 solutions were accepted about
two years later). This was in the era of ten-week quarters
and everyone had to work independently. These
days it's semesters and people work on teams modest sized
teams -- assuming they take the architecture class at all.
</rant>
--
Chris Kennedy
chris(a)mainecoon.com
http://www.mainecoon.com
PGP fingerprint: 4E99 10B6 7253 B048 6685 6CBC 55E1 20A3 108D AB97