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

使用mingw-w64编译x86汇编时遇R_X86_64_32S重定位错误求解

解决MingW编译AT&T汇编的重定位错误与运行问题

错误原因解析

  1. 重定位错误:x64 Windows的PE可执行文件中,符号地址可能超出32位范围,直接用mov $hello, %rdi这种32位立即数寻址会触发R_X86_64_32S截断错误。改用RIP相对寻址可以避免这个问题,无需使用movabs。
  2. 调用约定不匹配:你的代码使用的是Linux的SysV x64调用约定(参数存在RDI/RDX等),但Windows x64采用Microsoft调用约定,前4个参数需放在RCX/RDX/R8/R9,且栈要保持16字节对齐。

修正后的代码

.text
hello:      .asciz "Hello World!\n"

.global main

main:
    push    %rbp
    mov     %rsp, %rbp
    sub     $16, %rsp          # 保证栈16字节对齐(Windows x64调用约定要求)

    mov     $0, %rax           # 无浮点参数,AL设为0
    lea     hello(%rip), %rcx  # RIP相对寻址加载字符串地址到RCX(第一个参数寄存器)
    call    printf

    mov     $0, %rcx           # exit函数的参数放在RCX
    call    exit

    mov     %rbp, %rsp
    pop     %rbp
    ret

编译命令

保持你原来的命令即可:

x86_64-w64-mingw32-gcc -o test test.s

关键修改点

  • RIP相对寻址:用lea hello(%rip), %rcx替代mov $hello, %rdi,既解决了32位地址截断问题,又符合x64 PE的寻址规范。
  • 调用约定适配:
    • 将字符串地址从RDI移到RCX(Windows x64第一个参数寄存器)。
    • exit函数的参数从RDI移到RCX。
    • 新增sub $16, %rsp保证栈16字节对齐(调用函数前必须满足的要求)。

后续Windows API开发提示

如果要调用Windows原生API(比如创建窗口),需要注意:

  • 所有API遵循Microsoft x64调用约定,参数按RCX/RDX/R8/R9顺序传递。
  • 需要链接对应系统库,比如kernel32.dll(ExitProcess)、user32.dll(CreateWindowEx)等,MingW会自动处理大部分常用库的链接。
  • 部分Windows API仅支持宽字符版本(如CreateWindowExW),需注意字符串编码适配。

内容的提问来源于stack exchange,提问作者Floris van Onna

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 13:22:05