开发者

What is the trick in pAddress & ~(PAGE_SIZE - 1) to get the page's base address

Following function is used to get the page's base address of an address which is inside this page:

void* GetPageAddress(void* pAddress)
{
    return (void*)((ULONG_PTR)pAddress & ~(PAGE_SIZE - 1));
}

But I couldn't quite get it, what is the trick it plays here?

Conclusion:开发者_JAVA百科

Personally, I think Amardeep's explanation plus Alex B's example are best answers. As Alex B's answer has already been voted up, I would like to accept Amardeep's answer as the official one to highlight it! Thanks you all.


The function clears low bits of a given address, which yields the address of its page.

For example, if PAGE_SIZE is 4096, then in 32-bit binary:

   PAGE_SIZE      = 00000000000000000001000000000000b
   PAGE_SIZE - 1  = 00000000000000000000111111111111b
 ~(PAGE_SIZE - 1) = 11111111111111111111000000000000b

If you bitwise-and it with a 32-bit address, it will turn lower bits into zeros, rounding the address to the nearest 4096-byte page address.

 ~(PAGE_SIZE - 1)             = 11111111111111111111000000000000b
                    pAddress  = 11010010100101110110110100100100b
 ~(PAGE_SIZE - 1) & pAddress  = 11010010100101110110000000000000b

So, in decimal, original address is 3533139236, page address (address with lower bits stripped) is 3533135872 = 862582 x 4096, is a multiple of 4096.


What it does is clears the bits of the address that fit within the mask created by the page size. Effectively it gets the first valid address of a block.

PAGE_SIZE must be a power of 2 and is represented by a single bit set in the address.

The mask is created by subtracting one from PAGE_SIZE. That effectively sets all the bits that are a lower order than the page size bit. The ~ then complements all those bits to zero and sets all the bits that are a higher order than the mask. The & then effectively strips all the lower bits away, leaving the actual base address of the page containing the original address.


When PAGE_SIZE is some power of 2 (say 4096 for example), this clears all the bits below those that specify the page.


This is just a tricky way of clearing the low order bits.

Another way to implement it might be

void* GetPageAddress(void* pAddress)
{
    return pAddress - pAddress%PAGE_SIZE;
}

That probably won't compile, as you need to cast the types a bit, bit it shows the algorithm.

Effectively it is getting the largest multiple of PAGE_SIZE that is less than pAddress.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜