现代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 arrays
    for (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 functions
    CalcZ_cpp(z1, x, y, n);
    CalcZ_avx(z2, x, y, n);

    // Display the results
    constexpr 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 arguments
        test r9,r9                              ;n == 0?
        jz Done                                 ;jump if yes

; Initialize
        mov rax,-SF                             ;rax = array offset (Loop2)
        cmp r9,NSE                              ;n < NSE?
        jb Loop2                                ;jump if yes
        mov 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 offset
        vmovups 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 -= NSE
        cmp r9,NSE                              ;n >= NSE?
        jae Loop1                               ;jump if yes

        test r9,r9                              ;n == 0?
        jz Done                                 ;jump if yes
        add 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 offset
        vmovss 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 -= 1
        jnz Loop2                               ;repeat until done

Done:   vzeroupper
        ret                                     ;return to caller
CalcZ_avx endp
        end

最终构建运行即可

代码有点高大上,估计是用了AVX,两个loop同时运行。慢慢看书了解含义吧,还挺复杂的。

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

crowdsec 使用补充说明

1、服务器地址 10.99.50.1 2、后台地址 https://app.crowdsec.net/ 3、查看信息 查看解释器–用于识别读取日志 cscli parsers list查看场景–用于识别攻击&#xff08;防护手段&#xff09; cscli scenarios list产看集合–是解释器和场景的集合 cscli collections list4、…

SwaggerSpy:一款针对SwaggerHub的自动化OSINT安全工具

关于SwaggerSpy SwaggerSpy是一款针对SwaggerHub的自动化公开资源情报&#xff08;OSINT&#xff09;安全工具&#xff0c;该工具专为网络安全研究人员设计&#xff0c;旨在简化广大红队研究人员从SwaggerHub上收集已归档API信息的过程&#xff0c;而这些OSINT信息可以为安全人…

HTML静态网页成品作业(HTML+CSS)—— 非遗皮影戏介绍网页(6个页面)

&#x1f389;不定期分享源码&#xff0c;关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 &#x1f3f7;️本套采用HTMLCSS&#xff0c;未使用Javacsript代码&#xff0c;共有6个页面。 二、作品演示 三、代…

Duplicate keys detected: ‘tab-角色‘. This may cause an update error

项目场景&#xff1a; 使用el-tab和v-for循环渲染标签 问题描述 报错&#xff1a; Duplicate keys detected: ‘tab-角色’. This may cause an update error 原因分析&#xff1a; 看资料说是因为循环遍历的key值重复&#xff0c;但还是我的代码里key是唯一的&#xff0c;绑…

Vue2后台管理:项目开发全流程(二)

​&#x1f308;个人主页&#xff1a;前端青山 &#x1f525;系列专栏&#xff1a;vue篇 &#x1f516;人终将被年少不可得之物困其一生 依旧青山,本期给大家带来vue篇专栏内容:Vue2后台管理&#xff1a;项目开发全流程(二) 目录 功能实现 8、会员用户管理 ①使用数据模拟文…

HCIA 10 网络安全之结合ACL访问控制列表登录Telnet及FTP

ACL 本质上是一种报文过滤器&#xff0c;规则是过滤器的滤芯。设备基于这些规则进行报文匹配&#xff0c;可以过滤出特定的报文&#xff0c;并根据应用 ACL 的业务模块的处理策略来允许或阻止该报文通过。 1.实验介绍及拓扑 R3 为telnet服务器&#xff0c;R1 为客户端&#…

目标检测中的anchor机制

目录 一、目标检测中的anchor机制 1.什么是anchor boxes&#xff1f; 二、什么是Anchor&#xff1f; ​编辑三、为什么需要anchor boxes&#xff1f; 四、anchor boxes是怎么生成的&#xff1f; 五、高宽比&#xff08;aspect ratio&#xff09;的确定 六、尺度(scale)的…

Druid 参数配置详解

简介 Java 程序很大一部分要操作数据库&#xff0c;为了提高性能操作数据库的时候&#xff0c;又不得不使用数据库连接池。 Druid 是阿里巴巴开源平台上一个数据库连接池实现&#xff0c;结合了 C3P0、DBCP 等 DB 池的优点&#xff0c;同时加入了日志监控。 Druid 可以很好的…

【设计模式】行为型设计模式之 迭代器模式

介绍 迭代器模式&#xff08;Iterator Pattern&#xff09; 是行为设计模式之一&#xff0c;它提供了一种访问集合对象&#xff08;如列表、数组或其他集合结构&#xff09;中元素的方式&#xff0c;而不需要暴露集合的内部结构。迭代器模式定义了一个迭代器接口&#xff0c;该…

大数据学习——安装hive

一. 安装准备 1. 打开虚拟机&#xff0c;启动配置了NameNode节点的虚拟机&#xff08;一般和mysql在同一台虚拟机&#xff09;并连接shell 二. 安装 1. 上传hive安装包 hive安装包 提取码&#xff1a;6666 切换到/opt/install_packages目录下 可以将之前解压的rpm文件删除…

Adaboost集成学习 | Matlab实现基于CNN-LSTM-Adaboost集成学习时间序列预测(股票价格预测)

目录 效果一览基本介绍模型设计程序设计参考资料 效果一览 基本介绍 Adaboost集成学习 | Matlab实现基于CNN-LSTM-Adaboost集成学习时间序列预测&#xff08;股票价格预测&#xff09; 模型设计 融合Adaboost的CNN-LSTM模型的时间序列预测&#xff0c;下面是一个基本的框架。 …

渗透测试工具NMAP

nmap是一个网络连接端扫描软件&#xff0c;用来扫描网上电脑开放的网络连接端。确定哪些服务运行在哪些连接端&#xff0c;并且推断计算机运行哪个操作系统&#xff08;这是亦称 fingerprinting&#xff09;。它是网络管理员必用的软件之一&#xff0c;以及用以评估网络系统安全…

linux安装jdk + docker+dockercompose+aliyunACR

下载安装包 链接&#xff1a;https://pan.baidu.com/s/1AyFvPA5qwy4IxfZoTQohrQ 提取码&#xff1a;6666 安装jdk jdk-8u411-linux-x64.tar.gz 链接&#xff1a;https://pan.baidu.com/s/1BZ7J4L5PY-9nuQyxBMDGTA 提取码&#xff1a;6666 1、解压jdk tar -xvf jdk-8u411-li…

HTML静态网页成品作业(HTML+CSS+JS)—— 美食企业曹氏鸭脖介绍网页(4个页面)

&#x1f389;不定期分享源码&#xff0c;关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 &#x1f3f7;️本套采用HTMLCSS&#xff0c;使用Javacsript代码实现 图片轮播切换&#xff0c;共有4个页面。 二、…

SylixOS下UDP组播测试程序

SylixOS下UDP组播测试 测试效果截图如下: udp组播发送测试程序。 /********************************************************************************************************* ** ** 中国软件开源组织 ** ** …

即插即用!CVD:第一个生成具有相机控制的多视图一致视频方案!(斯坦福港中文)

论文链接&#xff1a;https://arxiv.org/abs/2405.17414 项目链接&#xff1a;https://collaborativevideodiffusion.github.io/ 最近对视频生成的研究取得了巨大进展&#xff0c;使得可以从文本提示或图像生成高质量的视频。在视频生成过程中添加控制是未来的重要目标&#x…

算法:模拟题目练习

目录 题目一&#xff1a;替换所有的问号 题目二&#xff1a;提莫攻击 题目三&#xff1a;N字形变换 题目四&#xff1a;外观数列 题目五&#xff1a;数青蛙 首先先解释一下模拟算法是什么&#xff0c;其实模拟算法就是题目让我们干什么我们就干什么&#xff0c;思路比较简…

【数据库设计】宠物商店管理系统

目录 &#x1f30a;1 问题的提出 &#x1f30a;2 需求分析 &#x1f30d;2.1 系统目的 &#x1f30d;2.2 用户需求 &#x1f33b;2.2.1 我国宠物行业作为新兴市场&#xff0c;潜力巨大 &#x1f33b;2.2.2 我国宠物产品消费规模逐年增大 &#x1f33b;2.2.3 我国宠物主选…

YOLOv5改进 | Head | 将yolov5的检测头替换为ASFF_Detect

&#x1f4a1;&#x1f4a1;&#x1f4a1;本专栏所有程序均经过测试&#xff0c;可成功执行&#x1f4a1;&#x1f4a1;&#x1f4a1; 在目标检测中&#xff0c;为了解决尺度变化的问题&#xff0c;通常采用金字塔特征表示。然而&#xff0c;对于基于特征金字塔的单次检测器来…

凡尔码来访登记卡助力来访安全

来访登记制度是指为了加强对来访人员的管理和安全控制&#xff0c;确保组织内部秩序和安全的一项制度。通过来访登记制度&#xff0c;可以对来访人员的身份进行核实&#xff0c;了解来访目的&#xff0c;并采取相应的安全措施&#xff0c;为组织内部的工作和人员安全提供保障。…