【问题标题】:Why does an 8-byte array (C) in 64-bit Ubuntu take 16 bytes?为什么 64 位 Ubuntu 中的 8 字节数组 (C) 占用 16 字节?
【发布时间】:2013-01-05 07:11:13
【问题描述】:

我最近一直在(重新学习)较低级别的 CS 材料,并且一直在探索缓冲区溢出。我创建了一个基本的 C 程序,它有一个 8 字节数组 char buffer[8];。然后我使用 GDB 探索和反汇编程序并逐步执行它。我在 64 位版本的 Ubuntu 上,我注意到我的 8 字节 char 数组实际上在内存中以 16 字节表示 - 高位都只是 0。

例如而不是 0xDEADBEEF 0x12345678 我可能期望代表 8 字节数组,它实际上类似于 0x00000000 0xDEADBEEF 0x00000000 0x12345678

我做了一些谷歌搜索,并能够让 GCC 将我的程序编译为 32 位程序(使用 -m32 标志) - 这导致预期的 8 个字节正常。

我只是在寻找一个明确的解释,说明为什么 8 字节字符数组在 64 位系统上以 16 字节表示。是不是因为最小字长/可寻址单元是 16 字节(64 位),而 GDB 只是基于 8 字节字长打印?

希望这很清楚,但如果需要澄清,请告诉我。

【问题讨论】:

  • 这个char buffer[8];在哪里?它在struct 内吗?它在堆栈上吗?
  • 尝试使用#pragma pack解决
  • 仅供参考,16 字节是 128 位。
  • 如果您能向我们展示您使用的确切代码以及编译器版本和选项会更清楚。我们所能做的就是推测。
  • @UrielFrankel #pragma pack 没有加入其中。 T 的数组的大小是 T 的大小的 n 倍,总是 (C99 6.5.3.4:6),char 的大小是一,总是 (C99 6.5.3.4:3)。

标签: c 64-bit x86-64 32bit-64bit sizeof


【解决方案1】:

64 位系统旨在将所有内存对齐到 16 字节边界(16 字节堆栈对齐是 System-V ABI 的一部分),对于堆栈分配,有两个部分,首先,堆栈本身需要对齐,其次,任何分配都会尝试保持这种对齐方式。

这解释了为什么 8 字节数组在堆栈上变成 16 字节的第一部分,以及为什么它被分成两个 8 字节的 qword,这有点难说,因为你没有提供任何代码(汇编或C)关于这个缓冲区的使用。并且尝试使用 mingw64 复制它提供了 16 字节对齐,但不是您看到的有趣布局。

当然,缺少 ASM 的另一种可能性是 GDB 显示的是 2xQWORD,尽管它实际上是 2xDWORD(换句话说,尝试使用 p/x (char[8]) 转储内容...)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-30
    • 1970-01-01
    • 2015-09-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多