Conversational x86 ASM: Learning to Appreciate Your Compiler • Matt Godbolt • YOW! 2020

Learn how x86 assembly works, what your compiler actually does, and gain insights to write better code. Matt Godbolt demystifies low-level programming at YOW! 2020.

Key takeaways
  • Assembly language isn’t as scary as it seems - it’s a way to understand what your computer is actually executing and appreciate what compilers do for you

  • Most x86 assembly instructions have a destination operand (which is also usually a source) and one or more source operands that can be registers, memory locations, or constants

  • Registers have different names based on size - RAX/EAX/AX/AL refer to 64/32/16/8 bits of the same register. The first 8 registers have special names (RAX, RBX etc) while additional ones are numbered (R8-R15)

  • Function calling conventions (ABI) specify which registers are used for parameters and return values - on Linux x86-64, RDI holds the first parameter, RSI the second, etc. Return values go in RAX

  • Common instructions include MOV (copy), arithmetic (ADD/SUB/MUL), comparisons (CMP/TEST), and jumps (JE/JNE). Memory access can often be combined with arithmetic in x86

  • Modern compilers are extremely good at optimizing code - they can transform loops, eliminate redundant operations, and use specialized instructions (like LEA for address calculations)

  • Writing maintainable high-level code and trusting the compiler is generally better than trying to outsmart it with manual optimizations

  • Tools like Compiler Explorer help developers understand assembly output and verify compiler optimizations by showing the mapping between source code and assembly

  • Benchmarking is essential but challenging - looking at assembly can help develop intuition about performance but actual measurements are required

  • Assembly knowledge is particularly valuable in performance-critical domains like games, finance and systems programming, but the principles apply broadly