c - 为什么 pushl %ebp 和 movl %esp, %ebp 在每个 ASM 函数的开头?

标签 c function assembly instructions

我正在 Uni 学习计算机体系结构和汇编编程类(class)。前段时间我们学习了如何在 ASM 中编写函数并从 C 中调用它们。但是有一件事我不明白——在每个 ASM 函数的开头,讲师总是进行两条指令;

pushl   %ebp
movl    %esp, %ebp

我不明白他为什么这样做,以及它在调用时对函数有什么影响。在我的 Intel Mac 上,为 IA32 编写程序集时,无论是包含这些指令还是直接跳过它似乎都没有任何区别。

有人能告诉我调用这些指令时实际发生了什么,以及为什么总是在 ASM 函数的开头调用它们吗?最好在 GNU ASM 中,尽管 Intel ASM 也可以。

最佳答案

这是正确堆栈展开所必需的约定的一部分。 %ebp 基指针指向调用者的栈帧。调用约定是通过将​​调用者的基指针压入堆栈来保存它。请参阅 Agner Fog 综合调用约定文档中的第 9 章异常处理和堆栈展开

http://www.agner.org/optimize/calling_conventions.pdf .

如果你想使用一个调试器,比如gdb来调试你的程序,并且你想让它显示一个backtrace,那么你需要遵循那个调用约定。

http://ftp.gnu.org/old-gnu/Manuals/gdb-5.1.1/html_node/gdb_42.html

A backtrace is a summary of how your program got where it is. It shows one line per frame, for many frames, starting with the currently executing frame (frame zero), followed by its caller (frame one), and on up the stack.

关于c - 为什么 pushl %ebp 和 movl %esp, %ebp 在每个 ASM 函数的开头?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22844456/

相关文章:

使用 fork() 的并发进程

c - 使用 strtok() 输入字符串或声明字符串的区别

java - 通过 ASM Java 字节码访问外部类的私有(private)字段时出现 java.lang.IllegalAccessError

visual-c++ - VC++ SSE 代码生成 - 这是编译器错误吗?

assembly - 与汇编代码的 .L2 标签关联的代码是否在此段中按程序调用?

c - 如何使 winxp ms-dos 虚拟机像 win98 ms-dos 一样工作,尤其是图形

c++ - (c/c++) 试图强制 EOF 从父进程发送输入到子进程

JavaScript 函数.subfunction()

Javascript:如何从方法内的函数获取值

java - 可以使用函数式操作