Skip to content

MOVAPS:对齐打包单精度数据移动

MOVAPS 是 SSE 的 128 位复制指令。它可以在两个 XMM 寄存器之间复制,也可以加载或存储 128 位内存;助记符中的 PS 描述预期的数据布局,但指令不会执行浮点运算或数值转换。

操作码
0F 28 /r
指令集
SSE
英文全称
Move Aligned Packed Single-Precision Floating-Point Values
参考资料
INTEL SDM
页码
763
01MOVAPS02xmm003xmm1/m128
01
指令助记符MOVAPSmnemonic

Move Aligned Packed Single-Precision Floating-Point Values,原样复制 128 位数据。

02
目标寄存器xmm0destination

接收源 XMM 寄存器或 128 位内存中的全部位。

03
源操作数xmm1/m128source

可以是 XMM 寄存器;使用内存源时,地址必须按 16 字节对齐。

操作码
0F 29 /r
指令集
SSE
英文全称
Move Aligned Packed Single-Precision Floating-Point Values
参考资料
INTEL SDM
页码
763
01MOVAPS02xmm1/m12803xmm0
01
指令助记符MOVAPSmnemonic

存储形式使用另一个操作码,但仍然原样复制 128 位。

02
目标操作数xmm1/m128destination

可以是 XMM 寄存器或按 16 字节对齐的 128 位内存位置。

03
源寄存器xmm0source

提供要写入目标的全部 128 位。

位复制与地址对齐

下图按“低 lane 到高 lane”的数组顺序直接绘制完整的 128 位数据。切换 LOAD / STORE 可以观察复制方向。

MOVAPS · PACKED BIT COPY · 128 BITS4 × FLOAT32
内存操作数必须按 16 字节对齐
m128(内存)128 BITS
m128[127:0]
m128[3]4FLOAT32
m128[2]3FLOAT32
m128[1]2FLOAT32
m128[0]1FLOAT32
xmm0128 BITS
xmm0[127:0]
xmm0[3]4FLOAT32
xmm0[2]3FLOAT32
xmm0[1]2FLOAT32
xmm0[0]1FLOAT32
每个圆球代表一个 FLOAT32 元素强调背景:复制目标图中高索引在左、低索引在右
text
load:  XMM_DEST[127:0] = SRC[127:0]
store: DEST[127:0]     = XMM_SRC[127:0]

只有操作数实际访问内存时才检查 16 字节对齐。movaps xmm0, xmm1 的两个操作数都是寄存器,不存在内存地址对齐问题;未对齐的 m128 源或目标会触发 #GP

汇编示例

asm
section .data
align 16
input:  dd 1.5, -2.0, 10.0, 0.25
output: times 4 dd 0.0

section .text
movaps xmm0, [input]     ; 0F 28:对齐加载
movaps [output], xmm0    ; 0F 29:对齐存储

sourcedestination 必须满足 16 字节对齐。普通 new float[] 或栈数组是否满足该条件取决于其声明和分配方式;需要时可使用 alignas(16)

向量编码

形式宽度内存对齐指令集目标寄存器高位
MOVAPS xmm, xmm/m128128 位16 字节SSEXMM 以上对应位保持不变
VMOVAPS xmm, xmm/m128128 位16 字节AVX高于 128 位的对应目标位清零
VMOVAPS ymm, ymm/m256256 位32 字节AVX高于 256 位的对应目标位清零
VMOVAPS zmm, zmm/m512512 位64 字节AVX-512F / AVX10.1写入完整 ZMM

128/256 位 EVEX 形式还需要 AVX-512VL(或相应 AVX10 支持),并可使用写掩码。对未对齐的单精度内存,应改用 MOVUPS / VMOVUPS

MOVAPS 不修改 EFLAGS,也不产生 SIMD 浮点异常。

参考

SIGNAL MAINTAINED · BUILT FROM MARKDOWN