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

x86-64汇编报错:IMAGE_REL_AMD64_ADDR32 against '.bss' 求解

解决Win64下NASM+GNU ld访问.bss变量的重定位截断错误

问题分析

你遇到的Relocation truncated to fit: IMAGE_REL_AMD64_ADDR32 against '.bss'错误,和变量尺寸无关——handle resq 1确实能存下64位的HANDLE(PVOID)。错误根源是Win64 PE程序的默认基地址超出32位范围,而你用的绝对寻址方式会触发32位重定位,导致地址截断。

Win64程序的默认加载基地址是0x140000000,这个值大于32位能表示的最大值0xFFFFFFFF。当你用mov [handle], rax这种绝对寻址时,GNU ld会尝试生成IMAGE_REL_AMD64_ADDR32重定位(32位绝对地址),但目标地址超过32位,因此报错。

解决方案

最直接的修复是改用RIP相对寻址,这也是Win64 ABI推荐的全局变量访问方式。NASM中可以通过rel前缀实现:

修改代码中的两处错误位置:

; 错误位置1 修改为
mov [rel handle], rax

; 错误位置2 修改为
mov rcx, [rel handle]

为什么这样有效?

RIP相对寻址是基于当前指令地址的32位有符号偏移,Win64程序的代码段和数据段(包括.bss)之间的偏移不会超过2GB,因此32位有符号偏移完全能覆盖。这种方式会生成IMAGE_REL_AMD64_REL32重定位,避免了32位绝对地址的截断问题。

验证步骤

修改后重新执行编译链接命令:

nasm -f win64 main.asm
ld main.o -o main.exe -e _start C:/Windows/System32/kernel32.dll

此时链接应该能正常完成,程序也能正确运行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 10:52:07