ホームに戻る
 配列へのマスク処理を考える

;
;   アセンブラ
;

segment .code USE32

global _mmx

_mmx:
  push    ebp
  mov     ebp, esp
  push    ecx

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

  pcmpeqd mm0, mm0
  psrld   mm0, 28
  movq    mm1, mm0

  xor     eax, eax

@1:
  movq    mm2, [edx + eax*8]
  movq    mm3, [ecx + eax*8]
  pand    mm2, mm0
  pand    mm3, mm1
  movq    [edx + eax*8], mm2
  movq    [ecx + eax*8], mm3

  inc     eax
  cmp     eax, 16
  jl      short @1

  emms

  pop     ecx
  leave
  ret 
__end__mmx

/*
*   C言語
*/

#include <stdio.h>

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

int main()
{
  int i;
  int buf[8 * 8 + 2];
  int *pbuf1 = (int *)(((unsigned)buf + 7) & ~7);
  int *pbuf2 = &pbuf1[8 * 4];

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

  mmx(pbuf1, pbuf2);

  for(i = 0; i < 64; i++){
    if(i % 8 == 0)printf("\n");
    printf("%02d,", pbuf1[i]);
  }

  return 0;
}


このプログラムについて

バッファの32ビット値すべてに下4ビットをマスクして0でクリアします。

まずバッファについて先頭アドレスを8の倍数にあわせています。

(((unsigned)buf + 7) & ~7);

最大7バイトのずれが生じるのでバッファは8バイトぶん余分に確保。
バッファは buf[8 * 8 + 2] というふうにしています。

pcmpeqd mm0, mm0

は mm0 のビットをすべて 1 にします。

psrld   mm0, 28

は32ビット幅で右に28ビットシフトなので、
mm0 は、

0000000000000000000000000000111100000000000000000000000000001111

というような状態になっているはずです。
これでバッファに対してANDをかけます。

inserted by FC2 system