Quoteinvoke LocalAlloc,LMEM_FIXED OR LMEM_ZEROINIT,N
memory always begin from multiple for 4 point?
as align 4
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.
You can rely on that the memory returned by Global/LocalAlloc is to be aligned by 8.
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
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.
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
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
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?
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
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?
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.)
http://msdn.microsoft.com/en-us/library/aa366574%28v=vs.85%29.aspx
where it documented?
follow the link and read the whole text!
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.
I thought I posted an earlier version of the code in the attachment somewhere here, but I can't seem to find it.
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.
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
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.
nice find sinsi
they should add that to the allocation functions dox :P
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