2012-04-06 8 views
1

アセンブリ言語でいくつかの演習を行っていますが、わからない最適化に関する質問がありました。誰もが彼らとアセンブラコードの最適化(intel x86)

を私を助けることができますので、質問には、以下のアセンブリコードを最適化することです:

------------------------- ---例1 -------------------------

mov dx, 0 ---> this one I know-> xor dx,dx 

-------------- --------------例2 ------------------------

cmp ax, 0 
je label 

---- ------------------------例3 -------------------------

mov ax, x 
cwd 
mov si, 16 
idiv si  

---->私はこの例ではと考えることができ、ほとんどが潜水艦にIDIV 16による最後の2行ですが、私は

わかりません------------ ----------------例4 -------------------------

mov ax, x 
mov bx, 7 
mul bx 
mov t, ax 

- --------------------------- Example5 ---------------------- -----

mov si, offset array1 
mov di, offset array2 
; for i = 0; i < n; ++i 
do: 
    mov bx, [si] 
    mov [di], bx 
    add si, 2 
    add di, 2 
loop do 
endforloop 

答えて

5

たとえば、andまたはtestオペコード。例1と同様に、定数の必要性を取り除くことができます。

たとえば、x * 7x * (8 - 1)と同じか、またはそれを拡張してx * 8 - xであることを覚えておいてください。シフト命令で8を乗算することができます。

例5では、インテルがSIからDIへの転送方法をもっと簡単に提供してくれたと思いますたぶんREPetitive MOVe String Wordのようなものかもしれません:-)

+0

ありがとうございます。本当に役に立ちます。 – Alex

0

たとえば、3の除数は2のべき乗で右シフトとして実装できます。

例5では、現在のコードが必要に応じてCXを初期化できないことに注意してください(最適化されたバージョンでは、やはりそうしたいと思います)。

+0

よくある誤解。 'idiv'は符号付き整数で動作し、' -3/2!= -3 >> 1'です。 – Voo

+0

@Voo:x86命令セット、特にshr(論理シフト右)とsar(算術シフト右)の両方を持っていることを少し注意深く見ていく必要があります。 'sar'は正または負の数値を2の累乗で除算して算術的に正しい結果を返します。 –

+0

ポイントを逃しません。サインビットが拡張されているわけではありません。基本的に3つの異なる分割モード(切り捨て、モジュラス、フロア)があります。右シフトトリックを拡張する符号は、モジュラスとフロア定義のためにのみ機能します。今問題は、Cとcoがすべて部門を切り捨てることを要求し、うまく機能しないということです。したがって、 '-3/2 == -1'、' -3 >> 1 == -2'です。 (2つの追加の命令で修正することができますが、通常ははるかに効率的です) – Voo