在C程序中调用汇编函数遇LNK2019错误的技术问询
在VS2022中C调用汇编出现LNK2019未解析外部符号问题
问题详情
尝试在C程序中调用x86-64汇编代码,相关代码如下:
C代码
// Template C to x86 call #include <stdio.h> #include <stdlib.h> #include <windows.h> extern void asmhello(); int main(int argc, char* argv[]) { asmhello(); return 0; }
原汇编代码(NASM格式)
; assembly part using x86-64 section .data msg db "Hello World",13,10,0 section .text bits 64 default rel ; to handle address relocation global asmhello extern printf asmhello: sub rsp, 8*5 ; caller mov rcx, msg1 call printf add rsp, 8*5 ret
编译错误提示(已翻译)
LNK2019 未解析的外部符号 asmhello,该符号在函数 main 中被引用
找不到“asmhello”的函数定义
问题原因
- 汇编语法不兼容:VS2022默认使用Microsoft Macro Assembler(MASM),而原代码是NASM格式,两者语法差异导致汇编器无法正确导出
asmhello符号,链接器找不到该符号。 - 笔误问题:汇编代码中引用的
msg1未定义,实际应为msg。 - x64 Windows调用约定未遵守:未正确处理栈对齐和影子空间要求。
解决方法
1. 使用MASM格式重写汇编代码
替换原汇编代码为以下MASM兼容的x86-64代码,保存为.asm文件:
; MASM x86-64 汇编代码 .data msg db "Hello World",13,10,0 .code ; 导出asmhello符号供C代码调用 PUBLIC asmhello ; 声明外部printf函数 EXTERN printf:PROC asmhello PROC ; x64 Windows要求栈保持16字节对齐,且需为前4个参数预留32字节影子空间 ; main调用asmhello后,rsp因返回地址占用8字节,需再减8凑齐16对齐,加上32字节影子空间 sub rsp, 8 + 32 ; 第一个参数通过rcx传递,使用lea加载字符串地址(因启用默认重定位) lea rcx, msg call printf ; 恢复栈指针 add rsp, 8 + 32 ret asmhello ENDP END
2. 配置VS2022项目
- 将上述
.asm文件添加到x64项目中。 - 右键该asm文件 → 属性 → 常规 → 项类型,选择Microsoft Macro Assembler。
- 确保项目编译目标为x64(而非x86)。
3. 验证
重新编译链接项目,即可正常运行并输出Hello World。
内容的提问来源于stack exchange,提问作者Stephanie Joy Relles
相关产品推荐
相关产品推荐

