fwiffo
fwiffo

Reputation: 45

NASM invalid address behaviour?

I have an array named a and a constant named n that I'm trying to address as a two-dimensional array with the following line: mov al, [a+ebx*n+esi] The problem is that if n is even (n equ 4), it works perfectly, but if n is odd (n equ 3) the compiler gives "error: invalid effective address". I could understand if it worked or failed in both cases, but I cannot understand why they are working differently.

Compiler: NASM
Linker: GCC (minGW for Windows)
IDE: SASM

The program:

    %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

Upvotes: 0

Views: 402

Answers (1)

Michael
Michael

Reputation: 58447

The offset part of an address is given on the form base + index*scale + displacement. There are only certain values that are allowed for the scale part of the offset. These are 1 (the default), 2, 4 and 8.

This is described in Intel's Software Developers Manual Vol 1 (the section named Specifying an Offset):

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.

(The above quote is for 32-bit mode, but the same limitation on the scale factor applies in 64-bit mode)

Upvotes: 2

Related Questions