News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Arrgggh! Arrays of structures

Started by Astro, August 09, 2009, 11:05:11 PM

Previous topic - Next topic

Astro

I must be the dumbest programmer to have ever lived.  :eek

There are actually two questions, semi-related in purpose. First, structures.

As an example, if I have the following structure:

SomeStruct struct
    hHandleToSomething DWORD ?
    Data1 DWORD ?
    Data2 DWORD ?
    SomeArrayOfBytes BYTE 100 DUP (?)
SomeStruct ends


The size of the structure is (3 * DWORD) + (100 * BYTE) = 112 bytes.

If I then define:

.data?
ptrSomeStruct SomeStruct <?>


and access it in the code as:

mov [ptrSomeStruct].Data1,50h

...this works (if I haven't screwed up when to use brackets etc...) to access the single element Data1.

However... my problem arises when I have an array of say 50 structures.

I define it thus:

.data?
ptrSomeStruct SomeStruct <>


Is this correct?

Assuming it is, I then need to iterate the array in a loop, doing some processing on the elements as I go.

.code
; code ... blah ...

mov StructOffset,70h ; sizeof struct = 112 bytes
mov ecx,0 ; first index

SomeLoop:
    mov eax,[ptrSomeStruct].Data1+StructOffset*ecx ; this line fails - invalid use of (ecx) register

    inc ecx
    cmp ecx,MaxCount
    jnz SomeLoop


I also tried more simply:

    mov eax,[ptrSomeStruct].Data1+112*ecx
...with all manner of combinations of [ and ] for the +112*ecx part but to no avail.

My intention is to create an offset based upon 0*112 = 0 for the first element, etc..

I've yet to test:

mov ebx,112*ecx

;...

    mov eax,[ptrSomeStruct].Data1+ebx


...but I'm not hopeful.

Seperately, I need to allocate sufficient memory for the array, which appears to simply be a call to HeapAlloc, providing ptrSomeStruct as the subject of the memory allocation. Again, this wants to be based on the format MaxCount * 112.

I'm sure I've seen code formatted similarly, that appears to be working, valid code, but for some reason when I tried it I got compiler errors, or it simply crashed.

I've tried just about everything I can think of (except the method I mention above using ebx).

Thanks in advance for any help.

If anyone has any tips for not getting confused over when to use [ and ] as well, I'd appreciate it. Oddly, I understand the "why", I just don't quite see the "when" yet (especially when dealing with registers).

Best regards,
Astro.

jj2007

This should work:

include \masm32\include\masm32rt.inc

SomeStruct struct
    hHandleToSomething DWORD ?
    Data1 DWORD ?
    Data2 DWORD ?
    SomeArrayOfBytes BYTE 100 DUP (?)
SomeStruct ends

.data?
ptrSomeStruct SomeStruct 99 dup(<?>)

.code
start:
Element = 30 ; test
mov esi, offset ptrSomeStruct
mov ebx, SIZEOF SomeStruct
mov eax, Element
mul ebx

mov [eax+esi.SomeStruct.Data1], 50h

inkey "Press any key"
exit

end start

Astro

That's great! Thanks! I shall examine your code!  :U

A question:

ptrSomeStruct SomeStruct 99 dup(<?>)
This obviously allocates memory for 99 structures, but I want to dynamically assign this at run-time for two reasons:

1) So I'm not using more memory than required
2) I've no idea what the upper limit is, and by fixing it like this I could potentially run out of space if I under-estimate it.

How would I particularly solve (2)?

Best regards,
Astro.

dedndave

allocated blocks may be resized
but, that can get sloppy if you have a lot of dynamic allocation going on
it's best if you can find some indicator to early predict usage and allocate the block, say 5 to 10 % larger than estimated

Astro

I anticipate maybe 2 elements in the array, but from testing I only need 1 (so far...), but I must account for the case whereby I get a return of say, 10. The actual number is unknown and must account for this.

How would I dynamically re-allocate the memory? I figured it might be easier to just start with one structure and allocate based upon MaxCount prior to filling the structure.

Is my syntax in the OP for structure definition correct? Specifically:

.data?
ptrSomeStruct SomeStruct <>


Best regards,
Astro.

dedndave

well, first of all, that whole thing sounds mighty small
you have 4 gb of memory space to play with
if it is let's say, 40 to 100 bytes, resizing is a bad idea
just allocate 1 kb - that doesn't even put a dent in the available workspace
you could even place it on the stack

        sub     esp,1024
        mov     BufferSpacePointer,esp
.
.
.
        add     esp,1024


HeapReAlloc
http://msdn.microsoft.com/en-us/library/aa366704(VS.85).aspx

Astro

Am I taking this whole "assembler is small and fast" too far?

Quote        sub     esp,1024
        mov     BufferSpacePointer,esp
.
.
.
        add     esp,1024

Simplicity at its finest.

Are there any limits to stack size (e.g. is it the same as the process memory) or is this a bad method for larger allocation (e.g. 512 Mb)?

Tomorrow I'm going to go try and answer these questions.

Best regards,
Astro.

dedndave

i think stack is default 1 gb - knock yourself out

Astro

 :8)

Thanks for your patience with my questions.  :thumbu

Best regards,
Astro.

dedndave


MichaelW

AFAIK the default stack sizes are 4096 bytes committed and 1048576 bytes reserved. The system maintains a guard page at the end of the committed stack, and accessing into the guard page will cause the system to increase the committed size, but only until is reaches the reserved size. Your application will die if the stack exceeds the reserved size, or if the stack beyond the guard page is accessed. The stack sizes can be controlled from the linker command line.
eschew obfuscation

dedndave

my bad, Michael - thanks for correcting me
i got 1 gb mixed with 1 mb
quite a difference - lol

Slugsnack

if you are unsure how many instances of the structure you're going to need then perhaps you could consider something like a linked list. as you need a new structure, allocate it then link it to the end of the original list

hutch--

 :bg

Dave,

Its just extreme forward thinking to attribute 1 gig to the stack, just wait for Windows 9.0.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

jj2007

Quote from: Astro on August 09, 2009, 11:36:41 PM
...
This obviously allocates memory for 99 structures, but I want to dynamically assign this at run-time for two reasons:

1) So I'm not using more memory than required
2) I've no idea what the upper limit is, and by fixing it like this I could potentially run out of space if I under-estimate it.

How would I particularly solve (2)?


Just allocate a generous amount in the .data? section, it doesn't cost anything. The only thing to keep in mind is that there is a bug in the dup macro that makes assembly (not the code) slow for large numbers. But for a thousand or so elements, you will not run into problems - see below some timings. Of course, you can use HeapAlloc etc, too, but why bother?
:wink

; 10000   13 seconds
; 5000   3.8
; 2000   1.1
; 1000   0.8

.data?
ptrSomeStruct SomeStruct 1000 dup(<?>)