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
使用UltraEdit看bin文件如下:
可以看到,与上面的一样。
其中MOV的机器码如下(ARM体系结构pdf:p156):
cond,AL(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
使用UltraEdit看bin文件如下:
不知道为什么,ADS里面的BL doadd的机器码和bin中的机器码不一样。
BL的机器指令如下:
0x00000008: ebfffffe .... BL doadd ; 0x18
按bin中的机器码,EB000002,1110_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
Rn为R15=PC,Rd=R0,address=16(4*Instruction)+PC
有时候ADS会把doadd函数的两条指令放到最开始,此时Image Entry Point变为0x8,不知道ADS在分配主程序和doadd时有什么原则?