Like so many other people, over the last few weeks of lockdown, I’ve been trying to use the extra time that I’m not spending commuting to work to learn some new skills that I’ve always meant to get around to learning. In particular, I been teaching myself ARM Assembly Language programming.
I’ve always been more interested in the low-level side of computer programming – than I have been in applications. I’ve always (even as a child) wanted to know how the magic box that is the computer actually works. I’m not new to assembly programming: I’ve done all kind of odds and ends of assembly over the years: from (emulated) 6502 on the KIM-Uno, to the real thing on a BBC model B; as well as more recently taking a course looking at the (also emulated) Atari 2600, and following along with Ben Eater’s fabulous breadboard 6502 series. The observant amongst you will note a common-thread there – the iconic 6502 processor (yes; I was an ‘80s kid). In addition to this, I have also done some assembly programming for PIC microcontrollers, and (rather more years ago than I’d care to admit!) back when I was doing my A-Levels in college I learnt a little x86 too; but I’ve never done anything much with ARM CPUs. Given my professional interests in the Internet of Things & cybersecurity, I thought that learning ARM assembler would be fun (and potentially useful in the future too, perhaps).
Interacting with the Operating System
Unlike some of the older computer systems that I mentioned earlier, the vast majority of microprocessors (and even some microcontrollers) today run some sort of operating system. The point of an operating system is easily missed today because of their ubiquity; but they essentially exist provide services to user programs. Without an OS, every application would have to include it’s own code to drive all of the peripheral devices: vital functionality such as reading a keyboard, displaying things on a screen, and providing an abstraction of storage devices to enable users to work with the concept of files.
In 2020 there are basically two types of OS in regular use. There are the POSIX (Portable Operating System Interface) standard compliant OS (as implemented in Linux, MacOS, BSD: and to some extent in iOS and Android too); and Windows. Given that I am not a Windows user (apart from for Office stuff at work) – the choice here was easy. So for my learning environment, I pulled out a Raspberry Pi (running Raspbian Linux): with its ARM Cortex-A72 processor.
I’ve heard it said that in order to learn to program in C, you need to understand everything – before you can do anything; I’m not sure that’s really true for C, but I’d argue that it’s undeniably for assembly language. When learning to program in a new language, the canonical introductory program is is Hello World; but in many assembler books it’s often one of the very last things you’ll see. There are some good reasons for that: not least of which is that because there’s almost no abstraction from the underlying OS when it comes to printing a message on the screen. Since we don’t have a handy
print() function: we have to set about directly request that the OS shows our message to the user.