mini 2440 init.s(二)

 

;这里引入一些在其它文件中实现在函数,包括为我们所熟知的main函数

       IMPORT  Main    ; The main entry of mon program

;从这里开始就是真正的代码入口了!

       AREA    Init,CODE,READONLY;这表明下面的是一个名为Init的代码段

 

       ENTRY                         ;定义程序的入口(调试用)

      

       EXPORT      __ENTRY                ;导出符号_ENTRY

__ENTRY

ResetEntry

       ;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 not be used here because the linker generates error.

***********************************************************

1、ASSERT :DEF:ENDIAN_CHANGE
ASSERT
是断言伪指令,语法是:ASSERT +逻辑表达式
def
是逻辑伪操作符,格式为: :DEF:label,作用是:判断label是否定义过
2
、四句蓝色的指令能且只能执行一句,并且前三句若执行跳转后处理程序的最后一句也是
b ResetHandler
3
" [ " 相当于 if
" | "
相当于else
" ] "
相当于endif

;***************************************************************

       ASSERT      :DEF:ENDIAN_CHANGE      ;判断是否定义了模式改变

       [ ENDIAN_CHANGE

           ASSERT  :DEF:ENTRY_BUS_WIDTH  ;判断是否定义了总线宽度

;条件分支语句1:如果存储器是32位的总线宽度

      [ ENTRY_BUS_WIDTH=32           

              b     ChangeBigEndian          ;DCD 0xea000007

           ]

;条件分支语句2:如果存储器是16位的总线宽度

      [ ENTRY_BUS_WIDTH=16             

              andeq    r14,r7,r0,lsl #20   ;DCD 0x0007ea00

           ]

;条件分支语句3:如果存储器是8位的总线宽度

           [ 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.

;===============================================================
;
下面是改变大小端的程序,这里采用直接定义机器码的方式,至说为什么这么做就得问三星了
;
反正我们程序里这段代码也不会去执行,不用去管它
;===============================================================

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

       ;如上所说,这里采用HANDLER宏去建立Hander***Handle***之间的联系

HandlerFIQ      HANDLER HandleFIQ

HandlerIRQ      HANDLER HandleIRQ

HandlerUndef    HANDLER HandleUndef

HandlerSWI      HANDLER HandleSWI

HandlerDabort   HANDLER HandleDabort

HandlerPabort   HANDLER HandlePabort

 ;=========================================================================
;呵呵,来了来了.好戏来了,这一段程序就是用来进行第二次查表的过程了.
;如果说第一次查表是由硬件来完成的,那这一次查表就是由软件来实现的了.
;为什么要查两次表??
;没有办法,ARM把所有的中断都归纳成一个IRQ中断异常和一个FIRQ中断异常
;第一次查表主要是查出是什么异常,可我们总要知道是这个中断异常中的什么中断呀!
;没办法了,再查一次表呗!
;========================================================================

IsrIRQ

       sub  sp,sp,#4       ; PC寄存器保留

       stmfd     sp!,{r8-r9}  ; r8-r9压入栈

 

       ldr   r9,=INTOFFSET   ; 把中断偏移INTOFFSET的地址装入r9

       ldr   r9,[r9]             ; 把中断偏移INTOFFSET的值装入r9

       ldr   r8,=HandleEINT0     ; 这就是向量表的入口HandleEINT0装入r8

 

;把中断服务程序装入

       add r8,r8,r9,lsl #2          ;为什么左移两位?不是很清楚

       ldr   r8,[r8]                  ; 装入中断服务程序的入口

       str   r8,[sp,#8]                ;把入口压入堆栈

       ldmfd    sp!,{r8-r9,pc}          ;出栈

 

 

       LTORG   ;声明文字池

 

你可能感兴趣的:(c,存储,import,三星,byte,linker)