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
raxis a temporary register, when we call a syscall,
raxmust contain the syscall number.
rdxis used to pass 3rd argument to functions
rdiis used to pass 1st argument to functions
rsiis 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.
- Learning Assembly for linux-x64
- NASM Tutorial
- Linux Syscall Table
- NASM Manual
- Intel Processor Manuals
- CRDTs go brrr
- x86 NASM Assembly Crash Course
- 5 Hobby Projects - Joe Armstrong EEF17
- A strange Request
- Reflections on a decade of coding
- weird blog
- future of work is written
- in defence of bulb studies
- Rollercoaster Tycoon was written in 99% in assembly.
- Spy on the Kernel
- bracket pair colorization
- smashing the stack for fun and profit
Second Assembly Lecture
- Why Isn’t Functional Programming the Norm? – Richard Feldman
- smalltalk and squeak
- command line heroes ‘95
- x86 NASM Assembly Crash Course
- go ballast
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.