Ask HN: Going low-level – what to learn next?

100 points by visil ↗ HN
I've been interested in (relatively) low-level programming for quite some time. I know C, I can read assembly (write - not so much) and I have basic understanding of CPU (registers, cache, stack and whatnot). What should I read or learn next to be able to reason about things like cache usage of a C program or possible low-level microoptimizations? It's still just a hobby for me for the most part, so it's not that I'm trying to prematurely optimize some production code. I'm just interested in how it all works under the hood.

58 comments

[ 4.3 ms ] story [ 112 ms ] thread
I would recommend either to build up some RTOS/OS knowledge or excercise your skills in Low-levelish game programming with maybe C and SDL. I found especially these two very rewarding and I'm also making a living on the former for 15 years.

https://wiki.osdev.org/ is a good source for getting a hold in OS development

I love Kip Irvine's book on x86 assembly. Very practical for building small programs, with questions and exercises. It is in the Windows environment though, but I don't think it matters significantly much, instructions are the same after all.

http://asmirvine.com/index.htm

RTOS, robotics, virtual machines, bare metal games. Or move on to the GPU and pick up CUDA?
Unless you are working on firmware for the actual actuators I would argue that nowadays robotics is not that low level as OP is aiming for.
Nowadays robotics is about throwing stuff (including ROS, necessarily) in docker containers and running them on an Ubuntu 24.04 onboard the robot, and then adding GPUs and say "so that we can do AI in the future", right?

At least that's my experience :-).

Join the Handmade Network [0]. Much can be learned by hanging out with the right kind of competent/enthusiastic crowd. And if you allow the plug, I run the conferences [1].

[0] https://handmade.network

[1] https://handmadecities.com

It seems that I've been on a right track in some sense - I stumbled upon Handmade Network a few weeks ago!
This is one of the coolest things ever.
If you want something on the more application side, I.e. utilization of low-level techniques, I can highly recommend looking into game engine development, even if you aren't interested in games per say.

I've recently enjoyed Game Engine Architecture, mostly because there is an interesting mix using low level techniques to solve problems a normal application wouldn't be required to fix.

Game development in general is case for tuning yourself to when you should utilize high level programming techniques, and when required dropping into low level optimization to solve local problems.

> What should I read or learn next to be able to reason about things like cache usage of a C program or possible low-level microoptimizations?

Learn how to use a profiler like Linux' perf, VTune or Apple's Instruments. Which means interpreting the results of it to optimise your code.

Game engine development or going even lower and dabbling in embedded. Embedded in particular helped me to understand computers way more in depth than I would have just sticking even to application-side C.

Also, learn Rust.

to be honest, i think you have it all there - now write something useful using it
This is really the key. Grinding something you don't actually enjoy or find useful is pretty deathly, even if you get actively paid for it. "Low level", as others have said, is a very, very broad field and if you have an general interest in lower-level stuff, home in on what specifically interests you by trying to achieve some actual goal of use or interest to you.

It doesn't really matter what it is, it could be porting FeeeRTOS to your toaster, writing a kernel driver for something, reversing some device protocol, implementing something on an FPGA or building some embedded device or hacking another one into something else. Just get stuck into something and feel the gravity of your open interests.

Nothing you learn along the way will be a waste.

Might not exactly be very low level but I really liked the learn c programming by dr. chuck youtube course on freecodecamp youtube
an optimizing Lua or Lisp compiler
Yes: +1, this.

Learning Lua is a great way to get introduced to a lot of low-level concepts, from bytecode to VM's to language design and beyond.

Ironically, I've been avoiding learning Lua for quite some time for some reason. I guess it's finally time to give it a try!
Lua is one of the most amazing bits of programming tech you can use... I have done all sorts of crazy things with it, from applications-with-databases to realtime scientific analysis, games engines and games ahoy, simple automation tooling for devops, and more. I recently decided to sit down and organize a few hundred directories, each with more than 20,000+ files in them, and I've now built a system that my colleagues are asking about installing for themselves..

Its just such a great tool, please don't deny yourself this wonderful experience. Get the VM, put it in something - or find a VM somewhere in something already, and have a lot of fun. And don't forget to make sure you know what a sparse array is, and why pairs() and why ipairs() .. you'll be glad you did!

PS - don't fall for the hype, you can do someTable[0] = "first", someTable[1] = "second" all you like .. :)

Proceed to highload.fun. Read the resources in the highload.fun wiki.
Go all the way down, grab an FPGA dev board and learn Verilog/VHDL!
What you're basically after is some "Tooling and Methodology" studies for embedded. You've got the basics, but now you need to learn some more tools and the methods that make those tools really useful to the embedded/low-level context.

Some simple things you can do:

* Get yourself a suitable embedded development system - I would recommend anything ESP32'ish that suits your fancy such as a Liligo or Watchy ESP32-based watch, or PineTime if thats more up your alley - and then write some little apps for it.

* Get to know Godbolt with a great deal of intimacy, just as a general approach to understanding what is going on:

https://godbolt.org/

* Invest a little workbench time in some of the various embedded frameworks out there - platformio, FreeRTOS, etc. and, very important: learn the Tooling And Methodology techniques that these frameworks manifest.

* Invest some workbench time in the RETRO Computing Scene. Seriously, you can still learn extremely valuable principles of tooling and methodology from an 8-bit retro system from the 80's. Get your favourite platform, get all its tools onboard, engage with its community - you will learn a lot of things that are still entirely relevant, in spite of the changes over the decades.

* Get into the F/OSS tooling/methdology flow - find software projects that are interesting to you, find their repositories, learn to clone and build and test locally, and so on. There are so many fantastic projects out there for which low-level skills can be developed/fostered. Get onboard with something that interests you.

Good luck!

If you like game progrmaming I recommend some of the low level C courses by Pikuma. I've done the 3D graphics from scratch course and will do the Playstation 1 Programming course next.
What do you want low programming for?

I learned assembly so I could disassemble and understand programs.

I learned C so I could use all the libraries that people had made and their frameworks than later because C++, Objective C, C#, java, python and other derivatives.

I wanted to manipulate images, speech and video and using high level programming language was so inefficient so I continued using C.

I learned FPFGAs again because I needed efficiency or the things I wanted to do like controlling robots did not work at all(they moved so sluggishly).

I love learning things, but that was never enough for me to learn something deeply when problems appear.

While there are a ton of replies here with great ideas, you make the most important point: most of the best work (across disciplines) is done when you have an objective. Find an issue in need of a solution (or better solution) and use the tools available (or make better ones) to accomplish the task at hand.

My suggestion would be to find something that can be improved on in daily life and then learn the skills necessary to make that improvement, to include the trades more physical in nature, such as woodworking, 3D printing, etc. Then, combine those skills with, say, programming embedded devices, etc. or whatever else is needed to accomplish the task.

This ultimately provides a diverse skill-set, feeds the desire to learn, and provides legitimate improvements to quality of life - both tangible and intangible.

my approach is always to pick an idea for a project that I care about and go full autistic not-invented-here in implementing it. i never finish such things, nothing I'd show/publish, but by the time I'm sick of it, I've learnt a huge amount.
Arduino/embedded, but forego the "drivers" - interact with the registers directly. I recommend anything RP2040-based (the Pi Pico is the first-party option) because the datasheet stands completely alone in terms of quality.
If you want to "go low" in the operating system, you could write a Linux kernel module:

https://sysprog21.github.io/lkmpg/

https://blog.sourcerer.io/writing-a-simple-linux-kernel-modu...

If you want to "go low" in the way hardware works, you could try and write an interrupt handler on an embedded device.

If you want to "go low" in how optimizations work in application development, you could try and implement microbenchmarks and look at flamegraphs.

https://github.com/brendangregg/FlameGraph

https://bheisler.github.io/criterion.rs/book/index.html

Low-level means different things to different people:

1. The best source of low-level information on things like operating systems (writing your own) etc is https://wiki.osdev.org/Expanded_Main_Page

2. Compiler related low-level should include a read through Crafting Interpreters (https://craftinginterpreters.com/), even if all you're going to do is create compiled languages.

3. Hardware type low-level (where you build your own logic) is a long and ultimately non-rewarding path. I would suggest https://eater.net/8bit/

All those links are only starting points; use them to find a direction in which to head.

[EDIT: I also recommend writing a eBPF module for linux - easier than writing a kernel module, with just as much low-level hooks as you might need].

> with just as much low-level hooks as you might need

eBPF is great for some things and is "easier" for some things but kernel modules are able to do _way_ more by design.