私は命令とそれに対応するオペコードを見ていました。「je」や「jz」などの命令のオペコードは同じです。
je,jz - 0x74 (8 bit)
je,jz - 0x0f84 (16/32 bit).
なぜそのような冗長な指示があるのでしょうか?
アセンブリコーディングが簡単になるからですか?つまり、場合によっては「等しい場合にジャンプ」し、他の場合には「ゼロにジャンプ」する方が理解しやすいということです。しかし、最近では実際にアセンブリでコーディングすることはありません。
私たち全員が学校で持っていたコンピューター アーキテクチャの本からの古い引用は何ですか? 「x86 には何も問題はありません。多くのことが意味をなさないだけです。」
あなたの質問に答えるには:「ゼロでジャンプ」と「等しい場合はジャンプ」はどちらも、前の命令の結果に基づいた宛先アドレスへのジャンプであるためです。つまり、前の命令の結果によってゼロ フラグ (ZF) が 1 に設定されます。JZ は「数学」用であり、JE は「比較」用である可能性があります。したがって、プログラマーの観点からは、ニーモニックを 2 つにすることはある程度理にかなっています。おそらく、初期のアセンブラー作成者は、別の一般的なアセンブリ言語を模倣しようとしていたのでしょう。
Jcc (条件付きジャンプ命令のセット) の Intel x86 マニュアルを見ると、JZ と JE の両方が本質的に「等しい場合は近くにジャンプ (ZF=1)」を意味することがわかります。そして、ドキュメントでは、これは特定のジャンプ命令セットに共通していると実際に述べています。
ステータス フラグの特定の状態は 2 つの方法で解釈される場合があるため、一部のオペコードに対して 2 つのニーモニックが定義されています。たとえば、JA (上にジャンプ) 命令と JNBE (下または等しくない場合にジャンプ) 命令は、オペコード 77H の代替ニーモニックです。
それらは同じ命令の異なる同義語です。命令は、Z フラグに基づいて分岐するだけです。コンペアイコール命令の結果が真の場合、Z フラグがセットされます。また、たまたまゼロになる値をテストすると、設定されます。
英語を話す人がトラックと言い、他の人がローリーと言うのはなぜですか? 誰もが 1 つの標準に準拠するよう強制する必要がありますか? ハンバーガーは全部ビッグマック...
まず、アセンブリでプログラムを実行します。他の人がそうする必要がないように、十分な数の人がそうしています。コンパイラはそれに大きく依存しています。それなしでは、コンパイラとプロセッサを開発してデバッグすることは困難です。コンパイラとプロセッサがなければ、私たちはどうするでしょうか?
アセンブラ パーサーが等しい場合のジャンプとゼロ ビットが設定されている場合のジャンプを受け入れるようにするのは簡単です。これらは同じ関数、同じ命令です。フラグを理解して使用する人 (z フラグは簡単ですが、signed と unsigned のキャリーはそうではありません) は、フラグがキャリーの場合はジャンプ、ゼロの場合はジャンプなどを使用するのが好きです。これらの特定の数値の関係の観点から考える人その特定の操作について、等しい場合はジャンプ、より大きい場合はジャンプ、より小さい場合はジャンプなどを確認したい。等しい場合はジャンプ、より小さい場合はジャンプなどを取り除き、c が設定されている場合はジャンプ、c がクリアされている場合はジャンプ、n==v の場合はジャンプ、n!=v の場合はジャンプなどのフラグを設定することをお勧めします。
Intel は、これが見られる最初または最後のアーキテクチャではありません。同じ理由で、ステータス レジスタのビットがオンまたはオフであると考える人もいれば、これはそれよりも大きいと考える人もいると思います。z フラグを知っているということは、プロセッサーが z フラグを持っていた限り、同等であったことを意味しますが、x86 ファミリーやその間抜けな命令セットの時代とは何の関係もありません。このように開発者にとって使いやすいものにすることで、開発者はプロセッサに惹きつけられます。ツールに実装するのは簡単です。
これについて本当に知りたいのなら、同じ命令セットに対して intel 構文と AT&T 構文があるのはなぜですか? その狂気は、等しい場合のジャンプ(ゼロビットが設定されている)とゼロビットが設定されている場合のジャンプをはるかに超えています。
今ではあまり使われていないとはいえ、インテルのアセンブリ言語は古いものです。元の 8086 および 8088 プロセッサは 1970 年代のものであることを思い出してください...
むかしむかし、IBM PC/XT のようなものをまだアセンブリで書いていたとき、
CMP AX, BX
JE Somewhere
また
AND AX, BX
JZ somewhere_else
それらがたまたま同じハードウェア命令にマップされたことは重要ではありません。
今日最も広く使用されているプログラミング言語ではありませんが、それでも使用されています。g++ はアセンブリ コードをコンパイルできます。自分が何をしているのかを知っていれば、明確な速度の利点が得られます。
あなたの質問に関しては、はい、あなたは正しいです。状況に応じて、同じオペコードを持つ異なる命令につながる何らかの方法を考えることが役立ちます。