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

如何使用clang编译可调用Windows API的64位汇编(含Linux交叉编译)

汇编代码实现(clang兼容)

clang默认支持GAS汇编语法,你可以在代码开头添加.intel_syntax noprefix切换为更易读的Intel语法,避免AT&T语法的前缀冗余。以下是x64架构下调用目标API的示例:

.intel_syntax noprefix
# 声明外部导入的Windows API函数,x64架构下无下划线前缀
.extern OpenFile
.extern VirtualAlloc

.text
# 示例导出函数,可被你的C代码调用
.global my_win_api_call
my_win_api_call:
    # 预留32字节影子空间+8字节栈对齐空间,保证调用API时栈16字节对齐
    sub rsp, 40

    # --------------------- 调用VirtualAlloc示例 ---------------------
    # Microsoft x64调用约定:前4个参数依次存入rcx、rdx、r8、r9
    # VirtualAlloc参数顺序:lpAddress, dwSize, flAllocationType, flProtect
    mov rcx, 0                 # 分配地址由系统指定
    mov rdx, 4096              # 分配4KB内存
    mov r8, 0x3000             # 同时提交和保留内存页
    mov r9, 0x40               # 内存权限为可读可写可执行
    call VirtualAlloc
    # 调用后返回的内存起始地址存在rax寄存器,可自行存储使用

    # --------------------- 调用OpenFile示例 ---------------------
    # OpenFile参数顺序:lpFileName, lpReOpenBuff, uStyle
    lea rcx, [rip + test_file_path]  # 第一个参数:文件路径指针
    lea rdx, [rip + of_struct_buf]   # 第二个参数:OFSTRUCT结构缓冲区指针
    mov r8, 0x00000000               # 第三个参数:只读模式打开
    call OpenFile
    # 调用后返回的文件句柄存在rax寄存器

    # 恢复栈指针
    add rsp, 40
    ret

.data
test_file_path:
    .asciz "test.txt"    # 以0结尾的ASCII文件名
of_struct_buf:
    .fill 136, 1, 0      # 预分配136字节的OFSTRUCT结构空间,初始化为0

如果你习惯使用AT&T语法,删除开头的.intel_syntax noprefix,将寄存器、立即数、寻址格式替换为AT&T规范即可,调用逻辑完全一致。

编译选项

Windows本地编译

直接使用Windows版clang执行以下命令:

clang -target x86_64-pc-windows-gnu -nostdlib -static 你的C代码.c 你的汇编代码.s -lkernel32 -o 输出程序.exe

参数说明:

  • -target x86_64-pc-windows-gnu 指定目标为Windows x64架构,使用GNU ABI避免MSVC兼容问题
  • -nostdlib -static 和你Linux版本的编译参数保持一致,不链接标准库
  • -lkernel32 手动链接kernel32导入库,OpenFile和VirtualAlloc均由系统kernel32.dll导出,必须链接该库才能解析符号

Linux交叉编译Windows二进制

先安装好mingw-w64配套的clang交叉编译环境,编译参数和本地几乎完全一致,仅需调整target参数:

clang -target x86_64-w64-mingw32 -nostdlib -static 你的C代码.c 你的汇编代码.s -lkernel32 -o 输出程序.exe
注意事项
  • 如果需要编译32位x86版本,调用约定改为cdecl,参数从右往左压栈,导入符号需要加下划线前缀(即_OpenFile、_VirtualAlloc),target参数替换为对应的32位Windows target即可
  • 所有Windows API调用前必须保证栈16字节对齐,且预留32字节影子空间,否则会直接触发运行时崩溃
  • OpenFile属于微软标记为已废弃的API,如果你需要更稳定的文件操作能力,可以替换为CreateFileA,调用方式、编译要求完全一致,同样属于kernel32导出函数

内容的提问来源于stack exchange,提问作者Eric Stotch

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 22:27:04