80x86 16 位 asm:lea cx,[cx*8+cx] 导致 NASM 出现错误(编译 .com 文件)

发布于 2024-08-30 00:02:37 字数 301 浏览 9 评论 0原文

NASM 给出的错误(尽管我的操作系统正常)是“无效的有效地址”。

现在我已经看到了很多如何使用 LEA 的例子,我认为我做对了,但我的 NASM 不喜欢它。我尝试了 lea cx, [cx+9] 并成功了; lea cx,[bx+cx] 没有。

现在,如果我将寄存器扩展到 32 位(即 lea ecx, [ecx*8+ecx]),一切都会好起来,但我只能使用 16 位和 8 位寄存器。

这里有知识渊博的人可以解释一下为什么我的汇编器不允许我按照我认为应该使用的方式使用 lea 吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

从此见与不见 2024-09-06 00:02:38

下面用于构建后字节的表格显示了哪个寄存器可以用作地址寄存器,以及其中哪些可以与第二个地址寄存器(基址寄存器+索引寄存器以及可能的缩放)组合以用它构建地址。
(从 16 位地址模式观察,其中 D 标志未设置。)

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

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

几味少女 2024-09-06 00:02:37

这是因为 [bx+cx] 在 16 位 x86 上的任何寻址模式下都无效,请参阅此 网站 了解更多信息。

lea cx,[bx+di]lea cx,[bx+si] 应该可以。

如果您的代码将在 386 或更高版本的 16 位模式下运行,则可以使用 lea cx, [ecx + 9](地址大小前缀,但仍然是 16 位操作数大小)。

另请参阅此有关 x86 寻址模式的问答(主要讨论 32/64 位寻址模式)和 标签 wiki。

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 tag wiki.

在风中等你 2024-09-06 00:02:37

lea cx,[cx*8+cx] 不起作用,因为“scale-index-base”寻址仅适用于 32 位寄存器。这不是汇编器的限制——而是处理器的限制。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文