加入星計劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴(kuò)散
  • 作品版權(quán)保護(hù)
  • 300W+ 專業(yè)用戶
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長期合作伙伴
立即加入
  • 正文
  • 相關(guān)推薦
  • 電子產(chǎn)業(yè)圖譜
申請入駐 產(chǎn)業(yè)圖譜

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

10/22 11:10
1209
閱讀需 5 分鐘
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

相關(guān)推薦

電子產(chǎn)業(yè)圖譜

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