实验一 ARM汇编程序的编写以及启动代码的分析.docx

上传人:b****5 文档编号:7886295 上传时间:2023-01-26 格式:DOCX 页数:24 大小:29.91KB
下载 相关 举报
实验一 ARM汇编程序的编写以及启动代码的分析.docx_第1页
第1页 / 共24页
实验一 ARM汇编程序的编写以及启动代码的分析.docx_第2页
第2页 / 共24页
实验一 ARM汇编程序的编写以及启动代码的分析.docx_第3页
第3页 / 共24页
实验一 ARM汇编程序的编写以及启动代码的分析.docx_第4页
第4页 / 共24页
实验一 ARM汇编程序的编写以及启动代码的分析.docx_第5页
第5页 / 共24页
点击查看更多>>
下载资源
资源描述

实验一 ARM汇编程序的编写以及启动代码的分析.docx

《实验一 ARM汇编程序的编写以及启动代码的分析.docx》由会员分享,可在线阅读,更多相关《实验一 ARM汇编程序的编写以及启动代码的分析.docx(24页珍藏版)》请在冰豆网上搜索。

实验一 ARM汇编程序的编写以及启动代码的分析.docx

实验一ARM汇编程序的编写以及启动代码的分析

实验ARM汇编程序的编写以及启动代码的分析

一、实验目的:

练习ARM汇编程序的编写,对提供的程序的启动代码进行分析,了解S3C2410初始化过程,初始化代码主要是包含在start.s中。

二、实验原理:

启动程序要完成的任务包括:

硬件初始化,系统存储系统的配置,复制二级中断向量表。

启动程序过程

●系统硬件初始化

系统上电或复位后,程序从位于地址0x0的ResetExceptionVector处开始执行,因此需要在这里放置Bootloader的第一条指令:

bResetHandler,跳转到标号为ResetHandler处进行第一阶段的硬件初始化,执行完,系统进行堆栈和存储器的初始化。

使用了外设,则需要设置相关的寄存器,确定其刷新频率、总线宽度等信息。

●代码段复制到RAM中运行

需要把系统的代码复制到RAM中运行。

映像文件内部共有三种输出段:

RO段、RW段和ZI段。

ARMLink同时还产生了这三种输出段的起始和终止定位信息:

Image$$RO$$Base、Image$$RO$$Limit、Image$$RW$$Base、Image$RW$Limit、Image$ZI$Base和Image$$ZI$$Limit。

可以在程序中使用这些定位信息。

将ROM中的代码和数据搬移到RAM中。

●建立二级中断向量表

在ARM系统中,中断向量表位于0X0开始的地址处,意味着无论运行什么样的上层软件,一旦发生中断,程序就得到Flash存储器中的中断向量表里去,降低系统的运行效率。

因此在RAM中建立自己的二级中断向量表,当中断发生后,程序直接从RAM中取中断向量进入中断子程序。

尤其是在中断频繁发生的系统里,这种方法可以大大提高系统的运行效率。

三、实验内容:

1.运行一个简单的串口程序,单步执行初始化代码,观察寄存器变化。

2.分析系统上电后的初始化工作包括哪些内容。

3.分析中断的处理过程,包括中断向量表的建立、中断源的识别及中断IRQ服务程序是如何进入的。

4.分析应用程序的结构。

四、实验代码:

在系统上电后,初始化部分的工作注意包含以下部分:

1、关看门狗定时器

2、屏蔽所有中断

3、设置CPU时钟频率。

4、设置存储器控制寄存器,对外部存储器的参数进行设置。

5、初始化各模式下的堆栈

6、建立IRQ中断的总的入口地址

7、初始化应用程序的执行环境

8、跳入Main函数,进入C程序

;=========================================

;NAME:

2410INIT.S

;DESC:

Cstartupcodes

;Configurememory,ISR,stacks

;InitializeC-variables

;HISTORY:

;2002.02.25:

kwtark:

ver0.0

;2002.03.20:

purnnamu:

AddsomefunctionsfortestingSTOP,POWER_OFFmode

;=========================================

GEToption.s;GET相当INCLUDE将一个源文件包含到当前源文件,这里表示包含option.s,并在当前位置进行汇编

GETmemcfg.s

GET2410addr.s

BIT_SELFREFRESHEQU(1<<22);定义了一些符号常量

;ARM异常模式的定义

;SDRAM/DRAM刷新控制器bit22REFMD位0:

CBR/AUTOREFRESH1:

SHIFREFRESH

;下面是对arm处理器模式寄存器对应值的常数定义,arm处理器中有一个CPSR程序状

;态寄存器,CPSR后五位决定目前的处理器模式。

;Pre-definedconstants

USERMODEEQU0x10;用户模式

FIQMODEEQU0x11;FIQ快速中断模式

IRQMODEEQU0x12;中断模式

SVCMODEEQU0x13;管理模式

ABORTMODEEQU0x17;中止模式

UNDEFMODEEQU0x1b;未定义指令模式

MODEMASKEQU0x1f;系统模式

NOINTEQU0xc0;禁止IRQ和FIQ中断

;ARM各异常模式堆栈,定义各模式堆栈地址

;_STACK_BASEADDRESS在option.s中,

;Thelocationofstacks

_STACK_BASEADDRESSEQU(SDRAM_END-0x8000);0x33ff8000

UserStackEQU(_STACK_BASEADDRESS-0x3800);0x33ff4800~;用户模式堆栈

SVCStackEQU(_STACK_BASEADDRESS-0x2800);0x33ff5800~0x3ff47ff;管理模式堆栈4k

UndefStackEQU(_STACK_BASEADDRESS-0x2400);0x33ff5c00~0x3ff57ff;未定义指令模式堆栈1k

AbortStackEQU(_STACK_BASEADDRESS-0x2000);0x33ff6000~0x3ff5bff;中止模式堆栈1k

IRQStackEQU(_STACK_BASEADDRESS-0x1000);0x33ff7000~0x3ff5fff;中断模式堆栈4k

FIQStackEQU(_STACK_BASEADDRESS-0x0);0x33ff8000~0x33ff6fff;快速中断模式堆栈4k

;arm处理器有两种工作状态

;1.arm:

32位这种工作状态下执行字对齐的arm指令

;2.Thumb:

16位这种工作状;态执行半字对齐的Thumb指令

;因为处理器分为16位32位两种工作状态程序的编译器也是分16位和32两种编译方式

;所以下面的程序用于根据处理器工作状态确定编译器编译方式

;code16伪指令指示汇编编译器,后面的指令为16位的thumb指令

;code32伪指令指示汇编编译器,后面的指令为32位的arm指令

;这段是为了统一目前的处理器工作状态和软件编译方式(16位编译环境使用tasm.exe编译)

;Checkiftasm.exe(armasm-16...@ADS1.0)isused.检查是否是用tasm.exe进行16位编译

GBLLTHUMBCODE;声明一个全局变量并初始化为{FALSE}

[{CONFIG}=16;ifconfig=16这里表示用16位编译方式

THUMBCODESETL{TRUE};SETL给全局变量赋值,设置THUMBCODE为true

CODE32;CODE32表明一下操作都在ARM状态,转入32位编译模式

|;|=ELSE|等同ELSE

THUMBCODESETL{FALSE};设置THUMBCODE为false,THUMBCODE=FALSE

];endif]等同ENDIF

;宏定义MOV_PC_LR

MACRO;MACRO定义宏,宏定义开始

MOV_PC_LR;宏将被下面定义部分展开,宏名MOV_PC_LR

[THUMBCODE;ifTHUMBCODE=true

bxlr;THUMBCODE模式上返回ARM状态

|;else

movpc,lr;ARM状态下返回

];endif

MEND;宏结束

MACRO;宏定义开始

MOVEQ_PC_LR;宏名为MOVEQ_PC_LR,与上面部分相同

[THUMBCODE;ifTHUMBCODE=true

bxeqlr;EQ相等则跳转回ARM状态

|;else

moveqpc,lr;同上位置相同部分,不同的是如果相等才跳回ARM状态

];endif

MEND;宏结束

;宏定义-进入异常流程

;HANDLER-宏的名称

;$HandleLabel-宏的参数

;这个宏的作用是把各个中断程序的地址装入当前的PC,2410有两种装断模式:

一种是没有

;中断向量表,一种是使用中断向量表的

;使用中断向量表只能是IRQ方式,当使用中断向量表的时候,中断发生时由2410的中断控

;制器自动跳转到

;相应的位置。

;注意下面这段宏定义程序

;下面包含的HandlerXXXHANDLERHandleXXX将都被下面这段程序展开

;本初始化程序定义了一个数据区(在文件最后),34个字空间,存放相应中断服务程序的首

;地址。

每个字,即4字节

;空间都有一个标号,以Handle***命名。

;在向量中断模式下使用“加载程序”来执行中断服务程序。

;向量中断模式和非向量中断模式的区别是:

向量中断模式是当cpu读取位于0x18处的IR

;Q中断指令的时候,系统自动读取对应于该中断源确定地址上的指令取代0x18处的指令,

;通过跳转指令系统就直接跳转到对应地址

;函数中节省了中断处理时间提高了中断处理速度标例如ADC中断的向量地址为0xC0,

;在0xC0处放如下代码:

;ldrPC,=HandlerADC当ADC中断产生的时候系统会自动跳转到HandlerADC函数中

;非向量中断模式处理方式是一种传统的中断处理方法,当系统产生中断的时候,系统将int

;erruptpending寄存器中对应标志位置位

;然后跳转到位于0x18处的统一中断;函数中

;该函数通过读取interruptpending寄存器中对应标志位来判断中断源,并根据优先级关系

;再跳到;对应中断源的处理代码中

;大致作用是把宏的第一个参数$HandlerLabel转变为一个标号,然后让程序跳转到第二个参

;数$HandleLabel(为一个地址)对应的值的地址去。

;所以,通过上面的分析可以看出,$HandlerLabelHANDLER$HandleLabel是让PC跳转到$H

;andleLabel中存放的地址执行。

MACRO;宏定义

$HandlerLabelHANDLER$HandleLabel;宏名字叫HANDLER,$HandleLabel是

;行参,定义了一个标号$HandlerLabel,展开时可替换成相应的符号

$HandlerLabel

subsp,sp,#4;sp-sp-4,空出的空间用于存放跳转地址

stmfdsp!

{r0};sp=sp-4,并将r0入栈

ldrr0,=$HandleLabel;获取存放跳转地址的标号HandleLabel到r0

ldrr0,[r0];将HandleLabel中存放的跳转地址送给r0

strr0,[sp,#4];将r0存放到sp+4的地方,

ldmfdsp!

{r0,pc};弹出栈顶2个字,分别保存到r0和pc中,系统将跳

;转到对应中断处理函数,由上r0和pc都没变,但程序已跳转

MEND;宏定义结束

;连接器生成的输出段相关的符号

;引入连接器生成的映象文件的各个部分地址。

;OR-只读区域、RW-读写区域、ZI-初始化为0的区域。

IMPORT|Image$$RO$$Limit|;EndofROMcode(=startofROMdata),RO结束

;地址+1

IMPORT|Image$$RW$$Base|;BaseofRAMtoinitialise,RW起始

IMPORT|Image$$ZI$$Base|;Baseandlimitofarea,RW段结束+1

IMPORT|Image$$ZI$$Limit|;tozeroinitialise,ZI段起始地址

;引入外部函数Main,进入C程序。

IMPORTMain;Themainentryofmonprogram

;IMPORTLEDTEST

;定义ARM汇编程序段,段名为SelfBoot,程序段为只读的代码段。

AREASelfBoot,CODE,READONLY;Selfboot初始化程序

;板子上电和复位后程序开始从位于0x0处开始执行,硬件刚刚上电复位后程序从这里开始

;执行跳转到标为ResetHandler处执行

;DCD用于分配一段字内存单片,并用后面的伪指令初始化,分配字节由expr个数决定

;程序入口地址

ENTRY

ResetEntry

;1)Thecode,whichconvertstoBig-endian,shouldbeinlittleendiancode.

;2)ThefollowinglittleendiancodewillbecompiledinBig-Endianmode.Thecodebyteordershouldbechangedasthememorybuswidth.

;3)Thepseudoinstruction,DCDcan'tbeusedherebecausethelinkergenerateserror.

ASSERT:

DEF:

ENDIAN_CHANGE;ASSERT断言错误伪指令,这里表示是否定义过ENDIAN_CHANGE

[ENDIAN_CHANGE;如果定义了ENDIAN_CHANGE

ASSERT:

DEF:

ENTRY_BUS_WIDTH;这里表示是否定义过ENTRY_BUS_WIDTH

[ENTRY_BUS_WIDTH=32;ifENTRY_BUS_WIDTH=32

bChangeBigEndian;DCD0xea000007,跳转到ChangeBigEndian,

;执行DCD0xea000007改变大小端数据模式

];endif

[ENTRY_BUS_WIDTH=16;ifENTRY_BUS_WIDTH=16

andeqr14,r7,r0,lsl#20;DCD0x0007ea00,标志状态寄存器CPSR的Z

;=1时,r14=r7+r0逻辑左移20位,执行DCD0x0007ea00改变大小端模式

];endif

[ENTRY_BUS_WIDTH=8;ifENTRY_BUS_WIDTH=8

streqr0,[r0,-r10,ror#1];DCD0x070000e,当标志状态寄存器CPSR的Z

;=1时…,执行DCD0x070000ea改变大小端模式

];endif

|;ELSE即如果没定义ENDIAN_CHANGE

bResetHandler;复位处理模式

]

bHandlerUndef;handlerforUndefinedmode处理为定义模式

bHandlerSWI;handlerforSWIinterrupt处理软中断模式

bHandlerPabort;handlerforPAbort处理终止程序访问终止模式

bHandlerDabort;handlerforDAbort处理数据访问终止模式

b.;reserved保留,"."代表指令的地址,即表示进行死循环

bHandlerIRQ;handlerforIRQinterrupt处理中断模式

bHandlerFIQ;handlerforFIQinterrupt处理快速中断模式

;@0x20"@"存储区位置计数器的当前值

bEnterPWDN;进入掉电模式,见下面的标号

ChangeBigEndian;上面提到的ChangeBigEndian,改变大小端数据模式

;@0x24

[ENTRY_BUS_WIDTH=32;ifENTRY_BUS_WIDTH=32

DCD0xee110f10;0xee110f10=>mrcp15,0,r0,c1,c0,0

DCD0xe3800080;0xe3800080=>orrr0,r0,#0x80;//Big-endian

DCD0xee010f10;0xee010f10=>mcrp15,0,r0,c1,c0,0

]

[ENTRY_BUS_WIDTH=16;ifENTRY_BUS_WIDTH=16

DCD0x0f10ee11

DCD0x0080e380

DCD0x0f10ee01

]

[ENTRY_BUS_WIDTH=8;ifENTRY_BUS_WIDTH=8

DCD0x100f11ee

DCD0x800080e3

DCD0x100f01ee

]

DCD0xffffffff;swinv0xffffffissimilarwithNOPandrunwellinbothendianmode.

DCD0xffffffff

DCD0xffffffff

DCD0xffffffff

DCD0xffffffff

bResetHandler;复位处理程式

;Functionforenteringpowerdownmode

;1.SDRAMshouldbeinself-refreshmode.

;2.AllinterruptshouldbemakskedforSDRAM/DRAMself-refresh.

;3.LCDcontrollershouldbedisabledforSDRAM/DRAMself-refresh.

;4.TheI-cachemayhavetobeturnedon.

;5.Thelocationofthefollowingcodemayhavenottobechanged.

;进入掉电模式功能

;1.SDRAM必须在自刷新模式.

;2.所有中断必须屏蔽forSDRAM/DRAMself-refresh.

;3.LCD关闭forSDRAM/DRAMself-refresh.

;4.TheI-cache可能需要开启.

;5.Thelocationofthefollowingcodemayhavenottobechanged.

;voidEnterPWDN(intCLKCON);;进入掉电模式

EnterPWDN

movr2,r0;r2=rCLKCONCLKCON[3]掉电模式控制位0:

关闭1:

进入掉电模式

tstr0,#0x8;POWER_OFFmode?

判断POWER_OFF是否为0。

r0和

#0X8相与,更新CPSR位

bneENTER_POWER_OFF;NE不相等(则表示power_off不为O)标志位Z=0

ENTER_STOP;不进入掉电模式

ldrr0,=REFRESH;0x48000024;DRAM/SDRAMrefreshDRAM/SDRAM刷新控制器,刷新DRAM/SDRAM

ldrr3,[r0];r3=rREFRESH

movr1,r3;r1=r3

orrr1,r1,#BIT_SELFREFRESH;BIT_SELFREFRESHEQU(1<<22)bit22TREFMD位

0:

CBR/AUTOREFRESH1:

SHIFREFRESH

strr1,[r0];R1->[R0]EnableSDRAMself-refresh

;%B是向后搜索局部标号,%F是向前搜索局部标号。

movr1,#16;延时waituntilself-refreshisissued.maynotbeneeded.

0subsr1,r1,#1;0为局部标号(延时)

bne%B0

ldrr0,=CLKCON;enterSTOPmode.CLKCON;Clockgeneratorcontrol

strr2,[r0]

movr1,#32

0subsr1,r1,#1;1)延时waituntiltheSTOPmodeisineffect.

bne%B0;2)OrwaithereuntiltheCPU&Peripheralswillbeturned-off

;EnteringPOWER_OFFmode,onlytheresetbywake-upisavailable.

ldrr0,=REFRESH;exitfromSDRAMselfrefreshmode.

strr3,[r0]

MOV_PC_LR;调用宏MOV_PC_LR

ENTER_POWER_OFF;进入掉电模式

;NOTE.

;1)rGSTATUS3shouldhavethereturnaddressafterwake-upfromPOWER_OFFmode.

ldrr0,=REFRESH

ldrr1,[r0];r1=rREFRESH

orrr1,r1,#BIT_SELFREFRESH

strr1,[r0];EnableSDRAMself-refresh

movr1,#16;Waituntilself-refreshisissued,whichmaynotbeneeded.

0subsr1,r1,#1;延时

bne%B0

ldrr1,=MISCCR;;Miscellaneouscontrol,混杂控制模式

ldrr0,[r1]

orrr0,r0,#(7<<17);MakesurethatSCLK0:

SCLK->0,SCL

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 农林牧渔 > 林学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1