IA-32 指令集包含传送 SSE 浮点数据类型值的指令。这些指令分为对打包单精度浮点数据进行操作的SSE指令,以及对打包双精度浮点数据进行操作的SSE2指令。
有一个完整的指令集用于在内存和处理器上的 XMM 寄存器之间传送 128 位打包单精度浮点值,下标列出这些指令:
指令
| 描述
| MOVAPS
| 把4个对准的打包单精度值传送到XMM寄存器或者内存
| MOVUPS
| 把4个不对准的打包单精度值传送到XMM寄存器或者内存
| MOVSS
| 把1个单精度值传送到内存或者寄存器的低双字
| MOVLPS
| 把2个单精度值传送到内存或者寄存器的低四字
| MOVHPS
| 把2个单精度值传送到内存或者寄存器的高四字
| MOVLHPS
| 把2个单精度值从低四字传送到高四字
| MOVHLPS
| 把2个单精度值从高四字传送到低四字
|
上面的指令的每一条都使用 128 位 XMM 寄存器在 XMM 寄存器和内存之间传送打包 32 位单精度浮点值。它们不仅可以传送整组的打包单精度浮点值,也可以在 XMM 寄存器之间传送 2 个打包单精度浮点值的子集。
下面程序测试传送 SSE 打包单精度浮点值:
.section .data
value1:
.float 12.34, 2345.543, -3493.2, 0.44901
value2:
.float -5439.234, 32121.4, 1.0094, 0.00003
.section .bss
.lcomm data, 16
.section .text
.global _start
_start:
nop
movups value1, %xmm0
movups value2, %xmm1
movups %xmm0, %xmm2
movups %xmm0, data
movl $1, %eax
movl $0, %ebx
int $0x80 在执行前面 3 条 movups 指令后,在调试器中查看程序执行的情况:(gdb) print $xmm0
$1 = {v4_float = {12.3400002, 2345.54297, -3493.19995, 0.449010015}, v2_double = {
5.6204289471764299e+24, 1.0439462282443856e-05}, v16_int8 = {-92, 112, 69, 65, -80, -104, 18,
69, 51, 83, 90, -59, -92, -28, -27, 62}, v8_int16 = {28836, 16709, -26448, 17682, 21299,
-15014, -7004, 16101}, v4_int32 = {1095069860, 1158846640, -983936205, 1055253668},
v2_int64 = {4977208420974555300, 4532279996355072819},
uint128 = 0x3ee5e4a4c55a5333451298b0414570a4}
(gdb) print $xmm1
$2 = {v4_float = {-5439.23389, 32121.4004, 1.00940001, 2.99999992e-05}, v2_double = {
8.7452727745837517e+33, 5.0800159140664774e-39}, v16_int8 = {-33, -7, -87, -59, -51, -14, -6,
70, 5, 52, -127, 63, -126, -88, -5, 55}, v8_int16 = {-1569, -14935, -3379, 18170, 13317,
16257, -22398, 14331}, v4_int32 = {-978716193, 1190851277, 1065432069, 939239554}, v2_int64 = {
5114667292431088095, 4034003168605058053}, uint128 = 0x37fba8823f81340546faf2cdc5a9f9df}
(gdb) print $xmm2
$3 = {v4_float = {12.3400002, 2345.54297, -3493.19995, 0.449010015}, v2_double = {
5.6204289471764299e+24, 1.0439462282443856e-05}, v16_int8 = {-92, 112, 69, 65, -80, -104, 18,
69, 51, 83, 90, -59, -92, -28, -27, 62}, v8_int16 = {28836, 16709, -26448, 17682, 21299,
-15014, -7004, 16101}, v4_int32 = {1095069860, 1158846640, -983936205, 1055253668},
v2_int64 = {4977208420974555300, 4532279996355072819},
uint128 = 0x3ee5e4a4c55a5333451298b0414570a4} 从输出可以发现,所有数据都被正确的加载到了 XMM 寄存器中。v4_float 格式显示使用的打包单精度浮点值。
最后的一条 movups 指令是把 XMM 寄存器的值复制到 data 位置。可以使用 x/4f 命令显示结果:(gdb) x/4f &data
0x80490c0 <data>: 12.3400002 2345.54297 -3493.19995 0.449010015 为了把存储在内存位置 data 中的字节显示为 4 个单精度浮点值,可以使用 x 命令的 4f 选项。 |