0

This is the code:

section .data
v dw 4, 6, 8, 12
len equ 4
section .text
    global main
main:
    mov eax, 0 ;this is i
    mov ebx, 0 ;this is j
cycle:
    cmp eax, 2 ;i < len/2
    jge exit
    mov ebx, 0
    jmp inner_cycle
continue:
    inc eax
    jmp cycle
inner_cycle:
    cmp ebx, 2
    jge continue
    mov di, [v + eax * 2 * 2 + ebx * 2]
    inc ebx
    jmp inner_cycle
exit:
    push dword 0
    mov eax, 0
    sub esp, 4
    int 0x80

I'm using an array and scanning it as a matrix, this is the C translation of the above code

int m[4] = {1,2,3,4};
for(i = 0; i < 2; i++){
    for(j = 0; j < 2; j++){
        printf("%d\n", m[i*2 + j]);
    }
}

When I try to compile the assembly code I get this error:

DoubleForMatrix.asm:20: error: beroset-p-592-invalid effective address

which refers to this line

mov di, [v + eax * 2 * 2 + ebx * 2]

can someone explain me what is wrong with this line? I think that it's because of the register dimensions, I tried with

mov edi, [v + eax * 2 * 2 + ebx * 2]

but I've got the same error.

This is assembly for Mac OS X, to make it work on another SO you have to change the exit syscall.

Carl Norum
  • 219,201
  • 40
  • 422
  • 469
AR89
  • 3,548
  • 7
  • 31
  • 46

2 Answers2

1

The SIB (Scale Immediate Base) addressing mode takes only one Scale argument (1,2,4 or 8) to be applied to exactly one register.

The proposed solution is to premultiply eax by 4 (also has to modify the comparison). Then inc eax can be replaced with add eax,4 and the illegal instruction by mov di,[v+eax+ebx*2]

A higher level optimization would be just to for (i=0;i<4;i++) printf("%d\n",m[i]);

Aki Suihkonen
  • 19,144
  • 1
  • 36
  • 57
1

You can't use arbitrary expressions in assembler. Only a few addressingmodes are allowed.

basically the most complex form is register/imm+register*scale with scale 1,2,4,8

Of course constants (like 2*2) will probably be folded to 4, so that counts as a single scale with 4 (not as two multiplications)

Your example tries to do two multiplies at once.

Solution: insert an extra LEA instruction to calculate v+ebx*2 and use the result in the mov.

     lea regx , [v+ebx*2]
     mov edi, [eax*2*2+regx]

where regx is a free register.

Marco van de Voort
  • 25,628
  • 5
  • 56
  • 89