在mini2440(3) 2440init.s代码关键字注解 中对2440init.s文件中的汇编语言伪指令等关键字做了简单的注释,也提出了一些问题,对汇编器对伪指令的处理也有了更深刻的理解:汇编语言程序中伪指令会对汇编器的行为产生影响
2440init.s文件中程序的执行流程:
1、程序入口
AREA Init,CODE,READONLY
ENTRY
;1)The code, which converts to Big-endian, should be in little endian code.
;2)The following little endian code will be compiled in Big-Endian mode.
; The code byte order should be changed as the memory bus width.
;3)The pseudo instruction,DCD can't be used here because the linker generates error.
ASSERT :DEF:ENDIAN_CHANGE
[ ENDIAN_CHANGE
ASSERT :DEF:ENTRY_BUS_WIDTH
[ ENTRY_BUS_WIDTH=32
b ChangeBigEndian ;DCD 0xea000007
]
[ ENTRY_BUS_WIDTH=16
andeq r14,r7,r0,lsl #20 ;DCD 0x0007ea00
]
[ ENTRY_BUS_WIDTH=8
streq r0,[r0,-r10,ror #1] ;DCD 0x070000ea
]
|
b ResetHandler
]
b HandlerUndef;handler for Undefined mode
b HandlerSWI;handler for SWI interrupt
b HandlerPabort;handler for PAbort
b HandlerDabort;handler for DAbort
b .;reserved
b HandlerIRQ;handler for IRQ interrupt
b HandlerFIQ;handler for FIQ interrupt
;@0x20
b EnterPWDN; Must be @0x20.
系统上电或者复位之后,从这个程序入口开始执行:
不考虑条件汇编的情况下,执行的第一条指令是:bResetHandler
若考虑条件汇编的情况下,执行的指令则不同:
参考ADS 1.2的Assembler Guide(Page81/354),armasm的默认Endian是littleend,如果要编译成bigend,则需要为armasm指定参数为-bigend,默认情况是littleend,如果要编译为bigend,则ENDIAN_CHANGE定义为{TRUE},如果ENDIAN_CHANGE为{TRUE},则再判断变量ENTRY_BUS_WIDTH的值,如果是32位,则跳转到符号ChangeBigEndian处执行,如果是16位和8位,则再执行其它操作
问题:在option.inc中,定义:
GBLAENTRY_BUS_WIDTH
ENTRY_BUS_WIDTH SETA16
其中ENTRY_BUS_WIDTH的值定义为16位宽,为什么是16位,而不是32位呢?
2、ChangeBigEndian
ChangeBigEndian
;@0x24
[ ENTRY_BUS_WIDTH=32
DCD 0xee110f10 ;0xee110f10 => mrc p15,0,r0,c1,c0,0
DCD 0xe3800080 ;0xe3800080 => orr r0,r0,#0x80; //Big-endian
DCD 0xee010f10 ;0xee010f10 => mcr p15,0,r0,c1,c0,0
]
[ ENTRY_BUS_WIDTH=16
DCD 0x0f10ee11
DCD 0x0080e380
DCD 0x0f10ee01
]
[ ENTRY_BUS_WIDTH=8
DCD 0x100f11ee
DCD 0x800080e3
DCD 0x100f01ee
]
DCD 0xffffffff ;swinv 0xffffff is similar with NOP and run well in both endian mode.
DCD 0xffffffff
DCD 0xffffffff
DCD 0xffffffff
DCD 0xffffffff
b ResetHandler
在
[ ENTRY_BUS_WIDTH=32
DCD0xee110f10;0xee110f10 => mrc p15,0,r0,c1,c0,0
DCD0xe3800080;0xe3800080 => orr r0,r0,#0x80; //Big-endian
DCD0xee010f10;0xee010f10 => mcr p15,0,r0,c1,c0,0
]
中,直接在内存空间中存放指令的二进制补码形式
mrc p15,0,r0,c1,c0,0:mrc指令:Move to ARM register from coprocessor
p15是协处理器的名称,0是特定协处理器的操作码,r0是ARM的目的处理器,c1、c0是协处理器的寄存器,0是可选的特定协处理器的操作码
mcr p15,0,r0,c1,c0,0