Encoding of Effective Addresses

Unless you are concerned with the nitty-gritty details of 86
instruction encoding, you don't need to read this file.

Every instruction with an effective address has an encoded byte,
known as the effective address byte, following the 1-byte opcode
for the instruction. (For obscure reasons, Intel calls this byte
the ModRM byte.)  If the effective address is a memory variable,
or an indexed memory location with a non-zero constant offset,
then the effective address byte will be immediately followed by
the offset amount.  Amounts in the range -128 to +127 are given
by a single signed byte, denoted by "d8" in the table below.
Amounts requiring a 2-byte representation are denoted by "d16" in
the table below.  As with all 16-bit memory quantities in the 86
family, the word is stored with the least significant byte FIRST.

The following table of effective address byte values is organized
into 32 rows and 8 columns.  The 32 rows give the possible values
for the effective address operand: 8 registers and 24 memory
indexing modes.  A 25th indexing mode, [BP] with zero
displacement, has been pre-empted by the simple-memory-variable
case.  If you code [BP] with no displacement, you will get
[BP]+d8, with a d8-value of zero.

The 8 columns of the table reflect further information given by
the effective address byte.  Usually, this is the identity of the
other (always a register) operand of a 2-operand instruction.
Those instructions are identified by a "/r" following the opcode
byte in the instruction list.  Sometimes, the information given
supplements the opcode byte in identifying the instruction
itself.  Those instructions are identified by a "/" followed by a
digit from 0 through 7.  The digit tells which of the 8 columns
you should use to find the effective address byte.

For example, suppose you have a perverse wish to know the precise
bytes encoded by the instruction SUB B[BX+17],100.  This
instruction subtracts an immediate quantity, 100, from an
effective address quantity, B[BX+17].  By consulting the
instruction list, you find the general form SUB eb,ib.  The
opcode bytes given there are 80 /5 ib.  The "/5" denotes an
effective address byte, whose value will be taken from column 5
of the following table.  The offset 17 decimal, which is 11 hex,
will fit in a single "d8" byte, so we take our value from the
"[BX] + d8" row.  The table tells us that the effective address
byte is 6F.  Immediately following the 6F is the offset, 11 hex.
Following that is the ib-value of 100 decimal, which is 64 hex.
So the bytes generated by SUB B[BX+17],100 are 80 6F 11 64.

Table of Effective Address byte values

s  =     ES   CS   SS   DS
rb =     AL   CL   DL   BL   AH   CH   DH   BH
rw =     AX   CX   DX   BX   SP   BP   SI   DI
digit=    0    1    2    3    4    5    6    7
                                                  Effective
EA byte                                           address:
values:  00   08   10   18   20   28   30   38    [BX + SI]
         01   09   11   19   21   29   31   39    [BX + DI]
         02   0A   12   1A   22   2A   32   3A    [BP + SI]
         03   0B   13   1B   23   2B   33   3B    [BP + DI]

         04   0C   14   1C   24   2C   34   3C    [SI]
         05   0D   15   1D   25   2D   35   3D    [DI]
         06   0E   16   1E   26   2E   36   3E    d16 (simple var)
         07   0F   17   1F   27   2F   37   3F    [BX]

         40   48   50   58   60   68   70   78    [BX + SI] + d8
         41   49   51   59   61   69   71   79    [BX + DI] + d8
         42   4A   52   5A   62   6A   72   7A    [BP + SI] + d8
         43   4B   53   5B   63   6B   73   7B    [BP + DI] + d8

         44   4C   54   5C   64   6C   74   7C    [SI] + d8
         45   4D   55   5D   65   6D   75   7D    [DI] + d8
         46   4E   56   5E   66   6E   76   7E    [BP] + d8
         47   4F   57   5F   67   6F   77   7F    [BX] + d8

         80   88   90   98   A0   A8   B0   B8    [BX + SI] + d16
         81   89   91   99   A1   A9   B1   B9    [BX + DI] + d16
         82   8A   92   9A   A2   AA   B2   BA    [BP + SI] + d16
         83   8B   93   9B   A3   AB   B3   BB    [BP + DI] + d16

         84   8C   94   9C   A4   AC   B4   BC    [SI] + d16
         85   8D   95   9D   A5   AD   B5   BD    [DI] + d16
         86   8E   96   9E   A6   AE   B6   BE    [BP] + d16
         87   8F   97   9F   A7   AF   B7   BF    [BX] + d16

         C0   C8   D0   D8   E0   E8   F0   F8    ew=AX   eb=AL
         C1   C9   D1   D9   E1   E9   F1   F9    ew=CX   eb=CL
         C2   CA   D2   DA   E2   EA   F2   FA    ew=DX   eb=DL
         C3   CB   D3   DB   E3   EB   F3   FB    ew=BX   eb=BL

         C4   CC   D4   DC   E4   EC   F4   FC    ew=SP   eb=AH
         C5   CD   D5   DD   E5   ED   F5   FD    ew=BP   eb=CH
         C6   CE   D6   DE   E6   EE   F6   FE    ew=SI   eb=DH
         C7   CF   D7   DF   E7   EF   F7   FF    ew=DI   eb=BH

d8 denotes an 8-bit displacement following the EA byte, to be
sign-extended and added to the index.

d16 denotes a 16-bit displacement following the EA byte, to be
added to the index.

Default segment register is SS for effective addresses containing
a BP index; DS for other memory effective addresses.

