ARM启动代码分析_第1页
ARM启动代码分析_第2页
ARM启动代码分析_第3页
ARM启动代码分析_第4页
ARM启动代码分析_第5页
已阅读5页,还剩2页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

ARM启动代码分析ARM启动代码分析-philips的LPC2xxx系列/***********************************************************************************File:startup.s*Author:Embestw.h.xie2005.02.21*Desc:lpc22xx\lpc212x\lpc211x\lpc210xstartupcode*History:*notemodify:cuijianjie2006-4-25*comment:**********************************************************************************/#处理器的七种工作方式的常量定义.EQUMode_USR,0x10#用户模式.EQUMode_FIQ,0x11#FIQ模式.EQUMode_IRQ,0x12#IRQ模式.EQUMode_SVC,0x13#超级用户模式.EQUMode_ABT,0x17#终止模式.EQUMode_UND,0x1B#未定义模式.EQUMode_SYS,0x1F#系统模式#中断屏蔽位.EQUI_Bit,0x80//IRQ中断控制位,当被置位时,IRQ中断被禁止.EQUF_Bit,0x40//FIQ中断控制位,当被置位时,FIQ中断被禁止#状态屏蔽位.EQUT_bit,0x20//T位,置位时在Thumb模式下运行,清零时在ARM下运行#定义程序入口点.globl_start.code32.TEXT_start:#中断向量表Vectors:LDRPC,Reset_Addr//把Reset_Addr地址处的内容放入PC中LDRPC,Undef_AddrLDRPC,SWI_AddrLDRPC,PAbt_AddrLDRPC,DAbt_Addr.long0xb9205f80@keepinterruptvectorssumis0LDRPC,[PC,#-0xff0]//当前PC值减去0xFF0等于IRQ中断入口地址LDRPC,FIQ_Addr#地址表:Reset_Addr:#该地址标号存放Reset_Handler程序段的入口地址.longReset_HandlerUndef_Addr:#该地址标号存放Undef_Handler程序段的入口地址.longUndef_HandlerSWI_Addr:#该地址标号存放SWI_Handler程序段的入口地址.longSWI_HandlerPAbt_Addr:#该地址标号存放PAbt_Handler程序段的入口地址.longPAbt_HandlerDAbt_Addr:.longDAbt_Handler.long0IRQ_Addr:#地址标号处存放一个无效的数据.long0FIQ_Addr:#该地址标号存放FIQ_Handler程序段的入口地址.longFIQ_HandlerUndef_Handler:BUndef_HandlerPAbt_Handler:BPAbt_HandlerDAbt_Handler:BDAbt_Handler#软中断的中断服务子程序入口地址SWI_Handler:STMFDsp!,{r0-r3,r12,lr}//入栈,现场数据保护MOVr1,sp//把堆栈指针SP存入R1中MRSr0,spsr//把SPSR值存入R0,SPSR值为产生软中断时的CPSRTSTr0,#T_bit//判断R0(SPSR)的T位是否为0#SPSR的T位不为0,工作在Thumb模式下LDRNEHr0,[lr,#-2]//SPSR的T位不为0,则[lr-2]-〉r0BICNEr0,r0,#0xFF00//SPSR的T位不为0,清除r0的Bit8~Bit15位#SPSR的T位为0,工作在ARM模式下LDREQr0,[lr,#-4]//SPSR的T位为0,则[lr-4]-〉r0BICEQr0,r0,#0xFF000000//SPSR的T位为0,清除r0的Bit24~Bit131位#R0isinterruptnumber//R0是中断号#R1isstackpoint//R1是堆栈指针BLSWI_Exception//进入软中断处理程序LDMFDsp!,{r0-r3,r12,pc}^//出栈,现场数据恢复#快速响应中断的中断服务自程序的入口地址FIQ_Handler:STMFDSP!,{R0-R3,LR}//入栈的现场保护#BLFIQ_Exception//进入FIQ的中断处理程序LDMFDSP!,{R0-R3,LR}//出栈,恢复现场SUBSPC,LR,#4//返回到主程序#复位后程序处理的入口地址Reset_Handler:BLRemapSRAM//进行存储器映射的操作#下面几行代码用来判断当前的工作模式MRSR0,CPSR//读CPSR到寄存器R0ANDR0,R0,#0x1F//R0=R0AND0x1FCMPR0,#Mode_USR//比较R0和#Mode_USR,二者相减//如果相等则说明当前处在用户模式下,需要通过产生11号软中断进入系统模式。因为下面的初始化堆栈//需要在不同的工作模式下切换,而在用户模式下不能直接切换,只有系统模式可以,所以要通过产生11//号软中断切换到用户模式。SWIEQ#11BLInitStack//进行堆栈初始化工作ARM启动代码分析-philips的LPC2xxx系列32006-7-2414:33:00#------------------------------------------------------------------------------#-初始化C变量#------------------------#-下表由连接器自动产生#-RO:只读=代码区。#-RW:可读可写=预先初始化的数据(初始化的全局变量)和预先被清零的数据(未初始化的全局变量)。.#-ZI:预先被清零的数据区(未初始化的全局变量)#-预先被初始化的数据区定位在代码区之后。#-预先被清零的数据区定位在预先被初始化的数据区之后。#-注意数据区的位置:#-I如果用ARMSDT,当链接器选择no-rw-base时,数据区被映射在代码区之后#-你可以把数据区房子内部的SRAM(-rw-base=0x40or0x34)中#-或者放在外部的SRAM(-rw-base=0x2000000)中。#-注意:为了提高代码的密度,预先被初始化的数据必须尽可能的少。#------------------------------------------------------------------------------#该部分程序功能:先判断当前是在RAM中运行还是在FLASH中运行,如果在FLASH中运行,先把FLASH#中的预先赋值的RW段数据和未赋值的ZI段数据都搬移到RAM区中,再把ZI段数据全部清零;如果程#序就是在RAM中运行,则直接把ZI段数据清零。.externImage_RO_Limit/*ROM区中数据段的起始地址*/.externImage_RW_Base/*RW段起始地址*/.externImage_ZI_Base/*ZI段的起始地址*/.externImage_ZI_Limit/*ZI段的结束地址加1*/ldrr0,=Image_RO_Limit/*取ROM区中数据段的首地址*/ldrr1,=Image_RW_Base/*取RAM区中RW段的目标首地址*/ldrr3,=Image_ZI_Base/*取RAM区中ZI段的首地址*/cmpr0,r1/*比较ROM区中数据段首地址和RAM区中RW段目标首地址*/beqNoRW/*相等代表当前是在RAM中运行*/LoopRw:cmpr1,r3/*不相等则和RAM区中ZI段的目标地址比较*/ldrccr2,[r0],#4/*如果r1<r3,则把r0地址上的数据读出到r2中,然后r0=r0+4*/strccr2,[r1],#4/*如果r1<r3,则把r2内数据写入道r1地址中,然后r1=r1+4*/bccLoopRw/*如果r1<r3,则跳转到LoopRw继续执行*/NoRW:ldrr1,=Image_ZI_Limit/*取ZI段的结束地址*/movr2,#0/*将r2赋0*/LoopZI:cmpr3,r1/*将ZI段清零*/strccr2,[r3],#4/*如果r3<r1,将r2内容写入到r3地址单元中,然后r3=r3+1*/bccLoopZI/*如果r3<r1(即C=0),则跳转到LoopZI*/.externMain/*声明外部变量*/BMain/*t跳转到用户的主程序入口*/#为每一种模式建立堆栈,ARM堆栈指针向下生长InitStack:MOVR1,LR//把该子程序返回地址保留在R1中LDRR0,=Top_Stack//取栈定地址到R0中#进入未定义模式,并禁止FIQ中断和IRQ中断MSRCPSR_c,#Mode_UND|I_Bit|F_Bit#设置未定义模式下堆栈的栈顶指针MOVSP,R0SUBR0,R0,#UND_Stack_Size#未定义模式下堆栈深度#进入终止模式,并禁止禁止FIQ中断和IRQ中断MSRCPSR_c,#Mode_ABT|I_Bit|F_Bit#紧接着未定义模式下的堆栈,设置终止模式下栈顶指针MOVSP,R0SUBR0,R0,#ABT_Stack_Size#终止模式下堆栈深度#进入FIQ模式,并禁止FIQ中断和IRQ中断MSRCPSR_c,#Mode_FIQ|I_Bit|F_Bit#紧接着终止模式下的堆栈,设置下FIQ模式下栈顶指针MOVSP,R0SUBR0,R0,#FIQ_Stack_Size#FIQ模式下的堆栈深度#进入IRQ模式,并禁止FIQ中断和IRQ中断MSRCPSR_c,#Mode_IRQ|I_Bit|F_Bit#紧接着FIQ模式下的堆栈,设置IRQ模式下的栈顶指针MOVSP,R0SUBR0,R0,#IRQ_Stack_Size#IRQ模式下的堆栈深度#进入超级用户模式,并禁止FIQ中断和IRQ中断MSRCPSR_c,#Mode_SVC|I_Bit|F_Bit#紧接着IRQ模式下的堆栈,设置超级用户下的栈顶指针MOVSP,R0SUBR0,R0,#SVC_Stack_Size#超级用户下的堆栈深度#设置进入用户模式MSRCPSR_c,#Mode_USR#紧接着超级用户模式下的堆栈,设置用户模式下的栈顶指针,剩余的空间都开辟为堆栈MOVSP,R0MOVPC,R1#堆栈初始化子程序返回#重映射SRAM区RemapSRAM:MOVR0,#0x40000000//RAM区首地址LDRR1,=Vectors//向量表首地址#下面一段程序是把从0x00000000开始的64个字节(FLASH中的中断向量表和地址表)搬移到以#0x40000000为首地址的RAM区中LDMIAR1!,{R2-R9}//把以[R1]为首地址的32个字节数据装载到R2-R9中STMIAR0!,{R2-R9}//把R2-R9中的数据存入以[R0]为首地址的单元中LDMIAR1!,{R2-R9}//把以[R1]为首地址的32个字节数据装载到R2-R9中STMIAR0!,{R2-R9}////把R2-R9中的数据存入以[R0]为首地址的单元中#下面几行代码设置存储器映射控制寄存器LDRR0,=MEMMAP//取MEMMAP地址到R0MOVR1,#0x02STRR1,[R0]//给MEMMAP赋值为0x02,设置中断向量从RAM区从新映射movpc,lr//跳转到主程序#下面一段程序代码是进入软中断来切换系统的工作模式,当希望从一种模式切换入另一种模式时,可以通#过调用下面对应标号的程序段进入软中断。在软中断处理程序中会根据所给定的中断号处理,执行SWI#num后软中断号被存入R0中。.globldisable_IRQ.globlrestore_IRQ.globlToSys.globlToUser#禁止IRQdisable_IRQ:STMFDSP!,{LR}//把LR值压入堆栈swi#0//

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论