2010-11-20 1 views
2

最近masmのアセンブリを学び始めました。私のプログラムの多くを逆アセンブルしました。私はあなたが__int16(単語)を使用するとき、その値が最初にeaxにコピーされて変数そのものになることに気がつきましたが、int(dword/32)では変数に直接コピーされます:__int16とint(32)がC++で異なるasmを生成するのはなぜですか?

int y = 5; 
0040101E mov   dword ptr [y],5 

    y += 7; 
00401025 mov   eax,dword ptr [y] 
00401028 add   eax,7 
0040102B mov   dword ptr [y],eax 

    __int16 x = 3; 
0040102E mov   eax,3 
00401033 mov   word ptr [x],ax 

    x += 6; 
00401037 movsx  eax,word ptr [x] 
0040103B add   eax,6 
0040103E mov   word ptr [x],ax 

私は、__int16のサイズが16であることに気付きました。これは、eaxのサイズの半分です。この理由は、最初にeaxに入れられてからxだけになります。

また、どちらが最速ですか?

お勧めのマスコミサイトはありますか?あなたの入力のための

おかげで、あなたのCPUのアーキテクチャと一致

+0

どのコンパイラですか?どのような最適化レベルですか? –

答えて

1

命令がmov ax,3であれば同じ結果が得られますが、コンパイラはおそらくmov eax,3を選択します。これはマシンコードが短く、この特定のケースで効果が同じであるためです。 mov ax,3には、CPUに16ビット操作であることを伝える特別なプレフィックスバイトがあります。

Visual C++を使用している場合は、逆アセンブリウィンドウのマシンコードバイトの表示をオンにして、各命令の大きさを確認することができます。

ある時点で、16ビットの命令(または、より正確には、現在のCPUモードの「その他の」ワードサイズを使用する命令)の効率が低下しました。これ以上のケースではないかもしれませんが、わかりません。 (私の推測では、これの効果は一般的には見つけるのがかなり難しく、コードスニペットを工夫して明らかにする必要があります)

1

Wordのサイズは、常に最速です。他のものは、すべての操作のために前後に変換されることが強制されます。

TLDR:非常に具体的な理由がない限り、intを使用してください。

0

私は特に分かりませんが、これを作っています。

しかし、現代のプロセッサでは、eaxで作業する方が、より小さいaxレジスタで作業するより効率的です。

最初に(最初の割り当てで)eaxに移動すると、CPUは定数を32ビットレジスタに拡張します。

コンパイラが32ビットで(レジスタを使って)すべての計算を行い、残っている部分(つまりax)を透過的に与えることは、良いことです。

それは私に似ています。

+2

技術的には、「最新の」プロセッサは64ビットモードで動作し、 'eax'の代わりに' rax'を使用します。 – Blindy

関連する問題