HALICERY

free-time coding, hardware dev, articles

Top
Home 8042 Blogs About
Home IntelEssential 16/32-bit Instructions LEA

Last modified: Thu Jun 18 18:27:08 UTC+0200 2026 © A. Tarpai


386 LEA

Load effective address into register: lea reg, r/m (source operand r/m should be memory location).

                                operand-size = 16                      operand-size = 32
                                D=0 or D=1 and 66h                     D=1 or D=0 and 66h

                                Destination register                   Destination register
                                is 16-bit                              is 32-bit
                      |--------------------------------------|--------------------------------------|
                      |                                      |                                      |
 address-size = 16    |                  +---------+         |                  +---------+         |
 D=0 or D=1 and 67h   |                  |   EA    |         |                  |   EA    |         |
                      |                  +---------+         |                  +---------+         |
                      |                       |              |                       |              |
                      |                       v              |                       v              |
                      |        +---------+---------+         |        +---------+---------+         |
                      |        | . . . .     EA    | REG     |        | 0 0 0 0     EA    | REG     |
                      |        +---------+---------+         |        +---------+---------+         |
                      |            LEA r16, m16              |            LEA r32, m16              |
                      |                                      |                                      |
                      |          REG-HI unchanged (.)        |         EA-HI zero-padded            |
                      |          16-bit 8086 emulation       |         REG-HI zeroed (0)            |
                      |--------------------------------------|--------------------------------------|
                      |                                      |                                      |
 address-size = 32    |        +-------------------+         |        +-------------------+         |
 D=1 or D=0 and 67h   |        |        EA         |         |        |        EA         |         |
                      |        +-------------------+         |        +-------------------+         |
                      |                  |                   |                  |                   |
                      |                  v                   |                  v                   |
                      |        +---------+---------+         |        +-------------------+         |
                      |        | . . . .     EA    | REG     |        |        EA         | REG     |
                      |        +---------+---------+         |        +-------------------+         |
                      |            LEA r16, m32              |            LEA r32, m32              |
                      |                                      |                                      |
                      |         EA-HI lost                   |                                      |
                      |         REG-HI unchanged (.)         |                                      |
                      |--------------------------------------|--------------------------------------|

How the assembler works:

  1. when we write a 16-bit addressing mode, eg. [BX+SI], address-size = 16; otherwise 32-bit addressing modes, eg. [EAX], address-size = 32
  2. based on destination register operand-size = 16 or 32
  3. based on [BITS 16/32] the assembler inserts 66/67h prefixes:
NASM

             [BITS 32]                           [BITS 16]

     8D00    lea eax, [eax]              8D00    LEA  AX, [BX+SI]
  66 8D00    lea  ax, [eax]           66 8D00    LEA EAX, [BX+SI]

  67 8D00    lea eax, [BX+SI]         67 8D00    LEA  AX, [EAX]
6667 8D00    lea  ax, [BX+SI]       6667 8D00    LEA EAX, [EAX]

Conformance tests for LEA

Test with a zero modr/m byte addressing mode both in 16- and 32-bit addressing modes (easy to compare). That is MOD=00 zero disp, REG=(E)AX (000). For R/M:

LEA opcode: 8D

Test run-time with these values:

      FF00
  +   8000
___________
    1 7F00    <-- 16-bit overflow

For 16-bit addressing modes this should result in 7F00 (64K wrap-around emulation).

VC++ (D=1 32-bit) test for REG HI zeroed:

    or eax, -1
    mov ebx, 0xFF00
    mov esi, 0x8000

    // lea eax, [BX+SI]
    _emit 0x67
    _emit 0x8D
    _emit 0x00

    eax = 0000_7F00  <-- REG HI zeroed

VC++ (D=1 32-bit) test for 16-bit 8086 emulation and REG HI unchanged:

    or eax, -1
    mov ebx, 0xFF00
    mov esi, 0x8000

    // lea ax, [BX+SI]
    _emit 0x66
    _emit 0x67
    _emit 0x8D
    _emit 0x00

    eax = FFFF_7F00  <-- REG HI unchanged

VC++ (D=1 32-bit) test for EA HI lost (and REG HI unchanged):

    or eax, -1
    mov ecx, 0xaaaaaaaa

    // lea ax, [ecx]
    _emit 0x66
    _emit 0x8D
    _emit 0x01

    eax = FFFF_AAAA  <-- REG HI unchanged and EA HI lost