arm的bin二进制代码分析

bin文件中,就是一条条的机器指令,每条指令4个字节。

ADS中打开一个.s文件,选择project->disassemble

可以看到汇编的机器码

汇编代码如下(ADS中的一个例程/ARM/ADSv1_2/Examples/asm/armex.s):

        AREA ARMex, CODE, READONLY  ; name this block of code

        ENTRY                       ; mark first instruction

                                    ; to execute

start

        MOV     r0, #10             ; Set up parameters

        MOV     r1, #3

        ADD     r0, r0, r1          ; r0 = r0 + r1

 

stop

        MOV     r0, #0x18           ; angel_SWIreason_ReportException

        LDR     r1, =0x20026        ; ADP_Stopped_ApplicationExit

        SWI     0x123456            ; ARM semihosting SWI

 

        END                         ; Mark end of file

 

执行project->disassemble后:

** Section #1 'ARMex' (SHT_PROGBITS) [SHF_ALLOC + SHF_EXECINSTR + SHF_ENTRYSECT]

    Size   : 28 bytes (alignment 4)

 

    start

    $a

    ARMex

        0x00000000:    e3a0000a    ....    MOV      r0,#0xa

        0x00000004:    e3a01003    ....    MOV      r1,#3

        0x00000008:    e0800001    ....    ADD      r0,r0,r1

    stop

        0x0000000c:    e3a00018    ....    MOV      r0,#0x18

        0x00000010:    e59f1000    ....    LDR      r1,0x18

        0x00000014:    ef123456    V4..    SWI      0x123456

    $d

        0x00000018:    00020026    &...    DCD    131110

使用UltraEditbin文件如下:

 

可以看到,与上面的一样。

其中MOV的机器码如下(ARM体系结构pdfp156):

 

condAL(Always)0b1110

最后有一个131110不知道是什么意思。

 

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

另一个汇编代码如下(ADS中的一个例程/ARM/ADSv1_2/Examples/asm/ subrout.s):

        AREA subrout, CODE, READONLY    ; name this block of code

        ENTRY                           ; mark first instruction

                                        ; to execute

start

        MOV     r0, #10                 ; Set up parameters

        MOV     r1, #3

        BL      doadd                   ; Call subroutine

 

stop   

        MOV     r0, #0x18               ; angel_SWIreason_ReportException

        LDR     r1, =0x20026            ; ADP_Stopped_ApplicationExit

        SWI     0x123456                ; ARM semihosting SWI

 

doadd  

        ADD     r0, r0, r1              ; Subroutine code

        MOV     pc, lr                  ; Return from subroutine.

 

        END                             ; Mark end of file

 

执行project->disassemble后:

** Section #1 'subrout' (SHT_PROGBITS) [SHF_ALLOC + SHF_EXECINSTR + SHF_ENTRYSECT]

    Size   : 36 bytes (alignment 4)

 

    start

    $a

    subrout

        0x00000000:    e3a0000a    ....    MOV      r0,#0xa

        0x00000004:    e3a01003    ....    MOV      r1,#3

        0x00000008:    ebfffffe    ....    BL       doadd  ; 0x18

    stop

        0x0000000c:    e3a00018    ....    MOV      r0,#0x18

        0x00000010:    e59f1008    ....    LDR      r1,0x20

        0x00000014:    ef123456    V4..    SWI      0x123456

    doadd

        0x00000018:    e0800001    ....    ADD      r0,r0,r1

        0x0000001c:    e1a0f00e    ....    MOV      pc,r14

    $d

        0x00000020:    00020026    &...    DCD    131110

  

使用UltraEditbin文件如下:

 

 

不知道为什么,ADS里面的BL       doadd的机器码和bin中的机器码不一样。

 

BL的机器指令如下:

        0x00000008:    ebfffffe    ....    BL       doadd  ; 0x18

 

 

bin中的机器码,EB0000021110_1101_0000_0000____0000_0000_0000_0010

会在执行bl指令时的PC后面加上2*4byte,正好跳过3条指令。

 

 

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

下面这个将doadd写到另一个.s文件中。

 

subrout.s文件:

        AREA subrout, CODE, READONLY    ; name this block of code

        ENTRY                           ; mark first instruction

                                        ; to execute

        IMPORT doadd                                  ; import

start

        MOV     r0, #10                 ; Set up parameters

        MOV     r1, #3

        BL      doadd                   ; Call subroutine

stop   

        MOV     r0, #0x18               ; angel_SWIreason_ReportException

        LDR     r1, =0x20026            ; ADP_Stopped_ApplicationExit

        SWI     0x123456                ; ARM semihosting SWI

 

        END                             ; Mark end of file

 

fun.s文件:

              AREA subrout, CODE, READONLY    ; name this block of code

 

              EXPORT doadd

 

doadd   FUNCTION

 

        ADD     r0, r0, r1              ; Subroutine code

       

        MOV     pc, lr                  ; Return from subroutine.

               

        ENDFUNC

 

        LTORG

       

        END

 

UE查看bin结果:

可以看出,跳转指令变为跳转3个指令,doadd函数放在了bin的最后。

 

 

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

将上面的subrout.s文件改为:

        AREA subrout, CODE, READONLY    ; name this block of code

        ENTRY                           ; mark first instruction

                                        ; to execute

                                       

        IMPORT doadd                                  ; import

start

        LDR     r0, Param1              ; Set up parameters

        LDR     r1, Param2

        BL      doadd                   ; Call subroutine

 

stop   

        MOV     r0, #0x18               ; angel_SWIreason_ReportException

        LDR     r1, =0x20026            ; ADP_Stopped_ApplicationExit

        SWI     0x123456                ; ARM semihosting SWI

 

Param1   DCD 10

Param2   DCD 3

 

        END                             ; Mark end of file

MOV只能操作reg和立即数

操作内存,MOV要改为LDR

 

UE查看bin为:

LDR     r0, Param1的机器码为:

E59F0010=0111_0101_1001_1111_0000_0000_0001_0000

RnR15=PCRd=R0address=16(4*Instruction)+PC

 

有时候ADS会把doadd函数的两条指令放到最开始,此时Image Entry Point变为0x8,不知道ADS在分配主程序和doadd时有什么原则?

原文地址:https://www.cnblogs.com/yanhc/p/2175245.html