在bin文件中,就是一條條的機器指令,每條指令4個字節。
在ADS中打開一個.s文件,選擇project->disassemble
可以看到匯編的機器碼
匯編代碼如下(ADS中的一個例程ARMADSv1_2Examplesasmarmex.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中的一個例程ARMADSv1_2Examplesasm 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文件改為(工程subroutprj_2F_DCD):
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
輸出的Image Symbol Table為:
================================================================================
Image Symbol Table
Mapping Symbols
Sym Value Execution Region
$a 0x00000000 ER_RO
$d 0x00000020 ER_RO
其中$a表示ARM Code,$d表示Data
這是整個bin文件的區域分配,從0開始為ARM Code,然后從20開始為Data,其中ARM Code是fun section和subrout section合在一起的,Data也是兩個數據合在一起的(似乎是armlink把input section中同一屬性的段合并到output section中)。
ADS中輸出調試信息Image Map
Symbol
Section cross-reference
在list file中choose一個文件,比如boot270.txt,可以把信息輸出到txt中
下面這個輸出是subroutprj_2F_DCD的輸出,在arm反匯編.doc里。
================================================================================
Image Symbol Table
Mapping Symbols
Sym Value Execution Region
$a 0x00000000 ER_RO
$d 0x00000020 ER_RO
Local Symbols
Symbol Name Value Ov Type Size Object(Section)
E:dsparmpxa270projectsubroutprj_2F_DCDsubrout.s 0x00000000 Number 0 subrout.o ABSOLUTE
subrout 0x00000008 ARM Code 36 subrout.o(subrout) start 0x00000008 ARM Code 0 subrout.o(subrout) stop 0x00000014 ARM Code 0 subrout.o(subrout) Param1 0x00000020 Data 4 subrout.o(subrout) Param2 0x00000024 Data 4 subrout.o(subrout) E:dsparmpxa270projectsubroutprj_2F_DCDfun.s 0x00000000 Number 0 fun.o ABSOLUTE fun 0x00000000 ARM Code 8 fun.o(fun) Global Symbols Symbol Name Value Ov Type Size Object(Section) BuildAttributes$$ARM_ISAv4$M$PE$A:L22$X:L11$S22$~IW$~STKCKD$~SHL$OSPACE 0x00000000 Number 0 anon$$obj.o ABSOLUTE doadd 0x00000000 ARM Code 8 fun.o(fun) UE查看bin結果 從bin看到,doadd兩條指令放在了bin的最前面,這樣 start的值value為0x00000008 fun的值value為0x00000000 start和fun都是ARM Code,是代碼的標號label,標號的值代表一個地址,所以start和fun在bin中的地址即為它們的值。 Image Symbol Table中包含兩部分,Local Symbol和Global Symbol,前者在只能在定義的文件中引用,后者可以在整個工程中引用。在這個工程中后者只有doadd函數。 ======================================================================== Memory Map of the image Image Entry point : 0x00000000 Load Region LR_1 (Base: 0x00000000, Size: 0x0000002c, Max: 0xffffffff, ABSOLUTE) Execution Region ER_RO (Base: 0x00000000, Size: 0x0000002c, Max: 0xffffffff, ABSOLUTE) Base Addr Size Type Attr Idx E Section Name Object 0x00000000 0x00000008 Code RO 5 * fun fun.o 0x00000008 0x00000024 Code RO 1 * subrout subrout.o Execution Region ER_RW (Base: 0x0000002c, Size: 0x00000000, Max: 0xffffffff, ABSOLUTE) **** No section assigned to this execution region **** Execution Region ER_ZI (Base: 0x0000002c, Size: 0x00000000, Max: 0xffffffff, ABSOLUTE) **** No section assigned to this execution region **** Image Entry point : 0x00000000這句話有點問題??!! Base Addr Size Type Attr Idx E Section Name Object 0x00000000 0x00000008 Code RO 5 * fun fun.o 0x00000008 0x00000024 Code RO 1 * subrout subrout.o 上面這些說明了各段的基地址,長度,類型(code,data),屬性(RO,RW),段名,存在的目標文件。 在這里fun放在了subrout的前面,由于armlinker在鏈接input section的時候排序sort是有規則的,先同一屬性(RO,RW,RI),然后按名字的字母表順序。由于fun和subrout都是RO,所以按名字fun在前面。 ----------------------------------------------------------------- 下面以boot270工程為例子分析: 輸出的Image Symbol Table Global Symbols Symbol Name Value Ov Type Size Object(Section) xlli_read_SCR 0xa000cea0 ARM Code 420 xlli_LowLev_Init.o(text) 可以看出xlli_read_SCR為ARM Code,是一個標號label,值即為其在bin中的地址,由于設置RO Base為0xA0000000,所以在bin中找0x0000cea0處的指令: 指令為E59F_419C,即為 xlli_read_SCR FUNCTION ; ; Insure the RDH and PH bits on PXA27x must be clear to enable GPIO pins. ; They are sticky bits so they must be set to clear them. ; ldr r4, =xlli_PMRCREGS_PHYSICAL_BASE 該指令表示(E表示AL,無條件,F為R15=PC,4表示放到R4里,地址為PC+19C=D03C,再加2*4為D044) 0x0000d044處的數據為40F00000,與代碼中的數據吻合: ; POWER MANAGER base address and register offsets from the base address ; xlli_PMRCREGS_PHYSICAL_BASE EQU 0x40F00000 這個數據在Image Symbol Table中也能找到,在Local Symbols中: xlli_PMRCREGS_PHYSICAL_BASE 0x40f00000 Number 0 main_Flash.o ABSOLUTE 能看到是一個Number,值value為0x40f00000。 這個數據的地址在Image Symbol Table中也能看到: Mapping Symbols Sym Value Execution Region $d 0xa000d044 ER_RO $d表示數據data。 下一條指令: ; Get, and save the present GPIO settings for direction registers 0, 1 and 2 ; ldr r4, =xlli_GPIOREGS_PHYSICAL_BASE ; Get the GPIO registers base address 指令為:E5_9F_4_194 數據的地址為:PC+194+2*4=D048 數據為:40E0 0000,與代碼中的定義對應: ; GENERAL PURPOSE I/O (GPIO) base address and register offsets from the base address ; xlli_GPIOREGS_PHYSICAL_BASE EQU 0x40E00000 地址0x0000 D048在Image Symbol Table中沒有,不過有: Mapping Symbols Sym Value Execution Region $d 0xa000d044 ER_RO 說明從0xa000d044處開始為許多RO data 上面的工程只有RO,怎么才能產生RW,RI呢? MOV E3 LDR E5 ADD E0
上一篇:ARM中的程序狀態寄存器(CPSR)
下一篇:淺析arm的異常、中斷和arm工作模式的聯系
推薦閱讀
史海拾趣