1056 lines
109 KiB
Markdown
1056 lines
109 KiB
Markdown
# User-mode x86 + amd64 Cheatsheet
|
||
|
||
## Terminology
|
||
|
||
- **IA-32**:
|
||
- The official name for the 32-bit processor architecture made by Intel, commonly known as x86.
|
||
- **x86**:
|
||
- A more ubiquitous name for IA-32, but technically also includes older, 16-bit CPUs.
|
||
- The name originated from Intel processors with this architecture having model numbers
|
||
ending in 86, beginning with the Intel 8086.
|
||
- Notable models include Intel 80186, 80286, 80386 and 80486, colloquially referred to
|
||
as "186", "286", "386" and "486" respectively.
|
||
- **i386**, **i686**:
|
||
- Versions of the x86 architecture specific to the respective CPU models.
|
||
For practical purposes synonymous to x86.
|
||
- Often used in so called [target triples](https://wiki.osdev.org/Target_Triplet).
|
||
- **amd64**:
|
||
- A 64-bit extension of IA-32 developed by AMD. Today's predominant PC architecture.
|
||
- **Intel® 64** (also **IA-32e**):
|
||
- Intel's name for amd64.
|
||
- **x86_64**, **x64**:
|
||
- Aliases for amd64. Notably, `x86_64` is used in [target triples](https://wiki.osdev.org/Target_Triplet).
|
||
|
||
---
|
||
|
||
## Modes of operation
|
||
|
||
- **Real address mode**:
|
||
- The initial operating mode for any x86/amd64 CPU following a reset.
|
||
- There is no paging in real-address mode, although segmentation can be used.
|
||
- **Protected mode**:
|
||
- The "standard" operating mode for 32-bit CPUs. On 32-bit systems, user apps and (usually) the OS
|
||
operate here.
|
||
- After processor reset (boot), the bootloader or early kernel initializes protected mode
|
||
by setting up various control registers and structures in physical memory, such as an Interrupt
|
||
Vector Table or a Global (segment) Descriptor Table.
|
||
- Protected mode allows for paging and segmentation, although the latter is rarely used.
|
||
- **IA-32e mode** (also **long mode**):
|
||
- The extended mode available to 64-bit CPUs, with backwards compatibility with 32-bit code.
|
||
- **64-bit mode**:
|
||
- Fully 64-bit mode (addresses are 64 bits long, instruction operands up to 64 bits).
|
||
- **Compatibility mode**:
|
||
- Allows running 32-bit user applications within a long-mode enabled OS.
|
||
- Addresses as 32-bit and operands are 32-bit by default.
|
||
- Paging is mandatory in both compatibility and 64-bit mode.
|
||
- **System management mode (SMM)**:
|
||
- Enables (usually) the operating system to perform platform-specific actions
|
||
(think power management, invoking BIOS functions, ...).
|
||
- **Virtual-8086 mode**:
|
||
- Practically of negligible importance.
|
||
|
||
---
|
||
|
||
## Basic program execution registers & data size terminology
|
||
|
||
- A **byte** is an octet — a memory cell containing 8 binary digits.
|
||
- A **word** is twice the size of a byte, i.e. a 16-bit cell.
|
||
- A **doubleword** (also **dword**) is a 32-bit cell.
|
||
- A **quadword** (also **qword**) is a 64-bit cell.
|
||
- (An **xmmword** is a 128-bit cell.)
|
||
|
||
### General purpose registers
|
||
|
||
**General purpose registers available in 32-bit mode:**
|
||
|
||
| 32-bit register name | 16-bit register name | high 8-bit register name | low 8-bit register name | typical usage |
|
||
| -------------------- | -------------------- | ------------------------ | ----------------------- | ------------------------ |
|
||
| EAX | AX | AH | AL | return value |
|
||
| EBX | BX | BH | BL | - |
|
||
| ECX | CX | CH | CL | - |
|
||
| EDX | DX | DH | DL | - |
|
||
| EBP | BP | - | BPL | stack frame base pointer |
|
||
| ESI | SI | - | SIL | copy source |
|
||
| EDI | DI | - | DIL | copy destination |
|
||
| ESP | SP | - | SPL | pointer to top of stack |
|
||
|
||
**General purpose registers available in 64-bit mode:**
|
||
|
||
| 64-bit register name | 32-bit register name | 16-bit register name | high 8-bit register name | low 8-bit register name | typical usage |
|
||
| -------------------- | -------------------- | -------------------- | ------------------------ | ----------------------- | ------------------------ |
|
||
| RAX | EAX | AX | AH | AL | return value |
|
||
| RBX | EBX | BX | BH | BL | - |
|
||
| RCX | ECX | CX | CH | CL | - |
|
||
| RDX | EDX | DX | DH | DL | - |
|
||
| RBP | EBP | BP | - | BPL | stack frame base pointer |
|
||
| RSI | ESI | SI | - | SIL | copy source |
|
||
| RDI | EDI | DI | - | DIL | copy destination |
|
||
| RSP | ESP | SP | - | SPL | pointer to top of stack |
|
||
| R8 | R8D | R8W | - | R8B | - |
|
||
| R9 | R9D | R9W | - | R9B | - |
|
||
| R10 | R10D | R10W | - | R10B | - |
|
||
| R11 | R11D | R11W | - | R11B | - |
|
||
| R12 | R12D | R12W | - | R12B | - |
|
||
| R13 | R13D | R13W | - | R13B | - |
|
||
| R14 | R14D | R14W | - | R14B | - |
|
||
| R15 | R15D | R15W | - | R15B | - |
|
||
|
||
### Segment registers
|
||
|
||
| Register name | Register size | Meaning |
|
||
| ------------- | ------------- | ---------------------- |
|
||
| CS | 16-bit | Code segment selector |
|
||
| DS | 16-bit | Data segment selector |
|
||
| SS | 16-bit | Stack segment selector |
|
||
| ES | 16-bit | Data segment selector |
|
||
| FS | 16-bit | Data segment selector |
|
||
| GS | 16-bit | Data segment selector |
|
||
|
||
**Segment registers in 64-bit mode (quote from the manual):**
|
||
|
||
> In 64-bit mode: CS, DS, ES, SS are treated as if each segment base is 0, regardless of the value of the associated
|
||
> segment descriptor base. This creates a flat address space for code, data, and stack. FS and GS are exceptions.
|
||
> Both segment registers may be used as additional base registers in linear address calculations (in the addressing
|
||
> of local data and certain operating system data structures).
|
||
> Even though segmentation is generally disabled, segment register loads may cause the processor to perform
|
||
> segment access assists. During these activities, enabled processors will still perform most of the legacy checks on
|
||
> loaded values (even if the checks are not applicable in 64-bit mode). Such checks are needed because a segment
|
||
> register loaded in 64-bit mode may be used by an application running in compatibility mode.
|
||
> Limit checks for CS, DS, ES, SS, FS, and GS are disabled in 64-bit mode.
|
||
|
||
### Instruction pointer and status flags
|
||
|
||
| 64-bit register name | 32-bit register name | Meaning |
|
||
| -------------------- | -------------------- | ----------------------------------- |
|
||
| RFLAGS | EFLAGS | Program Status and Control Register |
|
||
| RIP | EIP | Instruction Pointer |
|
||
|
||
**Status Flags in the EFLAGS/RFLAGS register:**
|
||
|
||
| Bit number | Bit mask | Name | Shorthand | Meaning |
|
||
| ---------- | -------- | -------------------- | --------- | -------------------------------------------------------------------------------------- |
|
||
| 0 | 0x001 | Carry flag | CF | Did a carry occur? |
|
||
| 2 | 0x004 | Parity flag | PF | Does the least-significant byte of the result contain an even number of 1 bits? |
|
||
| 4 | 0x010 | Auxiliary Carry flag | AF | Did a carry or a borrow out of bit 3 of the result occur? (Used in decimal arithmetic) |
|
||
| 6 | 0x040 | Zero flag | ZF | Is the result zero? |
|
||
| 7 | 0x080 | Sign flag | SF | Is the (signed) result negative? |
|
||
| 11 | 0x800 | Overflow flag | OF | Did an overflow occur? |
|
||
|
||
### Floating-point number registers
|
||
|
||
todo
|
||
|
||
---
|
||
|
||
## Instruction encoding
|
||
|
||
### Opcodes, ModR/M and SIB bytes
|
||
|
||
todo
|
||
|
||
### Prefixes
|
||
|
||
| Prefix | Name | Description |
|
||
| ------ | ----------------------------- | ----------------------- |
|
||
| `F0` | LOCK | todo |
|
||
| `F2` | BND, REPNE/REPNZ | see string instructions |
|
||
| `F3` | REP, REPE/REPZ | see string instructions |
|
||
| `2E` | CS segment override | todo |
|
||
| `36` | SS segment override | todo |
|
||
| `3E` | DS segment override | todo |
|
||
| `26` | ES segment override | todo |
|
||
| `64` | FS segment override | todo |
|
||
| `65` | GS segment override | todo |
|
||
| `66` | Operand-size override prefix | todo |
|
||
| `67` | Address-size override prefix | todo |
|
||
| `4?` | REX prefix (64-bit mode only) | todo |
|
||
|
||
### Data copying instructions
|
||
|
||
#### MOV — Move
|
||
|
||
**Encodings available in 32-bit mode:**
|
||
|
||
| Opcode | Operands | Assembly | Description |
|
||
| ------ | -------- | -------- | ----------- |
|
||
|
||
**Encodings available in 64-bit mode:**
|
||
|
||
| Opcode | Operands | Assembly | Description |
|
||
| ----------------------------------------- | ----------------------- | -------------------------------------------------------------- | -------------------- |
|
||
| todo | | | |
|
||
| | | | |
|
||
| `C6 0[0???] ??`\*\* | R/M != \{4, 5\}; imm8 | `mov byte ptr [r64], imm8` | Move imm8 to r/m8. |
|
||
| `C6 04 ?[????] ??`\*\* | SIB, Base != 5; imm8 | `mov byte ptr [base_r64 + (index_r64*scale)], imm8` | Move imm8 to r/m8. |
|
||
| `C6 04 ?[?101] ?? ?? ?? ?? ??`\*\* | SIB; disp32; imm8 | `mov byte ptr [(index_r64*scale) + disp32], imm8` | Move imm8 to r/m8. |
|
||
| `C6 05 ?? ?? ?? ?? ??`\*\* | disp32; imm8 | `mov byte ptr [$ + 7 + disp32], imm8` | Move imm8 to r/m8. |
|
||
| `C6 4[0???] ?? ??`\*\* | R/M != 4; disp8; imm8 | `mov byte ptr [r64 + disp8], imm8` | Move imm8 to r/m8. |
|
||
| `C6 44 ?? ?? ??`\*\* | SIB; disp8; imm8 | `mov byte ptr [base_r64 + (index_r64*scale) + disp8], imm8` | Move imm8 to r/m8. |
|
||
| `C6 8[0???] ?? ?? ?? ?? ??`\*\* | R/M != 4; disp32; imm8 | `mov byte ptr [r64 + disp32], imm8` | Move imm8 to r/m8. |
|
||
| `C6 84 ?? ?? ?? ?? ?? ??`\*\* | SIB; disp32; imm8 | `mov byte ptr [base_r64 + (index_r64*scale) + disp32], imm8` | Move imm8 to r/m8. |
|
||
| `C6 C[0???] ??`\*\* | R/M; imm8 | `mov r8, imm8` | Move imm8 to r/m8. |
|
||
| | | | |
|
||
| `66 C7 0[0???] ?? ??` | R/M != \{4, 5\}; imm16 | `mov word ptr [r64], imm16` | Move imm16 to r/m16. |
|
||
| `66 C7 04 ?[????] ?? ??` | SIB, Base != 5; imm16 | `mov word ptr [base_r64 + (index_r64*scale)], imm16` | Move imm16 to r/m16. |
|
||
| `66 C7 04 ?[?101] ?? ?? ?? ?? ?? ??` | SIB; disp32; imm16 | `mov word ptr [(index_r64*scale) + disp32], imm16` | Move imm16 to r/m16. |
|
||
| `66 C7 05 ?? ?? ?? ?? ?? ??` | disp32; imm16 | `mov word ptr [$ + 11 + disp32], imm16` | Move imm16 to r/m16. |
|
||
| `66 C7 4[0???] ?? ?? ??` | R/M != 4; disp8; imm16 | `mov word ptr [r64 + disp8], imm16` | Move imm16 to r/m16. |
|
||
| `66 C7 44 ?? ?? ?? ??` | SIB; disp8; imm16 | `mov word ptr [base_r64 + (index_r64*scale) + disp8], imm16` | Move imm16 to r/m16. |
|
||
| `66 C7 8[0???] ?? ?? ?? ?? ?? ??` | R/M != 4; disp32; imm16 | `mov word ptr [r64 + disp32], imm16` | Move imm16 to r/m16. |
|
||
| `66 C7 84 ?? ?? ?? ?? ?? ?? ??` | SIB; disp32; imm16 | `mov word ptr [base_r64 + (index_r64*scale) + disp32], imm16` | Move imm16 to r/m16. |
|
||
| `66 C7 C[0???] ?? ??` | R/M; imm16 | `mov r16, imm16` | Move imm16 to r/m16. |
|
||
| | | | |
|
||
| `C7 0[0???] ?? ?? ?? ??`\* | R/M != \{4, 5\}; imm32 | `mov dword ptr [r64], imm32` | Move imm32 to r/m32. |
|
||
| `C7 04 ?[????] ?? ?? ?? ??`\* | SIB, Base != 5; imm32 | `mov dword ptr [base_r64 + (index_r64*scale)], imm32` | Move imm32 to r/m32. |
|
||
| `C7 04 ?[?101] ?? ?? ?? ?? ?? ?? ?? ??`\* | SIB; disp32; imm32 | `mov dword ptr [(index_r64*scale) + disp32], imm32` | Move imm32 to r/m32. |
|
||
| `C7 05 ?? ?? ?? ?? ?? ?? ?? ??`\* | disp32; imm32 | `mov dword ptr [$ + 11 + disp32], imm32` | Move imm32 to r/m32. |
|
||
| `C7 4[0???] ?? ?? ?? ?? ??`\* | R/M != 4; disp8; imm32 | `mov dword ptr [r64 + disp8], imm32` | Move imm32 to r/m32. |
|
||
| `C7 44 ?? ?? ?? ?? ?? ??`\* | SIB; disp8; imm32 | `mov dword ptr [base_r64 + (index_r64*scale) + disp8], imm32` | Move imm32 to r/m32. |
|
||
| `C7 8[0???] ?? ?? ?? ?? ?? ?? ?? ??`\* | R/M != 4; disp32; imm32 | `mov dword ptr [r64 + disp32], imm32` | Move imm32 to r/m32. |
|
||
| `C7 84 ?? ?? ?? ?? ?? ?? ?? ?? ??`\* | SIB; disp32; imm32 | `mov dword ptr [base_r64 + (index_r64*scale) + disp32], imm32` | Move imm32 to r/m32. |
|
||
| `C7 C[0???] ?? ?? ?? ??`\* | R/M; imm32 | `mov r64, imm32` | Move imm32 to r/m32. |
|
||
|
||
\*: The REX.W prefix (`4[1???]`) can be used to change the destination operand to 64-bits, i.e. a 64-bit register or a `qword ptr` location.
|
||
In this situation, the imm32 value is sign-extended to 64 bits.
|
||
|
||
\*\* The REX prefix (`4?`) can be used, e.g. to access additional registers not available in 32-bit mode.
|
||
|
||
#### MOVZX — Move With Zero-Extension
|
||
|
||
**Encodings available in both 32-bit and 64-bit mode:**
|
||
|
||
| Opcode | Operands | Assembly (32-bit) | Assembly (64-bit) | Description |
|
||
| -------------------------------------------- | --------------------- | ----------------------------------------------------------- | ----------------------------------------------------------- | -------------------------------------------- |
|
||
| `0F B6 [00 ??? ???]`\* | Reg, R/M != \{4, 5\} | `movzx r32, byte ptr [r32]` | `movzx r32, byte ptr [r64]` | Move byte to doubleword with zero-extension. |
|
||
| `0F B6 [00 ??? 100] ?[????]`\* | Reg; SIB, Base != 5 | `movzx r32, byte ptr [base_r32 + index_r32*scale]` | `movzx r32, byte ptr [base_r64 + index_r64*scale]` | Move byte to doubleword with zero-extension. |
|
||
| `0F B6 [00 ??? 100] ?[?101] ?? ?? ?? ??`\* | Reg; SIB; disp32 | `movzx r32, byte ptr [index_r32*scale + disp32]` | `movzx r32, byte ptr [index_r64*scale + disp32]` | Move byte to doubleword with zero-extension. |
|
||
| `0F B6 [00 ??? 101] ?? ?? ?? ??`\* | Reg; disp32 | `movzx r32, byte ptr ds:disp32` | `movzx r32, byte ptr [$ + 7 + disp32]`\* | Move byte to doubleword with zero-extension. |
|
||
| `0F B6 [01 ??? ???] ??`\* | Reg, R/M != 4; disp8 | `movzx r32, byte ptr [r32 + disp8]` | `movzx r32, byte ptr [r64 + disp8]` | Move byte to doubleword with zero-extension. |
|
||
| `0F B6 [01 ??? 100] ?? ??`\* | Reg; SIB; disp8 | `movzx r32, byte ptr [base_r32 + index_r32*scale + disp8]` | `movzx r32, byte ptr [base_r64 + index_r64*scale + disp8]` | Move byte to doubleword with zero-extension. |
|
||
| `0F B6 [10 ??? ???] ?? ?? ?? ??`\* | Reg, R/M != 4; disp32 | `movzx r32, byte ptr [r32 + disp32]` | `movzx r32, byte ptr [r64 + disp32]` | Move byte to doubleword with zero-extension. |
|
||
| `0F B6 [10 ??? 100] ?? ?? ?? ?? ??`\* | Reg; SIB; disp32 | `movzx r32, byte ptr [base_r32 + index_r32*scale + disp32]` | `movzx r32, byte ptr [base_r64 + index_r64*scale + disp32]` | Move byte to doubleword with zero-extension. |
|
||
| `0F B6 [11 ??? ???]`\* | Reg, R/M | `movzx r32, r8` | `movzx r32, r8` | Move byte to doubleword with zero-extension. |
|
||
| | | | | |
|
||
| `0F B7 [00 ??? ???]`\*\* | Reg, R/M != \{4, 5\} | `movzx r32, word ptr [r32]` | `movzx r32, word ptr [r64]` | Move word to doubleword with zero-extension. |
|
||
| `0F B7 [00 ??? 100] ?[????]`\*\* | Reg; SIB, Base != 5 | `movzx r32, word ptr [base_r32 + index_r32*scale]` | `movzx r32, word ptr [base_r64 + index_r64*scale]` | Move word to doubleword with zero-extension. |
|
||
| `0F B7 [00 ??? 100] ?[?101] ?? ?? ?? ??`\*\* | Reg; SIB; disp32 | `movzx r32, word ptr [index_r32*scale + disp32]` | `movzx r32, word ptr [index_r64*scale + disp32]` | Move word to doubleword with zero-extension. |
|
||
| `0F B7 [00 ??? 101] ?? ?? ?? ??`\*\* | Reg; disp32 | `movzx r32, word ptr ds:disp32` | `movzx r32, word ptr [$ + 7 + disp32]`\* | Move word to doubleword with zero-extension. |
|
||
| `0F B7 [01 ??? ???] ??`\*\* | Reg, R/M != 4; disp8 | `movzx r32, word ptr [r32 + disp8]` | `movzx r32, word ptr [r64 + disp8]` | Move word to doubleword with zero-extension. |
|
||
| `0F B7 [01 ??? 100] ?? ??`\*\* | Reg; SIB; disp8 | `movzx r32, word ptr [base_r32 + index_r32*scale + disp8]` | `movzx r32, word ptr [base_r64 + index_r64*scale + disp8]` | Move word to doubleword with zero-extension. |
|
||
| `0F B7 [10 ??? ???] ?? ?? ?? ??`\*\* | Reg, R/M != 4; disp32 | `movzx r32, word ptr [r32 + disp32]` | `movzx r32, word ptr [r64 + disp32]` | Move word to doubleword with zero-extension. |
|
||
| `0F B7 [10 ??? 100] ?? ?? ?? ?? ??`\*\* | Reg; SIB; disp32 | `movzx r32, word ptr [base_r32 + index_r32*scale + disp32]` | `movzx r32, word ptr [base_r64 + index_r64*scale + disp32]` | Move word to doubleword with zero-extension. |
|
||
| `0F B7 [11 ??? ???]`\*\* | Reg, R/M | `movzx r32, r16` | `movzx r32, r16` | Move word to doubleword with zero-extension. |
|
||
|
||
\* `66` applicable; REX.W applicable in 64-bit mode (applies to dest register); note: using a prefix increases the instruction length and influences RIP-relative addressing!
|
||
|
||
\*\* REX.W applicable in 64-bit mode (applies to dest register)
|
||
|
||
**Encodings available in 32-bit mode only:**
|
||
|
||
todo (pain)
|
||
|
||
#### MOVSX — Move With Sign-Extension
|
||
|
||
**Encodings available in both 32-bit and 64-bit modes:**
|
||
|
||
| Opcode | Operands | Assembly (32-bit) | Assembly (64-bit) | Description |
|
||
| ------------------------------------------ | --------------------- | ----------------------------------------------------------- | ----------------------------------------------------------- | -------------------------------------------- |
|
||
| `0F BE [00 ??? ???]`\* | Reg, R/M != \{4, 5\} | `movsx r32, byte ptr [r32]` | `movsx r32, byte ptr [r64]` | Move byte to doubleword with sign-extension. |
|
||
| `0F BE [00 ??? 100] ?[????]`\* | Reg; SIB, Base != 5 | `movsx r32, byte ptr [base_r32 + index_r32*scale]` | `movsx r32, byte ptr [base_r64 + index_r64*scale]` | Move byte to doubleword with sign-extension. |
|
||
| `0F BE [00 ??? 100] ?[?101] ?? ?? ?? ??`\* | Reg; SIB; disp32 | `movsx r32, byte ptr [index_r32*scale + disp32]` | `movsx r32, byte ptr [index_r64*scale + disp32]` | Move byte to doubleword with sign-extension. |
|
||
| `0F BE [00 ??? 101] ?? ?? ?? ??`\* | Reg; disp32 | `movsx r32, byte ptr ds:disp32` | `movsx r32, byte ptr [$ + 7 + disp32]`\* | Move byte to doubleword with sign-extension. |
|
||
| `0F BE [01 ??? ???] ??`\* | Reg, R/M != 4; disp8 | `movsx r32, byte ptr [r32 + disp8]` | `movsx r32, byte ptr [r64 + disp8]` | Move byte to doubleword with sign-extension. |
|
||
| `0F BE [01 ??? 100] ?? ??`\* | Reg; SIB; disp8 | `movsx r32, byte ptr [base_r32 + index_r32*scale + disp8]` | `movsx r32, byte ptr [base_r64 + index_r64*scale + disp8]` | Move byte to doubleword with sign-extension. |
|
||
| `0F BE [10 ??? ???] ?? ?? ?? ??`\* | Reg, R/M != 4; disp32 | `movsx r32, byte ptr [r32 + disp32]` | `movsx r32, byte ptr [r64 + disp32]` | Move byte to doubleword with sign-extension. |
|
||
| `0F BE [10 ??? 100] ?? ?? ?? ?? ??`\* | Reg; SIB; disp32 | `movsx r32, byte ptr [base_r32 + index_r32*scale + disp32]` | `movsx r32, byte ptr [base_r64 + index_r64*scale + disp32]` | Move byte to doubleword with sign-extension. |
|
||
| `0F BE [11 ??? ???]`\* | Reg, R/M | `movsx r32, r8` | `movsx r32, r8` | Move byte to doubleword with sign-extension. |
|
||
| | | | | |
|
||
| `0F BF [00 ??? ???]`\*\* | Reg, R/M != \{4, 5\} | `movsx r32, word ptr [r32]` | `movsx r32, word ptr [r64]` | Move word to doubleword with sign-extension. |
|
||
| `0F BF [00 ??? 100] ?[????]`\*\* | Reg; SIB, Base != 5 | `movsx r32, word ptr [base_r32 + index_r32*scale]` | `movsx r32, word ptr [base_r64 + index_r64*scale]` | Move word to doubleword with sign-extension. |
|
||
| `0F BF [00 ??? 100] ?[?101]`\*\* | Reg; SIB; disp32 | `movsx r32, word ptr [index_r32*scale + disp32]` | `movsx r32, word ptr [index_r64*scale + disp32]` | Move word to doubleword with sign-extension. |
|
||
| `0F BF [00 ??? 101] ?? ?? ?? ??`\*\* | Reg; disp32 | `movsx r32, word ptr ds:disp32` | `movsx r32, word ptr [$ + 7 + disp32]`\* | Move word to doubleword with sign-extension. |
|
||
| `0F BF [01 ??? ???] ??`\*\* | Reg, R/M != 4; disp8 | `movsx r32, word ptr [r32 + disp8]` | `movsx r32, word ptr [r64 + disp8]` | Move word to doubleword with sign-extension. |
|
||
| `0F BF [01 ??? 100] ?? ??`\*\* | Reg; SIB; disp8 | `movsx r32, word ptr [base_r32 + index_r32*scale + disp8]` | `movsx r32, word ptr [base_r64 + index_r64*scale + disp8]` | Move word to doubleword with sign-extension. |
|
||
| `0F BF [10 ??? ???] ?? ?? ?? ??`\*\* | Reg, R/M != 4; disp32 | `movsx r32, word ptr [r32 + disp32]` | `movsx r32, word ptr [r64 + disp32]` | Move word to doubleword with sign-extension. |
|
||
| `0F BF [10 ??? 100] ?? ?? ?? ?? ??`\*\* | Reg; SIB; disp32 | `movsx r32, word ptr [base_r32 + index_r32*scale + disp32]` | `movsx r32, word ptr [base_r64 + index_r64*scale + disp32]` | Move word to doubleword with sign-extension. |
|
||
| `0F BF [11 ??? ???]`\*\* | Reg, R/M | `movsx r32, r8` | `movsx r32, r8` | Move word to doubleword with sign-extension. |
|
||
|
||
\* `66` applicable; REX.W applicable in 64-bit mode (applies to dest register); note: using a prefix increases the instruction length and influences RIP-relative addressing!
|
||
|
||
\*\* REX.W applicable in 64-bit mode (applies to dest register)
|
||
|
||
**Encodings available only in 64-bit mode:**
|
||
|
||
| Opcode | Operands | Assembly | Description |
|
||
| --------------------------------------- | --------------------- | ------------------------------------------------------------- | ------------------------------------------------------------- | -------------------------------------------------- |
|
||
| `63 [00 ??? ???]`\* | Reg, R/M != \{4, 5\} | `movsxd r32, dword ptr [r32]` | `movsxd r32, dword ptr [r64]` | Move doubleword to doubleword with sign-extension. |
|
||
| `63 [00 ??? 100] ?[????]`\* | Reg; SIB, Base != 5 | `movsxd r32, dword ptr [base_r32 + index_r32*scale]` | `movsxd r32, dword ptr [base_r64 + index_r64*scale]` | Move doubleword to doubleword with sign-extension. |
|
||
| `63 [00 ??? 100] ?[?101] ?? ?? ?? ??`\* | Reg; SIB; disp32 | `movsxd r32, dword ptr [index_r32*scale + disp32]` | `movsxd r32, dword ptr [index_r64*scale + disp32]` | Move doubleword to doubleword with sign-extension. |
|
||
| `63 [00 ??? 101] ?? ?? ?? ??`\* | Reg; disp32 | `movsxd r32, dword ptr ds:disp32` | `movsxd r32, dword ptr [$ + 7 + disp32]`\* | Move doubleword to doubleword with sign-extension. |
|
||
| `63 [01 ??? ???] ??`\* | Reg, R/M != 4; disp8 | `movsxd r32, dword ptr [r32 + disp8]` | `movsxd r32, dword ptr [r64 + disp8]` | Move doubleword to doubleword with sign-extension. |
|
||
| `63 [01 ??? 100] ?? ??`\* | Reg; SIB; disp8 | `movsxd r32, dword ptr [base_r32 + index_r32*scale + disp8]` | `movsxd r32, dword ptr [base_r64 + index_r64*scale + disp8]` | Move doubleword to doubleword with sign-extension. |
|
||
| `63 [10 ??? ???] ?? ?? ?? ??`\* | Reg, R/M != 4; disp32 | `movsxd r32, dword ptr [r32 + disp32]` | `movsxd r32, dword ptr [r64 + disp32]` | Move doubleword to doubleword with sign-extension. |
|
||
| `63 [10 ??? 100] ?? ?? ?? ?? ??`\* | Reg; SIB; disp32 | `movsxd r32, dword ptr [base_r32 + index_r32*scale + disp32]` | `movsxd r32, dword ptr [base_r64 + index_r64*scale + disp32]` | Move doubleword to doubleword with sign-extension. |
|
||
| `63 [11 ??? ???]`\* | Reg, R/M | `movsxd r32, r32` | `movsxd r32, r32` | Move doubleword to doubleword with sign-extension. |
|
||
|
||
\* REX.W applicable (applies to dest register)
|
||
|
||
**Encodings available in 32-bit mode only:**
|
||
|
||
todo (pain)
|
||
|
||
#### CMOVcc — Conditional Move
|
||
|
||
**Relation between second opcode byte and condition:**
|
||
|
||
| Opcode byte following `0F` | Assembly mnemonic | Description | Test |
|
||
| -------------------------- | ----------------- | ----------------------------- | ---------------- |
|
||
| `40` | `cmovo` | Move if overflow. | OF=1 |
|
||
| `41` | `cmovno` | Move if not overflow. | OF=0 |
|
||
| `42` | `cmovb` | Move if below/move if carry. | CF=1 |
|
||
| `42` | `cmovnae` | Move if not above or equal. | CF=1 |
|
||
| `42` | `cmovc` | Move if carry. | CF=1 |
|
||
| `43` | `cmovae` | Move if above or equal. | CF=0 |
|
||
| `43` | `cmovnb` | Move if not below. | CF=0 |
|
||
| `43` | `cmovnc` | Move if not carry. | CF=0 |
|
||
| `44` | `cmove` | Move if equal. | ZF=1 |
|
||
| `44` | `cmovz` | Move if zero. | ZF=1 |
|
||
| `45` | `cmovne` | Move if not equal. | ZF=0 |
|
||
| `45` | `cmovnz` | Move if not zero. | ZF=0 |
|
||
| `46` | `cmovbe` | Move if below or equal. | CF=1 or ZF=1 |
|
||
| `46` | `cmovna` | Move if not above. | CF=1 or ZF=1 |
|
||
| `47` | `cmova` | Move if above. | CF=0 and ZF=0 |
|
||
| `47` | `cmovnbe` | Move if not below or equal. | CF=0 and ZF=0 |
|
||
| `48` | `cmovs` | Move if sign. | SF=1 |
|
||
| `49` | `cmovns` | Move if not sign. | SF=0 |
|
||
| `4A` | `cmovp` | Move if parity. | PF=1 |
|
||
| `4A` | `cmovpe` | Move if parity even. | PF=1 |
|
||
| `4B` | `cmovnp` | Move if not parity. | PF=0 |
|
||
| `4B` | `cmovpo` | Move if parity odd. | PF=0 |
|
||
| `4C` | `cmovl` | Move if less. | SF≠OF |
|
||
| `4C` | `cmovnge` | Move if not greater or equal. | SF≠OF |
|
||
| `4D` | `cmovge` | Move if greater or equal. | SF=OF |
|
||
| `4D` | `cmovnl` | Move if not less. | SF=OF |
|
||
| `4E` | `cmovle` | Move if less or equal. | ZF=1 or SF≠OF |
|
||
| `4E` | `cmovng` | Move if not greater. | ZF=1 or SF≠OF |
|
||
| `4F` | `cmovg` | Move if greater. | ZF=0 and SF=OF |
|
||
| `4F` | `cmovnle` | Move if not less or equal. | ZF=0 and SF=OF |
|
||
|
||
**Encodings available in both 32-bit and 64-bit mode:**
|
||
|
||
In the following table, the `XX` placeholder signifies one of the condition opcodes from the table above.
|
||
|
||
| Opcode | Operands | Assembly (32-bit) | Assembly (64-bit) | Description |
|
||
| ------------------------------------------ | --------------------- | ------------------------------------------------------------- | ------------------------------------------------------------- | -------------------------------------------------- |
|
||
| `0F XX [00 ??? ???]`\* | Reg, R/M != \{4, 5\} | `cmovcc r32, dword ptr [r32]` | `cmovcc r32, dword ptr [r64]` | Move doubleword to doubleword with sign-extension. |
|
||
| `0F XX [00 ??? 100] ?[????]`\* | Reg; SIB, Base != 5 | `cmovcc r32, dword ptr [base_r32 + index_r32*scale]` | `cmovcc r32, dword ptr [base_r64 + index_r64*scale]` | Move doubleword to doubleword with sign-extension. |
|
||
| `0F XX [00 ??? 100] ?[?101] ?? ?? ?? ??`\* | Reg; SIB; disp32 | `cmovcc r32, dword ptr [index_r32*scale + disp32]` | `cmovcc r32, dword ptr [index_r64*scale + disp32]` | Move doubleword to doubleword with sign-extension. |
|
||
| `0F XX [00 ??? 101] ?? ?? ?? ??`\* | Reg; disp32 | `cmovcc r32, dword ptr ds:disp32` | `cmovcc r32, dword ptr [$ + 7 + disp32]`\* | Move doubleword to doubleword with sign-extension. |
|
||
| `0F XX [01 ??? ???] ??`\* | Reg, R/M != 4; disp8 | `cmovcc r32, dword ptr [r32 + disp8]` | `cmovcc r32, dword ptr [r64 + disp8]` | Move doubleword to doubleword with sign-extension. |
|
||
| `0F XX [01 ??? 100] ?? ??`\* | Reg; SIB; disp8 | `cmovcc r32, dword ptr [base_r32 + index_r32*scale + disp8]` | `cmovcc r32, dword ptr [base_r64 + index_r64*scale + disp8]` | Move doubleword to doubleword with sign-extension. |
|
||
| `0F XX [10 ??? ???] ?? ?? ?? ??`\* | Reg, R/M != 4; disp32 | `cmovcc r32, dword ptr [r32 + disp32]` | `cmovcc r32, dword ptr [r64 + disp32]` | Move doubleword to doubleword with sign-extension. |
|
||
| `0F XX [10 ??? 100] ?? ?? ?? ?? ??`\* | Reg; SIB; disp32 | `cmovcc r32, dword ptr [base_r32 + index_r32*scale + disp32]` | `cmovcc r32, dword ptr [base_r64 + index_r64*scale + disp32]` | Move doubleword to doubleword with sign-extension. |
|
||
| `0F XX [11 ??? ???]`\* | Reg, R/M | `cmovcc r32, r32` | `cmovcc r32, r32` | Move doubleword to doubleword with sign-extension. |
|
||
|
||
\* `66` applicable; REX.W applicable in 64-bit mode (applies to source and dest); note: using a prefix increases the instruction length and influences RIP-relative addressing!
|
||
|
||
**Encodings available in 32-bit mode only:**
|
||
|
||
todo (pain)
|
||
|
||
#### XCHG — Exchange Register/Memory With Register
|
||
|
||
**Encodings available in both 32-bit and 64-bit mode:**
|
||
|
||
| Opcode | Operands | Assembly | Description |
|
||
| ------- | -------- | ---------------------------------- | ------------------------------------- |
|
||
| `90`\* | - | `xchg eax, eax` | Exchange EAX with EAX (no operation). |
|
||
| `91`\* | - | `xchg eax, ecx` or `xchg ecx, eax` | Exchange EAX with ECX. |
|
||
| `92`\* | - | `xchg eax, edx` or `xchg edx, eax` | Exchange EAX with EDX. |
|
||
| `93`\* | - | `xchg eax, ebx` or `xchg ebx, eax` | Exchange EAX with EBX. |
|
||
| `94`\* | - | `xchg eax, esp` or `xchg esp, eax` | Exchange EAX with ESP. |
|
||
| `95`\* | - | `xchg eax, ebp` or `xchg ebp, eax` | Exchange EAX with EBP. |
|
||
| `96`\* | - | `xchg eax, esi` or `xchg esi, eax` | Exchange EAX with ESI. |
|
||
| `97`\* | - | `xchg eax, edi` or `xchg edi, eax` | Exchange EAX with EDI. |
|
||
| `86 /r` | todo | | |
|
||
| `87 /r` | todo | | |
|
||
|
||
\*: The `66` prefix can be used to exchange the contents of corresponding **16-bit** registers.
|
||
|
||
**Encodings only available in 64-bit mode:**
|
||
|
||
| Opcode | Operands | Assembly | Description |
|
||
| ------------ | -------- | ---------------------------------- | ------------------------------------- |
|
||
| `4[1???] 90` | - | `xchg rax, rax` | Exchange RAX with RAX (no operation). |
|
||
| `4[1???] 91` | - | `xchg rax, rcx` or `xchg rcx, rax` | Exchange RAX with RCX. |
|
||
| `4[1???] 92` | - | `xchg rax, rdx` or `xchg rdx, rax` | Exchange RAX with RDX. |
|
||
| `4[1???] 93` | - | `xchg rax, rbx` or `xchg rbx, rax` | Exchange RAX with RBX. |
|
||
| `4[1???] 94` | - | `xchg rax, rsp` or `xchg rsp, rax` | Exchange RAX with RSP. |
|
||
| `4[1???] 95` | - | `xchg rax, rbp` or `xchg rbp, rax` | Exchange RAX with RBP. |
|
||
| `4[1???] 96` | - | `xchg rax, rsi` or `xchg rsi, rax` | Exchange RAX with RSI. |
|
||
| `4[1???] 97` | - | `xchg rax, rdi` or `xchg rdi, rax` | Exchange RAX with RDI. |
|
||
|
||
### Effective address computation
|
||
|
||
#### LEA — Load Effective Address
|
||
|
||
**Encodings available in both 32-bit and 64-bit mode:**
|
||
|
||
| Opcode | Operands | Assembly (32-bit) | Assembly (64-bit) | Description |
|
||
| -------------------------------------------- | --------------------- | -------------------------------------------------- | -------------------------------------------------- | ----------------------- |
|
||
| `8D [00 ??? ???]`\* | Reg, R/M != \{4, 5\} | `lea r32, [r32]` | `lea r32, [r64]` | |
|
||
| `8D [00 ??? 100] [?? ??? ???]`\* | R/M; SIB, Base != 5 | `lea r32, [base_r32 + (index_r32*scale)]` | `lea r32, [base_r64 + (index_r64*scale)]` | |
|
||
| `8D [00 ??? 100] [?? ??? 101] ?? ?? ?? ??`\* | R/M; SIB | `lea r32, [(index_r32*scale) + disp32]` | `lea r32, [(index_r64*scale) + disp32]` | |
|
||
| `8D [00 ??? 101] ?? ?? ?? ??`\* | R/M; disp32 | `lea r32, ds:disp32` | `lea r32, [$ + 6 + disp32]` | |
|
||
| `8D [01 ??? ???]`\* | Reg, R/M != 4 | `lea r32, [r32 + disp8]` | `lea r32, [r64 + disp8]` | |
|
||
| `8D [01 ??? 100] ?? ??`\* | R/M; SIB; disp8 | `lea r32, [base_r32 + (index_r32*scale) + disp8]` | `lea r32, [base_r64 + (index_r64*scale) + disp8]` | |
|
||
| `8D [10 ??? ???] ?? ?? ?? ??`\* | Reg, R/M != 4; disp32 | `lea r32, [r32 + disp32]` | `lea r32, [r64 + disp32]` | |
|
||
| `8D [10 ??? 100] ?? ?? ?? ?? ??`\* | Reg, R/M; SIB; disp32 | `lea r32, [base_r32 + (index_r32*scale) + disp32]` | `lea r32, [base_r64 + (index_r64*scale) + disp32]` | |
|
||
| `8D [11 ??? ???]` | Reg, R/M | - | - | Raises a #UD exception. |
|
||
| `66 8D [11 ??? ???]` | Reg, R/M | - | - | Raises a #UD exception. |
|
||
| `67 8D [11 ??? ???]` | Reg, R/M | - | - | Raises a #UD exception. |
|
||
|
||
**Encodings available in 32-bit mode only:**
|
||
|
||
| Opcode | Operands | Assembly | Description |
|
||
| ---------------------------- | ---------------- | ------------------------------- | ----------- |
|
||
| `67 8D [00 ??? ???]`\* | Reg, R/M != 6 | `lea r32, [r16(+r16)?]` | |
|
||
| `67 8D [00 ??? 110] ?? ??`\* | R/M; disp16 | `lea r32, ds:disp16` | |
|
||
| `67 8D [01 ??? ???] ??`\* | Reg, R/M; disp8 | `lea r32, [r16(+r16) + disp8]` | |
|
||
| `67 8D [10 ??? ???] ?? ??`\* | Reg, R/M; disp16 | `lea r32, [r16(+r16) + disp16]` | |
|
||
|
||
\* 66 applicable -> dest r16
|
||
|
||
**Encodings available in 64-bit mode only:**
|
||
|
||
| Opcode | Operands | Assembly | Description |
|
||
| ------------------------------------------------------ | ------------------------------ | -------------------------------------------------------- | ----------------------- |
|
||
| `67 8D [00 ??? ???]`\* | Reg, R/M != \{4, 5\} | `lea r32, [r32]` | |
|
||
| `67 8D [00 ??? 100] [?? ??? ???]`\* | R/M; SIB, Base != 5 | `lea r32, [base_r32 + (index_r32*scale)]` | |
|
||
| `67 8D [00 ??? 100] [?? ??? 101] ?? ?? ?? ??`\* | R/M; SIB | `lea r32, [(index_r32*scale) + disp32]` | |
|
||
| `67 8D [00 ??? 101] ?? ?? ?? ??`\* | R/M; disp32 | `lea r32, [eip+disp32]` (`eip` = `($ + 7) & 0xffffffff`) | |
|
||
| `67 8D [01 ??? ???]`\* | Reg, R/M != 4 | `lea r32, [r32 + disp8]` | |
|
||
| `67 8D [01 ??? 100] ?? ??`\* | R/M; SIB; disp8 | `lea r32, [base_r32 + (index_r32*scale) + disp8]` | |
|
||
| `67 8D [10 ??? ???] ?? ?? ?? ??`\* | Reg, R/M != 4; disp32 | `lea r32, [r32 + disp32]` | |
|
||
| `67 8D [10 100 ???] ?? ?? ?? ?? ??`\* | Reg; SIB; disp32 | `lea r32, [base_r32 + (index_r32*scale) + disp32]` | |
|
||
| `4[1???] 8D [00 ??? ???]`\*\* | REX.RXB; Reg, R/M != \{4, 5\} | `lea r64, [r64]` | |
|
||
| `4[1???] 8D [00 ??? 100] [?? ??? ???]`\*\* | REX.RXB; Reg; SIB, Base != 5 | `lea r64, [base_r64 + (index_r64*scale)]` | |
|
||
| `4[1???] 8D [00 ??? 100] [?? ??? 101] ?? ?? ?? ??`\*\* | REX.RXB; Reg; SIB; disp32 | `lea r64, [(index_r64*scale) + disp32]` | |
|
||
| `4[1???] 8D [00 ??? 101] ?? ?? ?? ??`\*\* | REX.RXB; Reg, R/M; disp32 | `lea r64, [$ + 7 + disp32]` | |
|
||
| `4[1???] 8D [01 ??? ???] ??`\*\* | REX.RXB; Reg, R/M != 4; disp8 | `lea r64, [r64 + disp8]` | |
|
||
| `4[1???] 8D [01 ??? 100] ?? ??`\*\* | REX.RXB; Reg; SIB; disp8 | `lea r64, [base_r64 + (index_r64*scale) + disp8]` | |
|
||
| `4[1???] 8D [10 ??? ???] ?? ?? ?? ??`\*\* | REX.RXB; Reg, R/M != 4; disp32 | `lea r64, [r64 + disp32]` | |
|
||
| `4[1???] 8D [10 ??? 100] ?? ?? ?? ?? ??`\*\* | REX.RXB; Reg, R/M; SIB; disp32 | `lea r64, [base_r64 + (index_r64*scale) + disp32]` | |
|
||
| `4[1???] 8D [11 ??? ???]`\*\* | REX.RXB; Reg, R/M | - | Raises a #UD exception. |
|
||
|
||
\*: 66 applicable -> dest register 16-bit
|
||
|
||
\*\*: 67 applicable -> memory addressing 32-bit
|
||
|
||
### Stack manipulation instructions
|
||
|
||
#### PUSH — Push Word, Doubleword, or Quadword Onto the Stack
|
||
|
||
**Push encodings available in both 32-bit and 64-bit mode:**
|
||
|
||
| Opcode | Operands | Assembly | Description |
|
||
| ---------------- | -------- | -------------- | --------------------------------------------------------------- |
|
||
| `50`\* | - | `push (e/r)ax` | Push the value in the (E/R)AX register to the stack. |
|
||
| `51`\* | - | `push (e/r)cx` | Push the value in the (E/R)CX register to the stack. |
|
||
| `52`\* | - | `push (e/r)dx` | Push the value in the (E/R)DX register to the stack. |
|
||
| `53`\* | - | `push (e/r)bx` | Push the value in the (E/R)BX register to the stack. |
|
||
| `54`\* | - | `push (e/r)sp` | Push the (original) value in the (E/R)SP register to the stack. |
|
||
| `55`\* | - | `push (e/r)bp` | Push the value in the (E/R)BP register to the stack. |
|
||
| `56`\* | - | `push (e/r)si` | Push the value in the (E/R)SI register to the stack. |
|
||
| `57`\* | - | `push (e/r)di` | Push the value in the (E/R)DI register to the stack. |
|
||
| `6A ??` | imm8 | `push imm8` | Push an immediate value to the stack. |
|
||
| `66 68 ?? ??` | imm16 | `push imm16` | Push an immediate value to the stack. |
|
||
| `68 ?? ?? ?? ??` | imm32 | `push imm32` | Push an immediate value to the stack. |
|
||
| `0F A0` | - | `push fs` | Push the value in the FS register to the stack. |
|
||
| `0F A8` | - | `push gs` | Push the value in the GS register to the stack. |
|
||
|
||
\*: The instruction pushes the corresponding 32-bit register in 32-bit mode and the corresponding 64-bit register in 64-bit mode.
|
||
In both modes, the `66` prefix may be used to push the corresponding **16-bit** register instead of the native-sized register.
|
||
|
||
**Push encodings only available in 32-bit mode:**
|
||
|
||
| Opcode | Operands | Assembly | Description |
|
||
| ----------------------------- | ---------------------- | ---------------------------------------------------------- | ----------------------------------------------- |
|
||
| `FF 3[0???]`\* | R/M value != \{4, 5\} | `push dword ptr [r32]` | todo |
|
||
| `FF 34 ?[?101] ?? ?? ?? ??`\* | SIB; disp32 | `push dword ptr [(index_r32 * scale) + disp32]` | todo |
|
||
| `FF 34 ?[????]`\* | SIB, Base != 5 | `push dword ptr [base_r32 + (index_r32 * scale)]` | todo |
|
||
| `FF 35 ?? ?? ?? ??`\* | disp32 | `push dword ptr ds:disp32` | todo |
|
||
| `FF 7[0???] ??`\* | R/M value != 4; disp8 | `push dword ptr [r32 + disp8]` | todo |
|
||
| `FF 74 ?? ??`\* | SIB; disp8 | `push dword ptr [base_r32 + (index_r32 * scale) + disp8]` | todo |
|
||
| `FF B[0???] ?? ?? ?? ??`\* | R/M value != 4; disp32 | `push dword ptr [r32 + disp32]` | todo |
|
||
| `FF B4 ?? ?? ?? ?? ??`\* | SIB; disp32 | `push dword ptr [base_r32 + (index_r32 * scale) + disp32]` | todo |
|
||
| `FF F[0???]`\*\* | R/M value | `push r32` | todo |
|
||
| `67 FF 3[0???]`\* | R/M value != 6 | `push dword ptr [r16(+r16)?]` | todo |
|
||
| `67 FF 36 ??`\* | disp16 | `push dword ptr [disp16]` | todo |
|
||
| `67 FF 7[0???] ??` | R/M value; disp8 | `push dword ptr [r16(+r16)?+disp8]` | todo |
|
||
| `67 FF B[0???] ?? ??` | R/M value; disp16 | `push dword ptr [r16(+r16)?+disp16]` | todo |
|
||
| `67 FF F[0???]` | R/M value | `push r16` | todo |
|
||
| `0E` | - | `push cs` | Push the value in the CS register to the stack. |
|
||
| `16` | - | `push ss` | Push the value in the SS register to the stack. |
|
||
| `1E` | - | `push ds` | Push the value in the DS register to the stack. |
|
||
| `06` | - | `push es` | Push the value in the ES register to the stack. |
|
||
|
||
\*: `66` prefix applicable (todo)
|
||
|
||
\*\*: `66` prefix applicable (todo)
|
||
|
||
**Push encodings only available in 64-bit mode:**
|
||
|
||
| Opcode | Operands | Assembly | Description |
|
||
| ----------------------------- | ---------------------- | ---------------------------------------------------------- | ----------- |
|
||
| `FF 3[0???]`\* | R/M value != \{4, 5\} | `push qword ptr [r64]` | todo |
|
||
| `FF 34 ?[?101] ?? ?? ?? ??`\* | SIB; disp32 | `push qword ptr [(index_r64 * scale) + disp64]` | todo |
|
||
| `FF 34 ?[????]`\* | SIB, Base != 5 | `push qword ptr [base_r64 + (index_r64 * scale)]` | todo |
|
||
| `FF 35 ?? ?? ?? ??`\* | disp32 | `push qword ptr [$+6+disp32]` | todo |
|
||
| `FF 7[0???] ??`\* | R/M value != 4; disp8 | `push qword ptr [r64 + disp8]` | todo |
|
||
| `FF 74 ?? ??`\* | SIB; disp8 | `push qword ptr [base_r64 + (index_r64 * scale) + disp8]` | todo |
|
||
| `FF B[0???] ?? ?? ?? ??`\* | R/M value != 4; disp32 | `push qword ptr [r64 + disp32]` | todo |
|
||
| `FF B4 ?? ?? ?? ?? ??`\* | SIB; disp32 | `push qword ptr [base_r64 + (index_r64 * scale) + disp32]` | todo |
|
||
| `FF F[0???]`\*\* | R/M value | `push r64` | todo |
|
||
|
||
todo REX? push r8-r15 etc.
|
||
|
||
\*: todo
|
||
|
||
#### POP — Pop a Value From the Stack
|
||
|
||
**Pop encodings available in both 32-bit and 64-bit mode:**
|
||
|
||
| Opcode | Operands | Assembly | Description |
|
||
| ---------- | -------- | ------------- | ------------------------------------------------------------- |
|
||
| `58`\* | - | `pop (e/r)ax` | Pop value into the (E/R)AX register from the stack. |
|
||
| `59`\* | - | `pop (e/r)cx` | Pop value into the (E/R)CX register from the stack. |
|
||
| `5A`\* | - | `pop (e/r)dx` | Pop value into the (E/R)DX register from the stack. |
|
||
| `5B`\* | - | `pop (e/r)bx` | Pop value into the (E/R)BX register from the stack. |
|
||
| `5C`\* | - | `pop (e/r)sp` | Pop value into the (E/R)SP register from the stack. |
|
||
| `5D`\* | - | `pop (e/r)bp` | Pop value into the (E/R)BP register from the stack. |
|
||
| `5E`\* | - | `pop (e/r)si` | Pop value into the (E/R)SI register from the stack. |
|
||
| `5F`\* | - | `pop (e/r)di` | Pop value into the (E/R)DI register from the stack. |
|
||
| `66 0F A1` | - | `popw fs` | Pop top of stack into FS; increment stack pointer by 16 bits. |
|
||
| `66 0F A9` | - | `popw gs` | Pop top of stack into GS; increment stack pointer by 16 bits. |
|
||
|
||
\*: The instruction uses the corresponding 32-bit register in 32-bit mode and the corresponding 64-bit register in 64-bit mode.
|
||
In both modes, the `66` prefix may be used to pop into the corresponding **16-bit** register instead of the native-sized register.
|
||
|
||
**Pop encodings only available in 32-bit mode:**
|
||
|
||
| Opcode | Operands | Assembly | Description |
|
||
| ----------------------------- | ---------------------- | ------------------------------------------------------- | ------------------------------------------------------------- |
|
||
| `8F 0[0???]`\* | R/M value != \{4, 5\} | `pop dword ptr [r32]` | |
|
||
| `8F 04 ?[????]`\* | SIB, Base != 5 | `pop dword ptr [base_r32 + (index_r32*scale)]` | |
|
||
| `8F 04 ?[?101] ?? ?? ?? ??`\* | SIB; disp32 | `pop dword ptr [(index_r32*scale) + disp32]` | |
|
||
| `8F 05 ?? ?? ?? ??`\* | disp32 | `pop dword ptr ds:disp32` | |
|
||
| `8F 4[0???] ??`\* | R/M value != 4; disp8 | `pop dword ptr [r32 + disp8]` | |
|
||
| `8F 44 ?? ??`\* | SIB; disp8 | `pop dword ptr [base_r32 + (index_r32*scale) + disp8]` | |
|
||
| `8F 8[0???] ?? ?? ?? ??`\* | R/M value != 4; disp32 | `pop dword ptr [r32 + disp32]` | |
|
||
| `8F 84 ?? ?? ?? ?? ??`\* | SIB; disp32 | `pop dword ptr [base_r32 + (index_r32*scale) + disp32]` | |
|
||
| `8F C[0???]` | R/M value | `pop r32` | |
|
||
| `67 8F 0[0???]`\* | R/M value != 6 | `pop dword ptr [r16(+r16)?]` | todo |
|
||
| `67 8F 06 ?? ??`\* | disp16 | `pop dword ptr ds:disp16` | todo |
|
||
| `67 8F 4[0???] ??`\* | R/M value; disp8 | `pop dword ptr [r16(+r16)? + disp8]` | todo |
|
||
| `67 8F 8[0???] ?? ??`\* | R/M value; disp16 | `pop dword ptr [r16(+r16)? + disp16]` | todo |
|
||
| `66 8F C[0???]` | R/M value | `pop r16` | todo |
|
||
| `1F` | - | `pop ds` | Pop top of stack into DS; increment stack pointer. |
|
||
| `07` | - | `pop es` | Pop top of stack into ES; increment stack pointer. |
|
||
| `17` | - | `pop ss` | Pop top of stack into SS; increment stack pointer. |
|
||
| `0F A1` | - | `pop fs` | Pop top of stack into FS; increment stack pointer by 32 bits. |
|
||
| `0F A9` | - | `pop gs` | Pop top of stack into GS; increment stack pointer by 32 bits. |
|
||
|
||
**Pop encodings only available in 64-bit mode:**
|
||
|
||
| Opcode | Operands | Assembly | Description | Notes |
|
||
| ----------------------------- | ---------------------- | ------------------------------------------------------- | ------------------------------------------------------------- | ----- |
|
||
| `8F 0[0???]`\* | R/M value != \{4, 5\} | `pop qword ptr [r64]` | | |
|
||
| `8F 04 ?[????]`\* | SIB, Base != 5 | `pop qword ptr [base_r64 + (index_r64*scale)]` | | |
|
||
| `8F 04 ?[?101] ?? ?? ?? ??`\* | SIB; disp32 | `pop qword ptr [(index_r64*scale) + disp32]` | | |
|
||
| `8F 05 ?? ?? ?? ??`\* | disp32 | `pop qword ptr [$ + 6 + disp32]` | RIP-relative addressing | |
|
||
| `8F 4[0???] ??`\* | R/M value != 4; disp8 | `pop qword ptr [r64 + disp8]` | | |
|
||
| `8F 44 ?? ??`\* | SIB; disp8 | `pop qword ptr [base_r64 + (index_r64*scale) + disp8]` | | |
|
||
| `8F 8[0???] ?? ?? ?? ??`\* | R/M value != 4; disp32 | `pop qword ptr [r64 + disp32]` | | |
|
||
| `8F 84 ?? ?? ?? ?? ??`\* | SIB; disp32 | `pop qword ptr [base_r64 + (index_r64*scale) + disp32]` | | |
|
||
| `8F C[0???]` | R/M value | `pop r64` | | |
|
||
| `0F A1` | - | `pop fs` | Pop top of stack into FS; increment stack pointer by 64 bits. |
|
||
| `0F A9` | - | `pop gs` | Pop top of stack into GS; increment stack pointer by 64 bits. |
|
||
|
||
\*: The `67` prefix can be used to pop a 32-bit value into a `dword ptr` location.
|
||
|
||
todo 66, 67 prefixes, r8-r15 etc.
|
||
|
||
### Control flow instructions
|
||
|
||
#### JMP — Jump
|
||
|
||
**Short jump encodings available in both 32-bit and 64-bit modes:**
|
||
|
||
| Opcode | Operands | Assembly | Description |
|
||
| ------- | ------------------------- | --------------------- | ------------------------------------------------------------------------------------------------------- |
|
||
| `EB ??` | 8-bit signed displacement | `jmp short $+2+disp8` | Jump short, relative to the next instruction, EIP/RIP += (8-bit displacement sign-extended to 32 bits). |
|
||
|
||
**Near jump encodings available in 32-bit mode:**
|
||
|
||
| Opcode | Operands | Assembly | Description |
|
||
| ------------------------------ | ------------------------------------------------ | ---------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
|
||
| `E9 ?? ?? ?? ??` | 32-bit signed displacement | `jmp $+5+disp32` | Jump near, relative to the next instruction, EIP += 32-bit signed displacement. |
|
||
| `FF 2[0???]` | ModR/M:RM value != \{4, 5\} | `jmp dword ptr [reg]` | Jump near, absolute indirect, 32-bit address read from `[eax]`/`[ecx]`/`[ebx]`/`[edx]`/`[esi]`/`[edi]`. |
|
||
| `FF 25 ?? ?? ?? ??` | 32-bit absolute address | `jmp address` | Jump near, absolute, 32-bit address given as operand. |
|
||
| `FF 24 [????????]` | SIB byte, Base != 5 | `jmp dword ptr [reg (+ scale * reg)]` | todo |
|
||
| `FF 24 [?????101] ?? ?? ?? ??` | SIB Index and Scale values; disp32 | `jmp dword ptr [(scale * reg) + disp32]` | todo |
|
||
| `FF 6[0???] ??` | ModR/M:RM value != 4; 8-bit signed displacement | `jmp dword ptr [reg + disp8]` | Jump near, absolute indirect, 32-bit address read from `[(eax\|ecx\|edx\|ebx\|ebp\|esi\|edi)+disp8]`. |
|
||
| `FF 64 ?? ??` | SIB byte; 8-bit signed displacement | `jmp dword ptr [reg (+ scale * reg) + disp8]` | todo |
|
||
| `FF A[0???] ?? ?? ?? ??` | ModR/M:RM value != 4; 32-bit signed displacement | `jmp dword ptr [reg + disp32]` | Jump near, absolute indirect, 32-bit address read from `[(eax\|ecx\|edx\|ebx\|ebp\|esi\|edi)+disp32]`. |
|
||
| `FF A4 ?? ?? ?? ?? ??` | SIB byte; 32-bit signed displacement | `jmp dword ptr [reg (+ scale * reg) + disp32]` | todo |
|
||
| `FF E[0???]` | ModR/M:RM value | `jmp reg` | Jump near, absolute, to zero-extended `eax`/`ecx`/`edx`/`ebx`/`esp`/`ebp`/`esi`/`edi`. |
|
||
| `66 E9 ?? ??` | 16-bit signed displacement | `jmp $+4+disp16` | Jump near, relative to the next instruction, EIP += (16-bit displacement sign-extended to 32 bits). |
|
||
| `67 FF 26 ?? ??` | 16-bit absolute address | `jmp address` | Jump near, absolute, 16-bit address given as operand. |
|
||
| `67 FF 2[0???]`\* | ModR/M:RM value != 6 | `jmp dword ptr [reg(+reg)?]` | Jump near, absolute indirect, 32-bit address zero-extended from `[bx]` or one of `[(bx\|bp)+(si\|di)]`. |
|
||
| `67 FF 6[0???] ??`\* | ModR/M:RM value, disp8 | `jmp dword ptr [reg(+reg)? + disp8]` | Jump near, absolute indirect, 32-bit address zero-extended from `[(bx\|bp)+disp8]` or `[(bx\|bp)+(si\|di)+disp8]`. |
|
||
| `67 FF A[0???] ?? ??`\* | ModR/M:RM value, disp16 | `jmp dword ptr [reg(+reg)? + disp16]` | Jump near, absolute indirect, 32-bit address zero-extended from `[(bx\|bp)+disp16]` or `[(bx\|bp)+(si\|di)+disp16]`. |
|
||
| `66 FF E[0???]` | ModR/M:RM value | `jmp reg` | Jump near, absolute, to zero-extended `ax`/`cx`/`dx`/`bx`/`sp`/`bp`/`si`/`di`. |
|
||
|
||
\*: The `66` prefix can be used to change the dword ptr to a word ptr and jump to a 16-bit address instead.
|
||
|
||
**Near jump encodings available in 64-bit mode:**
|
||
|
||
| Opcode | Operands | Assembly | Description |
|
||
| ------------------------ | ---------------------------- | ------------------------------------------------- | ------------------------------------------------------------------------------- |
|
||
| `E9 ?? ?? ?? ??` | 32-bit signed displacement | `jmp $+5+disp32` | Jump near, relative to the next instruction, RIP += 32-bit signed displacement. |
|
||
| `FF 2[0???]` | ModR/M:RM value != \{4, 5\} | `jmp qword ptr [reg]` | ?? |
|
||
| `FF 24 [????????]` | SIB byte, Base != 5 | `jmp qword ptr [base + (scale * index)]` | ?? |
|
||
| `FF 24 [?????101]` | SIB:Scale; SIB:Index | `jmp qword ptr [(scale * index) + disp32]` | ?? |
|
||
| `FF 25 ?? ?? ?? ??` | disp32 | `jmp qword ptr [$+6+disp32]` | ?? |
|
||
| `FF 6[0???] ??` | ModR/M:RM value != 4; disp8 | `jmp qword ptr [reg + disp8]` | ?? |
|
||
| `FF 64 ?? ??` | SIB byte; disp8 | `jmp qword ptr [base + (scale * index) + disp8]` | ?? |
|
||
| `FF A[0???] ?? ?? ?? ??` | ModR/M:RM value != 4; disp32 | `jmp qword ptr [reg + disp32]` | ?? |
|
||
| `FF A4 ?? ?? ?? ?? ??` | SIB byte; disp32 | `jmp qword ptr [base + (scale * index) + disp32]` | ?? |
|
||
| `FF E[0???]` | ModR/M:RM value | `jmp reg` | ?? |
|
||
|
||
todo: far jumps
|
||
|
||
#### Jcc — Jump if Condition Is Met
|
||
|
||
**Optional branch predictor hint prefixes (both 32-bit and 64-bit mode):**
|
||
|
||
| Prefix | Meaning |
|
||
| ------ | ---------------- |
|
||
| `2E` | Branch not taken |
|
||
| `3E` | Branch taken |
|
||
|
||
**Short jump encodings available in both 32-bit and 64-bit modes:**
|
||
|
||
| Opcode | Operands | Assembly | Description | Test |
|
||
| ------- | -------- | ---------------- | ----------------------------------- | ---------------- |
|
||
| `77 ??` | rel8 | `ja $+2+rel8` | Jump short if above. | CF=0 and ZF=0 |
|
||
| `73 ??` | rel8 | `jae $+2+rel8` | Jump short if above or equal. | CF=0 |
|
||
| `72 ??` | rel8 | `jb $+2+rel8` | Jump short if below (CF=1). | CF=1 |
|
||
| `76 ??` | rel8 | `jbe $+2+rel8` | Jump short if below or equal. | CF=1 or ZF=1 |
|
||
| `72 ??` | rel8 | `jc $+2+rel8` | Jump short if carry. | CF=1 |
|
||
| `E3 ??` | rel8 | `jecxz $+2+rel8` | Jump short if ECX register is 0. | ECX=0 |
|
||
| `74 ??` | rel8 | `je $+2+rel8` | Jump short if equal. | ZF=1 |
|
||
| `7F ??` | rel8 | `jg $+2+rel8` | Jump short if greater. | ZF=0 and SF=OF |
|
||
| `7D ??` | rel8 | `jge $+2+rel8` | Jump short if greater or equal. | SF=OF |
|
||
| `7C ??` | rel8 | `jl $+2+rel8` | Jump short if less. | SF≠OF |
|
||
| `7E ??` | rel8 | `jle $+2+rel8` | Jump short if less or equal. | ZF=1 or SF≠OF |
|
||
| `76 ??` | rel8 | `jna $+2+rel8` | Jump short if not above. | CF=1 or ZF=1 |
|
||
| `72 ??` | rel8 | `jnae $+2+rel8` | Jump short if not above or equal. | CF=1 |
|
||
| `73 ??` | rel8 | `jnb $+2+rel8` | Jump short if not below. | CF=0 |
|
||
| `77 ??` | rel8 | `jnbe $+2+rel8` | Jump short if not below or equal. | CF=0 and ZF=0 |
|
||
| `73 ??` | rel8 | `jnc $+2+rel8` | Jump short if not carry. | CF=0 |
|
||
| `75 ??` | rel8 | `jne $+2+rel8` | Jump short if not equal. | ZF=0 |
|
||
| `7E ??` | rel8 | `jng $+2+rel8` | Jump short if not greater. | ZF=1 or SF≠OF |
|
||
| `7C ??` | rel8 | `jnge $+2+rel8` | Jump short if not greater or equal. | SF≠OF |
|
||
| `7D ??` | rel8 | `jnl $+2+rel8` | Jump short if not less. | SF=OF |
|
||
| `7F ??` | rel8 | `jnle $+2+rel8` | Jump short if not less or equal. | ZF=0 and SF=OF |
|
||
| `71 ??` | rel8 | `jno $+2+rel8` | Jump short if not overflow. | OF=0 |
|
||
| `7B ??` | rel8 | `jnp $+2+rel8` | Jump short if not parity. | PF=0 |
|
||
| `79 ??` | rel8 | `jns $+2+rel8` | Jump short if not sign. | SF=0 |
|
||
| `75 ??` | rel8 | `jnz $+2+rel8` | Jump short if not zero. | ZF=0 |
|
||
| `70 ??` | rel8 | `jo $+2+rel8` | Jump short if overflow. | OF=1 |
|
||
| `7A ??` | rel8 | `jp $+2+rel8` | Jump short if parity. | PF=1 |
|
||
| `7A ??` | rel8 | `jpe $+2+rel8` | Jump short if parity even. | PF=1 |
|
||
| `7B ??` | rel8 | `jpo $+2+rel8` | Jump short if parity odd. | PF=0 |
|
||
| `78 ??` | rel8 | `js $+2+rel8` | Jump short if sign. | SF=1 |
|
||
| `74 ??` | rel8 | `jz $+2+rel8` | Jump short if zero. | ZF=1 |
|
||
|
||
**Short jump encodings only available in 32-bit mode:**
|
||
|
||
| Opcode | Operands | Assembly | Description | Test |
|
||
| ------- | -------- | --------------- | ------------------------------- | ---- |
|
||
| `E3 cb` | rel8 | `jcxz $+2+rel8` | Jump short if CX register is 0. | CX=0 |
|
||
|
||
**Short jump encodings only available in 64-bit mode:**
|
||
|
||
| Opcode | Operands | Assembly | Description | Test |
|
||
| ------- | -------- | ---------------- | -------------------------------- | ----- |
|
||
| `E3 cb` | rel8 | `jrcxz $+2+rel8` | Jump short if RCX register is 0. | RCX=0 |
|
||
|
||
**Near relative jump encodings available in both 32-bit and 64-bit modes:**
|
||
|
||
| Opcode | Operands | Assembly | Description | Test |
|
||
| ------------------- | -------- | ---------------- | ---------------------------------- | ---------------- |
|
||
| `0F 87 ?? ?? ?? ??` | rel32 | `ja $+6+rel32` | Jump near if above. | CF=0 and ZF=0 |
|
||
| `0F 83 ?? ?? ?? ??` | rel32 | `jae $+6+rel32` | Jump near if above or equal. | CF=0 |
|
||
| `0F 82 ?? ?? ?? ??` | rel32 | `jb $+6+rel32` | Jump near if below. | CF=1 |
|
||
| `0F 86 ?? ?? ?? ??` | rel32 | `jbe $+6+rel32` | Jump near if below or equal. | CF=1 or ZF=1 |
|
||
| `0F 82 ?? ?? ?? ??` | rel32 | `jc $+6+rel32` | Jump near if carry. | CF=1 |
|
||
| `0F 84 ?? ?? ?? ??` | rel32 | `je $+6+rel32` | Jump near if equal. | ZF=1 |
|
||
| `0F 84 ?? ?? ?? ??` | rel32 | `jz $+6+rel32` | Jump near if 0. | ZF=1 |
|
||
| `0F 8F ?? ?? ?? ??` | rel32 | `jg $+6+rel32` | Jump near if greater. | ZF=0 and SF=OF |
|
||
| `0F 8D ?? ?? ?? ??` | rel32 | `jge $+6+rel32` | Jump near if greater or equal. | SF=OF |
|
||
| `0F 8C ?? ?? ?? ??` | rel32 | `jl $+6+rel32` | Jump near if less. | SF≠OF |
|
||
| `0F 8E ?? ?? ?? ??` | rel32 | `jle $+6+rel32` | Jump near if less or equal. | ZF=1 or SF≠OF |
|
||
| `0F 86 ?? ?? ?? ??` | rel32 | `jna $+6+rel32` | Jump near if not above. | CF=1 or ZF=1 |
|
||
| `0F 82 ?? ?? ?? ??` | rel32 | `jnae $+6+rel32` | Jump near if not above or equal. | CF=1 |
|
||
| `0F 83 ?? ?? ?? ??` | rel32 | `jnb $+6+rel32` | Jump near if not below. | CF=0 |
|
||
| `0F 87 ?? ?? ?? ??` | rel32 | `jnbe $+6+rel32` | Jump near if not below or equal. | CF=0 and ZF=0 |
|
||
| `0F 83 ?? ?? ?? ??` | rel32 | `jnc $+6+rel32` | Jump near if not carry. | CF=0 |
|
||
| `0F 85 ?? ?? ?? ??` | rel32 | `jne $+6+rel32` | Jump near if not equal. | ZF=0 |
|
||
| `0F 8E ?? ?? ?? ??` | rel32 | `jng $+6+rel32` | Jump near if not greater. | ZF=1 or SF≠OF |
|
||
| `0F 8C ?? ?? ?? ??` | rel32 | `jnge $+6+rel32` | Jump near if not greater or equal. | SF≠OF |
|
||
| `0F 8D ?? ?? ?? ??` | rel32 | `jnl $+6+rel32` | Jump near if not less. | SF=OF |
|
||
| `0F 8F ?? ?? ?? ??` | rel32 | `jnle $+6+rel32` | Jump near if not less or equal. | ZF=0 and SF=OF |
|
||
| `0F 81 ?? ?? ?? ??` | rel32 | `jno $+6+rel32` | Jump near if not overflow. | OF=0 |
|
||
| `0F 8B ?? ?? ?? ??` | rel32 | `jnp $+6+rel32` | Jump near if not parity. | PF=0 |
|
||
| `0F 89 ?? ?? ?? ??` | rel32 | `jns $+6+rel32` | Jump near if not sign. | SF=0 |
|
||
| `0F 85 ?? ?? ?? ??` | rel32 | `jnz $+6+rel32` | Jump near if not zero. | ZF=0 |
|
||
| `0F 80 ?? ?? ?? ??` | rel32 | `jo $+6+rel32` | Jump near if overflow. | OF=1 |
|
||
| `0F 8A ?? ?? ?? ??` | rel32 | `jp $+6+rel32` | Jump near if parity. | PF=1 |
|
||
| `0F 8A ?? ?? ?? ??` | rel32 | `jpe $+6+rel32` | Jump near if parity even. | PF=1 |
|
||
| `0F 8B ?? ?? ?? ??` | rel32 | `jpo $+6+rel32` | Jump near if parity odd. | PF=0 |
|
||
| `0F 88 ?? ?? ?? ??` | rel32 | `js $+6+rel32` | Jump near if sign. | SF=1 |
|
||
|
||
**Near relative jump encodings only available in 32-bit mode:**
|
||
|
||
| Opcode | Operands | Assembly | Description | Test |
|
||
| ---------------- | -------- | ---------------- | ---------------------------------- | ---------------- |
|
||
| `66 0F 87 ?? ??` | rel16 | `ja $+5+rel16` | Jump near if above. | CF=0 and ZF=0 |
|
||
| `66 0F 83 ?? ??` | rel16 | `jae $+5+rel16` | Jump near if above or equal. | CF=0 |
|
||
| `66 0F 82 ?? ??` | rel16 | `jb $+5+rel16` | Jump near if below. | CF=1 |
|
||
| `66 0F 86 ?? ??` | rel16 | `jbe $+5+rel16` | Jump near if below or equal. | CF=1 or ZF=1 |
|
||
| `66 0F 82 ?? ??` | rel16 | `jc $+5+rel16` | Jump near if carry. | CF=1 |
|
||
| `66 0F 84 ?? ??` | rel16 | `je $+5+rel16` | Jump near if equal. | ZF=1 |
|
||
| `66 0F 84 ?? ??` | rel16 | `jz $+5+rel16` | Jump near if 0. | ZF=1 |
|
||
| `66 0F 8F ?? ??` | rel16 | `jg $+5+rel16` | Jump near if greater. | ZF=0 and SF=OF |
|
||
| `66 0F 8D ?? ??` | rel16 | `jge $+5+rel16` | Jump near if greater or equal. | SF=OF |
|
||
| `66 0F 8C ?? ??` | rel16 | `jl $+5+rel16` | Jump near if less. | SF≠OF |
|
||
| `66 0F 8E ?? ??` | rel16 | `jle $+5+rel16` | Jump near if less or equal. | ZF=1 or SF≠OF |
|
||
| `66 0F 86 ?? ??` | rel16 | `jna $+5+rel16` | Jump near if not above. | CF=1 or ZF=1 |
|
||
| `66 0F 82 ?? ??` | rel16 | `jnae $+5+rel16` | Jump near if not above or equal. | CF=1 |
|
||
| `66 0F 83 ?? ??` | rel16 | `jnb $+5+rel16` | Jump near if not below. | CF=0 |
|
||
| `66 0F 87 ?? ??` | rel16 | `jnbe $+5+rel16` | Jump near if not below or equal. | CF=0 and ZF=0 |
|
||
| `66 0F 83 ?? ??` | rel16 | `jnc $+5+rel16` | Jump near if not carry. | CF=0 |
|
||
| `66 0F 85 ?? ??` | rel16 | `jne $+5+rel16` | Jump near if not equal. | ZF=0 |
|
||
| `66 0F 8E ?? ??` | rel16 | `jng $+5+rel16` | Jump near if not greater. | ZF=1 or SF≠OF |
|
||
| `66 0F 8C ?? ??` | rel16 | `jnge $+5+rel16` | Jump near if not greater or equal. | SF≠OF |
|
||
| `66 0F 8D ?? ??` | rel16 | `jnl $+5+rel16` | Jump near if not less. | SF=OF |
|
||
| `66 0F 8F ?? ??` | rel16 | `jnle $+5+rel16` | Jump near if not less or equal. | ZF=0 and SF=OF |
|
||
| `66 0F 81 ?? ??` | rel16 | `jno $+5+rel16` | Jump near if not overflow. | OF=0 |
|
||
| `66 0F 8B ?? ??` | rel16 | `jnp $+5+rel16` | Jump near if not parity. | PF=0 |
|
||
| `66 0F 89 ?? ??` | rel16 | `jns $+5+rel16` | Jump near if not sign. | SF=0 |
|
||
| `66 0F 85 ?? ??` | rel16 | `jnz $+5+rel16` | Jump near if not zero. | ZF=0 |
|
||
| `66 0F 80 ?? ??` | rel16 | `jo $+5+rel16` | Jump near if overflow. | OF=1 |
|
||
| `66 0F 8A ?? ??` | rel16 | `jp $+5+rel16` | Jump near if parity. | PF=1 |
|
||
| `66 0F 8A ?? ??` | rel16 | `jpe $+5+rel16` | Jump near if parity even. | PF=1 |
|
||
| `66 0F 8B ?? ??` | rel16 | `jpo $+5+rel16` | Jump near if parity odd. | PF=0 |
|
||
| `66 0F 88 ?? ??` | rel16 | `js $+5+rel16` | Jump near if sign. | SF=1 |
|
||
|
||
#### CALL — Call Procedure
|
||
|
||
**Near relative call encodings available in 32-bit mode:**
|
||
|
||
| Opcode | Operands | Assembly | Description |
|
||
| --------------------------- | ---------------------------- | ---------------------------------------------- | ------------------------------------------------------------------------ |
|
||
| `E8 ?? ?? ?? ??` | rel32 | `call $+5+rel32` | Call near, relative, displacement relative to next instruction. |
|
||
| `FF 1[0???] todo` | ModR/M:RM value != \{4, 5\} | `call dword ptr [reg]` | Call near, absolute indirect, address given in register. |
|
||
| `FF 14 ?[?101] ?? ?? ?? ??` | SIB byte; disp32 | `call dword ptr [scale*index + disp32]` | Call near, absolute indirect, address given according to SIB and disp32. |
|
||
| `FF 14 ?[????]` | SIB byte; Base != 5 | `call dword ptr [base + scale*index]` | Call near, absolute indirect, address given according to SIB. |
|
||
| `FF 15 ?? ?? ?? ??` | disp32 | `call dword ptr ds:disp32` | Call near, absolute, address given in disp32. |
|
||
| `FF 5[0???] ??` | ModR/M:RM value != 4; disp8 | `call dword ptr [reg + disp8]` | Call near, absolute indirect, address given in register and disp8. |
|
||
| `FF 54 ?? ??` | SIB byte; disp8 | `call dword ptr [base + scale*index + disp8]` | Call near, absolute indirect, address given according to SIB and disp8. |
|
||
| `FF 9[0???] ?? ?? ?? ??` | ModR/M:RM value != 4; disp32 | `call dword ptr [reg + disp32]` | Call near, absolute indirect, address given in register and disp32. |
|
||
| `FF 94 ?? ?? ?? ?? ??` | SIB byte; disp32 | `call dword ptr [base + scale*index + disp32]` | Call near, absolute indirect, address given according to SIB and disp32. |
|
||
| `FF D[0???]` | ModR/M:RM value | `call dword ptr reg` | Call near, absolute indirect, address given in register. |
|
||
| `66 E8 ?? ??` | rel16 | `callw $+4+rel16` | Call near, relative, displacement relative to next instruction. |
|
||
| `67 FF 1[0???]`\* | ModR/M:RM value != 6 | `call dword ptr [reg(+reg)?]` | Call near, absolute indirect. |
|
||
| `67 FF 16 ?? ??`\* | disp16 | `call dword ptr ds:disp16` | Call near, absolute, address given in disp16. |
|
||
| `67 FF 5[0???] ??`\* | ModR/M:RM value; disp8 | `call dword ptr [reg(+reg)?+disp8]` | Call near, absolute indirect. |
|
||
| `67 FF 9[0???] ?? ??`\* | ModR/M:RM value; disp16 | `call dword ptr [reg(+reg)?+disp16]` | Call near, absolute indirect. |
|
||
| `67 FF D[0???]`\* | ModR/M:RM value | `call reg` | Call near, absolute. |
|
||
|
||
\*: The `66` prefix can be used to change the dword ptr to a word ptr and jump to a 16-bit address instead.
|
||
|
||
**Near relative call encodings available in 64-bit mode:**
|
||
|
||
| Opcode | Operands | Assembly | Description | Notes |
|
||
| --------------------------- | --------------------------- | ---------------------------------------------- | --------------------------------------------------------------- | ----------------------- |
|
||
| `E8 ?? ?? ?? ??` | rel32 | `call $+5+rel32` | Call near, relative, displacement relative to next instruction. | - |
|
||
| `FF 1[0???] todo` | ModR/M:RM value != \{4, 5\} | `call qword ptr [reg]` | Call near, absolute indirect, address given in register. | - |
|
||
| `FF 14 ?[?101] ?? ?? ?? ??` | SIB byte; disp32 | `call qword ptr [index*scale + disp32]` | Call near, absolute indirect, address given in r/m64. | - |
|
||
| `FF 14 ?[????]` | SIB byte, Base != 5 | `call qword ptr [base + index*scale]` | Call near, absolute indirect, address given in r/m64. | - |
|
||
| `FF 15 ?? ?? ?? ??` | disp32 | `call qword ptr [$+6+disp32]` | Call near, absolute indirect, RIP offset given in disp32. | RIP-relative addressing |
|
||
| `FF 5[0???] ??` | ModR/M:RM value != 4 | `call qword ptr [reg + disp8]` | Call near, absolute indirect, address given in r/m64. | - |
|
||
| `FF 54 ?? ??` | SIB byte, disp8 | `call qword ptr [base + index*scale + disp8]` | Call near, absolute indirect, address given in r/m64. | - |
|
||
| `FF 9[0???] ?? ?? ?? ??` | ModR/M:RM value != 4 | `call qword ptr [reg + disp32]` | Call near, absolute indirect, address given in r/m64. | - |
|
||
| `FF 94 ?? ?? ?? ?? ??` | SIB byte, disp32 | `call qword ptr [base + index*scale + disp32]` | Call near, absolute indirect, address given in r/m64. | - |
|
||
| `FF D[0???]` | ModR/M:RM value | `call reg` | Call near, absolute. | - |
|
||
|
||
todo: far calls
|
||
|
||
#### RET — Return from procedure call
|
||
|
||
**Encodings available in both 32-bit and 64-bit modes:**
|
||
|
||
| Opcode | Operands | Assembly | Description |
|
||
| ---------- | -------- | ------------ | ------------------------------------------------------------------ |
|
||
| `C3` | - | `ret` | Near return to calling procedure. |
|
||
| `CB` | - | `retf` | Far return to calling procedure. |
|
||
| `C2 ?? ??` | imm16 | `ret imm16` | Near return to calling procedure and pop `imm16` bytes from stack. |
|
||
| `CA ?? ??` | imm16 | `retf imm16` | Far return to calling procedure and pop `imm16` bytes from stack. |
|
||
|
||
### Integer arithmetic operations
|
||
|
||
#### ADD — Add
|
||
|
||
#### SUB — Subtract
|
||
|
||
#### MUL — Unsigned Multiply
|
||
|
||
#### IMUL — Signed Multiply
|
||
|
||
#### DIV — Unsigned Divide
|
||
|
||
#### IDIV — Signed Divide
|
||
|
||
#### INC — Increment by 1
|
||
|
||
**Encodings available in 32-bit mode:**
|
||
|
||
| Opcode | Operands | Assembly | Description |
|
||
| ------------------------------ | ---------------- | ------------------------------------------------------- | ------------------------------- |
|
||
| `FE 0[0???]` | R/M != \{4, 5\} | `inc byte ptr [r32]` | Increment r/m byte by 1. |
|
||
| `FE 04 ?[????]` | SIB, Base != 5 | `inc byte ptr [base_r32 + (index_r32*scale)]` | Increment r/m byte by 1. |
|
||
| `FE 04 ?[?101] ?? ?? ?? ??` | SIB; disp32 | `inc byte ptr [(index_r32*scale) + disp32]` | Increment r/m byte by 1. |
|
||
| `FE 05 ?? ?? ?? ??` | disp32 | `inc byte ptr ds:disp32` | Increment r/m byte by 1. |
|
||
| `FE 4[0???] ??` | R/M != 4; disp8 | `inc byte ptr [r32 + disp8]` | Increment r/m byte by 1. |
|
||
| `FE 44 ?? ??` | SIB; disp8 | `inc byte ptr [base_r32 + (index_r32*scale) + disp8]` | Increment r/m byte by 1. |
|
||
| `FE 8[0???] ?? ?? ?? ??` | R/M != 4; disp32 | `inc byte ptr [r32 + disp32]` | Increment r/m byte by 1. |
|
||
| `FE 84 ?? ?? ?? ?? ??` | SIB; disp32 | `inc byte ptr [base_r32 + (index_r32*scale) + disp32]` | Increment r/m byte by 1. |
|
||
| `FE C[0???]` | R/M | `inc r8` | Increment r/m byte by 1. |
|
||
| | | | |
|
||
| `67 FE 0[0???]` | todo | | Increment r/m byte by 1. |
|
||
| `67 FE 04 ?[????]` | todo | | Increment r/m byte by 1. |
|
||
| `67 FE 04 ?[?101] ?? ?? ?? ??` | todo | | Increment r/m byte by 1. |
|
||
| `67 FE 05 ?? ?? ?? ??` | todo | | Increment r/m byte by 1. |
|
||
| `67 FE 4[0???] ??` | todo | | Increment r/m byte by 1. |
|
||
| `67 FE 44 ?? ??` | todo | | Increment r/m byte by 1. |
|
||
| `67 FE 8[0???] ?? ?? ?? ??` | todo | | Increment r/m byte by 1. |
|
||
| `67 FE 84 ?? ?? ?? ?? ??` | todo | | Increment r/m byte by 1. |
|
||
| | | | |
|
||
| `FF 0[0???]`\* | R/M != \{4, 5\} | `inc dword ptr [r32]` | Increment r/m doubleword by 1. |
|
||
| `FF 04 ?[????]`\* | SIB, Base != 5 | `inc dword ptr [base_r32 + (index_r32*scale)]` | Increment r/m doubleword by 1. |
|
||
| `FF 04 ?[?101] ?? ?? ?? ??` | SIB; disp32 | `inc dword ptr [(index_r32*scale) + disp32]` | Increment r/m doubleword by 1. |
|
||
| `FF 05 ?? ?? ?? ??`\* | disp32 | `inc dword ptr ds:disp32` | Increment r/m doubleword by 1. |
|
||
| `FF 4[0???] ??`\* | R/M != 4; disp8 | `inc dword ptr [r32 + disp8]` | Increment r/m doubleword by 1. |
|
||
| `FF 44 ?? ??`\* | SIB; disp8 | `inc dword ptr [base_r32 + (index_r32*scale) + disp8]` | Increment r/m doubleword by 1. |
|
||
| `FF 8[0???] ?? ?? ?? ??`\* | R/M != 4; disp32 | `inc dword ptr [r32 + disp32]` | Increment r/m doubleword by 1. |
|
||
| `FF 84 ?? ?? ?? ?? ??`\* | SIB; disp32 | `inc dword ptr [base_r32 + (index_r32*scale) + disp32]` | Increment r/m doubleword by 1. |
|
||
| `FF C[0???]`\* | R/M | `inc r8` | Increment r/m doubleword by 1. |
|
||
| | | | |
|
||
| `67 FF 0[0???]`\* | todo | todo | Increment r/m doubleword by 1. |
|
||
| `67 FF 04 ?[????]`\* | todo | todo | Increment r/m doubleword by 1. |
|
||
| `67 FF 04 ?[?101] ?? ?? ?? ??` | todo | todo | Increment r/m doubleword by 1. |
|
||
| `67 FF 05 ?? ?? ?? ??`\* | todo | todo | Increment r/m doubleword by 1. |
|
||
| `67 FF 4[0???] ??`\* | todo | todo | Increment r/m doubleword by 1. |
|
||
| `67 FF 44 ?? ??`\* | todo | todo | Increment r/m doubleword by 1. |
|
||
| `67 FF 8[0???] ?? ?? ?? ??`\* | todo | todo | Increment r/m doubleword by 1. |
|
||
| `67 FF 84 ?? ?? ?? ?? ??`\* | todo | todo | Increment r/m doubleword by 1. |
|
||
| `67 FF C[0???]`\* | todo | todo | Increment r/m doubleword by 1. |
|
||
| | | | |
|
||
| `66 40` | - | `inc ax` | Increment 16-bit register by 1. |
|
||
| `66 41` | - | `inc cx` | Increment 16-bit register by 1. |
|
||
| `66 42` | - | `inc dx` | Increment 16-bit register by 1. |
|
||
| `66 43` | - | `inc bx` | Increment 16-bit register by 1. |
|
||
| `66 44` | - | `inc sp` | Increment 16-bit register by 1. |
|
||
| `66 45` | - | `inc bp` | Increment 16-bit register by 1. |
|
||
| `66 46` | - | `inc si` | Increment 16-bit register by 1. |
|
||
| `66 47` | - | `inc di` | Increment 16-bit register by 1. |
|
||
| `40` | - | `inc eax` | Increment 32-bit register by 1. |
|
||
| `41` | - | `inc ecx` | Increment 32-bit register by 1. |
|
||
| `42` | - | `inc edx` | Increment 32-bit register by 1. |
|
||
| `43` | - | `inc ebx` | Increment 32-bit register by 1. |
|
||
| `44` | - | `inc esp` | Increment 32-bit register by 1. |
|
||
| `45` | - | `inc ebp` | Increment 32-bit register by 1. |
|
||
| `46` | - | `inc esi` | Increment 32-bit register by 1. |
|
||
| `47` | - | `inc edi` | Increment 32-bit register by 1. |
|
||
|
||
\* The prefix `66` can be used to increment a 16-bit register or memory location instead of a 32-bit one.
|
||
|
||
**Encodings available in 64-bit mode:**
|
||
|
||
| Opcode | Operands | Assembly | Description |
|
||
| ------------- | -------- | -------- | ------------------------------ |
|
||
| `FE /0` | todo | todo | Increment r/m byte by 1. |
|
||
| `REX + FE /0` | todo | todo | Increment r/m byte by 1. |
|
||
| `66 FF /0` | todo | todo | Increment r/m word by 1. |
|
||
| `FF /0` | todo | todo | Increment r/m doubleword by 1. |
|
||
| `REX.W FF /0` | todo | todo | Increment r/m quadword by 1. |
|
||
|
||
#### DEC — Decrement by 1
|
||
|
||
#### NOT — One's Complement Negation
|
||
|
||
**Encodings available in both 32-bit and 64-bit mode:**
|
||
|
||
| Opcode | Operands | Assembly (32-bit) | Assembly (64-bit) | Description |
|
||
| ------------------------------- | ---------------- | ------------------------------------------------------- | ------------------------------------------------------- | ------------------------------------------ |
|
||
| `F6 1[0???]`\* | R/M != \{4, 5\} | `not byte ptr [r32]` | `not byte ptr [r64]` | Invert each bit of a byte in memory. |
|
||
| `F6 14 ?[????]`\* | SIB, Base != 5 | `not byte ptr [base_r32 + (index_r32*scale)]` | `not byte ptr [base_r64 + (index_r64*scale)]` | Invert each bit of a byte in memory. |
|
||
| `F6 14 ?[?101] ?? ?? ?? ??`\* | SIB; disp32 | `not byte ptr [(index_r32*scale) + disp32]` | `not byte ptr [(index_r64*scale) + disp32]` | Invert each bit of a byte in memory. |
|
||
| `F6 15 ?? ?? ?? ??`\* | disp32 | `not byte ptr ds:disp32` | `not byte ptr [$ + 6 + disp32]` | Invert each bit of a byte in memory. |
|
||
| `F6 5[0???] ??`\* | R/M != 4; disp8 | `not byte ptr [r32 + disp8]` | `not byte ptr [r64 + disp8]` | Invert each bit of a byte in memory. |
|
||
| `F6 54 ?? ??`\* | SIB; disp8 | `not byte ptr [base_r32 + (index_r32*scale) + disp8]` | `not byte ptr [base_r64 + (index_r64*scale) + disp8]` | Invert each bit of a byte in memory. |
|
||
| `F6 9[0???] ?? ?? ?? ??`\* | R/M != 4; disp32 | `not byte ptr [r32 + disp32]` | `not byte ptr [r64 + disp32]` | Invert each bit of a byte in memory. |
|
||
| `F6 94 ?? ?? ?? ?? ??`\* | SIB; disp32 | `not byte ptr [base_r32 + (index_r32*scale) + disp32]` | `not byte ptr [base_r64 + (index_r64*scale) + disp32]` | Invert each bit of a byte in memory. |
|
||
| `F6 D[0???]`\* | R/M | `not r8` | `not r8` | Invert each bit of an 8-bit register. |
|
||
| | | | | |
|
||
| `F7 1[0???]`\*\* | R/M != \{4, 5\} | `not dword ptr [r32]` | `not dword ptr [r64]` | Invert each bit of a doubleword in memory. |
|
||
| `F7 14 ?[????]`\*\* | SIB, Base != 5 | `not dword ptr [base_r32 + (index_r32*scale)]` | `not dword ptr [base_r64 + (index_r64*scale)]` | Invert each bit of a doubleword in memory. |
|
||
| `F7 14 ?[?101] ?? ?? ?? ??`\*\* | SIB; disp32 | `not dword ptr [(index_r32*scale) + disp32]` | `not dword ptr [(index_r64*scale) + disp32]` | Invert each bit of a doubleword in memory. |
|
||
| `F7 15 ?? ?? ?? ??`\*\* | disp32 | `not dword ptr ds:disp32` | `not dword ptr [$ + 6 + disp32]` | Invert each bit of a doubleword in memory. |
|
||
| `F7 5[0???] ??`\*\* | R/M != 4; disp8 | `not dword ptr [r32 + disp8]` | `not dword ptr [r64 + disp8]` | Invert each bit of a doubleword in memory. |
|
||
| `F7 54 ?? ??`\*\* | SIB; disp8 | `not dword ptr [base_r32 + (index_r32*scale) + disp8]` | `not dword ptr [base_r64 + (index_r64*scale) + disp8]` | Invert each bit of a doubleword in memory. |
|
||
| `F7 9[0???] ?? ?? ?? ??`\*\* | R/M != 4; disp32 | `not dword ptr [r32 + disp32]` | `not dword ptr [r64 + disp32]` | Invert each bit of a doubleword in memory. |
|
||
| `F7 94 ?? ?? ?? ?? ??`\*\* | SIB; disp32 | `not dword ptr [base_r32 + (index_r32*scale) + disp32]` | `not dword ptr [base_r64 + (index_r64*scale) + disp32]` | Invert each bit of a doubleword in memory. |
|
||
| `F7 D[0???]`\*\* | R/M | `not r32` | `not r32` | Invert each bit of an 32-bit register. |
|
||
|
||
\* REX applicable
|
||
|
||
\*\* 66 -> 16-bit memory/reg; REX.W -> 64-bit memory/reg
|
||
|
||
**Encodings only available in 32-bit mode:**
|
||
|
||
todo (pain)
|
||
|
||
#### NEG — Two's Complement Negation
|
||
|
||
**Encodings available in both 32-bit and 64-bit mode:**
|
||
|
||
| Opcode | Operands | Assembly (32-bit) | Assembly (64-bit) | Description |
|
||
| ------------------------------- | ---------------- | ------------------------------------------------------- | ------------------------------------------------------- | ----------------------------------------------- |
|
||
| `F6 1[1???]`\* | R/M != \{4, 5\} | `neg byte ptr [r32]` | `neg byte ptr [r64]` | Two's complement negate a byte in memory. |
|
||
| `F6 1C ?[????]`\* | SIB, Base != 5 | `neg byte ptr [base_r32 + (index_r32*scale)]` | `neg byte ptr [base_r64 + (index_r64*scale)]` | Two's complement negate a byte in memory. |
|
||
| `F6 1C ?[?101] ?? ?? ?? ??`\* | SIB; disp32 | `neg byte ptr [(index_r32*scale) + disp32]` | `neg byte ptr [(index_r64*scale) + disp32]` | Two's complement negate a byte in memory. |
|
||
| `F6 1D ?? ?? ?? ??`\* | disp32 | `neg byte ptr ds:disp32` | `neg byte ptr [$ + 6 + disp32]` | Two's complement negate a byte in memory. |
|
||
| `F6 5[1???] ??`\* | R/M != 4; disp8 | `neg byte ptr [r32 + disp8]` | `neg byte ptr [r64 + disp8]` | Two's complement negate a byte in memory. |
|
||
| `F6 5C ?? ??`\* | SIB; disp8 | `neg byte ptr [base_r32 + (index_r32*scale) + disp8]` | `neg byte ptr [base_r64 + (index_r64*scale) + disp8]` | Two's complement negate a byte in memory. |
|
||
| `F6 9[1???] ?? ?? ?? ??`\* | R/M != 4; disp32 | `neg byte ptr [r32 + disp32]` | `neg byte ptr [r64 + disp32]` | Two's complement negate a byte in memory. |
|
||
| `F6 9C ?? ?? ?? ?? ??`\* | SIB; disp32 | `neg byte ptr [base_r32 + (index_r32*scale) + disp32]` | `neg byte ptr [base_r64 + (index_r64*scale) + disp32]` | Two's complement negate a byte in memory. |
|
||
| `F6 D[1???]`\* | R/M | `neg r8` | `neg r8` | Two's complement negate an 8-bit register. |
|
||
| | | | | |
|
||
| `F7 1[1???]`\*\* | R/M != \{4, 5\} | `neg dword ptr [r32]` | `neg dword ptr [r64]` | Two's complement negate a doubleword in memory. |
|
||
| `F7 1C ?[????]`\*\* | SIB, Base != 5 | `neg dword ptr [base_r32 + (index_r32*scale)]` | `neg dword ptr [base_r64 + (index_r64*scale)]` | Two's complement negate a doubleword in memory. |
|
||
| `F7 1C ?[?101] ?? ?? ?? ??`\*\* | SIB; disp32 | `neg dword ptr [(index_r32*scale) + disp32]` | `neg dword ptr [(index_r64*scale) + disp32]` | Two's complement negate a doubleword in memory. |
|
||
| `F7 1D ?? ?? ?? ??`\*\* | disp32 | `neg dword ptr ds:disp32` | `neg dword ptr [$ + 6 + disp32]` | Two's complement negate a doubleword in memory. |
|
||
| `F7 5[1???] ??`\*\* | R/M != 4; disp8 | `neg dword ptr [r32 + disp8]` | `neg dword ptr [r64 + disp8]` | Two's complement negate a doubleword in memory. |
|
||
| `F7 5C ?? ??`\*\* | SIB; disp8 | `neg dword ptr [base_r32 + (index_r32*scale) + disp8]` | `neg dword ptr [base_r64 + (index_r64*scale) + disp8]` | Two's complement negate a doubleword in memory. |
|
||
| `F7 9[1???] ?? ?? ?? ??`\*\* | R/M != 4; disp32 | `neg dword ptr [r32 + disp32]` | `neg dword ptr [r64 + disp32]` | Two's complement negate a doubleword in memory. |
|
||
| `F7 9C ?? ?? ?? ?? ??`\*\* | SIB; disp32 | `neg dword ptr [base_r32 + (index_r32*scale) + disp32]` | `neg dword ptr [base_r64 + (index_r64*scale) + disp32]` | Two's complement negate a doubleword in memory. |
|
||
| `F7 D[1???]`\*\* | R/M | `neg r32` | `neg r32` | Two's complement negate an 32-bit register. |
|
||
|
||
\* REX applicable
|
||
|
||
\*\* 66 -> 16-bit memory/reg; REX.W -> 64-bit memory/reg
|
||
|
||
**Encodings only available in 32-bit mode:**
|
||
|
||
todo (pain)
|
||
|
||
#### AND — Logical AND
|
||
|
||
#### OR — Logical Inclusive OR
|
||
|
||
#### XOR — Logical Exclusive OR
|
||
|
||
#### CMP — Compare Two Operands
|
||
|
||
#### TEST — Logical Compare
|
||
|
||
### String instructions
|
||
|
||
#### REP\* Prefixes
|
||
|
||
#### MOVS — Move Data From String to String
|
||
|
||
#### LODS — Load String
|
||
|
||
#### STOS — Store String
|
||
|
||
#### CMPS — Compare String Operands
|
||
|
||
#### SCAS — Scan String
|
||
|
||
### Miscellaneous instructions
|
||
|
||
#### NOP — No Operation
|
||
|
||
Encodings available in both 32-bit and 64-bit modes:
|
||
|
||
| Opcode | Operands | Assembly (32-bit mode) | Description |
|
||
| --------------------------- | ---------------------------- | ---------------------------------- | ------------------------------------ |
|
||
| `90` | - | `nop` | One byte no-operation instruction. |
|
||
| `67 0F 1F 06 ?? ??` | disp16 | `nop dword ptr ds:disp16` | Multi-byte no-operation instruction. |
|
||
| `67 0F 1F 0[0???]` | ModR/M:RM value != 6 | `nop dword ptr [reg(+reg)?]` | Multi-byte no-operation instruction. |
|
||
| `67 0F 1F 4[0???] ??` | ModR/M:RM value; imm8 | `nop dword ptr [reg(+reg)?+imm8]` | Multi-byte no-operation instruction. |
|
||
| `67 0F 1F 8[0???] ?? ??` | ModR/M:RM value; imm16 | `nop dword ptr [reg(+reg)?+imm16]` | Multi-byte no-operation instruction. |
|
||
| `67 0F 1F C[0???]` | ModR/M:RM value | `nop reg` | Multi-byte no-operation instruction. |
|
||
| `0F 1F 04 ??` | SIB byte | `nop dword ptr todo` | Multi-byte no-operation instruction. |
|
||
| `0F 1F 05 ?? ?? ?? ??` | disp32 | `nop dword ptr ds:disp32` | Multi-byte no-operation instruction. |
|
||
| `0F 1F 0[0???] todo` | ModR/M:RM value != \{4, 5\} | `nop dword ptr [reg]` | Multi-byte no-operation instruction. |
|
||
| `0F 1F 44 ?? ??` | SIB byte; disp8 | `nop dword ptr todo` | Multi-byte no-operation instruction. |
|
||
| `0F 1F 4[0???] ??` | ModR/M:RM value != 4; disp8 | `nop dword ptr [reg+disp8]` | Multi-byte no-operation instruction. |
|
||
| `0F 1F 84 ?? ?? ?? ?? ??` | SIB byte; disp32 | `nop dword ptr todo` | Multi-byte no-operation instruction. |
|
||
| `0F 1F 8[0???] ?? ?? ?? ??` | ModR/M:RM value != 4; disp32 | `nop dword ptr [reg+disp32]` | Multi-byte no-operation instruction. |
|
||
| `0F 1F C[0???]` | ModR/M:RM value | `nop reg` | Multi-byte no-operation instruction. |
|
||
|
||
#### FNOP — No Operation
|
||
|
||
Encodings available in both 32-bit and 64-bit modes:
|
||
|
||
| Opcode | Operands | Assembly | Description |
|
||
| ------- | -------- | -------- | -------------------------- |
|
||
| `D9 D0` | - | `fnop` | No operation is performed. |
|
||
|
||
#### INT3 — Generate Breakpoint Trap
|
||
|
||
Encodings available in both 32-bit and 64-bit modes:
|
||
|
||
| Opcode | Operands | Assembly | Description |
|
||
| ------ | -------- | -------- | ------------------------- |
|
||
| `CC` | - | `int3` | Generate breakpoint trap. |
|
||
|
||
#### INT — Call to Interrupt Procedure
|
||
|
||
Encodings available in both 32-bit and 64-bit modes:
|
||
|
||
| Opcode | Operands | Assembly | Description |
|
||
| ------- | -------- | ---------- | -------------------------------------------------------------------- |
|
||
| `CD ??` | imm8 | `int imm8` | Generate software interrupt with vector specified by immediate byte. |
|
||
|
||
#### SYSCALL — Fast System Call (64-bit only)
|
||
|
||
Encodings available in 64-bit mode:
|
||
|
||
| Opcode | Operands | Assembly | Description |
|
||
| ------- | -------- | --------- | ------------------------------------------------- |
|
||
| `0F 05` | - | `syscall` | Fast call to privilege level 0 system procedures. |
|
||
|
||
## Appendix
|
||
|
||
## References
|
||
|
||
[Intel® 64 and IA-32 Architectures Software Developer’s Manual Combined Volumes: 1, 2A, 2B, 2C, 2D, 3A, 3B, 3C, 3D, and 4](https://cdrdv2.intel.com/v1/dl/getContent/671200)
|