ARM实验汇编代码.

合集下载

arm汇编编程(示例)

arm汇编编程(示例)

一、arm的认知及基本概念(一).arm的基本概念1.什么是armarm是一家英国电子公司的名字,全名是Advanced RISC Machine这家企业设计了大量高性能、廉价、耗能低的RISC(精简指令集)处理器,ARM公司只设计芯片而不生产,它将技术授权给世界上许多公司和厂商。

目前采用arm技术知识产权内核的微处理器,即通常所说的arm微处理器所以arm也是对一类微处理器的通称。

arm指令集体系版本号(软件)为V1 ~ V7目前V1 ~ V3已很少见。

从V4版不再与以前的版本兼容。

arm的CPU系列(硬件)主要有ARM7 ~ ARM112.典型的嵌入式处理器arm 占市场79.5%ARMmips 占市场13.9%MIPSmicroSPARC 占市场3.1%SUNPowerPc 占市场2.8%IBM其它占市场0.8%3. arm的应用范围:工业控制:如机床、自动控制等无线通信:如手机网络应用:如电子产品:如音视频播放噐、机顶盒、游戏机、数码相机、打印机其它各领域:如军事、医疗、机器人、xx等4.计算机体系结构见图:xx.xx计算机体系图xx.xx体系结构处理器使用同一个存储器,经由同一个总线传输完成一条指令需要3个步骤:即取指令->指令译码->执行指令指令和数据共享同一总线的结构哈佛体系结构将程序指令存储和数据存储分开中央处理器首先到程序指令存储器中读取程序指令。

解码后到数据地址,再到相应的数据存储器读取数据,然后执行指令程序指令存储与数据存储分开,可以使指令和数据有不同的数据宽度。

5.复杂指令集与精简指令集CISC 复杂指令集:采用冯.诺依曼体系结构。

数据线和指令线分时复用(只能通过一辆车)。

存储器操作指令多汇编程序相对简单指令结束后响应中断CPU电路丰富面积大功耗大RISC 精简指令集:采用哈佛体系结构。

数据线和指令线分离(同时能通过多辆车)。

对存储器操作有限汇编程序占空间大在适当地方响应中断CPU电路较少体积小功耗低ARM采用RISC精简指令集Thumb是ARM体系结构中一种16位的指令集。

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

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

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

二、实验原理:启动程序要完成的任务包括:硬件初始化,系统存储系统的配置,复制二级中断向量表。

启动程序过程●系统硬件初始化系统上电或复位后,程序从位于地址0x0的Reset Exception Vector处开始执行,因此需要在这里放置Bootloader的第一条指令:b ResetHandler,跳转到标号为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 服务程序是如何进入的。

02实验二 ARM汇编语言程序设计

02实验二 ARM汇编语言程序设计

实验二 ARM汇编语言程序设计一、实验目的1.了解ARM汇编语言的基本框架,学会使用ARM的汇编语言编程2.掌握ARM汇编指令二、实验设备1. EL-ARM-830教学实验箱,PentiumII以上的PC机,仿真器电缆。

2. PC操作系统WIN98或WIN2000或WINXP, ADS1.2集成开发环境,仿真器驱动程序。

三、汇编语言简介1.ARM汇编的一些简要的书写规范ARM汇编中,所有标号必须在一行的顶格书写,其后面不要添加“:”,而所有指令均不能顶格书写。

ARM汇编对标识符的大小写敏感,书写标号及指令时字母大小写要一致。

在ARM汇编中,ARM指令、伪指令、寄存器名等可以全部大写或者全部小写,但不要大小写混合使用。

注释使用“;”号,注释的内容由“;”号起到此行结束,注释可以在一行的顶格书写。

详细的汇编语句及规范请参照ARM汇编的相关书籍、文档。

2. ARM汇编语言程序的基本结构在ARM汇编语言程序中,是以程序段为单位来组织代码。

段是相对独立的指令或数据序列,具有特定的名称。

段可以分为代码段的和数据段,代码段的内容为执行代码,数据段存放代码运行时所需的数据。

一个汇编程序至少应该有一个代码段,当程序较长时,可以分割为多个代码段和数据段,多个段在程序编译链接时最终形成一个可执行文件。

可执行映像文件通常由以下几部分构成:◆一个或多个代码段,代码段为只读属性。

◆零个或多个包含初始化数据的数据段,数据段的属性为可读写。

◆零个或多个不包含初始化数据的数据段,数据段的属性为可读写。

链接器根据系统默认或用户设定的规则,将各个段安排在存储器中的相应位置。

源程序中段之间的相邻关系与执行的映象文件中的段之间的相邻关系不一定相同。

3. 简单的小例子下面是一个代码段的小例子AREA Init,CODE,READONLYENTRYLDR R0, =0x3FF5000LDR R1, 0x0fSTR R1, [R0]LDR R0, =0x3F50008LDR R1, 0x1STR R1, [R0]……END在汇编程序中,用AREA指令定义一个段,并说明定义段的相关属性,本例中定义了一个名为Init的代码段,属性为只读。

ARM汇编实验报告

ARM汇编实验报告

《嵌入式系统原理与应用B》课程实验报告ARM汇编语言编程与调试要求完成的主要实验1、给出的数据中寻找最大、最小数问题2、两种求和运算的编程与调试3、第四章作业第9题4、排序冒泡程序的调试与总结5、第四章作业第11题说明:标注完成的实验,未完成的给予说明专业名称:通信工程班级:1510班学生姓名:石龙飞学号(8位):03151307指导教师:刘钊远给出的数据中寻找最大、最小数问题一、实验目的1、学习汇编软件的安装、使用,熟悉汇编环境。

2、学会使用汇编软件,如何新建一个工程,如何书写源代码,如何进行链接、编译,以及如何调试。

3、尝试一些简单的指令,学会用汇编指令写一些简单的程序。

二、实验内容编写一个汇编程序,要求在给定的一组数中找到最大数和最小数。

三、实验主要步骤1、首先建立一个工程2、再新建.s的源文件,添加到工程中3、编写源代码,这里主要是实现在一组数中寻找最大数和最小数,最后将找到的两个数放到相应的寄存器中。

4、进行链接编译,看看有没有语法的错误,如果有错误编译器会提示错误的类型以及在哪里出错。

5、进行debug调试,查找代码中的逻辑错误,若无逻辑错误,可在debug界面查看运行结果,其最需要的关注的几个地方是菜单栏的一组运行按钮、源码执行的步骤以及断点、左边的寄存器状态、下方的存储器状态,将这些综合起来,就可以很明确的回到程序如何运行,运行结果如何。

四、实验代码五、实验总结与分析1、实验结果分析其中用红色方框框起来的是最后程序运行的结果,也就是在R3中保存了最小数在R2中保存了最大数,完成了实验要求。

2、在用汇编语言编程之前首先要看看有没有汇编软件ADS、没有的话需要安装,Windows XP安装起来比较简单,只需要点击setup,一直点击写一部就可以,但是如果是Windows 7或者更高版本的话就需要在setup的属性里点击兼容Windows XP,运行时以管理员身份运行才能正确进行安装。

arm汇编编程(示例)

arm汇编编程(示例)
ARM采用RISC精简指令集
Thumb是ARM体系结构中一种16位的指令集。
从ARMv4T之后,的ARM处理器有一种16-bit指令模式,叫做Thumb,较短的指令码提供整体更佳的编码密度,更有效地使用有限的内存带宽。所有ARM9和后来的家族,包括XScale都纳入了Thumb技术。
即ARM有两种指令集:RISC、Thumb
(3)流水线对pc值的影响
CPU内部的组成部分:指令寄存器,指令译码器,指令执行单元(包括ALU和通用寄存器组)
CPU执行指令的步骤:取指->译码->执行
取指:将指令从内存或指令cache中取入指令寄存器
译码:指令译码器对指令寄存器中的指令进行译码操作,辨识add,或是sub等操作
执行:指令执行单元根据译码的结果进行运算并保存结果
2.主板
电源
并口线
复位
RTC电源
RS232电平转换DB9插座
音频IIS,AC97
按键、PS/2与IC接口
数码管
触摸屏
以太网卡
主USB HUB 1转4
3.寄存器
见图:ARM模块和内核框图
寄存器是中央处理器内的组成部份。
寄存器是有限存贮容量的高速存贮部件,用来暂存指令、数据和位址。在中央处理器的控制部件中,包含的寄存器有指令寄存器(IR)和程序计数器(PC)。在中央处理器的算术及逻辑部件中,包含的寄存器有累加器(ACC)。
处理器使用同一个存储器,经由同一个总线传输
完成一条指令需要3个步骤:即取指令->指令译码->执行指令
指令和数据共享同一总线的结构
哈佛体系结构
将程序指令存储和数据存储分开
中央处理器首先到程序指令存储器中读取程序指令。解码后到数据地址,再到相应的数据存储器读取数据,然后执行指令

ARM中常用的汇编指令

ARM中常用的汇编指令

ARM 中常⽤的汇编指令1 处理器内部数据传输指令MSR & MRS⽤于在状态寄存器和通⽤寄存器之间传送数据MRS: 状态寄存器到通⽤寄存器的传送指令。

({R0-R12} <== CPSR,SPSR)MSR: 通⽤寄存器到状态寄存器的传送指令。

MRS:(CPSR,SPSR==>{R0-R12})MOVMOV 指令⽤于将数据从⼀个寄存器拷贝到另外⼀个寄存器,或者将⼀个⽴即数传递到寄存器⾥⾯,使⽤⽰例如下:2 存储器访问指令ARM 不能直接访问存储器,⽐如 RAM 中的数据,⼀般先将要配置的值写⼊到 Rx(x=0~12)寄存器中,然后借助存储器访问指令将 Rx 中的数据写⼊到寄存器中。

指令描述LDR Rd, [Rn , #offset]从存储器 Rn+offset 的位置读取数据存放到 Rd 中STR Rd, [Rn, #offset]将 Rd 中的数据写⼊到存储器中的 Rn+offset 位置LDR 指令LDR 主要⽤于从存储加载数据到寄存器 Rx 中, LDR 也可以将⼀个⽴即数加载到寄存器 Rx中, LDR 加载⽴即数的时候要使⽤“=”,⽽不是“#”。

在嵌⼊式开发中, LDR 最常⽤的就是读取 CPU 的寄存器值。

上述代码就是读取寄存器中的值,读取到的寄存器值保存在 R1 寄存器中,上⾯代码中 offset 是 0,也就是没有⽤到 offset。

STR 指令LDR 是从存储器读取数据, STR 就是将数据写⼊到存储器中LDR 和 STR 都是按照字进⾏读取和写⼊的,也就是操作的 32 位数据,如果要按照字节、半字进⾏操作的话可以在指令“LDR”后⾯加上B 或 H,⽐如按字节操作的指令就是 LDRB 和STRB,按半字操作的指令就是 LDRH 和 STRH。

MRS R0, CPSR @ 将特殊寄存器 CPSR ⾥⾯的数据传递给 R0,即R0=CPSR1MSR CPSR , R0 @ 将 R0 中的数据复制到 CPSR 中,即 CPSR =R01MOV R0, R1 @ 将寄存器 R1 中的数据传递给 R0,即 R0=R1MOV R0, #0X12 @ 将⽴即数 0X12 传递给 R0 寄存器,即 R0=0X1212LDR R0, =0X0209C004 @ 将寄存器地址 0X0209C004 加载到 R0 中,即 R0=0X0209C004LDR R1, [R0] @ 读取地址 0X0209C004 中的数据到 R1 寄存器中12LDR R0, =0X0209C004 @ 将寄存器地址 0X0209C004 加载到 R0 中,即 R0=0X0209C004LDR R1, =0X20000002 @ R1 保存要写⼊到寄存器的值,即R1=0X20000002STR R1, [R0] @ 将 R1 中的值写⼊到 R0 中所保存的地址中1233 压栈和出栈指令我们通常会在 A 函数中调⽤ B 函数,当 B 函数执⾏完以后再回到 A 函数继续执⾏。

ARM汇编指令集

ARM汇编指令集

ARM汇编指令集1 跳转指令1.1 跳转指令B:B LABLE ;跳转到标号LABEL处B 0X1111 ;跳转到绝对地址0X1111处1.2 带连接的跳转指令BL:START …BL NEXT ;跳转到标号NEXT处,同时保存当前PC到R14中…;返回地址…NEXT…;子程序入口MOV PC,R14 ;返回1.3 带状态切换的跳转指令BX:MOV R0, #0X0201BX R0 ;程序跳转到0x0200处,微处理器切换到Thumb状态(地址必须是4的倍数,否则产生不可预知的后果)2算术运算指令2.1不带进位加法指令ADDADD R0, R1, R2 ;R0←(R1)+(R2)ADD R0, R1, #112 ;R0←(R1)+ 112ADD R0, R1, R2, LSL #1 ;R0←(R1)+(R2<<1) ;将R2中的值左移1位,再与R1值相加,结果送R02.2带进位加法指令ADCADDS R0, R3, R6 ;加最低位字节,不带进位ADCS R1, R4, R7 ;加第二个字,带进位ADCS R2, R5,R8 ;加第三个字,带进位;三句话实现了96bit加法运算,由于ARM寄存器宽度只有32bit所以分三次相加2.3 不带进位减法指令SUB ;S—进位标志SUB R0, R1, R2 ;R0←(R1)- (R2)SUB R0, R1, #112 ;R0←(R1)- 112SUB R0, R1 ,R2 LSL#1 ;R0←(R1)- (R2<<1)2.4 带进位减法指令SBCSUBS R0, R3, R6 ;减最低位字节,不带进位SBCS R1, R4, R7 ;减第二个字,带进位SBCS R2, R5, R8 ;减第三个字,带进位;三句话实现了96bit减法运算,由于ARM寄存器宽度只有32bit所以分三次相减2.5 不带进位逆向减法指令RSBRSB R0, R1, R2 ;R0←(R2)- (R1)RSB R0, R1, #112 ;R0←112- (R1)RSB R0, R1, R2, LSL#1 ;R0←(R2<<1)-R12.6 带进位逆向减法指令RSCRSBS R0, R6, R3 ;减最低字节的字,不带进位RSCS R1, R7, R4 ;减第二个字,带进位RSCS R2, R8, R5 ;减第三个字,带进位;三句话实现了96bit减法运算,由于ARM寄存器宽度只有32bit所以分三次相减2.732位乘法指令MULMUL R0, R1, R2 ;R0←(R1) X(R2)MULS R0, R1, R2 ;R0←(R1) X(R2) ;更新CPSR标志位2.8乘-累加指令MLAMLA R0, R1, R2, R3 ;R0←(R1) X(R2)+(R3)MLAS R0, R1, R2, R3 ;R0←(R1) X(R2)+(R3) ;更新CPSR标志位2.9 无符号数长乘指令UMULLMOV R5, #0X01MOV R8, #0X02UMULL R0, R1, R5, R8 ;(R1) (R0)←(R5)X(R8);UMULL指令实现64bit无符号数乘法2.10无符号长乘-累加指令 UMLALMOV R0, #0X01MOV R1, #0X02MOV R5, #0X01MOV R8, #0X02UMLAL R0, R1, R5, R8 ;R0←(R0) +(R5)X(R8)低字节;R1←(R1) +(R5) X(R8)高字节;UMLAL 指令为64位无符号乘-累加指令2.11有符号长乘指令SMULLMOV R5, #0X01MOV R8, #0X02SMULL R0, R1, R5, R8 ;(R1) (R0)←(R5)X(R8);SMULL指令实现64bit有符号数乘法2.12 有符号长乘-累加指令 SMLALMOV R0, #0X01MOV R1, #0X02MOV R5, #0X01MOV R8, #0X02SMLAL R0, R1, R5, R8 ;R0←(R0) +(R5)X(R8)低字节;R1←(R1) +(R5) X(R8)高字节; SMLAL 指令为64位有符号乘-累加指令2.13 比较指令 CMPCMP R1, #0X10 ;比较BGT TAG ;R1> #0X10转到TAG标号处……2.14负数比较指令 CMNCMN R0, #1 ;判断R0中的值是否为1的补码,是则置标志位Z为13逻辑运算指令3.1“与”指令 ANDMOV R0, 0XFFAND R0, R0, #3 ;取出R0的最低2bit3.2“或”指令 ORRMOV R0, 0XFFORR R0, R0, #33.3“异或”指令 EORMOV R0, 0XFFEOR R0, R0, #3 ;R0←(R0)^(0X03)3.4位清除指令 BICMOV R0, 0XFFBIC R0, R0, #B11 ;寄存器R0的低2bit被清零3.5测试比较指令 TSTTST R1, #b11 ;测试寄存器R1中的第0位和第1位,更新CPSR中标志位,应用中会在TST指令后加一条跳转指令。

ARM汇编指令实验

ARM汇编指令实验

ARM 汇编指令实验一一. 实验目的1.初步学会使用μVision IDE for ARM 开发环境及ARM 软件模拟器;2.通过实验掌握简单 ARM 汇编指令的使用方法。

二. 实验设备1.硬件:PC 机一台;2.软件:μVision IDE for ARM 集成开发环境,Windows 98/2000/NT/XP。

三. 实验内容1.熟悉开发环境的使用并使用 ldr/str,mov 等指令访问寄存器或存储单元;2.使用 add/sub/lsl/lsr/and/orr 等指令,完成基本算术/逻辑运算。

四. 实验原理ARM 处理器共有37 个寄存器:31 个通用寄存器,包括程序计数器(PC)。

这些寄存器都是32 位的;6 个状态寄存器。

这些寄存器也是32 位的,但是只是使用了其中的12 位。

1. ARM 通用寄存器通用寄存器(R0-R15)可分为三类:1)不分组寄存器 R0~R7不分组寄存器R0~R7 在所有处理器模式下,它们每一个都访问一样的32 位寄存器。

它们是真正的通用寄存器,没有体系结构所隐含的特殊用途。

2)分组寄存器 R8~R14分组寄存器R8~R14 对应的物理寄存器取决于当前的处理器模式。

若要访问特定的物理寄存器而不依赖当前的处理器模式,则要使用规定的名字。

寄存器R8~R12 各有两组物理寄存器:一组为FIQ 模式,另一组为除了FIQ 以外的所有模式。

寄存器R8~R12 没有任何指定的特殊用途,只是在作快速中断处理时使用。

寄存器R13,R14 各对应6 个分组的物理寄存器,1 个用于用户模式和系统模式,其它5 个分别用于5 种异常模式。

寄存器R13 通常用做堆栈指针,称为SP;寄存器R14 用作子程序链接寄存器,也称为LR。

3)程序计数器 PC寄存器R15 用做程序计数器(PC)。

在本实验中,ARM 核工作在用户模式,R0~R15 可用。

2. 存储器格式ARM 体系结构将存储器看作是从零地址开始的字节的线性组合。

ARM总汇编指令列表

ARM总汇编指令列表

目的操作数1 + 操作数2 + !C 目的操作数1 + 操作数2目的操作数1 & 操作数2跳转至目的地, PC目标地址(PC R14,跳转)(PC R14,跳转并切换为thumb)目的操作数1 XOR 操作数2 LDC P3,C4,[R0] ;P3: C4 [R0]register MemeryRegister<存储器地址>目的操作数1 * 操作数2 + 操作数3 目的源操作数Register状态寄存器CPSR或SPSR<域> 操作数结果MODE(2^32),目的操作数1 * 操作数2 目的~(取反) 源操作数目的操作数1 OR 操作数2目的操作数2 - 操作数1目的操作数2 - 操作数1 - !C=64目的L(操作1 * 操作2)L+ 目的L 目的H(操作1 * 操作2)H +目的HSTC P3,C4,[R0] ;P3:C4[R0]Mem Register<存储器地址>Register 目的操作数1 –操作数2ARM汇编伪指令ARM条件码CPSR位[31:24]为条件位域,用f表示;位[23:16]为状态位域,用s表示;位[15:8] 为扩展位域,用x表示;位[7:0] 为控制位域,用c表示;与指令MSR相关关于移位中断向量表APCS寄存器使用约定Load and Store指令LDR R0,[R1] ;将存储器地址为R1的字数据读入寄存器R0。

LDR R0,[R1,R2] ;将存储器地址为R1+R2的字数据读入寄存器R0。

LDR R0,[R1,#8] ;将存储器地址为R1+8的字数据读入寄存器R0。

LDR R0,[R1,R2] !;将存储器地址为R1+R2的字数据读入寄存器R0,并将新地址R1+R2写入R1。

LDR R0,[R1,#8] !;将存储器地址为R1+8的字数据读入寄存器R0,并将新地址 R1+8写入R1。

LDR R0,[R1],R2 ;将存储器地址为R1的字数据读入寄存器R0,并将新地址 R1+R2写入R1。

arm实验代码

arm实验代码

arm实验代码1.寄存器R0和R1中有两个正整数,求这两个数的最大公约数,结果保存在R3中。

AREA TEST, CODE,READONL YENTRYSTARTMOV R0,#3MOV R1,#4MOV R2,#5CMP R0,R1BHI EXIBLS EXTEXICMP R0,R2BHI AXIBLS AXYAXIMOV R3,R0EXTCMP R1,R2BHI AXTBLS AXYAXTMOV R3,R1AXYMOV R3,R2END2.用汇编语言设计程序实现10!AREA TEST, CODE,READONL YENTRYSTRA TMOV R13 ,#0X1000MOV R0,#0X01MOV R1,#0X02MOV R2,#0X03STMFD R13,{R0,R2,R1}MOV R7,#&FFLDMFD R13!,{R3-R5}MOV R8,#&55END3.实现字符串的逆序复制TEXT1=HELLO=>TEXT2=0LLEH AREA invstring, CODE, READONL YstartADR R1,TEXT1ADR R2,TEXT2MOV R3, #0LOOP LDRB R0,[R1], #1ADD R3,R3,#1CMP R0,#0BNE LOOPSUB R1,R1,#2LOOP1 LDRB R0,[R1], #-1STRB R0,[R2], #1SUB R3,R3, #1CMP R3,#1BNE LOOP1MOV R5,#&55NOPTEXT1 =“HELLO”,0ALIGNTEXT2 =“OELLH”END4.用调用子程序的方法实现1!+2!+3!+ (10) asmp.sAREA JC, CODE, READONL YEXPORT JCPENTRY JCPADD R3, R0, #1MOV R2, #1MOV R1, #1LOOP MUL R0, R1, R2MOV R1, R0ADD R2, R2, #1CMP R2, R3BNE LOOPNOPNOPMOV PC, LRENDPROGC.c#includeExtern int JCP(int N)int main() {int res=0;int m=10;int i;for (i=1;i<=m;i++)res=res+JCP(i);printf(“The result =%d\”,res);return 0; }1.线程创建线程创建所需的头文件:#include线程创建函数:pthread_create()函数原型:int pthread_create ((pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *), void *arg)) 其中thread:线程标识符attr:线程属性设置(常为空)start_routine:线程函数的起始地址arg:传递给start_routine的参数函数返回值成功:0 出错:-12.线程退出所需头文件:#include线程退出函数:pthread_exit();函数原型:void pthread_exit(void *retval)函数传入值retval: pthread_exit()调用者线程的返回值,可由其他函数如pthread_join 来检索获取3. 线程等待,资源释放所需头文件#include等待线程退出并释放资源pthread_join()函数原型:int pthread_join ((pthread_t th, void **thread_return))函数传入值th:要等待退出的线程标识符thread_return:用户定义的指针,用来存储被等待线程的返回值(不为NULL 时)函数返回值成功:0 出错:-1实验用的是UP-NetARM2410-S试验箱,里面配有三星的芯片S3c2410X。

ARM汇编-冒泡排序-实验报告

ARM汇编-冒泡排序-实验报告

实验要求实现字符串冒泡排序。

实验过程首先在内存中定义字符串,使用的方法是AREA SORTDATA,DATA,READWRITEstr DCB "9847210356"len DCD 10DCB表示在内存中开辟一个byte的空间。

DCD则表示开辟一个word的空间采用两层循环来进行冒泡排序。

第一层循环首先把r1初始化为字符串首地址,把r5初始化为0,r5代表内循环执行次数。

然后把r4 减1,因为最后的一个字符已经排好序了。

如果r4 = 0, 代表排序已经完成,调到结束代码。

loop0MOV r1,r0 ;r1 is the start address of stringSUBS r4,r4,#1 ;r4 is the last index, the counterCMP r4,#0BEQ endMOV r5,#0第二层循环就是从左往右对字符进行交换,每次把r1和r5的值都增加1。

当r5=r4的时候就跳出循环,到达外层循环。

;in every loop, s value of contiguous two bytes from the start to start+r4;using r1 as the address,increment in every inner loop;using r2,r3 to load the two bytes then compare; if r3 is smaller than r2,;then store the val in s placeloopLDRB r2,[r1]LDRB r3,[r1,#1]CMP r2,r3STRGTB r2,[r1,#1]STRGTB r3,[r1]ADD r1,r1,#1ADD r5,r5,#1CMP r5,r4BNE loop;if reaches the end, branch to outer loopB loop0为了让字符从小到大排列,在CMP r2,r3后,连续使用STRGT(Store Greater Than),如果r2>r3, 就分别把他们存进对方的地址实现交换。

arm实验源程序代码

arm实验源程序代码

ARM处理器工作模式实验程序代码:USR_STACK_LEGTH EQU 64SVC_STACK_LEGTH EQU 0FIQ_STACK_LEGTH EQU 16IRQ_STACK_LEGTH EQU 64ABT_STACK_LEGTH EQU 0UND_STACK_LEGTH EQU 0AREA Example5,CODE,READONL Y ; 声明代码段Example5ENTRY ; 标识程序入口CODE32 ; 声明32位ARM指令START MOV R0,#0MOV R1,#1MOV R2,#2MOV R3,#3MOV R4,#4MOV R5,#5MOV R6,#6MOV R7,#7MOV R8,#8MOV R9,#9MOV R10,#10MOV R11,#11MOV R12,#12BL InitStack ; 初始化各模式下的堆栈指针; 打开IRQ中断(将CPSR寄存器的I位清零)MRS R0,CPSR ; R0 <= CPSRBIC R0,R0,#0x80MSR CPSR_cxsf,R0 ; CPSR <= R0; 切换到用户模式MSR CPSR_c, #0xd0MRS R0,CPSR; 切换到管理模式MSR CPSR_c, #0xdfMRS R0,CPSRHALT B HALT; 名称:InitStack; 功能:堆栈初始化,即初始化各模式下的堆栈指针。

; 入口参数:无; 出口参数:无; 说明:在特权模式下调用此子程序,比如复位后的管理模式InitStackMOV R0, LR ; R0 <= LR,因为各种模式下R0是相同的;设置管理模式堆栈MSR CPSR_c, #0xd3LDR SP, StackSvc;设置中断模式堆栈MSR CPSR_c, #0xd2LDR SP, StackIrq;设置快速中断模式堆栈MSR CPSR_c, #0xd1LDR SP, StackFiq;设置中止模式堆栈MSR CPSR_c, #0xd7LDR SP, StackAbt;设置未定义模式堆栈MSR CPSR_c, #0xdbLDR SP, StackUnd;设置系统模式堆栈MSR CPSR_c, #0xdfLDR SP, StackUsrMOV PC, R0StackUsr DCD UsrStackSpace + (USR_STACK_LEGTH - 1)*4StackSvc DCD SvcStackSpace + (SVC_STACK_LEGTH - 1)*4StackIrq DCD IrqStackSpace + (IRQ_STACK_LEGTH - 1)*4StackFiq DCD FiqStackSpace + (FIQ_STACK_LEGTH - 1)*4StackAbt DCD AbtStackSpace + (ABT_STACK_LEGTH - 1)*4StackUnd DCD UndtStackSpace + (UND_STACK_LEGTH - 1)*4; 分配堆栈空间AREA MyStacks, DATA, NOINIT, ALIGN=2UsrStackSpace SPACE USR_STACK_LEGTH * 4 ; 用户(系统)模式堆栈空间SvcStackSpace SPACE SVC_STACK_LEGTH * 4 ;管理模式堆栈空间IrqStackSpace SPACE IRQ_STACK_LEGTH * 4 ; 中断模式堆栈空间FiqStackSpace SPACE FIQ_STACK_LEGTH * 4 ; 快速中断模式堆栈空间AbtStackSpace SPACE ABT_STACK_LEGTH * 4 ;中止义模式堆栈空间UndtStackSpace SPACE UND_STACK_LEGTH * 4 ; 未定义模式堆栈ENDGPIO输出控制实验程序代码#include "config.h"// 定义LED控制口(输出高电平时点亮LED)#define LED1_CON (1<<11) /* GPE11口*/#define LED2_CON (1<<12) /* GPE12口*/#define LED3_CON (1<<4) /* GPH4口*/#define LED4_CON (1<<6) /* GPH6口*/// 定义蜂鸣器控制口#define BEEP (1<<10) /* GPH10口*/#define BEEP_MASK (~BEEP)void DelayNS(uint32 dly){uint32 i;for(; dly>0; dly--)for(i=0; i<50000; i++);}void RunBeep(void){rGPHDAT = rGPHDAT & BEEP_MASK; // BEEP = 0 DelayNS(5);rGPHDAT = rGPHDAT | BEEP; // BEEP = 1DelayNS(5);}void LED_DispAllOn(void){rGPEDAT = rGPEDAT | (0x03<<11);rGPHDAT = rGPHDAT | (0x05<<4);}void LED_DispAllOff(void){rGPEDAT = rGPEDAT & (~(0x03<<11));rGPHDAT = rGPHDAT & (~(0x05<<4));}void LED_DispNum(uint32 dat){dat = dat & 0x0000000F; // 参数过滤// 控制LED4、LED3显示(d3、d2位)if(dat & 0x08) rGPHDAT = rGPHDAT | (0x01<<6);else rGPHDAT = rGPHDAT & (~(0x01<<6));if(dat & 0x04) rGPHDAT = rGPHDAT | (0x01<<4);else rGPHDAT = rGPHDAT & (~(0x01<<4));// 控制LED2、LED1显示(d1、d0位)rGPEDAT = (rGPEDAT & (~(0x03<<11))) | ((dat&0x03) << 11);}int main(void){int i;// 初始化I/OrGPECON = (rGPECON & (~(0x0F<<22))) | (0x05<<22); // rGPECON[25:22] = 0101b,设置GPE11、GPE12为GPIO输出模式rGPHCON = (rGPHCON & (~(0x33<<8))) | (0x11<<8); // rGPHCON[13:8] = 01xx01b,设置GPH4、GPH6为GPIO输出模式rGPHCON = (rGPHCON & (~(0x03<<20))) | (0x01<<20); // rGPHCON[21:20] = 01b,设置GPH10为GPIO输出模式// LED显示控制while(1){RunBeep(); // 蜂鸣器响一声// LED全闪烁5次for(i=0; i<5; i++){LED_DispAllOff(); // LED全熄灭DelayNS(5);LED_DispAllOn(); // LED全点亮DelayNS(5);}// 控制LED指示0~F的16进制数值for(i=0; i<16; i++){LED_DispNum(i); // 显示数值iDelayNS(5);}}return(0);}外部中断实验程序代码:#include "config.h"// 定义LED控制口(输出高电平时点亮LED)#define LED1_CON (1<<11) /* GPE11口*/#define LED2_CON (1<<12) /* GPE12口*/#define LED3_CON (1<<4) /* GPH4口*/#define LED4_CON (1<<6) /* GPH6口*/// 定义独立按键KEY1的输入口#define KEY_CON (1<<4) /* GPF4口*/// 定义LED1控制值变量uint8 ledcon = 0x00;void DelayNS(uint32 dly){uint32 i;for(; dly>0; dly--)for(i=0; i<50000; i++);}void IRQ_Eint4(void){int i;// 按键去抖动rGPFCON = rGPFCON & (~(0x03<<8)); // 设置为GPIO输入方式for(i=0; i<10000; i++); // 延时去抖动if(rGPFDAT&KEY_CON) // 若是假按键,则直接退出{rGPFCON = rGPFCON | (0x02<<8); // 设置回EINT4中断口// 清除中断标志rEINTPEND = (1<<4);rSRCPND = (1<<4);rINTPND = rINTPND;return;}rGPFCON = rGPFCON | (0x02<<8); // 设置回EINT4中断口// 把LED1控制口输出信号取反if(ledcon){ledcon = 0;rGPEDAT = rGPEDAT & (~LED1_CON) ;}else{ledcon = 1;rGPEDAT = rGPEDAT | LED1_CON;}// 清除中断标志rEINTPEND = (1<<4);rSRCPND = (1<<4);rINTPND = rINTPND;}void EINT_init(void){rGPFCON = (rGPFCON & 0xFFFFFCFF) | (0x02<<8); // 设置GPF4引脚为外部中断EINT4功能rEXTINT0 = (0x2<<16); // 外部中断EINT4设置为下降沿触发VICVectAddr[4] = (uint32) IRQ_Eint4; // 中断向量地址设置rPRIORITY = 0x00000000; // 使用默认的固定的优先级rINTMOD = 0x00000000; // 所有中断均为IRQ中断rINTMSK = ~0x0000010; // 使能EINT4中断rEINTMASK = ~0x0000010;}void LED_DispAllOff(void){rGPEDAT = rGPEDAT & (~(0x03<<11));rGPHDAT = rGPHDAT & (~(0x05<<4));}int main(void){// 初始化I/OrGPECON = (rGPECON & (~(0x0F<<22))) | (0x05<<22); // rGPECON[25:22] = 0101b,设置GPE11、GPE12为GPIO输出模式rGPHCON = (rGPHCON & (~(0x33<<8))) | (0x11<<8); // rGPHCON[13:8] = 01xx01b,设置GPH4、GPH6为GPIO输出模式LED_DispAllOff(); // 熄灭LED1--LED4EINT_init(); // 外部中断初始化IRQEnable(); // 使能IRQ中断(清零CPSR寄存器的I位)while(1); // 等待外部中断return(0);}步进电机控制实验程序代码#include "config.h"// 步进电机控制口线及操作宏函数定义#define MOTOA (1<<5) /* GPC5 */#define MOTOB (1<<6) /* GPC6 */#define MOTOC (1<<7) /* GPC7 */#define MOTOD (1<<0) /* GPC0 */#define GPIOSET(PIN) rGPCDAT = rGPCDAT | PIN /* 设置PIN输出1,PIN 为MOTOA--MOTOD */#define GPIOCLR(PIN) rGPCDAT = rGPCDAT & (~PIN) /* 设置PIN输出0,PIN 为MOTOA--MOTOD */void DelayNS(uint32 dly){uint32 i;for(; dly>0; dly--)for(i=0; i<50000; i++);}void MOTO_Mode2(uint8 dly){uint32 i;for(i=0; i<20; i++){// AB相有效GPIOSET(MOTOA);GPIOSET(MOTOB);DelayNS(dly);GPIOCLR(MOTOA);GPIOCLR(MOTOB);// BC相有效GPIOSET(MOTOB);GPIOSET(MOTOC);DelayNS(dly);GPIOCLR(MOTOB);GPIOCLR(MOTOC);// CD相有效GPIOSET(MOTOC);GPIOSET(MOTOD);DelayNS(dly);GPIOCLR(MOTOC);GPIOCLR(MOTOD);// DA相有效GPIOSET(MOTOD);GPIOSET(MOTOA);DelayNS(dly);GPIOCLR(MOTOD);GPIOCLR(MOTOA);}}int main(void){// 步进电机控制口设置rGPCCON = (rGPCCON & (~0x0000FC03)) | (0x00005401); // GPC0、GPC5--7口设置为输出rGPCUP = rGPCUP | 0x00E1; // 禁止GPC0、GPC5--7口的上拉电阻rGPCDAT = rGPCDAT & (~0x00E1); // 设置GPC0、GPC5--7口输出低电平while(1){MOTO_Mode2(1); // 控制步进电机正转DelayNS(50); // 停止步进电机,延时}return(0);}基于μC/OS-Ⅱ程序代码#include "config.h"#define Task0StkLengh 64 // Define the Task0 stack length 定义用户任务0的堆栈长度#define Task1StkLengh 64 // Define the Task1 stack length 定义用户任务1的堆栈长度OS_STK Task0Stk [Task0StkLengh]; // Define the Task0 stack 定义用户任务0的堆栈OS_STK Task1Stk [Task1StkLengh]; // Define the Task1 stack 定义用户任务1的堆栈// 定义LED控制口(输出高电平时点亮LED)#define LED1_CON (1<<11) /* GPE11口*/#define LED2_CON (1<<12) /* GPE12口*/#define LED3_CON (1<<4) /* GPH4口*/#define LED4_CON (1<<6) /* GPH6口*/// 定义蜂鸣器控制口#define BEEP (1<<10) /* GPH10口*/#define BEEP_MASK (~BEEP)void Task0(void *pdata); // Task0 任务0void Task1(void *pdata); // Task1 任务1void RunBeep(void);void LED_DispNum(uint32 dat);int main (void){OSInit ();OSTaskCreate (Task0,(void *)0, &Task0Stk[Task0StkLengh - 1], 2);OSTaskCreate (Task1,(void *)0, &Task1Stk[Task1StkLengh - 1], 3);OSStart ();return 0;}void Task0 (void *pdata){pdata = pdata;TargetInit ();// 初始化I/OrGPECON = (rGPECON & (~(0x0F<<22))) | (0x05<<22); // rGPECON[25:22] = 0101b,// 设置GPE11、GPE12为GPIO输出模式rGPHCON = (rGPHCON & (~(0x33<<8))) | (0x11<<8); // rGPHCON[13:8] = 01xx01b,// 设置GPH4、GPH6为GPIO输出模式rGPHCON = (rGPHCON & (~(0x03<<20))) | (0x01<<20); // rGPHCON[21:20] = 01b,// 设置GPH10为GPIO输出模式while (1){RunBeep();OSTimeDly(OS_TICKS_PER_SEC);}}void Task1 (void *pdata){ uint8 i;pdata = pdata;while (1){for(i=0; i<16; i++){LED_DispNum(i);OSTimeDly(OS_TICKS_PER_SEC/2);}}}void RunBeep(void){rGPHDAT = rGPHDAT & BEEP_MASK; // BEEP = 0OSTimeDly(OS_TICKS_PER_SEC/10);rGPHDAT = rGPHDAT | BEEP; // BEEP = 1OSTimeDly(OS_TICKS_PER_SEC/10);}void LED_DispNum(uint32 dat){dat = dat & 0x0000000F; // 参数过滤// 控制LED4、LED3显示(d3、d2位)if(dat & 0x08) rGPHDAT = rGPHDAT | (0x01<<6);else rGPHDAT = rGPHDAT & (~(0x01<<6));if(dat & 0x04) rGPHDAT = rGPHDAT | (0x01<<4);else rGPHDAT = rGPHDAT & (~(0x01<<4));// 控制LED2、LED1显示(d1、d0位)rGPEDAT = (rGPEDAT & (~(0x03<<11))) | ((dat&0x03) << 11);}。

实验1-ARM基础编程仿真(Keil)

实验1-ARM基础编程仿真(Keil)
23
5、ARM汇编实现冒泡算法(选做) 冒泡排序参考流程-----较小的数值排放到后面
24
5、ARM汇编实现冒泡算法(选做)
冒泡排序法原理:
这种方法的基本思想:是将待排序的元素看作是竖着排列的 “气泡”,较大的元素比较重,从而要往下沉。在冒泡排序算法 中我们要对这个“气泡”序列处理若干遍。所谓一遍处理,就是 自上向下检查一遍这个序列,并时刻注意两个相邻的元素的顺序 是否正确。如果发现两个相邻元素的顺序不对,即“轻”的元素 在下面,就交换它们的位置。显然,处理一遍之后,“最重”的 元素就沉到了最低位置;处理二遍之后,“次重”的元素就沉到 了次低位置。在作第二遍处理时,由于最低位置上的元素已是 “最重”元素,所以不必检查。一般地,第i遍处理时,不必检 查第i低位置以下的元素,因为经过前面i-1遍的处理,它们已正 确地排好序。
25
5、ARM汇编实现冒泡算法(选做)
实验步骤: 1、建立新工程,加入实验1.5文件夹中的maopao.s。 2、补充完成源代码中缺失的部分,实现冒泡排序功能。 3、运行Debug进行调试
实验一 ARM基础编程实验
1
一、实验目的与实验环境
实验目的
1.熟悉并掌握常用ARM汇编指令 2.熟悉并掌握“C+汇编”混合编程技术 3.熟练使用ARM软件开发调试工具Keil
实验环境
1. 硬件:PC 机 2. 软件:Windows操作系统,Keil软件
2
二、实验内容
1. 学习使用Keil开发工具 2. 实现累加运算功能(汇编编程,必做) 3. 实现字符串拷贝功能(C+汇编,必做) 4. 实现求和运算功能(C+汇编,必做) 5. 实现冒泡排序算法(汇编编程,选做)
16
2、用汇编语言实现1+2+...+N的累加(必做)

实验二 ARM汇编语言编程实验.doc

实验二 ARM汇编语言编程实验.doc

实验二:ARM 汇编语言编程实验一、实验目的1、掌握ADT IDE ARM 开发环境中基本的工程设置以及程序编译方法。

2、掌握ADT IDE ARM 开发环境中基本的程序调试方法。

3、掌握基本的ARM 汇编语言编程方法。

二、实验内容用汇编语言编写一个程序实现如下目的:从源地址拷贝num 个字(num*4个字节)的数据到目的地址dst 中。

三、预备知识1、ARM 汇编语言的基础知识。

2、程序调试的基础知识和方法。

四、实验设备1、硬件:JXARM9-2440教学实验箱、PC 机。

2、软件:PC 机操作系统Windows 98(2000、XP)+ADT IDE 开发环境。

五、基础知识ADT IDE 集成了GNU 汇编器arm-elf-as 、编译器arm-elf-gcc 和链接器arm-elf-ld 。

在ADT IDE 中编写的程序必须符合GNU 的语法规则。

下面介绍一些基本的GNU 汇编知识以及本实验用到的ARM 汇编指令。

1、GUN 汇编语言语法及规则1)_start_start 为程序默认入口点,代码段默认起始地址为0x800,如果需要修改可以在链接脚本文件中指定。

2)标号语法:symbol:symbol 为定义的符号。

说明:上述代码定义一个标号,它表示程序中当前的指令或数据地址。

如果在程序中出现两个相同的标号,汇编器将会产生一个警告,且只有第一个标号有效。

课程名称 ARM 体系结构 实验成绩 指导教师 冯灵霞实 验 报 告 院系 信息工程学院班级计算机科学与技术(嵌入式) 学号 姓名 日期2、GNU汇编语言伪操作1).equ伪操作语法:.equ symbol,exprexpr为基于寄存器的地址值、程序中的标号、32位的地址常量或位的常量。

symbol为.equ 伪操作为expr定义的字符名称。

说明:该操作符为数字常量、基于寄存器的值和程序中的标号定义一个字符名称,相当于C语言中的宏定义。

示例:.equ USERMODE,0x102).global伪操作符语法:.global symbolsymbol为声明的符号的名称。

ARM汇编指令学习:[0]编码格式与条件码域

ARM汇编指令学习:[0]编码格式与条件码域

ARM汇编指令学习:[0]编码格式与条件码域ARM 汇编指令学习:[0]编码格式与条件码域⼀、ARM指令的编码格式31 2827 212019 1615 1211 0cond opcode S Rn Rd shifter_operand其中:cond [31-28] 4-bit 指令执⾏的条件编码opcode [27-21] 4-bit 指令操作符编码S [20] 1-bit 决定指令的操作是否影响CPSR的值Rn [19-16] 4-bit 包含第1个操作数的寄存器编码Rd [15-12] 4-bit ⽬标寄存器编码shifter_operand [11-0] 12-bit 表⽰第2个操作数⼀条典型的ARM指令语法如下:<opcode>{<cond>}{S} <Rd>,<Rn>,<shifter_operand>其中:<opcode> 指令助记符{<cond>} 指令执⾏的条件{S} 决定指令的操作是否影响CPSR的值<Rd> 表⽰⽬标寄存器<Rn> 表⽰包含第1个操作数的寄存器<shifter_operand> 表⽰第2个操作数⼆、ARM指令的条件码域条件码<cond>条件码助记符含义CPSR中条件标志位值0000EQ相等Z=10001NE不相等Z=00010CS/HS⽆符号数⼤于/等于C=10011CC/LO⽆符号数⼩于C=00100MI负数N=10101PL⾮负数N=00110VS上溢出V=10110VS上溢出V=1条件码<cond>条件码助记符含义CPSR中条件标志位值0111VC没有上溢出V=01000HI⽆符号数⼤于C=1且Z=01001LS⽆符号数⼩于/等于C=0且Z=11010GE带符号数⼤于/等于N=1且V=1或N=0且V=01011LT带符号数⼩于N=1且V=0或N=0且V=11100GT带符号数⼤于Z=0且N=V1101LE带符号数⼩于/等于Z=1或N!=V1110AL⽆条件执⾏1111NV该指令从不执⾏我的个⼈主页:我的个⼈站点博客:我的CSDN博客:我的简书:我的GitHub:欢迎相互follow~。

arm常用汇编指令

arm常用汇编指令

arm常用汇编指令ARM的汇编指令是ARM处理器在运行时所执行的基本操作。

汇编指令是一种低级编程语言,它主要是为了直接操作硬件而设计的。

在ARM 汇编指令中,每个指令都是由一个操作码和一些操作数组成的。

操作码就是指令的类型,而操作数则是指令要操作的数据。

下面是一些常用的ARM汇编指令:1. mov指令mov指令是ARM汇编指令中最常用的指令之一。

它用来将一个数据从一个位置复制到另一个位置。

例如,下面的代码将寄存器r1中的值复制到寄存器r2中:mov r2, r12. add指令add指令用来将两个数相加并将结果存放在一个寄存器中。

例如,下面的代码将r1和r2中的值相加并将结果存放在r3中:add r3, r1, r23. sub指令sub指令用来将一个数从另一个数中减去并将结果存放在一个寄存器中。

例如,下面的代码将r2中的值从r1中减去并将结果存放在r3中:sub r3, r1, r24. cmp指令cmp指令用来比较两个数的大小。

它会将两个数相减,并将结果存放在一个特殊的寄存器中。

如果相减结果为0,表示两个数相等;如果结果为正数,表示第一个数大于第二个数;如果结果为负数,表示第一个数小于第二个数。

例如,下面的代码比较r1和r2的大小:cmp r1, r25. beq指令beq指令用来进行条件分支。

如果cmp指令的结果为0,则跳转到指定的地址。

例如,下面的代码如果r1等于r2,就跳到标号my_label处执行:beq my_label6. bne指令bne指令用来进行条件分支。

如果cmp指令的结果不为0,则跳转到指定的地址。

例如,下面的代码如果r1不等于r2,就跳到标号my_label处执行:bne my_label7. ldr指令ldr指令用来从内存中读取一个值并存放到寄存器中。

例如,下面的代码从内存地址0x100处读取一个值并存放到寄存器r1中:ldr r1, [0x100]8. str指令str指令用来将一个值存储到内存中。

实验2基于ARM的汇编语言程序设计

实验2基于ARM的汇编语言程序设计

实验2基于ARM的汇编语⾔程序设计实验⼆基于ARM的汇编语⾔程序设计⼀、实验⽬的了解ARM汇编语⾔的基本框架,学会使⽤ARM的汇编语⾔编程。

⼆、实验设备标准硬件。

三、实验内容⽤汇编语⾔编写“连续发送128个ASCII字符”的应⽤程序。

四、实验原理ARM汇编语⾔程序中,是以程序段为单位来组织代码。

段是相对独⽴的指令或数据序列,具有特定的名称。

段可以分为代码段和数据段,代码段的内容为执⾏代码,数据段存放代码运⾏时所需的数据。

⼀个汇编程序⾄少应该有⼀个代码段,当程序较长时,可以分割为多个代码段和数据段,多个段在程序编译链接时最终形成⼀个可执⾏⽂件。

因此在进⾏汇编时除了要了解其书写规范外,还要能理解段的应⽤。

下⾯是⼀个代码段的⼩例⼦,实现数据的装载AREA Init,CODE,READONLYENTRYLDR R0, =0x3FF5000LDR R1, 0x0fSTR R1, [R0]LDR R0, =0x3F50008LDR R1, 0x1STR R1, [R0]…END上述程序,在汇编程序中,⽤AREA指令定义⼀个段,并说明定义段的相关属性,其格式为AREA 段名,属性1,属性2,…,属性n。

本例中定义了段名为Init的属性为代码段,只读。

ENTRY伪指令标识程序的⼊⼝,即代码从此处开始执⾏,程序的末尾为END指令,该伪指令告诉编译器源⽂件的结束,每⼀个汇编⽂件都要以END结束。

AREA DataArea, DATA, NOINIT, ALIGN=2DISPBUF SPACE 200RCVBUF SPACE 200…DATA为数据段的标识。

本程序段名为DataArea,属性数据段,不含初始化,采⽤align表达式对其⽅式2表达式次⽅。

五、实验步骤1.打开ADS1.2开发环境,打开\基础实验\实验五\asm.mcp项⽬⽂件,然后进⾏compile和make⽣成*.axf⽂件。

2.编译通过后,进⼊ADS1.2调试界⾯,加载\基础实验\实验五\asm_Data\Debug中的映象⽂件asm.axf。

ARM汇编指令

ARM汇编指令

ARM指令格式
• ARM指令集——第2个操作数
<opcode> {<cond>} {S} <Rd> ,<Rn>{,<operand2>}
灵活的使用第2个操作数“operand2”能够提高代码效率。
它有如下的形式:
▪Rm——寄存器方式;
如:SUB R1,R1,R2
▪Rm,shift——寄存器移位方式;
ARM指令种类
存储器访问指令
➢ARM处理器是典型的RISC处理器,对存储器的访问 只能使用加载和存储指令实现。对外围IO、程序数据 的访问均要通过加载/存储指令进行。 ➢存储器访问指令分为单寄存器操作指令和多寄存器操 作指令。 ➢所有单寄存器加载/存储指令可分为“字和无符号字 节加载存储指令”和“半字和有符号字节加载存储指 令。 ➢一条指令处理多寄存器的的加载/存储。
个寄存器的任何子集或所有寄存器。多寄存器寻址指令举例如下:
LDMIA
R1!,{R2-R4,R6}
;将R1指向的单元中的数据读出到R2~R4,R6中
• 相对寻址
相对寻址是基址寻址的一种变通。由程序计数器
PC提供基准地址,指令中的地址码字段作为偏移量,两者
相加后得到的地址即为操作数的有效地址。
BL
SUBR1
四种类型的堆栈方式:满递增、空递增、满递减、空递减
ARM指令格式
ARM指令的基本格式如下:
<opcode> {<cond>} {S} <Rd> ,<Rn>{,<operand2>}
其中<>号内的项是必须的,{}号内的项是可选的。 各项的说明如下:
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

AREA Example1,CODE,READONLY ENTRY CODE32START MOV R0,#15MOV R1,#8ADDS R0,R0,R1B STARTENDTest2.sX EQU 11Y EQU 8BIT23 EQU (1<<23AREA Example3,CODE,READONLY ENTRY CODE32STARTYMOV R0,#XMOR R1,#YADD R3,R0,R1MOV R8,R3MVN R0,#0XA0000007SUB R5,R0,R8,LSL #3MOV R0,#YADD R0,R0,R0,LSL #2MOV R0,R0,LSR #1MOV R1,#XMOV R1,R1,LSL #1CMP R0,R1LDRHI R2,=0XFFFF0000ANDHI R5,R5,R2ORRLS R5,R5,#0X000000FFTST R5,#BIT32BICNE R5,R5,#0X00000040B STARTEND//*******Test3.s******************** X EQU 11Y EQU 8BIT23 EQU (1<<23AREA Example3,CODE,READONLY ENTRY CODE32STARTMOV R0,#XMOV R1,#YADD R3,R0,R1MOV R8,R3MVN R0,#0XA0000007SUB R5,R0,R8,LSL #3MOV R0,#YADD R0,R0,R0,LSL #2MOV R0,R0,LSR #1MOV R1,#XMOV R1,R1,LSL #1CMP R0,R1LDRHI R2,=0XFFFF0000ANDHI R5,R5,R2ORRLS R5,R5,#0X000000FFTST R5,#BIT23BICNE R5,R5,#0X00000040B STARTEND//*************Test4.s*************** ;******************************** ****** ;Name :test4.s;Function :Caculate X^n;Entrance parametre :;Out parametre :R0 Result;Source occupation :R0,R1;Explanation :;**************************************X EQU 9n EQU 8AREA Example4,CODE,READONLYENTRYCODE32START LDR SP,=0X40D03F0DLDR R0,=XLDR R1,=nBL POWHALT B HALT;**************************************;Name :POW;Function :zhengshu chengfang;Entrance parametre :;Out parametre :;Source occupation :R0,R1;Explanation :This code doesnt care the number overflow ;**************************************POWSTMFD SP!,{R1-R12,LR}MOVS R2,R1MOVEQ R0,#1BEQ POW_ENDCMP R2,#1BEQ POW_ENDMOV R1,R0SUB R2,R2,#1POW_L1 BL DO_MULSUBS R2,R2,#1BNE POW_L1POW_END LDMFD SP!,{R1-R12,PC};************************************** ;Name :DO_MUL;Function :MULTIPLE OF 32BIT DATA;Entrance parametre :R0 CHENGSHU; R1 BEICHENGSU;Out parametre :R0 Result;Source occupation :R0,R1;Explanation :;************************************** DO_MUL MUL R0,R1,R0MOV PC,LREND//***********Test5.s***************;************************************** ;Name :test5.s;Function :Caculate 1+2+3+…+N;Entrance parametre :;Out parametre :;Source occupation :;Explanation :N>=0, if N=0 reult=0,if N=1 resualt=1;**************************************N EQU 100AREA Example5,CODE,READONLYENTRYCODE32ARM_CODE LDR SP,=0X40003F00 ;There should be no space before ARM_CODE ADR R0,THUMB_CODE+1BX R0LTORGCODE16THUMB_CODELDR R0,=NBL SUM_NB THUMB_CODE;**************************************;Name :SUM_N;Function :Caculate 1+2+3+…+N;Entrance Parametre :R0 N;Out Parametre :R0 Result;Source Occupation :R0;Explanation :N>=0, if N=0 result=0,if N=1 resualt=1; if any overflow result=0;;************************************** SUM_N PUSH {R1-R7,LR}MOVS R2,R0BEQ SUM_ENDCMP R2,#1BEQ SUM_ENDMOV R1,#1MOV R0,#0SUM_L1 ADD R0,R1BCS SUM_ERRCMP R1,R2BHS SUM_ENDADD R1,#1B SUM_L1SUM_ERR MOV R0,#0SUM_END POP {R1-R7,PC}END//*************Test6.s******************** ;*************************** *********** ;Name :tes6.s;Function :show if for while switch ;Entrance Parametre :;Out Parametre :;Source Occupation :;Explanation :;************************************** AREAExample6,CODE,READONLY ENTRYCODE32START ;if(x>yz=100;;else z=50MOV R0,#76MOV R1,#243CMP R0,R1MOVHI R2,#100MOVLS R2,#50;for(i=0;i<10;i++FOR_L1 ;{ ; x++; ;} MOV R0,#0 MOV R2,#0 CMP R2,#10 BHS FOR_END ADD R0,R0,#1 ADD R2,R2,#1 B FOR_L1 NOP ;while(x<=y ;{ ; x*=2; ;} MOV R0,#1 MOV R1,#20 B WHILE_L2 FOR_END WHILE_L1 WHILE_L2 MOV R0,R0,LSL #1 CMP R0,R1 BLS WHILE_L1 WHILE_END NOP ;do ;{x--;} ;while(x>0 MOV R0,#5 DOWHILE_L1 ADD R0,R0,#-1 DOWHILE_L2 MOVS R0,R0 BNE DOWHILE_L1 DOWHILE_END NOP ;switch(key&0x0f ;{case 0: ; case 2: ; case 3:x=key+y; break; ; case 5:x=key-y; break; ; case 7:x=key*y; break;;default:x=168; break; ;} MOV R1,#3 MOV R2,#2 SWITCH AND R2,R2,#0X0F CASE_0 CMP R2,#0 CASE_2 CMPNE R2,#2 CASE_3 CMPNE R2,#3 BNE CASE_5 ADD R0,R2,R1 B SWITCH_END CASE_5 CMP R2,#5 BNE CASE_7 SUB R0,R2,R1 B SWITCH_END CASE_7 CMP R2,#7 BNE DEFAULT MUL R0,R2,R1 BSWITCH_END DEFAULT MOV R0,#168 SWITCH_END NOP HALT B HALT END。

相关文档
最新文档