flat assembler
Message board for the users of flat assembler.

Index > Windows > Snippet: round up to page size for VirtualAlloc

Author
Thread Post new topic Reply to topic
hopcode



Joined: 04 Mar 2008
Posts: 563
Location: Germany
hopcode
Hallo all,
hier a snippet to round up the size of mem allocation using VirtualAlloc
For example, for an x86, that uses a 4-KB page size (and a granularity of 64kb):
edx = page size for x86 = 4kb
ecx = result = size of memory to be allocated

Code:
 mov edx,1000h
 dec edx
 neg ecx
 or ecx,edx
 xor ecx,edx
 not ecx   
 inc ecx
 ; or simply [b]neg ecx[/b] for [not ecx/inc ecx]
    


Also, for
ecx = 4567h byte to allocate -> 5000h byte allocated in ecx
ecx = 1001h byte to allocate -> 2000h " "
ecx = 0900h byte to allocate -> 1000h " "
ecx = 1000h byte to allocate -> 1000h " "


hopcode Very Happy
Post 14 Dec 2008, 00:08
View user's profile Send private message Visit poster's website Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17327
Location: In your JS exploiting you and your system
revolution
Why not simply:
Code:
add ecx,0xfff
and ecx,not 0xfff    
Post 14 Dec 2008, 00:22
View user's profile Send private message Visit poster's website Reply with quote
hopcode



Joined: 04 Mar 2008
Posts: 563
Location: Germany
hopcode
revolution wrote:
Code:
add ecx,0xfff
and ecx,not 0xfff    

It must be said that the not 0xffff will be parsed on
preprocessing stage,right ?
but it is really Cool your improvement!! Wink
Thanks
Post 14 Dec 2008, 00:32
View user's profile Send private message Visit poster's website Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
LocoDelAssembly
hehe, I liked this way Razz

Here a slight modification
Code:
; mov edx,1000h
; dec edx
 neg ecx
; or ecx,edx
; xor ecx,edx
 and ecx, -1 shl 12
; not ecx
; inc ecx
 ; or simply [b]neg ecx[/b] for [not ecx/inc ecx]
 neg ecx
    


But, the commonly used code for achieving what your code does is:
Code:
 add ecx, $1000 - 1
 and ecx, -1 shl 12    


Also, note that VirtualAlloc already rounds up your parameter so you don't have to do it.

MSDN wrote:
dwSize [in]

The size of the region, in bytes. If the lpAddress parameter is NULL, this value is rounded up to the next page boundary. Otherwise, the allocated pages include all pages containing one or more bytes in the range from lpAddress to lpAddress+dwSize. This means that a 2-byte range straddling a page boundary causes both pages to be included in the allocated region.
Post 14 Dec 2008, 00:33
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17327
Location: In your JS exploiting you and your system
revolution
hopcode wrote:
It must be said that the not 0xffff will be parsed on
preprocessing stage,right ?
No, it is processed during the assembly stage. The assembly stage deals with numbers, the preprocessing stage deals with strings.
Post 14 Dec 2008, 00:36
View user's profile Send private message Visit poster's website Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17327
Location: In your JS exploiting you and your system
revolution
LocoDelAssembly wrote:
But, the commonly used code for achieving what your code does is:
Code:
 add ecx, $1000 - 1
 and ecx, -1 shl 12    
That is just another way of writing the same thing I posted above.
Post 14 Dec 2008, 00:37
View user's profile Send private message Visit poster's website Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
LocoDelAssembly
revolution wrote:

That is just another way of writing the same thing I posted above.


Yep, but your post wasn't there when I was reading and after a couple of minutes of pure skepticism on hopcode's code, I started to compose my reply and later pressed "Submit".
Post 14 Dec 2008, 00:43
View user's profile Send private message Reply with quote
hopcode



Joined: 04 Mar 2008
Posts: 563
Location: Germany
hopcode
LocoDelAssembly wrote:

Also, note that VirtualAlloc already rounds up your parameter so you don't have to do it.

Yes,right,well kwnown...
Another excellent improvement...
Thanks Loco
Post 14 Dec 2008, 00:45
View user's profile Send private message Visit poster's website Reply with quote
hopcode



Joined: 04 Mar 2008
Posts: 563
Location: Germany
hopcode
revolution wrote:
hopcode wrote:
It must be said that the not 0xffff will be parsed on
preprocessing stage,right ?
No, it is processed during the assembly stage. The assembly stage deals with numbers, the preprocessing stage deals with strings.

Also,should not be not 0xffff first "translated" by preprocessor to its equivalent value, and then assembled ? Please, could you gently explain me why it is processed during the assembly stage?
Thanks in advance, for your attention
Post 14 Dec 2008, 00:55
View user's profile Send private message Visit poster's website Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17327
Location: In your JS exploiting you and your system
revolution
IIRC, the preprocessor will do macro expansion and fix/equ translation.

The parser will convert not into a token and take no action other than that. This is the same for other things like mov, and etc.

The assembler will decode the not token as an arithmetic operator and do the computation.
Post 14 Dec 2008, 01:01
View user's profile Send private message Visit poster's website Reply with quote
hopcode



Joined: 04 Mar 2008
Posts: 563
Location: Germany
hopcode
/to revolution/ .mmmhhh... I am not completely persuaded about... but, frankly, i cannot say a word on the separation of preprocessing/assembling stages. I like to imagine it in such a way, and for the reason that i have not read a single line in the Fasm's code till now. I like the "surprise effect" Very Happy
Quote:

The parser will convert not into a token...
The assembler will decode the not token as...and do the computation

I dont know. It seems to me that the not 0fffh has a "long living time" before the final computation.
Post 14 Dec 2008, 01:29
View user's profile Send private message Visit poster's website Reply with quote
FrozenKnight



Joined: 24 Jun 2005
Posts: 128
FrozenKnight
i think you should really use GetSystemInfo() to get the page size for this kind of thing. Even though most systems use the standard 1000h page size it's still possible that a system may be using a custom page size.
Post 15 Dec 2008, 11:41
View user's profile Send private message Reply with quote
hopcode



Joined: 04 Mar 2008
Posts: 563
Location: Germany
hopcode
FrozenKnight wrote:

Even though most systems use the standard 1000h page size it's still possible that a system may be using a custom page size.

for Granularity ok,AFAIK,it is depending on the system.
But do you know cases/examples for such a custum pagesize possibility ? I dont...
Let me know, if you have references on this possibility.

But i partially agree with you. This is the reason why i have written the code
in that assembly way, it is to say:
Code:
 
mov edx,1000h ;(1000h as to simplify/and mean, in that fragment the result from a 
              ;SYSTEM_INFO.dwPageSize)
    

The code then was improved by revolution and commented by LocoDelAssembly.
BTW /to LocoDelAssembly/
LocoEtcEtc wrote:

..a couple of minutes of pure skepticism on hopcode's code, I started to compose my reply and later pressed "Submit".

on a so clear and dummy code,your pure skepticism has no reason.do you need to test
it to see what happens ?
.
On the contrary, I am skeptic on your english so that, after more than 2600 posts,
you have finally learned lots of programming tecniques, but surely
not the meaning of the english words. Yes, starting from the Press-Submit,
Technique is surely not your own problem !!! Razz
...
hopcode
Post 15 Dec 2008, 23:56
View user's profile Send private message Visit poster's website Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
LocoDelAssembly
Quote:

do you need to test
it to see what happens ?

Yes and in fact I have simulated it with the Windows Calculator and after I got a FAILED result then I had to run it to confirm that your code was wrong, but after running several test cases it was clear that your code was doing right. Then after looking at it more carefully it was clear what it was doing, so I have removed some superfluous operations (for example replacing the OR/XOR pair with an AND), and later I gave you the "canonical" solution which was the same thing revolution posted when all I've commenting above was happening.

About English, it is not part of my elementary education, all I have learnt came from this forum, other Internet sites and some VERY basic concepts at ultra low-quality high school.

FrozenKnight, he simply should do nothing at all since as stated in the documentation, the round up is automatic and unavoidable.
Post 16 Dec 2008, 00:40
View user's profile Send private message Reply with quote
bitRAKE



Joined: 21 Jul 2003
Posts: 2914
Location: [RSP+8*5]
bitRAKE
I'm a binary nut, so I like to code it this way 'cus it's easier for me to remember:
Code:
add ecx,N-1 
and ecx,0-N    
...notice the use of one and zero.
(assuming alignment is actually needed, and N is a power of two)
Post 16 Dec 2008, 00:59
View user's profile Send private message Visit poster's website Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17327
Location: In your JS exploiting you and your system
revolution
Since this topic is now done to death I will try to throw a spanner into the works:

What if the OS page size is not a power of two?
Post 16 Dec 2008, 01:04
View user's profile Send private message Visit poster's website Reply with quote
hopcode



Joined: 04 Mar 2008
Posts: 563
Location: Germany
hopcode
Razz Razz
Quote:

the round up is automatic and unavoidable.
Post 16 Dec 2008, 01:50
View user's profile Send private message Visit poster's website Reply with quote
bitRAKE



Joined: 21 Jul 2003
Posts: 2914
Location: [RSP+8*5]
bitRAKE
"What if the OS page size is not a power of two?"

A) Find a different OS to program on, lol.

B) Make all data structures in program multiples of crazy page size.

C) Split the problem if only a couple bits are set in page size.

D) Use reciprocal multiply trick, rounding up - then multiply.

E) Catch spanner...

_________________
¯\(°_o)/¯ unlicense.org
Post 16 Dec 2008, 08:56
View user's profile Send private message Visit poster's website Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr
revolution,

Let's round 'em all: Wink
Code:
ceil_mod:
;;; Rounds value up to multiple
;;;
;;; Expects:
;;;     u32 value @ eax -- value to round up
;;;     u32 divisor @ ecx -- round up to multiple of; divisor != 0
;;;
;;; Returns:
;;;     u32 ceil_value @ eax -- value, rounded up to multiple of divisor
;;;
;;; Modifies:
;;;     edx

        lea     edx, [ecx-1]
        ;;; fall through

round_mod:
;;; Rounds value to multiple
;;;
;;; Expects:
;;;     u32 value @ eax -- value to round down
;;;     u32 divisor @ ecx -- round to multiple of; divisor != 0
;;;     u32 threshold @ edx -- specifies rounding threshold (0 <= threshold < divisor)
;;;                         -- round down when 0 <= (value % divisor) < (divisor - threshold);
;;;                         -- round up otherwise
;;;                         -- in other words: when distance to next multiple greater than threshold, round down
;;; Returns:
;;;     u32 round_value @ eax -- value, rounded to multiple of divisor according to threshold
;;;
;;; Modifies:
;;;     edx

        add     eax, edx        ; add threshold
        sbb     edx, edx        ; with carry
        neg     edx             ; to edx
        jmp     @f
        ;;; may be some neutral xx 31 D2 opcode
        ;;; instead of jump over "xor edx, edx"???

floor_mod:
;;; Rounds value down to multiple
;;;
;;; Expects:
;;;     u32 value @ eax -- value to round down
;;;     u32 divisor @ ecx -- round down to multiple of; divisor != 0
;;;
;;; Returns:
;;;     u32 round_value @ eax -- value, rounded down to multiple of divisor
;;;
;;; Modifies:
;;;     edx == 0

        xor     edx, edx
@@:     div     ecx
        mul     ecx
        ret    
Will definitely overflow in marginal cases like ceil_mod(0xFFFFFFFF, 7) (but gracefully: edx:eax will hold the 0x100000003), degenerate cases like floor_mod(x, 1) were tested also.

_________________
"Don't belong. Never join. Think for yourself. Peace." – Victor Stone.
Post 16 Dec 2008, 19:03
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17327
Location: In your JS exploiting you and your system
revolution
baldr wrote:
Let's round 'em all:
One rounding function to rule them all.
Post 17 Dec 2008, 01:11
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2020, Tomasz Grysztar. Also on YouTube, Twitter.

Website powered by rwasa.