The MASM Forum

General => The Campus => Topic started by: Force on February 17, 2015, 11:39:32 AM

Title: Allocate Memory
Post by: Force on February 17, 2015, 11:39:32 AM
Is it possible to allocate memory without windows api in assembly ?
Title: Re: Allocate Memory
Post by: jj2007 on February 17, 2015, 11:45:03 AM
StackBuffer (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1255), for example. But why do you want to avoid HeapAlloc?
Title: Re: Allocate Memory
Post by: dedndave on February 17, 2015, 11:52:57 AM
how much memory - and how long do you need it ?

there is also the uninitialized data section
    .DATA?

buffer db 16384 dup(?) ;16 KB buffer - lifetime of the process
Title: Re: Allocate Memory
Post by: Force on February 18, 2015, 01:27:50 AM
i found something in Fasm but i m not sure if it's possible in Masm32

macro allocMem var,nbytes
{
virtual at nbytes
var db nbytes dup (?)
  end virtual
}





allocMem buffer,70


Title: Re: Allocate Memory
Post by: AssemblyChallenge on February 18, 2015, 05:59:35 AM
I have a question too.

So far I have been using the .Data? section too for buffers and stuff without increasing the final exe's size. But, is there a limit on how much you should allocate by this method? How do you know memory APIs are mandatory instead of .Data?

Please.
Title: Re: Allocate Memory
Post by: dedndave on February 18, 2015, 06:32:22 AM
if it weren't for a MASM bug, you can go as far as address space will allow - assuming the user has memory
for XP, that would be almost 2 GB, including all your code and data

MASM has a bug that makes the assembler run slow for buffers above 64 KB

but - unless you need all that memory for the entire life of the process, it's not very responsible programming
in many cases, it is better to allocate memory, as needed - and release it when done

and - if you want to use 2 GB, and the user has 1 GB of RAM, the program won't load - lol
Title: Re: Allocate Memory
Post by: Force on February 18, 2015, 08:55:31 AM
i think Globalalloc is better  :biggrin:
Title: Re: Allocate Memory
Post by: dedndave on February 18, 2015, 10:51:31 AM
that depends on what your strategy is
you may want to use virtual memory - if you need more than available RAM
and - GlobalAlloc ends up calling HeapAlloc, as i recall
MS has depricated GlobalAlloc, except places where it must be used
the clipboard is one place that comes to mind
some streaming i/o also requires globally allocated memory
Title: Re: Allocate Memory
Post by: rrr314159 on February 18, 2015, 12:11:34 PM
Random comments,

yes MASM32 has similar to FASM's macro allocmem. Look in MASM32/macros/macros.asm; macros called "literal", SADD and CADD.

GlobalAlloc is deprecated by MS; MS wants u to use HeapAlloc instead in most cases; it's a little quicker too. {NOTE, as I was typing this dedndave mentioned same thing; guess I'll leave it here, reinforce the point}. Works the same. But ANY alloc is very slow; definitely don't want it in inner loop. Still it can be more convenient than data?, particularly when you don't know how many blocks of mem will be used in the prog. Whenever you know initially how many blocks of mem u need, data? probably better.

The ML.exe bug, for data? above 64k, is still there in ML64 (big disappointment). However JWasm works right; allocates as much as 2 gig too quick to notice. JWasm does have a couple problems ML doesn't; but generally it's better, give it a try. True, it's not responsible programming to pre-allocate huge amounts of mem, but 64K is not huge; even a few megabytes is, really, nothing. So for smaller (up to 100 megs, say) amounts this is usually best.

Using the stack - up to 4K, no problem, but don't try to access it after u return from the proc that does the allocating.  Up to a megabyte or so should be possible but stack must be probed. MASMBasic's StackBuffer takes care of that; but when you use the mem sequentially pre-probing's not necessary, usually init not necessary either. For thread-safe, and for speed, this is (IMHO) the best way; but requires more than usual care.

So if you're using data? happily, you're all set. Otherwise u need either JWasm, HeapAlloc, or stack allocation, depending what the problem is.

WARNING: as a newbie, I don't really know what I'm talking about, so take it for what it's worth  :icon_cool:
Title: Re: Allocate Memory
Post by: hutch-- on February 18, 2015, 12:56:14 PM
Uninitialised data is handy for variables that you need but it is fundamentally a poor technique for memory of any real size. Anything you add to the DATA? section stays there for the duration of the running app where dynamically allocated memory can be turned on and off.

RE: GlobalAlloc(), there is another term for deprecated, its "stable" which means Microsoft will not stuff it up any longer. Trace it through the guts of system DLLs and you will find it uses the same memory source as HeapAlloc() but is a bit simpler to use. This much, with any allocated memory, once it is allocated, its all the same speed. If you need many small allocations, do yourself a favour and allocate it all in one lump then chop it up to the sizes you need. It is trivial to align memory so if you can find a way to allocate it that works, you can do most anything you like with it as long as you stay within its range.
Title: Re: Allocate Memory
Post by: Force on February 19, 2015, 03:16:35 AM
Thanks for explaining Hutch !..

I just use GlobalAlloc in my programs but There are afew ways for allocation .... VirtualAlloc, HeapAlloc etc..

please someone can explain me, should i use others too ?  or are they for different memory (long or short)?
Title: Re: Allocate Memory
Post by: dedndave on February 19, 2015, 04:03:45 AM
HeapAlloc and GlobalAlloc are similar in many ways
they allocate memory from available RAM
HeapAlloc takes a little more work - you have to use CreateHeap or GetProcessHeap (easy way) to get a heap handle
GlobalAlloc may allocate moveable or non-moveable blocks - no heap handle required

VirtualAlloc will allocate from RAM when available
if not, it will use a cache file on the hard drive (or a combination of the 2)
therefore, you can allocate larger blocks, beyond what might be available

i often use the stack for temporary allocations
care must be taken so that you don't try to access uncommitted memory
this is done by probing the stack
in this post, and a few that follow, i show some examples

http://masm32.com/board/index.php?topic=3326.msg35046#msg35046 (http://masm32.com/board/index.php?topic=3326.msg35046#msg35046)
Title: Re: Allocate Memory
Post by: Force on February 19, 2015, 05:04:35 AM
Thank you Dave

I understand clearly  now :t
Title: Re: Allocate Memory
Post by: MichaelW on February 19, 2015, 06:06:42 AM
Quote from: rrr314159 on February 18, 2015, 12:11:34 PM
Using the stack - up to 4K, no problem, but don't try to access it after u return from the proc that does the allocating.  Up to a megabyte or so should be possible but stack must be probed. MASMBasic's StackBuffer takes care of that; but when you use the mem sequentially pre-probing's not necessary, usually init not necessary either. For thread-safe, and for speed, this is (IMHO) the best way; but requires more than usual care.

Or you can just use the linker /STACK:reserve[,commit] option to make the stack whatever size you need, and forget about the probing.
Title: Re: Allocate Memory
Post by: Force on February 19, 2015, 07:41:26 AM
Thanks rrr314159 and  Michael

Before starting to learn assembly programming ... anybody said that I can find any solution in assembly
Yes we can make every C functions in assembly except allocation memory. So i was finding out if it's possible in assembly.Other problem ... Even i write any  macro   i can't be sure if really memory is allocated or not. i test it with GlobalSize or HeapSize .... Result is always zero
Title: Re: Allocate Memory
Post by: dedndave on February 19, 2015, 09:36:53 AM
if HeapAlloc (et al) returns a non-zero pointer, the memory was allocated
Title: Re: Allocate Memory
Post by: rrr314159 on February 20, 2015, 02:05:33 AM
MichaelW:
QuoteOr you can just use the linker /STACK:reserve[,commit] option to make the stack whatever size you need
The only time I use the stack for largish mem blocks is in threads created by my main process. I don't think this linker option affects thread stack size? Can't seem to find answer on net. Actually I think u can allocate stack when u create the thread, but probing hasn't been too much of an issue ...

I tried uninitialized data for threads but that doesn't work so well. U have to make sure multiple threads aren't using data too near each other; they can "step on each other's toes", I guess because they lock a larger block than they write. Stack memory is usually already in cache and therefore is faster (so to speak), and of course it's much faster to allocate (0 nanoseconds). 

The reason I said it requires "more than usual care" is not any of that, rather that the stack is also being used for call/return and function parameters (of course), so ... but I can't cover all these points in a short post - or even a long one!

Hutch:
QuoteRE: GlobalAlloc(), there is another term for deprecated, its "stable" which means Microsoft will not stuff it up any longer.
Yes, now that u mention it - you're right! The heck with getting heap handles - I'm going back to GlobalAlloc (for main process). MS can deprecate my elbow, if they want.  :lol:
Title: Re: Allocate Memory
Post by: jj2007 on February 20, 2015, 03:02:27 AM
The one thing I dislike with the linker /STACK:reserve[,commit] option is that you can't just post a snippet here, you'll have to explain how exactly the linker commandline has to be set etc - usually a messy action, especially but not only with new members. Using *Alloc is simpler.

But...
/stack:1980000000      ; stack pointer will be e.g. 1984298892
...works as expected. The higher the commit value, the higher the private working memory used initially - for a committed 1980000000 it is around 4.7MB on my Win7-64 machine; for the same stacksize but no commit value, it is only 932 kBytes. The management of committed pages costs a bit of space...
Title: Re: Allocate Memory
Post by: MichaelW on February 21, 2015, 10:20:04 AM
For  CreateThread (https://msdn.microsoft.com/en-us/library/windows/desktop/ms682453(v=vs.85).aspx) you must specify the stack size, and you can choose for it to be the executable stack size. A large commit is a bad idea if you're working under conditions where there are memory constraints, but for the typical conditions (at least for me), where you're not doing heavy multitasking, what does it matter? KISS, get the necessary memory by the easiest possible route.

But then again, maybe my simplistic use of a computer is not typical.

Title: Re: Allocate Memory
Post by: rrr314159 on February 21, 2015, 11:27:42 AM
MichaelW
Quote... maybe my simplistic use of a computer is not typical
Well, it's typical for me, so you're in bad company! :biggrin: Hutch makes a lot of service-type programs that people will run along with other software, so he (admirably) is careful with his bytes. In another routine (posted in the laboratory), to tokenize a text file, he counts the number of lines first, then allocates exactly that many dwords for pointers; whereas I would figure 100K ought to do it, so make it a meg and we're all set. If I ever do post a service-type routine, for general use, I'll try to emulate him.
Title: Re: Allocate Memory
Post by: jj2007 on February 21, 2015, 05:03:02 PM
Quote from: rrr314159 on February 21, 2015, 11:27:42 AMIn another routine (posted in the laboratory), to tokenize a text file, he counts the number of lines first, then allocates exactly that many dwords for pointers

That was a nice thread indeed, see here (http://masm32.com/board/index.php?topic=3713.0). There is also the option (used in Recall (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1172)) to allocate for the pointers sizeoffile/2 (=worst case, all crlf), and to reallocate the pointer table at the end.