x86 Assembly
Assembly Programming
- Move instructions, registers, and operands
- Memory addressing modes
- swap example: 32-bit vs 64-bit
- Arithmetic operations
- Condition codes
- Conditional and unconditional branches
- Loops
- Switch statements
Three Basic Kinds of Instructions
- Transfer data between memory and register
Loaddata from memory into register%reg = Mem[address]
Storeregister data into memoryMem[address] = %reg
Memory is indexed just like an array[]
- Perform arithmetic function on register or memory data
c = a + b;
- Transfer control
- Unconditional jumps to/ from procedures
- Conditional branches
Moving Data: IA32
- IA32 has 8 registers. 6 are general purpose and 2 special purpose(the last 2)
| Register | Size(32-bit) | Usage (mostly obsolete) |
|---|---|---|
| %eax | 32 | Accumulator for operands and results data |
| %ecx | 32 | Counter for string and loop operations |
| %edx | 32 | I/O pointer |
| %ebx | 32 | Pointer to data in the data segment |
| %esi | 32 | Source pointer for string operations |
| %edi | 32 | Destination pointer for string operations |
| %esp | 32 | Stack pointer |
| %ebp | 32 | Pointer to the base of the current stack frame |
- Moving Data
-
movx Source, Dest -
x is one of {b, w, l}
-
movl Source, Dest:- Move 4-byte “long word”
-
movw Source, Dest:- Move 2-byte “word”
-
movb Source, Dest:- Move 1-byte “byte”
-
- Lots of these in typical code
Moving Data: IA32 Continue…
- Moving Data
movl Source, Dest:
- Operand Types
- Immediate: Constant integer data
- Example:
$0x400, $-533 - Like C constant, but prefixed with
$ - Encoded with 1, 2, or 4 bytes
- Example:
- Register: One of 8 integer registers
- Example:
%eax,%edx - But
%espand%ebpreserced for special use - Others have special uses for particular instructions
- Example:
- Memory: 4 consecutive bytes of memory at address given by register
- Simplest example: (
%eax) - Various other “address modes”
- Simplest example: (
- Immediate: Constant integer data
movl Operand Combination
| Operand | Source | Destination | Src, Dest | C Analog |
|---|---|---|---|---|
mov1 |
Imm | Reg | movl $0x4, %eax |
var_a = 0x4; |
mov1 |
Imm | Mem | movl $-147,(%eax) |
*p_a = -147; |
mov1 |
Reg | Reg | movl %eax, %edx |
var_d = var_a; |
mov1 |
Reg | Mem | movl %eax, (%edx) |
*p_d = var_a; |
mov1 |
Mem | Reg | movl (%eax), %edx |
var_d = *p_a; |
Cannot do memory-memory transfer with a single instruction.
Memory Addressing Modes: Basic
- Indirect (R) Mem[Reg[R]]
- Register R specifies the momory address
- `movl (%ecx), %eax
- Register R specifies the momory address
- Displacement D(R) Mem[Reg[R]+D]
- Register R specifies a memory address
- (e.g. the start of some memory region)
- Constant displacement D specifies the offset from that address
movl 8 (%ebp), %edx
- Register R specifies a memory address
Using Basic Addressing Modes
void swap(int *xp, int *yp)
{
int t0 = *xp;
int t1 = *yp;
*xp = t1;
*yp = t0;
}
swap:
// Set Up
pushl %ebp
movl %esp, %ebp
pushl %ebx
// Body
movl 12(%ebp), %ecx
movl 8(%ebp), %edx
movl (%ecx), %eax
movl (%edx), %ebx
movl %eax, (%edx)
movl %ebx, (%ecx)
// Finish
movl -4(%ebp), %ebx
movl %ebp, %esp
popl %ebp
ret
Understanding Swap
void swap(int *xp, int *yp)
{
int t0 = *xp;
int t1 = *yp;
*xp = t1;
*yp = t0;
}
| Rgister | Value |
|---|---|
| %ecx | yp |
| %edx | xp |
| %eax | t1 |
| %ebx | t0 |

x86-64 Integer Registers
| 64-bit | 32-bit |
|---|---|
| %rax | %eax |
| %rbx | %ebx |
| %rcx | %ecx |
| %rdx | %edx |
| %rsi | %esi |
| %rdi | %edi |
| %rsp | %esp |
| %rbp | %ebp |
| %r8 | %r8d |
| %r9 | %r9d |
| %r10 | %r10d |
| %r11 | %r11d |
| %r12 | %r12d |
| %r13 | %r13d |
| %r14 | %r14d |
| %r15 | %r15d |
32-bit vs. 64-bit operands
-
Long word
l(4 Bytes) <-> Quad wordq(8 Bytes) -
New instruction forms:
movl -> movqaddl -> addqsall -> salq- etc
-
x86-64 can still use 32-bit instructions that generate 32-bit results
- Higher-order bits of destination register are just set to 0
- Example:
addl
Swap Ints in 64-bit Mode
void swap(int *xp, int *yp)
{
int t0 = *xp;
int t1 = *yp;
*xp = t1;
*yp = t0;
}
swap:
movl (%rdi), %edx
movl (%rsi), %eax
movl %eax, (%rdi)
movl %edx,(%rsi)
retq
- Arguments passed in registers
- First
(xp)in%rdi, second(yp)in%rsi - 64-bit pointers
- First
- No stack operations required
- 32-bit data
- Data held in registers
%eaxand%edx movloperation (the l refers to data width, not address width)
- Data held in registers
Swap Long Ints in 64-bit Mode
void swap_1
(long int *xp, long int *yp)
{
long int t0 = *xp;
long int t1 = *yp;
*xp = t1;
*yp = t0;
}
```asm
swap_1:
movq (%rdi), %rdx
movq (%rsi), %rax
movq %rax, (%rdi)
movq %rdx, (%rsi)
retq
- 64-bit data
- Data held in registers
%raxandrdx movqoperationqstands for quad-word
- Data held in registers