Hacker News new | past | comments | ask | show | jobs | submit login

I'm not talking about the instruction set, or teaching basic assembly (probably anything except Malbolge is suitable for that).

Let's look at just one thing every programmer has to deal with, memory.

On an LC-3, the address space is exactly 64KiB. There is no concept of missing memory, all addresses are assumed to exist, no memory detection is needed or possible, and memory mapped IO uses fixed addresses.

There are no memory management capabilities on the LC-3, no MMU, no paging, no segmentation. In turn there are no memory-related exceptions, page faults or protection faults.

When an x86 machine boots with 1MB of RAM, the 4GB address space still exists in full, but accessing certain addresses will cause bus timeouts, crashes. One must track and manage available memory. There's a BIOS, and manually probing memory locations may trash its critical structures. There's INT 0x15.

I picked memory arbitrarily but you run into the same limitations no matter what you pick. Would a students who was educated on LC-3 know how a computer keeps time? Of course not, there's no PIT, there's no CMOS clock. Would they have thought about caches? Nope.

Oh, but wouldn't a student who implements a timer emulation extension for LC-3 learn more about timers than somebody who just learned to use an x86 PIT? Alas, no. There are 20 equally easy and reasonable mathematical ways to implement a timer abstraction. A good 15 of these are physically impossible on real hardware, out of the remaining 5 two would be prohibiitively expensive due to electrical engineering reasons, one has never been implemented in real hardware due to historical accidents, and two are designs that are actually in use. So to write timer emulation that teaches you anything at all about how actual timers work, you'll have to look at and understand a real architecture anyway.

That's why educational architectures are so contraproductive. They abstract away exactly the things that make modern computers modern computers. One comes away with fundamentally wrong ideas about what computers do and how they actually work, or could work.

It's like learning to drive in GTA: in principle, there could be plenty of skills that transfer to the real thing, but in practice you'll prefer to teach how to drive to the person who didn't play GTA at all.




There seems to be a misunderstanding what fields those learning architectures are geared towards.

They are usually not for learning about application or even systems programming, in assembly and otherwise. They are about CPU architectures (and some surrounding concepts) themselves. The goal is to be able to quickly build your own emulator/simulator (like the VM behind the link), and maybe an assembler. Or, coming from the other side, given a working emulator/simulator, implement a high level language compiler, such as for a simplified C language.

In both those goals the CPU architecture is geared towards quickly converging towards a working system. So of course they don't require you to implement (as someone learning architecture engineering) or even use (as someone learning to build a compiler) an entire MMU, much like your first project car likely wouldn't contain a computerized double clutch transmission. Instead, they are simplified CPU architectures that allow you to make steady progress, without being slowed down by the tedious complexity that a real architecture brings for reasons that are not relevant yet when starting out.

Then, once that is achieved, you can freely add things like an MMU, a cache controller, maybe shift towards a pipelined or even superscalar architectures...

Besides, a very large class of computers don't have many of the things that you mentioned. For one, even very advanced microcontrollers explicitly don't even have an MMU, because that would destroy latency guarantees (very bad for automative controllers). For the rest, I've got to say that there is a certain irony in complaining that computer architecture students don't know about "modern computers", while in the same breath mentioning things like INT 15h, segmentation, and x86 PITs, as if we were in the 1990s.


> On an LC-3, the address space is exactly 64KiB. There is no concept of missing memory, all addresses are assumed to exist, no memory detection is needed or possible, and memory mapped IO uses fixed addresses.

> There are no memory management capabilities on the LC-3, no MMU, no paging, no segmentation. In turn there are no memory-related exceptions, page faults or protection faults.

Sounds an awful lot like a Commodore 64, where I got my start. There's plenty to learn before needing to worry about paging, protection, virtualization, device discovery, bus faults, etc.

It sounds like it's not teaching the wrong things like your GTA driving example, but teaching a valid subset, but not the subset you'd prefer.


Interesting. How would you advocate actually gaining that knowledge then?

It seems like a student would need to know a significant amount of coding in order to learn those abstractions in an interactive manner.

And by learn them I mean learn them (not just following a tutorial), organizing the code for a fully working x86 architecture is no joke.

But a student with that level of skill probably doesn't need to learn the x86 architecture so intensively, they are probably already employable.

I am asking this seriously, by the way, not trying to nitpick. I'm trying to put together a free course based on the video game Turing Complete[1] but from what you're saying it sounds like it might not be very effective. (to be clear the goal is to teach programming, not Computer Engineering)

[1]: https://store.steampowered.com/app/1444480/Turing_Complete/


Very good question.

My working assumption throughout was that the people in a computer architecture class already had 1 or 2 semesters of other programming courses where they worked in a high-level language, and are looking to learn how computers work "closer to the hardware". And educational architectures create a completely false impression in this domain.

If I had to teach assembly programming to people who never programmed before, I'd _definitely_ not want to start with x86 assembly. I'd start by teaching them JavaScript so that they can program the computers that they themselves, and other people, actually use. At that point they'd be ready to learn computer architechture through an x86 deep dive, but would no longer need to learn it, since, as you said, they'd probably already be employable. But the same goes for learning LC-3, and much more so.

To be honest, my opinion is only that educational architectures are a poor way to learn what modern computers actually do, and while I think I have good reasons for holding that particular opinion, I don't have the breadth of experience to generalize this specific observation into an overarching theory about teaching programming and/or compsci. I hope your course will be a useful resource for many people, but I doubt listening to me will make it better: my experience does not generalize to the domain you're targeting.


Many years ago I taught CMPT215 - Intro to Computer Architecture. This was a second year course and taught MIPS assembler. There’s a chain of follow on courses culminating in a 400-level course where you implement a basic OS from scratch on x86 (when I took it) or ARM (present day, I believe).

MIPS was, I think, a decent compromise between academic architecture and industrial architecture. There was a decent amount of practical stuff the students had to deal with without having to eg do the dance from x86 real mode to protected mode.

One of the most memorable lectures though was on the second last day. As it turned out I had gotten through all of my material one say early. We had a review/Q&A session scheduled for the last day but needed 1h30 of filler. I ended up putting together a lecture on JVM bytecode. Throughout the course I would often use C <-> MIPS ASM throughout examples because the 214, which was a prerequisite, was a C course. All of their first year work had been in Java. Anyway, we took real Java programs and disassembled them down to bytecode and walked through it, showing how it’s very similar to hardware assembly but with extra instructions for eg placing objects on the stack or calling methods on objects. The class ended up going almost an hour over because everyone was oddly engaged and had a ton of questions.


This is very interesting. I assume that most of the students would never manage to get a similar job such as working with JVM or MIPS assembly, but I'm sure they would recall your class with a smile.


The thing is that you are conflating CPU architectures with computer architectures; In academia they are treated as two different educational topics, for good reason.

The first one covers the lowest level of how logic gates are physically wired to produce a Turing-equivalent computing machine. For that purpose, having the simplest possible instruction set is a pedagogical must. It may also cover more advanced topics like parallel and/or segmented instruction pipelines, but they're described in the abstract, not as current state-of-the-art industry practice.

Then, for actually learning how modern computers work you have another separate one-term course for whole machine architecture. There you learn about data and control buses, memory level abstractions, caching, networking, parallel processing... taking for granted a previous understanding of how the underlying electronics can be abstracted away.


I appreciate the candid response. I have noticed there is a class of very intelligent, well-educated adult learners who have nevertheless been unexposed to software education until adulthood who are now looking for a career change. I've found that there is a lot of difficulty initially with combining abstractions, i.e., "a variable holds a value, a function is also a value, a function is also a thing that sometimes takes values and sometimes returns values, therefore a variable can hold a function, a function can be passed as an argument to a function, and a function can return a function".

Reasonable adults might have reasonable questions about those facts, such as, "what does any of that have to do with a computer?"

To my embarrassment, I realized they were completely right and my early exposure to software made me overlook some extremely important context.

So for these adults, the expectation of struggling through a few semesters/years of javascript is not an optimal learning route.

My hope was that working from the logic gate level up would at least provide the intuition about the relationship between computers (Turing Machines, really, not modern computers) and software.

However, I think based on your excellent critique I will be sure to include a unit on how "educational architectures are very different from modern architectures and I may have ruined your brain by teaching you this" haha.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: