Hacker News new | past | comments | ask | show | jobs | submit login
Introduction to Computer Organization: ARM Assembly Language on the Raspberry Pi (sonoma.edu)
358 points by ingve on Nov 16, 2017 | hide | past | favorite | 35 comments



Awesome! Personally, I think that ARM assembly has a TON of potential for teaching people how to code and/or work with electronics hardware from a state of almost no background knowledge.

- They teach the concept of a computer program as a bunch of single small logical 'steps'.

- They make it easier to keep new students interested without plying them with pages and pages of 'magic code' - not only can you make a zero-dependencies program (in the case of simple mobile chips), your 'hello world' is actually in the physical world. An LED, a motor, what-have-you.

- The core instruction set for a Cortex-M0+ processor has what, 60 instructions? It's not very complicated.

On the con side of things, the whole idea of registers controlling hardware peripherals can be a little weird, and you have to get people comfortable with command-line debugging utilities. The concepts are simple, but GDB isn't. And many of the available IDEs aren't very cross-platform.

And I guess application processors also probably introduce their own extra complexities, compared to a Cortex-M line which is more comparable to an Arduino than a RasPi or Chromebook. But hey, there's also less hardware available with the sort of support that a Raspberry Pi has; the closest you'd probably get is a cheap generic $3-5 STM32F103C8 dev board.

If anyone else is interested in this sort of thing, the reference manuals provided by ARM are also very readable, for example: http://infocenter.arm.com/help/topic/com.arm.doc.ddi0484c/DD...


Maybe it's just me, but I don't think basing a whole book on a sparsely-documented SoC from a notoriously proprietary company is a great idea at all. There are plenty of other ARM processors with far more documentation available, and if your goal is to teach how computers work from the hardware up, also plenty of other much simpler and equally well-documented microcontrollers.


I also don't like that the Pi is not fully open, but it is also extremely available and cheap, so an ideal system for people starting out. And ARM assembly is a much nicer first assembly language than x86. A microcontroller is a possibility, but has its own barriers to entry (not a standalone computer in itself, can't be attached easily to display, etc.).

Maybe someday the lowrisc project will become a reality, and they can use that, and teach RISC-V instead.


6502s are cheap (though probably not as widely available as a complete system) and have an even simpler assembly language.


Well, if it's meant to serve the same purpose as the book I had for the same class this is likely targeted at, at the same University, with the same teacher who wrote a book for the class as a teaching aid, but using a small embedded Motorola platform 15+ years so, it's largely a teaching aid. When I took the class we got one of Plantz's prior books at the University bookstore, and it was photocopied and stapled together and like $12, which was real nice considering the cost of most class books.

Basically it's an embedded programming class where the teacher decided to write the manual and publish it as a book, so don't read too much into the platform they targeted beyond that. But the book we had was quite good if I recall (I might have it packed away somewhere in the garage), so I expect this one might be good as well.

As an aside, from looking at the linked author info, I'm happy Plantz finally got the chance to retire in 2004. He's a great teacher, but he was planning to retire before 2000 IIRC, and kept putting it off because of staffing issues, and then California university budget cuts and hiring freezes making getting good (actually, any non-temp) teachers hard. I'm sure he has a few happy cats, and if you ever run into him, he's got a few space program stories from the past to share. :)


I agree with you, but I think you're definitely talking more about teaching using a small microcontroller (Which a STM32 definitely qualifies as) rather then what they're doing here. The Raspberry Pi runs full Linux, so their code is a fair bit removed from direct hardware access and has a decent amount of boilerplate before you can begin to start messing around with GPIO. They do still eventually memory map the GPIOs, but IMO it's not really the same.

That said, I think the AVR ATTiny and ATMega chips easily fit the bill, and possibly better. From a teaching perspective, they meet all of what you're talking about, and IMO they're better for simple circuits like flipping LEDs because they can really work with basically no extra components - you can just plug it into a breadboard like any other simple chip.


Just do it Amiga style and boot directly to the application, no need to run Linux.

https://github.com/PeterLemon/RaspberryPi

https://hackaday.com/2014/06/23/programming-pi-games-with-ba...


Running baremetal on the Pi is about the same difficulty as running AVR code; you're under no requirement to run Linux. It's probably easier to teach architecture on the Pi too. The AVR c runtime stuff is poorly architected IMO.


100% has great potential for education, even (or especially) at a collegiate level.

Current CS student and in our architecture course we were learning surface-level x86 but mostly Y86, which is a toy language simplification of the x86 architecture. No real complaints about it, but friends of mine in electrical and electrical computer engineering (different school at my university) were learning ARM. Not only was it simpler it was much easier for them to implement non-virtualized code.

I thought the engineering department was doing it better.

+1 to GDB not being simple, was a larger learning curve for most of our class than C, x86, or any of the concepts.


I teach this stuff using a stm32l476vg discovery board at the Australian National University[0]. I re-wrote the course earlier this year to use that board (previous incarnations used a homebrew teaching architecture - emulated in software only).

It went really well - although there are always rough edges the first time through a course. Next year, I'm going to tighten things up (one of my jobs over the southern summer before the course runs again in Feb 2018).

Happy to answer any questions that folks have.

[0] https://cs.anu.edu.au/courses/comp2300/


Any plans to put the course materials online?


If you click through, pretty everything is online (except lecture recordings). Slides, lab material, etc. is all available. Next year I'm planning on releasing the lecture recordings as well.

Although as I said, there are certainly some things I'll tweak next year, having been through it once. I'm under no illusions about it being perfect :)


Sorry, missed the tabs! But this looks really awesome! By looks of it there are recordings of the lectures already up..

Will for sure go through the materials. If you ever come to sweden, let me buy you a beer!


The documentation for ARMv8, in my experience, is absolutely awful. I still, for instance, can't figure out how to copy a value directly from one register to another. `MOV [dest], [src]` doesn't seem to work, so I've just been doing `ADD [dest], [src], #0` in my recent projects in school.

EDIT: looking a little deeper into this website, it looks like a better resource than any other thing I've found.


"mov x5, x0" is the right way to copy from x0 to x5, so if that doesn't work for you then perhaps something is odd with whatever assembler you're using.

Note that under the hood "mov Xd, Xm" is a convenience alias for "orr Xd, XZR, Xm" -- the CPU itself will only see the logical-or, but the assembler and disassembler will understand the 'mov' syntax and should convert each way automatically. This is documented in the v8M ARM ARM in the "MOV (register)" instruction description. Perhaps whatever assembler you're using hasn't implemented that convenience syntax, but all the common ones (including the GNU assembler and LLVM assembler) should do, so it's surprising to encounter one that doesn't.


Here in the UK, we gave every 11-year-old in the country a Cortex M0+ dev board. Because that's how we roll, yo.

https://en.wikipedia.org/wiki/Micro_Bit


Very clearly written. Thanks for posting. Would recommend to anyone wishing to dive deep into architectures. And I love that you are teaching undergrads with the RP3 ;)

Anyone wanting more, the MIT Computational Structures courses are always available via EDX:

https://www.edx.org/course/computation-structures-3-computer...


Wow, this is absolutely amazing. I'm just starting out and this is actually pretty inspirational, especially as I have a few Pi's already.

I hear stories about the 'good old days' when everyone was hacking on some amazing open hardware and earning their chops knee deep in assembler etc etc.

This kind of feels like I might get a little taste of that by following this book.

Awesome!

PS - Is there a hardcopy or pdf available too?


I've had a quick look through and I really like this. Bookmarked for future reading.

As a security person, I have just one request - in 2.9 you explain/recall how functions look in C, then you explain printf, then the first C statement you execute is

printf("Enter an unsigned decimal integer: ");

Please, please can this kind of thing be printf("%s", "Enter an unsigned decimal integer: ");

I know this string is a compile-time constant, so it's not going to hurt anyone, but you're teaching people the old myth that printf(string) is the way to print a string and at some point they'll try this with a user-supplied string.

In my opinion, a printf with only one argument is always a code smell.

EDIT: also, the solutions to exercises 1 and 2 in 2.16 are vulnerable to buffer overflows.


> I know this string is a compile-time constant, so it's not going to hurt anyone, but you're teaching people the old myth that printf(string) is the way to print a string and at some point they'll try this with a user-supplied string.

I am also very security-conscious in my programming, but the rule that I apply is

   printf(string);
is the way to use if string is some compile-time constant that visibly contains no '%' character and

  printf("%s", string);
is the way to go otherwise. In this sense I consider the rule

> In my opinion, a printf with only one argument is always a code smell.

as cargo-cult coding.


Your answer is correct, secure and has fewer false positives than mine. But I interpret cargo cult to mean doing something with no unserstanding why it should work (and in the original example, ending up with "it doesn't work"). That's not the case here.

"Code smell" to me means code that should make you feel bad when reading/writing it, as opposed to code that's wrong - a psychological device to make code that often is wrong, always look wrong. The classic example is if(a = b) which is sometimes really what you want - but I'd write this if((a = b)) in this case to make it clear it's deliberate. printf("%s", str) is the same kind of thing, and it means when I'm reviewing code I don't have to go and check whether str really is a compile-time constant or not. Better still, it's also a sign to the human reader that there's no fancy formatting going on here - you're really just printing a string.

"Always use 2+ arguments to printf" is a rule for humans that has the advantage of being really easy to follow and to teach and avoids the most common version of the vulnerability. I don't mind people who know what they're doing breaking this rule (sometimes breaking a rule when you know it's ok is pretty much a definition of being an expert) but I do include the rule whenever I'm teaching printf to beginners.


From a security perspective I would be more concerned with using printf at all when puts/fputs would have been fine and less susceptible to possible run-time errors. If you're not really using a formatting template for anything meaningful, you shouldn't be using a string formatting function. So the point that you should "always use 2+ arguments to printf" holds, but the solution isn't to make the first argument "%s".


I accept your reasoning, but I am a little bit divided on this advice. On the one hand your reasoning is sound. On the other hand, in particular in an embedded or security field one wants to keep the code footprint really small if possible (fewer lines of code mean fewer lines of code that might contain a bug - of course under the assumption that the bug rate is constant in both code bases). So if one does not even have puts/fputs in the codebase, there trivially cannot be any obscure corner case bug in the used puts/fputs implementation.


From a security standpoint, if your standard I/O implementation has a bug in its `fputs`, it is broken on such a fundamental level that you should print it, delete it and burn the printed copy. Better to find this out with something relatively trivial with a minimal surface for errors like puts than through an obscure format string.

`printf` gives the caller more opportunities to accidentally cause bugs. The difference in LOC when comparing for example FreeBSD `puts` to `printf` variants is so great that if you had any reason to doubt the implementation of the standard library you would be better off writing your own formatting functions and print everything with puts/putc because that would likely be easier to test and verify than identifying all the edge cases in `printf` flag parsing.

Personally, I think either way to do it is fine, but since we're seemingly all in the mood to be picky about code smell, security and such, I thought I'd join in. In reality the examples mentioned are not production code, and they are likely to be used with GNU libc, not Cheap Chip Factory libc 0.0.1 alpha. In most cases, the standard library is well exercised because its use is ubiquitous. If that can not be assumed, and you're somehow stuck with a broken standard library, I'd rather go ahead and verify puts, and let you dig into the `vsprintf` parser and make sure it works in all the cases it gives the caller an opportunity to create :)


> Your answer is correct, secure and has fewer false positives than mine. But I interpret cargo cult to mean doing something with no unserstanding why it should work (and in the original example, ending up with "it doesn't work"). That's not the case here.

To me it also includes:

- forbid patterns that are perfectly fine (as in this example), but we nevertheless forbid them for a fear of wrath of a demon, eh, I mean for the fear that it might introduce some bug (without giving a very good reasoning).

- using "best practises" (in particular "best security practises") that are either not based on strong evidence, but on some obscure oral tradition/scripture that says this is the way to go.


Even better would of course be puts(string); -- no point in running a parser that will scan each character looking for formatting instructions, when you don't have any.

Using puts() will give you a terminating line feed though, which might not be what you want for a prompt. On the other hand that likely saves you from having to deal with output-flushing and so on ... Might be nice for teaching.


fputs(stdout, string) avoids the newline too, although you'd now have to teach two functions (printf, fputs) as well as saying what "stdout" means. In a teaching context, printf("%s", string) is probably best as printf is being used in other lines in the same file already.


What sacrifices you are willing to make in a teaching context is a matter of taste. You draw the line somewhere between using printf in an entirely acceptable way where fputs would have been better suited, and using printf in another entirely acceptable way where fputs would have been better suited. That seems inconsistent and hard to justify.


Massive upvote, the standard text book for Computer Organization is Patterson and Hennesy's "Computer Organization and Design: The Hardware/Software Interface"

Its a lovely book, but its hard to get hold of MIPS processors these days. Hopefully this creates a new generation of devs which can tinker with real hardware and are armed with proper education behind how it all works.

Super happy, wish I had this during mys schooling. :)


There are now ARMv8 and RISC-V editions of COAD. I’m sort of waiting for the second edition of the ARMv8 version. However at this point I prefer COAD to CAAQA which is bloated with IMHO non CA stuff.


Back in the 8/16 bit days, ARM assembly was said to be one of the best features of Acorns — even compared with 68k asm. Maybe it’s finally time to look at this...


Yes, although the new instruction set in ARMv8 removes several of the things that made programming in 'classic' ARM assembly such fun on the Acorn, such as the free barrel shifter on most arithmetic ops, conditional execution on all instructions and fast multiple loads/stores with groups of registers. These have gone for various reasons; the fully-flexible barrel shifter is awkward at high frequencies with deep pipelines, the conditional execution flags became a waste of opcode space as branch prediction improved and the load/store multiples required microcode on modern implementations and so increased complexity.


Superb. This is so neatly and thoughtfully organized. Presented in simple terms and covers a lot of ground. Great stuff to build upon.


This looks like a superbly designed curriculum.


Thanks for posting!




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

Search: