Intel Syntax : mov eax, 1 (命令先、命令元)
AT&T 構文: movl $1, %eax (命令元、命令先)
Intel の構文は一目瞭然です。上記の例では、移動されるデータの量は、レジスターのサイズ (eax の場合は 32 ビット) から推測されます。使用されるアドレッシング モードは、オペランド自体から推測されます。
AT&T 構文に関しては、いくつかの癖があります。まず、命令l
の末尾にあるサフィックスに注意してください。これは、 32 ビットのデータを表し、意味します。他の命令サフィックスに
は、ワード (16 ビット - CPU のワード サイズと混同しないでください!)、クワッド ワード (64 ビット)、およびシングル バイトが含まれます。常に必要というわけではありませんが、通常、AT&T 構文を使用するアセンブリ コードは、命令によって操作されるデータの量を明示的に示しています。mov
long
w
q
b
ソースオペランドとデスティネーションオペランドで使用されるアドレッシングモードに関しては、より明確にする必要があります。命令自体で値を使用する場合と同様に、アドレス指定を$
意味します。immediate
上記の例では、 this なしで記述された場合$
、direct
アドレッシングが使用されます。つまり、CPU はメモリ アドレス 1 の値をフェッチしようとします (これは、セグメンテーション フォールトを引き起こす可能性が高くなります)。%
はアドレッシングを意味します。上記register
の例でこれを含めなかった場合、ラベル付きメモリ アドレスeax
として扱われ、リンク時にエラーが発生する可能性が高くなります。したがって、両方で使用されるアドレッシング モードについて明示することが必須です。symbol
undefined reference
ソースオペランドとデスティネーションオペランド。
メモリ オペランドの指定方法も異なります。
Intel : [ベース レジスタ + インデックス * インデックスのサイズ + オフセット]
AT&T : オフセット (ベース レジスタ、インデックス、インデックスのサイズ)
Intel 構文は、メモリ アドレスを見つけるためにどのような計算が行われているのかをより明確にします。AT&T 構文を使用しても結果は同じですが、計算が行われていることを知っている必要があります。
少なくとも理論的には、同じバイナリを生成する必要があります
これはツールチェーンに完全に依存します。
どちらかを支持する理由は何ですか?
もちろん個人的な好みですが、私の意見では、メモリをアドレス指定するときにどの構文がより快適に感じるかということになります。AT&T 構文の強制的な明示性を好みますか? それとも、アセンブラーがこの低レベルの細目を理解することを好みますか?
コマンドラインオプションですか?マクロ?ニーモニックでないキーワード?
これは、アセンブラ (GAS、NASM) 自体に関係しています。繰り返しますが、個人的な好みです。