【发布时间】:2015-10-23 17:42:35
【问题描述】:
我正在阅读 Multiboot2 规范。你可以找到它here。与之前的版本相比,它将所有结构命名为“标签”。它们的定义如下:
3.1.3 通用标签结构
标签构成了一个结构缓冲区,这些结构在
u_virt大小上填充。每个结构都有 以下格式:+-------------------+ u16 |类型 | u16 |旗帜 | u32 |尺寸 | +-------------------+
type分为两部分。 Lower 包含一个标识符 标签其余部分的内容。size包含标签的大小 包括标题字段。如果flags的位0(也称为optional) 设置如果引导加载程序可能会忽略此标记,如果它缺少 相关支持。标签以0类型和大小的标签终止8.
然后在示例代码中:
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) 是什么意思吗?
【问题讨论】:
-
如果需要,它会返回一个四舍五入的
size到 8 的倍数。 -
你必须了解两个概念。首先,它要求您了解按位运算符的工作原理。假设您可以遵循使用 ~ 和 & 的逻辑,那么您需要了解它在做什么以及它为什么起作用。以下答案的组合解释了第一部分的按位逻辑。然后其他答案解释说,整个程序在第二部分以 8 的倍数进行舍入。
-
@jaybers 虽然代码会因注释而受益。 7这个神奇的数字已经准备好避免。代码应该放弃位摆弄、铸造和幻数并使用
tag += (tag->size + sizeof *tag -1)/sizeof *tag;,并带有注释。 (现在看到评论消失了。)
标签: c bit-manipulation