Article by Ayman Alheraki on January 11 2026 10:38 AM
Data movement instructions are some of the most fundamental and essential operations in assembly language programming. These instructions are responsible for transferring data between registers, memory, and the stack, allowing the processor to manipulate data during program execution. In GAS, data movement instructions such as mov, lea, push, and pop serve crucial roles in the management of data flow.
The mov instruction is one of the most commonly used instructions in assembly language. It is used to copy data from one location to another, typically between registers or between memory and registers. The syntax of mov in GAS varies based on the architecture being used (e.g., x86, x86-64, ARM, etc.), but the basic principle remains the same.
xxxxxxxxxxmov source, destinationsource: The location from where data will be moved (usually a register or immediate value).
destination: The location where data will be moved (usually a register or memory location).
movl %eax, %ebx # Move the value in the EAX register to the EBX register (x86)movq %rdi, %rax # Move the value in the RDI register to the RAX register (x86-64)movl $10, %eax # Move the immediate value 10 into the EAX register (x86-64)In this example:
The first line moves the contents of register EAX to EBX (on the x86 architecture).
The second line moves the contents of register RDI to RAX (on x86-64 architecture).
The third line moves the immediate value 10 into register EAX.
The mov instruction does not affect the source operand.
It is used for direct data transfer.
mov cannot be used to move data between two memory locations directly; the data must first be moved to a register.
The lea instruction, short for Load Effective Address, is used to compute an address and store it in a register. It is particularly useful when dealing with pointers or when you need to calculate the address of a memory location without actually dereferencing it (i.e., accessing the value stored at that address).
While mov copies the contents of a memory address or register into another register,
lea calculates the address of an operand and stores it in a register.
lea source, destinationsource: This is usually a memory operand, which can be an address or an expression involving registers.
destination: A register where the computed address is stored.
xxxxxxxxxxleal (%eax, %ebx, 4), %ecx # Load the effective address of (%eax + %ebx*4) into ECX (x86)leaq 8(%rbp), %rax # Load the effective address of 8(%rbp) into RAX (x86-64)In this example:
The first line calculates the effective address of the memory location %eax + (%ebx * 4) and stores it in register ECX.
The second line calculates the address 8 + (%rbp) and stores it in register RAX.
lea does not access memory; it just computes the address.
This instruction is useful for pointer arithmetic or when working with data structures like arrays.
It can be used for more complex addressing modes that involve scaling and offsets.
The push instruction is used to place a value onto the stack. In most architectures, this operation involves two steps:
Decrementing the stack pointer (sp or rsp).
Storing the value at the location pointed to by the stack pointer.
In a stack-based architecture, values are stored in the LIFO (Last In, First Out) order, making it ideal for function calls, saving return addresses, and storing local variables.
xxxxxxxxxxpush source– source: The value or register whose data will be pushed onto the stack.
xxxxxxxxxxpushl %eax # Push the value in the EAX register onto the stack (x86)pushq %rax # Push the value in the RAX register onto the stack (x86-64)pushl $100 # Push the immediate value 100 onto the stackIn this example:
The first line pushes the contents of register EAX onto the stack (x86).
The second line pushes the contents of register RAX onto the stack (x86-64).
The third line pushes the immediate value 100 onto the stack.
The stack pointer (sp or rsp) is automatically adjusted when using push.
The stack grows downwards (in most systems), meaning the stack pointer is decremented before the value is written to memory.
push is often used to store registers before calling functions or saving the state during interrupts.
The pop instruction is used to retrieve a value from the stack and place it into a register. This operation typically involves two steps:
The value at the top of the stack is loaded into the specified register.
The stack pointer is incremented to point to the next value.
Just like push, the pop instruction works with the stack in a LIFO manner.
xxxxxxxxxxpop destination– destination: The register where the value will be placed after it is popped from the stack.
xxxxxxxxxxpopl %eax # Pop the top value from the stack into the EAX register (x86)popq %rax # Pop the top value from the stack into the RAX register (x86-64)In this example:
The first line pops the top value from the stack and places it into register EAX.
The second line pops the top value from the stack and places it into register
RAX.
The stack pointer (sp or rsp) is automatically adjusted when using pop.
The pop operation is often used to restore registers that were saved with
push.
After the pop instruction, the stack pointer points to the next value in the stack.
Data movement instructions are foundational in assembly language programming. Whether you're moving data between registers with mov, calculating addresses with lea, or managing the stack with push and pop, these instructions help control the flow of data in a program. Understanding how to use these instructions effectively is key to writing efficient assembly code, and GAS provides a powerful framework to manage data in a variety of system architectures.
By mastering these basic data movement instructions in GAS, you'll be better equipped to perform tasks like handling function calls, managing memory, and implementing low- level operations efficiently across different architectures, including x86, x86-64, ARM, MIPS, and others.