服务器正文20:跨平台(win和linux)用cmake给程序增加汇编代码

  • 备注(文件格式要求)
需要注意所有文件的编码格式一定要是utf-8或者utf-8 with BOM

一、cmake在linux下增加.S汇编文件到程序调用

1)背景介绍

在Linux下常用的C/C++编译器为GCC。近些年,随着LLVM项目的发展,Clang也占有了一席之地。但它们在Linux平台下,背后默认的汇编器依然是GAS。GAS使用语法格式为AT&T,与我们平常学习的Intel格式截然不同。它们的差别这里就不赘述了,网络上很多这方面的资料。那我们能不能在Linux平台也使用我们熟悉的Intel语法格式的汇编呢?答案是肯定的。

2)cmakelists.txt

if(MSVC)
	XXXX
else()
	enable_language(ASM)
	list (APPEND  SRC_FILES
		"${BASE_DIR}/src/asm/jump_x86_64_linux.S"
		"${BASE_DIR}/src/asm/make_x86_64_linux.S"
	)
endif()

二、cmake在win下增加.asm汇编文件到程序调用

1)代码

  • asm汇编代码
extern printf ;声明printf,将调用C语言的printf函数

section .rodata
    msg  db "这是汇编中的输出",0xa,0

section .text
global 汇编函数
汇编函数:
    push 	rbp
    mov 	rbp, rsp
    lea 	rdi, [rel msg]
    call printf wrt ..plt ;也可以使用 call 	[rel printf wrt ..got]
    mov 	eax, 0
    leave
    ret
  • main.cpp代码
    在这里插入图片描述

2)cmakelists.txt(一部分)

if(MSVC)
	list (APPEND  SRC_FILES
		"${BASE_DIR}/src/asm/jump_x86_64_win.asm"
		"${BASE_DIR}/src/asm/make_x86_64_win.asm"
	)
	SET(MASMFound FALSE)
	enable_language(ASM_MASM)
	//SET(CMAKE_ASM_NASM_FLAGS "-g") # 让NASM生成调试信息
	if(CMAKE_ASM_MASM_COMPILER_WORKS)
		SET(MASMFound TRUE)
	else()
		# This could happen if the CMakeCache.txt was deleted; 
		#try finding the ASM_MASM compiler again
		include(CMakeDetermineASM_MASMCompiler)
    	include(CMakeTestASM_MASMCompiler)
    	if(NOT CMAKE_ASM_MASM_COMPILER_WORKS)
			message(FATAL_ERROR "enable  ASM_MASM failed")
		endif()
	endif(CMAKE_ASM_MASM_COMPILER_WORKS)
endif()

3)masm需要注意的点(.plt)

lea  rdi, [rel msg]
call printf wrt ..plt 

因为GCC编译器默认会使用PIE(Position-Independent-Executable)模式(即位置无关的模式,这里就不深入探讨了,感兴趣的朋友可以网上查资料深入了解),所以64位的汇编也必须要使用PIE模式。如果我们直接按下面的方式来写:

lea  rdi, [msg]

就会出现链接错误:

[build] /usr/bin/ld: CMakeFiles/demo.dir/test.asm.o: relocation R_X86_64_32S against `.rodata' can not be used when making a PIE object; recompile with -fPIE
[build] /usr/bin/ld: failed to set dynamic section sizes: bad value
[build] collect2: error: ld returned 1 exit status

或者调用的方式写成:

call printf

也会出现链接错误:

[build] /usr/bin/ld: CMakeFiles/demo.dir/test.asm.o: warning: relocation against `printf@@GLIBC_2.2.5' in read-only section `.text'
[build] /usr/bin/ld: CMakeFiles/demo.dir/test.asm.o: relocation R_X86_64_PC32 against symbol `printf@@GLIBC_2.2.5' can not be used when making a PIE object; recompile with -fPIE
[build] /usr/bin/ld: final link failed: bad value
[build] collect2: error: ld returned 1 exit status

当然,也可以让GCC不使用PIE模式,在CMakeLists.txt中添加一句:

SET(CMAKE_CXX_FLAGS "-no-pie")

这样就可以把前面两句写成:

lea  rdi, [msg]
call printf

但是不建议这样做

4)cmake判断编译成32位还是64位(CMAKE_CL_64是64位)

在这里插入图片描述

三、其他备注(boost汇编看到的一些其他东西)

因为最近需要用汇编实现协程的切换,考虑到boost是全平台的实现,所以用了boost的汇编代码,下面是一些备注

1、elf
目标文件再不同的系统或平台上具有不同的命名格式,在Unix和X86-64 Linux上称为ELF(Executable and Linkable Format, ELF)。
ELF文件详解

2、MASM的环境搭建(没用到)
传送门

3、clang
clang是C,C ++和Objective-C编译器,包括预处理,解析,优化,代码生成,汇编和链接。通过模式设置(参考阶段选择选项),Clang将在完成链接之前停止
介绍传送门

4、macho
MachO文件是一种文件格式,是iOS或者OSX系统的可执行文件的格式
介绍传送门

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值