Instructions
As x86-64 is a CISC architecture, it has a vast range of different instructions (about ~980, not counting different operand types for the same instruction), varying in complexity. Below are some of the most commonly used/most important instructions, grouped by functionality. For those interested in a more extensive set of instructions, the official Intel Manual is a nice (and with ~5,000 pages fairly light) read.
Note that a . postfix is a placeholder for a size indicator, so either b(byte), w (word), l (long), or q (quadword). Some instructions allow only a subset of these postfixes.
mov.
SRC, DST
DST = SRC
push.
SRC
rsp -= <#bytes>; (rsp) = SRC
pop.
DST
DST = (rsp); rsp += <#bytes>
xchg.
A, B
TMP = A; A = B; B = TMP
movzb.
SRC, DST
DST = SRC (one byte only, higher-order bits set to zero)
movzw.
SRC, DST
DST = SRC (one word only, higher-order bits set to zero)
lea.
A, DST
DST = &A (address of A)
add.
SRC, DST
DST = DST + SRC
sub.
SRC, DST
DST = DST - SRC
inc.
DST
DST = DST + 1
dec.
DST
DST = DST - 1
mul.
SRC
rdx:rax = rax * SRC (unsigned)
imul.
SRC
rdx:rax = rax * SRC
imul.
SRC, DST
DST = SRC * DST
imul.
C, SRC, DST
DST = C * SRC
(i)div.
SRC
rax = rdx:rax / SRC;
rdx = rdx:rax % SRC
cmp.
A, B
B - A (only set flags)
or.
SRC, DST
DST = SRC | DST (bitwise)
and.
SRC, DST
DST = SRC & DST (bitwise)
xor.
SRC, DST
DST = SRC ^ DST (bitwise)
neg.
DST
DST = !DST (bitwise)
shl.
C, DST
DST = DST << C (overflowing bits discarded)
shr.
C, DST
DST = DST >> C (underflowing bits discarded)
rol.
C, DST
DST = DST << C (overflowing bits become least sig. bits)
ror.
C, DST
DST = DST >> C (underflowing bits become most sig. bits)
call
ADDR
jump to ADDR and push return address
ret
pop address and jump to it
cmp.
A, B
B - A (only set flags, see below)
test.
A, B
A & B (only set flags, see below)
All conditional branch instructions (except jrcxz, jecxz, and jcxz) use the state of the processor flags to decide whether or not to perform the jump. The flags are (among others) set through the result of arithmetic instructions (like cmp or test). x86-64 processors have a large set of flags, below are the ones commonly used for conditional jumps:
Carry Flag (CF): set on high-order bit carry or borrow (cleared otherwise)
Parity Flag (PF): set if low-order 8 bits contain an even number of '1' bits (cleared otherwise)
Zero Flag (ZF): set if the result is zero (cleared otherwise)
Sign Flag (SF): set to equal high-order bit of result
Overflow Flag (OF): set if the result is too large of a positive number or too small of a negative number (excluding sign bit) to fit the destination operand (cleared otherwise)
All following instructions take the location to jump to as their only operand.
jmp
jo
overflow
OF
jno
no overflow
!OF
js
sign bit (negative number)
SF
jns
no sign bit
!SF
je / jz
equal / zero
ZF
jne / jnz
not equal / not zero
!ZF
jb / jnae / jc
below / not above or equal / carry (unsigned)
CF
jnb / jae / jnc
not below / above or equal / not carry (unsigned)
!CF
jbe / jna
below or equal / not above (unsigned)
CF or ZF
ja/ jnbe
above / not below or equal (unsigned)
!CF and !ZF
jl / jnge
less / not greater or equal (signed)
SF != OF
jge / jnl
greater or equal / not less (signed)
SF = OF
jle / jng
less or equal / not greater (signed)
ZF or (SF != OF)
jg / jnle
greater / not less or equal (signed)
!ZF and (SF = OF)
jp / jpe
parity / parity even
PF
jnp / jpo
not parity / parity odd
!PF
jrcxz
rcx register is 0 (loop counter at 0)
rcx = 0
jecxz
ecx register is 0 (loop counter at 0)
ecx = 0
jcxz
cx register is 0 (loop counter at 0)
cx = 0
Addressing Modes
The x86-64 architecture allows for many different (memory) addressing modes. Below are some of the most commonly used:
Immediate
move the a value 1 into the register rax
Register
move (copy) the contents (8 bytes) from the register rdi into the register rax
Indirect
move 8 bytes from memory starting at the address stored in rdi into the register rax
Base and Displacement
move 8 bytes from memory starting at the address:
rdi - 8 into the register rax
The displacement may be any positive or negative value.
Base and Index
move 8 bytes from memory starting at the address:
rdi + rbx into the register rax
Base, Index, and Scale
move 8 bytes from memory starting at the address:
rdi + (rbx * 4) into the register rax
The scale factor may be either 1, 2, 4, or 8.
Base, Index, Scale, and Displacement
move 8 bytes from memory starting at the address:
rdi + (rbx * 4) + 16 into the register rax
The displacement may be any positive or negative value.
Note on Order of Operands
For all of these modes, except Immediate, the order of operands given in the example may also be reversed (to use the addressing for the destination instead of the source operand). However, at least one of the operands needs to be a register or intermediate value, so the following would not be a valid instruction:
as both the source and destination operands are memory locations.
Last updated