将虚拟地址与紧邻的下一页边界对齐

时间:2014-04-09 18:08:44

标签: c paging

我遇到了以下算法,它将虚拟地址与紧邻的下一页界限对齐。

VirtualAddr = (VirtualAddr & ~(PageSize-1));

此外,给定一个字节长度将长度(将其舍入)对齐在页面边界上

len = ((PageSize-1)&len) ? ((len+PageSize) & ~(PageSize-1)):len;

我发现很难破译它是如何工作的。 有人可以帮我分解吗?

3 个答案:

答案 0 :(得分:7)

这些计算假设页面大小是 2的幂(情况就是如此) 我所知道的所有系统,例如

PageSize = 4096 = 2^12 = 1000000000000 (binary)

然后(写成二进制数字)

PageSize-1    = 00...00111111111111
~(PageSize-1) = 11...11000000000000

这意味着

(VirtualAddr & ~(PageSize-1))

VirtualAddr,低12位设置为零,换句话说, VirtualAddr向下舍入到2^12 = PageSize的下一个倍数。

现在你可以(希望)在

中看到它
len = ((PageSize-1)&len) ? ((len+PageSize) & ~(PageSize-1)):len;

第一个表达

 ((PageSize-1)&len)
如果lenPageSize的倍数,则

为零。在这种情况下,剩下len 不变。否则(len + PageSize)向下舍入到下一个倍数 PageSize

因此,无论如何,len向上舍入到PageSize的下一个倍数。

答案 1 :(得分:2)

我认为第一个应该是

VirtualAddr = (VirtualAddr & ~(PageSize-1)) + PageSize; 

答案 2 :(得分:0)

这个单行将会这样做 - 如果它已经对齐,它将跳到下一页边界:

aligned = ((unsigned long) a & (getpagesize()-1)) ? (void *) (((unsigned long) a+getpagesize()) & ~(getpagesize()-1)) : a;

这个单行将会这样做 - 如果它已经对齐,它将跳到下一页边界:

如果你真的想要跳到下一页边界,即使它已经对齐 - 只需这样做:

aligned = (void *) (((unsigned long) a+getpagesize()) & ~(getpagesize()-1))

这应该避免所有编译器警告。

getpagesize()是一个POSIX的东西。 #include <unistd.h>以避免警告。