How can I experiment?
How do I go from instructions in a text file, to compiling, to getting input in some form? What programs do I use (on Linux)? What commands do I run? What are fun projects that are worthwhile doing with assembly?
Beyond that, what are good applications of assembly in general? Where should I use it in my day-to-day development projects? Where can I read about best practices? Where can I find good examples of x86_64 assembly programming?
It's really easy to merely describe the instructions, the registers, the mapping from compiled procedural languages - but I feel like that information is superficial so long as you don't tell us how to apply it.
It's focused on actually doing rather than how stuff works. In order to succinctly be able to present this, I had to choose a target platform, which unfortunately seems not to be the one that you prefer.
My tutorial targets OS X, and there is great similarity between coding assembly on OS X and Linux. The tutorial does not spend much time pointing out these similarities, and you unfortunately don't get sensible error messages if you make mistakes. Never the less, you might want to try :)
I long time ago I wrote a threaded/fiber system for DOS. It was mostly C, but the task switching and interrupt stuff was all assembly. It's basically an implementation of setjmp/longjmp hooked up with timer interrupts.
You might use it in your day to day if you were a driver developer for something like PCI chipset drivers, network drivers, things like that. Even then, C is usually preferred. I worked for a company that wrote drivers for scsi jukebox systems and they had a compete software suite written in 100% assembly. It was very clean, modular, well commented, and even object oriented. Yes, you can have objects in assembly, you just have to make your own this pointers. Since the language itself is so limited, most good assembly programs have a lot of macro wizardry involved.
What I've found with most assembly language textbooks and online resources is that while the basics get covered well enough, the fundamental knowledge base is often skimmed over, as are the many assumptions and conventions that are made in how the CPU is supposed to work.
I first learned 8086 assembler from Peter Norton's book (http://www.amazon.com/Peter-Nortons-Assembly-Language-Book/d...), and more than any other resource, that taught me about how things actually work. It goes beyond just knowing the registers and the mnemonics and explains in a fantastically clear way all the implicit work that's going on behind the scenes, even in assembly code. From the stack to data segments and direct video control, I learned more about how computers work from this book than from my entire college Computer Science program. And I didn't even have an assembler to actually try any of the code at the time I read it.
I'm not sure if the book would still hold up from a practical perspective, as it does focus very much on MS-DOS-specific interrupts. So what I wonder is... is there a similar resource available today for learning what's going on behind the scenes in the modern 64-bit CPU on modern OSes?
https://web.archive.org/web/20110713081927/http://siyobik.in... (anyone know of a mirror? this was nice)
Does anyone who regularly writes assembly really believe that it's difficult to write better code than a modern compiler? This isn't my experience at all. Instead, I'd say that with just a handful of tricks and a dozen hours practice you can speed up just about anything a compiler generates. The issue is not that it's hard to beat a modern compiler, but that it's rarely worthwhile.
It's almost as if there is some compiler-writers-protection-racket out there that threatens anyone who doesn't bow to the powers of the modern compiler. The wonder isn't that they generate perfect code (by and large, they don't), but that they can optimize as well as they do without introducing bugs left and right. The relative rarity of compiler bugs is the impressive part, not the speed of the code generated.
> It's almost as if there is some compiler-writers-protection-racket out there that threatens anyone who doesn't bow to the powers of the modern compiler.
A lot of it seems to come from the "religious belief in abstraction" that is prevalent among academics; the belief that somehow, a "higher level" solution is always better.
> The wonder isn't that they generate perfect code (by and large, they don't), but that they can optimize as well as they do without introducing bugs left and right.
It's not so surprising when you consider that compilers are just following patterns/transformations when they generate or optimise code, and these patterns are designed to be very general so they work for all cases, even when they're not the most efficient way to do it in some of these cases. When a human is writing the Asm there is (or should be - otherwise you'd be better off just using a compiler) a higher level of thought, a different process, one that may be more prone to errors but one that also shows some form of creativity - thinking about the specific application and, understanding that, applying a transformation/pattern that is only applicable in that case to improve the generated code.
Size optimisation is also another area where even a novice Asm programmer can very easily beat a compiler due to this general/specific pattern-ness divide. From what I've seen, compilers start with often overly-general code-generating patterns to produce initially unoptimised output, and then attempt to remove unnecessary instructions; while a human would not have this generality - because the human knows more about the specific problem - and the "first-cut" of code he/she writes is already more specific than the compiler's.
(Not that I'm against compilers in general - I would very much like them to generate better code, but for that to happen there is likely going to have to be large changes in how they're written and how the whole process of compilation is thought of. Trying to make a compiler "think" like a human is a good first step...)
x86_64 is just plain ugly. While I admire the backward compatibility, it's sad that this nasty-looking architecture won out. I'm really glad that the compiler handles it.
I would go as far to say I really love debug things on RISC instruction set.
Things got really out of hand from AT on (80286). IMO that's not Personal Computing anymore, but rather Home Computer. You are mostly a consumer, even if you develop in ASM. You delegate control of your hardware completely.
I'd recommend anyone to learn Commodore 64 coding inside out. Or maybe Spectrum 48K. These are not the simplest machines of their time but they allow you to do a lot and were popular enough that almost everything that truly matters in computing exists for these architectures. And you can fathomably grok them inside out to such a level it will blow your mind.
When I was in my teens I even occasionally resorted to compling C code and disassembling it to work with it, because I preferred M68k assembly to the C source, and the C compilers of the time were horribly inefficient - I could often delete pointless lines and reassign registers etc. almost as fast as I could read the code...
* Dr Paul Carter's tutorial 
* Intel processor reference 
* C ABI standard 
Yes, especially Halide looks interesting.
personally i had all these books and never really cared too much about them in the end is was having a c compiler and a good disassembler - ida at that time - that made me learn it.
here's the free copy of ida 5 . i think it doesn't do 64 bit, but it's good enough, and works perfectly fine in wine on both osx and linux. you can always use biew/hiew/olly etc, or more recently hopper, but i think for learning ida is still hands down the best choice
do a string copy see what it does. make a function notice how it always starts with
mov ebp, esp
i commend the author for what he's doing. a little improvement would be to reduce some of the text, and add some more examples, and some guidance on how to experiment.
another sidenote is that the code is basically the same as simple c code. c++ code even doing simple things, depending on what you link, and compile in, can be terribly confusing for a newbie to look at.
So is there a book or web resources that is really a beginners guide to assembly? I understand x86 is not the nicest place to start but I have an x86 CPU in my laptop and not much else so it is a better place to start that anywhere else really. Anyone got any advice?
You may find Agner Fog's Optimization series helpful too:
Check out every volume, as each has very useful information tucked away. For example, "Calling Conventions" is great for understanding how C++ and assembly interfaces should work.
And the world was never the same again.
1) Some more detail about how the low level of the computer actually works
2) A more "beginner friendly" guide to getting started in programming assembly.
My first programming language was mc68k assembler where the "correct" order of registers is the opposite.
68k has numerical, not named registers, and they're in the same order as the encoding.