1. Introduction to x86-64 Assembly
x86-64, specifically, is the architecture that powers most desktop, laptop, and server processors today (from Intel and AMD). Learning it means you’re learning the language of the dominant computing platform.
What is Assembly Language?
At its heart, a computer’s CPU only understands sequences of bits (1s and 0s) called machine code. Each instruction is a binary pattern that tells the CPU to perform a very specific task, like “add these two numbers” or “load a value from memory.”
Assembly Language is a human-readable representation of this machine code. Instead of writing cryptic binary patterns, we use short, memorable text commands called mnemonics.
- Machine Code (Hex):
48 89 F8 - Assembly (Mnemonic):
mov %rax, %rdi
An assembler is a program that translates these mnemonics back into the machine code that the CPU can execute.
A Peek at What’s to Come
Let’s look at a simple C function and what its x86-64 assembly might look like. Don’t worry about understanding every line; just get a feel for it.
C Code:
1
2
3
int add(int a, int b) {
return a + b;
}
x86-64 Assembly (GAS Syntax):
add:
push %rbp
mov %rsp, %rbp
mov %edi, -0x4(%rbp)
mov %esi, -0x8(%rbp)
mov -0x4(%rbp), %edx
mov -0x8(%rbp), %eax
add %edx, %eax
pop %rbp
ret
See the add %edx, %eax instruction? That’s the core of our function! The rest is “boilerplate” for setting up the function’s stack frame. We will demystify all of this—registers like %eax, the stack, instructions like mov and push—in the coming chapters.
This blog series is designed to take you from zero to a solid foundational understanding. Here’s what we’ll cover:
- Introduction (You are here!): Setting the stage.
- Computer Architecture: We’ll learn about the CPU, registers, and memory—the “hardware stage” where our code performs.
- Data Representation: How numbers, characters, and addresses are represented in binary and hex.
- Assembly Language Basics: Your first assembly program, understanding syntax (AT&T vs. Intel), and core instructions.
- Data Representation and Basic Arithmetic Instructions: Moving data around and doing simple math.
- Flags: The CPU’s status report—how it knows if a result was zero, negative, or caused an overflow.
- Bitwise Instructions: Directly manipulating individual bits for powerful operations.
- Branch Instructions: Implementing
if,else, andswitchstatements—the foundation of decision-making. - Array and Addressing Modes: How to efficiently access and process lists of data in memory.
- Multiplication and Division Instructions: Moving beyond addition and subtraction.
- Shift and Rotate Instructions: More powerful bit manipulation for fast math and data packing.
- Strings: How sequences of characters are processed at the lowest level.
- Stack and Procedures: The magic behind function calls, local variables, and program structure.
What You’ll Need to Follow Along
- A Linux Environment: We’ll be using the GNU Assembler (
as) and linker (ld), which are standard on Linux. (Windows users can use Windows Subsystem for Linux (WSL)). - A Text Editor: VS Code, Vim, Emacs, or any editor you prefer.
- A 64-bit x86 Processor: This is almost a given if you have a computer made in the last 15 years.
- Curiosity and Patience: This is a different way of thinking about programming. Take your time with each concept.
Next Up: In Chapter 2, we will dive into Computer Architecture. To command the machine, you must first understand its parts. We’ll explore the CPU, registers, and memory hierarchy—the very foundation upon which all our code will run.