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

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

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

深度剖析ARM內(nèi)核寄存器及基本匯編語言3

jf_78858299 ? 來源:矜辰所致 ? 作者:矜辰所致 ? 2023-04-24 10:01 ? 次閱讀

三、代碼反匯編簡析

  • 匯編 匯編文件轉(zhuǎn)換為目標文件(里面是機器碼,機器碼是給CPU使用的,燒錄保存在Flash空間的就是機器碼)。
  • 反匯編 可執(zhí)行文件(目標文件,里面是機器碼),轉(zhuǎn)換為匯編文件。

3.1 不同編譯器的反匯編

3.1.1 Keil下面生成反匯編文件

fromelftext -a -c –output=(改成你想生成的反匯編名字一般是工程名字).dis (需要的axf文件,根據(jù)你工程生成axf的路徑填寫).axf圖片設(shè)置好以后編譯之后就會生成反匯編.dis文件:圖片

打開如下所示:圖片對于上圖中的紅色圈出來的語句,我們可以根據(jù)本文 第 二 章節(jié)的第2小節(jié) ARM匯編格式中的介紹來分析一下:圖片

簡單分析如下(立即數(shù)就不分析了= =?。?img src="http://file1.elecfans.com/web2/M00/82/2B/wKgZomRF4HuAbEwuAAQjAZF3cTI607.jpg" alt="圖片" />

3.1.2 gcc下生成反匯編文件

在X86架構(gòu)下的電腦上生成ARM架構(gòu)的匯編代碼有兩種方式:

  • 使用交叉編譯工具鏈 指定-S選項可以生成匯編中間文件。ex:gcc -S test.c
  • 使用 objdump 反匯編 arm二進制文件。

上述兩種方法的區(qū)別為:

(1)反匯編可以生成ARM指令操作碼,-S生成的匯編沒有指令碼 (2)反匯編的代碼是經(jīng)過編譯器優(yōu)化過的。(3)反匯編代碼量很大。

對于ARM Cortex-M,使用的是 arm-none-eabi-objdump,常用指令如下:

  • arm-none-eabi-objdump -d -S(可省) a1.o 查看a1.o反匯編可執(zhí)行段代碼
  • arm-none-eabi-objdump -D -S(可省) a1.o 查看a1.o反匯編所有段代碼
  • arm-none-eabi-objdump -D -b binary -m arm ab.bin 查看ab.bin反匯編所有代碼段

對于使用 arm-none-eabi-gcc 工具鏈(以STM32CUbeMX)的內(nèi)核來說,使用如下方式生成反匯編文件:

$(OBJDUMP) -D -b binary -m arm (需要的elf文件,一般是工程名字).elf > (改成你想生成的反匯編名字,一般是工程名字).dis # OBJDUMP = arm-none-eabi-objdump

-D表示對全部文件進行反匯編,-b表示二進制,-m表示指令集架構(gòu)

Makefile修改如下:

...
TARGET = D6TPir
#######################################
# paths
#######################################
# Build path
BUILD_DIR = build
...
PREFIX = arm-none-eabi-
...
OBJDUMP = $(PREFIX)objdump

dis:
 $(OBJDUMP) -D -b binary -m arm $(BUILD_DIR)/$(TARGET).elf > $(BUILD_DIR)/$(TARGET).dis
# $(OBJDUMP) -D -b binary -m arm $(BUILD_DIR)/$(TARGET).bin > $(BUILD_DIR)/$(TARGET).dis

執(zhí)行 make dis 即可生成 .dis 文件:圖片圖片打開文件查看,發(fā)現(xiàn)怎么這個匯編語言有點不一樣:圖片經(jīng)過研究了一段時間,加上了-M force-thumb后稍微有點樣子了:圖片! 在網(wǎng)上有各種參考,但是我都測試過了,并沒有找到合適的生成完全和標準匯編一致的那種,-M后面的參數(shù)也不能亂加,需要根據(jù)自己的交叉編譯器,因為這里用的是 arm-none-eabi-gcc,所以可以通過arm-none-eabi-objdump --help 查看能用的命令和參數(shù): gcc工具鏈下的匯編還是不太熟悉,所以我們下面反匯編文件與 C語言的對比,使用Keil下的反匯編進行說明。

3.2 C 和 匯編 比較分析

前面介紹了那么多,最終用一個簡單的程序?qū)Ρ纫幌翪語言反匯編后的匯編語言,加深一下印象,當作個實戰(zhàn)總結(jié)。

基于STM32L051(Cortex-M0)內(nèi)核,目的是為了比較C和匯編,用了個最簡單的程序來分析,沒有用到任務(wù)外設(shè),程序如下:

//前面省略...
void delay(u32 count)
{
 while(count--);
}

u32 add(u16 val1,u16 val2)
{
 u32 add_val;
 
 add_val = val1 + val2;
 
 return add_val;
}
 int main(void)
 {
 u16 a,b;
 u32 c;
 a = 12345;
 b = 45678;
 c = add(a,b);
 while(1)
 {
   c--;
   delay(200000);
  }
 }

反匯編的代碼對應(yīng)部分如下(因為基于硬件平臺,其他異常中斷,堆,棧,包括其他一些也有匯編代碼,這里省略):

;省略前面
    delay
        0x080001ae:    bf00        ..      NOP      
        0x080001b0:    1e01        ..      SUBS     r1,r0,#0
        0x080001b2:    f1a00001    ....    SUB      r0,r0,#1
        0x080001b6:    d1fb        ..      BNE      0x80001b0 ; delay + 2
        0x080001b8:    4770        pG      BX       lr
    add
        0x080001ba:    4602        .F      MOV      r2,r0
        0x080001bc:    1850        P.      ADDS     r0,r2,r1
        0x080001be:    4770        pG      BX       lr
    main
        0x080001c0:    f2430439    C.9.    MOV      r4,#0x3039
        0x080001c4:    f24b256e    K.n%    MOV      r5,#0xb26e
        0x080001c8:    4629        )F      MOV      r1,r5
        0x080001ca:    4620         F      MOV      r0,r4
        0x080001cc:    f7fffff5    ....    BL       add ; 0x80001ba
        0x080001d0:    4606        .F      MOV      r6,r0
        0x080001d2:    e003        ..      B        0x80001dc ; main + 28
        0x080001d4:    1e76        v.      SUBS     r6,r6,#1
        0x080001d6:    4804        .H      LDR      r0,[pc,#16] ; [0x80001e8] = 0x30d40
        0x080001d8:    f7ffffe9    ....    BL       delay ; 0x80001ae
        0x080001dc:    e7fa        ..      B        0x80001d4 ; main + 20
    $d
        0x080001de:    0000        ..      DCW    0
        0x080001e0:    e000ed0c    ....    DCD    3758157068
        0x080001e4:    05fa0000    ....    DCD    100270080
        0x080001e8:    00030d40    @...    DCD    200000
;省略后面

3.2.1 MOV后面 立即數(shù)的疑問

在對比分析這段代碼前,在 main 函數(shù)中的第一句:

0x080001c0:    f2430439    C.9.    MOV      r4,#0x3039

就有一個大大的疑問, MOV r4,#0x3039中 0x3039 并不是立即數(shù)(按照我們第二章 立即數(shù)的說明) ,包括接下來的 0xb26e 也不是立即數(shù),怎么可以直接用 mov,按理來說需要用 LDR偽指令的??

至于這個問題,網(wǎng)上簡單查找了一下,找到一篇有關(guān)說明的文章:ARM 匯編的mov操作立即數(shù)的疑問 其中有說到,在 keil 公司方網(wǎng)站里關(guān)于arm匯編的說明里有這么一段:

Syntax MOV{cond} Rd, #imm16 where: imm16 is any value in the range 0-65535.

所以是不是在 Keil 中的arm匯編 立即數(shù)可以使16位的?

為了驗證一下,我稍微修改了一下程序,就是把a的值賦值超過16位(當然定義函數(shù)之類的也要跟著改,測試代碼中a為u16的無符號整形),測試了一下。

a賦值為 65535,結(jié)果如下(65535不是立即數(shù),也可以直接mov):

0x080001c0:    f64f75ff    O..u    MOV      r5,#0xffff

a賦值為 65536,結(jié)果如下(65536是立即數(shù),可以直接mov):

0x080001c0:    f44f3580    O..5    MOV      r5,#0x10000

a賦值為一個大于16位的,不是立即數(shù)的數(shù),比如:0x1FFFF :

0x080001c0:    4d08        .M      LDR      r5,[pc,#32] ; [0x80001e4] = 0x1ffff

果然,最后當 a 大于16位,不是立即數(shù)時候,會使用偽指令 LDR,所以我們可以得出結(jié)論:

在 Keil 中的arm匯編中,16位內(nèi)(包括16位)的數(shù)都直接使用 MOV 賦值,大于16位,如果是立即數(shù),直接使用MOV,不是立即數(shù)用LDR (立即數(shù)的判斷方式還是前面講的那樣)

3.2.2 反匯編文件解析

對于上面的示例程序的匯編碼,簡單解析如下:圖片添加一個有意思的測試對于delay函數(shù)中的語句,上圖是while(count--);改成while(--count);后匯編代碼如下:圖片

對于上面的測試程序,匯編中并沒有使用到 PUSH 和 POP 指令,因為程序太簡單了,不需要使用到棧,為了能夠熟悉下單片機中必須且經(jīng)常需要用到的 棧,我們稍微修改一下add函數(shù),在add函數(shù)中調(diào)用了delay函數(shù):

u32 add(u16 val1,u16 val2)
{
 u32 add_val;
 
 add_val = val1 + val2;
 
 delay(10);
 
 return add_val;
}

對于的add函數(shù)匯編代碼如下:

add
        0x080001ba:    b530        0.      PUSH     {r4,r5,lr}   ;把r4 r5 lr的值入棧
        0x080001bc:    4603        .F      MOV      r3,r0
        0x080001be:    460c        .F      MOV      r4,r1
        0x080001c0:    191d        ..      ADDS     r5,r3,r4
        0x080001c2:    200a        .       MOVS     r0,#0xa
        0x080001c4:    f7fffff3    ....    BL       delay ; 0x80001ae
        0x080001c8:    4628        (F      MOV      r0,r5
        0x080001ca:    bd30        0.      POP      {r4,r5,pc}  ;把r4 r5 lr的值出棧,

(匯編中可以看到指令后面后面加了個S ,MOVS 、ADDS,這就是我們前面說到的,帶了S 會影響 xPSR 寄存器中的值)

可以看到,因為存在函數(shù)的多次調(diào)用,main函數(shù)中調(diào)用add函數(shù),add函數(shù)中調(diào)用delay函數(shù),所以在add函數(shù)運行之前,通過 push 把 r4,r5,lr 寄存器的值先存入棧中,等待程序執(zhí)行完(函數(shù)調(diào)用結(jié)束)再吧 r4,r5,lr 寄存器的值恢復(fù)。

上面的程序雖然簡單,但是通過我們C程序 與 匯編程序的對比分析,能夠讓我們更加深入的理解匯編語言。

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

    關(guān)注

    134

    文章

    9098

    瀏覽量

    367707
  • 寄存器
    +關(guān)注

    關(guān)注

    31

    文章

    5343

    瀏覽量

    120437
  • PC
    PC
    +關(guān)注

    關(guān)注

    9

    文章

    2084

    瀏覽量

    154259
  • 匯編語言
    +關(guān)注

    關(guān)注

    14

    文章

    410

    瀏覽量

    35818
收藏 人收藏

    評論

    相關(guān)推薦

    匯編語言長什么樣子的呢

    文章目錄匯編語言長什么的樣子呢?ARM匯編指令條件和狀態(tài)Status碼ARM匯編尋址方式數(shù)據(jù)操作(ALU操作)邏輯操作(與,或,非,異或)比
    發(fā)表于 12-14 07:28

    如何用C語言寄存器匯編語言去實現(xiàn)流水燈

    目錄一、初始化1、地址映射和寄存器映射2、接線3、程序下載二、用C語言寄存器實現(xiàn)流水燈三、匯編語言實現(xiàn)流水燈四、心得一、初始化1、地址映射和
    發(fā)表于 02-10 07:55

    ARM匯編語言與指令格式資料分享

    1、ARM匯編語言與指令格式介紹匯編語言介紹概念指的是用助記符代替操作碼,用地址符號或標簽(:#&)代替地址碼的編程語言。優(yōu)缺點優(yōu)點:可以直接訪問硬件目標,代碼簡短,執(zhí)行速度快
    發(fā)表于 04-22 16:10

    匯編語言教程-段寄存器的說明語句

    匯編語言教程-段寄存器的說明語句   在匯編語言源程序中可以定義多個段,每個段都要與一個段寄存器建立一種對應(yīng)關(guān)系。建立這
    發(fā)表于 03-27 17:17 ?1406次閱讀

    ARM匯編語言官方手冊(中文)

    ARM匯編語言官方手冊(中文)匯編語言ARM匯編語言官方手冊(中文)
    發(fā)表于 12-28 15:02 ?212次下載

    匯編語言

    匯編語言舉例,比如讀寄存器內(nèi)容的源代碼、匯編語言制作的光帶菜單及源程序、獲得操作系統(tǒng)版本的匯編源代碼等
    發(fā)表于 12-31 10:40 ?33次下載

    51單片機匯編語言教程_單片機的特殊功能寄存器

    51單片機匯編語言教程:7課單片機的特殊功能寄存器
    發(fā)表于 01-19 15:26 ?0次下載

    匯編語言學(xué)習(xí)

    寄存器 一個cpu有多個寄存器 就是cpu中可以存儲數(shù)據(jù)的器件,一個cpu中有多個寄存器匯編語言由一下3類組成 1、
    發(fā)表于 11-23 18:06 ?14次下載
    <b class='flag-5'>匯編語言</b>學(xué)習(xí)

    [從零學(xué)習(xí)匯編語言] -寄存器詳解

    文章目錄前言一、 存儲與通用寄存器1. 存儲2. 通用寄存器前言上一章我們曾簡單的介紹過計算機中的一些硬件和軟件的相關(guān)概念,還不熟悉的小伙伴可以點擊下面的鏈接進行預(yù)習(xí):[
    發(fā)表于 11-26 20:51 ?8次下載
    [從零學(xué)習(xí)<b class='flag-5'>匯編語言</b>] -<b class='flag-5'>寄存器</b>詳解

    [從零學(xué)習(xí)匯編語言] - 寄存器與內(nèi)存訪問

    [從零學(xué)習(xí)匯編語言] - 寄存器與內(nèi)存訪問
    發(fā)表于 11-26 20:51 ?13次下載
    [從零學(xué)習(xí)<b class='flag-5'>匯編語言</b>] - <b class='flag-5'>寄存器</b>與內(nèi)存訪問

    ARM匯編語言官方手冊

    ARM匯編語言官方手冊
    發(fā)表于 10-10 10:44 ?30次下載

    深度剖析ARM內(nèi)核寄存器及基本匯編語言1

    M3/M4內(nèi)核寄存器 * 1.2 A7內(nèi)核寄存器 * 1.3 ARM中的PC指針的
    的頭像 發(fā)表于 04-24 09:59 ?974次閱讀
    <b class='flag-5'>深度</b><b class='flag-5'>剖析</b><b class='flag-5'>ARM</b><b class='flag-5'>內(nèi)核</b><b class='flag-5'>寄存器</b>及基本<b class='flag-5'>匯編語言</b>1

    深度剖析ARM內(nèi)核寄存器及基本匯編語言2

    M3/M4內(nèi)核寄存器 * 1.2 A7內(nèi)核寄存器 * 1.3 ARM中的PC指針的
    的頭像 發(fā)表于 04-24 10:00 ?1099次閱讀
    <b class='flag-5'>深度</b><b class='flag-5'>剖析</b><b class='flag-5'>ARM</b><b class='flag-5'>內(nèi)核</b><b class='flag-5'>寄存器</b>及基本<b class='flag-5'>匯編語言</b>2

    單片機匯編語言的結(jié)構(gòu)/數(shù)據(jù)類型/匯編指令

    開發(fā)匯編語言是為了為機器級代碼指令提供助記符或符號,匯編語言程序由助記符組成,因此應(yīng)將它們翻譯成機器代碼。負責(zé)這種轉(zhuǎn)換的程序稱為匯編程序。匯編語言通常被稱為低級
    的頭像 發(fā)表于 07-07 12:28 ?3033次閱讀

    ARM匯編語言工具

    電子發(fā)燒友網(wǎng)站提供《ARM匯編語言工具.pdf》資料免費下載
    發(fā)表于 11-06 09:12 ?0次下載
    <b class='flag-5'>ARM</b><b class='flag-5'>匯編語言</b>工具