为什么64位Ubuntu中的8字节数组(C)占用16个字节?

DJS*_*nny 3 c 64-bit byte 32bit-64bit

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

例如,而不是0xDEADBEEF 0x12345678像我期望的那样代表8字节数组,它实际上就像是0x00000000 0xDEADBEEF 0x00000000 0x12345678.

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

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

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

Nec*_*lis 5

64位系统适用于将所有内存对齐到16字节边界(16字节堆栈对齐是System-V ABI的一部分),对于堆栈分配,有两个部分,首先,堆栈本身需要对齐,其次是任何然后分配尝试保持该对齐.

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

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