49

私は Intel 対 AT&T の戦争を引き起こしようとしているわけではありません (どちらも Intel の構文をサポートしているため、問題点はあります)、またはどちらが本質的に「優れている」かを尋ねるつもりはありません。どちらかを選択する際の実際的な違いを知りたいだけです。 .

基本的に、数年前に基本的な x86 アセンブリを手に入れたとき、読んでいた本以外の理由で NASM を使用していました。それ以来、アセンブリを使用する理由がほとんどないため、GAS を試す機会がありませんでした。

どちらも Intel 構文 (個人的には好み) をサポートしており、少なくとも理論的には同じバイナリを生成する必要があることを念頭に置いてください (おそらく変更されないことはわかっていますが、意味は変更されるべきではありません)。どちらか一方?

コマンドラインオプションですか?マクロ?ニーモニックでないキーワード?または、他の何か?

ありがとう :)

4

3 に答える 3

29

Intel Syntax : mov eax, 1 (命令先、命令元)

AT&T 構文: movl $1, %eax (命令元、命令先)

Intel の構文は一目瞭然です。上記の例では、移動されるデータの量は、レジスターのサイズ (eax の場合は 32 ビット) から推測されます。使用されるアドレッシング モードは、オペランド自体から推測されます。

AT&T 構文に関しては、いくつかの癖があります。まず、命令lの末尾にあるサフィックスに注意してください。これは、 32 ビットのデータを表し、意味します。他の命令サフィックスに は、ワード (16 ビット - CPU のワード サイズと混同しないでください!)、クワッド ワード (64 ビット)、およびシングル バイトが含まれます。常に必要というわけではありませんが、通常、AT&T 構文を使用するアセンブリ コードは、命令によって操作されるデータの量を明示的に示しています。movlongwqb

ソースオペランドとデスティネーションオペランドで使用されるアドレッシングモードに関しては、より明確にする必要があります。命令自体で値を使用する場合と同様に、アドレス指定を$意味します。immediate上記の例では、 this なしで記述された場合$directアドレッシングが使用されます。つまり、CPU はメモリ アドレス 1 の値をフェッチしようとします (これは、セグメンテーション フォールトを引き起こす可能性が高くなります)。%はアドレッシングを意味します。上記registerの例でこれを含めなかった場合、ラベル付きメモリ アドレスeaxとして扱われ、リンク時にエラーが発生する可能性が高くなります。したがって、両方で使用されるアドレッシング モードについて明示することが必須です。symbolundefined referenceソースオペランドとデスティネーションオペランド。

メモリ オペランドの指定方法も異なります。

Intel : [ベース レジスタ + インデックス * インデックスのサイズ + オフセット]

AT&T : オフセット (ベース レジスタ、インデックス、インデックスのサイズ)

Intel 構文は、メモリ アドレスを見つけるためにどのような計算が行われているのかをより明確にします。AT&T 構文を使用しても結果は同じですが、計算が行われていることを知っている必要があります。

少なくとも理論的には、同じバイナリを生成する必要があります

これはツールチェーンに完全に依存します。

どちらかを支持する理由は何ですか?

もちろん個人的な好みですが、私の意見では、メモリをアドレス指定するときにどの構文がより快適に感じるかということになります。AT&T 構文の強制的な明示性を好みますか? それとも、アセンブラーがこの低レベルの細目を理解することを好みますか?

コマンドラインオプションですか?マクロ?ニーモニックでないキーワード?

これは、アセンブラ (GAS、NASM) 自体に関係しています。繰り返しますが、個人的な好みです。

于 2015-06-20T13:16:12.287 に答える