2016-05-14 12 views
-5

私は8080アセンブリ用の逆アセンブラを作っています。もし私が間違っているなら私を訂正してください: 私がしなければならないことは、バイトごとにバイナリを読んで、各バイトをコマンドに変換することです。 または、コマンドの長さを増やす条件(バイナリ形式)があります。8080アセンブリの明確化

+1

あまりにも(メモリアドレスや即値のような)オペランドがあります。 – Thilo

+2

オペコードは1バイトですが、追加のオペランドが必要な場合は命令全体がそれ以上の場合があります。とにかく命令セットのリファレンスが必要になります。だから、ちょうど1つを見てみませんか? – Jester

答えて

3

なぜdosタグがありますか? 8080ではなく8088を意味しましたか?

いずれにしても、一度に1バイトずつリニアに進むことはできません。それらの命令セットは両方とも可変長命令である。彼らはどのように起動するか、ベクタテーブルまたはエントリアドレスを見なければならず、実行可能なパスに従わなければなりません。

条件分岐または無条件分岐に達するまでリセットしたエントリポイントからリニアに逆アセンブルする2つのエントリポイントが用意されています。無条件分岐はセクションの分解を終了します。

これらのオペコードのうち、どのバイトがオペコードであり、どのバイトが追加データであるかを把握する必要があります。あなたがバイトi j k l mとiを持っているならば、kとlはオペコードです、あるいは命令の最初のバイトを言うことができ、jとmはセカンダリバイトです。次に、kバイトが存在するアドレスへのブランチが見つかった場合、それは問題ありませんが、jが賢いハッカーであるか、問題があるかのどちらかでバイトへの分岐が見つかった場合。そしてその問題が分解を意図的に阻止していたのであれば、時には驚くことはありません。コンパイラで生成されたコードではこの問題は発生しないことがよくありますが、手作業でのアセンブリ(マシンコード)は(意図しないケースでは)さらに時間がかかります。

1

8086の命令セットと比較すると、8080の命令セットは命令の長さが非常に単純です。

  1. 1バイトの命令は、たとえばXRA Aです。
  2. 1バイトの命令の後に1バイトのデータが続きます(例:MVI A,0)。
  3. 1バイト命令の後に2バイトのデータが続きます(例:LXI B,0)。

これは逆アセンブラを本当に簡単にします。実際にこれは私が8080のアセンブリ言語を一般的に学んだ方法です:自分のコンピュータ上で組み込みのBasicインタープリタを逆アセンブルして(PEEKコマンドをたくさん使ってBasicで書かれた逆アセンブラを使って)、知識を使ってBIOSをビルドしてCP/Mをインストールします。

dwelchは、コードが命令の途中にジャンプする可能性があります。次のようにMicrosoft基本インタープリタは、まさにこのトリックを使用:

01 2E 00 
01 2E 01 
01 2E 02 
... code using the value of L 

呼び出しのバイトは、この順序で01のオフセットをゼロにレジスタLを設定する、MVI L,0である、2E 00を実行します。 2つの命令に続いて、レジスタBCを012Eと022Eに設定します。これは無意味です(値は無視されます)。バイトを呼び出す

は、この順序で04をオフセット1つのLXI B無意味です022EにBC設定レジスタ命令、(その値は無視されます)を以下のそこ1にレジスタLを設定する、MVI L,1ある2E 01を実行します。バイトを呼び出す

MVI L,2ある、2E 02を実行し、2

にレジスタLを設定する一番下の行は01だったオフセットた場合に09をオフセット、我々はL = 0で終わるということであるだろう、この順序で07をオフセットオフセット04が呼び出された場合はL = 1、オフセット07が呼び出された場合はL = 2と呼ばれます。各呼び出しには3バイト(CD xxx xx)しかかからず、これらの異なるL値を設定するオーバーヘッドはわずか9バイトです。

L(2バイト)を設定し、L(3バイト)を使用しているルーチンの開始点にジャンプするには、15バイトのいずれかを使用する必要があります。これは呼び出し側の呼び出しが3回ではなく5バイト(Lを設定するには2回、呼び出しを行うには3回)だったことを意味します。

8080分解の楽しみの一部がこのトリックを発見しています。