Windows逆向工程入门之小数类型
文章目录
- 浮点数处理技术详解与汇编用法
- 1. x87 FPU指令集详解
- 应用场景
- 汇编指令详细解析
- 2. SSE指令集详解
- 应用场景
- SSE汇编指令详细解析
- 3. AVX指令集详解
- 应用场景
- AVX汇编指令详细解析
- 4. 综合测试主函数
- 各指令集关键特点总结
- x87 FPU
- SSE
- AVX
- 浮点数指令集汇编指令详解
- 浮点数指令集汇编指令详解
- 1. x87 FPU 指令集汇编指令
- 数据传送指令
- 算术运算指令
- 超越函数指令
- 比较和测试指令
- 控制指令
- 2. SSE 指令集汇编指令
- 数据传送指令
- 算术运算指令
- 比较指令
- 数据重排指令
- 转换指令
- 3. AVX 指令集汇编指令
- 数据传送指令
- 算术运算指令(三操作数格式)
- 融合乘加指令 (FMA)
- 比较和测试指令
- 数据重排和混合指令
- 4. 实用汇编代码示例
- x87 FPU 复杂计算示例
- SSE 向量点积计算
- AVX 矩阵向量乘法
- 5. 指令集选择指南
- 根据数据类型选择
- 根据精度要求选择
浮点数处理技术详解与汇编用法
1. x87 FPU指令集详解
应用场景
- 传统兼容性应用:老式软件、嵌入式系统
- 高精度计算:80位扩展精度提供更高计算精度
- 顺序计算:不适合并行但需要高精度的场景
- 金融计算:需要精确小数运算的场合
汇编指令详细解析
#include <stdio.h>void x87_detailed_analysis() {printf("=== x87 FPU 详细分析 ===\n");float f1 = 5.75f;float f2 = 3.14f;double d1 = 123.456;// 1. 寄存器栈操作printf("1. 寄存器栈操作:\n");__asm {fldz // 加载0到ST0,栈顶下移fld1 // 加载1到ST0,栈顶下移fldpi // 加载π到ST0// 当前栈: ST0=π, ST1=1, ST2=0}printf(" 加载了0, 1, π到FPU栈\n");// 2. 基本算术运算printf("2. 基本算术运算:\n");float add_result, sub_result, mul_result, div_result;__asm {// 加法fld f1 // ST0 = 5.75fld f2 // ST0 = 3.14, ST1 = 5.75fadd // ST0 = ST1 + ST0 = 8.89fstp add_result // 存储并弹出// 减法fld f1fld f2fsub // ST0 = ST1 - ST0 = 2.61fstp sub_result// 乘法fld f1fld f2fmul // ST0 = ST1 * ST0 = 18.055fstp mul_result// 除法fld f1fld f2fdiv // ST0 = ST1 / ST0 = 1.831fstp div_result}printf(" 加法: %.2f + %.2f = %.2f\n", f1, f2, add_result);printf(" 减法: %.2f - %.2f = %.2f\n", f1, f2, sub_result);printf(" 乘法: %.2f * %.2f = %.2f\n", f1, f2, mul_result);printf(" 除法: %.2f / %.2f = %.2f\n", f1, f2, div_result);// 3. 复杂运算printf("3. 复杂运算:\n");float sqrt_result, sin_result, cos_result;__asm {// 平方根fld f1fsqrt // ST0 = sqrt(5.75)fstp sqrt_result// 三角函数 (需要先设置角度模式)fld f2fsin // ST0 = sin(3.14)fstp sin_resultfld f2fcos // ST0 = cos(3.14)fstp cos_result}printf(" 平方根: sqrt(%.2f) = %.3f\n", f1, sqrt_result);printf(" 正弦: sin(%.2f) = %.3f\n", f2, sin_result);printf(" 余弦: cos(%.2f) = %.3f\n", f2, cos_result);// 4. 比较和条件运算printf("4. 比较运算:\n");int compare_result;__asm {fld f1fld f2fcomip st, st(1) // 比较ST0和ST1,设置状态寄存器// 根据状态寄存器设置标志位jg greaterjl lessje equalgreater:mov compare_result, 1 // f2 > f1jmp doneless:mov compare_result, -1 // f2 < f1jmp doneequal:mov compare_result, 0 // f2 == f1done:fstp st(0) // 清理栈fstp st(0)}printf(" 比较 %.2f 和 %.2f: %d\n", f2, f1, compare_result);
}// x87 控制字操作
void x87_control_word() {printf("\n=== x87 控制字操作 ===\n");unsigned short cw;__asm {fstcw cw // 存储控制字}printf("当前控制字: 0x%04X\n", cw);// 修改控制字 - 设置舍入模式__asm {fstcw cwand cw, 0xF3FF // 清除舍入模式位or cw, 0x0C00 // 设置向零舍入fldcw cw // 加载新控制字}printf("修改后控制字: 0x%04X\n", cw);
}
2. SSE指令集详解
应用场景
- 多媒体处理:图像、音频、视频编码解码
- 游戏开发:3D图形变换、物理引擎
- 科学计算:向量运算、矩阵操作
- 数据处理:批量浮点运算
SSE汇编指令详细解析
#include <xmmintrin.h>void sse_detailed_analysis() {printf("\n=== SSE 详细分析 ===\n");alignas(16) float a[4] = {1.0f, 2.0f, 3.0f, 4.0f};alignas(16) float b[4] = {5.0f, 6.0f, 7.0f, 8.0f};alignas(16) float result[4];// 1. 数据加载和存储printf("1. 数据加载和存储:\n");__asm {movaps xmm0, [a] // 对齐加载16字节movups xmm1, [b] // 非对齐加载movaps [result], xmm0 // 对齐存储}printf(" 数据加载完成\n");// 2. 标量运算 (只操作最低位)printf("2. 标量运算:\n");float scalar_result;__asm {movss xmm0, [a] // 加载标量 (只加载第一个元素)movss xmm1, [b]addss xmm0, xmm1 // 标量加法movss [scalar_result], xmm0}printf(" 标量加法: %.1f + %.1f = %.1f\n", a[0], b[0], scalar_result);// 3. 向量运算 (并行操作所有元素)printf("3. 向量运算:\n");// 向量加法__asm {movaps xmm0, [a]movaps xmm1, [b]addps xmm0, xmm1 // 并行加法: [a0+b0, a1+b1, a2+b2, a3+b3]movaps [result], xmm0}printf(" 向量加法结果: ");for(int i = 0; i < 4; i++) printf("%.1f ", result[i]);printf("\n");// 向量乘法__asm {movaps xmm0, [a]movaps xmm1, [b]mulps xmm0, xmm1 // 并行乘法movaps [result], xmm0}printf(" 向量乘法结果: ");for(int i = 0; i < 4; i++) printf("%.1f ", result[i]);printf("\n");// 4. 混合和洗牌操作printf("4. 混合和洗牌操作:\n");__asm {movaps xmm0, [a]movaps xmm1, [b]shufps xmm0, xmm1, 0x44 // 混合两个向量的元素movaps [result], xmm0}printf(" 混合操作结果: ");for(int i = 0; i < 4; i++) printf("%.1f ", result[i]);printf("\n");// 5. 比较操作printf("5. 比较操作:\n");__asm {movaps xmm0, [a]movaps xmm1, [b]cmpps xmm0, xmm1, 1 // 比较是否小于 (a < b)movaps [result], xmm0}printf(" 比较结果 (a < b): ");for(int i = 0; i < 4; i++) printf("%s ", ((int)result[i] == 0xFFFFFFFF) ? "true" : "false");printf("\n");
}// SSE 矩阵向量乘法示例
void sse_matrix_vector_multiply() {printf("\n=== SSE 矩阵向量乘法 ===\n");// 4x4 矩阵和4x1向量alignas(16) float matrix[16] = {1, 2, 3, 4,5, 6, 7, 8,9, 10, 11, 12,13, 14, 15, 16};alignas(16) float vector[4] = {2, 3, 4, 5};alignas(16) float result[4] = {0};__asm {movaps xmm3, [vector] // 加载向量// 第一行movaps xmm0, [matrix] // [1,2,3,4]mulps xmm0, xmm3 // 逐元素相乘haddps xmm0, xmm0 // 水平加法haddps xmm0, xmm0 // 再次水平加法得到总和movss [result], xmm0 // 存储结果// 第二行 movaps xmm0, [matrix+16] // [5,6,7,8]mulps xmm0, xmm3haddps xmm0, xmm0haddps xmm0, xmm0movss [result+4], xmm0// 第三行movaps xmm0, [matrix+32] // [9,10,11,12]mulps xmm0, xmm3haddps xmm0, xmm0haddps xmm0, xmm0movss [result+8], xmm0// 第四行movaps xmm0, [matrix+48] // [13,14,15,16]mulps xmm0, xmm3haddps xmm0, xmm0haddps xmm0, xmm0movss [result+12], xmm0}printf("矩阵向量乘法结果:\n");for(int i = 0; i < 4; i++) {printf(" 行%d: %.1f\n", i, result[i]);}
}
3. AVX指令集详解
应用场景
- 高性能计算:科学模拟、数值分析
- 机器学习:神经网络推理、矩阵运算
- 信号处理:实时信号分析、滤波
- 大数据分析:批量数据处理
AVX汇编指令详细解析
#include <immintrin.h>void avx_detailed_analysis() {printf("\n=== AVX 详细分析 ===\n");alignas(32) float a[8] = {1, 2, 3, 4, 5, 6, 7, 8};alignas(32) float b[8] = {8, 7, 6, 5, 4, 3, 2, 1};alignas(32) float result[8];// 1. AVX三操作数指令格式printf("1. AVX三操作数指令:\n");__asm {vmovaps ymm0, [a] // 加载a到ymm0vmovaps ymm1, [b] // 加载b到ymm1vaddps ymm2, ymm0, ymm1 // ymm2 = ymm0 + ymm1 (不破坏源操作数)vmovaps [result], ymm2}printf(" AVX加法结果: ");for(int i = 0; i < 8; i++) printf("%.1f ", result[i]);printf("\n");// 2. 融合乘加 (FMA) 操作printf("2. 融合乘加操作:\n");__asm {vmovaps ymm0, [a]vmovaps ymm1, [b]vfmadd213ps ymm0, ymm1, ymm0 // ymm0 = ymm0 * ymm1 + ymm0vmovaps [result], ymm0}printf(" FMA结果: ");for(int i = 0; i < 8; i++) printf("%.1f ", result[i]);printf("\n");// 3. 数据广播printf("3. 数据广播操作:\n");float scalar = 2.5f;__asm {vbroadcastss ymm0, [scalar] // 将标量广播到所有8个位置vmovaps [result], ymm0}printf(" 广播结果: ");for(int i = 0; i < 8; i++) printf("%.1f ", result[i]);printf("\n");// 4. 掩码操作printf("4. 掩码操作:\n");__asm {vmovaps ymm0, [a]vmovaps ymm1, [b]vcmpps ymm2, ymm0, ymm1, 1 // 比较 a < bvblendvps ymm3, ymm0, ymm1, ymm2 // 根据掩码混合vmovaps [result], ymm3}printf(" 掩码混合结果: ");for(int i = 0; i < 8; i++) printf("%.1f ", result[i]);printf("\n");
}// AVX 高性能矩阵运算
void avx_matrix_operations() {printf("\n=== AVX 高性能矩阵运算 ===\n");const int N = 8;alignas(32) float matrixA[N*N];alignas(32) float matrixB[N*N];alignas(32) float result[N*N];// 初始化矩阵for(int i = 0; i < N*N; i++) {matrixA[i] = (float)(i + 1);matrixB[i] = (float)(N*N - i);}// AVX优化的矩阵加法for(int i = 0; i < N*N; i += 8) {__asm {vmovaps ymm0, [matrixA + i]vmovaps ymm1, [matrixB + i]vaddps ymm2, ymm0, ymm1vmovaps [result + i], ymm2}}printf("AVX矩阵加法完成\n");printf("结果矩阵前8个元素: ");for(int i = 0; i < 8; i++) printf("%.1f ", result[i]);printf("\n");
}// 性能对比测试
void performance_comparison() {printf("\n=== 性能特性对比 ===\n");printf("x87 FPU 特性:\n");printf(" - 栈式寄存器结构 (ST0-ST7)\n");printf(" - 80位扩展精度\n");printf(" - 顺序执行\n");printf(" - 适合: 高精度计算, 兼容性应用\n\n");printf("SSE 特性:\n");printf(" - 128位 XMM寄存器\n");printf(" - 4路单精度 / 2路双精度并行\n");printf(" - SIMD (单指令多数据)\n");printf(" - 适合: 多媒体, 游戏, 图形处理\n\n");printf("AVX 特性:\n");printf(" - 256位 YMM寄存器\n");printf(" - 8路单精度 / 4路双精度并行\n");printf(" - 三操作数指令格式\n");printf(" - 融合乘加 (FMA)\n");printf(" - 适合: 科学计算, 机器学习, 大数据\n");
}
4. 综合测试主函数
int main() {printf("浮点数处理技术详细分析\n");printf("======================\n");// x87 FPU 详细分析x87_detailed_analysis();x87_control_word();// SSE 详细分析sse_detailed_analysis();sse_matrix_vector_multiply();// AVX 详细分析avx_detailed_analysis();avx_matrix_operations();// 性能对比performance_comparison();return 0;
}
各指令集关键特点总结
x87 FPU
- 寄存器结构: 8个80位栈式寄存器 (ST0-ST7)
- 数据格式: 32位单精度, 64位双精度, 80位扩展精度
- 编程模式: 栈操作, 隐式操作数
- 优势: 高精度, 兼容性好
- 劣势: 顺序执行, 无并行能力
SSE
- 寄存器结构: 16个128位XMM寄存器 (XMM0-XMM15)
- 数据格式: 4个单精度或2个双精度浮点数
- 编程模式: 显式寄存器操作, SIMD并行
- 优势: 数据并行, 多媒体优化
- 劣势: 128位宽度限制
AVX
- 寄存器结构: 16个256位YMM寄存器 (YMM0-YMM15)
- 数据格式: 8个单精度或4个双精度浮点数
- 编程模式: 三操作数指令, 更灵活的寄存器使用
- 优势: 双倍并行度, FMA操作, 更好的指令格式
- 劣势: 需要较新的硬件支持
这种分层设计使得开发者可以根据具体应用需求选择合适的指令集,在兼容性、性能和开发复杂度之间找到最佳平衡。
浮点数指令集汇编指令详解
浮点数指令集汇编指令详解
1. x87 FPU 指令集汇编指令
数据传送指令
; 加载指令
FLD m32/m64/m80 ; 加载浮点数到ST0
FILD m32/m64 ; 加载整数到ST0
FLD1 ; 加载+1.0到ST0
FLDZ ; 加载+0.0到ST0
FLDPI ; 加载π到ST0
FLDL2E ; 加载log2(e)到ST0
FLDL2T ; 加载log2(10)到ST0
FLDLG2 ; 加载log10(2)到ST0
FLDLN2 ; 加载ln(2)到ST0; 存储指令
FST m32/m64 ; 存储ST0到内存(不弹出)
FSTP m32/m64/m80 ; 存储ST0到内存并弹出
FIST m32/m64 ; 存储ST0为整数(不弹出)
FISTP m32/m64 ; 存储ST0为整数并弹出
算术运算指令
; 基本算术
FADD ; ST1 = ST1 + ST0, 弹出ST0
FADD m32/m64 ; ST0 = ST0 + m
FADDP STi, ST0 ; STi = STi + ST0, 弹出ST0FSUB ; ST1 = ST1 - ST0, 弹出ST0
FSUBR ; ST1 = ST0 - ST1, 弹出ST0
FSUBP STi, ST0 ; STi = STi - ST0, 弹出ST0FMUL ; ST1 = ST1 * ST0, 弹出ST0
FMUL m32/m64 ; ST0 = ST0 * mFDIV ; ST1 = ST1 / ST0, 弹出ST0
FDIVR ; ST1 = ST0 / ST1, 弹出ST0
超越函数指令
; 三角函数
FSIN ; ST0 = sin(ST0)
FCOS ; ST0 = cos(ST0)
FSINCOS ; ST1 = sin(ST0), ST0 = cos(ST0)
FPTAN ; ST0 = tan(ST0), 压入1.0
FPATAN ; ST1 = atan(ST1/ST0), 弹出ST0; 对数和指数
F2XM1 ; ST0 = 2^ST0 - 1
FYL2X ; ST1 = ST1 * log2(ST0), 弹出ST0
FYL2XP1 ; ST1 = ST1 * log2(ST0+1.0), 弹出ST0
比较和测试指令
FCOM m32/m64 ; 比较ST0与m
FCOM STi ; 比较ST0与STi
FCOMP ; 比较并弹出
FCOMPP ; 比较并弹出两次
FTST ; 比较ST0与0.0
FUCOM STi ; 无序比较
FUCOMPP ; 无序比较并弹出两次; 条件码测试
FSTSW AX ; 存储状态字到AX
SAHF ; 将AH存入标志寄存器
控制指令
FINCSTP ; 增加栈指针
FDECSTP ; 减少栈指针
FFREE STi ; 释放寄存器
FNOP ; 空操作
FWAIT ; 等待FPU就绪
2. SSE 指令集汇编指令
数据传送指令
; 对齐加载/存储
MOVAPS xmm1, xmm2/m128 ; 对齐打包单精度加载
MOVAPD xmm1, xmm2/m128 ; 对齐打包双精度加载
MOVAPS m128, xmm1 ; 对齐打包单精度存储; 非对齐加载/存储
MOVUPS xmm1, xmm2/m128 ; 非对齐打包单精度加载
MOVUPD xmm1, xmm2/m128 ; 非对齐打包双精度加载; 标量加载/存储
MOVSS xmm1, xmm2/m32 ; 标量单精度加载
MOVSD xmm1, xmm2/m64 ; 标量双精度加载
MOVLPS xmm1, m64 ; 加载低64位打包单精度
MOVHPS xmm1, m64 ; 加载高64位打包单精度
算术运算指令
; 打包单精度浮点运算
ADDPS xmm1, xmm2/m128 ; 打包单精度加法
SUBPS xmm1, xmm2/m128 ; 打包单精度减法
MULPS xmm1, xmm2/m128 ; 打包单精度乘法
DIVPS xmm1, xmm2/m128 ; 打包单精度除法
SQRTPS xmm1, xmm2/m128 ; 打包单精度平方根
MAXPS xmm1, xmm2/m128 ; 打包单精度最大值
MINPS xmm1, xmm2/m128 ; 打包单精度最小值; 标量单精度浮点运算
ADDSS xmm1, xmm2/m32 ; 标量单精度加法
SUBSS xmm1, xmm2/m32 ; 标量单精度减法
MULSS xmm1, xmm2/m32 ; 标量单精度乘法
DIVSS xmm1, xmm2/m32 ; 标量单精度除法
SQRTSS xmm1, xmm2/m32 ; 标量单精度平方根
比较指令
; 打包比较
CMPPS xmm1, xmm2/m128, imm8 ; 打包单精度比较
CMPPD xmm1, xmm2/m128, imm8 ; 打包双精度比较; 标量比较
CMPSS xmm1, xmm2/m32, imm8 ; 标量单精度比较
CMPSD xmm1, xmm2/m64, imm8 ; 标量双精度比较; 比较谓词 (imm8值)
; 0: EQ (等于), 1: LT (小于), 2: LE (小于等于)
; 4: NEQ (不等于), 5: NLT (不小于), 6: NLE (不小于等于)
数据重排指令
SHUFPS xmm1, xmm2/m128, imm8 ; 打包单精度洗牌
UNPCKHPS xmm1, xmm2/m128 ; 交错高单精度
UNPCKLPS xmm1, xmm2/m128 ; 交错低单精度; 位操作
ANDPS xmm1, xmm2/m128 ; 按位与
ORPS xmm1, xmm2/m128 ; 按位或
XORPS xmm1, xmm2/m128 ; 按位异或
ANDNPS xmm1, xmm2/m128 ; 按位与非
转换指令
CVTPS2PD xmm1, xmm2/m64 ; 打包单精度转双精度
CVTPD2PS xmm1, xmm2/m128 ; 打包双精度转单精度
CVTSI2SS xmm1, r32/m32 ; 整数转标量单精度
CVTSS2SI r32, xmm1/m32 ; 标量单精度转整数
3. AVX 指令集汇编指令
数据传送指令
; 对齐加载/存储
VMOVAPS ymm1, ymm2/m256 ; 对齐打包单精度加载
VMOVAPD ymm1, ymm2/m256 ; 对齐打包双精度加载
VMOVAPS m256, ymm1 ; 对齐打包单精度存储; 非对齐加载/存储
VMOVUPS ymm1, ymm2/m256 ; 非对齐打包单精度加载
VMOVUPD ymm1, ymm2/m256 ; 非对齐打包双精度加载; 标量加载/存储
VMOVSS xmm1, xmm2, xmm3/m32 ; 标量单精度加载(三操作数)
VMOVSD xmm1, xmm2, xmm3/m64 ; 标量双精度加载(三操作数); 广播指令
VBROADCASTSS ymm1, xmm2/m32 ; 广播标量单精度到所有位置
VBROADCASTSD ymm1, xmm2/m64 ; 广播标量双精度到所有位置
算术运算指令(三操作数格式)
; 打包单精度浮点运算
VADDPS ymm1, ymm2, ymm3/m256 ; 打包单精度加法
VSUBPS ymm1, ymm2, ymm3/m256 ; 打包单精度减法
VMULPS ymm1, ymm2, ymm3/m256 ; 打包单精度乘法
VDIVPS ymm1, ymm2, ymm3/m256 ; 打包单精度除法
VSQRTPS ymm1, ymm2/m256 ; 打包单精度平方根
VMAXPS ymm1, ymm2, ymm3/m256 ; 打包单精度最大值
VMINPS ymm1, ymm2, ymm3/m256 ; 打包单精度最小值; 标量单精度浮点运算
VADDSS xmm1, xmm2, xmm3/m32 ; 标量单精度加法
VSUBSS xmm1, xmm2, xmm3/m32 ; 标量单精度减法
VMULSS xmm1, xmm2, xmm3/m32 ; 标量单精度乘法
VDIVSS xmm1, xmm2, xmm3/m32 ; 标量单精度除法
融合乘加指令 (FMA)
; FMA指令系列
VFMADD132PS ymm1, ymm2, ymm3/m256 ; ymm1 = ymm1 * ymm3 + ymm2
VFMADD213PS ymm1, ymm2, ymm3/m256 ; ymm1 = ymm2 * ymm1 + ymm3
VFMADD231PS ymm1, ymm2, ymm3/m256 ; ymm1 = ymm2 * ymm3 + ymm1VFMADD132SS xmm1, xmm2, xmm3/m32 ; 标量版本
VFMADD213SS xmm1, xmm2, xmm3/m32
VFMADD231SS xmm1, xmm2, xmm3/m32; FMSUB (乘减) 系列
VFMSUB132PS ymm1, ymm2, ymm3/m256 ; ymm1 = ymm1 * ymm3 - ymm2
比较和测试指令
; 打包比较
VCMPPS ymm1, ymm2, ymm3/m256, imm8 ; 打包单精度比较
VCMPPD ymm1, ymm2, ymm3/m256, imm8 ; 打包双精度比较; 标量比较
VCMPSS xmm1, xmm2, xmm3/m32, imm8 ; 标量单精度比较
VCMPSD xmm1, xmm2, xmm3/m64, imm8 ; 标量双精度比较; 测试指令
VTESTPS ymm1, ymm2/m256 ; 测试打包单精度位
VTESTPD ymm1, ymm2/m256 ; 测试打包双精度位
数据重排和混合指令
; 洗牌指令
VSHUFPS ymm1, ymm2, ymm3/m256, imm8 ; 打包单精度洗牌
VPERMILPS ymm1, ymm2, ymm3/m256 ; 排列打包单精度
VPERM2F128 ymm1, ymm2, ymm3/m256, imm8 ; 排列128位通道; 混合指令
VBLENDVPS ymm1, ymm2, ymm3/m256, ymm4 ; 条件混合打包单精度
VBLENDPS ymm1, ymm2, ymm3/m256, imm8 ; 立即数混合打包单精度; 位操作
VANDPS ymm1, ymm2, ymm3/m256 ; 按位与
VORPS ymm1, ymm2, ymm3/m256 ; 按位或
VXORPS ymm1, ymm2, ymm3/m256 ; 按位异或
4. 实用汇编代码示例
x87 FPU 复杂计算示例
; 计算: result = (a * b) + sqrt(c) / d
fld dword [a] ; ST0 = a
fmul dword [b] ; ST0 = a * b
fld dword [c] ; ST0 = c, ST1 = a*b
fsqrt ; ST0 = sqrt(c)
fdiv dword [d] ; ST0 = sqrt(c) / d
fadd ; ST0 = (a*b) + (sqrt(c)/d)
fstp dword [result] ; 存储结果
SSE 向量点积计算
; 计算4元素向量点积
movaps xmm0, [vec1] ; 加载向量1
movaps xmm1, [vec2] ; 加载向量2
mulps xmm0, xmm1 ; 逐元素相乘
; 水平求和
movaps xmm1, xmm0
shufps xmm1, xmm1, 0x4E ; 交换高低64位
addps xmm0, xmm1
movaps xmm1, xmm0
shufps xmm1, xmm1, 0xB1 ; 交换32位对
addps xmm0, xmm1
movss [result], xmm0 ; 存储结果
AVX 矩阵向量乘法
; 使用AVX计算矩阵4x4与向量4x1乘法
vmovaps ymm0, [matrix] ; 加载矩阵第一行和第二行
vmovaps ymm1, [matrix+32] ; 加载矩阵第三行和第四行
vbroadcastss ymm2, [vector] ; 广播向量第一个元素
vbroadcastss ymm3, [vector+4] ; 广播向量第二个元素vmulps ymm4, ymm0, ymm2 ; 第一、二行乘以向量[0]
vmulps ymm5, ymm1, ymm2 ; 第三、四行乘以向量[0]vbroadcastss ymm2, [vector+8] ; 广播向量第三个元素
vbroadcastss ymm3, [vector+12] ; 广播向量第四个元素vfmadd231ps ymm4, ymm0, ymm3 ; 融合乘加
vfmadd231ps ymm5, ymm1, ymm3; 水平求和并存储结果
vhaddps ymm4, ymm4, ymm4
vhaddps ymm4, ymm4, ymm4
vextractf128 xmm5, ymm4, 1
vaddss xmm4, xmm4, xmm5
vmovss [result], xmm4
5. 指令集选择指南
根据数据类型选择
; 单精度浮点数组处理
; SSE: 适合4元素并行
movaps xmm0, [array]
addps xmm0, [array2]
movaps [result], xmm0; AVX: 适合8元素并行
vmovaps ymm0, [array]
vaddps ymm0, ymm0, [array2]
vmovaps [result], ymm0; 双精度浮点
; SSE: 适合2元素并行
movapd xmm0, [array]
addpd xmm0, [array2]; AVX: 适合4元素并行
vmovapd ymm0, [array]
vaddpd ymm0, ymm0, [array2]
根据精度要求选择
; 高精度要求 - 使用x87
fldpi ; 80位精度的π
fld1 ; 精确的1.0
fdiv ; 高精度除法; 性能要求 - 使用AVX
vfmadd231ps ymm0, ymm1, ymm2 ; 融合乘加,更高性能
vbroadcastss ymm1, [scalar] ; 高效广播
这些汇编指令展示了不同指令集在处理浮点数时的能力和特点。在实际编程中,应根据具体的性能需求、精度要求和硬件支持来选择合适的指令集。