Valhalla Legends Forums Archive | Assembly Language (any cpu) | Getting global variable arrays' elements' addresses?

AuthorMessageTime
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?
November 6, 2007, 11:12 PM
Myndfyr
Actually you can.  I knew that you can do three-integer math with LEA, [code=http://www.geocities.com/SiliconValley/2151/opts.html]this site[/code] suggests four:

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

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

You'd want to do something like,
[code]
lea    ecx,    [edx * 144h + asdf]
add    ecx,    40h
push  ecx
[/code]
I'm curious as to why you're using edx as the indexer and ecx as the destination pointer....  ECX is the counting register!
November 7, 2007, 2:26 AM
BreW
[quote author=MyndFyre[vL] link=topic=17154.msg174648#msg174648 date=1194402407]
Actually you can.  I knew that you can do three-integer math with LEA, [code=http://www.geocities.com/SiliconValley/2151/opts.html]this site[/code] suggests four:

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

[/code]

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

You'd want to do something like,
[code]
lea     ecx,     [edx * 144h + asdf]
add    ecx,     40h
push   ecx
[/code]
[/quote]
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:
[code]
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
[/code]
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!
[/quote]
Beats me. It works just fine. I've always used them.
November 7, 2007, 3:05 AM
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.
November 9, 2007, 4:44 AM

Search