色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

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反編譯入門

嵌入式大雜燴 ? 來(lái)源:嵌入式大雜燴 ? 作者:嵌入式大雜燴 ? 2023-05-01 01:22 ? 次閱讀

我們?cè)趯?a target="_blank">單片機(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)看筆者以前的文章。

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

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

關(guān)于STM32裸機(jī)程序的創(chuàng)建,請(qǐng)看筆者博文:

https://bruceou.blog.csdn.net/article/details/78244735

但是今天這個(gè)程序非常簡(jiǎn)單,不應(yīng)那么復(fù)雜。

1.新建文件夾

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

1682861784044ce1xngvdb1

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

1682861784745y77tys7nql

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

2.新建工程

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

1682861785045yci29v8yep

輸入工程名,保存即可。

1682861785347ejt3txvtdg

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

1682861785701fybynmt941

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

16828617860678xirkyf7u2

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

168286178659146c097dxaa

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

1682861786890i3ruwx50xk

其中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

接下來(lái)還有配置工程。

16828617871720kp1099zbj

選擇Output文件夾。

1682861787441yb2iav40ku

選擇Listing文件夾。

168286178774709w1fbwxlj

基本配置就這些,接下來(lái)編譯工程。

1682861788115kc6kgvwaat

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

1682861788425ht484axtbw

LED會(huì)不停閃爍。

2 Keil反匯編

接下來(lái)才是今天正題,反匯編。

在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。

如下圖所示:

1682861788915ugsuzllsu3

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

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

1682861789194tjjboqezsx

3 反匯編代碼解析

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

C:\\Users\\BruceOu\\Desktop\\20210628222656.png

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

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

1682861789789h0yw0lt7wp

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

1682861790181wc7gex8qa6

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

16828617907087x3urvsswf

其中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指令集)。

1682861791012zlh0i8hbkk

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

1682861791382rgl1c89djy

后面16bit除了23位意外,全是固定的,其中‘U’表示無(wú)條件執(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

ARM?v7-M Architecture Reference Manual.pdf

4 反匯編代碼全解析

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

1682861791732udl87y2hkk

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

1682861792161laj05ypw17

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

1682861792494kvv8rmggr9

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

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

1682861792854yx7buaxbnh

168286179328181dgh7q884

【C代碼33行】

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

r3 = * 0x0800 017c

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

1682861793680n54j8yfcae

【C代碼34行】

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

168286179399049x6zh3xs2

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

ORR r0,r0,#8

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

【C代碼37行】

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

1682861794278a3l8unid93

【C代碼38行】

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

1682861794643xsiexuccee

【C代碼40行】

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

1682861794920c8o1lnkcmn

筆者認(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)化了。

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

1682861795209ylxlhden5n

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

【C代碼45行】

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

1682861795497jylbjwsdjc

【C代碼47行】

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

1682861795758qdjan7453d

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

1682861796046vsclfk8ad3

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

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

1682861796329nl965tt4jm

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

【C代碼50行】

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

1682861796601o6xh8txu3q

5 總結(jié)

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

C:\\Users\\BruceOu\\Desktop\\20210630233351.png

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

地址 Flash****內(nèi)容
0x08000000 00000000
0x08000004 08000009
0x08000008 f8dfd004
0x0800000c f000f80c

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

第一步:設(shè)置棧CPU會(huì)從0x08000000讀取值,用來(lái)設(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代碼。

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

    關(guān)注

    6035

    文章

    44554

    瀏覽量

    634634
  • 匯編
    +關(guān)注

    關(guān)注

    2

    文章

    214

    瀏覽量

    25927
  • 編譯
    +關(guān)注

    關(guān)注

    0

    文章

    657

    瀏覽量

    32852
  • 反編譯
    +關(guān)注

    關(guān)注

    1

    文章

    14

    瀏覽量

    8518
  • Cortex-M
    +關(guān)注

    關(guān)注

    2

    文章

    229

    瀏覽量

    29752
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    為什么說(shuō)Cortex-M是低功耗應(yīng)用的首選

    雖然Cortex-M處理器家族目標(biāo)瞄準(zhǔn)效能光譜較低端的區(qū)域,但是和大多數(shù)微控制器(MCU)采用的其他典型處理器相比,Cortex-M的效能依然算相當(dāng)強(qiáng)悍。舉例來(lái)說(shuō),像是許多高效能微控制器所采用的Cortex-M4與
    發(fā)表于 07-28 09:44 ?3481次閱讀
    為什么說(shuō)<b class='flag-5'>Cortex-M</b>是低功耗應(yīng)用的首選

    Cortex-M入門資料和書籍分享

    Cortex-M入門在網(wǎng)上看博客逛論壇也是能學(xué)到些東西的,但通常是知識(shí)點(diǎn),不能構(gòu)成知識(shí)面。書籍通常會(huì)系統(tǒng)性地講述,通過(guò)書籍可以建立起知識(shí)面,只有建立起了知識(shí)面才算是掌握。推薦兩本書:《ARM
    發(fā)表于 07-01 09:38

    Cortex-M內(nèi)核的GCC編譯

    下載ARM官方對(duì)應(yīng)Cortex-M內(nèi)核的GCC編譯
    發(fā)表于 08-24 06:44

    Android反編譯工具

    Android反編譯工具
    發(fā)表于 12-17 15:59 ?21次下載

    【ARM白皮書】ARM Cortex-M處理器入門

    ARM Cortex-M處理器家族現(xiàn)在有8款處理器成員。在本文中,會(huì)比較Cortex-M系列處理器之間的產(chǎn)品特性,重點(diǎn)講述如何根據(jù)產(chǎn)品應(yīng)用選擇正確的Cortex-M處理器。本文中會(huì)詳細(xì)的對(duì)照C
    發(fā)表于 04-20 15:34 ?39次下載

    Atmel Studio 6軟件中如何調(diào)試ARM Cortex-M

    Atmel Studio 6軟件中如何調(diào)試ARM Cortex-M
    的頭像 發(fā)表于 07-04 10:49 ?4239次閱讀

    關(guān)于STM32和Cortex-M內(nèi)核系列介紹(1)

    Cortex-M內(nèi)核系列和STM32-講座
    的頭像 發(fā)表于 07-05 01:07 ?8044次閱讀

    關(guān)于STM32與Cortex-M內(nèi)核系列的介紹(2)

    Cortex-M內(nèi)核系列和STM32-講座3
    的頭像 發(fā)表于 07-05 00:45 ?4524次閱讀

    關(guān)于Cortex-M 調(diào)試應(yīng)用的介紹

    Cortex-M 調(diào)試應(yīng)用
    的頭像 發(fā)表于 07-10 00:56 ?2618次閱讀

    米爾科技Cortex-M Prototyping System +介紹

    ARM? Cortex?-M原型系統(tǒng) MPS2+,為Cortex-M 系列微處理器設(shè)計(jì)的原型驗(yàn)證評(píng)估系統(tǒng),包含最新的Cortex-M7 及Corte
    的頭像 發(fā)表于 11-14 10:45 ?1938次閱讀
    米爾科技<b class='flag-5'>Cortex-M</b> Prototyping System +介紹

    Cortex-M內(nèi)核的MPU內(nèi)存保護(hù)單元

    講講Cortex-M內(nèi)核的MPU內(nèi)存保護(hù)單元
    的頭像 發(fā)表于 03-04 11:17 ?3673次閱讀
    <b class='flag-5'>Cortex-M</b>內(nèi)核的MPU內(nèi)存保護(hù)單元

    Cortex-M可以跑Linux操作系統(tǒng)嗎?

    Cortex-M可以跑Linux操作系統(tǒng)嗎?
    發(fā)表于 12-01 11:36 ?2次下載
    <b class='flag-5'>Cortex-M</b>可以跑Linux操作系統(tǒng)嗎?

    no cortex-m sw device found 問(wèn)題解決【轉(zhuǎn)】

    no cortex-m sw device found 問(wèn)題解決【轉(zhuǎn)】
    發(fā)表于 12-02 17:36 ?33次下載
    no <b class='flag-5'>cortex-m</b> sw device found 問(wèn)題解決【轉(zhuǎn)】

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

    做電子發(fā)燒友技術(shù)探索官,分享你的原創(chuàng)電子行業(yè)文章! 本期為大家推薦一篇嵌入式相關(guān)技術(shù)文章,作者主要從事嵌入式領(lǐng)域的開發(fā),感興趣的小伙伴可以關(guān)注學(xué)習(xí)哦~ 本期推 薦 專欄作者 : 嵌入式大雜燴 (點(diǎn)擊查看作者主頁(yè)) 介紹:該專欄主要介紹嵌入式開發(fā)相關(guān)的知識(shí),與大家一起交流學(xué)習(xí)。 ?? 我們?cè)趯?單片機(jī) 裸機(jī)程序時(shí),在主函數(shù)之前,會(huì)有一段啟動(dòng)代碼,而啟動(dòng)代碼是用 匯編 寫的,有些朋友可能看到匯編頭都大了,當(dāng)時(shí)要想深入研究底層
    的頭像 發(fā)表于 05-16 09:35 ?1461次閱讀

    Cortex-M位帶操作的原理

    Cortex-M位帶操作的原理
    的頭像 發(fā)表于 10-24 15:27 ?881次閱讀
    <b class='flag-5'>Cortex-M</b>位帶操作的原理
    主站蜘蛛池模板: 依人在线观看| 寂寞骚妇女被后入式抽插| 欧美日韩一区不卡在线观看| 中文无码字慕在线观看| 好大太快了快插穿子宫了| 天美传媒果冻传媒入口视频| 波多野结衣的AV一区二区三区| 免费撕开胸罩吮胸视频| 中文字幕视频免费在线观看| 九九久久久| 亚洲一卡久久4卡5卡6卡7卡 | 美女露出乳胸扒开尿口| 一边喂奶一边做边爱| 娇妻中日久久持久久| 亚洲精品无码AAAAAA片| 国产在线精彩亚洲久久| 亚洲第一区欧美日韩精品| 国产免费啪嗒啪嗒视频看看| 午夜久久影院| 国产精品在线手机视频| 午夜影院视费x看| 国产精品在线手机视频| 迅雷哥在线观看高清| 国产欧美一区二区精品性色tv| 午夜理论片日本中文在线| 国产免费麻传媒精品国产AV| 亚洲 色 欧美 爱 视频 日韩| 国产人妻人伦精品836700| 亚洲AV久久无码高潮喷水| 国内精品免费久久影院| 亚洲区视频在线观看| 久久99国产亚洲高清观着| 真实的强视频免费网站| 美女大本营| WRITEAS检查身体| 泡妞高手在都市完整版视频免费| xxxxhdvideos动漫| 色尼玛亚洲综合| 国产午夜免费视频片夜色| 亚洲第一伊人| 久久sese|