NASM 无效的地址行为?

NASM invalid address behaviour?

我有一个名为 a 的数组和一个名为 n 的常量,我试图将其作为二维数组进行寻址,并使用以下行:mov al, [a+ebx*n+esi] 问题在于,如果 n 是偶数 (n equ 4),它可以完美运行,但如果 n 是奇数 (n equ 3),编译器会给出 "error: invalid effective address"。我能理解它在两种情况下是否有效,但我不明白为什么它们的工作方式不同。

编译器:NASM
链接器:GCC(Windows 的 minGW)
IDE:SASM

程序:

    %include "io.inc"

section .data
a    db    1, 2, 3, 4
     db    5, 6, 7, 9
     db    9, 10, 11, 12
     db    13, 14, 15, 16
n    equ   4

section .text
global CMAIN
CMAIN:
    mov ebp, esp; for correct debugging
    ; write your code here
    ;
    ; get upper limit
    xor    eax, eax
    mov    edi, n
    ;
    ; get last column
    mov    esi, n-1
    xor    ebx, ebx
    xor    edx, edx ; count in DL
    xor    ecx, ecx ; sum in CX
    mov    dh, 3
cycle:
    xor    ah, ah
    mov    al, [a+ebx*n+esi]
    div    dh
    cmp    ah, 0
    jne    afteradd
    add    cl, [a+ebx*n+esi]
    add    dl, 1
afteradd:
    add    ebx, 1
    cmp    ebx, edi
    jl     cycle
solve:
    mov    ax, cx
    div    dl       ; среднее арифметическое будет в AL
aftercycle:
    xor    eax, eax
    ret

地址的偏移部分以base + index*scale + displacement的形式给出。偏移量的 scale 部分仅允许某些值。它们是 1(默认值)、248

这在 Intel's Software Developers Manual 第 1 卷(名为 指定偏移量 的部分)中进行了描述:

The offset part of a memory address can be specified directly as a static value (called a displacement) or through an address computation made up of one or more of the following components:
Displacement — An 8-, 16-, or 32-bit value.
Base — The value in a general-purpose register.
Index — The value in a general-purpose register.
Scale factor — A value of 2, 4, or 8 that is multiplied by the index value.

(以上引述适用于 32 位模式,但比例因子的相同限制适用于 64 位模式)