The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: 2-Bit Chip on March 18, 2010, 07:34:01 AM

Title: error A2083: invalid scale value
Post by: 2-Bit Chip on March 18, 2010, 07:34:01 AM
I don't understand why MASM is having a fit over this:
mov eax, dword ptr [edx+ecx*55]
Title: Re: error A2083: invalid scale value
Post by: BlackVortex on March 18, 2010, 07:37:09 AM
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
Title: Re: error A2083: invalid scale value
Post by: 2-Bit Chip on March 18, 2010, 07:46:49 AM
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]
Title: Re: error A2083: invalid scale value
Post by: sinsi on March 18, 2010, 08:08:18 AM
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.
Title: Re: error A2083: invalid scale value
Post by: 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

Title: Re: error A2083: invalid scale value
Post by: redskull on March 18, 2010, 04:02:35 PM
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
Title: Re: error A2083: invalid scale value
Post by: clive on March 18, 2010, 04:28:29 PM
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
Title: Re: error A2083: invalid scale value
Post by: 2-Bit Chip on March 19, 2010, 02:44:54 PM
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.
Title: Re: error A2083: invalid scale value
Post by: drizz on March 19, 2010, 03:49:12 PM
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
Title: Re: error A2083: invalid scale value
Post by: clive on March 19, 2010, 05:40:14 PM
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
Title: Re: error A2083: invalid scale value
Post by: sinsi on March 20, 2010, 12:10:27 AM
>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.