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

       IMPORTdoadd                                 ; 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

 

             EXPORTdoadd

 

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

                                       

       IMPORTdoadd                                 ; 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时有什么原则?


版权声明:本文为yanhc519原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。