汇编:内联汇编和混合编程

C/C++内联汇编

C/C++ 内联汇编(Inline Assembly)是一种在C或C++代码中嵌入汇编语言指令的方法,以便在不离开C/C++环境的情况下利用汇编语言的优势进行性能优化或执行特定的硬件操作。以下是一些详细的说明和示例,展示如何在C和C++代码中使用内联汇编:

创建新的控制台项目,将C/C++代码生成的运行库更换为多线程调试(/MTD)。在C++开发中,运行库(Runtime Library)是执行程序时所依赖的库,它提供了标准C和C++函数的实现,如输入输出、内存管理等。MTD(Multi-Threaded Debug):静态链接。程序在编译时将运行库静态地嵌入到可执行文件中,生成一个独立的可执行文件;除此之外还要确保同窗口下的Spectre缓解被禁用;

设置完成后就可在C/Cpp源代码文件中进行代码编写,以下是一个简单示例(脱裤子放屁版):

代码示例展示了在C++程序中使用内联汇编来调用一个C++函数,并将结果存储在一个全局变量中,这种方法展示了如何在内联汇编中传递参数并调用C++函数。

#include <iostream>
​
int nNumber = 20;
int myadd(int a, int b) {return a + b;
}
​
int main()
{__asm {xor eax,eaxmov eax,nNumberpush eaxxor eax,eaxmov eax,10push eaxcall myaddmov nNumber,eaxadd esp,8}std::cout << nNumber << std::endl;
}
内联汇编代码

寄存器初始化和使用

  • xor eax, eax 将EAX寄存器置0,这是一种常见的快速清零方式。

  • mov eax, nNumber 将全局变量 nNumber 的值移动到EAX寄存器中。

  • push eax 将EAX的值压入堆栈,这是函数调用约定的一部分,用于传递参数。

参数传递和函数调用

  • mov eax, 10 将立即数10移动到EAX寄存器中。

  • push eax 将EAX的值压入堆栈。这两个 push 操作将参数 nNumber10 压入堆栈,顺序为右到左,即 myadd(10, nNumber)

  • call myadd 调用 myadd 函数,函数的返回值将存储在EAX寄存器中。

结果处理和堆栈恢复

  • mov nNumber, eax 将函数 myadd 的返回值赋值给全局变量 nNumber

  • add esp, 8 恢复堆栈指针,这是为了平衡 push 操作,8 字节是两个 int 参数的大小。

运行后的结果:

C/C++&汇编混合编程

x64架构程序不适配上述内联汇编的语法,将debug改为x64再重新生成该代码会发现报错:

那么在x64架构下,若是需要在C或C++代码中嵌入汇编语言指令,可以使用混合编程的方式进行代码嵌入;混合编程(Mixed Programming)是指在一个软件项目中结合使用多种编程语言或编程范式,以便利用各自的优势来实现更高效、更灵活的应用。

首先需要在C/C++源码文件下创建.asm文件,接着将我们需要用到的汇编代码写入.asm文件中,接着需要在C/C++源码中对需要用到的汇编代码(过程)进行声明即可;以下是一个简单的示例:

项目文件
source.asm      MixCode.cpp     
source.asm代码:

实现了一个简单的加法函数myadd,接受两个参数,将它们相加,并返回结果。

.code
myadd procxor rax,raxsub rsp,28hadd rax,rdxadd rax,rcxadd rsp,28h
myadd endp
end
代码解释:

xor rax, rax 是一种快速清零寄存器 RAX 的方式。

sub rsp, 28h 调整栈指针 rsp,为函数调用创建一个栈帧,在64位模式下,栈需要16字节对齐,这里调整40字节以对齐栈。

add rax, rdx 将第一个参数(RDX 寄存器中的值)加到 RAX 中。

add rax, rcx 将第二个参数(RCX 寄存器中的值)加到 RAX 中。

add rsp, 28h 恢复栈指针 rsp,撤销之前的调整。

ret 指令从函数返回,将控制转移回调用点。

MixCode.cpp代码:
#include <iostream>
​
int nNumber = 20;
​
extern "C" long long myadd(long long llNumber_A, long long llNumberB); //声明函数
​
int main()
{long long resNumber = myadd(nNumber, 10);std::cout << resNumber << std::endl;system("pause");
}
C++和汇编的集成

变量声明int nNumber = 20; 声明了一个全局变量 nNumber,初始值为20。

外部函数声明extern "C" long long myadd(long long llNumber_A, long long llNumber_B); 告诉编译器 myadd 是一个C函数(使用C的调用约定),并接受两个long long参数,返回一个long long值。

调用汇编函数long long resNumber = myadd(nNumber, 10); 调用 myadd 函数,传入 nNumber10,将返回值赋给 resNumber

输出结果std::cout << resNumber << std::endl; 输出结果到控制台。

程序执行结果:

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

c++ 中 namespace包的 全局变量 c++ 中 static 全局变量 会给初值吗

在 C 中&#xff0c;命名空间&#xff08;namespace&#xff09;中的全局变量会被自动初始化为零值&#xff08;zero-initialized&#xff09;&#xff0c;除非显式地为其指定初始值。与静态全局变量类似&#xff0c;命名空间中的全局变量在程序启动时会被初始化&#xff0c;其…

zookeeper介绍 和 编译踩坑

zookeeper 分布式协调服务 ZooKeeper原理及介绍 - 鹿泉 - 博客园 Zookeeper是在分布式环境中应用非常广泛&#xff0c;它的优秀功能很多&#xff0c;比如分布式环境中全局命名服务&#xff0c;服务注册中心&#xff0c;全局分布式锁等等。 本项目使用其分布式服务配置中心&am…

Java:访问权限修饰符

文章目录 一、访问权限修饰符二、权限修饰符的分类 一、访问权限修饰符 访问权限修饰符&#xff0c;就是控制类中的属性和方法的被访问范围。 二、权限修饰符的分类 作用范围&#xff1a;private < 空着不写 < protected < public 修饰符同类同包不同类不同包下子类…

Minecraft模组开发(fabric)之准备工作

Minecraft模组开发&#xff08;fabric&#xff09;之准备工作 最近心血来潮想开发个Minecraft的模组&#xff0c;一边学习一边开发&#xff0c;顺带着将一些步骤、学习心得整理下来。之所以选择fabric&#xff0c;是因为自己的光影包使用的是iris-fabric&#xff0c;所以就想着…

深度学习-使用 Bash 脚本

在深度学习领域&#xff0c;Bash 脚本通常用于管理和自动化训练模型、数据预处理、后处理以及环境设置等任务。虽然 Bash 脚本本身并不直接参与深度学习的计算&#xff0c;但它在简化工作流程和提高效率方面扮演着重要角色。以下是一些使用 Bash 脚本的理由&#xff1a; 自动化…

Vue41-vc实例与vm实例

一、 vc实例与vm实例的区别 vc实例与vm实例&#xff0c;99%结构都是类似的&#xff0c;仅2点不同&#xff1a; el属性data的书写格式 1-1、 el属性 vc有的功能vm都有&#xff0c;但是vm能通过el决定为哪个容器服务&#xff0c;但是vc却不行&#xff01; 1-2、data的书写格式

【PythonCode】力扣Leetcode26~30题Python版

【PythonCode】力扣Leetcode26~30题Python版 前言 力扣Leetcode是一个集学习、刷题、竞赛等功能于一体的编程学习平台&#xff0c;很多计算机相关专业的学生、编程自学者、IT从业者在上面学习和刷题。 在Leetcode上刷题&#xff0c;可以选择各种主流的编程语言&#xff0c;如C…

XML 编辑器:功能、选择与使用技巧

XML 编辑器&#xff1a;功能、选择与使用技巧 简介 XML&#xff08;可扩展标记语言&#xff09;是一种用于存储和传输数据的标记语言。由于其灵活性和广泛的应用&#xff0c;XML编辑器成为开发者、数据管理者和内容创作者的重要工具。本文将探讨XML编辑器的功能、选择标准以及…

python,django好的get和post请求

获得get请求 df request.GET.get("dades")获得post请求 文件settings.py关闭csrf MIDDLEWARE [ ‘django.middleware.security.SecurityMiddleware’, ‘django.contrib.sessions.middleware.SessionMiddleware’, ‘django.middleware.common.CommonMiddleware’…

简单的Scikit-Learn入门示例

以下是一个简单的Scikit-Learn入门示例&#xff0c;该示例使用鸢尾花&#xff08;Iris&#xff09;数据集来演示分类问题的基本步骤。这个数据集包含了150个样本&#xff0c;每个样本有四个特征&#xff08;花萼长度、花萼宽度、花瓣长度、花瓣宽度&#xff09;&#xff0c;以及…

unity38——MemoryProfiler性能分析器,截帧分析当前性能占用率的具体文件

定义&#xff1a;性能分析器 (Unity Profiler) 是一种可以用来获取应用程序性能信息的工具。可以将性能分析器连接到网络中的设备或连接到已连接到计算机的设备&#xff0c;从而测试应用程序在目标发布平台上的运行情况。还可以在 Editor 中运行性能分析器&#xff0c;从而在开…

高精度减法的实现

这是C算法基础-基础算法专栏的第八篇文章&#xff0c;专栏详情请见此处。 引入 上次我们学习了高精度加法的实现&#xff0c;这次我们要学习高精度减法的实现。 高精度减法与高精度加法的定义、前置过程都是大致相同的&#xff0c;如果想了解具体内容&#xff0c;可以移步至我的…

显著提高iOS应用中Web页面的加载速度 - 提前下载页面的关键资源(如JavaScript、CSS和图像)

手动下载并缓存资源是一种有效的方式&#xff0c;可以确保在需要时资源已经在本地存储&#xff0c;这样可以显著提高加载速度。 缓存整个 web 页面的所有资源文件 具体实现步骤 下载和缓存资源&#xff1a;包括 HTML 文件、CSS、JavaScript 和图像。在应用启动时预加载资源。…

实现搜索功能中搜索内容高亮效果,本文通过fuzzysort库方案实现

目录 一&#xff1a;fuzzysort1.fuzzysort 介绍&#xff1a;2.需求所用方法介绍:gohighlight 3.效果实现 一&#xff1a;fuzzysort 1.fuzzysort 介绍&#xff1a; fuzzysort 是一个 JavaScript 库&#xff0c;用于对字符串数组进行模糊搜索和排序。它特别适用于自动补全&#…

Docker安装Nginx(各种错误版)

Docker安装-CSDN博客 安装启动Docker之后 docker run -d -p 81:81 --name nginx nginx 这样没有指定版本 docker run&#xff1a;启动一个新的容器。-d&#xff1a;以分离模式运行容器&#xff08;后台运行&#xff09;。-p 81:81&#xff1a;将主机的 81 端口映射到容器的 …

Pandoc工具笔记总结

1. 安装 参考&#xff1a; https://zhuanlan.zhihu.com/p/612355849 http://t.csdnimg.cn/WABXA 2. 必备工具说明 pandoc&#xff1a;用来转换格式&#xff0c;务必下载3.1版本&#xff0c;https://pandoc.org/installing.html pandoc-crossref&#xff1a;一个用于 Pand…

【网络安全学习】使用Kali做渗透情报收集-01-<域名信息主机信息>

1.收集开源情报 开源情报(Open Source Intelligence&#xff0c;OSINT)是指从各种公开的渠道中寻找和获取有价值的信息 如&#xff1a;互联网、媒体、社交网络、公共数据库等开源情报具有以下特点&#xff1a; - 丰富性&#xff1a;开源情报涵盖了各种类型和领域的信息 - 可…

Linux---系统的初步学习【项目一:Linux操作系统的安装与配置】

项目一 Linux操作系统的安装与配置 1.1 项目知识准备 1.1.1 操作系统是什么&#xff1f; ​ 操作系统&#xff08;Operating System&#xff0c;OS&#xff09;是管理计算机硬件与软件资源的计算机程序。操作系统需要处理如管理硬件、决定程序运行的优先次序、管理文件系统等…

WPF中的隧道路由和冒泡路由事件

文章目录 简介&#xff1a;一、事件最基本的用法二、理解路由事件 简介&#xff1a; WPF中使用路由事件升级了传统应用开发中的事件&#xff0c;在WPF中使用路由事件能更好的处理事件相关的逻辑&#xff0c;我们从这篇开始整理事件的用法和什么是直接路由&#xff0c;什么是冒…

HTML基础标签解析:H1-H6、DIV与P的正确使用方法

在网页设计与开发中&#xff0c;HTML&#xff08;HyperText Markup Language&#xff0c;超文本标记语言&#xff09;是最为基础也是最为重要的组成部分之一。它定义了网页的内容结构和意义&#xff0c;使得浏览器能够正确地解析并展示网页给用户。本文将重点介绍HTML中的标题标…