首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >这种对齐是如何工作的?((n + ZBI_ALIGNMENT - 1) & -ZBI_ALIGNMENT)

这种对齐是如何工作的?((n + ZBI_ALIGNMENT - 1) & -ZBI_ALIGNMENT)
EN

Stack Overflow用户
提问于 2021-07-30 17:48:24
回答 1查看 58关注 0票数 0

我在试着了解这条线是如何工作的。它应该将uint32地址对齐到其最近的8字节对齐地址。

代码语言:javascript
复制
static inline uint32_t
    ZBI_ALIGN(uint32_t n) {
  return ((n + ZBI_ALIGNMENT - 1) & -ZBI_ALIGNMENT);

让我们以n=10ZBI_ALIGNMENT=8为例。最近的地址应该是16

返回((10 + 8 -1) & -8) = 17 & -8

为什么这应该是一致的呢?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-07-30 18:46:11

这个公式的关键是,只有当ZBI_ALIGNMENT恰好是两个幂的时候,它才是有效的,这并不是什么大问题,因为对齐的要求往往符合这个标准。

正在对齐的数字(也称为2的倍数)二的幂表示所有小于该二次幂的位都被设置为0。只要看几个8位的数字,你就可以轻易地说服自己:

代码语言:javascript
复制
15: 00001111
16: 00010000   <--- aligned to 16
17: 00010001
31: 00011111
32: 00100000   <--- aligned to 16
48: 00110000   <--- aligned to 16

假设我们有一个只有16位高或等于16位的掩码,那么对于16的所有倍数,N & mask将是一个无运算,并给出所有其他值的16的前一个倍数。

代码语言:javascript
复制
16:          00010000
mask for 16: 11110000

15 & mask -> 00000000 : 0  
16 & mask -> 00010000 : 16
17 & mask -> 00010000 : 16
32 & mask -> 00100000 : 32

为了直接得到正确的值,我们可以使用(N + 15) & mask。如果N已经是16的倍数,那么N + 15将接近下一个倍数。否则,它总是会将值“凸”到下一个范围。例如1+15 = 1616 + 15 = 31等..。这被概括为(N + (DESIRED_ALIGMENT - 1))

所以剩下的就是如何计算给定对齐的掩码。

方便地,在两个补码表示中(所有有符号整数都必须使用),两个幂的负值正好是我们需要的掩码。

对于8位数,如下所示:

代码语言:javascript
复制
-1 -> 11111111
-2 -> 11111110
-4 -> 11111100
-8 -> 11111000
etc...

因此,mask可以简单地计算为-ZBI_ALIGNMENT

把所有这些放在一起,我们得到:

((n + ZBI_ALIGNMENT - 1) & -ZBI_ALIGNMENT)

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68595189

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档