从C代码生成的基本汇编代码理解需要帮助

3

我正在学习汇编语言,试图理解如何从C语言代码生成汇编语言。

我创建了以下虚拟的C代码:

#include <stdio.h>

int add(int x, int y){
    int result = x + y;
    return result;
}

int main(int argc, char *argv[]){

    int x = 1 * 10;
    int y = 2 * 5;
    int firstArg = x + y;
    int secondArg = firstArg / 2;
    int value;
    value = add(firstArg, secondArg);
    return value;
}

并获得了以下汇编代码

.file   "first.c"
    .text
    .globl  add
    .type   add, @function
add:
.LFB39:
    .cfi_startproc
    movl    8(%esp), %eax
    addl    4(%esp), %eax
    ret
    .cfi_endproc
.LFE39:
    .size   add, .-add
    .globl  main
    .type   main, @function
main:
.LFB40:
    .cfi_startproc
    movl    $30, %eax
    ret
    .cfi_endproc
.LFE40:
    .size   main, .-main
    .ident  "GCC: (Ubuntu 4.8.2-19ubuntu1) 4.8.2"
    .section    .note.GNU-stack,"",@progbits

我很惊讶主函数中所有那些算术操作都去哪了? 我不明白我们怎么从无处得到了30(好吧,我猜这是从 add 函数返回的值,但为什么我看不到任何获取该值的命令,实际上我看到返回值已经被推到了 eax 中,在 add 函数中,为什么我们需要再将 $30 移动到 eax 中?)。 所有 main 中的局部变量都在哪里声明?我特意创建了其中的五个,以查看其中一个是如何被推到栈上的。

你能帮我理解所有这些 .LFE39 .LFB40:.LFB39:是什么意思吗?

我正在阅读这本书,但它并没有为我澄清这个问题。 实际上,书中说所有函数都必须从堆栈初始化开始:

  pushl   %ebp
  movl    %esp, %ebp

在函数结束时,需要使用pop指令来完成函数。

但是在上面的代码中并没有这样做。我没有看到任何堆栈初始化的过程。

谢谢!


关闭编译器的优化功能,然后您将看到所有已被优化消失的代码。 - user3629249
1个回答

13

您正在启用优化进行编译。GCC足够聪明,能在编译时执行所有这些计算,并用简单的常量替换所有无用的代码。

首先,xy将被替换为它们的常量表达式:

    int x = 10;
    int y = 10;

然后,使用这些变量的地方将会得到它们的常量值:

    int firstArg = 20;
    int secondArg = 10;

接下来,你的add函数很小且简单,所以它肯定会被内联:

    value = firstArg + secondArg;

现在这些也是常量,所以整个东西将被替换为:

int main(int argc, char *argv[]) {
    return 30;
}
虽然大多数函数都会有像你展示的那样的序言,但您的程序除了返回30之外什么也不做。更具体地说,它不再使用任何本地变量,并且不调用任何其他函数。因此,main不需要帧或在调用堆栈上保留的空间。所以编译器没有必要发出序言/尾声。
main:
    movl    $30, %eax
    ret

除了 C 运行时启动代码之外,这是您的程序将要运行的唯一两个指令。


另外请注意,由于您的 add 函数没有被标记为 static,编译器必须假设外部可能会调用它。因此,即使没有人调用它,我们仍然在生成的汇编代码中看到了 add

add:
    movl    8(%esp), %eax
    addl    4(%esp), %eax
    ret

哦,谢谢,该死的书只是说要运行 gcc -O1 -S code.c - UserMoon
@FemX 是的,尝试使用 gcc -O0 -S 来禁用优化。 - Jonathon Reinhart

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接