一区二区三区三上|欧美在线视频五区|国产午夜无码在线观看视频|亚洲国产裸体网站|无码成年人影视|亚洲AV亚洲AV|成人开心激情五月|欧美性爱内射视频|超碰人人干人人上|一区二区无码三区亚洲人区久久精品

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

【專欄精選】Cortex-M 的反編譯入門

電子發(fā)燒友論壇 ? 來源:未知 ? 2023-05-16 09:35 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

做電子發(fā)燒友技術(shù)探索官,分享你的原創(chuàng)電子行業(yè)文章!

本期為大家推薦一篇嵌入式相關(guān)技術(shù)文章,作者主要從事嵌入式領(lǐng)域的開發(fā),感興趣的小伙伴可以關(guān)注學(xué)習(xí)哦~


本期推

專欄作者嵌入式大雜燴(點(diǎn)擊查看作者主頁)

介紹:該專欄主要介紹嵌入式開發(fā)相關(guān)的知識(shí),與大家一起交流學(xué)習(xí)。


我們?cè)趯?/span>單片機(jī)裸機(jī)程序時(shí),在主函數(shù)之前,會(huì)有一段啟動(dòng)代碼,而啟動(dòng)代碼是用匯編寫的,有些朋友可能看到匯編頭都大了,當(dāng)時(shí)要想深入研究底層架構(gòu),這快硬骨頭就必須去啃。


匯編:匯編文件轉(zhuǎn)換為目標(biāo)文件(里面是機(jī)器碼)。

反匯編:可執(zhí)行文件(目標(biāo)文件,里面是機(jī)器碼),轉(zhuǎn)換為匯編文件。

關(guān)于匯編的基礎(chǔ)知識(shí),請(qǐng)關(guān)注筆者專欄,閱讀以前的文章。

今天筆者以STM32F1的點(diǎn)燈程序?yàn)槔瑤ьI(lǐng)大家進(jìn)行反匯編,并閱讀反匯編后的代碼。

1 新建LED裸機(jī)程序

1.新建文件夾

新建文件夾“STM32F1”,當(dāng)然名字也可以另取,在 STM32F1文件夾下,我們新建五個(gè)文件夾,分別為CMSIS、Listing、Output、Project、User。

其中CMSIS文件夾放啟動(dòng)文件:


筆者的開發(fā)板芯片是STM32F103ZE,這個(gè)文件是根據(jù)STM32的固件庫startup_stm32f10x_md.s文件修改而來。

2.新建工程

打開Keil,在工具欄 Project->New μVision Project…新建我們的工程文件。


輸入工程名,保存即可。


窗口是讓我們選擇公司跟芯片的型號(hào),我們用的芯片是 ST 公司的STM32F103ZE,有64K SRAM,512K Flash,屬于高集成度的芯片。按如下選擇即可。



后點(diǎn)擊項(xiàng)目管理。


最后修改后的內(nèi)容如下:


并添加相應(yīng)的文件。


其中main.c的內(nèi)容如下所示:

/**
* @brief 延時(shí)函數(shù)
* @param d
* @retval None
*/
void delay(int d)
{
while(d--);
}


/**
* @brief main
* @param None
* @retval int
*/
int main(void)
{
unsigned int *pReg;

/* 使能GPIOB */
pReg = (unsigned int *)(0x40021000 + 0x18);
*pReg |= (1<<3);

/* 設(shè)置GPIOB0為輸出引腳 */
pReg = (unsigned int *)(0x40010C00 + 0x00);
*pReg |= (1<<0);


pReg = (unsigned int *)(0x40010C00 + 0x0C);

while (1)
{
/* 設(shè)置GPIOB0輸出1 */
*pReg |= (1<<0);

delay(1000000);


/* 設(shè)置GPIOB0輸出0 */
*pReg &= ~(1<<0);

delay(1000000);
}
}

startup.s文件的內(nèi)容如下:

;************************************ STM32F1 ************************************
;* File Name : startup.s
;* Author : BruceOu
;* Version : V1.0
;* Date : 2021-06-27
;* Description : STM32F10x Medium Density Devices vector table for MDK-ARM
;* toolchain.
;* This module performs:
;* - Set the initial SP
;* - Set the initial PC == Reset_Handler
;* - Set the vector table entries with the exceptions ISR address
;* - Configure the clock system
;* - Branches to __main in the C library (which eventually
;* calls main()).
;* After Reset the CortexM3 processor is in Thread mode,
;* priority is Privileged, and the Stack is set to Main.
;*******************************************************************************
PRESERVE8
THUMB




; Vector Table Mapped to Address 0 at Reset
AREA RESET, DATA, READONLY
EXPORT __Vectors

__Vectors DCD 0
DCD Reset_Handler ; Reset Handler


AREA |.text|, CODE, READONLY


; Reset handler
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT main


LDR SP, =(0x20000000+0x10000)
BL main


ENDP

END

接下來還有配置工程。


選擇Output文件夾。


選擇Listing文件夾。


基本配置就這些,接下來編譯工程。


只要沒有錯(cuò)誤就可以了,最后就是下載程序,筆者使用的是J-Link,最后的現(xiàn)象如下:


LED會(huì)不停閃爍。

2 Keil反匯編

接下來才是今天正題,反匯編。

在KEIL的User選項(xiàng)中,如下圖添加這兩項(xiàng):

fromelf --bin --output=STM32F1.bin ../Output/STM32F1.axf

fromelf --text -a -c --output=STM32F1.dis ../Output/STM32F1.axf

然后重新編譯,即可得到二進(jìn)制文件STM32F1.bin(以后會(huì)分析)、反匯編文件STM32F1.dis。

如下圖所示:


正常編譯過程是分為四個(gè)階段進(jìn)行的,即預(yù)處理(也稱預(yù)編譯,Preprocessing)、編譯(Compilation)、匯編 (Assembly)和鏈接(Linking)。

但是反編譯是講為二進(jìn)制文件反編譯成匯編文件,因此反匯編的流程如下:

3 反匯編代碼解析

接下來就是查看反編譯代碼,打開反編譯文件Project/STM32F1.dis。這里只截取一段查看,因?yàn)楦袷蕉际且粯拥?,知識(shí)每條內(nèi)容不同罷了。


第一列是鏈接地址,第二列是機(jī)器碼,第三列是匯編指令。

根本匯編指令,我們找到ARMv7-M Architecture Reference Manual_DDI 0403E.d (ID070218)中的LDR指令。


我們將F8DFD004變成二進(jìn)制。


這個(gè)使用的32位的Thumb2指令集。


其中b0~b11是立即數(shù),這里是4,對(duì)應(yīng)的匯編代碼的也是4,這里要注意的是,ARM指令采用流水線機(jī)制,當(dāng)前執(zhí)行地址A的指令,同時(shí)已經(jīng)在對(duì)下一條指令進(jìn)行譯碼同時(shí)已經(jīng)在讀取下下一條指令:PC = A +4 (Thumb/Thumb2指令集)。


B12~b15是寄存器,這段大小是0XC,對(duì)應(yīng)的寄存器就是sp;


后面16bit除了23位意外,全是固定的,其中‘U’表示無條件執(zhí)行,這里置為1。

其他的匯編指令對(duì)應(yīng)的機(jī)器碼也是類似的,值得注意的是,不同的架構(gòu)對(duì)應(yīng)的機(jī)器碼也是不同的,這也就回答了為了不同的處理器架構(gòu)會(huì)對(duì)應(yīng)不同的指令集。

有興趣的可以對(duì)比Cortex-M系列和Cortex-A系列的的指令集。請(qǐng)參考以下手冊(cè):

ARM Architecture Reference Manual ARMv7-A and ARMv7-R edition.pdf

ARMv7-M Architecture Reference Manual.pdf

4 反匯編代碼全解析

進(jìn)入debug模式,在View下選擇disassembly window。


這樣就可將機(jī)器碼和對(duì)應(yīng)的代碼對(duì)應(yīng)起來。當(dāng)程序運(yùn)行起來了,也就從異常向量表中跳轉(zhuǎn)到Reset_Handler中,然后跳轉(zhuǎn)到main函數(shù)中,而main函數(shù)是在棧中,因此需要設(shè)置占空間的起始位置。根據(jù)STM32的參考手冊(cè),SRAM的其起始地址和大小如下:


因此棧頂為起始位置加上棧的大小即可,只要不超過SRAM即可。


值得注意的是,棧是__向低地址擴(kuò)展的數(shù)據(jù)結(jié)構(gòu)__,是一塊連續(xù)的內(nèi)存區(qū)域,棧頂?shù)牡刂泛蜅5淖畲笕萘渴窃谕ㄟ^LDR設(shè)置,因此需要根據(jù)應(yīng)用需求合理分配??臻g。

接下來往下走,如果在匯編中不打斷點(diǎn),會(huì)默認(rèn)進(jìn)入main函數(shù)的一條指令,就從這里分析。為了分析方便,這里還有使用上一節(jié)方便出來的文件。



【C代碼33行】

從內(nèi)存地址0x0800 017c拷貝數(shù)據(jù)0x40021018到r3中,也就是

r3 = * 0x0800 017c

也就是將pReg指針保存到r3中。


【C代碼34行】

這里對(duì)應(yīng)3條指令


首先將r3拷貝到r0中,然后將r0或上1左移3位,也就是

ORR r0,r0,#8

最后將r0的值寫入r3所指地址中。

【C代碼37行】

同33行,從內(nèi)存地址0x0800 0180拷貝數(shù)據(jù)40010c00到r3中


【C代碼38行】

同34行,這里也對(duì)應(yīng)3條指令:


【C代碼40行】

和33行不同的是,這里分了兩條指令:


筆者認(rèn)為前面是編譯器優(yōu)化了。根據(jù)ARM指令采用流水線機(jī)制,當(dāng)前執(zhí)行地址A的指令,同時(shí)已經(jīng)在對(duì)下一條指令進(jìn)行譯碼同時(shí)已經(jīng)在讀取下下一條指令:PC = A +4 (Thumb/Thumb2指令集)。因此前面類似的代碼被優(yōu)化了。

接下來就進(jìn)入循環(huán)中。

后面就移植在死循環(huán)中,不斷操作GPIO的亮滅。

【C代碼45行】

這里是將B0設(shè)置為1,和34行類似。


【C代碼47行】

這里將進(jìn)入延時(shí)函數(shù)。


進(jìn)入延時(shí)函數(shù):


NOP是字節(jié)對(duì)齊,減少指令的內(nèi)存訪問次數(shù)。首先將變量d保存到r0,然后將r0賦給r1,接著是r0自減1,緊接著是r1與0比較,如果r1等于0,則會(huì)返回,否則,又從頭開始,值得注意的是,這里先比較,然后r0才自減的。

為了進(jìn)一步說明,可以看--d的匯編代碼。


這里就是相當(dāng)于r1先減1,然后再比較的。

【C代碼50行】

這行代碼對(duì)應(yīng)一下指令,很簡(jiǎn)單。

5 總結(jié)

在前面使用Keil進(jìn)行了反匯編,也對(duì)相應(yīng)的C代碼進(jìn)行了分析。我們看到的反匯編代碼如下:


根據(jù)反匯編的代碼,可將其對(duì)應(yīng)到Flash,在Flash上的內(nèi)容如下表所示:

地址Flash****內(nèi)容
0x0800000000000000
0x0800000408000009
0x08000008f8dfd004
0x0800000cf000f80c

最后總結(jié)下點(diǎn)燈的流程:

第一步:設(shè)置棧CPU會(huì)從0x08000000讀取值,用來設(shè)置SP。

第二步:跳轉(zhuǎn):CPU從0x08000004得到地址值,根據(jù)它的BIT0切換為ARM狀態(tài)或Thumb狀態(tài),然后跳轉(zhuǎn)。

__第三步:__對(duì)于cortex M3/M4,它只支持Thumb狀態(tài),所以0x08000004上的值bit0必定是1,0x08000004上的值 = Reset_Handler + 1。從Reset_Handler繼續(xù)執(zhí)行。

第四步:然后進(jìn)入到主函數(shù)中執(zhí)行相應(yīng)C代碼。


原文地址:http://www.www27dydycom.cn/d/2071474.html




版權(quán)說明:

本內(nèi)容為作者發(fā)布至電子發(fā)燒友平臺(tái)原創(chuàng)文章,相關(guān)創(chuàng)作版權(quán)歸原作者所有,如未經(jīng)作者授權(quán),禁止轉(zhuǎn)載!




聲明本文由電子發(fā)燒友社區(qū)發(fā)布,轉(zhuǎn)載請(qǐng)注明以上來源。如需社區(qū)合作及入群交流,請(qǐng)?zhí)砑游⑿臙EFans0806,或者發(fā)郵箱liuyong@huaqiu.com。


更多熱點(diǎn)文章閱讀

  • 電子工程師分享:常用電平轉(zhuǎn)換電路、電源自動(dòng)切換電路、太陽能充電電路總結(jié)

  • 基于32位RISC-V設(shè)計(jì)的互聯(lián)型微控制器,沁恒微CH32V307開發(fā)樣例

  • RK3568!四核64位ARMv8.2A架構(gòu),匯聚編譯源碼及實(shí)戰(zhàn)樣例

  • 尺寸僅有21mm*51mm,板邊采用郵票孔設(shè)計(jì),合宙 Air105 核心板開發(fā)總結(jié)

  • 基于ESP32芯片,搭載OpenHarmony操作系統(tǒng),NiobeU4開發(fā)板應(yīng)用實(shí)例


原文標(biāo)題:【專欄精選】Cortex-M 的反編譯入門

文章出處:【微信公眾號(hào):電子發(fā)燒友論壇】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴

原文標(biāo)題:【專欄精選】Cortex-M 的反編譯入門

文章出處:【微信號(hào):gh_9b9470648b3c,微信公眾號(hào):電子發(fā)燒友論壇】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    嵌入式開發(fā)入門指南:從零開始學(xué)習(xí)嵌入式

    (設(shè)備驅(qū)動(dòng)、內(nèi)核編譯) 4. 推薦的學(xué)習(xí)資源書籍:《嵌入式系統(tǒng)軟件設(shè)計(jì)基礎(chǔ)》《ARM Cortex-M系列嵌入式開發(fā)》在線課程:慕課網(wǎng)、B站嵌入式教學(xué)視頻實(shí)踐平臺(tái):Arduino、STM32開發(fā)板
    發(fā)表于 05-15 09:29

    瑞薩RA8快速上手指南:Cortex-M85內(nèi)核瑞薩RA8開發(fā)環(huán)境搭建 并點(diǎn)亮一個(gè)LED

    因?yàn)?b class='flag-5'>Cortex-M內(nèi)核,瑞薩RA8系列單片機(jī)支持多種市面上常見的開發(fā)環(huán)境,像Keil MDK、IAR EWARM等,而本文講述的是瑞薩自家官方的IDE(e2 studio)。
    的頭像 發(fā)表于 03-17 14:35 ?1024次閱讀
    瑞薩RA8快速上手指南:<b class='flag-5'>Cortex-M</b>85內(nèi)核瑞薩RA8開發(fā)環(huán)境搭建 并點(diǎn)亮一個(gè)LED

    【瑞薩RA2L1入門學(xué)習(xí)】+Uart printf

    ? Cortex?-M23 核心(現(xiàn)今 Arm? Cortex-M 系列中功耗最低的 CPU)。 這款產(chǎn)品采用優(yōu)化的制程和瑞薩電子的低功耗工藝技術(shù),是業(yè)界一流水平的超低功耗微控制器。 RA2L1 產(chǎn)品
    發(fā)表于 03-09 17:33

    【瑞薩RA2L1入門學(xué)習(xí)】+Key control LED

    ? Cortex?-M23 核心(現(xiàn)今 Arm? Cortex-M 系列中功耗最低的 CPU)。 這款產(chǎn)品采用優(yōu)化的制程和瑞薩電子的低功耗工藝技術(shù),是業(yè)界一流水平的超低功耗微控制器。 RA2L1 產(chǎn)品
    發(fā)表于 03-09 17:21

    【瑞薩RA2L1入門學(xué)習(xí)】+Led flash

    ? Cortex?-M23 核心(現(xiàn)今 Arm? Cortex-M 系列中功耗最低的 CPU)。 這款產(chǎn)品采用優(yōu)化的制程和瑞薩電子的低功耗工藝技術(shù),是業(yè)界一流水平的超低功耗微控制器。 RA2L1 產(chǎn)品
    發(fā)表于 03-09 17:12

    【瑞薩RA2L1入門學(xué)習(xí)】00. 開箱 + 點(diǎn)燈

    架構(gòu)的核心板,目前 Arm? Cortex-M 系列中功耗最低的 CPU。 板載USB轉(zhuǎn)TTL模塊,帶有2個(gè)LED,1個(gè)復(fù)位按鍵,1個(gè)自定義按鍵以及兩個(gè)觸摸按鍵。其實(shí)硬件資源挺豐富的,這里只介紹
    發(fā)表于 03-07 11:07

    Arm Cortex-A320 CPU助力嵌入式設(shè)備實(shí)現(xiàn)高能效AI計(jì)算

    ,要確定適合特定 AI 應(yīng)用的處理器,系統(tǒng)開發(fā)者需要通過比較基于 Arm Cortex-A、Arm Cortex-M 和 Arm Ethos-U NPU 的設(shè)備及其可能的搭配進(jìn)行決策。除了成本的考量,開發(fā)者還需了解各款處理器具備的 AI 功能,以及自身的項(xiàng)目可以通過何種軟
    的頭像 發(fā)表于 02-27 17:17 ?761次閱讀
    Arm <b class='flag-5'>Cortex</b>-A320 CPU助力嵌入式設(shè)備實(shí)現(xiàn)高能效AI計(jì)算

    Cortex-M3/M4F指令集技術(shù)用戶手冊(cè)

    電子發(fā)燒友網(wǎng)站提供《Cortex-M3/M4F指令集技術(shù)用戶手冊(cè).pdf》資料免費(fèi)下載
    發(fā)表于 12-23 16:31 ?8次下載
    <b class='flag-5'>Cortex-M</b>3/<b class='flag-5'>M</b>4F指令集技術(shù)用戶手冊(cè)

    如何使用Ozone分析Cortex-M異常

    Ozone可以幫助用戶快速分析和查找導(dǎo)致CPU故障的軟件bug。本文解釋如何使用Ozone的調(diào)試功能,深入了解Cortex-M架構(gòu)上的這些錯(cuò)誤。
    的頭像 發(fā)表于 11-29 11:14 ?1695次閱讀
    如何使用Ozone分析<b class='flag-5'>Cortex-M</b>異常

    TVP51471M1 VBI快速入門

    電子發(fā)燒友網(wǎng)站提供《TVP51471M1 VBI快速入門.pdf》資料免費(fèi)下載
    發(fā)表于 09-30 11:52 ?0次下載
    TVP51471<b class='flag-5'>M</b>1 VBI快速<b class='flag-5'>入門</b>

    TVP5146M2 VBI快速入門

    電子發(fā)燒友網(wǎng)站提供《TVP5146M2 VBI快速入門.pdf》資料免費(fèi)下載
    發(fā)表于 09-30 11:10 ?0次下載
    TVP5146<b class='flag-5'>M</b>2 VBI快速<b class='flag-5'>入門</b>

    java反編譯能拿到源碼嗎

    Java反編譯是一種將編譯后的Java字節(jié)碼(.class文件)轉(zhuǎn)換回Java源代碼的過程。雖然反編譯可以幫助理解代碼的邏輯和結(jié)構(gòu),但它并不總是能完美地還原原始源代碼。反編譯工具通常會(huì)
    的頭像 發(fā)表于 09-02 11:03 ?1804次閱讀

    java反編譯的代碼可以修改么

    Java反編譯是一種將編譯后的Java字節(jié)碼(.class文件)轉(zhuǎn)換回源代碼的過程。反編譯后的代碼可以進(jìn)行修改,但是需要注意,反編譯代碼的質(zhì)量和可讀性可能會(huì)受到原始
    的頭像 發(fā)表于 09-02 11:00 ?1279次閱讀

    ida反編譯出來代碼能直接用嗎

    IDA反編譯出來的代碼通常 不能直接使用 ,這主要基于以下幾個(gè)方面的原因: 一、代碼的不完整性 IDA反編譯生成的代碼可能缺少原始源代碼中的某些關(guān)鍵信息。在編譯過程中,編譯器會(huì)優(yōu)化代碼
    的頭像 發(fā)表于 09-02 10:55 ?1448次閱讀

    單片機(jī)hex文件反編譯成C語言的過程

    使用C語言編寫,然后編譯成機(jī)器碼并燒錄到單片機(jī)的存儲(chǔ)器中。 Hex文件是一種用于存儲(chǔ)單片機(jī)程序的文件格式,它包含了程序的機(jī)器碼和一些附加信息,如起始地址、結(jié)束地址等。Hex文件通常用于燒錄單片機(jī)程序,也可以用于程序的傳輸和存儲(chǔ)。 Hex文件反編譯的基本概念 Hex文
    的頭像 發(fā)表于 09-02 10:49 ?6132次閱讀