亚洲春色中文字幕久久久-三上亚,一吻二脱三床四吻胸,国产真实伦对白视频全集,在线毛片观看,精品成品入口黄网,国产毛aⅴ片久久久,亚洲AV色香蕉一区二区三区老师,萧皇后A级艳片,色情日本视频更新,99久久亚洲精品日本无码
標題:
STM32H7/cotex M內核 匯編,內嵌匯編小技巧
[打印本頁]
作者:
UH502
時間:
2025-11-6 02:39
標題:
STM32H7/cotex M內核 匯編,內嵌匯編小技巧
以下作為我個使用cotex M7內核統計的一些特性:
一 內核行為分析
實例代碼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)
都不支持與其他指令雙發射
二 性能優化:
對于需要性能優化的場景來說,手動添加(C#) __ASM volatile{ "PLI [這里填C里的一個變量]");用于提前預加載(提示內核等會兒要使用)需要執行的指令,可以在跳轉后更快的執行,通常用于執行動態代碼,例如:
__ASM volatile (
"push{r0,r1}\n"
"MOV R0,0X01 \n"
"ISB SY\n"
"PLI [R0]\n"
"ISB SY\n"
"pop {r0,r1}\n"
);
__ASM volatile (
"push {r0-r3,r12,lr} \n"
"MOV R0,0X01 \n"
"BLX R0 \n"
"pop {r0-r3,r12,lr} \n"
);
中,將動態代碼存放于ITCM內存中,代碼就是實例代碼1,存放地址0x00
對于需要跳轉動態代碼時,保存寄存器是一個必不可少的的操作,通常使用堆棧保存,通常建議堆棧始終為8字節對齊
(在cotex M系列內核權威手冊里亦有記載)
所以在使用push的時候,建議一次性壓入兩個寄存器(64位)保持一直為8字節對齊.對于未對其的情況下,我也測試過了,首先效率會下降,對齊的情況,入棧8個字節僅需一個周期,無阻塞的發射,即可執行接下來的指令,未對其情況下,與使用STM SP!{ }是等效的,需要1個周期解析指令+2個周期存入數據.
其次未8字節對齊容易導致未定義行為,進入HardFault_Handler,這個問題隱藏的很隱蔽,使用Jlink單步調試是無法復現問題.
(我沒記錯的話,權威手冊里應該有記載,不過容易忽略,這里就提個醒)
對于地址跳轉,一定要保證,需要跳轉的地址的最低位一定要為1, 例如你需要跳轉到0x0800346,那么你實際要寫入PC指針的地址一定是
0x0800347,而不是
0x0800346,否則也會導致未定義行為,進入
HardFault_Handler,同樣使用jlink無法復現,單步無法發現問題.
先記錄到這里,如有新的勘誤點會在更新,附件為cotex M4系列內核匯編編程手冊,全冊中文,對于初學者來說很有用處
STM32F3與F4系列Cortex M4內核編程手冊_中文版.pdf
2025-11-6 03:24 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
6.71 MB, 下載次數: 0, 下載積分: 黑幣 -5
歡迎光臨 (http://www.denmoz.com/bbs/)
Powered by Discuz! X3.1