You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在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”的函数定义

问题原因

  1. 汇编语法不兼容:VS2022默认使用Microsoft Macro Assembler(MASM),而原代码是NASM格式,两者语法差异导致汇编器无法正确导出asmhello符号,链接器找不到该符号。
  2. 笔误问题:汇编代码中引用的msg1未定义,实际应为msg。
  3. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 07:12:32