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

x64汇编实现可JIT复制的64位绝对跳转:Linux转Windows遇阻

Windows下NASM汇编64位绝对跳转的链接错误解决方法

问题场景

将Linux下的Forth解释器汇编代码移植到Windows时,原代码通过间接引用绝对地址实现跳转:

jmp [.n+0]
.n:
        DQ pushparam
ALIGN 8
doestargetlen EQU $ - doestarget

pushparam:
        mov [r12], rbx
        add r12, 8

使用MSVC链接器时出现以下错误:

64th.obj : error LNK2017: 'ADDR32' relocation to '.rodata' invalid without /LARGEADDRESSAWARE:NO

原因是Windows默认启用/LARGEADDRESSAWARE,允许进程使用4GB以上内存,此时32位地址重定位无效,而原代码生成的是32位ADDR32重定位。

解决方案

方案1:显式生成64位绝对地址重定位

修改代码,显式指定64位地址引用,避免NASM生成32位重定位:

jmp qword [.n]  ; 显式指定qword,确保跳转操作数是64位
.n:
        DQ qword pushparam  ; 强制生成64位绝对地址的重定位项
ALIGN 8
doestargetlen EQU $ - doestarget

pushparam:
        mov [r12], rbx
        add r12, 8

此方案保留了原有的间接跳转结构,确保代码复制到任意内存位置后,只要.n中的pushparam绝对地址正确,就能正常跳转。

方案2:寄存器加载64位绝对地址后跳转

更简洁的方式是直接将pushparam的64位绝对地址加载到寄存器,再跳转:

mov rax, qword pushparam  ; 加载64位绝对地址到rax寄存器
jmp rax
ALIGN 8
doestargetlen EQU $ - doestarget

pushparam:
        mov [r12], rbx
        add r12, 8

NASM会为mov rax, qword pushparam生成64位立即数重定位,MSVC链接器可正常处理,且代码逻辑清晰,同样支持内存任意位置的复制执行。

额外注意事项

  • 若必须限制进程使用4GB以内内存,可添加链接选项/LARGEADDRESSAWARE:NO绕过错误,但会限制程序的内存扩展性,不推荐。
  • 编译时需确保NASM使用-f win64参数生成64位Windows目标文件:nasm -f win64 yourcode.asm -o yourcode.obj

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 12:12:15