x64汇编fastcall调用约定

x64汇编环境:只需要在x86基础上对项目属性进行设置,将平台设置为所有平台;

以及在将debug改为x64模式即可:

后续写完代码直接生成项目再使用本地调试器进行运行即可。

fastcall调用约定

在x64架构下,fastcall调用约定是默认的调用约定。它旨在通过寄存器传递参数以提高调用效率。以下是详细的理论说明,涵盖了参数传递、返回值处理、栈管理和寄存器保存规则。

参数传递规则

前四个整数或指针参数通过以下寄存器传递:

  • 第一个参数:RCX

  • 第二个参数:RDX

  • 第三个参数:R8

  • 第四个参数:R9

超过四个的参数通过栈传递,从右到左的顺序依次入栈;即当参数数量超过四个时,第五个及之后的参数按照从右到左的顺序依次压入栈中。

假设有一个函数foo,定义如下:

void foo(int a, int b, int c, int d, int e, int f, int g);

在调用foo(1, 2, 3, 4, 5, 6, 7)时,参数传递顺序如下:

前四个参数通过寄存器传递

  • a(1)传递到RCX

  • b(2)传递到RDX

  • c(3)传递到R8

  • d(4)传递到R9

剩余的参数通过栈传递

  • e(5)

  • f(6)

  • g(7)

在栈中,参数按照从右到左的顺序依次压入栈中,即最右边的参数(g)最先压入栈,接着是f,最后是e。这样,在栈中的顺序如下(从栈顶到栈底):

栈顶 -> g (7)f (6)e (5)
栈底

简单的使用示例

段代码用MASM(Microsoft Assembler)编写的x64汇编代码,包含两个过程(proc):myaddmain;它们实现了一个简单的加法操作,myadd将接收的多个参数相加,而main负责设置这些参数并调用myadd

.code
myadd procxor rax,raxadd rax,qword ptr [rsp + 30h]add rax,qword ptr [rsp + 28h]add rax,r9add rax,r8add rax,rdxadd rax,rcxret
myadd endp
​
main procsub rsp,28hmov qword ptr [rsp + 28h],6mov qword ptr [rsp + 20h],5mov r9,4mov r8,3mov rdx,2mov rcx,1call myaddadd rsp,28hret
main endp
end
代码解释
①main过程

main过程负责设置参数并调用myadd过程:

调整栈指针

  • sub rsp, 28h:调整栈指针,预留40字节(0x28)的栈空间,以对齐栈并为局部变量提供空间。

设置额外参数

  • mov qword ptr [rsp + 28h], 6:将第6个参数6保存到栈上的位置[rsp + 28h]

  • mov qword ptr [rsp + 20h], 5:将第5个参数5保存到栈上的位置[rsp + 20h]

设置寄存器参数

  • mov r9, 4:将第4个参数4存储到r9寄存器。

  • mov r8, 3:将第3个参数3存储到r8寄存器。

  • mov rdx, 2:将第2个参数2存储到rdx寄存器。

  • mov rcx, 1:将第1个参数1存储到rcx寄存器。

调用myadd过程

  • call myadd:调用myadd过程,结果将存储在rax寄存器中。

恢复栈指针

  • add rsp, 28h:恢复栈指针到调用sub rsp, 28h之前的状态。

返回

  • ret:返回,结束程序。

②myadd过程

myadd过程从寄存器和栈中读取6个参数,并将它们相加。具体步骤如下:

初始化累加器

  • xor rax, rax:将rax寄存器清零,作为累加器。

执行加法操作

  • add rax, qword ptr [rsp + 30h]:将参数6(存储在[rsp + 30h])加到rax中。

  • add rax, qword ptr [rsp + 28h]:将参数5(存储在[rsp + 28h])加到rax中。

  • add rax, r9:将参数4(存储在r9寄存器中)加到rax中。

  • add rax, r8:将参数3(存储在r8寄存器中)加到rax中。

  • add rax, rdx:将参数2(存储在rdx寄存器中)加到rax中。

  • add rax, rcx:将参数1(存储在rcx寄存器中)加到rax中。

返回

  • ret:返回,rax寄存器中的结果作为函数返回值。

程序执行结果:

最后RAX寄存器中的值为15h转化为10进制就是21。

x64dbg查看堆栈变化

使用x64dbg进行调试;将程序拖进x64dbg程序中,以下是x64dbg进行调试的四个区域窗口,分别是反汇编、寄存器、内存和堆栈窗口。

刚进来显示的是ntdll.dll的反汇编调试信息,ntdll.dll是Windows操作系统中的一个重要动态链接库(DLL),其全称是NT Layer DLL;这个库包含了许多核心的系统服务和API,直接与Windows NT内核交互。此时要想调试自己的程序可以按下f9单步跳过。

转到自身程序后可以看到两个jmp跳转指令,一个是跳转程序中的入口main,另一个是跳转至自定义过程myadd,接着可以按下f7步进继续执行下一步(f7或者f8需要根据自身x64dbg程序的设置使用),进入main入口点,运行指令。

sub rsp,28h
mov qword ptr [rsp + 28h],6
mov qword ptr [rsp + 20h],5
...
寄存器赋值
...
call myadd

接着往下执行,此时我们对rsp进行查看;转到RSP(查看当前栈顶指针的情况);双击堆栈区并且在堆栈区右击,选择转到rsp即可查看当前rsp的情况:

sub rsp, 28h:调整栈指针,预留40字节(0x28)的栈空间,以对齐栈并为局部变量提供空间;运行此步此时RSP应该在$-28位置,

mov qword ptr [rsp + 28h], 6:将第6个参数6保存到栈上的位置[rsp + 28h]

mov qword ptr [rsp + 20h], 5:将第5个参数5保存到栈上的位置[rsp + 20h]

call myadd:调用myadd过程,结果将存储在rax寄存器中,至此因为使用了call命令,则此时会将函数的返回地址也压入栈内,所以此时RSP在$-30的位置。

继续往下运行进入myadd过程:

xor rax, rax:将rax寄存器清零,作为累加器。

add rax, qword ptr [rsp + 30h]:将参数6(存储在[rsp + 30h])加到rax中。

add rax, qword ptr [rsp + 28h]:将参数5(存储在[rsp + 28h])加到rax中。

...

将rcx、rdx、r8、r9寄存器中的值加入rax中

...

得到最后的结果:

接着进行函数返回,回到入口过程中继续运行;

add rsp, 28h:恢复栈指针到调用sub rsp, 28h之前的状态,此时RSP回到最初的位置。

至此dbg结束。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1450869.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

【StableDiffusion】采样方法对比优缺点及评估,采样器 调度器(目前已有的 采样器介绍与评估)

采样器 Sampler 采样方法 决定了 如何从 噪声 生成 图像 的过程,也就是去噪过程如何进行 包含 DPM 的采样方法(逆转扩散采样) DPM → Diffusion Probabilistic Models(扩散概率模型) DPM、DPM2 包含 DPM 的采样方…

解决CentOS的yum命令失效的问题

近日笔者对一台装有 CentOS 7.9 系统的服务器反复折腾,玩到最后发现 yum 命令用不了,总是报下面的错误信息: There was a problem importing one of the Python modules required to run yum. The error leading to this problem was:/usr/l…

C# WPF入门学习主线篇(二十八)—— 使用集合(ObservableCollection)

C# WPF入门学习主线篇(二十八)—— 使用集合(ObservableCollection) 在WPF中,数据绑定是构建动态和响应式用户界面的关键。ObservableCollection是一个特别有用的集合类型,它不仅支持数据绑定,还…

Python | Leetcode Python题解之第150题逆波兰表达式求值

题目: 题解: class Solution:def evalRPN(self, tokens: List[str]) -> int:op_to_binary_fn {"": add,"-": sub,"*": mul,"/": lambda x, y: int(x / y), # 需要注意 python 中负数除法的表现与题目不一…

面试题记录1

题目: 给定一个输入序列01101001101101101找出序列为1101并统计其个数。请用有限状态机(FSM)实现。 解题: 代码: module sequence_detector(input wire clk, // 时钟信号input wire reset, // 复位信号input wir…

JasperReport-报表中文不显示问题解决

在用Jaspersoft Studio进行报表设计的时候默认采用的字体是SansSerif,通过jasperreport的JAVA SDK进行报表输出时就会出现中文不显示问题。另外即便在Jaspersoft Studio设置的是中文字体,通过JAVA端生成也可能出现中文不显示。原因是SDK包中没有包含中文…

Github 2024-06-13开源项目日报Top10

根据Github Trendings的统计,今日(2024-06-13统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Python项目3非开发语言项目2Shell项目1TypeScript项目1Swift项目1PHP项目1Blade项目1JavaScript项目1从零开始构建你喜爱的技术 创建周期:2156…

【单片机毕业设计选题24003】-基于STM32和阿里云的家庭安全监测系统

系统功能: 此设计采用STM32单片机采集环境温湿度,烟雾浓度和一氧化碳浓度显示在OLED上,并将这些信息上报至阿里云平台。 1. 上电连接手机热点后自动连接阿里云,可通过阿里云平台收到系统上报的温湿度,烟雾 浓度,一氧化碳数据以…

日常销售数据分析为什么重要?三个维度全面分析日常销售数据

在当今电子商务的浪潮席卷全球的时代,网店如雨后春笋般涌现,并且竞争日趋激烈。在这样一个充满挑战与机遇的环境中,如何洞察市场动向,把握消费者需求,实现销售业绩的稳步增长,成为每一位电商运营者必须面对…

Jenkins For Windows编译构建C#项目环境搭建(完整版)

安装Jenkins 下载Windows安装包 官方下载地址 选择稳定版,这里下载的是最新版,如需下载指定版本点击 以前的发行版 配置java环境 下载 java jdk 17 jdk17官方下载链接 这里下载的是msi版本的安装包 安装jdk17 双击运行安装包,一直下…

Java | Leetcode Java题解之第150题逆波兰表达式求值

题目&#xff1a; 题解&#xff1a; class Solution {public int evalRPN(String[] tokens) {int n tokens.length;int[] stack new int[(n 1) / 2];int index -1;for (int i 0; i < n; i) {String token tokens[i];switch (token) {case "":index--;stack…

【分布式技术专题】「OceanBase深度解析」 探索OceanBase产品矩阵与核心设计

探索OceanBase产品矩阵与核心设计 OceanBase的六大特性高扩展高可用多租户&#xff08;资源隔离&#xff09;OceanBase架构和功能OceanBase广泛的数据源支持 OceanBase的六大特性 OceanBase以其卓越的产品平台整合方案&#xff0c;充分展现了六大核心特性的卓越与全面。这一方…

PID算法的离散化和参数调节方式的介绍

目录 概述 1 背景介绍 2 数字式 PID 控制算法 2.1 位置式 PID 2.2 增量式 PID 2.3 两种算法比较 3 控制器参数整定 3.1 凑试法 3.2 临界比例法 3.3 经验法 4 参数调整规则的探索 概述 本文主要介绍离散化PID算法的实现原理&#xff0c;以方便对其进行数字化的处理&a…

人工智能将成为数学家的“副驾驶”

人工智能将成为数学家的“副驾驶” 数学传统上是一门独立的科学。1986年&#xff0c;安德鲁怀尔斯为了证明费马定理&#xff0c;退到书房里呆了7年。由此产生的证明往往很难让同事们理解&#xff0c;有些至今仍有争议。但近年来&#xff0c;越来越多的数学领域被严格地分解为各…

Python-json模块

一、相关概念 # 序列号 和反序列号 # 序列号&#xff1a;把内存中的数据类型转成一种特定格式&#xff0c;这种格式&#xff08;json/pickle&#xff09;可以用于存储&#xff0c;或者传输给其他平台 import json # 内存中是数据类型 ----> 序列化 ----> 特定格式&…

RK3568技术笔记六 新建 Ubuntu Linux 虚拟机

VMware 安装完成后&#xff0c;启动 VMware 软件。启动后在 VMware 主界面点击“创建新的虚拟机”。如下图所示&#xff1a; 开始对新建的虚拟机进行设置。选择“自定义”&#xff0c;然后点击“下一步”。如下图所示&#xff1a; 使用默认配置&#xff0c;单击“下一步”。如下…

Python和OpenCV图像分块之图像边长缩小比率是2

import cv2 import numpy as npimg cv2.imread("F:\\mytupian\\xihuduanqiao.jpg") # 低反光 cv2.imshow(image, img) # # 图像分块 # dst np.zeros(img.shape, img.dtype) ratio 2 #图像边长缩小比率是2&#xff0c;也就是一张图片被分割成四份 height, wi…

破解发展难题 台山这家合作社以农业社会化服务助推乡村振兴

风吹稻田千层浪&#xff0c;眼下&#xff0c;台山四九镇的早稻长势喜人&#xff0c;沉甸甸的稻穗迎风而动&#xff0c;已进入破口抽穗的关键期&#xff0c;即将在6月底陆续迎来丰收。在台山市明华汇种养专业合作社管理的稻田里&#xff0c;合作社负责人梁明喜正仔细观察着稻苗的…

docker一些常用命令以及镜像构建完后部署到K8s上

docker一些常用命令以及镜像构建完后部署到K8s上 1.创建文件夹2.删除文件3.复制现有文件内容到新建文件4.打开某个文件5.查看文件列表6.解压文件&#xff08;tar格式&#xff09;7.解压镜像8.查看镜像9.删除镜像10.查看容器11.删除容器12.停止运行容器13.构建镜像14.启动容器15…

MySQL主从复制(六):数据库是否可用

select 1判断 场景示例&#xff1a; -- 设置innodb并发度为3&#xff0c;从而限制并发查询 set global innodb_thread_concurrency3;-- 创建表t CREATE TABLE t (id int(11) NOT NULL,c int(11) DEFAULT NULL,PRIMARY KEY (id) ) ENGINEInnoDB;-- 插入1行数据 insert into t v…