STM32H7/cotex M内核 汇编芯片解密
一 芯片解密内核行为分析
芯片解密实例代码1:
芯片解密FPU_Test: //double FPU_Test (double a_mul,double b_mul,double c_add);
PUSH{R4-R7}
MOV R0, #1024 //减少循环次数,避免缓存影响
// 初始化完全独立的寄存器组
LDR R1,=8234
MOV R6,R0
MOV R7,R1
PLI [LR]
FPU_Test_Loop_Opt:
// 8组完全独立的 VFMA 操作
VFMA.F32 S2, S1, S0 // 组1
SMLAL R3,R2,R1,R0
VFMA.F32 S3, S1, S0 // 组2 - 完全独立
SUBS R4,R4, #1
SHADD16 R5,R5,R0
SMLAL R3,R2,R1,R0
VFMA.F32 S4, S1, S0 // 组3 - 完全独立
SHADD16 R4,R4,R1
SUBS R5,R5, #1
SMLAL R3,R2,R1,R0
VFMA.F32 S5, S1, S0 // 组4 - 完全独立
SHADD16 R5,R5,R0
SUBS R4,R4, #1
SMLAL R3,R2,R1,R0
VFMA.F32 S6, S1, S0 // 组5 - 完全独立
SUBS R0,R0, #1
BNE FPU_Test_Loop_Opt
POP{R4-R7}
BX LR
以上为keilv5 MDK V5.23 编译器语法
1:使用VFMA(浮点区域指令)与使用SMLAL(整数区域指令)能够让处理器进行双发射(在cotex M7权威手册里亦有记载)
但是,注意需注意顺序即:
VFMA.F32 S2, S1, S0 // 组1
SMLAL R3,R2,R1,R0
VFMA.F32 S4, S1, S0 // 组3 - 完全独立
SHADD16 R4,R4,R1
是能够正常双发射
VFMA.F32 S2, S1, S0 // 组1
SMLAL R3,R2,R1,R0
SHADD16 R4,R4,R1
VFMA.F32 S4, S1, S0 // 组3 - 完全独立
以上只能单发射,而不能双发射
SHADD16 R4,R4,R1
SUBS R5,R5, #1
SMLAL R3,R2,R1,R0
VFMA.F32 S5, S1, S0 // 组4 - 完全独立
以上可以双发射
总结为:在使用浮点+整数指令时,下一条指令如果需要使用整数并且需要使用寄存器,那么MCU则不支持双发射,如果为浮点,即可成功双发射.
若持续为整数指令,那么在数据无依赖的情况下,即可双发射,否者只能单发射,或者阻塞 (均不包含除法指令)
1 针对于除法指令,在mcu上能不用就不用,无符号/有符号整数除法平均会消耗10个周期左右,除非你的结果较小,例如小于256.那么可以在较短的时间里得出结果,对于双精度浮点除法,通常需要14-16个时钟周期,单精度需要8-12个周期.除法指令是阻塞运行的,不支持单周期的吞吐量.除法比较特殊,即使数据无依赖也不行
2 在cotex-m7内核上,大部分都会有支持双精度浮点,但是,双精度浮点一般比单精度慢2-8倍,不同指令有着不同的效率,如VADD.F64就最快,2周期的吞吐量,基本与VADD.F32 的单周期差不了太多,对于像VFMA.F32(实例代码中的指令)为单周期吞吐量. VFMA.F64不支持单周期吞吐量,执行一条需要7个周期,并且不支持与其他指令双发射,包括大部分的.F64的运算指令(像VMOV.F64这种执行时间为2周期,与双精度与单精度无关,执行周期按位宽/32bit)都不支持与其他指令双发射

芯片解密