簡體   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