问题
The error NASM gives (despite my working OS) is "invalid effective address".
Now I've seen many examples of how to use LEA and I think I got it right but yet my NASM dislikes it. I tried lea cx, [cx+9]
and it worked; lea cx, [bx+cx]
didn't.
Now if I extended my registers to 32-bits (i.e. lea ecx, [ecx*8+ecx]
) everything would be well but i am restricted to use 16- and 8-bit registers only.
Is here anyone so knowledgeable who could explain me WHY my assembler doesn't let me use lea the way I supposed it should be used?
回答1:
This is because [bx+cx]
isn't valid in any addressing mode on 16-bit x86, see this site for more info.
lea cx, [bx+di]
or lea cx, [bx+si]
should work.
If your code will run on 386 or later in 16bit mode, you can use lea cx, [ecx + 9]
(address-size prefix but still 16bit operand-size).
See also this Q&A on x86 addressing modes (mostly discussing 32/64bit addressing modes, and the x86 tag wiki.
回答2:
lea cx,[cx*8+cx]
doesn't work because "scale-index-base" addressing is only available with 32-bit registers. It's not a limitation of the assembler--it's a limitation of the processor.
回答3:
These following tables for to build a postbyte shows which register can be used as an addressregister and which of them can be combine with a second addressregister(baseregister+indexregister and maybe scaling) to build an address with it. (Observed from the 16 bit address mode, where the D-flag is not set.)
Instruction Prefix 0 or 1 Byte
Address-Size Prefix 0 or 1 Byte
Operand-Size Prefix 0 or 1 Byte
Segment Prefix 0 or 1 Byte
Opcode 1 or 2 Byte
Mod R/M (Postbyte) 0 or 1 Byte
SIB, Scale Index Base (386+) 0 or 1 Byte
Displacement 0, 1, 2 or 4 Byte (4 only 386+)
Immediate 0, 1, 2 or 4 Byte (4 only 386+)
Format of Postbyte(Mod R/M from Intel-Manual)
------------------------------------------
MM RRR MMM
MM - Memeory addressing mode
RRR - Register operand address
MMM - Memoy operand address
RRR Register Names
Filds 8bit 16bit 32bit
000 AL AX EAX
001 CL CX ECX
010 DL DX EDX
011 Bl BX EBX
100 AH SP ESP
101 CH BP EBP
110 DH SI ESI
111 BH DI EDI
---
16bit memory (No 32 bit memory address prefix)
MMM Default MM Field
Field Sreg 00 01 10 11=MMM is reg
000 DS [BX+SI] [BX+SI+o8] [BX+SI+o16]
001 DS [BX+DI] [BX+DI+o8] [BX+DI+o16]
010 SS [BP+SI] [BP+SI+o8] [BP+SI+o16]
011 SS [BP+DI] [BP+DI+o8] [BP+DI+o16]
100 DS [SI] [SI+o8] [SI+o16]
101 DS [DI] [DI+o8] [SI+o16]
110 SS [o16] [BP+o8] [BP+o16]
111 DS [BX] [BX+o8] [BX+o16]
Note: MMM=110,MM=0 Default Sreg is DS !!!!
32bit memory (Has 67h 32 bit memory address prefix)
MMM Default MM Field
Field Sreg 00 01 10 11=MMM is reg
000 DS [EAX] [EAX+o8] [EAX+o32]
001 DS [ECX] [ECX+o8] [ECX+o32]
010 DS [EDX] [EDX+o8] [EDX+o32]
011 DS [EBX] [EBX+o8] [EBX+o32]
100 SIB [SIB] [SIB+o8] [SIB+o32]
101 SS [o32] [EBP+o8] [EBP+o32]
110 DS [ESI] [ESI+o8] [ESI+o32]
111 DS [EDI] [EDI+o8] [EDI+o32]
Note: MMM=110,MM=0 Default Sreg is DS !!!!
---
SIB is (Scale/Base/Index)
SS BBB III
Note: SIB address calculated as:
<sib address>=<Base>+<Index>*(2^(Scale))
Fild Default Base
BBB Sreg Register Note
000 DS EAX
001 DS ECX
010 DS EDX
011 DS EBX
100 SS ESP
101 DS o32 if MM=00 (Postbyte)
SS EBP if MM<>00 (Postbyte)
110 SS ESI
111 DS EDI
Fild Index
III register Note
000 EAX
001 ECX
010 EDX
011 EBX
100 never Index SS can be 00
101 EBP
110 ESI
111 EDI
Fild Scale coefficient
SS =2^(SS)
00 1
01 2
10 4
11 8
Dirk
来源:https://stackoverflow.com/questions/2716142/80x86-16-bit-asm-lea-cx-cx8cx-causes-error-on-nasm-compiling-com-file