JMP
x86プラットフォーム用のアセンブラを構築しているときに、命令のエンコードでいくつかの問題が発生しました。
OPCODE INSTRUCTION SIZE
EB cb JMP rel8 2
E9 cw JMP rel16 4 (because of 0x66 16-bit prefix)
E9 cd JMP rel32 5
...
(私のお気に入りのx86命令Webサイト、http://siyobik.info/index.php?module = x86&id = 147から)
すべて相対ジャンプであり、各エンコーディング(演算+オペランド)のサイズは3番目の列にあります。
現在、私の元の(したがってこのために障害がある)設計では、各命令に最大(5バイト)のスペースが予約されています。オペランドはまだ不明な場所へのジャンプであるため、まだ不明です。NOP
そこで、ジャンプの場所がわかっている場合は、メモリ内の正しい場所にオペランドを再書き込みし、残りをsで埋める、「再書き込み」メカニズムを実装しました。これは、タイトループではやや深刻な問題です。
今私の問題は次の状況にあります:
b: XXX
c: JMP a
e: XXX
...
XXX
d: JMP b
a: XXX (where XXX is any instruction, depending
on the to-be assembled program)
JMP
問題は、命令 に対して可能な限り最小のエンコーディングが必要なことです(そしてNOP
塗りつぶしは必要ありません)。
のオペランド間のc
相対距離を計算する前に、の命令のサイズを知る必要があります。同じことがatにも当てはまります。との間の相対距離を計算する前に、のサイズを知る必要があります。a
b
d
JMP
c
d
e
a
既存のアセンブラはこの問題をどのように解決しますか、またはこれをどのように行いますか?
これは私が問題を解決すると考えていることです:
最初に、とそのターゲットの間のオペコードへのすべての命令をエンコードします。
JMP
この領域に可変サイズのオペコードが含まれている場合は、最大サイズを使用します(例5
:JMP
。次に、JMP
可能な限り最小のエンコードサイズ(3、4、または5)を選択して、ターゲットを基準にしてエンコードし、距離を計算します。可変サイズのオペコードがエンコードされている場合は、前にすべての絶対オペランドを変更し、このエンコードされた命令をスキップするすべての相対命令を変更します。オペランドが変更されると、可能な限り最小のサイズを選択するように再エンコードされます。可変サイズのオペコードは(最大サイズを使用するため)縮小する可能性があるため、このメソッドは確実に終了します。
おそらくこれは過剰に設計されたソリューションなのだろうか、それが私がこの質問をする理由です。