• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:インラインアセンブラについて)

インラインアセンブラでの配列要素の加算について

このQ&Aのポイント
  • インラインアセンブラを使ってunsigned char型の配列の要素を加算するプログラムが正常に動作しない問題が発生しています。
  • 配列ansに正しい解が代入されず、全ての要素が205になってしまいます。
  • 問題の原因が特定できず、質問者は自力で問題点を見つけることができません。ご指摘をお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.3

★アドバイス >MovQ mm0, [eax][ecx * 8]  ↑  [ecx * 8]がオフセットになります。  この記述を使えば  max = (LEN / 8) - 1;    _asm {   mov   ecx, max   mov   eax, t0   mov   esi, t1   mov   edi, t2 LOOPSTART:   movq  mm1, [esi][ecx * 8]   movq  mm2, [edi][ecx * 8]   paddb  mm1, mm2   movq  [eax][ecx * 8],mm1      dec   ecx   jns   LOOPSTART      emms  }  と記述できますね。

その他の回答 (2)

  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.2

★追記。 ・ソースを良く見たらレジスタへのセットがおかしいようです。  ans、src1、src2 のポインタを普通のレジスタにセットしてから  movq で mm0、mm1、mm2 レジスタにセットします。  下に全ソースを貼り付けて置きます。 #include <stdio.h> #include <stdlib.h> #define LEN (64) // メイン関数 int main( void ) {  unsigned char *ans, *src1, *src2;  unsigned char *t0, *t1, *t2;  int i, max;    t0 = ans = (unsigned char *)malloc( sizeof(unsigned char) * LEN );  t1 = src1 = (unsigned char *)malloc( sizeof(unsigned char) * LEN );  t2 = src2 = (unsigned char *)malloc( sizeof(unsigned char) * LEN );    // 配列ans、src1、src2の初期化  for ( i = 0 ; i < LEN ; i++ ){   ans[ i ] = (unsigned char)(0);   src1[ i ] = (unsigned char)(i + 0);   src2[ i ] = (unsigned char)(i + 1);  }  max = (LEN / 8);    _asm {   mov   ecx, max LOOPSTART:   // レジスタへの代入   mov   eax, t0   mov   esi, t1   mov   edi, t2      // MMX演算   movq  mm1, [esi]   movq  mm2, [edi]   paddb  mm1, mm2   movq  [eax],mm1      // ポインタの加算   add   t0, 8   add   t1, 8   add   t2, 8   loop  LOOPSTART      emms  }  for ( i = 0 ; i < LEN ; i++ ){   printf( "%2d + %2d = %2d\n", src1[i], src2[i], ans[i] );  }  return 0; }

seven_star
質問者

お礼

Oh-Orange様、返信ありがとうございました。 適切な回答と、参考ページまで紹介いただき、とても感謝しています。 おっしゃる通り、ポインタをレジスタに一度格納しておかなければなりませんでした。 結果、正常に動作するようプログラムを組むことが出来ました。 ありがとうございました。 最後にひとつ気になったことがあるのですが、 ご紹介にいただいた2番目の参考ページについてです。 アセンブラ部分を見ると      MovQ mm0, [eax][ecx * 8] このような表記があります。 ソースオペランドに引数を2つもっているのですが、これはどのような意味なのでしょう?

  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.1

★アドバイス >高速化を目指しMMXを使用しているのですが、うまく動作しません。  ↑  paddusb命令は飽和演算を行います。  多倍長演算には利用できないと思います。  つまり加算・減算において 255 以上なら 255 になるためキャリーとして  次の配列に演算を行わないため上手く動作しなくても正常だと思います。 ・下に参考ページを載せておきますので MMX の paddusb 命令について  もう一度動作の確認をして下さい。  なお、使うなら paddb 命令の方ではないでしょうか?  こちらならバイト区切りのオーバーフローとキャリーありで加算を行います。 参考ページ: http://hp.vector.co.jp/authors/VA014520/asmhsp/chap8.html→『MMX命令による画像処理』 http://www7b.biglobe.ne.jp/robe/pf/pf009.html→『第九報:MMX 最適化』 http://www9.ocn.ne.jp/~mkisa/asm.htm→『インラインアセンブリ』

関連するQ&A