文章目录
- 一、cmake在linux下增加.S汇编文件到程序调用
- 1)背景介绍
- 2)cmakelists.txt
- 二、cmake在win下增加.asm汇编文件到程序调用
- 1)代码
- 2)cmakelists.txt(一部分)
- 3)masm需要注意的点(.plt)
- 4)cmake判断编译成32位还是64位(CMAKE_CL_64是64位)
- 三、其他备注(boost汇编看到的一些其他东西)
- 备注(文件格式要求)
需要注意所有文件的编码格式一定要是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系统的可执行文件的格式
介绍传送门