2022年实验六ARM数据加载与存储指令实验 .pdf
实验六ARM 数据加载与存储指令实验一、实验目的1、熟悉教学ADS 集成开发环境,2、懂得各种ARM 寻址方式,并能自己动手写一些简单小程序。3、能够运行程序并进行简单分析二、实验环境硬件: PC 机一台。软件: Windows98/XP/2000 系统, ADS 集成开发环境。三、预备知识LDR 和 STR用于字和无符号字节指令格式:LDR/STRcondT Rd, LDR/STRcondBT Rd, 指令 LDRcondT Rd, , 加载指定地址的字数据到Rd 中;指令 STRcondT Rd,存储 Rd 中的字数据到指定的地址单元中。LDRcondBT Rd,指令加载指定地址的字节数据到Rd 的的最低字节中 (Rd 的高 24 位清零);STRcondBT Rd,指令存储Rd 中的最低字节数据到指定的地址单元中。T 为可选后缀,若有T,那么即使处理器是在特权模式下,存储系统也将访问看成处理器是在用户模式下,T 在用户模式下无效,不能与前索引偏移一起使用T。地址部分可用的形式有4 种:零偏移 (zero offset) Rn ,Rn 的值作为传送数据的地址。如:LDR R0,R1 ;前索引偏移 (pre-indexed offset) Rn , Flexoffset! 在数据传送之前, 将偏移量 Flexoffset 加到 Rn 中。其结果作为传送数据的存储器地址。若使用后缀“!” ,则结果写回到Rn 中,35 且 Rn 不允许是R15,如:LDRB R0,R1,#8 LDR R0,R1,#8 !程序相对偏移(program relative) label ( label 必须是在当前指令的土4KB 范围内 ) 。程序相对偏移是前索引形式的另一种版本。从 PC 计算偏移量, 并将 PC 作为 Rn 生成前索引指令,不能使用后缀“!” ,如:LDR R0,place ;place 地址装入R0 后索引偏移 (post-indexed offset) Rn ,Flexoffset。在数据传送后,将偏移量Flexoffset 加到 Rn 中,结果写回到Rn, Rn 不允许是 R15,如:LDR R0,R1,R2,LSL 2 ;将存储器地址为R1 的字数据读入寄存器R0,并将新地址R1R24 写入 R1。四、实验内容(1)分析单寄存器操作,并学会简化给出的代码同时实现相同的效果;(2)使用多寄存器操作指令:LDMIA 、STMIA 实验上面单寄存器操作所实现的功能;(3)给出实验所提供的堆栈操作的代码执行过程的详细分析;(4)根据给出的用C 写成的数码管显示,用相应的汇编实现同样功能。五、实验程序(1)单寄存器操作代码如下:AREA Lab1, CODE ENTRY 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 1 页,共 5 页 - - - - - - - - - START ADR R1,SRC ADR R2,DST COPY LDR R0,R1 STR R0,R2 ADD R1,R1,#0 x4 ADD R2,R2,#0 x4 LDR R0,R1 STR R0,R2 ADD R1,R1,#0 x4 ADD R2,R2,#0 x4 LDR R0,R1 STR R0,R2 STOP B STOP SRC DCB one small! ALIGN DST DCB three big! END 对以上这段用单寄存器操作实现的代码的分析:功能实现的就是将“one small!”穿送到“ three big!”所在的内存空间,不过因为只是通过单寄存器来实现传送操作的,显得有些繁琐,这里是加一次数据,在分别给2 个寄存器加地址,一共写了3 段相同的代码才完成,下面我对这段不断重复的代码:LDR R0,R1 ;STR R0,R2 ;ADD R1,R1,#0 x4 ;ADD R2,R2,#0 x4 加以修改,使用两条指令实现与上面代码相同的功能操作:简化如下:指令一:LDR R0,R1 ,#0 x4;指令二: STR R0,R2 ,#0 x4。(2)多寄存器操作实验尽管前一个实验在完成后,对繁琐的蛋寄存器操作加以简化,提高了一点效率,但是这是在寄存器之间传递数据,那么就有了更加高效的方法来实现相同的功能。那就是使用多寄存器操作指令: LDMIA 、STMIA 实验上面代码的功能。下面我给出了给出完整的代码实现:AREA Lab1, CODE ENTRY START ADR R1,SRC ADR R2,DST COPY LDMIA R1!,R3,R4,R5 STMIA R2!,R3,R4,R5 STOP B STOP SRC DCB one small! ALIGN DST DCB three big! END 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 2 页,共 5 页 - - - - - - - - - 对以上这段用多寄存器实现数据的传递,要说的是只有在寄存器直接的数据传递才能使用多寄存器操作, 在这里 SRC,DST 分别代码2 组数据的所在的首地址,SRC 将 “one small! ”地址赋值给了寄存器R1,DST 将“three big! ”地址赋值给了寄存器R2,然后通过多寄存器操作“ LDMIA R1!,R3,R4,R5”将“ one small! ”暂时存放在寄存器R3,R4,R5 中,在通过指令“ STMIA R2!,R3,R4,R5 ”将暂存的数据传给DST 所代表的地址内存中讲原有的数据“ three big! ”覆盖。(3)堆栈操作实验AREA Lab2,CODE ENTRY START LDR SP,=NUM LDMFD SP!,R0-R4 ADD R4,R0,R1 ADD R4,R4,R2 ADD R4,R4,R3 MOV R4,R4,LSR #2 STR R4,SP STOP B STOP AREA Dblock,DATA NUM DCD 0 x12,0 x34,0 x56,0 x78 END 给出上面代码的详细执行过程:这段堆栈操作实现的是将内存中的原有的的4 个数据相加,再逻辑右移2 位并将最后的结果存入到与之相邻的后一个存储空间。具体分析如下:NUM 代表这组数的内存首地址,因为是堆栈操作说有用到sp,将 NUM 所代表的地址送至sp 中,即sp=0 x8024,然后执行出栈操作,遵循高地址的数传给编号打的寄存器,这样R0=0 x12,R1=0 x34,R2=0 x56,R3=0 x78, 在出栈的同时, sp 的指向也随之变化sp=0 x8038。然后几个简单的加操作件内存中的的那组数据相加,再将逻辑右移2 位后的值0 x45 传入 sp 现在所指向的内存空间。(4)数码管操作实验使用汇编语言实验下面C 语言代码的功能:*/ /*文件名称:LEDSEG7.C */ /*实验现象:数码管依次显示出0、1,2、 ,9、a、b、 C、d、E、F */ /*/ #define U8 unsigned char unsigned char seg7table16 = /* 0 1 2 3 4 5 6 7*/ 0 xc0, 0 xf9, 0 xa4, 0 xb0, 0 x99, 0 x92, 0 x82, 0 xf8, /* 8 9 A B C D E F*/ 0 x80, 0 x90, 0 x88, 0 x83, 0 xc6, 0 xa1, 0 x86, 0 x8e, ; 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 3 页,共 5 页 - - - - - - - - - void Delay(int time); /*/ /* 函数说明: JXARM9-2410 7段构共阳数码管测试*/ /* 功能描述 : 依次在 7 段数码管上显示0123456789ABCDEF */ /* 返回代码 : 无*/ /* 参数说明 : 无*/ /*/ void Main(void) int i; *(U8*) 0 x10000006) = 0 x00; for( ; ; ) /* 数码管从0 到 F 依次将字符显示出来*/ for(i=0;i=0 x0;i-) /* 查表并输出数据*/ *(U8*) 0 x10000004) = seg7tablei; Delay (100000); /*/ /* Function name : 循环延时子程序*/ /* Description : 循环time 次*/ /* Return type : void */ /* Argument : 循环延时计数器*/ /*/ void Delay(int time) int i; int delayLoopCount=1000; for(;time0;time-); for(i=0;idelayLoopCount;i+); 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 4 页,共 5 页 - - - - - - - - - 实现相同功能的汇编程序如下:LDR R0 , =#0 x10000006 LDR R1 , =#0 x10000004 MOV R0 ,#0X00 LDR R2 , =NUM START LDR R1 ,R2 !MOV r7 ,#0XFF DELAY NUM DCD 0 xc0, 0 xf9, 0 xa4, 0 xb0, 0 x99, 0 x92, 0 x82, 0 xf8, 0 x80, 0 x90, 0 x88, 0 x83, 0 xc6, 0 xa1, 0 x86, 0 x8e, 六、实验总结通过本次实验,我对ADS 开发环境的使用进一步熟练,在编写程序的过程中加深了对相关汇编指令的理解,对单字节传送指令的运用更加得心应手,我学到了很多, 最重要的是在这次实验中纠正了我犯的一个错误让我牢记:批数据传送指令STM 和 LDM 只能用在寄存器之间的数据传送,但是在讲c 写的数码显示的代码改成汇编是遇到了很大的困难。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 5 页,共 5 页 - - - - - - - - -