Windows system >> Windowsの知識 >  >> Linuxシステムチュートリアル >> Linuxチュートリアル >> LinuxでのAT&T Grammar入門(アセンブリ構文としてのGNU)

LinuxでのAT&T Grammar入門(アセンブリ構文としてのGNU)

  

長い間、私はC言語レベルで勉強し、一生懸命働いてきました。答えを見つけてください。プログラマーは完璧を追求する集団です、そして、彼の頭の中の少しのブラックホールさえ彼を落ち着かせません。少し前までは、itputフォーラムで、古典的な本 "Computer Systems A Programmer's Perspective"(以下、CS.APPと呼びます)が夕方にパズルを解くために読まれました。この本は私の疑問のいくつかに前向きな回答をしていませんでしたが、混乱しないための道を開くように私に指示してくれました。

アセンブリ言語は機械語に非常に近い言語であり、ステートメントと機械語命令の対応はより単純で明確になります。アセンブリドアを開くことは、高級言語がもたらす疑念を和らげるだけでなく、現代のコンピュータのオペレーティングシステムをよりよく理解することを可能にし、そしてさらに重要なことに、それはあなたに自信を与えます。 Hou Jieの「浮遊砂の中にプラットフォームを構築しない」という呼びかけに応えて、高さが落ちるのではないかという不安を軽減する。集会を学ぶ目的は今では以前とは大きく異なります。 CS.APPに記載されているように、プログラマがアセンブリ内で直接プログラムを書くことを要求することから始めて、プログラマがアセンブリを学ぶ必要性は時とともに変化し、そして今最適化コンパイラを読んで理解することを必要とする。生成コード'読んで理解することができるので、これはまさに私のニーズと目標です。

大学での編集、主にMicrosoft MASMマクロの編集との接触がありましたが、当時の理解は十分ではなく、態度も正しくなく、よい学習機会を逃していました。ほとんどの場合、私はUNIXシリーズのプラットフォームで作業するためにGCCを使用しますが、アセンブリ言語の選択は、もちろん、GNUアセンブリ構文がCS.APPで使用されているのと同じように、GNUアセンブリです。学習コンパイルの主な目的は「分解」であるため、形式はほとんどCコードとアセンブリコードの比較です。

1、アセンブリはより多くのことを見せます使用する言語のレベルが上がるにつれて、あなたの目の中のコンピュータはますますぼやけ、そしてあなたの焦点は言語自体にますます近くなるでしょう。反対側の「問題ドメイン」、例えば、JAVAを通して、あなたはその仮想マシンをもっと見ることができます、しかしあなたは本当のコンピュータを見ることはできません; Cを通して、あなたはメモリの1つの層しか見ることができません。あなたは、レジスタ層に深く入り、自由に遊ぶことができます。アセンブラから見た「ユニークなランドスケープ」は次のとおりです。a)プログラムカウンタ(%eip) - 永遠に実行される次の命令のアドレスを格納する特殊レジスタb)整数レジスタそれぞれ合計8つの%eax、%ebx、%ecx、%edx、%esi、%ebi、%esp、および%ebp。整数データの格納、アドレスの格納、およびプログラムステータスの記録も可能です。初期の頃は、それぞれのレジスタには特別な目的がありましたが、今ではLinuxのようなプラットフォームでは「プレーンアドレス指定」[1]が使用されるため、レジスタの特殊性はそれほど明白ではありません。 c)条件フラグレジスタ - 制御フローで条件変更を実行するために、最後に実行された算術命令のステータス情報を格納します。 d)浮動小数点レジスタ - その名前が示すように、浮動小数点数を格納するために使用されます。レジスタの特殊性の度合いは弱まっていますが、実際には、各コンパイラはこれらのレジスタを使用する際に依然として一定の規則に従います。これについては後で説明します。

2、アセンブリの最初の部分は単純なC関数です。void dummy(){int a = 1234; int b = a;}次のようにgccと-Sオプションを使用してアセンブリコードに変換します。一部省略しています):movl $ 1234、-4(%ebp)movl -4(%ebp)、%eaxmovl%eax、-8(%ebp)はまだ見ていませんが、それでも読むことはできません。 %ebp、%eaxなど、上記のようにこれは単なる紹介です。編集「face」の感性を教えてください。少し見てみましょう。一見すると、アセンブリコードは非常によく似ていますが、アセンブリコードは "order + operand"のステートメントの集まりです。アセンブリ命令は固定されており、各命令には独自の固定目的があり、オペランド表現にはさまざまな種類があります。

1)オペランドは、ほとんどのアセンブリ命令に命令操作のソースとデスティネーションを含む1つ以上のオペランドがあることを示します。標準命令フォーマットはおおよそ次のようなものです。「命令+ソースオペランド+デスティネーションオペランド」。ここで、ソースオペランドは即値、レジスタから読み取られた番号、またはメモリから読み取られた番号です。デスティネーションオペランドはレジスタまたはメモリのどちらかです。この分類によると、おおまかに3つのタイプのオペランドがあります:a)即値表記 - < 1 $ 1234、-4(%ebp)< 1234 $>のように、オペランドとしての即値GNUのアセンブリ構文によれば、即値は' $ + integer'として表されます。上記の例のように、即値データはコード内のいくつかの定数を表すためによく使用されます。たとえば、$ 1234です。即値をデスティネーションオペランドとして使用することはできません。 b)レジスタ表記 - これは比較的簡単です。レジスタの内容です。上記の "movl -4(%ebp)のように、%eax in%eax"はソースのオペランドとしてレジスタ表記を使用していますが、 "movl%eax、-8(%ebp)の%eax"では、デスティネーションオペランドとしてレジスタ表記が使用されます。 c)メモリ参照表記 - このオペランドの計算値は、対応するメモリアドレスを表します。アセンブリ命令は、このメモリアドレスに基づいて対応するメモリ位置にアクセスします。上記の例では、 "movl -4(%ebp)、%eax - "の中のそれが表すメモリアドレスは(%ebpレジスタの内容-4)です。

2)データ転送命令アセンブリ言語で最も一般的に使用されている命令、つまりデータ転送命令は、私たちが最初に晒されるアセンブリ命令の種類です。命令のフォーマットは、“ movソースオペランド、デスティネーションオペランド”である。 movシリーズは、最小1バイトから最大ダブルワードへのアクセスと転送をサポートしています。 movbを使用して1バイトの情報を転送する場合、movwを使用して2バイト、つまり1ワードの情報を転送し、movlを使用してダブルワード情報を転送します。これらについては詳しく述べられていません。これに加えて、movシリーズは、ビット拡張子movsblとmovzblを持つ2つの命令も提供しています。

================================= ============================================================================================ハードウェアプラットフォームと緊密に統合されたプログラミング言語は、オペレーティングシステム
、組み込み開発などの分野で重要な役割を果たしています。アセンブリはハードウェアアーキテクチャ(CPU命令コード)に依存しているため、異なるアーキテクチャでのアセンブリ言語はまったく異なります。この記事では、LinuxでのAT&T構文(アセンブリ構文としてのGNU)とLinuxでの基本的なアセンブリ方法について簡単に説明します。

AT&T構文は、AT& T Bell Labsに由来し、UNIXシステムの実装に使用されるプロセッサオペコード構文の上に形成されました。AT& T構文とインテル構文の主な違いは次のとおりです。 AT& Tは即値に$を使用しますが、Intelは使用しません。つまり、AT& Tは10進数2の$ 2、Intelは%beforeレジスタの%に対して2AT& T、%eaxAT& T処理オペランドのeaxレジスタなどです。例えば、Intelとは反対に、movl%eax、%ebxはeaxの値をebxに渡し、Intelはそのようなmov ebxであり、eaxAT& Tは操作内のデータの長さを示すためにニーモニックの後に1文字を追加します。例えば、movl $ foo、%eaxは、Intelのmov eax、word ptr fooと同等です。

Copyright © Windowsの知識 All Rights Reserved