web-dev-qa-db-ja.com

AT&Tアセンブリ構文がこのように設計されたのはなぜですか?

しばしばGAS構文と呼ばれるAT&Tアセンブリ構文は、私を驚かせ続けます。たとえば、パラメータの順序は次のとおりです。

mov $100,%eax /* Destination after source */

これは直感に反しているようです。ほぼすべてのプログラミング言語(および古き良き数学の表記法)は、次のように逆になります:destination before source、このように:

int a = 100;   /* Destination before source (C-style) */
a := 100       // Destination before source (Pascal-style)
mov eax,100    ;  Destination before source (Intel Assembly syntax)

他のポイント、例えば、印章があります... %- s各レジスタの前に$すべての定数リテラル(非常に奇妙に見える効果的なアドレッシング構文の4番目のオペランドとして使用されるものについては、exceptの前)は、コードを混乱させる可能性があります。彼らの利点は何ですか、または何でしたか?

6
Mints97

初心者を怖がらせたり、非常に簡単に行方不明になった可能性があることを知るのに十分賢い人たちを困らせたりする以外に、私はシギルとの契約が何であるかを知りません。うまくいけば、別の回答者がこれについてより多くの洞察を得るでしょう。 (ラチェットフリークがコメントで述べたように、これはおそらく、パーサーを単純化するためにこの方法で行われたものであり、コンピューティングリソースが乏しかった当時はおそらく意味がありました。)

さて、オペランドの順序に関しては、それに対する賛成論と反対の論議がありますが、反対論は勝ちます。

「移動する」ことを考えると、何かが移動するfromある場所to別のものが移動するため、GAS構文は、たとえばIntel構文よりも少し一貫していると主張できます。コードを大声で読む場合、「この値をそのレジスタに移動する」と言っても意味がありませんが、「このレジスタをその値から移動する」と言っても意味がありません。

対照的に、他のアセンブリ言語(Zilogなど)は、これらの命令を「ld」と呼びます。これは「load」を意味します。値がロードされているため、ソースの前に宛先を指定することが理にかなっています。これには、数学の標準的なオペランドの順序に従うという追加の利点がありますが、アセンブリ言語プログラミングはnot数学であるため、これが不要であると主張できます。 。 (似ているものは似ているように見え、違うものは違うように見えるべきです。)

もちろん、「移動」が動詞の最初の間違った選択であると考えると、GAS構文の引数は失われます。これは、「mov」操作の結果としてソースオペランドの内容が失われないためです。ビットは実際にはmovedを取得しませんが、それらはcopyedです。

そして、Intel x86命令セットに「lea」(ロード実効アドレス)などの「move」動詞の代わりに「load」動詞を使用する命令が含まれているという事実により、事態はさらに複雑になります。この場合、GASオペランドどちらの方向から見ても、順序はまったく間違っています。

結論:それは慣例の問題にすぎないので、CPUを構築する人は誰でも自分の優先する慣習を選択し、既存のアセンブラとの互換性を必要としないアセンブラを書く人は、そうしたい場合、独自の慣習。最初のGASアセンブラーは、おそらく規約がソースオペランドファーストであるアーキテクチャ向けに作成されたものであり、その後、アセンブラーを他のアーキテクチャーに移植する際に、命令セットとレジスターセットを変更するだけで十分だと判断しました。すでに負担があるので、少なくとも同じオペランドの順序を守ることはクールだと彼らはおそらく考えました。

4
Mike Nakis

簡単な答えは、ほとんどのプロセッサのバイナリ命令が配置される順序です。

男性が男性で羊が怖かった頃、アセンブリプログラマーは生のバイナリコードを調べるのに多くの時間を費やしました(コントロールパネルのオン/オフライトからどの命令がハングしているかを推測しようとすることもありました)。アセンブリコードがinstruction,target,sourceマシンコードの順序。

2
James Anderson