Assembly Programming

October 04, 2021

It’s my second week of Bradfield classes. We’re tackling a lot of assembly programming. Here are my unstructured notes, links and other various resources I’ve collected over the period of this week, mostly for my own reference, as I am Learning in Public.

Can you C that?

One thing worth noting before I proceed - learning C last year was an absolutely incredible investment. It is so common and present everywhere, truly my life has gotten easier since doing so. If you don’t know C, do yourself a favor and learn it.

First time assembly

My motivation behind learning assembly is rooted in the desire to have the ability to reason about programs performance. Although I don’t ever see myself writinig assembly to create programs, it is becoming increasingly more needed when trying to analyze what the compiler have produced. I have a very vague concept of what performance really means and what affects it. Although I understand big O notation and the reasoning around that, it still is just a tool to describe complexity of algorithms, not the performance of the actual hardware. The task before the first lecture is to write a bunch of simple assembly programs to get used to it. I’m going to start with reading chapter 3 of CS:APP in preparation.

It is possible to invoke the compiler with certain cli params to generate the assembly code form output. Reading it can expose the actual instructions to the computer and enable certain optimization capabilities if analyzed correctly. Exciting!

Other things that the assembly format can help us with:

  • Writing concurrent programs is tricky - we can understand through the assembly generated how program data are shared or kept private by different threads.
  • Understanding exploits used in malware is possible on the machine code level

Compiling and running assembly isn’t that straightforward. To run a example hello world program on macos I run:

nasm -fmacho64 hello_mac.asm && ld -L/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib -lSystem hello_mac.o && ./a.out

What a mouthful. It is using the nasm program directly to assemble the assembly code to something called a “relocatable object file”, then it uses the ld program to link this into an executable.

Assembly programming notes

  • rax is a temporary register, when we call a syscall, rax must contain the syscall number.
  • rdx is used to pass 3rd argument to functions
  • rdi is used to pass 1st argument to functions
  • rsi is a pointer used to pass 2nd argument to functions

Hex notation side note

One important thing I didn’t write down in last weeks post is that every hex digit maps to a nibble, and two hex digits map to a byte. Case in point:

Ox4c is hex for 76 dec, which is 0b01001100. If we slice the binary number at the nibble (four bytes) it’s easy to notice that 0x4 maps to 0100 (decimal 4) and 0xc maps to 1100 (decimal 12). Neat.

Links n’that

Second Assembly Lecture

Assembly epiphany

So, I feel like something very important happened this week. I’ve finally touched and interfaced with the machine instructions on a significantly closer level than I ever did - and that feels great. Bridging the gap between abstractions I was holding and getting closer to the machine, writing code knowing exactly how it’s going to be executed - that feeling is worth noting. It’s a feeling of newly found ability to control and observe the computer, on a whole new level.


Written by Daniel Kaczmarczyk, a software engineer and educator. you can find me on twitter or email me at daniel.kaczmarczyk@hey.com

a pale blue and yellow circle