Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 7

SSE2 指令集系列之一----浮点运算指令

1. 数据搬移指令
movapd XMM,XMM/m128
movapd XMM/m128,XMM

把源存储器内容值送入目的寄存器,当有 m128 时,内存变量地址必须 16 字节对齐.

movupd XMM,XMM/m128
movupd XMM/m128,XMM

把源存储器内容值送入目的寄存器,内存变量地址不必对齐 16 字节.
两条指令同 SSE1 的浮点搬移指令 movaps 和 movups 指令类似

movlpd XMM,m64
movlpd m64,XMM

把源存储器 64 位内容送入目的寄存器低 64 位,高 64 位不变,内存变量地址不必对齐


16 字节.

movhpd XMM,m64
movhpd m64,XMM

把源存储器 64 位内容送入目的寄存器高 64 位,低 64 位不变,内存变量地址不必对


齐 16 字节.

2. 浮点常用算数运算指令

addpd XMM,XMM/m128
addsd XMM,XMM/m128

subpd XMM,XMM/m128
subsd XMM,XMM/m128

mulpd XMM,XMM/m128
mulsd XMM,XMM/m128

divpd XMM,XMM/m128
divsd XMM,XMM/m128
sqrtpd XMM,XMM/m128
sqrtsd XMM,XMM/m128

maxpd XMM,XMM/m128
maxsd XMM,XMM/m128

minpd XMM,XMM/m128
minsd XMM,XMM/m128
小结:
1. 以 pd 结尾的指令对两个双精度浮点数执行相同的运算
2. 以 sd 结尾的指令只对低 64 位双精度执行运算,高 64 位保持不变。
3. 当有 m128 存储器是要求内存地址必须为 16 字节对齐。

3. 位运算指令

andpd XMM,XMM/m128
源存储器 128 个二进制位'与'目的寄存器 128 个二进制位,结果送入目的寄存器,内存
变量地址必须对齐 16 字节边界.

andnpd XMM,XMM/m128
目的寄存器 128 个二进制位先取'非',再'与'源存储器 128 个二进制位,结果送入目的寄
存器,内存变量地址必须对齐 16 字节边界

orpd XMM,XMM/m128
源存储器 128 个二进制位'或'目的寄存器 128 个二进制位,结果送入目的寄存器,内存
变量地址必须对齐 16 字节边界

xorpd XMM,XMM/m128
源存储器 128 个二进制位'异或'目的寄存器 128 个二进制位,结果送入目的寄存器,内
存变量地址必须对齐 16 字节边界

4. 数据类型转换指令

4.1 32 位浮点与 64 位浮点之间的转换


cvtps2pd XMM,XMM/m64
把源存储器低 64 位两个单精度浮点数变成两个双精度浮点数,结果送入目的寄存器.
cvtss2sd XMM,XMM/m32
把源存储器低 32 位 1 个单精度浮点数变成 1 个双精度浮点数,结果送入目的寄存器
的低 64 位,高 64 位不变.

cvtpd2ps XMM,XMM/m128
把源存储器两个双精度浮点数变成两个单精度浮点数,结果送入目的寄存器的低 64
位,高 64 位清零,

cvtsd2ss XMM,XMM/m64
把源存储器低 64 位 1 个双精度浮点数变成 1 个单精度浮点数,结果送入目的寄存器
的低 32 位,高 96 位不变.

4.2 浮点数与 32 位整数之间的转换


4.2.1 双精度与整数之间转换
cvtpd2pi MM,XMM/m128
把源存储器两个双精度浮点数变成两个双字有符号整数,结果送入目的寄存器,内存变
量必须对齐内存 16 字节.

如果结果大于所能表示的范围,那么转化为 80000000h(正数也转为此值).

当 XMM1 = 0x 0dd1a5e1f35aec736 41132a4000000000,执行 cvtpd2pi


MM0,XMM1

则 MM0 = 0x 80000000 0004ca90

因为 0dd1a5e1f35aec736h(双精度浮点数) = -3.14E140 超过 80000000h 所


以变为 80000000h

而 41132a4000000000h(双精度浮点数) = 3.14E5,所以转为 314000 =


0004ca90h(有符号整数)

cvtpi2pd XMM,MM/m64
把源存储器两个双字有符号整数变成两个双精度浮点数,结果送入目的寄存器.

cvtpd2dq XMM,XMM/m128
把源存储器两个双精度浮点数变成两个双字有符号整数

结果送入目的寄存器的低 64 位,高 64 位清零,内存变量必须对齐内存 16 字节.

此运算与 cvtpd2pi 类似但目的寄存器变为 XMM.

cvtdq2pd XMM,XMM/m128
把源存储器低 64 位两个双字有符号整数变成两个双精度浮点数,结果送入目的寄存
器,内存变量必须对齐内存 16 字节.

cvtsd2si r32,XMM/m64
把源存储器低 64 位 1 个双精度浮点数变成 1 个双字有符号整数,结果送入目的寄存
器.

此指令目的寄存器是 32 位通用寄存器

cvtsi2sd XMM,r32/m32
把源存储器 1 个双字有符号整数变成 1 个双精度浮点数,结果送入目的寄存器的低
64 位,高 64 位不变.

4.2.2 单精度浮点与整数之间转换

cvtps2dq XMM,XMM/m128
把源存储器 4 个单精度浮点数变成 4 个双字有符号整数,结果送入目的寄存器,内存
变量必须对齐内存 16 字节.

cvtdq2ps XMM,XMM/m128
把源存储器 4 个双字有符号整数变成 4 个单精度浮点数,结果送入目的寄存器,内存
变量必须对齐内存 16 字节.

float data1 = 30.55;


movss xmm0,dword ptr [__real@41f46666 (0319B44h)] //
movss dword ptr [data1],xmm0
float data2 = 10.22;
movss xmm0,dword ptr [__real@4123851f (0319B40h)]
movss dword ptr [data2],xmm0

float data_value;
data_value = data1 + data2;
movss xmm0,dword ptr [data1]
addss xmm0,dword ptr [data2]
movss dword ptr [data_value],xmm0

data_value = data1 - data2;


movss xmm0,dword ptr [data1]
subss xmm0,dword ptr [data2]
movss dword ptr [data_value],xmm0

data_value = data1 * data2;


movss xmm0,dword ptr [data1]
mulss xmm0,dword ptr [data2]
movss dword ptr [data_value],xmm0

data_value = data1 / data2;


movss xmm0,dword ptr [data1]
divss xmm0,dword ptr [data2]
movss dword ptr [data_value],xmm0

float data1 = 533.010;


movss xmm0,dword ptr [__real@440540a4 (03C9B44h)] //十六进制的 440540a4=553.010
[03C9B44h]=》553.010 内存地址
xmm0 浮点寄存器 movss 传值
movss dword ptr [data1],xmm0 //讲 xmm0 的值传给 data1
float data2 = 20.33;
movss xmm0,dword ptr [__real@41a2a3d7 (03C9B40h)]
movss dword ptr [data2],xmm0
float data_value;

data_value = data1 + data2; //加法


movss xmm0,dword ptr [data1] //讲 data1 传到 xmm0 寄存器
addss xmm0,dword ptr [data2] //add 整数类型加法 addss 加法。
1.将 data2 的值和 xmm0 的值相加,2.再把结果存到 xmm0 里

movss dword ptr [data_value],xmm0

data_value = data1 - data2;//减法


movss xmm0,dword ptr [data1]
subss xmm0,dword ptr [data2] // xmm0-data2 结果放到 xmm0
movss dword ptr [data_value],xmm0

data_value = data1 * data2;//乘法


movss xmm0,dword ptr [data1]
mulss xmm0,dword ptr [data2] //mulss 乘法
movss dword ptr [data_value],xmm0

data_value = data1 / data2; //除法


movss xmm0,dword ptr [data1]
divss xmm0,dword ptr [data2] // div divss
movss dword ptr [data_value],xmm0

单精度浮点数
float data1 = 533.010;
movss xmm0,dword ptr [__real@440540a4 (03C9B44h)]//单精度浮点数用 movss
movss dword ptr [data1],xmm0

双精度浮点数
double dataA = 5532.564645;
movsd xmm0,mmword ptr [__real@40b59c908c9320da (0879BF0h)] //双精度浮点数用 movsd
movsd mmword ptr [dataA],xmm0

double dataB = 223.555;


movsd xmm0,mmword ptr [__real@406bf1c28f5c28f6 (0879BE8h)]
movsd mmword ptr [dataB],xmm0

double data_value;
data_value = dataA + dataB; //双精度浮点数的加法
movsd xmm0,mmword ptr [dataA] //dataA 传给 xmm0
addsd xmm0,mmword ptr [dataB] // addsd 浮点数相加
movsd mmword ptr [data_value],xmm0 //讲 xmm0 传给变量 data_value

data_value = dataA - dataB;


movsd xmm0,mmword ptr [dataA]
subsd xmm0,mmword ptr [dataB]
movsd mmword ptr [data_value],xmm0

data_value = dataA * dataB;


movsd xmm0,mmword ptr [dataA]
mulsd xmm0,mmword ptr [dataB]
movsd mmword ptr [data_value],xmm0

data_value = dataA / dataB;


movsd xmm0,mmword ptr [dataA]
divsd xmm0,mmword ptr [dataB]
movsd mmword ptr [data_value],xmm0

You might also like