现代X86汇编-C和ASM混合编程举例
端午假期安装好了vs c++2022,并写了个简单的汇编代码,证明MASM真的可以运行。今天需要搞一个实实在在的C++和ASM混合编程的例子,因为用纯汇编的求伯君写WPS的时代一去不复返了。个别关键函数用汇编,充分发挥CPU的特色功能,偶尔还是需要的。
昨天找的随书代码的位置在github上:GitHub - Apress/modern-x86-assembly-language-programming-3e: Source Code for 'Modern X86 Assembly Language Programming' by Daniel Kusswurm
这是第三版,最新的书。又从z-liabrary上下载了这本英文书,导入微信读书,自动翻译为中文,z-libary加微信读书,使我实现了读书ziyou(啥时候财务ziyou,还远)。
这本书的附录A就举了怎样在vs2022环境建立一个C++加ASM的例子,今天咱们就逐步跟着书上学这个例子。
首先创建project
• Create a C++ project• Enable MASM support• Add an assembly language file• Set project properties•Edit the source code• Build and run the project
- 启动VS
- New Project
- Select Console App
- Project name:Example1
- Solution name:TestSolution
- Create
- Build>Configuration Manager,choose <Edit...>
- select X86, Remove--我的环境是Win32
其次,配置ASM环境的步骤:
- View>Solution Explorer
- rigtht-click Example1 and select Build Denpendencies>Build Customizations
- check masm
- Add New Item
- select .cpp for the file style
- Example1_fasm.asm Add
第三步是设置project属性
- Example1 and select Properties
- All Configurations All Platforms
- C/C++>Code Generation Set to Advanced Vector Extentions(/arch:AVX) or AVX2 or AVX512
- C/C++>Output change to Files Assembly Machine and Source Code(/FAcs)
- Microsoft Macro Assembler>Listing File Enable Assembly Generated Code Listing to Yes(/Sg)
- Change the Assembled Code Listing File text filed to $(IntDir)\%(filename).lst
- Click OK
$(IntDir)\%(filename).lst --这是1还是L?
最后一步就是写源码了
- AppendixA\TestSolution\Example1\Example1.cpp
- AppendixA\TestSolution\Example1\Example1_fasm.asm
Example1.cpp
#include <iostream>
#include <iomanip>
#include <string>
#include <cmath>extern "C" void CalcZ_avx(float* z, const float* x, const float* y, size_t n);static void CalcZ_cpp(float* z, const float* x, const float* y, size_t n)
{for (size_t i = 0; i < n; i++)z[i] = x[i] + y[i];
}int main(void)
{constexpr size_t n = 20;float x[n], y[n], z1[n], z2[n];// Initialize the data arraysfor (size_t i = 0; i < n; i++){x[i] = i * 10.0f + 10.0f;y[i] = i * 1000.0f + 1000.0f;z1[i] = z2[i] = 0.0f;}// Exercise the calculating functionsCalcZ_cpp(z1, x, y, n);CalcZ_avx(z2, x, y, n);// Display the resultsconstexpr char nl = '\n';constexpr size_t w = 10;constexpr float eps = 1.0e-6f;std::cout << std::fixed << std::setprecision(1);std::cout << std::setw(w) << "i";std::cout << std::setw(w) << "x";std::cout << std::setw(w) << "y";std::cout << std::setw(w) << "z1";std::cout << std::setw(w) << "z2" << nl;std::cout << std::string(50, '-') << nl;for (size_t i = 0; i < n; i++){std::cout << std::setw(w) << i;std::cout << std::setw(w) << x[i];std::cout << std::setw(w) << y[i];std::cout << std::setw(w) << z1[i];std::cout << std::setw(w) << z2[i] << nl;if (fabs(z1[i] - z2[i]) > eps){std::cout << "Compare error!\n";break;}}}
Example1_fasm.asm
;------------------------------------------------------------------------------
; Example1_fasm.asm
;------------------------------------------------------------------------------;------------------------------------------------------------------------------
; void CalcZ_avx(float* z, const float* x, const float* x, size_t n);
;------------------------------------------------------------------------------NSE equ 8 ;num_simd_elements
SF equ 4 ;scale factor for F32.code
CalcZ_avx proc; Validate argumentstest r9,r9 ;n == 0?jz Done ;jump if yes; Initializemov rax,-SF ;rax = array offset (Loop2)cmp r9,NSE ;n < NSE?jb Loop2 ;jump if yesmov rax,-NSE*SF ;rax = array offset (Loop1); Calculate z[i:i+7] = x[i:i+7] + y[i:i+7]
Loop1: add rax,NSE*SF ;update array offsetvmovups ymm0,ymmword ptr [rdx+rax] ;ymm0 = x[i:i+7]vmovups ymm1,ymmword ptr [r8+rax] ;ymm1 = y[i:i+7]vaddps ymm2,ymm0,ymm1 ;z[i:i+7] = x[i:i+7] + y[i:i+7]vmovups ymmword ptr [rcx+rax],ymm2 ;save z[i:i+7]sub r9,NSE ;n -= NSEcmp r9,NSE ;n >= NSE?jae Loop1 ;jump if yestest r9,r9 ;n == 0?jz Done ;jump if yesadd rax,NSE*SF-SF ;adjust array offset for Loop2; Calculate z[i] = x[i] + y[i] for remaining elements
Loop2: add rax,SF ;update array offsetvmovss xmm0,real4 ptr [rdx+rax] ;xmm0 = x[i]vmovss xmm1,real4 ptr [r8+rax] ;xmm1 = y[i]vaddss xmm2,xmm0,xmm1 ;z[i] = x[i] + y[i]vmovss real4 ptr [rcx+rax],xmm2 ;save z[i]sub r9,1 ;n -= 1jnz Loop2 ;repeat until doneDone: vzeroupperret ;return to caller
CalcZ_avx endpend
最终构建运行即可
代码有点高大上,估计是用了AVX,两个loop同时运行。慢慢看书了解含义吧,还挺复杂的。
这个例子太高深了,再举个简单的例子,把数组倒序输出。
相关文章:

现代X86汇编-C和ASM混合编程举例
端午假期安装好了vs c2022,并写了个简单的汇编代码,证明MASM真的可以运行。今天需要搞一个实实在在的C和ASM混合编程的例子,因为用纯汇编的求伯君写WPS的时代一去不复返了。个别关键函数用汇编,充分发挥CPU的特色功能,偶尔还是需要…...
485. 最大连续 1 的个数
给定一个二进制数组 nums , 计算其中最大连续 1 的个数。 示例 1: 输入:nums [1,1,0,1,1,1] 输出:3 解释:开头的两位和最后的三位都是连续 1 ,所以最大连续 1 的个数是 3.示例 2: 输入:nums […...

席卷的B站《植物大战僵尸杂交版》V2.0.88整合包,PC和手机可用,含通关存档和视频教程!
今天给大家安利一款席卷B站,火爆全网的游戏——《植物大战僵尸杂交版》2.0.88整合包。 这个是网络上现存植物大战僵尸杂交版的最全整合,包含了修改工具,超强通关存档和高清工具。工具包有安装视频教程,支持手机版和pc多端使用&am…...

液晶拼接屏企业应该采取哪些措施来提升整体竞争力和市场地位呢?
步入智能科技时代以来,商显行业面对着各式各样的挑战,人工智能、AI大模型等整合中,液晶拼接屏企业应该采取哪些措施以提升整体竞争力和市场地位。下面小编个人观点简单说一下;下是一些关键的措施: 首先,加…...

PHP在线生成查询产品防伪证书系统源码
源码介绍 PHP在线生成查询产品防伪证书系统源码,源码自带90套授权证书模板,带PSD公章模板,证书PSD源文件。 环境要求:PHPMYSQL,PHP 版本请使用PHP5.1 ~5.3。 图片截图 源码安装说明 1.上传所有文件至你的空间服务器…...

遥控玩具车电机驱动应用中的双H桥驱动芯片
遥控玩具车的基本工作原理是通过无线电遥控器发送信号,这些信号被玩具车内的接收器接收并解码,从而控制玩具车的运行。根据车身外型的不同,可以分为:普通的私家房车、越野车、货柜车、翻斗车等等。遥控器的操作,如前进…...

Linux 基本指令1
ls指令 ls【-选项】【目录或文件】当不指定目录或文件时指令能列出当前目录下所有文件除隐藏文件 选项: -a 列出所有包括隐藏的文件-隐藏文件以.开头。 -d 将目录如文件般显示-一般用ls显示目录是显示其目录中所有文件,加-d则显示目录的信息 -r 以反…...

基于Seatunnel最新2.3.5版本分布式集群安装部署指南(小白版)
基于Seatunnel2.3.5版本分布式集群安装部署 1.环境准备2.JDK安装3.Maven安装4.Seatunnel在master节点安装部署配置4.1.下载Seatunnel安装包4.2.解压下载好的tar.gz包4.3.下载连接器4.4.配置Seatunnel的系统环境变量4.5.配置 SeaTunnel Engine服务 JVM参数4.6.配置文件中集群相关…...

SSM小区疫情防控系统-计算机毕业设计源码03748
摘 要 随着社会的发展,社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 小区疫情防控系统,主要的模块包括查看首页、轮播图(轮播图管理)、社区公告管理(社区公告&#…...
英伟达算法岗面试,问的贼专业。。。
节前,我们星球组织了一场算法岗技术&面试讨论会,邀请了一些互联网大厂朋友、参加社招和校招面试的同学。 针对算法岗技术趋势、大模型落地项目经验分享、新手如何入门算法岗、该如何准备、面试常考点分享等热门话题进行了深入的讨论。 合集&#x…...
GIS之arcgis系列09:arcpy实现克里金差值
矢量点数据经过克里金差值后可以转换成栅格数据,那么就需要了解一下什么是克里金差值。 什么是克里金法? IDW(反距离加权法)和样条函数法插值工具被称为确定性插值方法,因为这些方法直接基于周围的测量值或确定生成表面的平滑度的指定数学公式。第二类…...

MySQL的group by与count(), *字段使用问题
文章目录 问题group by到底做了什么举个例子简单来说为什么select字段,count()不能和*共同使用总结 问题 这是一段摘抄自MySQL官网的文字。其大致意思是MySQL拓展了group by的使用,MySQL允许选择没有出现在group by中的字段。换句话说,标准SQ…...

Java——面向对象进阶(二)
前言: 多态,包,final关键字,权限修饰符和代码块 文章目录 一、多态1.1 概念1.2 多态存在条件1.3 多态中调用成员的特点1.4 instanceof关键字 二、包三、权限修饰符四、final 关键字4.1 修饰类4.2 修饰方法4.3 修饰变量 五、代码块…...

49.Python-web框架-Django解决多语言redirect时把post改为get的问题
目录 1.背景 2.思路 3.寻找 Find and Replace 4.再次运行程序,POST来了 5.小结 1.背景 昨天在练习一个Django功能时,把form的method设置为POST,但是实际提交时,一直是GET方法。最后发现这是与多语言相关,django前面…...

【数据结构】【版本1.1】【线性时代】——单链表
快乐的流畅:个人主页 个人专栏:《算法神殿》《数据结构世界》《进击的C》 远方有一堆篝火,在为久候之人燃烧! 文章目录 引言一、顺序表的问题二、链表的概念三、单链表的模拟实现3.1 定义3.2 打印3.3 创建新节点3.4 头插3.5 尾插3…...

【计算机毕业设计】258基于微信小程序的课堂点名系统
🙊作者简介:拥有多年开发工作经验,分享技术代码帮助学生学习,独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。🌹赠送计算机毕业设计600个选题excel文件,帮助大学选题。赠送开题报告模板ÿ…...
common.js和es6中模块引入的区别
common.js CommonJS 是一种模块系统,主要用于 Node.js 环境。它使用 require 函数来引入模块,并使用 module.exports 来导出模块。 语法: 导出模块: // moduleA.js const name Jo; module.exports name;// 或者导出一个对象…...

关于对pagination.js源代码进行修改且引入项目使用
实现效果 使用定时器对组件进行每秒请求,每过固定时间之后,进行下一页项目请求,进行到最后一页请求的时候返回第一页。 首先引入js插件 <script src"./js/pagination.js" type"text/javascript"></script>…...
《思考总结》
思考总结 ==标题==:卷积操作的作用1. **特征提取**2. **参数共享**3. **降维和数据压缩**4. **提升计算效率**5. **平滑和去噪**卷积操作示例输入图像卷积核卷积过程总结==标题==:上卷积什么是上卷积(反卷积/转置卷积)上卷积的作用上卷积的实现1. **最近邻插值(Nearest Ne…...

使用QT绘制简单的动态数据折线图
两个核心类时QChart和QLineSeries 下面这个示例代码中,定时器每隔一段时间将曲线图中的数据点向右移动 一个单位,同时调整横坐标轴的范围,实现了一次滚动对应移动一个数据点的效果。 QLineSeries最多容纳40961024个点 #include <QtWidg…...
【Linux】shell脚本忽略错误继续执行
在 shell 脚本中,可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行,可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令,并忽略错误 rm somefile…...

MFC内存泄露
1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...

基于Flask实现的医疗保险欺诈识别监测模型
基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施,由雇主和个人按一定比例缴纳保险费,建立社会医疗保险基金,支付雇员医疗费用的一种医疗保险制度, 它是促进社会文明和进步的…...
鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/
使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题:docker pull 失败 网络不同,需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...

深度学习水论文:mamba+图像增强
🧀当前视觉领域对高效长序列建模需求激增,对Mamba图像增强这方向的研究自然也逐渐火热。原因在于其高效长程建模,以及动态计算优势,在图像质量提升和细节恢复方面有难以替代的作用。 🧀因此短时间内,就有不…...

【Linux手册】探秘系统世界:从用户交互到硬件底层的全链路工作之旅
目录 前言 操作系统与驱动程序 是什么,为什么 怎么做 system call 用户操作接口 总结 前言 日常生活中,我们在使用电子设备时,我们所输入执行的每一条指令最终大多都会作用到硬件上,比如下载一款软件最终会下载到硬盘上&am…...
第八部分:阶段项目 6:构建 React 前端应用
现在,是时候将你学到的 React 基础知识付诸实践,构建一个简单的前端应用来模拟与后端 API 的交互了。在这个阶段,你可以先使用模拟数据,或者如果你的后端 API(阶段项目 5)已经搭建好,可以直接连…...
规则与人性的天平——由高考迟到事件引发的思考
当那位身着校服的考生在考场关闭1分钟后狂奔而至,他涨红的脸上写满绝望。铁门内秒针划过的弧度,成为改变人生的残酷抛物线。家长声嘶力竭的哀求与考务人员机械的"这是规定",构成当代中国教育最尖锐的隐喻。 一、刚性规则的必要性 …...
CppCon 2015 学习:Time Programming Fundamentals
Civil Time 公历时间 特点: 共 6 个字段: Year(年)Month(月)Day(日)Hour(小时)Minute(分钟)Second(秒) 表示…...

数据结构:泰勒展开式:霍纳法则(Horner‘s Rule)
目录 🔍 若用递归计算每一项,会发生什么? Horners Rule(霍纳法则) 第一步:我们从最原始的泰勒公式出发 第二步:从形式上重新观察展开式 🌟 第三步:引出霍纳法则&…...