5.1 Instruction Format and Machine-Code Encoding
Chapter 4 described the state an 8086 instruction can use: registers, FLAGS, segments, and memory. The processor cannot read assembly text such as MOV AX,1234H directly. It reads machine code, an ordered sequence of bytes.
An instruction encoding is the rule that translates an operation and its operands into those bytes. The reverse process is decoding or, when producing assembly text, disassembly.
An instruction is a structured byte packet
8086 instructions have variable length. Depending on the instruction, the stream may contain:
| Part | Purpose | Present in every instruction? |
|---|---|---|
| Prefix | modifies segment choice, repetition, or locking | no |
| Opcode | identifies the operation and sometimes width/direction/register | yes |
| ModR/M byte | describes register and register-or-memory operands | no |
| Displacement | constant added during address calculation, or a direct offset | no |
| Immediate | literal data used as an operand | no |
The opcode must come before the fields whose meaning it defines. A decoder cannot interpret a following byte as ModR/M, displacement, or immediate data until it knows the instruction family.
Not every instruction uses every box. For example:
MOV AL,7FHuses opcodeB0Hfollowed by one immediate byte7FH.
MOV AX,1234Huses opcodeB8H, then immediate bytes34H 12H.
The second example stores the 16-bit immediate in little-endian order: low byte first, high byte second. This is the same byte-order principle used for words in memory, now applied to bytes embedded in the instruction stream.
Some opcodes contain a register number
For MOV r16,imm16, opcodes B8H through BFH select one of eight 16-bit registers:
| Code | Register | Opcode |
|---|---|---|
| 000 | AX | B8H |
| 001 | CX | B9H |
| 010 | DX | BAH |
| 011 | BX | BBH |
| 100 | SP | BCH |
| 101 | BP | BDH |
| 110 | SI | BEH |
| 111 | DI | BFH |
The operation and register choice are packed into one byte. MOV DX,BEEFH therefore begins with BAH, followed by immediate low byte EFH and high byte BEH.
Lab 1 — forge a byte stream and let the decoder judge it
Edit opcode and data bytes directly. The live decoder reacts to every change, so a swapped immediate, wrong register number, or incorrect opcode produces a different instruction rather than a generic “wrong” message.
Check your understanding
The ModR/M byte describes two operands
Many 8086 instruction families place operand information in a second byte called ModR/M:
- mod distinguishes a register operand from memory forms and determines displacement length.
- reg usually selects a register operand. In some instruction families it instead extends the opcode.
- r/m selects either a register or one of the legal memory-address expressions.
The mod field has four patterns:
| mod | Meaning |
|---|---|
00 | memory, normally no displacement |
01 | memory plus signed 8-bit displacement |
10 | memory plus 16-bit displacement |
11 | register-to-register; r/m names a register |
There is one essential special case: mod=00 and r/m=110 means a direct 16-bit address follows. It does not mean [BP]. To encode [BP], the processor uses mod=01 with an 8-bit zero displacement, or mod=10 with a 16-bit displacement.
For word operands, both reg and register-form r/m use the same three-bit order shown in the table above. As an example, MOV AX,BX can use:
- opcode
8BH, meaningreg16 ← r/m16;
- ModR/M
11 000 011, meaning register form, reg=AX, r/m=BX;
- complete bytes
8B C3.
Lab 2 — assemble ModR/M one bit at a time
Choose MOV direction, toggle all eight ModR/M bits, and supply displacement bytes only when the selected mod form requires them. Missions include register-to-register, based/indexed memory, signed 8-bit displacement, and the direct-address special case.
Check your understanding
A disciplined encoding workflow
1. Identify the operation, operand width, and data direction.
2. Select the instruction family and opcode.
3. If required, assign mod, reg, and r/m.
4. Determine whether displacement bytes follow.
5. Append immediate data, placing the low byte first for a 16-bit value.
Never decode a byte in isolation without knowing its position and instruction family. The byte C3H, for example, can be a ModR/M byte in 8B C3, but the same bit pattern at an opcode boundary names a completely different instruction.
The next section focuses on the meaning of operands after they have been decoded: literal data, register data, and data reached through a direct memory address.