我正在阅读 Multiboot2 规范。你可以找到它here .与以前的版本相比,它将所有结构命名为“标签”。它们的定义如下:
3.1.3 General tag structure
Tags constitutes a buffer of structures following each other padded on
u_virt
size. Every structure has following format:+-------------------+ u16 | type | u16 | flags | u32 | size | +-------------------+
type
is divided into 2 parts. Lower contains an identifier of contents of the rest of the tag.size
contains the size of tag including header fields. If bit0
offlags
(also known asoptional
) is set if bootloader may ignore this tag if it lacks relevant support. Tags are terminated by a tag of type0
and size8
.
然后在示例代码中:
for (tag = (struct multiboot_tag *) (addr + 8);
tag->type != MULTIBOOT_TAG_TYPE_END;
tag = (struct multiboot_tag *) ((multiboot_uint8_t *) tag
+ ((tag->size + 7) & ~7)))
最后一部分让我很困惑。在 Multiboot 1 中,代码简单得多,您可以执行 multiboot_some_structure * mss = (multiboot_some_structure *) mbi->some_addr
并直接获取成员,而不会像这样混淆代码。
谁能解释一下 ((tag->size + 7) & ~7)
是什么意思?
最佳答案
正如 chux 在他的评论中提到的,这会将 tag->size
舍入到最接近的 8 的倍数。
让我们仔细看看它是如何工作的。
假设 size
为 16:
00010000 // 16 in binary
+00000111 // add 7
--------
00010111 // results in 23
表达式 ~7
取值 7
并反转所有位。所以:
00010111 // 23 (from pervious step)
&11111000 // bitwise-AND ~7
--------
00010000 // results in 16
现在假设 size
是 17:
00010001 // 17 in binary
+00000111 // add 7
--------
00011000 // results in 24
然后:
00011000 // 24 (from pervious step)
&11111000 // bitwise-AND ~7
--------
00011000 // results in 24
因此,如果 size
的低 3 位全为零,即 8 的倍数,(size+7)&~7
设置这些位,然后清除它们,所以没有净效应。但是,如果这些位中的任何一位为 1,则对应于 8 的位会递增,然后清除较低的位,即该数字会向上舍入到最接近的 8 的倍数。
关于c - (size + 7) & ~7 是什么意思?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33308421/