| ▲ | My application programmer instincts failed when debugging assembler(landedstar.com) | |||||||||||||||||||||||||||||||||||||||||||
| 24 points by lifefeed 2 days ago | 17 comments | ||||||||||||||||||||||||||||||||||||||||||||
| ▲ | xg15 5 hours ago | parent | next [-] | |||||||||||||||||||||||||||||||||||||||||||
> Abstractions. They don’t exist in assembler. Memory is read from registers and the stack and written to registers and the stack. [...] But my application-coded debugging brain kept looking at abstractions like they would provide all the answers. I rationally knew that the abstractions wouldn’t help, but my instincts hadn’t gotten the message. That feels like the wrong takeaway for me. Assembly still runs on abstractions: You're ignoring the CPU microcode, the physical interaction with memory modules, etc. If the CPU communicates with other devices, this has more similarities with network calls and calling the "high level APIs" of those devices. For user space assembly, the entire kernel is abstracted away and system calls are essentially "stdlib functions". So I think it has a different execution model, something like "everything is addressable byte strings and operates on addressable byte strings". But you can get that execution model occasionally in high-level languages as well, e.g. in file handling or networking code. (Or in entire languages built around it like brainfuck) So I think assembly is just located a few levels lower in the abstraction pile, but it's still abstractions all the way down... | ||||||||||||||||||||||||||||||||||||||||||||
| ▲ | Surac 14 minutes ago | parent | prev | next [-] | |||||||||||||||||||||||||||||||||||||||||||
I was luck to learn asm on a very simple 8 bit CPU (6502). It had a very limited register set (3) and instruction count. I think if you realy like to dive into the ASM topic try to find a small easy CPU model and use a emulator to run your code | ||||||||||||||||||||||||||||||||||||||||||||
| ▲ | david-gpu an hour ago | parent | prev | next [-] | |||||||||||||||||||||||||||||||||||||||||||
My unsolicited friendly advice to software folks who are curious about assembly languages is: ask yourself what is it that you expect to get out of it. If you want a better understanding of the architecture, reading the documentation from the hardware vendor will serve you better. If you want your code to be faster, almost certainly there will be better ways to go about it. C++ is plenty fast in 99% of the situations. So much so that it is what hardware vendors use to write the vast majority of their high-performance libraries. If you are just curious and are doing it for fun, sure, go ahead and gnaw your way in. Before you do so, why not have a look at how hand-written assembly is used in the rare niches where it can still be found? Chances are that you will find C/C++ with a few assembly intrinsics thrown in more often than long whole chunks of code in plain assembly. Contain that assembly into little functions that you can call from your main code. For bonus brownie points, here is a piece of trivia: the language is called assembly and the tool that translates it into executable machine code is called the assembler. | ||||||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||||||
| ▲ | userbinator 7 hours ago | parent | prev | next [-] | |||||||||||||||||||||||||||||||||||||||||||
Asm is simple enough that "mental execution" is far easier, if more tedious, than in HLLs, especially those with lots of hidden side-effects. The concept of a function doesn't really exist (and this is even more true when working with RISCs that don't have implicit stack management instructions), and although there are instructions that make it more convenient to do HLL-style call and return, it's just as easy to write a "function" that returns to its caller's caller (or further), switches to a different task or thread, etc. If you're going to learn Asm, then IMHO you should try to exploit this freedom in control flow and leverage the rest of the machine's ability, since merely being a human compiler is not particularly enlightening nor useful. | ||||||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||||||
| ▲ | jagged-chisel 3 hours ago | parent | prev | next [-] | |||||||||||||||||||||||||||||||||||||||||||
I think lots of commenters are being unintentionally pedantic. It’s clear that there are different types of abstractions one is concerned with when programming at the application level. Yes, it’s all abstractions on top of subatomic probability fields, but no one is thinking at even the atomic level when they step through the machine code execution with a debugger. | ||||||||||||||||||||||||||||||||||||||||||||
| ▲ | Chaosvex 7 hours ago | parent | prev | next [-] | |||||||||||||||||||||||||||||||||||||||||||
Not sure what to take away from this. __abstract works because GCC allows it as an alias to __abstract__, not because parsing the syntax is forgiving. Abstractions do exist (disagreeing with the single other post in here) and they also exist in most flavours of assembly, because assembly itself is still an abstraction for machine code. A very thin one, sure, but assemblers will generally provide a fair amount of syntactic sugar on top, if you want to make use of it. Protip: your functions should be padded with instructions that'll trap if you miss a return. | ||||||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||||||
| ▲ | Kiboneu 8 hours ago | parent | prev [-] | |||||||||||||||||||||||||||||||||||||||||||
Neat. The author is about to stumble onto a secret. > In Sum# > Abstractions. They don’t exist in assembler. Memory is read from registers and the stack and written to registers and the stack. Abstractions do not exist periodi. They are patterns, but these patterns aren’t isolated from each other. This is how a hacker is born, through this deconstruction. It’s just like the fact that electrons and protons don’t really exist. but the patterns in energy gradients are consistent enough to give them names and model their relationship. There are still points where these models fail (QM and GR at plank scale, or just the classical-quantum boundaries). It’s gradients all the way down, and even that is an abstraction layer. Equipped with this understanding you can make an exploit like Rowhammer. | ||||||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||||||