• Welcome to Valhalla Legends Archive.
 

Getting global variable arrays' elements' addresses?

Started by brew, November 06, 2007, 05:12 PM

Previous topic - Next topic

brew

Okay, so say I have an array like this:

struct asdf asdfg[32];

globally declared.
The struct's size is 144h.

I want to push the offset of asdfg[21], for example.
But there's more! The array index is dynamic (i.e.: i'm keeping count in edx)
So really, what I want to do is something like:
lea ecx, offset asdf + edx * 144h (the index) + 40h (struct's member)
then push ecx.
But that obviously won't work.
So I ask you, how would I do this without having to use mul (very expensive-- 30 cpu cycles) and a bunch of other arithmetic instructions?
<3 Zorm
Quote[01:08:05 AM] <@Zorm> haha, me get pussy? don't kid yourself quik
Scio te esse, sed quid sumne? :P

MyndFyre

Actually you can.  I knew that you can do three-integer math with LEA,
Code (http://www.geocities.com/SiliconValley/2151/opts.html) Select
this site suggests four:


-> LEA may be used as a three/four operand addition instruction.
  LEA ECX, [EAX+EBX*4+ARRAY_NAME]


Technically ARRAY_NAME should resolve to be a constant because the linker should know where it is.

You'd want to do something like,

lea     ecx,     [edx * 144h + asdf]
add    ecx,     40h
push   ecx

I'm curious as to why you're using edx as the indexer and ecx as the destination pointer....  ECX is the counting register!
QuoteEvery generation of humans believed it had all the answers it needed, except for a few mysteries they assumed would be solved at any moment. And they all believed their ancestors were simplistic and deluded. What are the odds that you are the first generation of humans who will understand reality?

After 3 years, it's on the horizon.  The new JinxBot, and BN#, the managed Battle.net Client library.

Quote from: chyea on January 16, 2009, 05:05 PM
You've just located global warming.

brew

Quote from: MyndFyre[vL] on November 06, 2007, 08:26 PM
Actually you can.  I knew that you can do three-integer math with LEA,
Code (http://www.geocities.com/SiliconValley/2151/opts.html) Select
this site suggests four:


-> LEA may be used as a three/four operand addition instruction.



Technically ARRAY_NAME should resolve to be a constant because the linker should know where it is.

You'd want to do something like,

lea     ecx,     [edx * 144h + asdf]
add    ecx,     40h
push   ecx

Tried it.

lea eax, [edx * 144h + asdf]
push eax

gives me
error C2423: '324' : illegal scale

Even if it did assemble without an error, wouldn't it just add the first four bytes of the base struct asdf?
I guess I gave up. So, I made some neat-o global struct array value assigning function then set a breakpoint, debugged, went do disassemble and it gave me this:

004011E6 8B 4D FC             mov         ecx,dword ptr [ebp-4]
004011E9 69 C9 41 01 00 00    imul        ecx,ecx,141h
004011EF 81 C1 40 37 42 00    add         ecx,offset asdf+40h (00423740)
004011F5 51                   push        ecx

which is almost exactly what i didn't want to do. :|
Just a little curious, why is the stack ALWAYS around 0012FE00 and the heap is around 0083FD00? It gets on my nerves for some reason.

Quote
I'm curious as to why you're using edx as the indexer and ecx as the destination pointer....  ECX is the counting register!
Beats me. It works just fine. I've always used them.
<3 Zorm
Quote[01:08:05 AM] <@Zorm> haha, me get pussy? don't kid yourself quik
Scio te esse, sed quid sumne? :P

Kp

The multiplier for lea can only be one of a few values.  If you need something more complex, you will need to do it manually with multiplications and/or shifts.

I think you are stressing too much about the cost of a multiplication.  You will probably spend more time on the stall induced by accessing a non-cached global than you do computing the address of that global.
[19:20:23] (BotNet) <[vL]Kp> Any idiot can make a bot with CSB, and many do!