如何在MSVC环境的asm文件中调用C或C++代码
首先明确:MSVC配套的64位MASM(ml64.exe)完全支持从汇编代码调用C函数,不需要更换汇编工具链,操作方法如下:
汇编侧声明C函数的方法
只要你的C函数已经用extern "C"修饰避免了C++名字修饰,直接在汇编代码开头用EXTERN伪指令声明即可,声明格式为:
EXTERN 函数名:PROC
注意函数名大小写必须和C代码中的定义完全一致,Windows平台下C符号区分大小写。
调用要求与示例
MSVC x64环境默认使用微软x64调用约定,调用C函数时必须遵守该约定,核心规则如下:
- 前4个整数/指针参数依次使用
RCX、RDX、R8、R9传递,前4个浮点参数依次使用XMM0、XMM1、XMM2、XMM3传递,超出4个的参数从右到左压入栈 - 调用前必须在栈上预留至少32字节的影子空间,供被调用函数暂存前4个参数的值
- 调用前需要保证栈指针
RSP16字节对齐 - 整数返回值存于
RAX,浮点返回值存于XMM0 RAX/RCX/RDX/R8/R9/R10/R11为易失寄存器,被调用函数可能直接修改,如需保留值需要调用前自行压栈保存
完整可运行示例
C代码(test.c)
#include <stdio.h> // 供汇编调用的C函数 extern "C" int add(int a, int b) { return a + b; } // 声明汇编函数供C调用 extern "C" int asm_calc(); int main() { printf("汇编调用C函数计算结果:%d\n", asm_calc()); return 0; }
汇编代码(calc.asm)
; 声明要调用的C函数 EXTERN add:PROC .code asm_calc PROC ; 预留32字节影子空间 + 8字节对齐空间,共40字节 sub rsp, 40 ; 第一个参数a=10放RCX,第二个参数b=20放RDX mov rcx, 10 mov rdx, 20 call add ; 返回值已经在RAX里,直接作为asm_calc的返回值 ; 恢复栈 add rsp, 40 ret asm_calc ENDP END
编译命令
- 汇编asm文件生成obj:
ml64 /c calc.asm - 编译C代码并链接obj:
cl test.c calc.obj
替代汇编器方案
如果需要使用其他汇编器,可选择NASM:
- 声明外部C函数的语法为
extern add - 调用约定规则和上述完全一致,编译时用
nasm -f win64 calc.asm -o calc.obj生成obj后,和MSVC编译的C代码obj正常链接即可。
内容的提问来源于stack exchange,提问作者blackshadow
相关产品推荐
相关产品推荐

