2016-08-28 8 views
0

アセンブリで製品に問題があります。私は次元、広告例、1raw x 1columnの2つの行列を乗算したい。 結果が2^15より大きい場合、IMULはオーバーフローのフラグOF = 1を設定しますが、理由はわかりませんが、実際には32ビットレジスタで16ビットではありません。ここでは、この問題を説明するためのいくつかのコードは、例えば:32ビットレジスタ乗算におけるOFのタグ

short int mat1[] = {-70}; 
short int mat2[] = {20000}; 

__asm { 
     lea eax, mat1 
     lea ebx, mat2 
     xor edx, edx 
     xor ecx, ecx 
     movsx esi, [eax][ecx*2] //esi = 70 
     imul esi, [ebx][edx*2] //multiplicates esi for mat2 that is 20000 
} 

今ESIは、なぜ、0022A340h代わりにFFFFFDDD20h(-140000)、および= 1フラグでありますか?結果は行列の代わりに数値と同じですが、私はそれらと一緒に作業していますが、それが不快なものかどうかはわかりません。この例ではmat1とmat2を投稿しました。

+2

を32ビットレジスタでは、メモリ参照も16ビットではなく32ビットです。その結果、2番目のオペランドは20000ではなく、何か他のもの(mat2の次の2バイトになることによる) –

+0

"mov edx、[ebx]"ならedxはCCCC4E20です。では、正しい結果を得るために何をすべきですか?わかりません。 – Caramelleamare

答えて

3

あなたは符号拡張すべき第2オペランドとしても:

short int mat1[] = {-70}; 
short int mat2[] = {20000}; 

__asm { 
     lea eax, mat1 
     lea ebx, mat2 
     xor edx, edx 
     xor ecx, ecx 
     movsx esi, WORD PTR[eax][ecx*2] //esi = 70 
     movsx edi, WORD PTR[ebx][edx*2] 
     imul esi, edi 
} 

またはちょうど16ビット乗算(DXに32ビットの結果を返します:斧)を行うあなたがIMULを使用しているので

__asm { 
     lea esi, mat1 
     lea edi, mat2 
     xor edx, edx 
     xor ecx, ecx 
     mov ax, [esi][ecx*2] //esi = 70 
     imul WORD PTR[edi][edx*2] 
     // result is now in dx:ax 
} 
+0

何か間違っている、または私のコードで動作しないdosn't: "movsx edi、[ebx]" edi = 00000020hの代わりに4E20hを設定してください...そして16ビットimulではaxはA340、DXは0です。 eaxでは、AXの左側にいくつかのビットが変更されています。 – Caramelleamare

+0

固定32ビット版。私は 'WORD PTR'を見逃していた。これがなければ、コンパイラはバイトまたはワードをesi(またはedi)で拡張する必要があるかどうかを知りません –

+0

固定16ビット版も同様です。 'imul ax、{r/m}'は 'imul {r/m} 'と同じではありません。前者は16ビットの乗算を行い、結果を16ビットに切り捨てます。後者は、al、axまたはeaxとオペランドの間に8x8 = 16または16x16 = 32または32x32 = 64ビットの乗算を行い、その結果をax、dx:axまたはedx:eax(オペランドのサイズに基づく) 。 –

関連する問題