那曲檬骨新材料有限公司

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

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

3天內不再提示

深度剖析ARM內核寄存器及基本匯編語言3

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

三、代碼反匯編簡析

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

3.1 不同編譯器的反匯編

3.1.1 Keil下面生成反匯編文件

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

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

簡單分析如下(立即數就不分析了= =!):圖片

3.1.2 gcc下生成反匯編文件

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

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

上述兩種方法的區別為:

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

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

  • arm-none-eabi-objdump -d -S(可省) a1.o 查看a1.o反匯編可執行段代碼
  • 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)的內核來說,使用如下方式生成反匯編文件:

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

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

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

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

3.2 C 和 匯編 比較分析

前面介紹了那么多,最終用一個簡單的程序對比一下C語言反匯編后的匯編語言,加深一下印象,當作個實戰總結。

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

//前面省略...
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);
  }
 }

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

;省略前面
    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后面 立即數的疑問

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

3.2.2 反匯編文件解析

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

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

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

對于的add函數匯編代碼如下:

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 寄存器中的值)

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

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

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • ARM
    ARM
    +關注

    關注

    134

    文章

    9169

    瀏覽量

    369239
  • 寄存器
    +關注

    關注

    31

    文章

    5363

    瀏覽量

    121194
  • PC
    PC
    +關注

    關注

    9

    文章

    2104

    瀏覽量

    154679
  • 匯編語言
    +關注

    關注

    14

    文章

    410

    瀏覽量

    35962
收藏 人收藏

    評論

    相關推薦

    匯編語言長什么樣子的呢

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

    如何用C語言寄存器匯編語言去實現流水燈

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

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

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

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

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

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

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

    匯編語言

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

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

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

    匯編語言學習

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

    [從零學習匯編語言] -寄存器詳解

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

    [從零學習匯編語言] - 寄存器與內存訪問

    [從零學習匯編語言] - 寄存器與內存訪問
    發表于 11-26 20:51 ?13次下載
    [從零學習<b class='flag-5'>匯編語言</b>] - <b class='flag-5'>寄存器</b>與內存訪問

    ARM匯編語言官方手冊

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

    深度剖析ARM內核寄存器及基本匯編語言1

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

    深度剖析ARM內核寄存器及基本匯編語言2

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

    單片機匯編語言的結構/數據類型/匯編指令

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

    ARM匯編語言工具

    電子發燒友網站提供《ARM匯編語言工具.pdf》資料免費下載
    發表于 11-06 09:12 ?0次下載
    <b class='flag-5'>ARM</b><b class='flag-5'>匯編語言</b>工具
    威尼斯人娱乐城投注网| 百家乐官网是骗人吗| 太阳神百家乐的玩法技巧和规则 | 百家乐官网试玩活动| 大发888好不好| 百家乐网上漏洞| 澳门百家乐真人娱乐城| 百家乐官网追号软件| 玩百家乐官网技巧看路| 邓州市| 石泉县| 百家乐官网路子分析| 大发888娱乐场下载 17| 威尼斯人娱乐城会员注册| 潘多拉百家乐的玩法技巧和规则| 百家乐的战术| 捷豹百家乐的玩法技巧和规则| 百家乐破解秘籍| 葡京百家乐的玩法技巧和规则| 百家乐园选百利宫| 华侨人百家乐的玩法技巧和规则 | 大发888 ipad版| 在线水果机游戏| 大发888体育开户| bet365娱乐平台| 优博最新网址| 茂名市| 澳门百家乐官网登陆网址 | 投真钱百家乐官网必输吗| 棋牌百家乐官网程序破解| 百家乐官网在线娱乐可信吗| 可信百家乐官网的玩法技巧和规则 | 百家乐游戏机| 精英百家乐官网现金网| 百家乐官网园zyylc| 百家乐官网真人娱乐平台| 免费百家乐官网统计| 百家乐破解的方法| 鼎盛娱乐城开户| bet365体育在线15| 杭州百家乐官网西园|