理解C函数调用生成的程序集

理解C函数调用生成的程序集,c,assembly,C,Assembly,我正在试图了解这个汇编代码的情况。我通过键入gcc-O1-S calc.c创建了它,它生成了一个calc.S汇编文件 有人能逐行解释一下(在calc.c中的加法和乘法)发生了什么吗 原始C代码是: .file "calc.c" .text .globl calc .type calc, @function calc: pushl %ebp movl %esp, %ebp

我正在试图了解这个汇编代码的情况。我通过键入
gcc-O1-S calc.c
创建了它,它生成了一个
calc.S
汇编文件

有人能逐行解释一下(在
calc.c
中的加法和乘法)发生了什么吗

原始C代码是:

        .file   "calc.c"
        .text
.globl calc
        .type   calc, @function
calc:
        pushl   %ebp     
        movl    %esp, %ebp 
        movl    8(%ebp), %edx
        movl    16(%ebp), %ecx  
        leal    (%edx,%edx,2), %edx 
        movl    12(%ebp), %eax 
        leal    (%edx,%eax,2), %eax
        movl    %ecx, %edx
        sall    $4, %edx
        subl    %ecx, %edx
        addl    %edx, %eax
        popl    %ebp
        ret
        .size   calc, .-calc
        .ident  "GCC: (Ubuntu 4.3.3-5ubuntu4) 4.3.3"
        .section        .note.GNU-stack,"",@progbits

好的,现在它做了一些事情,我将为您注释它

int calc(int x, int y, int z)
{
        return 3*x + 2*y + 15*z;
}

您已经创建了一个未使用的嵌套函数,该函数已经过优化,因此不在程序集列表中。删除
main
函数,然后重试。可能您键入了
。全局计算
对不起。我更正了代码。(组装和c)请改进标题,以便对未来的网站访问者有用。当前的标题非常模糊,有相同问题的人不会意识到这是同一个问题。此外,这似乎不是一个特定的编程问题。您遇到的编程问题是什么?理解这个计算函数是解决问题的方法吗?回答得很好!一些附加信息:C将函数参数按相反顺序推送到堆栈上,
int
s有4个字节长。我做了一些欺骗,并从对它们所做的操作中推断出它们的含义。您还可以查看
cdecl
调用约定,查看它们基于偏移量的参数索引。
leal(x,y,z),w
转化为
w=x+y*z
令人惊讶的是
16z-z
15z
更受欢迎。真棒的问答!移位和加法/减法是非常“便宜”的运算,而乘法在处理时间上是“昂贵”的。将一个数字向左移动相当于乘以2,现代编译器经过优化以有效处理常见操作。例如,您会发现,
10x
可能会转换为
2x+8x
,实现为
x
calc:
    pushl   %ebp           ; \
    movl    %esp, %ebp     ; /  set up basic stack frame
    movl    8(%ebp), %edx  ; load x
    movl    16(%ebp), %ecx ; load z
    leal    (%edx,%edx,2), %edx ; calculate x + 2 * x
    movl    12(%ebp), %eax ; load y
    leal    (%edx,%eax,2), %eax ; calculate (x + 2 * x) + (2 * y)
    movl    %ecx, %edx     ; make a temp copy of z
    sall    $4, %edx       ; calculate z * 16
    subl    %ecx, %edx     ; calculate (z * 16) - z
    addl    %edx, %eax     ; calculate final sum
    popl    %ebp
    ret