News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

A little problem and solution

Started by donkey, January 01, 2010, 06:52:20 PM

Previous topic - Next topic

donkey

I was using VirtualAlloc to create a memory buffer of a size determined programatically and ofcourse the base address is unknown at assembly time. Normally I would use global buffers to store the base address and the size, however, in the particular application I require the part of the program to be thread safe and did not want to use global memory. So, how do I determine the amount of space left in the buffer if I have only the value of the current pointer within the buffer and don't know either the size or base address ?

This is my solution to determining the remaining bytes in the buffer, TestAddr is a pointer within the buffer, smbi is a MEMORY_BASIC_INFORMATION structure.


invoke VirtualQuery,[TestAddr],offset smbi,SIZEOF MEMORY_BASIC_INFORMATION

mov eax,[TestAddr]
and eax,0FFFh ; assumes a page size of 4096 (0x1000)
sub [smbi.RegionSize],eax


smbi.RegionSize holds the exact number of bytes remaining in the buffer. Note that it assumes a page size of 4096, you can use GetSystemInfo if you prefer not to hard code it.

Donkey
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

BogdanOntanu

Alternatively, one could use a context structure as the parameter instead of the buffer pointer. The context structure would contain the buffer base address, the buffer size and any other "per thread global variables". This CTX structure could be the first parameter of all your thread safe functions (OOP style) or you could keep a pointer to it in a register (for example EBX). If you need to use EBX in a leaf function then a simple USES EBX would save it.
Ambition is a lame excuse for the ones not brave enough to be lazy.
http://www.oby.ro

donkey

Quote from: BogdanOntanu on January 02, 2010, 10:25:27 AM
Alternatively, one could use a context structure as the parameter instead of the buffer pointer. The context structure would contain the buffer base address, the buffer size and any other "per thread global variables". This CTX structure could be the first parameter of all your thread safe functions (OOP style) or you could keep a pointer to it in a register (for example EBX). If you need to use EBX in a leaf function then a simple USES EBX would save it.

I like that idea though its a bit beyond the scope of my current application which is a fairly simple tutorial but I can certainly see some places where it would be useful. Also the proc it's in is recursive so the pointer is passed as part of the recursion anyway, though 4 bytes for the CTX pointer is negligible I tend to try to limit stack loading in recursive procedures. I have to take some time to play with it a bit before I'd be comfortable using it in an application especially one I expect to have to answer a lot of questions about once I post it.
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable