Assembly VASM交叉汇编程序问题(m68k)
我想知道是否有人能帮我解决一个恼人的问题,使用VASM汇编程序为Amiga编译MC68000二进制文件。问题在于(我认为)标签地址操作的错误实现。Assembly VASM交叉汇编程序问题(m68k),assembly,cross-platform,68000,amiga,Assembly,Cross Platform,68000,Amiga,我想知道是否有人能帮我解决一个恼人的问题,使用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 我
详情如下:
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
我尝试了很多方法来解决这个问题,因为我认为由于屏幕地址很长(即不是单词),所以“屏幕>>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
但这显然是荒谬和完全错误的
感谢您的帮助。问题在于汇编程序(和链接器)的工作方式: 一些汇编器已经知道某些代码稍后将放在哪个地址,而其他汇编器编写对象文件,链接器将决定数据将放在哪里 在目标文件中,
dc.w 1234+screen>>16&$ffff
等指令将存储为dc.w 1234
,并存储一个附加信息,即一旦知道screen
的地址,就必须将screen
的高16位添加到1234
不幸的是,有两个问题:
- 并非所有体系结构都支持所有类型的信息。例如,Sparc CPU的对象文件支持信息“将地址的低10位添加到值”(因为此类CPU具有使用地址的低10位的指令),而m68k的对象文件不支持“地址的低10位”信息类型 不幸的是,m68k对象文件也不支持“地址的高16位”信息类型。(如果您使用GNU工具,至少不会这样做——我不确定VASM是否正确。)
- 汇编程序是愚蠢的。它们不会检测到
等于“地址的高16位”。因此,即使您的文件格式(例如PowerPC对象文件)支持这种类型的信息,汇编程序也会遇到问题屏幕>>16&$ffff
xyz
稍后将加载到内存中的地址$1234
现在,您可以执行以下操作:
xyz:
...
dc.w $e0, 0 + (screen - xyz + $1234) >> 16 & $ffff
...
screen:
但是,如果您不知道任何标签的“最终”地址,您将遇到问题…问题在于汇编程序(和链接器)的工作方式: 一些汇编器已经知道某些代码稍后将放在哪个地址,而其他汇编器编写对象文件,链接器将决定数据将放在哪里 在目标文件中,
dc.w 1234+screen>>16&$ffff
等指令将存储为dc.w 1234
,并存储一个附加信息,即一旦知道screen
的地址,就必须将screen
的高16位添加到1234
不幸的是,有两个问题:
- 并非所有体系结构都支持所有类型的信息。例如,Sparc CPU的对象文件支持信息“将地址的低10位添加到值”(因为此类CPU具有使用地址的低10位的指令),而m68k的对象文件不支持“地址的低10位”信息类型 不幸的是,m68k对象文件也不支持“地址的高16位”信息类型。(如果您使用GNU工具,至少不会这样做——我不确定VASM是否正确。)
- 汇编程序是愚蠢的。它们不会检测到
等于“地址的高16位”。因此,即使您的文件格式(例如PowerPC对象文件)支持这种类型的信息,汇编程序也会遇到问题屏幕>>16&$ffff
xyz
稍后将加载到内存中的地址$1234
现在,您可以执行以下操作:
xyz:
...
dc.w $e0, 0 + (screen - xyz + $1234) >> 16 & $ffff
...
screen:
但是,如果您不知道任何标签的“最终”地址,您将遇到问题…好的解决方法可能是:
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屏幕
...
移动。l SCRPT,d0
这样,链接器和exe加载程序重定位器将处理通常的32位地址,他们知道如何正确重定位。好的解决方法可能是:
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屏幕
...
移动。l SCRPT,d0
这样,链接器和exe加载程序重定位器将处理通常的32位地址,他们知道如何正确重定位。如何构建?您将哪些参数传递给汇编程序?如何将程序传输到Amiga?下面是我用来将source.s编译成result.bin的命令行:vasmm68k_mot_win32.exe-Fhunkexe-o“result.bin”-nosym“source.s”result.bin文件位于我在FS-UAE emulator中设置为硬盘驱动器的文件夹中,因此我可以在emu下直接运行它-但这不是重点。我的问题是,我甚至不能使用我在问题中描述的语法编译代码:/你是如何建造的?您将哪些参数传递给汇编程序?如何将程序传输到Amiga?以下是用于将source.s编译为result.bin的命令行:vasmm68k_mot_win32.exe-Fhunkexe