• 正文
  • 相關(guān)推薦
申請(qǐng)入駐 產(chǎn)業(yè)圖譜

為什么插入了幾條NOP指令,MCU的功耗就變了?

2024/10/22
2170
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

我最近在測(cè)試一個(gè)M0+ MCU的運(yùn)行功耗,測(cè)試代碼采用如下最簡(jiǎn)單的方式,即main函數(shù)里只跑一個(gè)while(1)空循環(huán),測(cè)試出來(lái)的電流是1.11mA,使用的IDE為KEIL MDK,優(yōu)化等級(jí)為0

當(dāng)我在while(1)的前面插入3條NOP指令,測(cè)出來(lái)的電流卻變成了0.89mA。

這是怎么回事?是測(cè)量誤差,還是事實(shí)就是如此?這可是足足差了200多uA啊,為此我又做了如下幾個(gè)對(duì)比實(shí)驗(yàn)。

測(cè)試條件 功耗
優(yōu)化等級(jí)0,while(1)前不加NOP 1.11mA
優(yōu)化等級(jí)0,while(1)前插入1個(gè)NOP 0.90mA
優(yōu)化等級(jí)0,while(1)前插入2個(gè)NOP 1.11mA
優(yōu)化等級(jí)0,while(1)前插入3個(gè)NOP 0.89mA
優(yōu)化等級(jí)0,while(1)前插入4個(gè)NOP 1.12mA
優(yōu)化等級(jí)0,while(1)前插入5個(gè)NOP 0.91mA
優(yōu)化等級(jí)0,while(1)前插入6個(gè)NOP 1.11mA
優(yōu)化等級(jí)0,while(1)前插入7個(gè)NOP 0.88mA
優(yōu)化等級(jí)0,while(1)前插入8個(gè)NOP 1.11mA

上述實(shí)驗(yàn)可以看到明顯的規(guī)律,只要while(1)前插入的NOP是奇數(shù)時(shí)功耗就相對(duì)小一點(diǎn)(差不多都是約0.9mA),while(1)前插入的NOP是偶數(shù)時(shí)功耗就大一點(diǎn)(差不多都是約1.11mA)。

說(shuō)到這里,我們需要來(lái)了解一下NOP指令,我之前對(duì)NOP指令的理解只停留在它可以用來(lái)做軟件延時(shí)用,其實(shí)它還有一個(gè)重要的作用是實(shí)現(xiàn)指令對(duì)齊

在調(diào)試窗口下,我們看一下匯編代碼

C代碼的while(1)被匯編成了2條指令,即NOP和B,跳轉(zhuǎn)指令B前自動(dòng)插了一個(gè)NOP。while(1)實(shí)際上是先執(zhí)行一個(gè)NOP指令,再執(zhí)行B指令,B指令跳轉(zhuǎn)的地址就是自身的地址,達(dá)到無(wú)限循環(huán)的效果??梢钥吹酱藭r(shí)while(1)里NOP指令地址是0x00000152(十進(jìn)制338),B指令地址是0x00000154(十進(jìn)制340)。

當(dāng)while(1)前插入奇數(shù)條NOP指令后,while(1)對(duì)應(yīng)的指令地址會(huì)改變。

指令地址的變化為什么會(huì)影響功耗呢?這又得需要提一下CPU執(zhí)行指令的過(guò)程。

CPU內(nèi)部一直重復(fù)執(zhí)行著 Fetch(取指令)–> Decode(指令譯碼)–> Execute(執(zhí)行指令)的過(guò)程。

CPU在執(zhí)行程序取指令的時(shí)候,每次按照Flash 4字節(jié)對(duì)齊的方式從Flash一次讀32bit的指令,如果while(1)前插入偶數(shù)(包括0)個(gè)NOP指令,那么CPU在執(zhí)行while(1)時(shí),需要從Flash讀取2次32bit內(nèi)容再Decode去執(zhí)行。如果while(1)前插入奇數(shù)個(gè)NOP指令,那么CPU在執(zhí)行while(1)時(shí),只需要從Flash讀取1次32bit內(nèi)容即可。就是這個(gè)地方的差異會(huì)引起功耗的差異,前者要執(zhí)行更多的操作所以功耗更大一點(diǎn)。

此外如果while(1)前不加入NOP,但是把優(yōu)化等級(jí)調(diào)到最高,此時(shí)while(1)里 B指令前就不會(huì)插入一條NOP指令,這時(shí)B指令的地址為0x00000152,這時(shí)效果和不開(kāi)優(yōu)化等級(jí)、while(1)之前插入奇數(shù)個(gè)NOP一樣,功耗也會(huì)低一點(diǎn)。道理其實(shí)是一樣的,因?yàn)閣hile(1)的執(zhí)行只需要從0x150地址取一次指。

最后我還做了一個(gè)實(shí)驗(yàn),就是把程序放到了RAM里,不管while(1)前加多少NOP,功耗都是一樣,都是0.58mA。程序在RAM里,就不用從Flash里讀程序了,所以功耗更低。

利用功耗的不同去做破解的行為,也是類(lèi)似的原理。

以上分析僅是猜測(cè),因?yàn)椴涣私釳CU內(nèi)部的運(yùn)行細(xì)節(jié),如果不對(duì)之處,歡迎大家指正。

相關(guān)推薦

登錄即可解鎖
  • 海量技術(shù)文章
  • 設(shè)計(jì)資源下載
  • 產(chǎn)業(yè)鏈客戶(hù)資源
  • 寫(xiě)文章/發(fā)需求
立即登錄

TopSemic,讓芯片使用更簡(jiǎn)單。 專(zhuān)注分享:嵌入式,單片機(jī),STM32,ARM,RTOS,Linux, 軟硬件,半導(dǎo)體,電子技術(shù)等相關(guān)內(nèi)容。