繁体   English   中英

VASM交叉汇编器问题(M68K)

[英]VASM cross-assembler issue (m68k)

我想知道是否有人可以使用VASM汇编器为Amiga编译MC68000二进制文件而遇到的烦人问题。 问题在于标签地址处理的错误(我认为)实现。
详细信息如下:

copper_scr:
    dc.w $e0, (screen>>16) & $ffff
    dc.w $e2, screen & $ffff

...

screen:
    dcb.w screen_size  ; screen_size value does not matter here

我在上面的代码中尝试做的是将屏幕地址分为最高有效字和较低有效字,以便为芯片寄存器提供屏幕数据地址(或向量,如果您愿意)。

但是,以这种形状编译代码会给我“非法重定位”错误39。

我尝试了多种方法来摆脱这种情况,因为我认为由于屏幕地址很长(即不是单词),因此“ screen >> 16”的结果可能会很长,因此无法将这样的值放在整个单词范围内。

有趣的是,下面的代码编译没有错误,但是结果二进制文件中的两个值都被编译为0:

...
dc.w $e0,0 + screen>>16 & $ffff
dc.w $e2,0 + screen&$ffff
...

作为暂时的变通办法,我在运行时在代码开头的某个位置计算这些值:

move.l #screen,a0
move.l a0,d7
lsr.l #4,d7
lsr.l #4,d7
lsr.l #4,d7
lsr.l #4,d7
andi.l #$ffff,d7
move.w d7,copper_scr+2
move.l a0,d7
andi.l #$ffff,d7
move.w d7,copper_scr+6

但这显然是荒谬的,完全是错误的。

任何帮助表示赞赏。

好的解决方法可能是:

move.l  #screen,d0
move.w  d0,scrptr_low+2
swap    d0
move.w  d0,scrptr_high+2
...
scrptr_high: dc.w $e0,0
scrptr_low:  dc.w $e2,0

要么

scrptr: dc.l screen
...
move.l  scrptr,d0
<then the same>

这样,链接器和exe-loader-relocator将处理它们知道如何正确定位的常规32位地址。

问题在于汇编器(和链接器)的工作方式:

一些汇编器已经知道某些代码以后将放置在哪个地址,而其他汇编器将写入目标文件,并且链接器将决定将数据放置在何处。

在目标文件中,诸如dc.w 1234 + screen>>16 & $ffff类的指令将被存储为dc.w 1234 ,并且还存储了附加信息,即地址一经添加, screen的高16位就必须添加到1234中。 screen是已知的。

不幸的是,有两个问题:

  • 并非所有架构都支持所有类型的信息。 例如,Sparc CPU的目标文件支持信息“ 将地址的低10位添加到值中 ”(因为此类CPU的指令使用地址的低10位),而m68k的目标文件不支持“ 低10位”信息地址信息类型的位。

    不幸的是,m68k目标文件也不支持“ 地址的高16位 ”信息类型。 (至少如果您使用GNU工具,则不会-我不确定VASM。)

  • 汇编程序很愚蠢。 他们将不会检测到screen>>16 & $ffff等于“ 地址的高16位 ”。 因此,即使您的文件格式(例如PowerPC目标文件)支持该类型的信息,汇编器也会出现问题。

可能的解决方法:

如果您在一部分中有标签,并且您确实知道该标签的地址,则可以执行以下操作。

假设您知道标签xyz稍后将被加载到内存中的地址$1234中。

现在,您可以执行以下操作:

xyz:
    ...
    dc.w $e0, 0 + (screen - xyz + $1234) >> 16 & $ffff
    ...
screen:

但是,如果您不知道任何标签的“最终”地址,就会遇到问题...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM