Message board for the users of flat assembler.
> Compiler Internals > [sug] targeted allocation of memory in Windows fasm
Goto page 1, 2, 3 Next
By using exception handling it is possible to make fasm use only the memory that it needs when assembling.
My motivation for this is fourfold:
Please see further ahead in the thread for updated code with enhancements and bug fixes.
We start by making fasm large address aware. This allows us to use up to approximately 2.75GB. Although the code shown here is only able to use 2GB. This can be raised if desired to the maximum of 2.75GB with some changes to the memory reservation code. For now we keep the limit to just under 2GB.
Next we need to add a link to the SetUnhandledExceptionFilter API. We also eliminate the GlobalMemoryStatus link because it is not needed.
- format PE console + format PE console large
- GlobalMemoryStatus dd rva _GlobalMemoryStatus + SetUnhandledExceptionFilter dd rva _SetUnhandledExceptionFilter ;... - _GlobalMemoryStatus dw 0 - db 'GlobalMemoryStatus',0 + _SetUnhandledExceptionFilter dw 0 + db 'SetUnhandledExceptionFilter',0
Define some constants for ease of readability.
Change the allocation algorithm to reserve (i.e. not commit) all of the address space. Because later we want to commit pages on demand.
+MEMORY_ALLOCATION_BLOCK_SIZE = 1 shl 16 ;64kB. Higher numbers reduce the number of calls to the allocator. A value of 1 will allocate just the pages where the memory is accessed but will call the allocator more times +MEMORY_ALLOCATION_MAX_SIZE = 0x7ffc0000 ;Windows fails all calls that try to allocate more than this
Change the API call for reservation.
- push buffer - call GlobalMemoryStatus - mov eax,dword buffer+20 - mov edx,dword buffer+12 - cmp eax,0 - jl large_memory - cmp edx,0 - jl large_memory - shr eax,2 - add eax,edx - jmp allocate_memory - large_memory - mov eax,80000000h + mov eax,MEMORY_ALLOCATION_MAX_SIZE allocate_memory
Add in a call to SetUnhandledExceptionFilter so that the memory can be committed on demand.
- push MEM_COMMIT + push MEM_RESERVE
Change the computation slightly for situations where the reservation fails so as to make more memory available if it is needed. Instead of halving the value each iteration we take 3/4 and try again.
+ push memory_allocation_handler + call SetUnhandledExceptionFilter
- shl eax,1 + lea eax,