I don't understand why MASM is having a fit over this:
mov eax, dword ptr [edx+ecx*55]
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
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]
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.
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 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
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
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.
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
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
>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.