我是一个学习装配的新人。我写了一个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
。
这是正确的?
谢谢你的回答。
答案 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会生成易于调试的代码,这种代码效率很低,有时也很重复。