(学习笔记)3.11 浮点代码(3.11.1 浮点传送和转换操作)

张开发
2026/4/7 1:12:14 15 分钟阅读

分享文章

(学习笔记)3.11 浮点代码(3.11.1 浮点传送和转换操作)
文章目录线索栏笔记栏总结栏线索栏x86-64浮点体系结构经历了哪几个关键发展阶段当前的AVX2架构提供了哪些寄存器YMM/XMM它们的位宽和用途是什么图1,2用于在内存和XMM寄存器之间、以及XMM寄存器之间传送标量浮点数据的核心指令有哪些vmovss, vmovsd,vmovaps, vmovapd图3使用哪些指令执行何种舍入vcvttsd2si等向零舍入/截断图4使用哪些指令为何是三操作数格式vcvtsi2sd等图4GCC将float转double、double转float时生成了什么看似复杂的指令序列其实际效果是什么vunpcklpsvcvtps2pd等图5浮点参数和返回值通过哪个寄存器传递%xmm0图5如何分析类似fcvt、fcvt2这样的混合类型转换函数的汇编代码图5, 6给定源类型(src_t)和目的类型(dest_t)如何选择正确的转换指令练习题3.51图6笔记栏第一部分体系结构概述与寄存器 (对应图1, 2)历史演进从MMX(64位) - SSE(128位 XMM) - AVX(256位 YMM)。当前叙述基于2013年Haswell处理器引入的AVX2。AVX浮点寄存器16个YMM寄存器%ymm0~ %ymm15每个256位32字节。XMM寄存器每个YMM寄存器的低128位名为%xmm0~%xmm15用于标量浮点操作。标量数据存储float只使用XMM寄存器的低32位double使用低64位。寄存器用途约定 (图2)%xmm0第一个浮点参数/浮点返回值。%xmm1~%xmm7后续浮点参数。部分为“调用者保存”部分为“被调用者保存”。第二部分浮点传送指令 (对应图3)指令与功能 (图3-46)vmovss在内存(M32)和XMM寄存器间传送单精度(float)标量值。vmovsd在内存(M64)和XMM寄存器间传送双精度(double)标量值。vmovaps/ vmovapd在两个XMM寄存器间传送对齐的单/双精度数也可用于标量。代码示例 (float_mov函数)floatfloat_mov(floatv1,float*src,float*dst){floatv2*src;*dstv1;returnv2;}#v1in%xmm0,src in%rdi,dst in%rsifloat_mov:vmovaps%xmm0,%xmm1 # 复制 v1vmovss(%rdi),%xmm0 # 从 src 读取 v2 vmovss%xmm1,(%rsi)# 将 v1 写入 dst ret # 返回值 v2 在%xmm0第三部分浮点转换指令 (对应图4, 5)浮点数 - 整数 (双操作数图3-47)vcvttsd2siq将双精度数(M64/X)转换为四字整数(R64)向零舍入。类似指令处理float转int/long。整数 - 浮点数 (三操作数图3-48)vcvtsi2sdq将四字整数(M64/R64)转换为双精度数存入目的XMM寄存器。第二个源操作数另一个XMM的值不影响低位结果通常与目的相同。例vcvtsi2sdq %rax, %xmm1, %xmm1浮点精度转换 (GCC的特殊代码图5)float- doublevunpcklps%xmm0,%xmm0,%xmm0 # 将[x3,x2,x1,x0]变为[x1,x1,x0,x0]vcvtps2pd%xmm0,%xmm0 # 将两个低位单精度转双精度得[dx0,dx0]double- floatvmovddup%xmm0,%xmm0 # 将[x1,x0]变为[x0,x0]vcvtpd2ps%xmm0,%xmm0 # 将两个双精度转单精度存入低64位高位置零注意GCC生成此多指令序列而非单条vcvtss2sd/vcvtsd2ss的原因不明但效果相同。第四部分综合示例与练习 (对应图5, 6)函数 fcvt分析 (图5)参数整数和指针通过通用寄存器(%edi, %rsi等)传递。操作演示了加载、存储、整数与浮点、浮点精度间的多种转换。返回值double类型通过 %xmm0返回。练习题3.51 解答思路 (图6)src_tdest_t指令注释longdoublevcvtsi2sdq %rdi, %xmm0, %xmm0整数在%rdi结果到%xmm0doubleintvcvttsd2si %xmm0, %eax浮点在%xmm0结果到%eaxdoublefloatvcvtsd2ss %xmm0, %xmm0, %xmm0(或GCC的多指令序列)结果在%xmm0的低32位longfloat先用vcvtsi2sdq转double再用vcvtsd2ss转float需两步转换floatlongvcvttss2siq %xmm0, %rax浮点在%xmm0结果到%rax总结栏本节系统阐述了x86-64架构上浮点运算的机器级表示揭示了与整数体系既相似又不同的设计。独立的寄存器文件浮点操作使用专属的XMM/YMM寄存器组16个而非整数寄存器。这允许并行处理标量或向量数据并定义了专门的调用约定参数/返回值通过%xmm0等传递。指令集的分化浮点指令通常以v前缀开头并通过后缀ss-单精度标量, sd-双精度标量, ps-打包单精度,pd-打包双精度精确指明数据类型和操作模式。这与整数指令的b/w/l/q后缀体系类似但独立。转换规则明确1浮点转整数有专用的vcvttsd2si等指令且遵循C语言规范向零舍入。2整数/浮点互转使用不同的指令集整数到浮点为三操作数格式。3精度转换虽然GCC有时生成复杂的指令序列但其最终效果与单条转换指令等价了解其模式有助于阅读编译器输出。从高级到低级的映射通过fcvt等示例可以看到复杂的C语言类型转换被系统地分解为加载、转换、存储等原子机器指令。分析此类代码的关键是追踪每个数据的来源寄存器/内存、类型转换过程以及最终目的地。核心启示浮点代码的编译是类型系统到指令集的精确映射。理解浮点寄存器、指令后缀和转换规则是分析科学计算、图形处理等涉及浮点运算程序性能与行为的必备技能。尽管GCC的某些代码生成策略如精度转换看似冗余但了解其模式对调试和逆向工程至关重要。

更多文章