奇怪的按位运算符组合的目的是什么?

Whats the purpose served by the strange bitwise operator combo?

我正在查看以下代码并发现了以下代码段。

https://www.virtualbox.org/svn/vbox/trunk/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Core/Pei/Hob/Hob.c

EFI_STATUS  
EFIAPI  
PeiCreateHob (  
  IN CONST EFI_PEI_SERVICES  **PeiServices,  
  IN UINT16            Type,  
  IN UINT16            Length,  
  IN OUT VOID          **Hob  
  )  
{  
  EFI_STATUS                           Status;  
  EFI_HOB_HANDOFF_INFO_TABLE           *HandOffHob;  
  EFI_HOB_GENERIC_HEADER               *HobEnd;  
  EFI_PHYSICAL_ADDRESS                 FreeMemory;  


  Status = PeiGetHobList (PeiServices, Hob);  
  if (EFI_ERROR(Status)) {  
    return Status;  
  }

  HandOffHob = *Hob;  

  //
  // Check Length to avoid data overflow.
  //
  if (0x10000 - Length <= 0x7) {  
    return EFI_INVALID_PARAMETER;  
  }
  Length     = (UINT16)((Length + 0x7) & (~0x7));  
  ...

我不明白我们通过以下操作实现了什么:

Length     = (UINT16)((Length + 0x7) & (~0x7));

我知道长度是 16 位对齐的。但是为什么我们要全零呢?据我所知,我们会在操作中丢失 LSB 3 位。这个操作有什么用?

Length = (UINT16)((Length + 0x7) & (~0x7));

该操作执行两个重要步骤:

  • Length
  • 的低三位以上的位进行进位
  • 确保低三位为空,从而使结果最接近等于或大于原始 Length 值的 8 的倍数。

第 1 部分:四舍五入

如果 Length 的低三位无论如何都点亮(除 000 之外的任何值),增量 0x7111 二进制)将通过进位到低三位以上的位。对于低三位的000,低三位就简单的变成了111,没有进位。例如:

 5 - 00000101
 7 - 00000111
=============
12 - 00001100
         ^-------note carry

另一个例子:

250 -  11111010
  7 -  00000111
===============
257 - 100000001

最后,一个在低三位上已经很清楚的例子(因此是 8 的倍数):

24 - 00011000
 7 - 00000111
=============
31 - 00011111

第 2 部分:剔除低位

一旦值向上舍入,低三位被剔除以确保最终结果是 8 的倍数。使用我们之前的示例

   5 - 00000101
+  7 - 00000111
===============
  12 - 00001100
& ~7 - 11111000
===============
   8   00001000

下一个例子

 250 -  11111010
+  7 -  00000111
================
 257 - 100000001
& ~7 - 111111000
================
 256 - 100000000

最后一个例子:

  24 - 00011000
+  7 - 00000111
===============
  31 - 00011111
& ~7 - 11111000
===============
  24 - 00011000

总而言之,这只是将 Length 设置为等于或大于 8 倍数的当前值的最接近值。就是这样。