オブジェクトコード、マシンコード、アセンブリコードの違いは何ですか?
それらの違いを視覚的に示していただけますか?
マシンコードは、CPUによって直接実行できるバイナリ(1および0)コードです。テキストエディタでマシンコードファイルを開くと、印刷できない文字を含むゴミが表示されます(いいえ、印刷できない文字ではありません;))。
オブジェクトコードは、完全なプログラムにまだリンクされていないマシンコードの一部です。完成した製品を構成するのは、特定のライブラリまたはモジュールのマシンコードです。また、完成したプログラムのマシンコードにないプレースホルダーまたはオフセットが含まれている場合もあります。リンカは、これらのプレースホルダーとオフセットを使用して、すべてを相互に接続します。
アセンブリコードはプレーンテキストであり、(ある程度)人間が読み取れるソースコードであり、ほとんどの場合、機械命令を含む直接1:1アナログを備えています。これは、実際の命令、レジスタ、またはその他のリソースのニーモニックを使用して実現されます。例にはJMP
、MULT
CPUのジャンプおよび乗算命令が含まれます。マシンコードとは異なり、CPUはアセンブリコードを理解しません。アセンブラまたはコンパイラを使用してアセンブリコードをマシンコードに変換しますが、通常、コンパイラはCPU命令からさらに抽象化された高級プログラミング言語に関連付けられていると考えられます。
完全なプログラムを構築するには、アセンブリまたはC++などの高級言語でプログラムのソースコードを作成する必要があります。ソースコードは、オブジェクトコードにアセンブル(アセンブリコードの場合)またはコンパイル(高級言語の場合)され、個々のモジュールがリンクされて、最終的なプログラムのマシンコードになります。非常に単純なプログラムの場合、リンク手順は必要ない場合があります。IDE(統合開発環境)の場合など、他の場合には、リンカーとコンパイラーを一緒に呼び出すことができます。また、複雑なmakeスクリプトまたはソリューションファイルを使用して、最終的なアプリケーションの構築方法を環境に指示する場合もあります。
異なる動作をするインタプリタ言語もあります。解釈される言語は、特別なインタプリタプログラムの機械語に依存しています。基本レベルでは、インタプリタがソースコードを解析し、すぐにコマンドを新しいマシンコードに変換して実行します。最近のインタプリタは、今でははるかに複雑になっています。一度にソースコードのセクション全体を評価し、可能な場合はキャッシュと最適化を行い、複雑なメモリ管理タスクを処理します。
プログラムの最後のタイプの1つは、ランタイム環境または仮想マシンの使用を含みます。この状況では、プログラムは最初に低レベルの中間言語またはバイトコードにプリコンパイルされます。次に、バイトコードは仮想マシンによってロードされ、仮想マシンはそれをネイティブコードにジャストインタイムでコンパイルします。ここでの利点は、仮想マシンが、プログラムの実行時およびその特定の環境で利用可能な最適化を利用できることです。コンパイラは開発者に属しているため、多くの場所で実行できる比較的一般的な(最適化されていない)マシンコードを生成する必要があります。ただし、ランタイム環境または仮想マシンはエンドユーザーのコンピューター上にあるため、そのシステムが提供するすべての機能を利用できます。
他の回答は違いをよく説明していましたが、ビジュアルも求めました。これは、C コードから実行可能ファイルへの移行を示す図です。
アセンブリコードは、人間が読める形式のマシンコードです。
mov eax, 77
jmp anywhere
マシンコードは純粋な16進コードです。
5F 3A E3 F1
オブジェクトファイルのようなオブジェクトコードを意味していると思います。これはマシンコードの変形ですが、リンカがジャンプを埋めることができるようにジャンプがパラメータ化されているという違いがあります。
アセンブラは、アセンブリコードをマシンコード(オブジェクトコード)に変換するために使用されます。リンカは、いくつかのオブジェクト(およびライブラリ)ファイルをリンクして、実行可能ファイルを生成します。
私はかつて純粋なヘックスでアセンブラプログラムを書いたことがあります(アセンブラは利用できません)。幸いなことに、これは古き良き(古代の)6502に戻ったものです。しかし、ペンティアムオペコード用のアセンブラがあるのはうれしいです。
8B 5D 32
マシンコードです
mov ebx, [ebp+32h]
組み立てです
lmylib.so
含まれ8B 5D 32
ているのはオブジェクトコードです
まだ言及されていない点の 1 つは、アセンブリ コードにはいくつかの異なる種類があるということです。最も基本的な形式では、命令で使用されるすべての数値を定数として指定する必要があります。例えば:
$1902: BD 37 14 : LDA $1437,X $1905: 85 03 : STA $03 $1907: 85 09 : STA $09 $1909: CA : DEX $190A: 10 : BPL $1902
上記のコードを Atari 2600 カートリッジのアドレス $1900 に格納すると、アドレス $1437 から始まるテーブルからフェッチされた行数が異なる色で表示されます。一部のツールでは、上記の行の右端にアドレスを入力すると、中央の列に示されている値がメモリに保存され、次のアドレスで次の行が開始されます。その形式でコードを入力することは、16 進数で入力するよりもはるかに便利でしたが、すべての正確なアドレスを知る必要がありました。
ほとんどのアセンブラでは、シンボリック アドレスを使用できます。上記のコードは、次のように記述されます。
rainbow_lp: lda ColorTbl,x sta WSYNC sta COLUBK デックス bpl rainbow_lp
アセンブラは、LDA 命令を自動的に調整して、ラベル ColorTbl にマップされたアドレスを参照するようにします。このスタイルのアセンブラを使用すると、すべてのアドレスを手動で管理しなければならない場合よりも、コードの作成と編集がはるかに簡単になります。
アセンブリは、CPU が実際に使用するマシン コードに直接変換できる、人間が理解できる短い説明用語です。
人間にはある程度理解できますが、アセンブラーはまだ低レベルです。有用なことを行うには、多くのコードが必要です。
その代わりに、C、BASIC、FORTAN などの高水準言語を使用します (OK、私は自分自身とデートしたことがあります)。これらをコンパイルすると、オブジェクト コードが生成されます。初期の言語には、オブジェクト コードとして機械語がありました。
今日、JAVA や C# などの多くの言語は通常、マシン コードではなく、実行時に簡単に解釈されてマシン コードを生成するバイトコードにコンパイルされます。
これらが主な違いだと思います
読みやすさは、わずかな労力で作成されてから 6 か月後にコードを改善または置換することができます。一方、パフォーマンスが重要な場合は、低レベル言語を使用して、本番環境にある特定のハードウェアをターゲットにすることができます。より高速な実行。
IMO 今日のコンピューターは、プログラマーが OOP で高速に実行できるほど高速です。