Reputation: 45
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
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