ARM实验.docx
《ARM实验.docx》由会员分享,可在线阅读,更多相关《ARM实验.docx(9页珍藏版)》请在冰豆网上搜索。
ARM实验
汇编与C语言的相互调用
一.实验目的阅读EmbestArmEduKitII启动代码,观察处理器启动过程;学会使用EmbestIDE辅助信息窗口来分析判断调试过程和结果;
二.实验设备硬件:
PC机。
软件:
EmbestIDEPro2004集成开发环境,Windows98/2000/NT/XP。
三.实验内容使用汇编完成一个随机数产生函数,通过C语言调用该函数,产生一系列随机数,存放到数组里面。
四.实验原理1.ARM过程调用ATPCS(ARM),ATPCS是一系列用于规定应用程序之间相互调用的基本规则,这此规则包括:
①支持数据栈限制检查;②支持只读段位置无关(ROPI);③支持可读/写段位置无关(RWPI);④支持ARM程序和Thumb程序的混合使用;⑤处理浮点运算。
使用以上规定的ATPCS规则时,应用程序必须遵守如下:
①程序编写遵守ATPCS②变量传递以中间寄存器和数据栈完成;③汇编器使用-apcs开关选项。
程序只要遵守ATPCS相应规则,就可以使用不同的源代码编写程序。
程序间的相互调用最主要的是解决参数传递问题。
应用程序之间使用中间寄存器及数据栈来传递参数,其中,第一个到第四个参数使用R0-R3,多于四个参数的使用数据栈进行传递。
这样,接收参数的应用程序必须知道参数的个数但是,在应用程序被调用时,一般无从知道所传递参数的个数。
不同语言编写的应用程序在调用时可以自定义参数传递的约定,使用具有一定意义的形式来传递,可以很好地解决参数个数的问题。
常用的方法是把第一个或最后一个参数作为参数个数(包括个数本身)传递给应用程序。
ATPCS中寄存器的对应关系
2.main()函数与__gccmain()当应用程序中包含了main()函数,将会引起对C运行时库的初始化。
该初始化是通过函数__gccmain()实现的,即在main()函数入口处,编译器会首先调用__gccmain()函数,然后才是执行编写的代码。
__gccmain()函数在gcc的标准库里面实现。
当应用程序中没有包含main()函数,将不会引起对C运行时库的初始化。
这时,C运行时库的很多功能在应用程序中是不能使用的。
我们使用main函数作为应用程序的主函数,可以在源代码中加入一个空的__gccmain()函数(用C语言或者汇编语言均可)。
五.实验操作步骤1.考本章其他实验,创建新的工程,工程名为:
explasm;2.按照参考程序,重新编写源代码文件并分别保存为randtest.c,init.s,random.s和ldscript,并把它们加入工程里面;3.参照其他基础实验操作,按照编译→汇编器配置→链接器配置→调试器配置设置新工程,并编译、链接工程,如图3-14所示;4.下载调试文件,打开memory/register/watch/variable/callstack窗口,单步执行程序。
通过以上窗口,跟踪程序运行,观察分析运行结果,通过实验学会使用EmbestIDE进行应用程序的开发与调试;六.实验源代码1.randtest.c参考源代码:
/***********************
*File:
randtest.c
*Author:
embest
*Desc:
Randomnumbergeneratordemoprogram
*Callsassemblerfunction'randomnumber'definedinrandom.s
*History:
y.y.wang2005.2.24
**********************/
/*-------------------------externfunction----------------*/
externunsignedintrandomnumber(void);
/************************name:
Main
*func:
ccodeentry
*para:
none
*ret:
none
*modify:
*comment:
***********************/
intMain()
{
unsignedinti,nTemp;
unsignedintunRandom[10];
for(i=0;i<10;i++){
nTemp=randomnumber();unRandom[i]=nTemp;}
return(0);
}2.init.s参考源代码:
#********************
*File:
init.s
*Author:
embest*
*Desc:
Cstartupcodes.Configurememory,InitializeISR,stacks,*
*initializeC-variables*
*Fillzerosintozero-initializedC-variables*
*History:
*
#*********************
/*-----------------globalsymboldefine--------------------*/
.global_start.global__gccmain
/*-------------------code---------------------*/
.text
_start:
#Setinterrupt/exceptionvectorsbReset_Handler
Undefined_Handler:
bUndefined_Handler
SWI_Handler:
bSWI_Handler
Prefetch_Handler:
bPrefetch_Handler
Abort_Handler:
bAbort_Handlernop/*Reservedvector*/
IRQ_Handler:
bIRQ_Handler
FIQ_Handler:
bFIQ_Handler
Reset_Handler:
ldrsp,=0x00002000
#/*************************
#BranchonCcodeMainfunction(withinterworking)*
#BranchmustbeperformedbyaninterworkingcallaseitheranARMorThumb*
#mainCfunctionmustbesupported.Thismakesthecodenotposition-*
#independant.ABranchwithlinkwouldgenerateerrors*
#/**************************
.externMainldrr0,=Main
movlr,pcbxr0
#/*************************
#Loopforever*
#Endofapplication.Normally,neveroccur.*
#CouldjumponSoftwareReset(B0x0).*
#/************************End:
bEnd
__gccmain:
movpc,lr
.end
C语言程序实验
一.实验目的1..学会使用EmbestIDE编写简单的C语言程序并进行调试;2.学会编写和使用命令脚本文件;3.掌握通过memory/register/watch/variable窗口分析判断运行结果。
二.实验设备硬件:
PC机。
软件:
EmbestIDEPro2004集成开发环境,Windows98/2000/NT/XP。
三.实验内容利用命令脚本初始化栈指针,并使用c语言完成延时函数。
四.实验原理1.命令脚本文件用户在集成环境与目标板连接时、软件调试过程中以及复位目标板后,有时需要完成环境自动完成一些特定的功能,比如复位目标板、清除看门狗、屏蔽中断寄存器、存储区映射等,这些特定的功能可以通过执行一组命令序列完成,保存一组命令序列的文本文件称为命令脚本文件(EmbestIDE使用.cs作为命令脚本文件扩展名)。
命令脚本文件中各行以半角格式的“;”号开始作为注释内容,分号前是一条命令。
凡是可以在调试命令窗口使用的命令,都可以在脚本文件中使用,包括执行脚本文件命令SCRIPT”。
调试命令及详细参考请参照EmbestIDE所带的电子文档UserGuide.chm中“调试命令列表”一节。
命令脚本文件执行时按照命令在脚本文件中排列的先后顺序自动连续地执行。
2.命令脚本文件的执行方法有两种执行方法:
在命令输入窗口,输入:
script脚本文件名,在项目设置对话框调试属性页指定连接后的行为(Actionafterconnected),此时,可选择命令脚本文件(Commandscript),并在编辑框中设定命令脚本文件名,则在IDE与目标系统连接后首先自动执行指定的脚本文件。
3.常用命令介绍1)GO–执行程序语法:
go说明:
从当前PC执行目标程序。
参数:
无选项:
无2)MEMWRITE–存储区写语法:
memwrite[–e]地址数值说明:
向存储区指定地址写入数值。
参数:
地址要写入数值的存储区地址选项:
-e大印第安方式写入3)REFRESH–刷新窗口语法:
refresh说明:
刷新所有窗口命令,调试命令执行后,各窗口相关内容并不更新,用户可以调用本命令刷新界面各窗口保持与实际内容一致。
参数:
无选项:
无
4)REGWRITE–寄存器写语法:
regwrite寄存器名称寄存器值说明:
写寄存器参数:
寄存器名称待写入数值的寄存器名称
5)RESET–复位目标设备
语法:
reset说明:
复位目标设备
参数:
无选项:
无
6)STOP–停止执行程序语法:
stop说明:
停止目标板运行参数:
无
选项:
无
五.实验操作步骤1.参考前面实验创建新的工程(工程名为C1);2.按照参考程序,编写源文件C1.c和C1.cs,并把它们加入工程里面。
C1.cs加在工程根目录即可。
3.参考前面例子进行标准的设置,其中需要注意的是,在调试Debug对话框设置的时候,增加连接后自动执行脚本文件:
4.参考前面实验步骤进行编译;5.下载打开Memory/Register/Watch/Variable窗口,单步执行,通过memory/register/watch/variable窗口分析判断结果,在watch框中输入要观察变量I和变量J的值,并记录下来。
特别注意在variable窗口观察变量I的变化并记录下来;6.结合实验内容和相关资料,观察程序运行,通过实验;7.理解和掌握实验后,完成实验练习题。
六.实验源代码1.c1.c参考源代码:
/*********************************File:
c1.c
*Author:
embest
*Desc:
clanguageexample1
*History:
******************************/
/*---------------functiondeclare---------------------*/
voiddelay(intnTime);
/*************************
*name:
_start
*func:
entrypoint
*para:
none
*ret:
none
*modify:
*comment:
***********************/
_start(){inti=5;for(;;)
{delay(i);}
}
/**************************
*name:
delay
*func:
delaysometime
*para:
nTime--input
*ret:
none
*modify:
*comment:
**********************/
voiddelay(nTime)
{inti,j=0;for(i=0;i}
2.C1.cs参考源代码
stop;stoptargetboard
regwritesp0x1000;initializethesp,sp=0x1000
ARM汇编指令实验
一.实验目的1.初步学会使用EmbestIDEforARM开发环境及ARM软件模拟器;2.通过实验掌握简单ARM汇编指令的使用方法。
二.实验设备硬件:
PC机软件:
EmbestIDEPro2004集成开发环境,Windows98/2000/NT/XP/win7。
三.实验内容1.熟悉开发环境的使用并使用ldr/str,mov等指令访问寄存器或存储单元。
2.使用add/sub/lsl/lsr/and/orr等指令,完成基本数学/逻辑运算。
四.实验原理ARM处理器共有37个寄存器:
31个通用寄存器,包括程序计数器(PC)。
这些寄存器都是32位的。
6个状态寄存器。
这些寄存器也是32位的,但是只是使用了其中的12位。
<1>ARM通用寄存器(R0~R15)可分为3类
1)不分组寄存器R0~R7;
在所有处理器模式下,它们每一个都访问一样的32位寄存器。
它们是真正的通用寄存器,没有体系结构所隐含的特殊用途。
2)分组寄存器R8~R14
它们每一个访问的物理寄存器取决于当前的处理器模式。
若要访问特定的物理寄存器而不依赖当前的处理器模式,则要使用规定的名字。
寄存器R8~R12各有两组物理寄存器:
一组为FIQ模式,另一组为除了FIQ以外的所有模式。
寄存器R8~R12没有任何指定的特殊用途。
只是使用R8~R14来简单地处理
中断。
寄存器R13,R14各有6个分组的物理寄存器。
1个用于用户模式和系统模式,其它5个分别用于5种异常模式。
寄存器R13通常用做堆栈指针,称为SP。
每种异常模式都自己的R13。
寄存器R14用作子程序链接寄存器,也称为LR。
3)程序计数器R15寄存器R15用做程序计数器(PC)。
在本实验中,我们认为ARM核工作在用户模式,R0~R15可用。
<2>ARM存储器格式ARM体系结构将存储器看作是从零地址开始的字节的线性组合。
eg:
字节0到字节3放置第一个字(WORD),字节4到字节7存储第二个字,依此类推。
ARM体系结构可以用两种方法存储字数据,分别称为大端格式和小端格式。
1)大端格式这种格式中,字数据的高位字节存储在低地址中,而字数据的低位字节则存放在高地址中
2)小端格式这种格式中,字数据的高位字节存储在高地址中,而字数据的低位字节则存放在低地址中
<3>GNU基础知识EmbestIDE集成了GNU汇编器as,编译器gcc,链接器ld。
1)程序默认入口点为“_start”,代码段默认起始地址为0x80002)as常用伪操作符.equ.equ伪操作为数字常量、基于寄存器的值和程序中的标号定义一个字符名称。
语法格式
.equsymbol,expr(expr为基于寄存器的地址值、程序中的标号,32位的地址常量或者32位的常量。
Symbol为.equ伪操作为expr定义的字符名称。
.global及.globl.global声明一个符号可以被其他文件引用。
相当于声明了一个全局变量,.globl与.global相同。
语法格式.globalsymbolsymbol为声明的符号的名称。
它是区分大小写的。
.text.text伪操作将操作符开始的代码编译到代码段或代码段子段(subsection)语法格式.text{subsection}.end标记汇编文件的结束行,即标号后的代码不作处理。
语法格式.end
<4>EmbestIDE开发环境的相关知识
五.实验操作步骤1.实验A1)新建工程:
运行EmbestIDE集成开发环境,选择菜单项File→NewWorkspace,系统弹出
一个对话框,点击OK按钮,将创建一个新工程,并同时创建一个与工程名相同的工作区。
此时在工作区窗口将打开该工作区和工程。
2)建立源文件:
点击菜单项File→New,系统弹出一个新的、没有标题的文本编辑窗,编辑输入源文件代码。
编辑完后,保存文件asm1_a.s。
3)添加源文件:
选择Project→AddToProject→Files命令,或单击工程管理窗口中的相应右键菜单命令,弹出文件选择对话框,在工程目录下选择刚才建立的源文件asm1_a.s。
4)基本配置:
选择菜单项Project→Settings…或快捷键Alt+F7,弹出工程设置对话框。
在工程设置对话框中,选择Processor设置对话框,进行目标板所用处理器的配置。
5)生成目标代码:
选择菜单项Build→Buildasm_a或快捷键F7,生成目标代码。
6)调试设置:
选择菜单项Project→Settings…或快捷键Alt+F7,弹出工程设置对话框。
在工程设置对话框中,选择Remote设置对话框。
对调试设备模块进行设置。
选择Debug设置对话框,进行调试模块配置。
(b)下载相关配置
注意:
Symbolfile与Downloadfile设置应该相同,用户可以从Linker页面拷贝系统默认的输出文件配置;且该实验输入下载地址为0x8000,即为AS默认的代码段起始地址。
由于汇编和链接选项在本实验中没有进行配置,完全使用其默认选项,所以,代码段是从0x8000开始的,下载地址应该与它保持一致。
7)选择Debug菜单RemoteConnect进行连接软件仿真器,执行Download命令下载程序,并打开寄存器窗口。
打开memory窗口,观察地址0x8000~0x801f的内容,与地址0xff0~0xfff的内容。
8)单步执行程序并观察和记录寄存器与memory的值变化。
9)结合实验内容和相关资料,观察程序运行,通过实验加深理解ARM指令的使用。
10)理解和掌握实验后,完成实验练习题。
2.实验B1)在工作区窗口工作区名称上击右键鼠标,“AddNewProjecttoWorkspace…”。
2)参照实验A及相应的实验参考程序,建立工程asm1_b。
3)参照实验A的步骤完成目标代码的生成与调试。
4)理解和掌握实验后,完成实验练习题。
六.实验源代码
实验A
/******************************************************************/
#NAME:
asm1_a.s#Author:
Embest
#Desc:
ARMinstructionexamples#History:
shw.He2005.02.22/*******************************************************************/
/*constantdefine*/
.equx,45/*x=45*/.equy,64/*y=64*/.equstack_top,0x1000/*definethetopaddressforstack*/.global_start
/*-------------codestart----------*/
.text_start:
movsp,#stack_topmovr0,#x
strr0,[sp]
movr0,#y
ldrr1,[sp]
addr0,r0,r1
strr0,[sp]stop:
bstop
.end
实验B:
/******************************/
#NAME:
asm1_a.s
#Author:
Embest
#Desc:
ARMinstructionexamples
#History:
shw.He2005.02.22
/****************************/
/*-----------------constantdefine----------------------------*/
.equx,45
.equy,64
.equz,87
.equstack_top,0x1000.global_start
/*----------------code-------------*/
.text
_start:
movr0,#x
movr0,r0,lsl#8movr1,#yaddr2,r0,r1,lsr#1movsp,#0x1000strr2,[sp]movr0,#zmovr1,#y
addr2,r0,r1,lsr#1ldrr0,[sp]
movr1,#0x01orrr0,r0,r1movr1,R2addr2,r0,r1,lsr#1stop:
bstop
.end
实验总结
在了解了基础知识之后,我开始进行上机操作,当然,其中遇到很多的难题,很多东西都是第一次接触,又没有别人在旁边指导操作,完全凭借自己去摸索练习。
其中的困难可想而知。
然而坚持就是胜利,牙一咬眼一闭坚持做下去,而通过本次实验,我感觉收获还是蛮多的。
可能我对于嵌入式的知识学习的还是不太多,但是这之外的东西收获颇丰。
它让我学会了如何通过自己的努力去认知一个新事物,更重要的是端正自己的学习态度,只有真正下功夫去学习,才能有收获,正所谓“一份耕耘,一份收获。
”没有付出,何谈回报呢?
再者,通过本次实验,我也学会了如何去分析问题,如