C++项目集成NASM函数遇链接错误,求正确配置方案
解决NASM函数集成到C++项目的链接错误及参数处理问题
问题根源
链接错误的核心原因有两点:
- CMake未启用NASM语言支持,导致
.asm文件未被编译,链接阶段找不到函数符号 - NASM代码错误地从栈上读取参数,不符合System V AMD64调用约定(第一个64位参数存储在
rdi寄存器中)
1. 修复CMakeLists.txt配置
必须启用ASM_NASM语言支持,让CMake正确识别并编译NASM代码:
cmake_minimum_required(VERSION 3.23) project(App) set(CMAKE_CXX_STANDARD 23) # 启用NASM语言支持(关键步骤) enable_language(ASM_NASM) # 设置目标对象格式为elf64(适配Linux x86_64平台) set(CMAKE_ASM_NASM_OBJECT_FORMAT elf64) # 可选:添加NASM编译警告 set(CMAKE_ASM_NASM_FLAGS "${CMAKE_ASM_NASM_FLAGS} -Wall") set(SOURCE_FILES main.cpp Tools/rnd_byseed.asm) add_executable(App ${SOURCE_FILES})
2. 修复NASM函数代码
按照System V AMD64调用约定,正确从rdi寄存器读取参数,修正栈操作逻辑:
global rnd_by_seed ;------------------------------------------ ; return random number by seed value ; @param rdi seed value (unsigned 64bit integer) ; @return rax random number (64bit unsigned) rnd_by_seed: push rbp mov rbp, rsp ; 将rdi中的64位seed拆分为低32位和高32位 mov eax, edi ; eax = seed低32位 mov edx, rdi ; edx = seed原始值 shr edx, 32 ; edx = seed高32位 mov ebx, 16807 ; 计算低32位 * 16807 mul ebx ; eax = 低32位乘积,edx = 进位 mov esi, edx ; 保存低32位乘法的进位 mov edi, eax ; 保存低32位乘法结果 ; 计算高32位 * 16807 mov eax, edx mul ebx ; eax = 高32位乘积,edx = 进位 add eax, esi ; 加上低32位乘法的进位 adc edx, 0 ; 处理进位 ; 左移后右移,清除最低位 shl eax, 1 rcl edx, 1 shr eax, 1 add edx, edi ; 加上低32位乘法结果 adc eax, 0 ; 处理进位 xchg eax, edx ; 交换eax和edx,调整高低位顺序 ; 处理最高位为1的情况 test edx, 80000000h jz Store and edx, 7fffffffh ; 清除最高位符号位 add eax, 1 ; 结果加1 adc edx, 0 ; 处理进位 Store: ; 将高低32位组合为64位结果存入rax shl rax, 32 or rax, rdx leave ret
3. 验证编译运行
执行以下命令重新构建项目:
mkdir build && cd build cmake .. make ./App
运行后应正常输出随机数结果。
内容的提问来源于stack exchange,提问作者urula
相关产品推荐
相关产品推荐

