ホームに戻る
 乗算を考える

;
;   アセンブラ
;

segment .code USE32

global _mmx

_mmx:
  push    ebp
  mov     ebp, esp

  mov     edx, dword [ebp+8]
  mov     eax, dword [ebp+12]

  movq      mm0, [edx]
  movq      mm1, mm0
  movq      mm2, [eax]
  movq      mm3, [eax + 8]
  movq      mm4, [eax + 16]
  movq      mm5, [eax + 24]

  pmaddwd   mm2, mm0
  pmaddwd   mm4, mm1
  pmaddwd   mm3, mm0
  pmaddwd   mm5, mm1

  movq      mm6, mm2
  movq      mm7, mm4
  punpckldq mm6, mm3
  punpckldq mm7, mm5
  punpckhdq mm2, mm3
  punpckhdq mm4, mm5
  paddd     mm6, mm2
  paddd     mm7, mm4

  packssdw  mm6, mm7

  movq      [edx], mm6

  emms

  leave
  ret 
__end__mmx

/*
*   C言語
*/

#include <stdio.h>

extern void mmx(short *buf1, short *buf2);

int main()
{
  int i;
  short buf1[4 + 4];
  short buf2[4 * 4 + 4];
  short *pbuf1 = (short *)(((unsigned)buf1 + 7) & ~7);
  short *pbuf2 = (short *)(((unsigned)buf2 + 7) & ~7);

  static short matrix1[4] = {
    3, 3, 3, 1
  };

  static short matrix2[4 * 4] = {
    1, 0, 0, 1,
    0, 1, 0, 2,
    0, 0, 1, 3,
    0, 0, 0, 1
  };

  for(i = 0; i < 4; i++){
    pbuf1[i] = matrix1[i];
  }

  for(i = 0; i < 16; i++){
    pbuf2[i] = matrix2[i];
  }

  mmx(pbuf1, pbuf2);

  for(i = 0; i < 4; i++){
    printf("%02d ", pbuf1[i]);
  }

  return 0;
}


このプログラムについて

以下の計算をしています。

                     |1 0 0 0|
                     |0 1 0 0|
|x y z w| = |3 3 3 1||0 0 1 0|
                     |1 2 3 1|

アセンブラのほうは見やすさを優先しているので速度の最適化は試みてません。
inserted by FC2 system