堆栈分配,填充和对齐 [英] Stack allocation, padding, and alignment

查看:303
本文介绍了堆栈分配,填充和对齐的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在试图获得的编译器产生怎样的机器code更深的了解,也更具体怎么用GCC堆栈交易。在这方面,我一直在写简单的C程序,它们编译为装配和尽我所能理解的结果。这里有一个简单的程序,并输出它产生:

I've been trying to gain a deeper understanding of how compilers generate machine code, and more specifically how GCC deals with the stack. In doing so I've been writing simple C programs, compiling them into assembly and trying my best to understand the outcome. Here's a simple program and the output it generates:

asmtest.c:

asmtest.c:

void main() {
    char buffer[5];
}

asmtest.s:

asmtest.s:

pushl   %ebp
movl    %esp, %ebp
subl    $24, %esp
leave
ret

什么是令人费解的我就是24个字节被分配给堆栈。我知道由于怎样的处理器地址存储器,堆栈具有在4个增量要被分配,但是,如果是这样的情况下,我们只能由8字节,而不是24作为参考,17缓冲移动指针字节产生堆栈指针移动40个字节,并没有缓存堆栈指针移动到8 ESP 24字节1和16字节包含移动之间的缓冲区。

What's puzzling to me is why 24 bytes are being allocated for the stack. I know that because of how the processor addresses memory, the stack has to be allocated in increments of 4, but if this were the case, we should only move the stack pointer by 8 bytes, not 24. For reference, a buffer of 17 bytes produces a stack pointer moved 40 bytes and no buffer at all moves the stack pointer 8. A buffer between 1 and 16 bytes inclusive moves ESP 24 bytes.

现在假设8个字节是一个必要的常数(它是什么需要的?),这意味着我们在16字节的块是分配。为什么会编译器是以这样的方式对齐?我使用的是x86_64的处理器,但即使是64位字只需要8字节对齐。为什么不一致?

Now assuming the 8 bytes is a necessary constant (what is it needed for?), this means that we're allocating in chunks of 16 bytes. Why would the compiler be aligning in such a way? I'm using an x86_64 processor, but even a 64bit word should only require an 8 byte alignment. Why the discrepancy?

有关引用我跑10.5用gcc 4.0.1在Mac上编译这一点,并没有启用的优化。

For reference I'm compiling this on a Mac running 10.5 with gcc 4.0.1 and no optimizations enabled.

推荐答案

这是由 -m preferred堆栈边界= N ,其中控制的gcc的功能编译器试图保持项目对齐堆栈 2 ^ N 。如果您更改 N 2 ,它只会分配堆栈上的8个字节。为默认值 N 4 即它会尝试对齐到16字节边界。

It's a gcc feature controlled by -mpreferred-stack-boundary=n where the compiler tries to keep items on the stack aligned to 2^n. If you changed n to 2, it would only allocate 8 bytes on the stack. The default value for n is 4 i.e. it will try to align to 16-byte boundaries.

为什么有默认的8个字节,然后24 = 8 + 16个字节是因为栈已经包含8个字节为离开,所以编译code必须由8个字节先调整栈得到它对齐到2 ^ 4 = 16。

Why there's the "default" 8 bytes and then 24=8+16 bytes is because the stack already contains 8 bytes for leave and ret, so the compiled code must adjust the stack first by 8 bytes to get it aligned to 2^4=16.

这篇关于堆栈分配,填充和对齐的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆