This blog post shows byte sequences in assembly to trigger various x86 CPU exceptions. The CPU must be in protected mode. The CPU may be in any ring (security level). Paging may or may not be enabled. The byte sequences work in both 16-bit protected mode (80286 CPU or later) and 32-bit protected mode (80386 CPU or later). The exceptions not mentioned below are harder to trigger.
The reason why triggering an exception deliberately is useful is that some environments (such as PMODE/W) display a register dump upon an unhandled CPU exception, and that can be used for debugging. GDB (the GNU Debugger) can do the same: when you
run a program, and it fails with a fatal signal caused by a CPU exception, use
info registers to see the register values at the time of the signal, and use
bt to see a stack trace.
Exception 0: Division Error #DE
Byte sequence: db 0d4h, 0
16-bit and 32-bit disassembly: aam 0
Exception 1: Debug #DB
Byte sequence: db 9ch, 58h, 80h, 0cch, 1, 50h, 9dh
16-bit disassembly: pushf; pop ax; or ah, 1; push ax; popf
32-bit disassembly: pushf; pop eax; or ah, 1; push eax; popf
This needs a valid stack. This sets TF (Trap Flag) to 1.
Exception 3: Breakpoint #BP
Byte sequence: db 0cch
16-bit and 32-bit disassembly: int3
Exception 4: Overflow #OF
Byte sequence: db 0b0h, 7fh, 0feh, 0c0h, 0ceh
16-bit and 32-bit disassembly: mov al, 127; inc al; into
This triggers a signed integer overflow by setting OF (Overflow Bit) := 1, and doing an into.
Exception 5: Bound Range Exceeded #BR
Byte sequence: db 31h, 0c0h, 50h, 50h, 40h, 89h, 0e3h, 89h, 0e7h, 36h, 62h, 7
16-bit disassembly: xor ax, ax; push ax; push ax; inc ax; mov bx, sp; mov di, sp; bound ax, [ss:bx]
32-bit disassembly: xor eax, eax; push eax; push eax; inc ax; mov ebx, esp; mov edi, esp; bound eax, [ss:edi]
This needs a valid stack. This triggers a signed integer out-of-bounds in the bound instruction.
Exception 6: Invalid Opcode #UD
Byte sequence: db 0fh, 0bh
16-bit and 32-bit disassembly: ud2
Exception 13 == 0dh: General Protection Fault #GP
Byte sequence: db 31h, 0c0h, 48h, 8eh, 0c0h
32-bit disassembly: xor eax, eax; dec eax; mov es, eax
16-bit disassembly: xor ax, ax; dec ax; mov es, ax
This doesn't trigger the exception if the LDT is full (i.e. it has limit 0ffffh), which is unlikely. LDTs typically have only a couple of entries.