Some time ago, an author of a new book about x86 assembly asked me to write a foreword. While their book was very straightforward and put in simple terms, I got carried away in opposite direction. What I wrote was needlessly metaphorical and elaborate in stark contrast to the actual book. I knew that, so I was not really surprised, that the response was to ask for something more "down to earth" and more "selling" as they put it.
I have not attempted to write something more appropriate for them, but I'm pretty sure that my original foreword is not going to make the cut. Therefore I've decided to preserve the text by posting it here. I could perhaps use it as an introduction to my own book about assembly - but, honestly, that is probably never going to happen.
You may have heard stories about pilots of passenger planes that managed to avert crash landing in emergency situation, where the skill they demonstrated was to some extent attributed to their experience in flying gliders. There were several such tales, contrasting with ones about catastrophes caused by pilots relying too much on automation and not having the right intuition about the forces acting on the plane.
In a sailplane, the pilot has unique contact with the basic principles of flight, to the point of almost directly experiencing all the nuances of movement through the air. The minimalism of the most basic steering devices and few instruments may appear limiting on the surface - but to the contrary, it gives all the necessary tools to perform impressive feats, as long as the pilot has enough dedication to patiently train them. There may be some romanticism in such idealization of gliding skills, but it has a grain of truth and I believe there is a parallel to be made with modern programming and assembly languages.
Nowadays, if you are coding in assembly language, you are most likely doing it as a hobby, just like gliding (although programming as a hobby is definitely less demanding and costly). But the skills that it gives you may surpass the boundaries of that niche and actually help in professional programming, by giving an understanding of what makes the programs fly.
There are countless examples of peculiar details in programming that are much more comprehensible when you know the underlying architecture of the processor and the instructions that it needs to interpret in order to execute a program. The knowledge of machine codes (or assembly language, which is just a nicer representation of them) allows for a better understanding of what may happen in a computer. Things like pointer arithmetic, buffer overflows, data execution, etc. become much clearer when you know what the CPU does under the hood. You may be able to choose better formulations of algorithms in higher level languages when you understand what they may translate to on the level of the hardware. And finally, such knowledge becomes invaluable when something goes really wrong and you need to trace and understand what the machine is doing (this includes things like malware analysis). For this reason, coding in assembly remains a valuable skill even in times when by itself it is quite rarely used.
This book focuses almost solely on digging through the internals of modern 64-bit computing with help of the assembly language and it does it with help of fasm - the assembler that I originally made for hobby purposes. Nonetheless, I believe that the knowledge you may find here should prove valuable no matter if you seek it to become a better professional programmer or simply out of curiosity.