现代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.rhkb.cn/news/349599.html

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

相关文章

关于RDMA传输的基本流量控制

Basic flow control for RDMA transfers | The Geek in the Corner (wordpress.com) 名词解释 IB &#xff1a; InfiniBand的缩写&#xff0c;指的就是InfiniBand技术。 MAD &#xff1a; Management Datagram的缩写。MAD是InfiniBand架构中用于设备管理和配置的一种特殊消息…

用数据说话,效果好上一万倍,不是空口说白话的“好很多”

作为一名大数据开发者&#xff0c;我深知数据的有很大的魔力&#xff08;我这句话就没用数据&#xff0c;听上去很无力&#xff09;。数据不仅仅是数字和图表&#xff0c;它还能赋予我们强大的说服力和权威感。让我给你详细讲讲数据如何让理论插上翅膀。 目录 数据的“靠谱”…

关于dwarf 中 DW_AT_data_member_location 的理解

1、用python elftool解析结构体的时候&#xff0c;成员偏移量存在DW_AT_data_member_location字段解析&#xff1b;此字段是可变长的&#xff08;uleb128编码&#xff09;&#xff1b; 第一个字节是操作码 后续是偏移量 uleb128编码&#xff0c;正如其名&#xff0c;是小端结尾…

【权威出版/投稿优惠】2024年智慧城市与信息化教育国际会议(SCIE 2024)

2024 International Conference on Smart Cities and Information Education 2024年智慧城市与信息化教育国际会议 【会议信息】 会议简称&#xff1a;SCIE 2024 大会时间&#xff1a;点击查看 大会地点&#xff1a;中国北京 会议官网&#xff1a;www.iacscie.com 会议邮箱&am…

BIO、NIO编程与直接内存、零拷贝

Socket Socket是应用层与TCP/IP协议族通信的中间软件抽象层&#xff0c;它是一组接口&#xff0c;其实就是一个门面模式。 本质上就是操作系统提供的一系列的API 网络通信编程基本常识 服务端、客户端、通信编程关注的三件事 连接&#xff08;客户端连接服务器&#xff0c;服务…

Python自动化

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

提升你的编程体验:自定义 PyCharm 背景图片

首先&#xff0c;打开 PyCharm 的设置菜单&#xff0c;点击菜单栏中的 File > Settings 来访问设置&#xff0c;也可以通过快捷键 CtrlAItS 打开设置。 然后点击Appearance & Behavior > Appearance。 找到Background image...左键双击进入。 Image:传入自己需要设置…

Golang的GC

目录 介绍GC 概要 什么是根对象 三色标记法 什么情况下三色标记法会失效 屏障机制 “强-弱” 三色不变式 插入屏障 (强三色) 删除屏障(弱三色) Go 的混合写屏障机制 混合写屏障规则 介绍GC 概要 作用范围&#xff1a;只回收堆内存&#xff0c;不回收栈内存&#xf…

list容器的基本使用

目录 前言一&#xff0c;list的介绍二&#xff0c;list的基本使用2.1 list的构造2.2 list迭代器的使用2.3 list的头插&#xff0c;头删&#xff0c;尾插和尾删2.4 list的插入和删除2.5 list 的 resize/swap/clear 前言 list中的接口比较多&#xff0c;与string和vector类似&am…

【Pytorch】一文向您详细介绍 torch.nn.DataParallel() 的作用和用法

【Pytorch】一文向您详细介绍 torch.nn.DataParallel() 的作用和用法 下滑查看解决方法 &#x1f308; 欢迎莅临我的个人主页 &#x1f448;这里是我静心耕耘深度学习领域、真诚分享知识与智慧的小天地&#xff01;&#x1f387; &#x1f393; 博主简介&#xff1a;985高…

Mysql学习(九)——存储引擎

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 七、存储引擎7.1 MySQL体系结构7.2 存储引擎简介7.3 存储引擎特点7.4 存储引擎选择7.5 总结 七、存储引擎 7.1 MySQL体系结构 连接层&#xff1a;最上层是一些客户…

SpringBoot之请求映射原理

前言 我们发出的请求&#xff0c;SpringMVC是如何精准定位到那个Controller以及具体方法&#xff1f;其实这都是 HandlerMapping 发挥的作用&#xff0c;这篇博文我们以 RequestMappingHandlerMapping 为例并结合源码一步步进行分析。 定义HandlerMapping 默认 HandlerMappi…

Java 反射机制 -- Java 语言反射的概述、核心类与高级应用

大家好,我是栗筝i,这篇文章是我的 “栗筝i 的 Java 技术栈” 专栏的第 010 篇文章,在 “栗筝i 的 Java 技术栈” 这个专栏中我会持续为大家更新 Java 技术相关全套技术栈内容。专栏的主要目标是已经有一定 Java 开发经验,并希望进一步完善自己对整个 Java 技术体系来充实自…

通用大模型VS垂直大模型,你更青睐哪一方?

这里写目录标题 一、通用大模型简介二、垂直大模型简介三、通用大模型与垂直大模型的比较四、如何选择适合的模型五、通用大模型和垂直大模型的应用场景六、总结 近年来&#xff0c;随着人工智能技术的飞速发展&#xff0c;大模型的应用越来越广泛。无论是自然语言处理、计算机…

STL-常用容器

3.1.1. string基本概念 本质&#xff1a; string是C风格的字符串&#xff0c;char*是C语言风格的字符串string本质上是一个类 string和char*的区别&#xff1a; char*是一个指针string是一个类&#xff0c;类内部封装并负责管理char*&#xff0c;是一个char*型的容器 特点&a…

[Vue3:组件通信)子组件props接收和watch监听,emit发送父组件 (添加修改设置成绩,添加、删除选课记录)

文章目录 一&#xff1a;系统功能&#xff1a;设置成绩&#xff08;添加或修改&#xff09;交互逻辑&#xff1a;涉及页面 Page02.vue&#xff0c;ModalEdit.vue主页面Page.vue注入子页面&#xff0c;使用子页面标签属性主页面对子页面做通信&#xff0c;子页面ModalEdit接收参…

蓝卓为中小制造企业注入数字化转型活力

随着劳动力成本上升,原材料价格上涨,企业生产成本逐年增加&#xff0c;市场竞争越来越激烈&#xff0c;传统的中小制造企业面临着巨大的压力。 通过数字化转型应对环境的变化已成为行业共识&#xff0c;在数字化的进程中&#xff0c;中小企业首要考虑生存问题&#xff0c;不能…

用python脚本转换图片分辨率

一、使用说明 确定已经安装python&#xff0c;且版本3.6以上&#xff0c;可以用下面指令查看python版本&#xff1a;python --version 配置环境&#xff0c;第一次使用先配置环境&#xff0c;后面不需要 把要转换的图片放到"img"文件夹下 转换&#xff0c;结果保存…

Git代码冲突原理与三路合并算法

Git代码冲突原理 Git合并文件是以行为单位进行一行一行合并的&#xff0c;但是有些时候并不是两行内容不一样Git就会报冲突&#xff0c;这是因为Git会帮助我们进行分析得出哪个结果是我们所期望的最终结果。而这个分析依据就是三路合并算法。当然&#xff0c;三路合并算法并不…

使用Python和Matplotlib绘制复杂数学函数图像

本文介绍了如何使用Python编程语言和Matplotlib库来绘制复杂的数学函数图像。通过引入NumPy库的数学函数,我们可以处理包括指数函数在内的各种复杂表达式。本文详细讲解了如何设置中文字体以确保在图像中正确显示中文标题和标签,并提供了一个完整的代码示例,用户可以通过输入…