5. 函数调用过程汇编分析

函数调用约定

5. 函数调用过程汇编分析_第1张图片

__cdecl 调用方式

5. 函数调用过程汇编分析_第2张图片

__stdcall 调用方式

5. 函数调用过程汇编分析_第3张图片

__fastcall 调用方式

5. 函数调用过程汇编分析_第4张图片

函数调用栈帧分析

5. 函数调用过程汇编分析_第5张图片

补充说明

  1. 不同的编译器实现不一样,上述情况只是VC++6.0的编译实现
  2. 即便是在同一个编译器,开启优化和关闭优化也不一样
  3. 即便是同一个编译器同一种模式,32位和64位下情况也会不一样

fastcall 实例分析

[[gnu::fastcall]] int fun1(int a, int b, int c, int d) {
  return a * a + b * b + 2 * a * b + c + d;
}
int main() {
  int c = fun1(3, 4, 5, 6);
  return 0;
}
#!/bin/bash
set -ex

/mnt/e/code/llvm-project/build/bin/clang fastcallTest.c -o fastcallTest -O0 -g -m32 -c
# 编译生成汇编代码
objdump -dS fastcallTest &> fastcallTest.asm
# sudo apt-get install -y build-essential module-assistant  
# sudo apt-get install -y gcc-multilib g++-multilib  

参考 GCC GNU 文档属性描述

fastcall
On x86-32 targets, the fastcall attribute causes the compiler to pass the first argument (if of integral type) in the register ECX and the second argument (if of integral type) in the register EDX. Subsequent and other typed arguments are passed on the stack. The called function pops the arguments off the stack. If the number of arguments is variable all arguments are pushed on the stack.

翻译: 在 x86-32 目标机上,fastcall 属性会导致编译器在寄存器 ECX 中传递第一个参数(如果是 INT 类型),在寄存器 EDX 中传递第二个参数(如果是INT类型)。后面的参数和其他类型的参数会传递到堆栈中。被调用函数将参数从堆栈中弹出。如果参数个数不固定,所有参数都会被推入堆栈。

5. 函数调用过程汇编分析_第6张图片

你可能感兴趣的:(编译器,汇编)