NASM • REGISTERS & INSTRUCTIONS

x86-64 Registers and NASM Assembly Instructions: A Practical Guide.

Understand the registers that hold data inside an x86-64 processor and the instructions that manipulate that data. This guide connects individual NASM instructions with the processor concepts behind them.

THE FOUNDATION

Registers are the working space of the processor.

Before learning large numbers of assembly instructions, it is important to understand where the processor keeps the values those instructions operate on.

A CPU register is a small storage location directly available to the processor. Registers are considerably smaller and faster than main memory, and individual instructions frequently use registers as their operands.

In x86-64 assembly, the 64-bit general-purpose registers are commonly represented by names such as RAX, RBX, RCX, RDX, RSI, RDI, RSP, RBP, and R8 through R15. Other registers, including RIP and RFLAGS, have specialised roles in program execution.

Understanding these registers makes NASM code much easier to read. Instead of seeing an instruction such as MOV RAX, 10 as an arbitrary command, you can understand it as placing the value 10 into a particular processor register.

← Return to the complete NASM guide

X86-64 REGISTERS

The major registers you should know.

The x86-64 architecture provides several registers for general computation, control flow, stack management, and processor state.

RegisterTypical roleWhy it matters
RAXAccumulator / general-purpose registerFrequently used for arithmetic operations, function return values, and Linux x86-64 system-call numbers.
RBXGeneral-purpose registerAvailable for general computation and data storage, subject to the calling convention used by the surrounding program.
RCXGeneral-purpose / counter registerCan hold general data and is commonly encountered in counting and loop-related operations.
RDXGeneral-purpose / data registerUsed for general computation and has specialised roles in some arithmetic and calling-convention contexts.
RSIGeneral-purpose / source registerCommonly associated with source data and function arguments under common x86-64 calling conventions.
RDIGeneral-purpose / destination registerCommonly associated with destination data and the first function argument under the System V AMD64 ABI.
RSPStack pointerPoints to the current top of the stack and is fundamental to stack operations, procedure calls, and stack frames.
RBPBase / frame pointerTraditionally used to reference locations within a stack frame, although modern optimising compilers may use it as a general-purpose register.
RIPInstruction pointerIdentifies the current instruction location and is central to sequential execution and control-flow operations.
R8–R15Additional general-purpose registersEight additional 64-bit general-purpose registers introduced as part of the x86-64 architecture.

GENERAL-PURPOSE REGISTERS

RAX, RBX, RCX, RDX, RSI and RDI.

These registers can hold data and participate in many different operations, although calling conventions and particular instructions may assign them specialised roles.

RAX

RAX is traditionally associated with accumulator-style operations. It is also widely encountered as a return-value register and has an important role in Linux x86-64 system calls, where it identifies the requested system call.

RBX

RBX is a general-purpose register that can hold data, addresses, or intermediate results. Its exact usage depends on the program and the calling convention involved.

RCX

RCX is another general-purpose register and is often useful for counters and loop-related operations. Particular instructions may also use it implicitly.

RDX

RDX is a general-purpose register with additional roles in certain arithmetic operations and calling conventions.

RSI

RSI can store general data but is also associated with source operands and function arguments under common x86-64 conventions.

RDI

RDI is a general-purpose register commonly used for destination-related operations and as the first integer or pointer argument under the System V AMD64 calling convention.

STACK & EXECUTION

RSP, RBP and RIP have special importance.

Some registers become particularly important when studying procedures, stack frames, debugging, and program execution.

RSP — Stack Pointer

RSP points to the current top of the stack. Instructions such as PUSH and POP change the stack and therefore affect RSP. Procedure calls also interact with the stack.

RBP — Base / Frame Pointer

RBP is traditionally used to provide a stable reference point within a stack frame. It can make local variables and saved values easier to reason about while learning procedure execution and debugging.

RIP — Instruction Pointer

RIP identifies the current instruction location. Sequential execution normally advances through instructions, while branches, calls, returns, and other control-flow mechanisms change where execution continues.

PROCESSOR STATE

RFLAGS: the register behind conditional decisions.

Many arithmetic and comparison instructions affect processor flags. Conditional jumps then use those flags to decide whether execution should branch.

RFLAGS contains individual status and control flags. Some of the most important flags for introductory assembly programming include the Zero Flag, Carry Flag, Sign Flag, and Overflow Flag.

FlagConceptTypical significance
ZFZero FlagIndicates that an operation produced a zero result.
CFCarry FlagIndicates a carry or borrow in relevant arithmetic operations.
SFSign FlagReflects the sign bit of the result in relevant operations.
OFOverflow FlagIndicates signed arithmetic overflow in relevant operations.

A useful way to think about this relationship is:

CMP RAX, RBX
JE  equal_case

The CMP instruction performs a comparison by effectively subtracting one operand from another for the purpose of setting flags. The JE instruction can then branch when the comparison indicates equality.

REGISTER SIZES

RAX is more than one 64-bit value.

x86-64 registers can often be accessed through smaller portions of the same register. Understanding these sub-registers is essential when reading low-level code.

A 64-bit general-purpose register can be accessed through different widths. For example, RAX represents the full 64-bit register, while EAX refers to its lower 32 bits, AX to its lower 16 bits, and AL to its lower 8 bits.

NameWidthRelationship
RAX64-bitFull register
EAX32-bitLow 32 bits of RAX
AX16-bitLow 16 bits of RAX
AL8-bitLow 8 bits of RAX

Similar naming patterns exist for many other general-purpose registers. The exact effect of writing a smaller register is important in x86-64 programming, particularly when moving between 32-bit and 64-bit values.

NASM INSTRUCTIONS

The instruction families you will encounter most often.

NASM source code is built from instructions. Learning them by purpose is usually more useful than memorising a flat alphabetical list.

Data movement

MOV · LEA · XCHG

Move values between registers and memory, calculate effective addresses, or exchange register contents.

Arithmetic

ADD · SUB · INC · DEC · NEG · IMUL

Perform addition, subtraction, increment/decrement, negation, and multiplication operations.

Comparison & control flow

CMP · TEST · JMP · JE · JNE · JL · JG

Compare values, update flags, and alter execution flow using unconditional and conditional jumps.

Logical & bitwise

AND · OR · XOR · NOT

Perform bit-level logical operations that are important in low-level programming, masking, and systems work.

Bit shifting

SHL · SHR · SAL · SAR

Shift bits left or right and provide useful operations for binary manipulation and efficient arithmetic.

Stack & procedures

PUSH · POP · CALL · RET

Manage stack data and support procedure calls and returns.

DATA MOVEMENT

MOV: the instruction you will see everywhere.

MOV transfers data between compatible operands. It is one of the first instructions beginners encounter and remains fundamental throughout x86-64 programming.

mov rax, 10
mov rbx, rax
mov rcx, 25

The first instruction places the immediate value 10 into RAX. The second copies the value from RAX into RBX. The third places 25 into RCX.

A useful distinction is that MOV copies a value; it does not inherently mean that a register becomes permanently associated with a particular value. The register contents can be changed by subsequent instructions.

ARITHMETIC

ADD, SUB, INC, DEC and IMUL.

Arithmetic instructions allow programs to transform values held in registers or memory.

mov rax, 10
add rax, 5
sub rax, 2
inc rax
dec rax

After the sequence above, RAX contains 13. Each instruction changes the value stored in the destination according to its operation.

Arithmetic instructions can also affect processor flags. Those flags may subsequently influence conditional branches, making arithmetic and control flow closely connected.

CONTROL FLOW

CMP, JMP and conditional branches.

Assembly programs become more powerful when execution can make decisions and repeat sections of code.

A program normally executes instructions sequentially. Jump instructions change that sequence. An unconditional JMP always transfers execution to a target label, while conditional jumps depend on processor flags.

cmp rax, rbx
je  values_equal
jg  rax_is_greater

values_equal:
    ; equality case

rax_is_greater:
    ; greater-than case

Labels give assembly programs named destinations. The combination of comparisons, flags, and conditional branches provides the foundation for if-statements, loops, and more complex control-flow structures.

BITWISE OPERATIONS

AND, OR, XOR and NOT.

Bitwise instructions operate directly on individual bits and are especially important in systems programming, binary manipulation, cryptography-related concepts, and cybersecurity.

mov rax, 0x0F
mov rbx, 0x03

and rax, rbx
xor rax, rax

AND, OR, XOR, and NOT provide direct bit-level operations. XORing a register with itself, for example, produces zero and is a common low-level pattern.

These operations become particularly useful when working with bit masks, flags, packed data, permissions, binary protocols, and low-level algorithms.

SHIFTING BITS

SHL, SHR, SAL and SAR.

Shift instructions move bits within an operand and are useful for binary manipulation and certain forms of arithmetic.

mov rax, 4
shl rax, 1

mov rbx, 16
shr rbx, 2

A left shift can move bits toward more significant positions, while a right shift moves them toward less significant positions. The precise behaviour depends on the instruction and whether the operation is logical or arithmetic.

STACK INSTRUCTIONS

PUSH, POP, CALL and RET.

These instructions connect registers and control flow with the stack and are essential for understanding procedures and function calls.

push rax
push rbx

pop rbx
pop rax

PUSH places data onto the stack and POP retrieves data from the stack. CALL and RET extend this concept to procedure execution by interacting with return addresses and control flow.

These instructions are closely related to RSP and stack-frame management. We will examine this relationship in much greater depth in the dedicated memory and addressing guide.

Explore NASM memory addressing and the stack →

COMMON BEGINNER MISTAKES

What often makes NASM difficult at first?

Assembly becomes much easier when a few recurring conceptual mistakes are identified early.

Confusing values and addresses

A register can contain a value, an address, or an intermediate result. Memory operands introduce another layer that beginners need to distinguish carefully.

Ignoring operand sizes

x86-64 instructions can operate on different operand widths. Mixing 8-bit, 16-bit, 32-bit, and 64-bit operands without understanding the consequences can produce unexpected results.

Forgetting that instructions affect flags

Arithmetic and comparison instructions can modify processor flags. Later conditional branches may depend on those flags.

Treating registers as permanent variables

Registers are shared working resources. Their contents can be overwritten by later instructions, function calls, and conventions governing how procedures preserve state.

Misunderstanding the stack

Stack behaviour becomes confusing when PUSH, POP, CALL, RET, RSP, and stack frames are learned separately rather than as parts of one mechanism.

Memorising instead of tracing execution

Assembly is easier to understand by tracing registers, memory, flags, and control flow instruction by instruction.

PUTTING IT TOGETHER

The real skill is tracing what the processor is doing.

A strong NASM foundation comes from connecting registers, instructions, memory, flags, and control flow rather than learning each topic in isolation.

Consider a simple operation in which a value is loaded into a register, modified, compared with another value, and then used to determine which branch of the program should execute.

mov rax, 20
mov rbx, 10

sub rax, rbx
cmp rax, 10
je  result_is_ten

mov rdi, 1
jmp done

result_is_ten:
    mov rdi, 0

done:
    ; continue execution

To understand this program, you need to follow the values in RAX and RBX, understand how SUB changes RAX and processor flags, understand what CMP tests, and then understand why JE either changes control flow or allows execution to continue.

That ability to trace execution is more important than memorising isolated instruction definitions.

CONTINUE LEARNING

Continue through the NASM technology cluster.

The supporting guides divide NASM into focused areas so that each major concept can be studied in depth.

NASM Complete Guide

Start with the main NASM guide for a broader introduction to x86-64 assembly, memory, stacks, Linux, and debugging.

Open the complete NASM guide →

Memory & Addressing

Go deeper into memory operands, addressing modes, arrays, pointers, the stack, PUSH/POP, CALL/RET, and stack frames.

Explore memory and addressing →

ACADEMIC & TECHNICAL WORK

Why registers and instructions matter in academic projects.

NASM often appears in computer architecture, operating systems, systems programming, cybersecurity, and low-level programming coursework.

A strong technical submission should do more than reproduce assembly instructions. Students may need to explain why a particular register is used, trace execution, interpret processor flags, document algorithms, explain memory operations, or justify design decisions.

Understanding the underlying processor behaviour also makes it easier to explain debugging results, identify errors, and communicate technical decisions in reports and project demonstrations.

ProjectAssignments provides structured technical and academic guidance for complex computing work, with an emphasis on understanding the concepts and reasoning behind the work.

Explore our technical academic services →

Let's make your work clearer

Bring us the difficult part.

Tell us what you're researching, building, or trying to understand. We'll help you find the clearest ethical next move.

Get Guidance
Chat with us on WhatsApp