News:

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

Where is the memory function "Malloc" ?

Started by zjw, August 05, 2009, 02:02:45 AM

Previous topic - Next topic

FORTRANS

Quote from: dedndave on August 06, 2009, 01:42:10 PM
in DOS, each heap allocation was aligned to 16-bytes and was preceeded in memory by a 16-byte "heap allocation header"
but i think that was done because of x86 real-mode segmented architecture

   Correct, the segment register addressing scheme gave you
16 byte granularity in segment placement.  One could have done
something else, but that would have bought almost nothing.

Cheers,

Steve

jj2007

Quote from: dedndave on August 06, 2009, 01:42:10 PM
i was thinking that requests should always be page-sized, as well
i.e. if you need 1009 bytes, request 1024
that way, issued block sizes are always on 16-byte boundries
i
movaps and company don't care about size, they crash on unaligned addresses

Quote
i don't know if that would cause them to start on 16-byte boundries, as well
Apparently not - with the exception of Alloc aka CoGetMalloc, they all return 8-byte alignment and worse. That's why I wrote the wrapper for HeapAlloc.

dedndave

i had started writing one
i figured the starting address would already be 16-aligned
but, i will make it that way
the PROC would perform a few tasks for you
in my (limited) experience using allocation, i found myself continually
1) getting and saving the heap handle
2) saving the address to a location for use later
3) i was going to write an error routine to attempt compact - (this is what prompted me to putting the whole thing in one proc)
so, the game-plan was to have a structure like this:

MEMCTRL STRUCT
  lpMemAddr dd ?
  dwMemSize dd ?
  dwMemFlag dd ?
MEMCTRL ENDS

each allocated block has a seperate structure, although the structure may be re-used once the block has been released
the routine gets the process heap handle for you, although, i was thinking of allowing that to be a value in the structure, as well
(-1 = use process heap - otherwise = created heap handle)

to allocate a block, set lpMemAddr to 0, set dwMemSize to the requested size, set the flags, if desired
invoke the function with a pointer to the structure
it returns the block address in lpMemAddr (so you don't have to save it)
it returns the actual allocated size in dwMemSize (16-byte justified)
the values are also returned in eax and edx for convenience (ecx preserved)

to release the allocated block, just invoke the function again with the pointer to the structure
because lpMemAddr is non-zero, the routine knows it is a "free" function, rather than an "allocate" function
it returns with both lpMemAddr and dwMemSize set to 0

the next time you want to use the structure, the lpMemAddr is already 0, the flags are already set (unless you want to change them)
you just need to set the desired size and invoke with the structure pointer

if the HeapAlloc function fails, the routine attempts a HeapCompact and tries again
if it fails the second time, the allocated addr and size is set to 0 (eax also) and GetLastError output is returned in edx

the flags are masked with 0Dh for allocating a block and 1 for freeing a block

i guess i will add another variable to the structure to store the assigned block address (dwReserved)
then, the lpMemAddr variable can be 16-byte aligned
when it comes time to release the block, the routine can use the second address value to free it

Astro

Is it insufficient to write align 4/8/16 etc.. before the HeapAlloc call?

Anyone any links to more information on this? I need to learn a lot more about memory.

Best regards,
Astro.

jj2007

Quote from: Astro on August 09, 2009, 11:28:17 PM
Is it insufficient to write align 4/8/16 etc.. before the HeapAlloc call?

align is for positioning a pointer in the .data and .data? segments (by inserting nops etc), and has nothing to do with HeapAlloc.
Masm32 has memalign, but caution: this aligns the pointer but you must keep a copy of the original one for the free call.
You might check my algo above, it works fine.

dedndave

noone ever likes my ideas   :(
i must suck really bad at this stuff
all that typing for nothing

Astro

Quote from: dedndave on August 09, 2009, 11:36:32 PM
noone ever likes my ideas   :(
i must suck really bad at this stuff
all that typing for nothing
I read it...I just didn't understand it...

Definitely have more research to do.

Quotealign is for positioning a pointer in the .data and .data? segments (by inserting nops etc), and has nothing to do with HeapAlloc.
OK! I know precisely NOTHING on this subject.  :tdown

Best regards,
Astro.

dedndave

 .data
db 12
dw 3               ;the address for this word will be odd

;words are best aligned by 2
;dwords are best aligned by 4
;qwords are best aligned by 8
;in many cases, data caches more smoothly if it is aligned by 16
;with some mmx/sse instructions, the data MUST be 16-aligned

align 16
dd 128 dup (?)  ;we know the address of this array will be evenly divisible by 16

Astro

OK...

All aligned correctly:

align 4
Item1 DWORD ?
Item2 DWORD ?
Item3 WORD ?
Item4 BYTE 2 DUP (?)

...or is the BYTE mis-aligned because it doesn't START aligned??

Mis-aligned:

align 4
Item1 DWORD ?
Item2 DWORD ?
Item3 WORD ?
Item4 BYTE 4 DUP (?) ; this is mis-aligned


Quote;we know the address of this array will be evenly divisible by 16
Would that still be true if the *length* was NOT divisible by 16?

e.g.:

align 16
ByteArray BYTE 70 DUP (?) ; is this still aligned?


Best regards,
Astro.

dedndave

byte arrays or strings don't usually care much about being aligned
you are going to access a byte on an odd address, no matter how they are set up
also, you can figure the first item declared in a segment is going to be 16-aligned (i think - lol)
i try to put dwords first, then words, then bytes last
then i don't use align at all

Astro

Thanks to something I read early on in this forum, I sort them in that order, too.

If you have the case:

.data?
;auto-aligned 16 here
Item1 DWORD ?
Item2 DWORD ?
Item3 BYTE 11 DUP (?) ;odd size
align 4 (16?) ;necessary?
Item4 BYTE 23 DUP (?) ;odd size
align 4 (16?) ;necessary?
Item5 BYTE 8 DUP (?)


is the align between each BYTE declaration optimal, or a waste of time? What would be best alignment assuming it was necessary at all?

Best regards,
Astro.

dedndave

waste of time - they are byte declarations
there are exceptions to this, as you may want to search that array with a scasw instruction or something
but, generally, it won't matter
if you are worried, just place item3 and item4 after the even-length item5

Astro