The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: bomz on June 09, 2011, 02:47:17 PM

Title: LocalAlloc memory begin
Post by: bomz on June 09, 2011, 02:47:17 PM
Quoteinvoke LocalAlloc,LMEM_FIXED OR LMEM_ZEROINIT,N

memory always begin from multiple for 4 point?
as align 4
Title: Re: LocalAlloc memory begin
Post by: hutch-- on June 09, 2011, 03:33:20 PM
There is no difference in 32 bit Windows from GlobalAlloc() using the GMEM_FIXED flag and the GMEM_ZEROINIT flag. In 32 bit windows there is no LOCAL alloc at all, its like many other memory strategies, its mapped to NTDLL internal functions.
Title: Re: LocalAlloc memory begin
Post by: qWord on June 09, 2011, 04:00:10 PM
You can rely on that the memory returned by Global/LocalAlloc is to be aligned by 8.
Title: Re: LocalAlloc memory begin
Post by: bomz on June 09, 2011, 04:03:26 PM
the function is not problem I need to be sure that memory allways /4 .
I try 10 times - always /4. but there is no about this in msdn
Title: Re: LocalAlloc memory begin
Post by: qWord on June 09, 2011, 04:59:05 PM
Quote from: bomz on June 09, 2011, 04:03:26 PMbut there is no about this in msdn
Quote from: msdn: GlobalAlloc FunctionMemory allocated with this function is guaranteed to be aligned on an 8-byte boundary.
GlobalAlloc() (http://msdn.microsoft.com/en-us/library/aa366574(v=vs.85).aspx)

So your on the 'save side' by using this function.
Title: Re: LocalAlloc memory begin
Post by: jj2007 on June 09, 2011, 05:14:32 PM
Here are some steps to produce align 16, in case you want to work with SSE2.

include \masm32\include\masm32rt.inc
.686
.xmm

.code
start:
mov ebx, alloc(123) ; produce misalignment ;-)
BytesNeeded=555
mov eax, BytesNeeded
add eax, 16
mov esi, alloc(eax)
print hex$(eax), 9, " result of first alloc", 13, 10
mov edi, esi ; keep that pointer for GlobalFree
add esi, 16 ; add the 16 extra bytes
and esi, -16 ; and align them downwards
movaps xmm0, [esi] ; if it's not aligned 16, you will see a GPF
print hex$(esi), 9, " aligned 16 for use with SSE2", 13, 10
nops 5
free edi
print str$(eax), 9, " result of free edi (0=success)", 13, 10
free ebx
inkey str$(eax), 9, " result of free ebx (0=success)", 13, 10
exit
end start
Title: Re: LocalAlloc memory begin
Post by: bomz on June 09, 2011, 05:59:19 PM
I think most easy correct begin point from memory begin to 4,8,16...
msdn says that located memory not allways the same size as need - may be greater. the begining is that how windows orginize all memory

Title: Re: LocalAlloc memory begin
Post by: qWord on June 09, 2011, 06:14:05 PM
Quote from: bomz on June 09, 2011, 05:59:19 PM
I think most easy correct begin point from memory begin to 4,8,16...
msdn says that located memory not allways the same size as need - may be greater. the begining is that how windows orginize all memory
What are you trying to say?
Title: Re: LocalAlloc memory begin
Post by: dedndave on June 09, 2011, 06:24:49 PM
it doesn't seem to be documented anywhere
so - i align it as desired

1) request (N-1) more bytes than you need, where N = alignment
2) save the original address for the handle to Free the allocated block
3) use the N-aligned address for data
   D = (A+N-1) AND (-N)

A = allocated block address
D = aligned data address
Title: Re: LocalAlloc memory begin
Post by: bomz on June 09, 2011, 06:25:52 PM
my mathematic english very poor

(http://xmages.net/storage/10/1/0/1/8/upload/e900c93a.png)

I mean that windows organize memory using some rule and all part of memory for program, for data, for system, for .... begins from /4
all pages?
Title: Re: LocalAlloc memory begin
Post by: qWord on June 09, 2011, 06:34:12 PM
bomz,
when allocating memory, there seems to be no documented warranty that the memory is aligned(this what you mean begin/x) in any form. Only GlobalAlloc() guarantees this - it is documented!
(This does not apply to the Virtual memory functions.)
Title: Re: LocalAlloc memory begin
Post by: bomz on June 09, 2011, 06:50:23 PM
http://msdn.microsoft.com/en-us/library/aa366574%28v=vs.85%29.aspx
where it documented?
Title: Re: LocalAlloc memory begin
Post by: qWord on June 09, 2011, 07:10:34 PM
follow the link and read the whole text!
Title: Re: LocalAlloc memory begin
Post by: bomz on June 10, 2011, 05:35:21 AM
QuoteMemory allocated with this function is guaranteed to be aligned on an 8-byte boundary. To execute dynamically generated code, use the VirtualAlloc function to allocate memory and the VirtualProtect function to grant PAGE_EXECUTE access.
Title: Re: LocalAlloc memory begin
Post by: MichaelW on June 10, 2011, 08:09:59 AM
I thought I posted an earlier version of the code in the attachment somewhere here, but I can't seem to find it.
Title: Re: LocalAlloc memory begin
Post by: hutch-- on June 10, 2011, 09:27:14 AM
From memory all of the Windows memory allocation function are aligned by at least 4 bytes. GlobalAlloc() is by 8 and there are options from memory to go higher for SSE and similar applications. Its easy enough to do your own, allocate as much as you need PLUS the number of bytes to align by then align a start address from the allocation address. Read and write to the aligned address, deallocate from the original allocated address.
Title: Re: LocalAlloc memory begin
Post by: dedndave on June 10, 2011, 10:05:19 AM
Quote1) request (N-1) more bytes than you need
2) save the original address for the handle to Free the allocated block
3) use the N-aligned address for data
   D = (A+N-1) AND (-N)

A = allocated block address
D = aligned data address
N = alignment

here is an example using HeapAlloc

        INCLUDE \masm32\include\masm32rt.inc

DesiredSize  EQU 4096
DesiredAlign EQU 16

        .DATA?

hHeap     dd ?
hBlock    dd ?
BlockUsed dd ?

        .CODE

_main   PROC

        INVOKE  GetProcessHeap
        mov     hHeap,eax

;if zeroed memory is not required, replace HEAP_ZERO_MEMORY with NULL

        INVOKE  HeapAlloc,eax,HEAP_ZERO_MEMORY,DesiredSize + DesiredAlign - 1
        mov     hBlock,eax
        add     eax,DesiredAlign - 1
        and     eax,-DesiredAlign
        mov     BlockUsed,eax

;BlockUsed is the aligned address used for data

;
;

;when done, use the original address like a handle to free the allocated block

        INVOKE  HeapFree,hHeap,NULL,hBlock

        INVOKE  ExitProcess,0

_main   ENDP

        END     _main
Title: Re: LocalAlloc memory begin
Post by: sinsi on June 10, 2011, 10:24:59 AM
Quote from: MicrosoftThe Windows heap managers (all versions) have always guaranteed that the heap allocations have a start address that is 8-byte aligned (on 64-bit platforms the alignment is 16-bytes).
http://support.microsoft.com/kb/286470

So use HeapAlloc, since Local/Global functions are only wrappers for heap functions.
Title: Re: LocalAlloc memory begin
Post by: dedndave on June 10, 2011, 10:40:25 AM
nice find sinsi
they should add that to the allocation functions dox   :P
Title: Align 16 of a LOCAL buffer for use with SSE2
Post by: jj2007 on June 11, 2011, 07:19:08 PM
Here is a simple example how to get a 16-byte aligned LOCAL buffer for use with SSE2 instructions. TheBuffer must be the first LOCAL.


Quoteinclude \masm32\include\masm32rt.inc
.686
.xmm

.code
Pad16 proc arg1, arg2
LOCAL TheBuffer:OWORD   ; the SSE2 buffer
LOCAL locdw:DWORD   ; any number of other locals
LOCAL padding:OWORD   ; do not use this one
   push ebp
   and ebp, -16
   ; ... whatever code you need here
   m2m eax, "xxxx"
   movd xmm2, eax
   pshufd xmm2, xmm2, 0   ; 4*"0"
   movaps TheBuffer, xmm2   ; will choke if not
   movaps xmm3, TheBuffer   ; aligned to 16 bytes
   ; ... code finished
   pop ebp
   ret
Pad16 endp
start:
            REPEAT 9
               invoke Pad16, chr$("123456789"), 123
               print hex$(esp), 13, 10
               push eax
            ENDM
            add esp, 9*4
            inkey "OK"
            exit
end start