调用方法/函数时汇编语言会发生什么?

Gor*_*son 19 c c++ assembly function

如果我有一个C++/C程序(语言无关紧要,只需要说明一个概念):

#include <iostream>    

void foo() {
    printf("in foo");
}

int main() {
    foo();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

装配中会发生什么?我实际上并不是在寻找汇编代码,因为我还没有那么远,但基本原理是什么?

Isa*_*avo 44

一般来说,这是发生的事情:

  1. 函数的参数存储在堆栈中.按平台特定顺序.
  2. 返回值的位置在堆栈上"分配"
  3. 该函数的返回地址也存储在堆栈或专用CPU寄存器中.
  4. 通过CPU特定call指令或通过普通jmpbr指令(跳转/分支)调用函数(或实际上,函数的地址)
  5. 该函数从堆栈中读取参数(如果有)并运行函数代码
  6. 函数返回值存储在指定位置(堆栈或专用CPU寄存器)
  7. 执行跳转回调用者并清除堆栈(通过将堆栈指针恢复为其初始值).

上述细节因平台而异,甚至从编译器到编译器也有所不同(参见例如STDCALL与CDECL调用约定).例如,在某些情况下,使用CPU寄存器而不是在堆栈上存储东西.一般的想法是相同的


小智 13

你可以自己看看:

在Linux下'编译'您的程序:

gcc -S myprogram.c
Run Code Online (Sandbox Code Playgroud)

并且您将获得汇编程序(myprogram.s)中的程序列表.

当然你应该对汇编程序有一点了解它(但它值得学习,因为它有助于理解你的计算机是如何工作的).调用函数(在x86架构上)基本上是:

  • 把变量放在堆栈上
  • 将变量b放在堆栈上
  • 将变量n放在堆栈上
  • 跳转到该函数的地址
  • 从堆栈加载变量
  • 做功能的东西
  • 干净的堆栈
  • 跳回主要

  • @Alex评论来得太晚了(大约6年,但谁关心:-P),但你可以在gcc命令中添加`-masm = intel`. (3认同)