组装 - 堆对齐 - x86 intel
Posted
技术标签:
【中文标题】组装 - 堆对齐 - x86 intel【英文标题】:Assembly - Heap alignment - x86 intel 【发布时间】:2015-11-20 15:29:44 【问题描述】:我想我理解堆栈对齐是 4 字节,例如如果我只添加一个字符,他的地址将在 4 字节的右侧(如果还有其他 1 或 2 字节变量,则稍早)
我仍然无法理解堆中的对齐方式,我认为有 4 字节或 8 字节对齐,但事情是这样的,当我分配 100 和 20 字节时,第一个结尾之间有 4 个字节和第二个的开头,所以我猜堆会使用 8bytes 对齐。
通过连续分配 1 4 7 8 9 14 16 17 个字节,我注意到 1、4、7、8、9 每个占用 16 个字节,而 14 16 17 占用 24 个字节,为什么会这样?
我正在使用 C/C++ 并使用 malloc 进行分配(与 new 相同)。
谢谢。
【问题讨论】:
可能取决于你如何分配这些东西,你没有展示出来。 对不起,我使用 C/C++,我用 malloc 分配它们。 【参考方案1】:在 Windows 上,malloc
函数被记录为返回对齐 32 位应用程序的 8 字节边界和 64 位应用程序的 16 字节边界的内存。在 Linux 上,它只说它返回“适合任何类型的变量对齐的内存”,但它可能也是 8 和 16。
最重要的是,malloc
需要保留额外的内存来存储管理堆所需的跟踪数据。这意味着当您请求 N 个字节时,malloc
实际上将使用 N+X 个字节,其中 X 是常量并取决于实现。
【讨论】:
谢谢,我确实在使用Linux,分配1字节需要16字节(15个额外字节)而分配100需要104字节仍然很奇怪。管理堆的这些额外字节是否有名称,以便我可以做一些研究?或者你有任何文档页面吗? @x4rkz 大约1个字节需要16个,分配机制可能没那么简单。也许分配 104 或 105 字节将使用 112 ?如果是这种情况,也许附加数据也需要某种对齐方式。关于附加数据本身,我不知道它是如何工作的,但我认为它是指向某个 malloc 状态结构的指针。我不确定它有一个特殊的名字。 Windows x64 和 x86-64 System V ABI 都具有alignof(max_align_t) = 16
(godbolt.org/z/4dKhfeqhn),因此您可以保证从 malloc 中对齐(至少对于至少 16 个字节的分配;在理论上,较小的分配可能不太对齐,因为它无论如何都不能容纳 16 字节类型)。但是,是的,在 32 位代码中,malloc 可能只给你 8 字节对齐,或者如果没有任何带有alignof(T) == 8
的类型,理论上只有 4 个。 (大多数现代 32 位 x86 实现选择为性能提供 8,以防它用于 double
或其他东西。)【参考方案2】:
对齐只是某事物开始的位置:它的地址将是 A 的倍数。内存管理器将这些分配放在哪里,以及为什么,完全是它的业务,并且可能(部分)依赖于在您的程序之外的计算机中发生的其他事情。这意味着您无法通过“下一个”分配的位置来确定上一个分配的“大小”(虽然它可能在您的程序旁边,但它可能不在内存管理器旁边);事实上,“下一个”分配可能有一个较小的地址(例如,如果在此期间释放了较低的内存)。
【讨论】:
以上是关于组装 - 堆对齐 - x86 intel的主要内容,如果未能解决你的问题,请参考以下文章
分配粒度和内存页面大小(x86处理器平台的分配粒度是64K,内存页是4K,所以section都是0x1000对齐,硬盘扇区大小是512字节,所以PE文件默认文件对齐是0x200)