News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

error A2083: invalid scale value

Started by 2-Bit Chip, March 18, 2010, 07:34:01 AM

Previous topic - Next topic

2-Bit Chip

I don't understand why MASM is having a fit over this:
mov eax, dword ptr [edx+ecx*55]

BlackVortex

GoAsm gives "Scaled index register - only 2,4 or 8 allowed for scale value:"
so I guess you can only use 2,4 or 8 for multiplication

2-Bit Chip

Well, I changed it to this now:
mov eax, dword ptr [edx+ecx*eax]

error A2026: constant expected

Fixed it finally.  :clap:

    mov edx, offset
    xor ecx, ecx
  @@:
    mov eax, 55
    mul ecx
    mov eax, dword ptr [edx+eax]

sinsi

Quote from: 2-Bit Chip on March 18, 2010, 07:46:49 AM
mov edx, offset
xor ecx, ecx
@@:
mov eax, 55
mul ecx
mov eax, dword ptr [edx+eax]

I assume this is part of a loop and you change ecx before the @b, else ecx is always 0.

mov eax,55
mul ecx
mov eax,[offset+eax]

Look up "SIB" in the docs.
Light travels faster than sound, that's why some people seem bright until you hear them.

clive

Using ecx as a scratch register, adjust as appropriate.
    lea eax,[eax + eax*4]  ; *5
    lea ecx,[eax + eax*2]  ; *5 *3
    lea eax,[ecx + eax*8]  ; *5 *3 (15) + *5 *8 (40) = *5 *11 = *55
    mov eax, dword ptr [edx + eax] ; edx + eax*55

It could be a random act of randomness. Those happen a lot as well.

redskull

It's a limitation of the CPU itself; you can do [base + offset + index*scale], where base is a register, offset is constant, index is register, and scale is 2,4 or 8.  The scale values come from being limited to a 4-bit power of two (makes the math easier by using a bit shift).  Be careful not to confuse the assembler math with CPU math; for example [MyVar+9*55] is really just a single base number (the math all gets done during assembly), but [eax+9+ebx*4] is actually done at run time by the CPU itself.

-r
Strange women, lying in ponds, distributing swords, is no basis for a system of government

clive

QuoteIt's a limitation of the CPU itself; you can do [base + offset + index*scale], where base is a register, offset is constant, index is register, and scale is 2,4 or 8.  The scale values come from being limited to a 4-bit power of two (makes the math easier by using a bit shift).

From an implementation standpoint there is also a *1 scale that permits the 386+ to use register combination previous x86 chips did not support. The scale is encoded as a 2-bit value driving a small barrel shifter, it is very fast. The assembler will typically encode the *1 on one of the registers implicitly, but it can be done explicitly if you want a specific opcode encoding.

mov ebx, [foo + edi + eax*1]

-Clive
It could be a random act of randomness. Those happen a lot as well.

2-Bit Chip

Quote from: clive on March 18, 2010, 03:46:51 PM
Using ecx as a scratch register, adjust as appropriate.
    lea eax,[eax + eax*4]  ; *5
    lea ecx,[eax + eax*2]  ; *5 *3
    lea eax,[ecx + eax*8]  ; *5 *3 (15) + *5 *8 (40) = *5 *11 = *55
    mov eax, dword ptr [edx + eax] ; edx + eax*55



It's an interesting way you set that up.

drizz

If you are trying to access elements from array[counter] where each element size is 55.
Instead of using mul to calculate offset use "add offs,55"

mov edx, offset
xor ecx, ecx
@@:
mov eax, dword ptr [edx]
add edx,55
The truth cannot be learned ... it can only be recognized.

clive

Quote from: 2-Bit Chip on March 19, 2010, 02:44:54 PM
It's an interesting way you set that up.

Back in the day that would have been quite efficient, with current CPUs the mul is actually faster.

Quote
    mov edx, offset
    xor ecx, ecx
  @@:
    mov eax, 55
    mul ecx
    mov eax, dword ptr [edx+eax]

Be aware that the "mul ecx" destroys the edx register with the high order 32-bits of the 64-bit multiplication solution (ie edx:eax = eax * ecx)

-Clive
It could be a random act of randomness. Those happen a lot as well.

sinsi

>Be aware that the "mul ecx" destroys the edx register with the high order 32-bits of the 64-bit multiplication solution (ie edx:eax = eax * ecx)

oops.
Light travels faster than sound, that's why some people seem bright until you hear them.