2016-04-13 16 views
-1

コンパイラが最終的に私にしていることをチェックするために、C++コードの逆アセンブルを開始したばかりなので、これはおそらくnoobの質問です。アセンブリ命令には計算がありますが、これはどのように機能しますか?

const int SIZE = 10000000; 
for(auto i = 0; i < SIZE; i++) 
{ 
    giantVector[i] = giantVector[i] * giantVector[i]; 
} 

これは最終的に(最適化されたリリースビルドでは、マイナスMMX命令)にコンパイルする:ここ

00021088 mov   esi,dword ptr [giantVector] //move a pointer to giantVector into esi 
0002108B xor   eax,eax      //clear out eax 
000210C4 mov   ecx,dword ptr [esi+eax*4] //move int from vector into ecx 
000210C7 imul  ecx,ecx      //multiply ecx by itself 
/* Move the result back into vector. This instruction uses esi as the base pointer 
    to the first element in the vector then adds eax(loop counter) * 4(sizeof(int)) 
    to determine where to stick it. */ 
000210CA mov   dword ptr [esi+eax*4],ecx //move result back into vector 
000210CD inc   eax       //increment the loop counter in eax 
000210CE cmp   eax,989680h     //compare with SIZE constant 
000210D3 jl   main+0C4h (0210C4h)   //If less, jump back into loop, otherwise fall through 

私のコメントだけであり、基本的に私はいくつかのC++のコードを持っている(これはおもちゃの例です)物事の私の理解、私は物事のより良い処理を得るために踏み込んでいます。

私の質問は.. 000210CAでの指示はどうやってできますか? esi + eax * 4は計算自体ではありませんか?その命令そのものが計算に他の命令を必要としないのはなぜですか?本当に何が起こっているのでしょうか?命令はアドレス空間で私に順番に見える。

これはすべてVisual Studio 2015でコンパイルされ、このコードは逆アセンブリデバッグウィンドウから引き出されます。

+1

x86アドレッシングモードについて説明している[この回答](http://stackoverflow.com/questions/34058101/referencing-the-contents-of-a-memory-location-x86-addressing-modes/34058400#34058400) 。はい、 '[base + index * scale]'は有効なアドレスをオペランドの1つとして許可する命令で使用できる有効なアドレッシングモードです。 [x86タグwiki](http://stackoverflow.com/tags/x86/info)のリンクも参照してください。 –

+0

また、 'mov esi、dword ptr [giantVector]'は負荷です。 'std :: vector'は、動的に割り当てられたメモリへのポインタを格納します。あなたは、Cからのasm出力、またはSTLを避けて配列を使用するC++のような出力を理解するのに、ずっと簡単に時間を取ることができます。通常、STLのものはここまでのようにコンパイルされませんが、実際には膨大な量のasmが発生します。 –

+1

@aqezこれは、削除された答えのあなたの質問についてです:LEA命令(ロード実効アドレス)は、x86アドレスを使用して一般的な整数計算を実行するためによく使用されます。簡単な例として、 'eax * = 5'は' LEA eax、[eax + eax * 2] 'で行うことができます。 LEAでは実際にメモリにアクセスすることなく「アドレス」を計算できます。 –

答えて

3

Intel x86アーキテクチャは、scaleは、レジスタ(EAX/EBX/ECX/EDX/ESP/EBP/ESI/EDI)1、2、4、または8、およびindexbaseあるれる形態[scale*index+base]のアドレスを可能にします。このようなアドレスは、SIBバイトと呼ばれるマシン命令バイトを使用して表されます。もちろん、単一のアセンブリ命令の中に任意の計算を組み込むことはできません。

関連する問題