前言

网上大多教程都是对x86汇编进行分析,少有x64的,因此,本次对x86和x64的函数调用的参数传递以及函数的调用约定进行详细的分析对比和总结。

(cdecl,fastcall,stdcall,vectorcall,thiscall)

注意本次实验中(环境):x86的cdecl, fastcall, stdcall代码以debug模式编译,x86的thiscall,以及x64代码均以relase模式下编译并关闭性能优化

x86 汇编分析 (cdecl, fastcall, stdcall,thiscall)

分析汇编的源码:

#include <iostream>

int __cdecl cdecl_test(int a, int b, int c, int d, int e, int f, int g) {
char p[] = "Hello, World!";
int result = 0;
result += a + b + c + d + e + f + g;
return result;
} int __fastcall fastcall_test(int a, int b, int c, int d, int e, int f, int g) {
char p[] = "Hello, World!";
int result = 0;
result += a + b + c + d + e + f + g;
return result;
} int __stdcall stdcall_test(int a, int b, int c, int d, int e, int f, int g) {
char p[] = "Hello, World!";
int result = 0;
result += a + b + c + d + e + f + g;
return result;
} int main(){
int a = 1, b = 2, c = 3, d = 4, e = 5, f = 6, g = 7;
int result = 0;
result = cdecl_test(a, b, c, d, e, f, g);
printf("cdecl_test result: %d\n", result);
result = fastcall_test(a, b, c, d, e, f, g);
printf("fastcall_test result: %d\n", result);
result = stdcall_test(a, b, c, d, e, f, g);
printf("stdcall_test result: %d\n", result);
return 0;
}
#include <iostream>

class Test {
public:
int func(int a, int b, int c, int d, int e, int f, int g) {
int result = 0;
result += a + b + c + d + e + f + g;
printf("Result: %d\n", result);
return result;
}
}; int main() {
int a = 1, b = 2, c = 3, d = 4, e = 5, f = 6, g = 7;
int result = 0;
Test test;
result = test.func(a, b, c, d, e, f, g);
printf("Result: %d\n", result);
return 0;
}

cdecl


传递参数

开辟栈空间,保存栈环境

恢复环境,恢复栈空间,返回

平栈,保存返回值

fastcall


传递参数

开辟栈空间,保存环境

恢复环境,恢复栈空间,平栈

stdcall


传递参数

开辟栈空间,保存环境

恢复环境,恢复栈空间,平栈

thiscall


传递参数

开辟栈空间,保存环境

恢复环境,恢复栈空间,平栈

总结

函数调用约定 参数传递方式 平栈方式
cdecl(默认) push(从右到左) 函数外平栈
fastcall ecx(参数1),edx(参数2),push(从右到左) 函数内平栈
stdcall push(从右到左) 函数内平栈
thiscall ecx(this指针),push(从右到左) 函数内平栈

值得注意的是:在winapi中大多是用stdcall

x64 汇编分析(vectorcall, thiscall)

分析汇编的源码

#include <iostream>

int __vectorcall test(int a, int b, int c, int d, int e, int f, int g) {
int result = 0;
result += a + b + c + d + e + f + g;
printf("Result: %d\n", result);
return result;
} int main() {
int a = 1, b = 2, c = 3, d = 4, e = 5, f = 6, g = 7;
int result = 0;
result = test(a, b, c, d, e, f, g);
printf("Result: %d\n", result);
return 0;
}

vectorcall


传递参数

保存参数,开辟栈空间,(保存环境)

恢复栈空间

总结

函数调用约定 参数1 参数2 参数3 参数4 参数5以上 平栈方式
vectorcall rcx rdx r8 r9 堆栈传递 函数内平栈
vectorcall(浮点参数) xmm0 xmm1 xmm2 xmm3 堆栈传递 函数内平栈
thiscall rcx(this) rdx r8 r9 堆栈传递 函数内平栈

我这里给出thiscall,vectorcall的浮点表现形式,thiscall,因为在底层默认函数第一个参数传递this指针,这两种函数调用约定在x64中本质是一样的

以上出现错误可评论区提醒!

逆向:x86,x64从汇编分析函数调用约定详解的更多相关文章

  1. 【集合框架】JDK1.8源码分析之ArrayList详解(一)

    [集合框架]JDK1.8源码分析之ArrayList详解(一) 一. 从ArrayList字表面推测 ArrayList类的命名是由Array和List单词组合而成,Array的中文意思是数组,Lis ...

  2. Android Telephony分析(五) ---- TelephonyRegistry详解

    本文紧接着上一篇文章<Android Telephony分析(四) —- TelephonyManager详解 >的1.4小节.从TelephonyRegistry的大部分方法中: 可以看 ...

  3. Android Telephony分析(三) ---- RILJ详解

    前言 本文主要讲解RILJ工作原理,以便更好地分析代码,分析业务的流程.这里说的RILJ指的是RIL.java (frameworks\opt\telephony\src\java\com\andro ...

  4. Android Telephony分析(二) ---- RegistrantList详解

    前言 本文主要讲解RegistrantList的原理,以及如何快速分析RegistrantList相关的代码流程.在Telephony模块中,在RIL.Tracker(ServiceStateTrac ...

  5. nginx源码分析线程池详解

    nginx源码分析线程池详解 一.前言     nginx是采用多进程模型,master和worker之间主要通过pipe管道的方式进行通信,多进程的优势就在于各个进程互不影响.但是经常会有人问道,n ...

  6. 汇编  cdecl 函数调用约定,stdcall 函数调用约定

    知识点:  cdecl 函数调用约定  stdcall 函数调用约定  CALL堆栈平衡 配置属性--> c/c++ -->高级-->调用约定 一.cdecl调用约定 VC++ ...

  7. explain分析SQL语句详解

    性能分析explain MySql Query Optimizer是MySql中专门负责优化select语句的优化器模块,主要功能:通过计算分析系统中收集到的系统信息,为客户端请求的Query提供他认 ...

  8. 大脸猫讲逆向之ARM汇编中PC寄存器详解

    i春秋作家:v4ever 近日,在研究一些开源native层hook方案的实现方式,并据此对ARM汇编层中容易出问题的一些地方做了整理,以便后来人能有从中有所收获并应用于现实问题中.当然,文中许多介绍 ...

  9. lua 函数调用 -- 闭包详解和C调用

    转自:http://www.cnblogs.com/ringofthec/archive/2010/11/05/luaClosure.html 这里, 简单的记录一下lua中闭包的知识和C闭包调用 前 ...

  10. Golang源码分析之目录详解

    开源项目「go home」聚焦Go语言技术栈与面试题,以协助Gopher登上更大的舞台,欢迎go home~ 导读 学习Go语言源码的第一步就是了解先了解它的目录结构,你对它的源码目录了解多少呢? 目 ...

随机推荐

  1. 浅谈Spring、Spring MVC、Spring Boot和Spring Cloud的关系和区别

      Spring 框架就像一个家族,有众多衍生产品,例如 boot.security.jpa等等.但它们的基础都是Spring的IOC和AOP等.IOC提供了依赖注入的容器,AOP解决了面向横切面编程 ...

  2. 20244104 实验二《Python程序设计》实验报告

    课程:<Python程序设计> 班级: 2441 姓名: 陈思淼 学号:20244104 实验教师:王志强 实验日期:2025年4月5日 必修/选修: 公选课 1.实验内容 设计并完成一个 ...

  3. 从零开始学Flink:揭开实时计算的神秘面纱

    一.为什么需要Flink? 当你在电商平台秒杀商品时,1毫秒的延迟可能导致交易失败:当自动驾驶汽车遇到障碍物时,10毫秒的计算延迟可能酿成事故.这些场景揭示了一个残酷事实:数据的价值随时间呈指数级衰减 ...

  4. Seo工具使用与流量数据观察实践(中)

    第12章.Seo工具使用与数据观察实践(中) 继上一节的SimilarWeb流量粗分析,我们已经选定了竞品,并且有了一个大致的用户画像和群体,接下来我们就进入细节的关键词和内容的分析. 那么这本节中, ...

  5. ArkUI-X平台桥接Bridge说明

    简介 平台桥接用于客户端(ArkUI)和平台(Android或iOS)之间传递消息,即用于ArkUI与平台双向数据传递.ArkUI侧调用平台的方法.平台调用ArkUI侧的方法. 以Android平台为 ...

  6. 你应该懂的AI大模型(十)之 LLamaFactory 之 LoRA微调Llama3

    本文标题中说的微调 Llama3指的是局部微调,使用 LLamaFactory 局部微调 LIama3. 一.什么是LLamaFactory LLaMA-Factory 是一个开源的大型语言模型微调框 ...

  7. 字节开源的AI Coding Agent —— Trae Agent深入浅出

    1. 项目概述 从Cursor到Trae,从claude code到gemini cli,AI Coding都是火热的战场,现在字节开源了新的trae-agent(https://github.com ...

  8. java下载文件写的工具类

    netUrl:提供一个文件的网址 filePath:本地保存的路径 1 ... 2 private File getNetUrlHttp(String netUrl, String filePath) ...

  9. vmware workstation 安装 Debian

    下载安装 vmware workstation 本文中用的是 VMware Workstation Pro v17. 点击这里,跳转至下载页. 下载 debian 点击这里跳转官网下载. 创建一个虚拟 ...

  10. CF2064E Mycraft Sand Sort 题解

    CF2064E Mycraft Sand Sort 第一次一眼秒了一道 E,但是被人均六分钟 C 题硬控一小时,未能写完,遗憾离场,特此纪念. 考虑第一列,无论排列 \(p'\) 是什么样子,第一列一 ...