ホームに戻る
配列へのマスク処理を考える
;
; アセンブラ
;
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をかけます。