1

前方にジャンプする命令がある場合、オフセット アドレスを計算する方法はありますか、それとも 2 番目のパススルーで絶対ジャンプを計算するだけですか?

このような:

Jump to Label
Move 0 to 64bit Register 1
Label:
Move 0 to 64bit Register 2

このような場合、コンパイラは絶対ジャンプのみを使用しますか? このような単純なケースでオフセットを計算することは可能ですが、ジャンプやラベルが互いにネストされていることは言うまでもなく、ラベルが増えると指数関数的に高価になります...

4

1 に答える 1

2

それは良い問題ですが、解決するのはそれほど難しくありません。解決策は絶対ジャンプを使用しないことです-それは何も解決しません。ターゲットのアドレスを知っている必要があり、それがわかっている場合は、現在のアドレスも知っている可能性があり、相対ジャンプを実行できます。それで行き止まりです。

簡単な解決策は、コードに対して 2 つのパス (または「1.5」) を実行することです。最初のパスでは、すべてのアドレスを収集します (この時点では forward について何も知らないため、コードを発行することはできません)。 2 回目のパスでは、この情報を使用して、ブランチとすべてを含むすべてのコードを発行します。「1.5」パスは、ブランチのコードとプレースホルダーを発行し、ブランチのオフセットを埋めるために戻ってきます。これにより、再度解析する必要がなくなります。

ただし、これには問題があります。最初のパスでは、短いジャンプを使用できるか通常のジャンプを使用できるかを判断できないため、実際にはコード サイズを知ることができません。しかし、それには推測が必要かもしれません。その後、範囲外のラベルを参照するすべてのブランチを、そのブランチをより広いラベルに置き換えることで、繰り返し修正できます。完全なジャンプから始めて、短いジャンプに置き換えてみることもできます。

于 2015-04-14T15:29:25.760 に答える