Registers are storage inside the CPU, faster than memory and named directly in instructions. Every 8086 register is 16 bits wide. Most instructions can use any general register, but many have a favourite, and some registers are the only ones allowed for a job.
| Register | Name | Special roles |
|---|---|---|
| AX (AH, AL) | accumulator | MUL, DIV, IN, OUT, LODS, STOS; AH = DOS function |
| BX (BH, BL) | base | addresses memory ([BX]); the XLAT table |
| CX (CH, CL) | count | LOOP, REP, JCXZ; CL = shift count |
| DX (DH, DL) | data | port number for IN/OUT; high half for MUL/DIV |
| SI | source index | addresses memory; DS:SI for strings |
| DI | destination index | addresses memory; ES:DI for strings |
| BP | base pointer | addresses the stack ([BP] uses SS) |
| SP | stack pointer | top of the stack, SS:SP |
| CS DS ES SS | segments | code, data, extra, stack |
| IP | instruction pointer | the next instruction, CS:IP |
| FLAGS | flags | results of the last operation, CPU control |
Halves
AX, BX, CX and DX each split into a high and a low byte: AH and AL make up AX, and so on. They are the same storage, not copies: writing AL changes the low byte of AX, and MOV AX, 0305h sets AH to 3 and AL to 5. SI, DI, BP and SP have no byte halves.
MOV AX, 0305h ; AH = 3, AL = 5MOV BX, AXMOV AL, BH ; the high half: 3ADD AL, '0' ; digit -> characterMOV DL, ALMOV AH, 02h ; DOS: print DLINT 21hMOV AL, BL ; the low half: 5ADD AL, '0' ; digit -> characterMOV DL, ALMOV AH, 02h ; DOS: print DLINT 21h
What you cannot do
Only BX, BP, SI and DI can hold an address in brackets; [AX] or [CX] do not exist. Segment registers take no arithmetic and are loaded only from a general register, memory or the stack. IP is never named: it changes with jumps, calls, returns and interrupts. To read it, call the next line and pop the return address.
CALL HERE1HERE1:POP BX ; BX = the offset of HERE1
Conventions
DOS and BIOS calls take their function number in AH and return results in fixed registers, listed for each function. Procedures usually save the registers they change, apart from those that return a result.
Later CPUs
The 80386 widens the general registers to 32 bits (EAX, EBX, ... ESP, with AX still the low half of EAX), widens IP and FLAGS to EIP and EFLAGS, and adds the segment registers FS and GS.