试验指导书.docx
- 文档编号:30013127
- 上传时间:2023-08-04
- 格式:DOCX
- 页数:16
- 大小:334.80KB
试验指导书.docx
《试验指导书.docx》由会员分享,可在线阅读,更多相关《试验指导书.docx(16页珍藏版)》请在冰豆网上搜索。
试验指导书
2.3实验3—处理器模式切换
一实验要求
1、掌握ARM处理器的常用寻址方式。
2、编写测试代码并利用AXD调试验证。
二实验器材
软件:
RVDS2.2AXD
硬件:
PC机j-linkTiny6410开发板
三背景知识
1、ARM处理器模式:
ARM微处理器支持7种运行模式,分别为:
ARM微处理器的运行模式可以通过软件改变,也可以通过外部中断或异常处理改变。
大多数应用程序运行在用户模式下,当处理器运行在用户模式下时,某些被保护的系统资源是不能被访问的。
除用户模式下以外,其余的所有6中模式称之为非用户模式下,或特权模式;其中除去用户模式和系统模式以外的5种称为异常模式,常用于处理中断或异常,以及需要访问受保护的系统资源等情况。
四实验代码分析
;定义堆栈的大小
USR_STACK_LEGTHEQU64
SVC_STACK_LEGTHEQU0
FIQ_STACK_LEGTHEQU16
IRQ_STACK_LEGTHEQU64
ABT_STACK_LEGTHEQU0
UND_STACK_LEGTHEQU0
AREAstart,CODE,READONLY;声明代码段start
ENTRY;标识程序入口
CODE32;声明32位ARM指令
START
MOVR0,#0
MOVR1,#1
MOVR2,#2
MOVR3,#3
MOVR4,#4
MOVR5,#5
MOVR6,#6
MOVR7,#7
MOVR8,#8
MOVR9,#9
MOVR10,#10
MOVR11,#11
MOVR12,#12
BLInitStack;初始化各模式下的堆栈指针
;打开IRQ中断(将CPSR寄存器的I位清零)
MRSR0,CPSR;R0<=CPSR
BICR0,R0,#0x80
MSRCPSR_cxsf,R0;CPSR<=R0
;切换到用户模式
MSRCPSR_c,#0xd0
MRSR0,CPSR
;切换到管理模式(用户模式无法再切换到其他特权模式)
MSRCPSR_c,#0xdf
MRSR0,CPSR
HALT
BHALT
;名称:
InitStack
;功能:
堆栈初始化,即初始化各模式下的堆栈指针。
;入口参数:
无
;出口参数:
无
;说明:
在特权模式下调用此子程序,比如复位后的管理模式
InitStack
MOVR0,LR;R0<=LR,因为各种模式下R0是相同的
;设置管理模式堆栈
MSRCPSR_c,#0xd3
LDRSP,StackSvc
;设置中断模式堆栈
MSRCPSR_c,#0xd2
LDRSP,StackIrq
;设置快速中断模式堆栈
MSRCPSR_c,#0xd1
LDRSP,StackFiq
;设置中止模式堆栈
MSRCPSR_c,#0xd7
LDRSP,StackAbt
;设置未定义模式堆栈
MSRCPSR_c,#0xdb
LDRSP,StackUnd
;设置系统模式堆栈
MSRCPSR_c,#0xdf
LDRSP,StackUsr
MOVPC,R0;请注意:
axd对PC赋值的操作可能引起异常
;记录各个模式堆栈的栈顶,因为是递减堆栈
StackUsrDCDUsrStackSpace+(USR_STACK_LEGTH-1)*4
StackSvcDCDSvcStackSpace+(SVC_STACK_LEGTH-1)*4
StackIrqDCDIrqStackSpace+(IRQ_STACK_LEGTH-1)*4
StackFiqDCDFiqStackSpace+(FIQ_STACK_LEGTH-1)*4
StackAbtDCDAbtStackSpace+(ABT_STACK_LEGTH-1)*4
StackUndDCDUndtStackSpace+(UND_STACK_LEGTH-1)*4
;分配堆栈空间
AREAMyStacks,DATA,NOINIT,ALIGN=2
UsrStackSpaceSPACEUSR_STACK_LEGTH*4;用户(系统)模式堆栈空间
SvcStackSpaceSPACESVC_STACK_LEGTH*4;管理模式堆栈空间
IrqStackSpaceSPACEIRQ_STACK_LEGTH*4;中断模式堆栈空间
FiqStackSpaceSPACEFIQ_STACK_LEGTH*4;快速中断模式堆栈空间
AbtStackSpaceSPACEABT_STACK_LEGTH*4;中止义模式堆栈空间
UndtStackSpaceSPACEUND_STACK_LEGTH*4;未定义模式堆栈
END
五实验步骤
1、按照“1.1实验1”中方法建立RVDS工程加入实验代码3-2-3中的S3.s,打开“DebugSettings”配置界面,在“RealViewlinker”的“Layout”标签下,填充如图内容:
图2-4设置RealViewLinker
2、编译通过后,打开AXD,按照“1.2实验2”的方法配置AXD导入调试镜像。
3、分析实验代码,并使用“1.2实验2”中介绍的方法。
单步调试程序,查看各个步骤寄存器和内存中的值,是否和程序逻辑值一致。
提示:
如图2-4所示,通过下拉【ProcessorViews】|【Rigiter】可以打开寄存器查看窗口。
从这个里面我们可以查看到CPU各种工作状态的寄存器情况。
通过在寄存器对应的Value双击鼠标右键,可以编辑这个寄存器的值。
如果是在cpsr和spsr这两个寄存器的Value上进行双击,还会弹出程序状态寄存器窗口,如图2-5所示。
通过其中Flags项下的按钮
,可以设置程序状态寄存器的五个标志位。
通过按钮
可以设置中断屏蔽情况。
通过按钮
,可以设置是否工作在Thumb模式下,最后还可以通过Mode项下的下拉列表选择要设置那个处理器工作模式下的程序状态寄存器。
图2-5查看寄存器情况
图2-6程序状态寄存器设置窗口
总结:
通过本节实验内容应该掌握处理器各种模式之间的切换方法。
并了解模式切换的时机,如实验代码中各自设置模式堆栈时,进行模式切换。
2.4实验4—C/汇编混合编程
一实验要求
1、掌握C与汇编混合编程方法。
2、编写汇编代码完成堆栈的初始化并跳至C语音程序执行
3、在C语言中调用汇编程序中定义的函数。
二实验器材
软件:
RVDS2.2AXD
硬件:
PC机j-linkTiny6410开发板
三背景知识
1、C/汇编混合编程
在应用程序设计中,如果所有任务均用汇编语言来完成,器工作量可想而知的,而不利于系统升级或应用软件移植。
事实上,ARM体系结构支持C/C++与汇编的混合编程,在一个完整的系统中,除了CPU初始化部分用汇编语言完成的,其主要还是用C语言完成的。
汇编语言与C/C++混合编程通常有以下几种方式:
(1)在C/C++程序中嵌入汇编指令的语法格式:
在C/C++程序中使用的内嵌的汇编指令语法格式:
_ASM
{
汇编语言程序
…………….
汇编语言程序
}
(1)汇编访问C/C++变量
内嵌汇编不用单独编辑汇编语言文件,比较简洁,但有诸多限制,当汇编代码比较多时一般单独放在汇编文件中。
这时就需要在汇编和C之间进行一些数据传递,最简单的方法就是使用全局变量。
(2)C/C++调用汇编函数
在C中调用汇编文件中的函数,要做的主要是两个工作,一个是在C中申明函数的原型并加extern关键字;二是在汇编中EXPORT导出函数名,并用该函数名作为汇编代码标示,最后用movpc,lr返回。
然后,就可以在C中使用该函数了。
(3)汇编程序中调用C/C++函数
在汇编中调用C函数,需要在汇编中IMPORT对应的C函数名,然后将C的代码放在个独立的C文件中进行编译。
四实验代码分析
Startups.s:
;启动文件。
初始化C程序的运行环境,然后进入C程序代码。
;导入连接器事先定义好的运行域中三个段变量
;ARM的可执行映像文件由RO、RW、ZI三个段组成
;RO为代码段,RW为已初始化的全局变量,ZI为未初始化的全局变量
IMPORT|Image$$RO$$Limit|;RO段结束地址
IMPORT|Image$$RW$$Base|;RW段起始地址
IMPORT|Image$$ZI$$Base|;ZI段起始地址
IMPORT|Image$$ZI$$Limit|;ZI段结束地址
IMPORTMain;声明C程序中的Main()函数
IMPORTInitStack;声明初始化堆栈函数
AREAStart,CODE,READONLY;声明代码段Start
ENTRY;标识程序入口
CODE32;声明32位ARM指令
;初始化C程序的运行环境
LDRR0,=|Image$$RO$$Limit|
LDRR1,=|Image$$RW$$Base|
LDRR3,=|Image$$ZI$$Base|
CMPR0,R1
BEQLOOP1
LOOP0
CMPR1,R3
LDRCCR2,[R0],#4
STRCCR2,[R1],#4
BCCLOOP0
LOOP1
LDRR1,=|Image$$ZI$$Limit|
MOVR2,#0
LOOP2
CMPR3,R1
STRCCR2,[R3],#4
BCCLOOP2
BLInitStack
BLMain;跳转到C程序代码Main()函数
END
Statc.s:
AREAstack,CODE,READONLY;声明代码段start
CODE32;声明32位ARM指令
;定义堆栈的大小
USR_STACK_LEGTHEQU128
SVC_STACK_LEGTHEQU0
FIQ_STACK_LEGTHEQU16
IRQ_STACK_LEGTHEQU64
ABT_STACK_LEGTHEQU0
UND_STACK_LEGTHEQU0
EXPORTInitStack
InitStack
MOVR0,LR;R0<=LR,因为各种模式下R0是相同的
;设置管理模式堆栈
MSRCPSR_c,#0xd3
LDRSP,StackSvc
;设置中断模式堆栈
MSRCPSR_c,#0xd2
LDRSP,StackIrq
;设置快速中断模式堆栈
MSRCPSR_c,#0xd1
LDRSP,StackFiq
;设置中止模式堆栈
MSRCPSR_c,#0xd7
LDRSP,StackAbt
;设置未定义模式堆栈
MSRCPSR_c,#0xdb
LDRSP,StackUnd
;设置系统模式堆栈
MSRCPSR_c,#0xdf
LDRSP,StackUsr
MOVPC,R0;请注意:
axd对PC赋值的操作可能引起异常
;记录各个模式堆栈的栈顶,因为是递减堆栈
StackUsrDCDUsrStackSpace+(USR_STACK_LEGTH-1)*4
StackSvcDCDSvcStackSpace+(SVC_STACK_LEGTH-1)*4
StackIrqDCDIrqStackSpace+(IRQ_STACK_LEGTH-1)*4
StackFiqDCDFiqStackSpace+(FIQ_STACK_LEGTH-1)*4
StackAbtDCDAbtStackSpace+(ABT_STACK_LEGTH-1)*4
StackUndDCDUndtStackSpace+(UND_STACK_LEGTH-1)*4
;分配堆栈空间
AREAMyStacks,DATA,NOINIT,ALIGN=2
UsrStackSpaceSPACEUSR_STACK_LEGTH*4;用户(系统)模式堆栈空间
SvcStackSpaceSPACESVC_STACK_LEGTH*4;管理模式堆栈空间
IrqStackSpaceSPACEIRQ_STACK_LEGTH*4;中断模式堆栈空间
FiqStackSpaceSPACEFIQ_STACK_LEGTH*4;快速中断模式堆栈空间
AbtStackSpaceSPACEABT_STACK_LEGTH*4;中止义模式堆栈空间
UndtStackSpaceSPACEUND_STACK_LEGTH*4;未定义模式堆栈
END
Main.c:
/**********************************************************************************
*实验要求:
掌握汇编代码初始化c环境并跳转到main函数的过程,学会在c代码中调用
*汇编函数的方法,以及理解编译器处理c函数参数和返回值的方式。
*功能描述:
本程序在汇编初始化代码中完成了必要的数据初始化和栈的初始化工作,跳到
*c语言main函数后调用了在汇编文件中定义的函数,请大家使用反汇编工具分析
*函数传参和函数返回的过程。
**********************************************************************************/
//下面这些函数调用时,那些函数会用到堆栈?
它们的返回值是怎么传回来的?
externintasmSum(int,int);
intcSum(intx,inty);
intcSumargs(inta1,inta2,inta3,inta4,inta5);
/*
*c语言入口函数
**/
voidMain(void)
{
inta,b,sum;
a=1;
b=2;
sum=0;
sum=cSumargs(1,3,5,7,9);//参数更长又会怎么样?
sum=0;
//计算1+3+5+7+9结果应该是sum=0x19
while(a<10)
{
sum=asmSum(a,sum);
a=cSum(a,b);
}
}
intcSum(intx,inty)
{
return(x+y);
}
intcSumargs(inta1,inta2,inta3,inta4,inta5)
{
return(a1+a2+a3+a4+a5);
}
Sum.c:
AREAstack,CODE,READONLY;声明代码段start
CODE32;声明32位ARM指令
EXPORTasmSum
asmSum
ADDR0,R0,R1;R0用来传递返回值
MOVPC,LR
END
五实验步骤
1、按照“1.1实验1”中方法建立RVDS工程加入实验代码3-2-3中的3-2-4中的代码,打开“DebugSettings”配置界面,在“RealViewlinker”的“Layout”标签下,填充如图内容:
图2-7设置RealViewlinker
2、编译通过后,打开AXD,按照“1.2实验2”的方法配置AXD导入调试镜像。
提示:
在使用AXD进行调试工作时,通常需要跟踪一些变量的变化情况。
要查看一个变量的值一般有两种方法:
一是直接将鼠标移到要查看的变量上方查看。
如图2-8所示,二是选择摸个变量后,点击鼠标右键,从弹出的菜单中选择“Addtowatch”,这时AXD左边框Watch窗口,如图2-9所示。
在这个窗口中不仅可以看到变量的值,还可以对变量的值进行修改。
图2-8直接查看变量的值
图2-9Addtowatch
图2-10开启watch窗口
3、分析实验代码,并使用“1.2实验2”中介绍的方法。
单步调试程序,查看各个步骤寄存器和内存中的值,是否和程序逻辑值一致。
提示:
在汇编中定义函数,并在C语言中调用,关键是要搞清楚C语言函数的参数表示如何传入汇编,其返回值又是通过什么返回的。
为了搞明白,函数返回是怎么返回的。
我们可以先设计好cSum函数,使用AXD进行调试,并通过AXD工具栏上的
打开反汇编窗口,参考cSum函数的反汇编结果,就不难写出函数asmsum了。
总结:
通过本节实验内容我们应该掌握汇编与C语言混合编程的基本方法。
在实验步骤中提到了关于C语言中调用汇编函数问题。
大家试验后应该清楚,实验中涉及到的C语言函数的传入参数是通过寄存器传递的,且函数参数中从左到右的参数,依次由寄存器R0、R1、R2….传递的。
并通过是实验代码中cSumargs()的反汇编结果页知道,当参数较多时(一般值超过4个)多出的参数会使用堆栈进行传递。
这同时说明要使用C语言编程,必须事先初始化堆栈
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 试验 指导书