I think I make a nice counter example. No, I'm not your average teenage programmer geek. I have a couple friends who are, but I'm not. I program. some. I could knonk off 300 lines in an afternoon, or a thousand in a week, or maybe more given more time, but I don't do huge projects. I mostly code Java. But, this fall, I decided to learn in detail how the very guts of a computer worked, from the logic gates up. I decided to build one.
A few friends and I undertook the task of designing and building a functional computer from basic logic gates and a few more complicated chips (the complete list: basic gates, adders, memory, multiplexers, latches, flip flops, and shift registers). The design goal was to have it work and have the minimum circuit complexity. Final design had around 200 discrete chips. As for specs, about 1MHz, with one instruction every five clocks. Some executed faster, but they had an idle cycle to make the routing logic simpler. One ALU (also used for address computation). Whole thing was 16 bits wide. Instructions were all 1 word (made loading from memory easier, but they were bitchy. Address came in the form of a register plus a five-bit offset). 8 registers, with r0 being a hard 0, r6 being the stach pointer (nothing special, just how it was used), and r7 being the program counter (made for PC relative jumps). ISA said r7 was read only, except for jumps, but the circuit couldn't care less.
There were nine total instructions, if you count IO read/write (no mem mapped io), which the circuit didn't implement. The ISA had it for completeness in case we cared to go back and change it. They were: load, store, jump, cond. jump, add, AND, the funky non memory referencing instruction that did stuff to one register (four kinds of shift, NOT, increment, and a byte swap (to deal with the fact that you couldn't load a byte from an odd address, you loaded from the odd address, which actually gave you the even one before it, and then that set a flag, which you could then conditionally byte swap on to get the right byte in the low order half of the register), in any combination; it just gave you access to the ALU control lines), io put, io get. We pulled some clever tricks so we could get a 32 bit multiply. All very cool. Did I mention it was probably the funkiest ISA ever designed?
We had hardwired electronics for loading off a carefully sequenced parralel port on a PC. Plan said we read in all 64K memory off the parralel port, let it run, and then read it back out. UI was nonexistant, just direct memory manipulation. Not even switches and lights. It was really cool. We designed a simpler chip than the original 8008, by transistor count. Programming was a *bitch*, but that's not the point. And you thought x86 memory addressing was bad...
Anyway, we had the vast majority of the circuit design done in the first semester. Interest in actually doing the wire wrap was low, and we were slightly behind schedule, and we ended up not building it. But, we still learned a hell of a lot. And, it appears as a quarter credit on my transcript (half-time, one semester). Oh, did I mention it was fun?
Anyway, I don't know x86 assembly, I don't really understand the guts of any OS, but I did craft an ISA and hardware to run it from the ground up. Oh, and we did go learn about the basic functioning of the CMOS we were building from, just for the hell of it. I'm not entirely sure what the point of this was, except to say that all the "old folks" out there who think your TRS-80s were cool, our computer was cooler. And only cost about $300. Well, had it been finished. And I'll bet we learned just as much, anyway. about other things, but still. Knowing that every extra chip you have is going to be another chip you (personally) have to squeeze on the wire-wrap board, purchase, put on the wire wrap board, verify the placement of, and wire-wrap properly, is as good a motivator for creative use of resources as anything. We're all heading off to college now. Of the 7 of us, one is in CE, on in CS, one in Chem E, one in Psych, and 3 undecided.