短い答え:コンパイルされ、リンクされた実行可能ファイルを翻訳することはできません。技術的には可能ですが、達成することはほとんどありません(以下を参照)。 ただし、アセンブリのソースファイル(手順とラベルを含む)がある場合は、それを行うことは非常に可能です(ただし、アセンブリソースを取得する場合、プログラムがアセンブリで記述されていない限り、元のプログラムソースコードはまあ、それであなたは最初に異なるアーキテクチャのためにそれをコンパイルする方が良いでしょう)。
長い答え:
QEMUおよびその他のエミュレーターは、命令をその場で翻訳できるため、コンパイルされていないコンピューターで実行可能ファイルを実行できます。プロセスをスピードアップするために、オンザフライでではなく、事前にこの翻訳を行わないのはなぜですか?
原則として簡単に思えるかもしれませんが、実際には、いくつかの主な理由でほとんど不可能です。開始するには、命令セットごとに大幅に異なるアドレス指定モード、異なるオペコード構造、異なるワードサイズが使用され、必要な命令さえないものもあります。
あなたは命令を置き換えるために必要としましょうXYZ
2つの命令で、ABC
とDEF
。これで、プログラム全体のすべての相対/オフセットアドレスがその時点から効果的にシフトされたので、プログラム全体を分析して調べ、オフセットを変更する必要があります(変更前後)。さて、オフセットの1つが大幅に変更されたとしましょう-アドレスのサイズを変更する可能性のあるアドレス指定モードを変更する必要があります。これにより、再びファイル全体を再スキャンし、すべてのアドレスを再計算する必要があります。
アセンブリプログラムを作成する場合、ラベルを使用できますが、CPUは使用しません。ファイルがアセンブルされると、すべてのラベルは相対、絶対、またはオフセットの位置に計算されます。なぜこれがすぐに重要なタスクになり、不可能に近いのかがわかります。単一の命令を置き換えるには、先に進む前にプログラム全体を何百回もパススルーする必要がある場合があります。
アセンブリに関する多少限られた知識から、MOV、ADDなどのほとんどの命令はアーキテクチャ間で移植可能である必要があります。
はい、しかし上で概説した問題を見てください。マシンのワードサイズはどうですか?アドレスの長さ?同じアドレッシングモードもありますか?繰り返しますが、単に「検索して置換」することはできません。プログラムの各セグメントには、明確に定義されたアドレスがあります。他のラベルへのジャンプは、プログラムのアセンブル時にリテラルまたはオフセットメモリアドレスに置き換えられます。
すべてのマシンはチューリング完了なので、直接マッピングされていないものは、他の命令セットにマッピングできます。これを行うのは複雑すぎるでしょうか?何らかの理由で私が慣れていないので、それはまったく機能しませんか?動作しますが、エミュレータを使用するよりも良い結果は得られませんか?
あなたはそれが両方可能であり、はるかに速くなることを100%正しいです。ただし、これを達成するためのプログラムを作成することは、上記で説明した問題を除いて、非常に困難であり、非常にありそうにありません。
実際のアセンブリソースコードがあれば、マシンコードを別の命令セットアーキテクチャに変換するのは簡単です。ただし、マシンコード自体はアセンブルされるため、アセンブリソース(メモリアドレスの計算に使用されるさまざまなラベルを含む)がないと、非常に困難になります。繰り返しますが、単一の命令を変更すると、プログラム全体のメモリオフセットが変更され、アドレスを再計算するために何百ものパスが必要になる場合があります。
数千の命令を持つプログラムに対してこれを行うには、数十万のパスではなくても数十のパスが必要になります。比較的小さなプログラムの場合、これは可能かもしれませんが、プログラム内のマシン命令の数とともにパスの数が指数関数的に増加することに注意してください。まともなサイズのプログラムでは、ほぼ不可能です。