我有关于堆栈框架结构的问题?

时间:2011-04-11 12:24:18

标签: c assembly

我是一个学习装配的新人。我写了一个c文件:

#include <stdlib.h>

int max( int c )
{
        int d;
        d = c + 1;

        return d;
}

int main( void )
{
        int a = 0;
        int b;
        b = max( a );

        return 0;
}

我使用gcc -S as01.c并创建一个程序集文件。

        .file   "as01.c"
        .text
.globl max
        .type   max, @function
max:
        pushl   %ebp
        movl    %esp, %ebp
        subl    $32, %esp
        movl    $0, -4(%ebp)
        movl    $1, -24(%ebp)
        movl    $2, -20(%ebp)
        movl    $3, -16(%ebp)
        movl    $4, -12(%ebp)
        movl    $6, -8(%ebp)
        movl    8(%ebp), %eax
        addl    $1, %eax
        movl    %eax, -4(%ebp)
        movl    -4(%ebp), %eax
        leave
        ret
        .size   max, .-max
.globl main
        .type   main, @function
main:
        pushl   %ebp
        movl    %esp, %ebp
        subl    $20, %esp
        movl    $0, -4(%ebp)
        movl    -4(%ebp), %eax
        movl    %eax, (%esp)
        call    max
        movl    %eax, -8(%ebp)
"as01.s" 38L, 638C          

我很困惑,因为max()中的movl %eax, -4(%ebp) movl -4(%ebp), %eax, 我知道%eax用于返回任何函数的值。 我认为%eax是临时注册商店c + 1。 这是正确的? 谢谢你的回答。

2 个答案:

答案 0 :(得分:4)

您没有启用优化,因此编译器生成的代码非常糟糕。所有值的主存储位于堆栈帧中,并且值仅加载到寄存器中的时间足以进行计算。

代码实际上分解为:

    pushl   %ebp
    movl    %esp, %ebp
    subl    $32, %esp

标准函数序言,设置新的堆栈帧,并为堆栈帧保留50个字节。

    movl    $0, -4(%ebp)
    movl    $1, -24(%ebp)
    movl    $2, -20(%ebp)
    movl    $3, -16(%ebp)
    movl    $4, -12(%ebp)
    movl    $6, -8(%ebp)

使用虚拟值填充堆栈帧(可能作为调试辅助工具)。

    movl    8(%ebp), %eax
    addl    $1, %eax
    movl    %eax, -4(%ebp)

从堆栈框架中读取参数c,添加一个参数,将其存储到(不同的)堆栈槽中。

    movl    -4(%ebp), %eax
    leave
    ret

从堆栈槽中读取值并将其返回。

如果你用优化编译它,你会发现大部分代码都消失了。如果你使用-fomit-frame-pointer -Os,你应该最终得到:

max:
    movl    4(%esp), %eax
    incl    %eax
    ret

答案 1 :(得分:0)

    movl    %eax, -4(%ebp)

这里为d计算的值(现在存储在eax中)保存在d的内存单元格中。

    movl    -4(%ebp), %eax

虽然这里返回值(d's)已加载到eax,因为正如您所知,eax包含函数的返回值。
正如@David所说,你在没有优化的情况下进行编译,因此gcc会生成易于调试的代码,这种代码效率很低,有时也很重复。