1、=;GET类似于C语言的include,option.inc文件内定义了一些全局变量,memcfg.inc文件内定义了关于内存bank的符号和数字常量,2440addr.inc文件内定义了用于汇编的s3c2440寄存器变量和地址 GET option.inc GET memcfg.inc GET 2440addr.incSDRAM自刷新位,把寄存器REFRESH的第22位处置1BIT_SELFREFRESH EQU (122)CPSR中的低5位定义了处理器的七种工作模式,为以后切换模式时使用Pre-defined constantsUSERMODE EQU 0x10FIQMODE EQU 0x
2、11IRQMODE EQU 0x12SVCMODE EQU 0x13ABORTMODE EQU 0x17UNDEFMODE EQU 0x1bMODEMASK EQU 0x1fCPSR中的I位和F位置1,表示禁止任何中断NOINT EQU 0xc0定义了7种处理器模式下的栈的起始地址,其中用户模式和系统模式共有一个栈空间_STACK_BASEADDRESS在option.inc文件内定义,值为0x33ff8000The location of stacksUserStack EQU (_STACK_BASEADDRESS-0x3800) ;0x33ff4800 SVCStack EQU (_ST
3、ACK_BASEADDRESS-0x2800) ;0x33ff5800 UndefStack EQU (_STACK_BASEADDRESS-0x2400) ;0x33ff5c00 AbortStack EQU (_STACK_BASEADDRESS-0x2000) ;0x33ff6000 IRQStack EQU (_STACK_BASEADDRESS-0x1000) ;0x33ff7000 FIQStack EQU (_STACK_BASEADDRESS-0x0) ;0x33ff8000 ARM处理器的两种工作状态:16位和32位编译器有相对应的用16位和32位两种编译方式这段的目的是统一
4、目前的处理器工作状态和软件编译方式Check if tasm.exe(armasm -16 .ADS 1.0) is used. GBLL THUMBCODE ;声明一个全局逻辑变量 CONFIG = 16 ;if CONFIG = 16THUMBCODE SETL TRUE ;THUMBCODE = TRUE CODE32 ;指示编译器为ARM指令 | ;elseTHUMBCODE SETL FALSE ;THUMBCODE = FALSE 宏定义,在后面出现MOV_PC_LR时,这个宏会被自动展开该宏的作用是跳出子程序,返回被调用处 MACRO MOV_PC_LR THUMBCODE ;i
5、f THUMBCODE = TRUE bx lrelse 即THUMBCODE = FALSE mov pc,lr MEND该宏定义的作用是有条件地(当Z=1时)跳出子程序,返回被调用处 MOVEQ_PC_LR THUMBCODE bxeq lr | moveq pc,lr该宏定义是把中断服务程序的首地址装载到pc中在后面当遇到HandlerXXX HANDLER HandleXXX时,该宏被展开注意:HANDLER前的符号HandlerXXX比其后的符号HandleXXX多了一个rHandlerXXX为ARM体系中统一定义的几种异常中断HandleXXX为每个ARM处理器各自定义的中断,见该
6、文件最后部分的中断向量表$HandlerLabel HANDLER $HandleLabel$HandlerLabel sub sp,sp,#4 ;ATPCS规定数据栈为FD类型 ;即栈指针指向栈顶元素,数据栈向内存地址减小的方向增长该语句是使栈地址减小4个字节,以留出空间装载中断服务函数首地址 stmfd sp!,r0 ;由于要利用r0寄存器来传递数据,所以要保存r0数据,使其入栈 ldr r0,=$HandleLabel ;把HandleXXX的地址装到r0 ldr r0,r0 ;装载中断服务函数的起始地址 str r0,sp,#4 ;中断函数首地址入栈 ldmfd sp!,r0,pc ;
7、将事先保存的r0数据和中断函数首地址出栈并使系统跳转到相应的中断处理函数导入连接器事先定义好的运行域中三个段变量ARM的可执行映像文件由RO、RW、ZI三个段组成RO为代码段,RW为已初始化的全局变量,ZI为未初始化的全局变量 IMPORT |Image$RO$Base| ;RO段起始地址 IMPORT |Image$RO$Limit| ;RO段结束地址加1,等于RW段起始地址 IMPORT |Image$RW$Base| ;RW段起始地址 IMPORT |Image$ZI$Base| ;ZI段起始地址 IMPORT |Image$ZI$Limit| ;ZI段结束地址加1导入两个关于MMU的函
8、数,用于设置时钟模式为异步模式和快速总线模式 IMPORT MMU_SetAsyncBusMode IMPORT MMU_SetFastBusMode ;导入Main,它为C语言程序入口函数 IMPORT Main ; The main entry of mon program导入用于复制从Nand Flash中的映像文件到SDRAM中的函数 IMPORT RdNF2SDRAM ; Copy Image from Nand Flash to SDRAM定义代码段,名为Init AREA Init,CODE,READONLY在入口处(0x0)开始的8个字单元空间内,存放的是ARM异常中断向量表,
9、每个字单元空间都是一条跳转指令,当异常发生时,ARM会自动跳转到相应的中断向量处,并由该处的跳转指令再跳转到相应的执行函数处 ENTRY ;程序入口处 EXPORT _ENTRY ;导出_ENTRY,即导出代码段入口地址_ENTRY ;主要用于MMUResetEntry ;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 ord
10、er should be changed as the memory bus width.3)The pseudo instruction,DCD can not be used here because the linker generates error.在0x0处的异常中断是复位异常中断,是上电后执行的第一条指令变量ENDIAN_CHANGE用于标记是否要从小端模式改变为大端模式,因为编译器初始模式是小端模式,如果要用大端模式,就要事先把该变量设置为TRUE,否则为FLASE变量ENTRY_BUS_WIDTH用于设置总线的宽度,因为用16位和8位宽度来表示32位数据时,在大端模式下,数据
11、的含义是不同的由于要考虑到大端和小端模式,以及总线的宽度,因此该处看似较复杂,其实只是一条跳转指令:当为大端模式时,跳转到ChangeBigEndian函数处,否则跳转到ResetHandler函数处 ASSERT :DEF:ENDIAN_CHANGE ;判断是否定义了ENDIAN_CHANGE如果没有定义,则报告该处错误信息 ENDIAN_CHANGE ;if ENDIAN_CHANGE =TRUEENTRY_BUS_WIDTH ;判断是否定义了ENTRY_BUS_WIDTH ENTRY_BUS_WIDTH=32 ;if ENTRY_BUS_WIDTH =32跳转到ChangeBigEndi
12、an(ChangeBigEndian在0x24),因此该条指令的机器码为0xea000007所以该语句与在该处(即0x0处)直接放入0xea000007数据(即DCD 0xea000007)作用相同 b ChangeBigEndian ENTRY_BUS_WIDTH=16 ;if ENTRY_BUS_WIDTH =16在小端模式下,用16位或8位数据总线宽度表示32位数据,与用32位总线宽度表示32位数据,格式完全一致。但在大端模式下,格式就会发生变化在复位时,系统默认的是小端模式,所以就要人为地改变数据格式,使得用16位大端数据表示的32位数据也能被小端模式的系统识别该语句的目的也是跳转到C
13、hangeBigEndian,即机器码也应该是0xea000007,但为了让小端模式系统识别,就要把机器码的顺序做一下调整,改为0x0007ea00,那么我们就可以用DCD 0x0007ea00把机器码装载进去了,但由于该处不能使用DCD伪指令,因此我们就要用一条真实的指令来代替DCD 0x0007ea00,即该指令编译后的机器码也为0x0007ea00,而andeq r14,r7,r0,lsl #20就是一条编译后机器码为0x0007ea00的指令,所以我们在该处写上该条指令 andeq r14,r7,r0,lsl #20 ;DCD 0x0007ea00 ENTRY_BUS_WIDTH=8 ;if ENTRY_BUS_WIDTH
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1