質問

  1. AT&T構文のすべての定数がその前に「$」を持っている理由を誰でも説明できますか?
  2. すべてのレジスタに「%」があるのはなぜですか?
  3. これは私に多くの足の不自由なタイピングをさせるためのもう一つの試みですか?
  4. また、見つけたのは私だけですか: 16(%esp) 本当に直感に反しています [esp+16]?
  5. 私はそれが同じことにコンパイルされることを知っていますが、なぜ誰かが必要なく「$」と「%」を多くの「$」と「%」と入力したいのでしょうか? - なぜGNUがこの構文をデフォルトとして選択したのですか?
  6. 別のことは、なぜAT&T構文のすべての指示がAN:Lが先行するのですか? - 私はオペランドのサイズについてそれを知っていますが、なぜアセンブラーにそれを把握させないのですか? (私はそのサイズではないオペランドでムーブをやりたいですか?)
  7. 最後のこと:なぜMOV引数が反転しているのですか?

ではない もっと 論理的:

eax = 5
mov eax, 5

AT&Tはここで:

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

注:私はトロールしようとはしていません。私は彼らが行ったデザインの選択を理解していないので、彼らが彼らがしたことをした理由を知るようにしています。

役に立ちましたか?

解決

1、2、3、5:表記はやや冗長ですが、アセンブリで開発するときは良いことだと思います。冗長性は読むのに役立ちます。 「アセンブラーがそれを把握する」ことについてのポイントは、「コードを読み取るプログラマーにそれを把握してみましょう」に簡単に変わります。プログラミングは書き込みのみのタスクではありません。プログラマー自身でさえ自分のコードを読む必要があり、構文の冗長性はかなり役立ちます。

別のポイントは、「%」と「$」は、新しいレジスタを後方互換性を破ることなく追加できることを意味することです。 xmm4, 、それが書かれているように %xmm4, 、これは呼ばれる変数と混同することはできません xmm4 「%」なしで書かれます。

タイピングの量については:通常、アセンブリでプログラミングするとき、ボトルネックは手ではなく脳です。 「$」と「%」があなたを遅くする場合、あなたは通常人間にとって実行可能であると考えられるものよりもはるかに速く考えているか、おそらく手元の仕事はあまりにも機械的であり、でやるべきではありません組み立て;自動コードジェネレーターに任せる必要があります。これは、「C Compiler」として口語的に知られています。

「L」接尾辞は、アセンブラーが「できない」状況を処理するために追加されました。たとえば、このコード:

mov  [esp], 10

曖昧です。なぜなら、値10のバイトを書きたいのか、同じ数値値を持つ32ビットワードを書きたいのかはわかりません。 Intelの構文は次のことを要求します。

mov  byte ptr [esp], 10

あなたがそれについて考えるとき、これは非常に醜いです。 AT&Tの人々は、より合理的なものを作りたかったので、彼らは思いついた:

movb   $10, (%esp)

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

mov   %al, (%ebx)

そして、GNUアセンブラーに「%al」について話しているので、単一のバイトのための動きであることを「把握」させます。それは実際に動作します !それでも、私はまだサイズを指定する方が良いと感じています(読者を本当に助けてくれます。プログラマー自身は、彼自身のコードの最初の読者です)。

「反転」の場合:それは逆です。 Intelの構文は、Cで発生するものを模倣します。Cで発生するもので、右側に値が計算され、左側に書かれています。したがって、読書が左から右に進むことを考慮して、文章は「逆」方向に右から左に進みます。 AT&T構文は「通常の」方向に戻ります。少なくとも彼らは考えました。とにかく独自の構文を使用することを決定したため、彼らは「正しい順序付け」と考えたものでオペランドを使用できると考えていました。これは主に大会ですが、非論理的なものではありません。 C条約は数学的表記を模倣しますが、数学は 定義 値( "xを値5"とする)ではなく 割り当て 値( "値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ベンダーが提供することを意図していました。また、インテルはUNIXの世界では大きなプレーヤーではありませんでした。大きなシステムは主にVaxまたはMotorola 680x0派生物を使用しました。 20年後、MS-DOS PCがデスクトップとサーバーの世界の支配的なアーキテクチャに変わることを誰も理解していませんでした。

他のヒント

1-2、5:おそらく、レジスタなどをプレフィックスすることを選択して、解析を容易にすることを選択しました。あなたは最初のキャラクターで、それがどんな種類のトークンなのかを直接知っています。

4:いいえ。

6:繰り返しますが、おそらくパーサーが出力する命令を把握しやすくすることです。

7:実際、これは文法的な意味でより理にかなっています、動きます どこ. 。おそらく mov 指示は次のとおりです Ld 命令。

誤解しないでください、AT&T構文は恐ろしいと思います。

GNUアセンブラーのAT&T構文は、その起源をUNIXアセンブラーに追跡します 1, 、それ自体がその入力構文を主にPDP-11 PAL-11アセンブラーから取得しました(1970年頃)。

AT&T構文のすべての定数がその前に「$」を持っている理由を誰でも説明できますか?

即時の定数をメモリアドレスと区別することができます。 Intelの構文は、メモリ参照を次のようにして、 [foo].

ちなみに、MASM(Microsoftアセンブラー)は、オペランドがシンボリック定数であるかラベルであるかを知ることができるため、構文レベルで区別を必要としません。 X86の他のアセンブラーは、読者と混同する可能性があるため、そのような推測を積極的に回避します。

PAL-11使用 # のために 即時 オペランドが命令に続いた場合、アドレス指定モード。なしの定数 # 意味した 相対的 アドレス指定モード。相対アドレスが命令に続いた場合。

unixは、DECアセンブラーと同じモードにアドレス指定するために同じ構文を使用し、 * それ以外の @, 、 と $ それ以外の #, 、 以来 @# 入力するのは明らかに不便でした 2.

すべてのレジスタに「%」があるのはなぜですか?

PAL-11では、レジスタはR0 =%0、R1 =%1、... R6としてSPとも呼ばれ、R7はPCとも呼ばれました。 DEC Macro-11マクロアセンブラーは、レジスタを参照することを許可しました %x, 、 どこ x たとえば、任意の表現である可能性があります %3+1 参照 %4.

これは私に多くの足の不自由なタイピングをさせるためのもう一つの試みですか?

いいえ。

また、[ESP+16]と比較して、16(%ESP)が実際に直感に反していることを発見するのは私だけですか?

これはPDP-11からのものです 索引 アドレス指定モード。レジスタの内容と命令に続くインデックスワードを合計することにより、メモリアドレスが形成されます。

私はそれが同じことにコンパイルされることを知っていますが、なぜ誰かが必要なく「$」と「%」を多くの「$」と「%」と入力したいのでしょうか? - なぜGNUがこの構文をデフォルトとして選択したのですか?

PDP-11から来ました。

別のことは、なぜAT&T構文のすべての指示がAN:Lが先行するのですか? - 私はオペランドのサイズについてそれを知っていますが、なぜアセンブラーにそれを把握させないのですか? (私はそのサイズではないオペランドでムーブをやりたいですか?)

ガスは通常それを理解できます。他のアセンブラーも特定の場合に支援が必要です。

PDP-11が使用されます b バイトの指示については、例: CLR vs CLRB. 。 Vax-11に他の接尾辞が登場しました: l 長い間、 w 言葉のために、 f フロートの場合、 d ダブルのために、 q クワッドワードの場合、...

Last thing: why are the mov arguments inverted?

間違いなく、PDP-11はインテルマイクロプロセッサよりも前のものであるため、それは逆です。


  1. Gas Info-Pageによると、BSD 4.2アセンブラーを介して。
  2. UNIXアセンブラーリファレンスマニュアル§8.1-デニスM.リッチー

AT&T構文がIntelと比較してオペランドの順序を反転させる理由は、UNIXが元々開発されたPDP-11が同じ順序のオペランドを使用しているためです。

IntelとDecは、単に反対の注文を選択しました。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top