how to managing Heap Memory without use api function
With great difficulty and even if you can get it to work, Windows will probably break it with a future upgrade. If you use HeapAlloc() to get a main block, you can chop it up any way you like with a pointer array and data storage.
StackBuffer (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1255):
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init ; <<<< attention, this one is full of API calls
mov ecx, 800000
mov edi, StackBuffer(800000)
mov al, "x"
rep stosb
StackBuffer()
Inkey "easy..."
EndOfCode
deleted
If HEAPSIZE is above, say, 800000 as in my example, make sure you are not using the Microsoft assembler 8)
Besides, as Hutch already, there is not much to gain in rolling your own. The only reason would be if you have no access to the API - and that might be against the forum rules...
You have not told us what the 800000 is yet. If you use /LARGEADDRESSAWARE with ML64 you can allocate over 32 gigabyte and I have so far tested 48 gigabyte. Are you trying to cripple ML64 with the assumptions of inferior tools ? :biggrin:
Here is an example of how to allocate large amounts of memory with ML64.
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
include \masm32\include64\masm64rt.inc
.code
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
entry_point proc
LOCAL pMem :QWORD
LOCAL pCnt :QWORD
LOCAL pFre :QWORD
heapinit ; initialise process heap
mov pMem, halloc(1024*1024*1024*16) ; allocate memory
conout str$(pMem)," halloc",lf
mov pCnt, hsize(pMem) ; display its size
conout str$(pCnt)," hsize",lf
mov pMem, hrealloc(pMem,1024*1024*1024*4) ; reallocate memory
conout str$(pMem)," hrealloc",lf
mov pCnt, hsize(pMem) ; show new size
conout str$(pCnt)," hsize",lf
mov pFre, hfree(pMem) ; release allocated memory
conout str$(pFre)," hfree",lf
waitkey
invoke ExitProcess,0
ret
entry_point endp
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
With this result,
2189686345792 halloc
17179869184 hsize
2189686345792 hrealloc
4294967296 hsize
1 hfree
Press any key to continue...
ML64 may not be pretending to be a consumer friendly compiler but it clearly is powerful and that is because its a real assembler. :biggrin:
Hutch,
the 800000 is about the amount of bytes you can allocate with dup(?) without risking to need a coffee break. The bug is about twenty years old, and I just checked with ML64 - it's still there :greenclp:
:biggrin:
This is why its a feature, not a bug. Setting large allocations in the BBS section is appallingly bad code, why cater for lousy programming ? :biggrin:
Thank you guys
Do I understand from your replys that I can exploit Bss Section Instead of using the Heap
QuoteThe heap area commonly begins at the end of the .bss and .data segments and grows to larger addresses from there
(https://upload.wikimedia.org/wikipedia/commons/thumb/5/50/Program_memory_layout.pdf/page1-149px-Program_memory_layout.pdf.jpg)
from:Data segment (https://en.wikipedia.org/wiki/Data_segment)
From
jj2007 on: January 07, 2012, 08:57:25 AM (http://www.masmforum.com/board/index.php?topic=17289.msg152755#msg152755) :biggrin:
Quote
Found this at http://www.tenouk.com/Bufferoverflowc/Bufferoverflow1c.html:
BSS stands for 'Block Started by Symbol'. Global and statically allocated data that initialized to zero by default are kept in what is called the BSS area of the process.
Unfortunately it's for Linux BigGrin
Microsoft seems very shy to reveal its secrets, but I also remember that I once saw a MSDN or so reference. Probably it has to do with the fact that VirtualAlloc has no option for non-zeroed memory.
The rough distinctions of memory fall into 3 categories, initialised data, uninitialised data that is set by the assembler at run time and dynamically allocated memory that is set by the programmer on demand. Dynamically allocated memory can handle the very large allocations (gigabytes), unitialised memory has the advantage of being faster as it is pre-allocated at program start but comes at the price that it cannot have its size changed dynamically. Initialised data is usually used for string data but can have anything written to it as DB squences and then for some data, primarily resource data, you can place that data in the resource section. It can be either identified types of resources or raw binary.
Hi
About this memory question, it seems that we are tallking about 3/4 types of memory allocation:
(1) - We allocate in the '.DATA?' segment (call it DATA? MEMMORY)
TOTALMEMORY equ 800000
.DATA
pStartMemHereTypeI dd offset StartMemHereTypeI <--- pointer for type I
pStartMemHereTypeII dd ? <--- pointer for type II
pStartMemHereTypeIII dd ? <--- pointer for type III
.DATA?
StartMemHereTypeI TOTALMEMORY dup (?)
(2) - We allocate using the API GlobalAlloc (call it GLOBAL MEMMORY)
invoke GlobalAlloc, TOTALMEMORY
mov pStartMemHereTypeII, eax
(3) - We allocate using the API HeapAlloc (call it HEAP MEMMORY)
invoke HeapAlloc, TOTALMEMORY
mov pStartMemHereTypeIII, eax
(4) - We allocate from the STACK (call it STACK MEMMORY)
How to do it ?
Why from Stack ?
Is there any advantage ?
Another point of view: If we have a procedure that copies one block of memmory
to another, is there any type of timing advantage in this 4 cases ?
Is it faster if we use STACK MEMMORY ? Is it faster if we use DATA? MEMMORY ?
...
Jochen and Hutch, could you say something about this ?
Thanks
:icon14:
Windows had had different memory strategies for a very long time, GlobalAlloc() with the GMEM_FIXED memory flag still works fine and it can handle very large allocations. You use the GMEM_MOVABLE for specific old style code like the clipboard. HeapAlloc() is the preferred modern method and if you stay away from the exotic but slow settings with it, it fast enough as well. VirtualAlloc() is mainly for large allocations that are not changed quickly.
Initialised memory is simple in assembler.
.data
mytext db "This is my text",0
Uninitialised memory is used to allocate space, mainly for variables, but without any specified content. It is used at run time by the programmer.
.data?
ptxt dw mytext ; used as a pointer
arr dd 16 dup (?) ; 64 bytes