Assembly language has long been regarded as the “hidden layer” of computing—the fundamental level where the behavior of the processor, memory operations, and performance boundaries are revealed without abstraction. Despite the advances of high-level languages, assembly remains the foundation beneath every compiler, every kernel interface, and every performance-critical software system.

The choice to base this work on the Linux environment is intentional. Linux is not merely an operating system—it is an open, inspectable ecosystem where internal processes can be traced, analyzed, and understood. Here, we do not deal with black-box behaviors; instead, we are given the ability to examine:

  • How executables are built.
  • How the kernel interacts with user applications.
  • How memory is structured.
  • How system calls flow from user space to the core of the operating system.

This transparency is invaluable.

Furthermore, Linux today forms the backbone of:

  • Servers.
  • Cloud computing platforms.
  • Embedded systems.
  • Scientific computing.
  • Mobile operating systems.
  • Industrial and research environments.

For the serious programmer, learning assembly in the context of Linux is no longer an academic curiosity—it is a practical step toward understanding why programs behave the way they do, not just how to write them.

This series was created to provide a clear and accessible introduction to x86-64 assembly under Linux, without overwhelming the reader or diving prematurely into deep architectural complexity.

The intent is to make this series:

  • A foundational base for deeper understanding.
  • A gradual learning path from basic concepts to advanced practice.
  • A practical handbook, where every example can be built and tested directly.
  • A bridge between assembly, the toolchain, the operating system, and the underlying hardware.

This booklet—the second volume in the series—focuses on the fundamentals of assembling with GAS using Intel syntax, linking, memory layout, the calling convention, function construction, and interoperability with high-level languages.

The material here forms the groundwork for later volumes, where we will progress toward building structured libraries, analyzing execution paths, and evaluating performance at the microarchitectural level.

I hope this work provides the reader with a clear starting point and serves as a guide for those who wish to move beyond using programming languages as mere tools, toward understanding the actual execution, memory interaction, and performance characteristics of the system.