Author | Message | Time |
---|---|---|
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 |