VASM交叉汇编器(m68k)编译Amiga MC68000代码地址拆分报错求助
解决VASM编译MC68000 Amiga代码时的地址拆分错误
这个问题在Amiga铜表(copper list)编程里非常典型,核心原因是VASM对重定位(relocation)类型的严格校验——你试图把32位的符号地址拆分后存入16位的dc.w伪指令,默认情况下VASM不允许直接将32位重定位截断为16位,所以抛出了“illegal relocation”错误39。
问题根源分析
screen是32位的符号地址(MC68000为32位架构,地址为长字宽度)screen>>16的结果仍属于32位重定位类型,但dc.w要求的是16位重定位,VASM拒绝这种类型不匹配的转换- 你尝试的
0 + screen>>16 & $ffff之所以能编译但生成0,是因为VASM错误地将这个表达式判定为常数计算,没有保留符号地址的重定位信息,最终输出了无效的0值
正确的解决方案
VASM提供了专门的内置宏来处理地址的高低16位拆分,同时生成合法的16位重定位。直接使用__upper()和__lower()宏即可:
copper_scr: dc.w $e0, __upper(screen) ; 提取screen地址的高16位 dc.w $e2, __lower(screen) ; 提取screen地址的低16位 ... screen: dcb.w screen_size
替代写法(手动指定重定位类型)
如果你不想用内置宏,也可以通过强制转换重定位类型来实现,使用:word:修饰符告诉VASM将表达式转换为16位重定位:
copper_scr: dc.w $e0, :word:(screen >> 16) dc.w $e2, :word:(screen & $ffff)
这两种写法都会在汇编/链接阶段直接计算出screen地址的高低16位,无需运行时通过CPU指令计算,完全符合Amiga铜表的规范要求。
验证编译参数
确保你使用的VASM命令行参数正确适配Amiga MC68000环境,例如:
vasmm68k_mot -Fhunk -m68000 -o copper_demo.o copper_demo.s
-Fhunk:生成Amiga标准的hunk格式目标文件-m68000:指定目标CPU为MC68000-o:指定输出文件路径
内容的提问来源于stack exchange,提问作者H_nk
相关产品推荐
相关产品推荐

