pAddress和〜(PAGE_SIZE - 1)中获取页面基址的技巧是什么?

Bai*_*ang 1 c c++ bit-manipulation

以下函数用于获取该页面内地址的页面基址:

void* GetPageAddress(void* pAddress)
{
    return (void*)((ULONG_PTR)pAddress & ~(PAGE_SIZE - 1));
}
Run Code Online (Sandbox Code Playgroud)

但是我无法理解它,它在这里扮演的诀窍是什么?

结论:就
个人而言,我认为Amardeep的解释加上Alex B的例子是最好的答案.由于亚历克斯B的答案已经被投票,我想接受Amardeep的答案作为正式的答案来突出它!谢谢大家.

Ale*_*x B 14

该函数清除给定地址的低位,从而产生其页面的地址.

例如,如果PAGE_SIZE是4096,那么是32位二进制:

   PAGE_SIZE      = 00000000000000000001000000000000b
   PAGE_SIZE - 1  = 00000000000000000000111111111111b
 ~(PAGE_SIZE - 1) = 11111111111111111111000000000000b
Run Code Online (Sandbox Code Playgroud)

如果你按位 - 并且它具有32位地址,它会将低位变为零,将地址四舍五入到最接近的4096字节页面地址.

 ~(PAGE_SIZE - 1)             = 11111111111111111111000000000000b
                    pAddress  = 11010010100101110110110100100100b
 ~(PAGE_SIZE - 1) & pAddress  = 11010010100101110110000000000000b
Run Code Online (Sandbox Code Playgroud)

因此,在十进制中,原始地址是3533139236,页面地址(剥离较低位的地址)是3533135872 = 862582 x 4096,是的倍数4096.


Ama*_*9MF 6

它的作用是清除适合页面大小创建的掩码的地址位.实际上它获得了块的第一个有效地址.

PAGE_SIZE必须是2的幂,并由地址中设置的单个位表示.

通过从PAGE_SIZE中减去一个来创建掩码.这有效地设置了比页面大小位低的所有位.然后,〜将所有这些位补充为零,并设置比掩码更高阶的所有位.&然后有效地剥离所有较低位,留下包含原始地址的页面的实际基址.