第1章●データ転送命令

第 1 章 データ転送命令

MOVD31src

MOVD

MMX

SSE

SSE2

SSE3

(r32/m32)

dst

(xmm)

■構文■

AT&T ニーモニック

0

MMXs0

SSE
127

9600000000

6400000000

320

SSE2

s000000000

SSE3Intel ニーモニック

MOVD r32/m32, mm
MOVD mm, r32/m32
MOVD r32/m32, xmm
MOVD xmm, r32/m32

（MMX）
（MMX）
（SSE2）（SSE2）MOVD mm, r32/m32
MOVD r32/m32, mm
MOVD xmm, r32/m32
MOVD r32/m32, xmm

（MMX）
（MMX）
（SSE2）（SSE2）

127

src

(xmm)

96s3

64s2

32s1

dst

(r32/m32)

0s0s0図 1.2 ● MOVD 命令（SSE2）■概要■

MMX 命令セットでサポートされる MOVD は、汎用レジスタ・ MMX レジスタ間、または 32ビットメモリロケーション・ MMX レジスタ間で相互にダブルワードの移動を行う命令です。
31

src

0

MMX 命令セットでサポートされる MOVD は、一方のオペランドとして MMX レジスタを指定し、もう一方のオペランドには汎用レジスタ、または 32 ビットメモリロケーションを指定します。ディスティネーションオペランドが MMX レジスタの場合、ソースオペランドの値は下位 32s0(r32/m32)■解説■

12ビットに格納され、レジスタの上位 32 ビットは 0 クリアされます。ディスティネーションオペラ

dst

63

32(mm)

0s000000000

ンドが汎用レジスタ、または 32 ビットメモリロケーションの場合、ソースオペランドの MMX レ
ジスタの下位 32 ビットの値がディスティネーションオペランドに格納されます。

SSE2 命令セットでサポートされる MOVD は、一方のオペランドとして XMM レジスタを指定

src

(mm)

6332s1

dst(r32/m32)

0s0

し、もう一方のオペランドには汎用レジスタ、または 32 ビットメモリロケーションを指定します。ディスティネーションオペランドが XMM レジスタの場合、ソースオペランドの値は下位 32ビットに格納され、レジスタの上位 96 ビットは 0 クリアされます。ディスティネーションオペラ

s0

ンドが汎用レジスタ、または 32 ビットメモリロケーションの場合、ソースオペランドの XMM レ
ジスタの下位 32 ビットの値がディスティネーションオペランドに格納されます。

図 1.1 ● MOVD 命令（MMX）■サンプル（MMX、AT&T）■

SSE2 命令セットでサポートされる MOVD は、汎用レジスタ・ XMM レジスタ間、または 32ビットメモリロケーション・ XMM レジスタ間で相互にダブルワードの移動を行う命令です。

MMX 命令セットでサポートされる MOVD のすべてのオペランド、つまりメモリ、汎用レジスタ、MMX レジスタの三者間で値の移動を行うプログラムです。はじめにメモリから mm0 レジスタへ値を読み込み、その値をメモリと汎用レジスタに格納します。

libcom.h については導入部の記述を参照してください。
リスト 1.1 ● movd̲mmx.c#include <stdio.h>#include "libcom.h"
voidusage(char *p)

2334

第 1 章 データ転送命令

MOVD{:"%eax", "%mm0"MMX);

SSE

fprintf(stderr, "usage: %s [arg1]\n", p);}intmain(int argc, char *argv[]){
operand*src, *dst0, *dst1;
/*
**/

/*
**/

SSE3
printf("printf("

result: %s\n", operand2str(dst0));
result: %s\n", operand2str(dst1));

free_operand(src);
free_operand(dst0);
free_operand(dst1);

check if 1 command line argument is givenif(argc != 2) {usage(argv[0]);return -1;}

SSE2

show the result

return 0;}1

リスト 1.1 の実行結果

/*
*
*/

convert each command line argument to packed valueif((src = hex2operand64(argv[1], 8, OPERAND_ALIGNED)) == NULL) {fprintf(stderr, "arg1(%s): invalid value.\n", argv[1]);return -1;}
if((dst0 = alloc_operand64(8, OPERAND_ALIGNED)) == NULL) {fprintf(stderr, "cannot allocate memory.\n");return -1;}
if((dst1 = alloc_operand64(8, OPERAND_ALIGNED)) == NULL) {fprintf(stderr, "cannot allocate memory.\n");return -1;}

/*
*
*/

show the contents of operands
printf("MOVD\n/*
*
*/

2
3

■サンプル（SSE2、AT&T）■

SSE2 命令セット（拡張 MMX 命令セットと表現される場合もある）でサポートされる MOVDのすべてのオペランド、つまりメモリ、汎用レジスタ、XMM レジスタの三者間で値の移動を行うプログラムです。はじめにメモリから xmm0 レジスタへ値を読み込み、その値をメモリと汎用レジスタに格納します。
リスト 1.2 ● movd̲xmm.c#include <stdio.h>#include "libcom.h"source: %s\n", operand2str(src));

do the calculation with using SIMD instruction
asm volatile("movd(%0),%%mm0\n\t""movd%%mm0, (%1)\n\t""movd%%mm0, %%eax\n\t""movl%%eax, (%2)\n\t""emms\n"::"r"(src->alligned), "r"(dst0->alligned), "r"(dst1->alligned)4> ./movd_mmx 0123456789abcdef
MOVD
source: 0123456789abcdef
result: 0000000089abcdef
result: 0000000089abcdef

voidusage(char *p){
fprintf(stderr, "usage: %s [arg1]\n", p);}intmain(int argc, char *argv[]){
operand*src, *dst0, *dst1;

54

第 1 章 データ転送命令

/*
*
*/

MOVD

if(argc != 2) {usage(argv[0]);return -1;
}
/*
*
*/

convert each command line argument to packed valueif((src = hex2operand128(argv[1], 16, OPERAND_ALIGNED)) == NULL) {fprintf(stderr, "arg1(%s): invalid value.\n", argv[1]);return -1;}
if((dst0 = alloc_operand128(16, OPERAND_ALIGNED)) == NULL) {fprintf(stderr, "cannot allocate memory.\n");return -1;}
if((dst1 = alloc_operand128(16, OPERAND_ALIGNED)) == NULL) {fprintf(stderr, "cannot allocate memory.\n");return -1;
}

/***/

show the contents of operands

do the calculation with using SIMD instruction

show the result
printf("printf("

result: %s\n", operand2str(dst0));
result: %s\n", operand2str(dst1));

free_operand(src);
free_operand(dst0);

6

return 0;

SSE}

SSE2
SSE3

リスト 1.2 の実行結果> ./movd_xmm 0123456789abcdeffedcba9876543210
MOVD
source: 0123456789abcdeffedcba9876543210
result: 00000000000000000000000076543210
result: 00000000000000000000000076543210■サンプル（MMX、Intel）■

Windows の Visual Studio でコンパイル・実行可能な、Intel ニーモニックのサンプルプログラムを示します。Windows 環境でも、Cygwin を導入すれば AT&T ニーモニックのソースコードをそのまま使用できます。しかし Visual C++ などでは、AT&T ニーモニックのソースコードがコンパイルできないため、Intel ニーモニックに書き換える必要があります。
リスト 1.3 は、MMX 命令セットでサポートされる MOVD のすべてのオペランド、つまりメモ

12リ、汎用レジスタ、MMX レジスタの三者間で値の移動を行うプログラムです。

3

リスト 1.3 ● movd̲mmx4

source: %s\n", operand2str(src));

asm volatile("movd(%0),%%xmm0\n\t""movd%%xmm0, (%1)\n\t""movd%%xmm0, %%eax\n\t""movl%%eax, (%2)\n"::"r"(src->alligned), "r"(dst0->alligned), "r"(dst1->alligned):"%eax", "%xmm0");
/*
*
*/

MMX

#include <stdio.h>
printf("MOVD\n/***/free_operand(dst1);
check if 1 command line argument is given

int main( int argc, char *argv[] ){unsigned int src[2];unsigned int dst0[2];unsigned int dst1;
int i;
for(i=0;i<2;i++)dst0[i]=0;
src[1]=0x01234567;
src[0]=0x89abcdef;__asm{
movd
movd
movd
mov

mm0, src
dst0, mm0
eax, mm0
dst1, eax

emms}

7

第 1 章 データ転送命令

MOVD

printf("printf("printf("printf("printf("

source: %08x%08x¥n", src[1], src[0]);result: %08x%08x¥n", dst0[1], dst0[0]);result: %08x¥n", dst1);

result: %08x%08x%08x%08x¥n", dst0[3], dst0[2], dst0[1], dst0[0]);result: %08x¥n", dst1);

MMXSSE

return 0;

SSE2}
return 0;

SSE3}
リスト 1.4 の実行結果
リスト 1.3 の実行結果

C:¥>pgmsource: 0123456789abcdef
result: 0000000089abcdef
result: 89abcdefC:¥>pgm
source: 0123456789abcdeffedcba9876543210
result: 00000000000000000000000076543210
result: 76543210■サンプル（SSE2、Intel）■

1

SSE2 命令セット（拡張 MMX 命令セットと表現される場合もある）でサポートされる MOVDのすべてのオペランド、つまりメモリ、汎用レジスタ、XMM レジスタの三者間で値の移動を行2うプログラムです。
リスト 1.4 ● movd̲xmm

3#include <stdio.h>
int main( int argc, char *argv[] ){unsigned int src[4];unsigned int dst0[4];unsigned int dst1;

4

int i;
for(i=0;i<4;i++)dst0[i]=0;
src[3]=0x01234567;
src[2]=0x89abcdef;src[1]=0xfedcba98;
src[0]=0x76543210;
__asm
{
movd
movd
movd
mov}
printf("8xmm0, src
dst0, xmm0
eax, xmm0
dst1, eax

source: %08x%08x%08x%08x¥n", src[3], src[2], src[1], src[0]);9