23
  1. AT&T 構文のすべての定数の前に「$」がある理由を誰か説明できますか?
  2. すべてのレジスタに「%」があるのはなぜですか?
  3. これは、私に多くの不完全なタイピングをさせようとする単なる別の試みですか?
  4. また、見つけたのは私だけ16(%esp)です[esp+16]か?
  5. 私はそれが同じものにコンパイルされることを知っていますが、なぜ誰かが必要なくたくさんの「$」と「%」を入力したいのでしょうか? - GNU がこの構文をデフォルトとして選択したのはなぜですか?
  6. もう 1 つのことですが、at&t 構文のすべての命令の前に : l があるのはなぜですか? -オペランドのサイズについては知っていますが、アセンブラにそれを理解させないのはなぜですか? (そのサイズではないオペランドで movl を実行したいと思うことはありますか?)
  7. 最後に: mov 引数が逆になっているのはなぜですか?

次のほうが論理的ではないでしょうか。

eax = 5
mov eax, 5

at&t は次のとおりです。

mov 5, eax
5 = a (? wait what ?)

注: 荒らすつもりはありません。彼らが行った設計上の選択を理解していないだけで、なぜ彼らがそうしたのかを理解しようとしています.

4

4 に答える 4

30

1、2、3、および 5: 表記はやや冗長ですが、アセンブリで開発する場合は良いことだと思います。冗長性は読書に役立ちます。「アセンブラーに考えさせる」というのは、「コードを読むプログラマーに考えさせる」に変わりやすく、自分が読む側になると好きになれません。プログラミングは書き込み専用のタスクではありません。プログラマ自身でさえ自分のコードを読む必要があり、構文の冗長性はかなり役立ちます。

もう 1 つのポイントは、'%' と '$' は、下位互換性を損なうことなく新しいレジスタを追加できることを意味することです。たとえば、 と呼ばれるレジスタを追加しても問題はxmm4あり%xmm4ません。これはxmm4「%」なしで記述されます。

タイピングの量に関しては、通常、アセンブリでプログラミングする場合、ボトルネックは手ではなく頭脳です。'$' と '%' によって速度が低下する場合は、人間が実行できると通常考えられているよりもはるかに速く考えているか、または、目の前のタスクがあまりにも機械的であり、時間内に行うべきではない可能性が高いです。組み立て; それは、口語的に「Cコンパイラ」として知られている自動コードジェネレータに任せるべきです。

「l」サフィックスは、アセンブラが「できない」状況を処理するために追加されました。たとえば、次のコード:

mov  [esp], 10

値 10 のバイトを書き込むか、同じ数値の 32 ビット ワードを書き込むかがわからないため、あいまいです。次に、インテルの構文は次のように呼び出します。

mov  byte ptr [esp], 10

あなたがそれについて考えるとき、それはかなり醜いです。AT&T の人々は、より合理的なものを作りたがっていたので、次のように考えました。

movb   $10, (%esp)

そして彼らは体系的であることを好み、どこにでも「b」(または「l」または「w」)の接尾辞を付けました. サフィックスは必ずしも必要ではないことに注意してください。たとえば、次のように記述できます。

mov   %al, (%ebx)

GNUアセンブラに「%al」について話しているので、1バイトの移動であることを「理解」させます。それは実際に動作します !それでも、サイズを指定する方が良いと思います (これは読者にとって本当に役に立ちます。また、プログラマー自身が自分のコードの最初の、そして何よりも重要な読者です)。

「反転」の場合:逆です。Intel の構文は C で発生するものを模倣しており、値は右側で計算され、左側に書き込まれます。したがって、読み取りが左から右に進むことを考慮して、書き込みは「逆」方向に右から左に進みます。AT&T 構文は「通常の」方向に戻ります。少なくとも彼らはそう考えた。とにかく独自の構文を使用することに決めたので、「正しい順序」と考えられるオペランドを使用できると考えました。これはほとんど慣例ですが、非論理的なものではありません。C の規則は数学表記法を模倣していますが、数学は値を定義すること (「x を値 5 にする」) であり、値を代入すること ("AT&T の選択は理にかなっています。混乱を招くのは、C コードをアセンブリに変換するときだけです。このタスクは通常、C コンパイラに任せるべきです。

質問 5 の最後の部分は、歴史的な観点から興味深いものです。x86 用の GNU ツールは AT&T の構文に従いました。当時、彼らは Unix の世界 (「GNU」は「GNU は Unix ではない」という意味) に定着しようとしていて、Unix ツールと競合していたからです。Unix は AT&T の管理下にありました。これは、Linux や Windows 3.0 の時代よりも前のことです。PC は 16 ビット システムでした。Unix は AT&T 構文を使用したため、GNU は AT&T 構文を使用しました。

良い質問は、なぜ AT&T は独自の構文を発明することが賢明であると判断したのかということです。上記のように、彼らにはいくつかの理由がありましたが、メリットがないわけではありませんでした。もちろん、独自の構文を使用することの代償は、相互運用性が制限されることです。当時、C コンパイラやアセンブラは個別のツールとしてはあまり意味がありませんでした。Unix システムでは、これらは OS ベンダーによって提供されることを意図していました。また、Intel は Unix の世界では大きなプレーヤーではありませんでした。大規模なシステムでは、ほとんどの場合、VAX または Motorola 680x0 の派生物が使用されていました。MS-Dos PC が 20 年後、デスクトップとサーバーの世界で支配的なアーキテクチャになるとは誰も予想していませんでした。

于 2010-11-16T13:25:40.493 に答える
11

1-2, 5: 彼らはおそらく、解析しやすくするためにレジスターなどにプレフィックスを付けることを選択しました。最初の文字で、それがどのような種類のトークンであるかが直接わかります。

4:いいえ。

6: 繰り返しますが、おそらく、パーサーがどの命令を出力するかを理解しやすくするためです。

7: 実際には、これは文法的な意味でもっと理にかなっています。おそらく、mov命令はld命令であるべきです。

誤解しないでほしいのですが、AT&T の構文はひどいものだと思います。

于 2010-11-16T12:03:30.407 に答える