现代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

  1. 启动VS
  2. New Project
  3. Select Console App
  4. Project name:Example1
  5. Solution name:TestSolution
  6. Create
  7. Build>Configuration Manager,choose <Edit...>
  8. select X86, Remove--我的环境是Win32

其次,配置ASM环境的步骤

  1. View>Solution Explorer
  2. rigtht-click Example1 and select Build Denpendencies>Build Customizations
  3. check masm
  4. Add New Item
  5. select .cpp for the file style
  6. Example1_fasm.asm Add

第三步是设置project属性

  1. Example1  and select Properties
  2. All Configurations   All Platforms
  3. C/C++>Code Generation Set to Advanced Vector Extentions(/arch:AVX) or AVX2 or AVX512
  4. C/C++>Output change to Files Assembly Machine and Source Code(/FAcs)
  5. Microsoft Macro Assembler>Listing File  Enable Assembly Generated Code Listing to Yes(/Sg)
  6. Change the Assembled Code Listing File text filed to $(IntDir)\%(filename).lst
  7. Click OK

$(IntDir)\%(filename).lst  --这是1还是L?

最后一步就是写源码了

  1. AppendixA\TestSolution\Example1\Example1.cpp
  2. 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同时运行。慢慢看书了解含义吧,还挺复杂的。

这个例子太高深了,再举个简单的例子,把数组倒序输出。

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

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

相关文章

Python自动化

python操作excel # 安装第三个库 cmd -> pip install xlrb 出现success即安装成功 # 导入库函数 import xlrb # 打开的文件保存为excel文档对象 xlsx xlrb.open_workbook("文件位置") # C:\Users\Adminstator\Desktop\学生版.xlsx # 操作工作簿里的工作表 # 1.…

关于FPGA对 DDR4 (MT40A256M16)的读写控制 I

关于FPGA对 DDR4 &#xff08;MT40A256M16&#xff09;的读写控制 I 语言 &#xff1a;Verilg HDL EDA工具&#xff1a;ISE、Vivado 关于FPGA对 DDR4 &#xff08;MT40A256M16&#xff09;的读写控制 I一、引言二、DDR4的特性&#xff08;MT40A256M16&#xff09;&#xff08;1…

git clone 项目报“鉴权失败”的解决办法

#问题展示# git clone https://gitee.com/soaringsoft/.....git 正克隆到...... Username for https://gitee.com:...... Password for https://.....gitee.com:...... remote: [session-1440f183] Unauthorized fatal: git clone https://gitee.com/soaringsoft/.....gi…

【perfetto分析性能学习笔记】

1.perfetto网站 https://ui.perfetto.dev/ 2.快捷键 3.线程状态分析 Runnable 表示线程正在运行或者等待CPU执行 Runnable (Preempted) 表示线程正在运行&#xff0c;但在运行过程中被其他高优先级线程抢占 Running 表示线程正在运行 Uninterruptible Sleep Uninterru…

ComfyUI-APISR 动漫的超分模型

本文参考 https://github.com/ZHO-ZHO-ZHO/ComfyUI-APISR/tree/main 介绍 APISR&#xff1a;专门用于动漫的超分模型&#xff0c;包含 2x 和 4x 双模型&#xff0c;速度飞快&#xff0c;效果很好。 APISR 模型加载 | &#x1f50e;APISR ModelLoader 支持 2 种官方模型&#…

动态规划、贪心在数组中的应用-334. 递增的三元子序列、300. 最长递增子序列

题目链接及描述 334. 递增的三元子序列 - 力扣&#xff08;LeetCode&#xff09; 300. 最长递增子序列 - 力扣&#xff08;LeetCode&#xff09; 题目分析 300. 最长递增子序列 - 力扣&#xff08;LeetCode&#xff09; 最长递增子序列作为一道经典的动态规划题目&#xff0c…

vue+elementplus模拟“山野愚人居”简单实现个人博客

目录 一、项目介绍 二、项目截图 1.项目结构图 2.项目首页 3.文章详情 4.留言 5.读者 三、源码实现 1.项目依赖package.json 2.项目启动 3.读者页面源码 四、总结 一、项目介绍 模仿原博客&#xff1a;山野愚人居 - 记录我的生活、所见、所闻、所想…… 本项目参考以…

UITableView初识之分组显示数据Demo

基本介绍 继承自UIScrollView&#xff0c;因此可以滚动。 需要Datasource 遵循UITableViewDataSource协议的OC对象&#xff0c;都可以是UITableView的数据源&#xff0c;该协议中的方法告诉UITableView如何显示数据。 关于UITableView UITableView显示分组数据&#xff0c;对应…

企事业单位安全生产月活动怎样向媒体投稿?

作为一名单位的信息宣传员,我肩负着将每一次重要活动的精彩瞬间转化为文字,向外界传递我们单位声音的重任。初入此行时,我满怀热情,坚信通过传统的方式——电子邮件投稿,能够有效地将我们的故事传播出去。然而,现实却给我上了生动的一课。 记得在筹备“安全生产月”活动的宣传时…

韩顺平0基础学java——第21天

p430-440 enum昨日剩余 enum常用方法&#xff1a; 1.toString已经重写过了&#xff0c;返回的是当前对象名。子类可以重写 2.name&#xff1a;返回当前对象名&#xff08;常量名&#xff09;&#xff0c;子类中不能重写 3.ordinal&#xff1a;返回当前对象的位置号。默认从…

妙用OSGraph:发掘GitHub知识图谱上的开源故事

作者&#xff1a;范志东 1. 何为OSGraph&#xff1f; OSGraph (Open Source Graph) 是一个开源图谱关系洞察工具&#xff0c;基于GitHub开源数据全域图谱&#xff0c;实现开发者行为、项目社区生态的分析洞察。可以为开发者、项目Owner、开源布道师、社区运营等提供简洁直观的…

时序分解 | Matlab实现SCSSA-VMD融合正余弦和柯西变异的麻雀搜索算法优化变分模态分解时间序列信号分解

时序分解 | Matlab实现SCSSA-VMD融合正余弦和柯西变异的麻雀搜索算法优化变分模态分解时间序列信号分解 目录 时序分解 | Matlab实现SCSSA-VMD融合正余弦和柯西变异的麻雀搜索算法优化变分模态分解时间序列信号分解效果一览基本介绍程序设计参考资料 效果一览 基本介绍 Matlab…

曲线拟合 | 二次B样条拟合曲线

B 样条曲线拟合实例&#xff1a;能平滑化曲线 1. 实例1 为MASS包中mcycle数据集。它测试了一系列模拟的交通车事故中&#xff0c;头部的加速度&#xff0c;以此来评估头盔的性能。times为撞击时间(ms)&#xff0c;accel为加速度&#xff08;g&#xff09;。首先导入数据&#…

Docker(一)-认识Docker

1.docker理念 Docker是基于Go语言实现的云开源项目。 Docker的主要目标是“Build,Ship and Run Any App,Anywhere”&#xff0c;也就是通过对应用组件的封装&#xff0c;分发&#xff0c;部署&#xff0c;运行等生命周期的管理&#xff0c;使用户的应用及其运行环境能够做到”…

论文阅读:H-ViT,一种用于医学图像配准的层级化ViT

来自CVPR的一篇文章&#xff0c;https://openaccess.thecvf.com/content/CVPR2024/papers/Ghahremani_H-ViT_A_Hierarchical_Vision_Transformer_for_Deformable_Image_Registration_CVPR_2024_paper.pdf 用CNNTransformer混合模型做图像配准。可变形图像配准是一种在相同视场…

奇思妙想:多头RAG

大模型技术论文不断&#xff0c;每个月总会新增上千篇。本专栏精选论文重点解读&#xff0c;主题还是围绕着行业实践和工程量产。若在某个环节出现卡点&#xff0c;可以回到大模型必备腔调或者LLM背后的基础模型新阅读。而最新科技&#xff08;Mamba,xLSTM,KAN&#xff09;则提…

c语言利用openssl实现简单客户端和服务端(观察记录层最大长度)

文章目录 前言一、客户端实现二、服务端实现总结 前言 本文是使用openssl111w实现的简单客户端和服务端&#xff0c;主要用于观察openssl一个记录层数据包的大小。 一、客户端实现 #include <stdio.h> #include <stdlib.h> #include <string.h> #inc…

bugku---misc---赛博朋克

1、下载附件解压之后是一个txt文本&#xff0c;查看文本的时候看到头部有NG的字样 2、把txt改为png后缀得到一张图片 3、binwalk没发现奇怪的地方&#xff0c;分离出来还是图片 4、stegslove分析&#xff0c;切换图片没有发现奇怪地方 5、将通道rgb置为0。出现了flag但是flag不…

6.13长难句打卡

Hard times may hold you down at what usually seems like the most inopportune time, but you should remember that they won’t last forever. 艰难时刻可能会在你最不顺心的时刻让你低迷&#xff0c;但请相信&#xff0c;它们不会永远持续下去。

179.二叉树:合并二叉树(力扣)

代码解决 /*** 二叉树节点的定义。* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}* TreeNode(int x, Tre…