CMake进行C/C++与汇编混合编程

1. 前提


    这篇文章记录一下怎么用CMake进行项目管理, 并用C/C++和汇编进行混合编程, 为了使用这项技术, 必须在VS的环境中安装好cmake组件
在这里插入图片描述
由于大部分人不会使用C/C++与汇编进行混合编程的情况。所以这篇文章并不适用于绝大部分人不会对其中具体细节进行过多叙述。只是做一些简单的记录

2. 配置

创建一个cmake工程
在这里插入图片描述
VS是支持多个工程在一个解决方案中的, 目前使用的是单工程。这是我习惯的目录树:在这里插入图片描述
解释一下其中含义:

  • include: 所有头文件都将放在这个目录下
  • src: 所有源文件都将放在这个目录下
  • out/build: 构建项目所生产的中间文件
  • install: 最终工程所生产的可执行文件以及库文件, 和必须的文件, 这是最终使用部分可以直接打包
  • scripts: 辅助编译链接的脚本

下面我将先用cmake脚本配置一个cpp项目:

首先看一下目录树:在这里插入图片描述
CMakeLists.txt编写:

# cmake的最低版本要求是3.8
cmake_minimum_required (VERSION 3.8)# 项目名称
project (TestJoke)# 设置默认安装路径
if (CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)set(CMAKE_INSTALL_PREFIX "${CMAKE_SOURCE_DIR}/install" CACHE PATH "默认安装路径" FORCE)
endif()# 生成可执行文件, 并使用main.cpp和arthmetic.cpp
add_executable(TestJoke main.cpp src/calc/arthmetic.cpp)# 将include/calc包含进头文件目录内
target_include_directories(TestJoke PRIVATE "${CMAKE_SOURCE_DIR}/include/calc")# 生成的目标放到install/bin目录下
install(TARGETS TestJoke DESTINATION bin)# 执行命令TestJoke, 依赖是TestJoke生成, 也就是说TestJoke生成后立马执行TestJoke
add_custom_command(TARGET TestJokeCOMMAND TestJoke DEPENDS TestJoke 
)

arthmetic.h编写:

#pragma once #ifdef __cplusplus
extern "C" {
#endif int add(int iNum1, int iNum2);int sub(int iNum1, int iNum2);int div1(int iNum1, int iNum2);int mul(int iNum1, int iNum2);#ifdef __cplusplus
}
#endif 

arthmetic.h编写:

#include "arthmetic.h"int add(int iNum1, int iNum2)
{return(iNum1 + iNum2);
}int sub(int iNum1, int iNum2)
{return(iNum1 - iNum2);
}int div1(int iNum1, int iNum2)
{return(iNum1 / iNum2);
}int mul(int iNum1, int iNum2)
{return(iNum1 * iNum2);
}

main.cpp编写:

#include <windows.h>
#include <cstdio>
#include <cstdlib>
#include "arthmetic.h"int main()
{printf("%d", add(12, 8));system("pause");return(0);
}

build.bat脚本编写:

@echo off:: 保存原本的环境变量
setlocal:: 进入out/build构建目录
set BUILD_PATH=%~dp0../out/build/
pushd "%BUILD_PATH%":: 以x86 Debug方式构建项目
cmake ../.. -DCMAKE_BUILD_TYPE=Debug -G "Visual Studio 17 2022" -A Win32 
cmake --build . --config Debug 
:: 将生成内容安装
cmake --install . --config Debug :: 回到原来目录
popd 
:: 恢复原本的环境变量
endlocal 

完成之后进入scripts目录执行build.bat脚本就可以发现执行成功了
在这里插入图片描述
执行成功后, 可执行文件被安装到了install/bin/目录下, 构建文件在out/build/目录下生成
在这里插入图片描述
下面将进行汇编语言的配置, 首先去masm32下载对应的sdk: 下载masm32 sdk

添加汇编代码后的目录树:
在这里插入图片描述
stupid.asm内容:

.586
.model flat, C
option casemap:noneinclude windows.inc
include kernel32.inc
include user32.inc
includelib kernel32.lib
includelib user32.lib.data
szCap SBYTE '测试', 0
szMsg SBYTE '这是一个测试', 0.code
MsgBox PROC pszMsg:PTR SBYTE, pszCap:PTR SBYTEpush MB_OKpush pszCappush pszMsg push NULLcall MessageBoxret 
MsgBox ENDP
END

完成之后就可以对cmake进行配置
主要是将masm32 SDK的库文件和头文件加入cmake环境变量中
CMakeLists.txt修改后:

# cmakee的最低版本要求是3.8
cmake_minimum_required (VERSION 3.8)# 项目名称
project (TestJoke)# 允许基于masm的Intel汇编
enable_language(ASM_MASM)# 设置默认安装路径
if (CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)set(CMAKE_INSTALL_PREFIX "${CMAKE_SOURCE_DIR}/install" CACHE PATH "默认安装路径" FORCE)
endif()# 包含masm32 sdk的头文件目录
include_directories(D:/masm32/include)
# 包含masm32 sdk的库文件目录
link_directories(D:/masm32/lib)# 生成可执行文件, 并使用main.cpp和arthmetic.cpp
add_executable(TestJoke main.cpp src/calc/arthmetic.cpp src/asm/stupid.asm)# 将include/calc包含进头文件目录内
target_include_directories(TestJoke PRIVATE "${CMAKE_SOURCE_DIR}/include/calc")# 生成的目标放到install/bin目录下
install(TARGETS TestJoke DESTINATION bin)# 执行命令TestJoke, 依赖是TestJoke生成, 也就是说TestJoke生成后立马执行TestJoke
add_custom_command(TARGET TestJokeCOMMAND TestJoke DEPENDS TestJoke 
)

再次运行构建脚本后发现这个错误, 这是studid.asm出的错, 因为汇编代码无法使用SafeSEH特性, 这里给关掉
在这里插入图片描述
在CMakeLists.txt中加入链接选项以此来关闭SafeSEH:在这里插入图片描述
再次运行build.bat后发现如下错误:
在这里插入图片描述
由于masm32 sdk开发包中是含有自己的编译器和链接器的。而当我使用VS编写cmake项目的时候使用的是VS自带的编译器和链接器, 这里是VS自带的编译器版本可以看到是14.x
而masm32 SDK开发套件的编译器版本是6.x
在这里插入图片描述
不同的编译器对汇编语法可能有细微的不同, 对语法的严格程度也不一样, 为了能适应VS自带版本编译器, 这里我选择修改masm32 sdk的头文件:
首先找到windows.inc并定位到出错行:
在这里插入图片描述
这里我选择将其改成宏, 这样可以规避这个问题:
在这里插入图片描述
代码如下:

COMP_ELEM_ALL MACROLOCAL temptemp = (COMP_ELEM_TYPE+COMP_ELEM_CHECKED+COMP_ELEM_DIRTY+COMP_ELEM_NOSCROLL)temp = temp + (COMP_ELEM_POS_LEFT+COMP_ELEM_SIZE_WIDTH+COMP_ELEM_SIZE_HEIGHT)temp = temp + (COMP_ELEM_POS_ZINDEX+COMP_ELEM_SOURCE+COMP_ELEM_FRIENDLYNAME)EXITM <temp>
ENDM

接着定位到winextra.inc, 并定位到出错的位置:
在这里插入图片描述
将方括号改成圆括号即可:
在这里插入图片描述
完成之后发现成功了:
在这里插入图片描述

3. 总结与注意点

  • 要非常注意名称粉碎的问题, 函数在C++编译后的名称, 与C编译后的名称是完全不同的, 为了确保能够找到对应的名称, 如果你要使用C++特性必须加上extern "C"让C++函数以C的名称粉碎的方式进行
  • 汇编语言和C的名称粉碎结果是一样的, 但是调用约定会影响名称粉碎的结果。默认情况下C/C++都用的是C调用约定, 所以你的汇编代码也要用C调用约定, 这也是为啥我用的是.model flat, C了

(完)

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

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

相关文章

正确看待OpenAI大模型Sora

2月16日凌晨&#xff0c;OpenAI发布了文生视频模型Sora。官方是这样描述的&#xff1a;Sora is an AI model that can create realistic and imaginative scenes from text instructions.Sora一个人工智能模型&#xff0c;它可以根据文本指令创建逼真和富有想象力的场景。Sora…

网络安全防御保护 Day5

今天的任务如下 要求一的解决方法&#xff1a; 前面这些都是在防火墙FW1上的配置。 首先创建电信的NAT策略 这里新建转换后的地址池 移动同理&#xff0c;不过地址池不一样 要求二的解决方法&#xff1a; 切换至服务器映射选项&#xff0c;点击新建&#xff0c;配置外网通过…

Java 基于 SpringBoot+Vue 的校园交友网站,附源码

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

DarkSide针对VMware EXSI系统进行加密

前言 最近黑客组织利用DarkSide勒索病毒对Colonial Pipeline 发起勒索攻击&#xff0c;国内外各大安全厂商和安全媒体也都有相关报道&#xff0c;DarkSide勒索软件是从2020年8月出现&#xff0c;并以(RAAS)勒索即服务的商业模式进行运作&#xff0c;此勒索病毒不仅可以部署基于…

详解 Redis 实现数据去重

✨✨ 欢迎大家来到喔的嘛呀的博客✨✨ &#x1f388;&#x1f388;希望这篇博客对大家能有帮助&#x1f388;&#x1f388; 目录 言 一. Redis去重原理 1. Redis Set 数据结构 2. 基于 Set 实现数据去重 3. 代码示例 4. 总结 …

月薪30K-100K,新一波工作机会来了,你准备好了吗

纯血版鸿蒙发布&#xff0c;开启一个新时代 1月18日下午&#xff0c;在“鸿蒙千帆起”发布会上&#xff0c;华为揭秘鸿蒙生态和纯血鸿蒙星河版HarmonyOS NEXT进阶的新进展。“几年来&#xff0c;在众多伙伴和开发者的共同努力下&#xff0c;鸿蒙生态设备数已达8亿&#xff0c;…

【医学图像分割 2024】BEFUnet

文章目录 【医学图像分割 2024】BEFUnet摘要1. 介绍2. 相关工作2.1 基于CNN的分割网络2.2 ViT2.3 用于医学图像分割的Transformer 3. 方法3.1 双支路编码器3.1.1 边缘编码器3.1.2 主体编码器 3.2 LCAF模块3.2.1 双级融合模块(DLF) 3.3 损失函数3.3.1 边缘监督损失3.3.2 整体边缘…

AJAX——接口文档

1 接口文档 接口文档&#xff1a;描述接口的文章 接口&#xff1a;使用AJAX和服务器通讯时&#xff0c;使用的URL&#xff0c;请求方法&#xff0c;以及参数 传送门&#xff1a;AJAX阶段接口文档 <!DOCTYPE html> <html lang"en"><head><meta c…

家人们,比赛打完了

啊&#xff0c;终于打完一场比赛了&#xff0c;但还有三场…… 先看看我的战绩&#xff1a; 共八题&#xff0c;AC6题&#xff0c;总共3902分&#xff0c;3.7k人参加&#xff0c;第980名 来看看第一&#xff1a; A8题&#xff0c;我只有2题没做出&#xff0c;相差4000多分&am…

Compose 自定义 - 数据转UI的三阶段(组合、布局、绘制)

一、概念 Compose 通过三个阶段把数据转化为UI&#xff1a;组合&#xff08;要显示什么&#xff09;、布局&#xff08;要显示在哪里&#xff09;、绘制&#xff08;如何渲染&#xff09;。 组合阶段 Compisition 界面首次渲染时会将可组合函数转化为一个个布局节点 Layout Nod…

0102awvs安装-扫描-信息收集

1 安装awvs23.7 解压压缩包&#xff0c;解压密码网站网址&#xff0c;下载地址在最后链接双击acunetix_23.7.230728157.exe安装程序 安装位置默认&#xff0c;如更改位置&#xff0c;后面需要更改bat文件相应内容 设置管理员信息 next直到浏览器跳出登录界面 2 运行运行www.dd…

第9章 网络编程

9.1 网络通信协议 通过计算机网络可以实现多台计算机连接&#xff0c;但是不同计算机的操作系统和硬件体系结构不同&#xff0c;为了提供通信支持&#xff0c;位于同一个网络中的计算机在进行连接和通信时必须要遵守一定的规则&#xff0c;这就好比在道路中行驶的汽车一定要遵…

Spring Resource

java.net.URL 类可用于访问带有各种URL前缀的资源&#xff0c;但是对于访问一些资源还是不够方便。比如不能从类路径或者相对于ServletContext来获取资源。而Spring 的Resource接口&#xff0c;则可以通过类路径等方式来访问资源。 1 Resource接口 图 Resource接口及方法 getI…

CCF编程能力等级认证GESP—C++2级—20231209

CCF编程能力等级认证GESP—C2级—20231209 单选题&#xff08;每题 2 分&#xff0c;共 30 分&#xff09;判断题&#xff08;每题 2 分&#xff0c;共 20 分&#xff09;编程题 (每题 25 分&#xff0c;共 50 分)小杨做题小杨的 H 字矩阵 参考答案单选题判断题编程题1编程题2 …

C++ STL->list模拟实现

theme: smartblue list list文档 list是可以在常数范围内在任意位置进行插入和删除的序列式容器&#xff0c;并且该容器可以前后双向迭代。list的底层是双向链表结构&#xff0c;双向链表中每个元素存储在互不相关的独立节点中&#xff0c;在节点中通过指针指向 其前一个元素…

bpmn-js 事件总线处理

bpmn-js中使用EventBus作为事件的处理句柄&#xff0c;EventBus的使用和我们常规使用的事件总线没啥大的区别&#xff0c;其源码位于&#xff1a;/diagram-js/lib/core/EventBus.js &#xff08;bpmn-js使用diagram-js实现流程图的web端绘制呈现工具&#xff09;。 EventBus使用…

代码随想录算法训练营第三二天 | 买卖股票、跳跃游戏

目录 买卖股票的最佳时机II跳跃游戏跳跃游戏ii LeetCode 122.买卖股票的最佳时机II LeetCode 55. 跳跃游戏 LeetCode 45.跳跃游戏II 买卖股票的最佳时机II 只有一只股票&#xff01; 当前只有买股票或者卖股票的操作。 最终利润是可以分解的&#xff1a;把利润分解为每天为…

变分自编码器(VAE)PyTorch Lightning 实现

✅作者简介&#xff1a;人工智能专业本科在读&#xff0c;喜欢计算机与编程&#xff0c;写博客记录自己的学习历程。 &#x1f34e;个人主页&#xff1a;小嗷犬的个人主页 &#x1f34a;个人网站&#xff1a;小嗷犬的技术小站 &#x1f96d;个人信条&#xff1a;为天地立心&…

SAP PP学习笔记- 豆知识02 - 品目要谁来维护?怎么决定更不更新品目的数量金额?

其实都是在品目类型的Customize中设定的。 咱们这里简单试着说一下什么场景使用。 1&#xff0c;SAP中品目有很多View&#xff0c;都要由哪些部门来维护呢&#xff1f; 其实就是谁用谁维护呗。 在新建一个品目的时候&#xff0c;品目Type本身就决定了该品目要由哪些部门来维…

数据结构(4) 链表(链式存储)

链表&#xff08;链式存储&#xff09; 单链表定义基本操作的实现单链表的插入按位序插入指定节点的前插指定节点的后插 单链表的删除 小结 单链表 定义 顺序表优点:可随机存取&#xff0c;存储密度高&#xff0c;缺点:要求大片连续空间&#xff0c;改变容量不方便。 单链表优…