当前位置: 动力学知识库 > 问答 > 编程问答 >

c - gcc function parameter alignment on stack frame

问题描述:

I have this test.c on my Ubuntu14.04 x86_64 system.

void foo(int a, long b, int c) {

}

int main() {

foo(0x1, 0x2, 0x3);

}

I compiled this with gcc --no-stack-protector -g test.c -o test and got the assembly code with objdump -dS test -j .text

00000000004004ed <_Z3fooili>:

void foo(int a, long b, int c) {

4004ed: 55 push %rbp

4004ee: 48 89 e5 mov %rsp,%rbp

4004f1: 89 7d fc mov %edi,-0x4(%rbp)

4004f4: 48 89 75 f0 mov %rsi,-0x10(%rbp)

4004f8: 89 55 f8 mov %edx,-0x8(%rbp) // !!Attention here!!

}

4004fb: 5d pop %rbp

4004fc: c3 retq

00000000004004fd <main>:

int main() {

4004fd: 55 push %rbp

4004fe: 48 89 e5 mov %rsp,%rbp

foo(0x1, 0x2, 0x3);

400501: ba 03 00 00 00 mov $0x3,%edx

400506: be 02 00 00 00 mov $0x2,%esi

40050b: bf 01 00 00 00 mov $0x1,%edi

400510: e8 d8 ff ff ff callq 4004ed <_Z3fooili>

}

400515: b8 00 00 00 00 mov $0x0,%eax

40051a: 5d pop %rbp

40051b: c3 retq

40051c: 0f 1f 40 00 nopl 0x0(%rax)

I know that the function parameters should be pushed to stack from right to left in sequence. So I was expecting this

void foo(int a, long b, int c) {

push %rbp

mov %rsp,%rbp

mov %edi,-0x4(%rbp)

mov %rsi,-0x10(%rbp)

mov %edx,-0x14(%rbp) // c should be push on stack after b, not after a

But gcc seemed clever enough to push parameter c(0x3) right after a(0x1) to save the four bytes which should be reserved for data alignment of b(0x2). Can someone please explain this and show me some documentation on why gcc did this?

网友答案:

The parameters are passed in registers - edi, esi, edx (then rcx, r8, r9 and only then pushed on stack) - just what the Linux amd64 calling convention mandates.

What you see in your function is just how the compiler saves them upon entry, so that the registers can be reused. It is free to do it in any way it wants, and it cleverly does this space optimization.

Saving them aids with debugging - you have access to all the arguments even later in the function, when they might not be used anymore and could be overwritten by other data. All this would be optimized out in release build in the end.

分享给朋友:
您可能感兴趣的文章:
随机阅读: