C 将虚拟地址与下一页边界对齐

C 将虚拟地址与下一页边界对齐,c,paging,C,Paging,我遇到了以下将虚拟地址与下一页边界对齐的算法 VirtualAddr = (VirtualAddr & ~(PageSize-1)); 另外,给定一个字节长度,则将长度(舍入)与页面边界对齐 len = ((PageSize-1)&len) ? ((len+PageSize) & ~(PageSize-1)):len; 我发现很难解释这是怎么回事。 有人能帮我把它拆了吗?我想第一个应该是 VirtualAddr = (VirtualAddr & ~(PageS

我遇到了以下将虚拟地址与下一页边界对齐的算法

VirtualAddr = (VirtualAddr & ~(PageSize-1));
另外,给定一个字节长度,则将长度(舍入)与页面边界对齐

len = ((PageSize-1)&len) ? ((len+PageSize) & ~(PageSize-1)):len;
我发现很难解释这是怎么回事。
有人能帮我把它拆了吗?

我想第一个应该是

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

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

PageSize = 4096 = 2^12 = 1000000000000 (binary)
然后(写为二进制数)

也就是说

(VirtualAddr & ~(PageSize-1))
virtualadr
,低12位设置为零,或者换句话说,
virtualadr
四舍五入到
2^12=PageSize
的下一个倍数

现在你可以(希望)从中看到这一点

len = ((PageSize-1)&len) ? ((len+PageSize) & ~(PageSize-1)):len;
第一个表达式

 ((PageSize-1)&len)
如果
len
PageSize
的倍数,则正好为零。在这种情况下,
len
被保留 不变。否则,
(len+PageSize)
将向下舍入到
PageSize


因此,在任何情况下,
len
被四舍五入到
PageSize
的下一个倍数,这一行将完成此操作-如果已对齐,则不会跳到下一页边界:

aligned=((无符号长)a&(getpagesize()-1))?(void*)((无符号长)a+getpagesize())&~(getpagesize()-1)):a


这一行将完成此操作-如果已对齐,则不会跳到下一页边界:

如果您真的想跳到下一页边界,即使它已经对齐了-只需执行以下操作:

aligned=(void*)((无符号长)a+getpagesize())&~(getpagesize()-1))

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


getpagesize()
是POSIX的东西<代码>#包括
以避免警告。

将虚拟地址与上一页边界对齐…第二个地址根本不起作用,除非您没有提到其他假设。(哦,等等,
if(lenYes)你是对的。1.要对齐到下一个边界的第一条语句应该是((virtualadr+PageSize)&~(PageSize-1))2。第二行的第二条语句将轮到页面大小。你对第一个问题的纠正也是不正确的(ish),因为它给已经对齐的语句添加了不必要的填充;使用
((VirtualADR+PageSize-1)和(PageSize-1))
取而代之。
lang py>>hex(0x00053000&~(4095))'0x53000'>>hex(0x00053FFF&~(4095))'0x53000'>>hex(0x00052FFF&~(4095))“0x52000”
事实上,即使这样也不太正确。除非VirtualAddr已经对齐,否则这是有效的。在这种情况下,它将前进到下一个页面边界。您是对的,也许if语句可以检查这一点。我相信这应该可以做到。((VirtualAddr+PageSize)&~(PageSize-1))选择此答案。详细、描述性且准确地说明了我要查找的内容。感谢大家帮助我:)。
 ((PageSize-1)&len)