Skip to content

MOVAPD:对齐打包双精度数据移动

MOVAPD 是 SSE2 的 128 位复制指令,通常把一个 XMM 寄存器理解成两个 float64。它不会解析或改变浮点值,因此同样可以原样搬运任意 128 位位模式。

操作码
66 0F 28 /r
指令集
SSE2
英文全称
Move Aligned Packed Double-Precision Floating-Point Values
参考资料
INTEL SDM
页码
759
01MOVAPD02xmm003xmm1/m128
01
指令助记符MOVAPDmnemonic

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

02
目标寄存器xmm0destination

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

03
源操作数xmm1/m128source

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

操作码
66 0F 29 /r
指令集
SSE2
英文全称
Move Aligned Packed Double-Precision Floating-Point Values
参考资料
INTEL SDM
页码
759
01MOVAPD02xmm1/m12803xmm0
01
指令助记符MOVAPDmnemonic

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

02
目标操作数xmm1/m128destination

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

03
源寄存器xmm0source

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

位复制与地址对齐

传统 MOVAPD 访问内存时要求 16 字节对齐。图中的两个 64 位 lane 只是便于阅读的分组;复制本身以完整的 128 位位模式为准。

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

寄存器到寄存器的形式不检查地址对齐。内存源或内存目标不是 16 字节对齐时,传统 MOVAPD 会触发 #GP;需要接受非对齐地址时使用 MOVUPD

汇编示例

asm
section .data
align 16
input:  dq 1.5, -2.0
output: times 2 dq 0.0

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

两个指针都必须满足 16 字节对齐;数组可使用 alignas(16) 明确声明该约束。

向量编码

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

128/256 位 EVEX 形式还需要 AVX-512VL(或相应 AVX10 支持),并可使用写掩码。对齐要求随内存操作数宽度增加,不应把传统 XMM 形式的 16 字节规则套到 YMM 或 ZMM。

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

参考

SIGNAL MAINTAINED · BUILT FROM MARKDOWN