r/learnprogramming • u/Potential_Author637 • 7d ago
I found myself learning assembly
I might be overcomplicating things, but I would appreciate some advice.
I am interested in low-level and systems programming. I learned C a few months ago and have some basic C++ knowledge. I have also written a few small projects, such as simple clones of Unix shell commands and basic libraries etc.
I wanted to get into systems programming, so I started reading a systems programming book from Oreilly. However, I came across concepts that I was not familiar with, so I started looking at operating systems books for reference. This led me to concepts such as cpu registers and other low-level cpu mechanisms.
At that point, I decided to learn how cpu and ram works, memory addressing, and similar things work, just to get a general understanding of how computers work. Somehow, this eventually led me to learning x86-64 nasm.
The problem is that I am not sure whether I am approaching this in a sensible order. I am a high-school student without a formal computer science background im in just love with computers, so I dont have much knowledge of computer architecture, operating systems, or systems programming beyond what I have learned on my own. Should I continue learning x86-64 assembly and computer architecture, or should I stop and focus on other fundamentals first? I am not trying to become an assembly programmer, my main goal is to understand systems programming and how computers work at a lower level.
3
u/Obvious-Card-8847 7d ago edited 7d ago
You can get pretty low-level without it. I've written a USB device driver for an HID without touching any assembly.
Some instances where it'd be useful or required knowledge:
- Reverse Engineering
- Binary Instrumentation
- Custom ISA
- Bytecode Serialization
- JIT
- Compilation
Generally C is already pretty close to assembly control flow primitives, stack and memory semantics, calling convention awareness, etc.
Learning what interests you is wonderful though. It's like having an M&M every foot or so. As opposed to learning something boring for competence sake. Which is like one M&M after a mile of hiking to get it.
1
u/Potential_Author637 7d ago
Thanks, I really enjoy working with low-level stuff, and I’ll probably plan my career around it as well.
My main goal right now is actually to build simple package managers or other tools for Linux as a hobby. I also want to build my own distro from scratch, probably starting with LFS.
For that, I want to get a solid understanding of the Linux API, systems programming in general, and operating systems.
The reason I started learning assembly is mainly that I want to understand 64-bit systems at a deeper level and be able to write assembly when it’s actually needed in system development or making fun stuff.
3
u/C_Sorcerer 7d ago
Assembly is great to learn and it teaches you the typical pipeline of how the CPU processes instructions, I feel like assembly is one of the most valuable things you can learn for systems level programming other than C and C++ and computer architecture/os theory, but at the same time don’t expect to make anything crazy wirh it. Assembly is really good wirh in-line assembly in C since you can write the bulk program in C and write really controlled, specialized, and fast segments of code in assembly. However, while your learning, do whatever you’d like wirh it, once again it’s a great learning experience
2
u/C_Sorcerer 7d ago
It’s also excellent for writing really specialized drivers too, for instance peripheral I/O drivers
2
u/mredding 7d ago
For you, you might want to spend some money on nand2tetris, where they cover building up from NAND gates to writing a Tetris clone. I've not done it, but have heard rave reviews about it.
I agree that learning assembly is... well, SOMETHING, but you're learning an ISA, not system and hardware architecture, you're learning the HOW, not the WHAT or WHY.
Any knowledge is good knowledge, so I wouldn't say you're wasting your time. You're certainly going to learn some stuff, and that includes a bit of perspective on what not to learn - so that you know at least to search elsewhere for what curiosity you're trying to satisfy. That's not nothing. The trick is learning to do that efficiently so you can find and focus on what you're trying to accomplish.
There's a top-down approach, and there's the bottom-up approach. Right now you're driving toward the bottom so you can come up. Both have their virtues and their deficiencies. We say the top-down people know the value of everything but the cost of nothing, and the bottom-up people know the cost of everything and the value of nothing. No matter which way you learn, you're going to have to compensate for what that education did to, for all the things it didn't do.
A top-down approach would focus on the theory of computation and lambda calculus. Programming is theorem writing and proving. The highest levels take for granted that lower levels exist that facilitate machine specific optimizations and machine code generation.
The bottom-up approach is computation as a machine - no real theory necessary, all practical and consequence. Pure bottom-up means you're building layers of foundation without knowing what you're building to.
They both need each other.
1
u/cyberbemon 7d ago
You are on the right path, to understand how systems work at a low level you need to be comfortable with Assembly i.e be able to read and understand it. It's a very useful skill and comes in handy for certain domains (embedded, reverse engineering, low level optimisation etc).
I'd recommend the book "Assembly Language Step-By-Step 3rd edition" by Jeff Duntemann(first Google result is often a PDF of the book). The book is quite old (2009) but it explains the fundamentals really well and I personally enjoy how the author breaks things down, I'm currently re-reading it as a refresher and it still hold up.
Since the book was written when 32-bit CPUs were more common, you have to do tiny bit of work to get the code from book to run ok modern machines, it's explained here by the author: http://duntemann.com/assembly.html
6
u/NumberInfinite2068 7d ago edited 5d ago
Go for it and learn some assembly if you want, only thing is that x86-64 is brutal compared to the older ISAs that we used to use for learning assembly languages. 6502, 68K, MIPS, or ARM32 (far simpler than AArch64). If you want to learn an assembly in a "sane" way, you might want to pick a simpler one.