2017-03-20 4 views
3

"cmp"の代わりに "or"を使用すると大きな正の品質がありますか?なぜ0をチェックするときにcmpを使用するか、代わりに

は、この関数のプロローグを考えてみましょう:

push ebp 
mov ebp,esp 
push ebx 

xor eax,eax  ;error return code 
mov ecx,[ebp +8] ;first integer arg after return addr. 
mov edx,[ebp +12] ;second integer argument 

機能はa/bまたはa % bを計算するものとします。
まず、0除数をチェックする必要があります。

私の直感的な動きが

cmp edx,0 
je InvalidDivisor 

を組み立てることであろう。しかし、私は、アセンブラに高度な図書に見たときにも使用されます。この:

or edx,edx 
jz InvalidDivisor 

この第二の溶液「より、なぜ私の質問は正しい"?
or-演算を計算してゼロフラグをチェックするのに、2つの値を比較するよりも時間がかかりませんか?

より高度なコーディングスタイルの問題ですか?

+0

これらはレイテンシとスループットは同じですが、マシンコードに直接エンコードする必要がないため、「または」形式は小さくなります。 – Michael

+0

これは何度も尋ねられ、回答されました。重複したリンクを見つける必要があります... –

+1

[またはeax、eaxとtest eax、eaxの違い]の可能な複製(https://stackoverflow.com/questions)/23691989/difference-between-or-eax-eax-and-test-eax-eax) –

答えて

3

or edx,edxは2バイトで、cmp edx, 0は3つで、サイズを気にする場合はどちらを選択するかわかります。

スピードを気にする人は、実際に測定する必要があります。 Orは明らかにレジスタを "変更"し、次の命令が同じレジスタを使用する場合はレイテンシを追加する可能性があります。

The best choice for comparing a register with zero is test reg, reg.

83 fa 00 cmp edx,0x0 
09 d2  or  edx,edx ; Smaller 
85 d2  test edx,edx ; Smaller and better, updates ZF but does not store the result 
+0

このアンサーは、より複雑な説明へのリンクを掲示し、他のすべてのポスターに感謝してくれてありがとう – clockw0rk

1

あなたは、これは何のためにあるのかプロセッサ明記していないが、一般的に:

あなたは、アセンブラでコーディングしているので、あなたは、メモリおよびクロック・サイクルを気に。

EAXがゼロであるかどうかを検出するだけです。 EAXは、EAXの内容に副作用がなく、0と直接比較するよりも速く、EAXがゼロの場合はZステータスビットを設定します。

レジスタを即値と比較すると、ロードに余分なサイクルがかかり、定数値 '0'に余分なバイト(または2または4)がかかる可能性があります。
一方、限られた数のレジスタがあり、EAXへの参照は、3ビットまたは4ビットを使用して命令に直接エンコードされる可能性があります。

3

両方の命令がに組み立てる:あなたはorを使用して見ることができるように

83 fa 00    cmp edx,0x0 
09 d2     or  edx,edx 

は短いです(実行時にロードするので、少ないコード)と同じ効果があります。 edxがゼロであり、さらに操作が、彼らはCPUがそれを把握していない場合でも、結果に依存する必要がないことがわかっている場合もゼロフラグを設定する

85 d2     test edx,edx 

を:しかし、使用することを実際に優れています既に。

1

問題の例は、Intelのx86用ですが、CMPおよびOR命令は、他のプロセッサに存在します。

レジスタがあまりなく、ステータスフラグにパラメータや戻り値を渡す可能性があるMOS 6502では、Cフラグに影響する命令は避けたい場合があります。したがって、EOR(排他的OR)、AND、ORをCMPよりも優先させることができます。 6502では、データをコピーする命令のほとんどすべてがNフラグとZフラグに影響します。

Atmel 8ビットAVRマイクロコントローラシリーズでは、正しく覚えていれば、フラグに影響を与えない便利な命令CPSE(比較とスキップが等しい場合)があります。 AVR-GCCは、32個のレジスタのうちの1つを「ゼロレジスタ」として指定し、そのレジスタでCPSEを使用するコードを発行します。

関連する問題