ARM单片机汇编指令使用一

发布者:ph49635359最新更新时间:2018-10-05 来源: eefocus关键字:ARM  单片机  汇编指令 手机看文章 扫描二维码
随时随地手机看文章

目录:

1、ldr/str/mov指令

1)LDR指令   2)STR和LDRB指令   3)MOV指令   4)使用示例

2、movs指令

3、LDM表示装载,STM表示存储

4、teq指令

5、使用tst来检查是否设置了特定的位

6、'^'的理解

7、spsr_cxsf,cpsr_cxsf的理解

8、cpsr的理解

9、指令后缀和条件判断

10、B、BL、BX、BLX 和 BXJ指令的区别

1)B 指令   2)BL 指令   3)BLX 指令   4)BX 指令和BXJ指令   5)总结

--------------------------------------------

说明:

ARM单片机汇编指令使用一

ARM单片机汇编指令使用二

ARM单片机汇编指令的查找见“ARM单片机二之十五、查找汇编指令”。

--------------------------------------------

.macro restore_user_regs //宏

   ldr r1,[sp, #S_PSR]

   ldr lr,[sp, #S_PC]!   @ !用来控制基址变址寻址的最终新地址是否进行回写操作,

                                  @ 执行ldr之后sp被回写成sp+#S_PC基址变址寻址的新地址

   msrspsr,r1              @ 把cpsr的值保存到spsr中

   ldmdb sp,{r0 - lr}^@lr=[sp-1*4],r13=[sp-2*4],r12=[sp-3*4],......,r0=[sp-15*4]

                                 @ 因为没对pc赋值,所以^的表示将数据恢复到User模式的[r0-lr]寄存器组中[gliethttp]

   mov r0,r0 

   add sp,sp,#S_FRAME_SIZE - S_PC

   movs pc,lr

.endm


-------------------------------------------------------------------------------------------------------

1、ldr/str/mov指令

1)LDR指令

LDR格式:LDR{条件}   目的寄存器  <存储器地址>

LDR作用:将存储器地址所指地址处连续的4个字节(1个字)的数据传送到目的寄存器

比如想把数据从内存中某处读取到寄存器中,只能使用ldr

比如:ldr r0, 0x12345678

就是把0x12345678这个地址中的值存放到r0。

而mov不能干这个活,mov只能在寄存器之间移动数据,或者把立即数移动到寄存器中。

-------------------

2)STR和LDRB指令

STR格式:STR{条件}  源寄存器,<存储器地址>

STR作用:STR指令用于从源寄存器中将一个32位的字数据传送到存储器中。该指令在程序设计中比较常用,寻址方式灵活多样,使用方式可参考指令LDR。 

LDRB:字节数据加载指令

-------------------

3)MOV指令

MOV格式:mov source, destination

MOV作用:source 和 destination 的值可以是内存地址,存储在内存中的数据值,指令语句中定义的数据值,或者寄存器。

-------------------

4)使用示例

   ldr ip,[sp],#4 //将sp中内容存入ip,之后sp=sp+4;

   ldr ip,[sp,#4] //将sp+4这个新地址下内容存入ip,之后sp值保持不变

   ldr ip,[sp,#4]! //将sp+4这个新地址下内容存入ip,之后sp=sp+4将新地址值赋给sp

   str ip,[sp],#4 //将ip存入sp地址处,之后sp=sp+4;

   str ip,[sp,#4] //将ip存入sp+4这个新地址,之后sp值保持不变

   str ip,[sp,#4]! //将ip存入sp+4这个新地址,之后sp=sp+4将新地址值赋给sp


-------------------------------------------------------------------------------------------------------

2、movs指令

   movs r1,#3 ; //movs将导致ALU被更改,因为r1赋值非0,即操作结果r0非0,所以ALU的Z标志清0

   bne 1f  ; //因为Z=0,说明不等,所以向前跳到标号1:所在处继续执行其他语句


MOVS pc,r14_und; //cpsr(状态寄存器)←spsr_und(备份状态寄存器),pc←r14_und

相关指令详见“嵌入式网络那些事LwIP协议深度剖析与实战演练P42下方”。

MOVS总是会影响cpsr, 包括N,Z,C标志位,执行MOVS pc,lr(也就是r14寄存器)时,cpsr会被spsr覆盖,如上。内核态,USER和SYSTEM模式下没有spsr。


-------------------------------------------------------------------------------------------------------

3、LDM表示装载,STM表示存储.

   LDMED LDMIB 预先增加装载

   LDMFD LDMIA 过后增加装载

   LDMEA LDMDB 预先减少装载

   LDMFA LDMDA 过后减少装载

   STMFA STMIB 预先增加存储

   STMEA STMIA 过后增加存储

   STMFD STMDB 预先减少存储

   STMED STMDA 过后减少存储

注意ED不同于IB;只对于预先减少装是相同的.在存储的时候,ED是过后减少的.

FD、ED、FA、和 EA 指定是满栈还是空栈,是升序栈还是降序栈.

对于存储STM而言

先加后存 FA 姑且这么来记,先加(first add),存数据

后加先存 EA 姑且这么来记,存数据,后加end add

先减后存 FD 姑且这么来记,先减first dec,存数据

后减先存 ED 姑且这么来记,存数据,后减end dec

然后记忆LDM,LDM是STM的反相弹出动作,所以

因为是先加后存,所以后减先取 FA 就成了与STM对应的取数据,后减

因为是后加先存,所以先减后取 EA 就成了与STM对应的先减,取数据

因为是先减后存,所以后加先取 FD 就成了与STM对应的取数据,后加

因为是后减先存,所以先加后取 ED 就成了与STM对应的先加,取数据

我想通过上面的变态方式可以比较容易的记住这套指令[gliethttp]

一个满栈的栈指针指向上次写的最后一个数据单元,而空栈的栈指针指向第一个空闲单元.

一个降序栈是在内存中反向增长(就是说,从应用程序空间结束处开始反向增长)而升序栈在内存中正向增长. 

其他形式简单的描述指令的行为,意思分别是

IA过后增加(Increment After)、

IB预先增加(Increment Before)、

DA过后减少(Decrement After)、

DB预先减少(Decrement Before).

RISC OS使用传统的满降序栈.在使用符合APCS规定的编译器的时候,它通常把你的栈指针设置在应用程序空间的

结束处并接着使用一个FD(满降序-Full Descending)栈.如果你与一个高级语言(BASIC或C)一起工作,你将别无选择.

栈指针(传统上是R13)指向一个满降序栈.你必须继续这个格式,或则建立并管理你自己的栈.


-------------------------------------------------------------------------------------------------------
4、teq指令
teq r1,#0      //r1-0,将结果送入状态标志,如果r1和0相减的结果为0,那么ALU的Z置位,否则Z清0
bne reschedule//ne表示Z非0,即:不等,那么执行reschedule函数


-------------------------------------------------------------------------------------------------------
5、使用tst来检查是否设置了特定的位
tst r1,#0x80 //按位and操作,检测r1的0x1<<7,即第7位是否置1,按位与之后结果为0,那么ALU的Z置位
beq reset    //如果Z置位,即:以上按位与操作结果是0,那么跳转到reset标号执行


-------------------------------------------------------------------------------------------------------
6、'^'的理解
'^'是一个后缀标志,不能在User模式和Sys系统模式下使用该标志.该标志有两个存在目的:
1)对于LDM操作,同时恢复的寄存器中含有pc(r15)寄存器,那么指令执行的同时cpu自动将spsr拷贝到cpsr中
如:在IRQ中断返回代码中[如下为ads环境下的代码gliethttp]
ldmfd {r4}           //读取sp中保存的的spsr值到r4中
msr spsr_cxsf,r4     //对spsr的所有控制为进行写操作,将r4的值全部注入spsr
ldmfd {r0-r12,lr,pc}^//当指令执行完毕,pc跳转之前,将spsr的值自动拷贝到cpsr中[gliethttp]

-------------------
2)数据的送入、送出发生在User用户模式下的寄存器,而非当前模式寄存器
如:ldmdb sp,{r0 - lr}^;表示sp栈中的数据回复到User分组寄存器r0-lr中,而不是恢复到当前模式寄存器r0-lr
当然对于User,System,IRQ,SVC,Abort,Undefined这6种模式来说[gliethttp]r0-r12是共用的,只是r13和r14
   为分别独有,对于FIQ模式,仅仅r0-r7是和前6中模式的r0-r7共用,r8-r14都是FIQ模式下专有.

ARM单片机汇编指令使用一

-------------------------------------------------------------------------------------------------------
7、spsr_cxsf,cpsr_cxsf的理解
c - control field maskbyte(PSR[7:0])
x - extension field maskbyte(PSR[15:8])
s - status field maskbyte(PSR[23:16)
f - flags field maskbyte(PSR[31:24]).
老式声明方式:cpsr_flg,cpsr_all在ADS中已经不在支持
cpsr_flg对应cpsr_f
cpsr_all对应cpsr_cxsf

需要使用专用指令对cpsr和spsr操作:mrs,msr
mrs tmp,cpsr      //读取CPSR的值
bic tmp,tmp,#0x80 //如果第7位为1,将其清0
msr cpsr_c,tmp    //对控制位区psr[7:0]进行写操作


-------------------------------------------------------------------------------------------------------
8、cpsr的理解
CPSR = Current Program Status Register
SPSR = Saved Program Status Registers
CPSR寄存器(和保存它的SPSR寄存器)

ARM单片机汇编指令使用一

(上图)
N,Z,C,V称为ALU状态标志
N:如果结果是负数则置位
Z:如果结果是零则置位
C:如果发生进位则置位
V:如果发生溢出则置位
I:置位表示禁用IRQ中断,清0表示使能IRQ
F:置位表示禁用FIQ中断,清0表示使能FIQ
T:置位表示系统运行在Thumb态,清0表示运行在ARM态
M[4:0]:
10000 User模式,和System系统模式一样
10001 FIQ模式
10010 IRQ模式
10011 SVC超级管理模式
10111 Abort数据异常模式
11011 Undefined未定义指令模式
11111 System系统模式,和User模式一样

举例:
ands r2,r2,#7 使用运算结果改变标志位,如果运算结果r2=0,那么Z置位,EQ相等判断成立
subs r2,r2,#1 使用运算结果改变标志位,如果运算结果r2=0,那么Z置位,EQ相等判断成立
beq wordcopy

-------------------------------------------------------------------------------------------------------

9、指令后缀和条件判断

ARM单片机汇编指令使用一

 (上图)

EQ : 等于
NE : 不等
CS : 无符号>=
CC : 无符号<
MI : 负数
PL : 非负[>=0]
VS : 溢出
VC : 无溢出
HI : 无符号>
LS : 无符号<=
GE : 有符号>=
LT : 有符号<
GT : 有符号>
LE : 有符号<=
AL : 总是[默认]


对于arm汇编指令,可以参考linux内核的arch/arm目录,那里的汇编指令很丰富[gliethttp_20080603]
__CopyFromStart
;    ldr     r3, [r9],#4
;    str     r3, [r7], #4
;    sub   r8, r8, #4
    ldrb   r3, [r9], #1
    strb   r3, [r7], #1
    sub   r8, r8, #1
    cmp  r8, #0
    bgt    __CopyFromStart
    b       __JumpToBootImage

    __JumpToBootImage
    MOV     pc, r0


-------------------------------------------------------------------------------------------------------

10、B、BL、BX、BLX 和 BXJ指令的区别

跳转指令用于实现程序流程的跳转,在 ARM 程序中有两种方法可以实现程序流程的跳转:

①使用专门的跳转指令。

②直接向程序计数器 PC 写入跳转地址值。

通过向程序计数器 PC 写入跳转地址值,可以实现在 4GB 的地址空间中的任意跳转,在跳转之前结合使用

MOV LR , PC

等类似指令,可以保存下一条指令地址作为将来的返回地址值,从而实现在 4GB 连续的线性地址空间的子程序调用。

专门的跳转指令

B、BL、BX、BLX 和 BXJ:

跳转、带链接跳转(带返回的跳转)、跳转并切换指令集、带链接跳转并切换指令集(带返回的跳转并切换指令集)、跳转并转换到 Jazelle 状态。

-------------------

1)B 指令

B 指令的格式为:B{条件} 目标地址

B 指令是最简单的跳转指令。一旦遇到一个 B 指令,ARM 处理器将立即跳转到给定的目标地址,从那里继
续执行。注意存储在跳转指令中的实际值是相对当前PC 值的一个偏移量,而不是一个绝对地址,它的值由汇编器来计算(参考寻址方式中的相对寻址)。它是 24 位有符号数,左移两位后有符号扩展为 32 位,表示的有效偏移为 26 位(前后32MB 的地址空间)。以下指令:

B Label ;程序无条件跳转到标号 Label 处执行

CMP R1 ,# 0 ;当 CPSR 寄存器中的 Z 条件码置位时,程序跳转到标号 Label 处执行

BEQ Label

-------------------

2)BL 指令

BL 指令的格式为:BL{条件} 目标地址

BL 是另一个跳转指令,但跳转之前,会在寄存器R14 中保存PC 的当前内容,因此,可以通过将R14 的内容重新加载到PC 中,来返回到跳转指令之后的那个指令处执行。该指令是实现子程序调用的一个基本但常用的手段。以下指令:

BL Label ;当程序无条件跳转到标号 Label 处执行时,同时将当前的 PC 值保存到 R14 中

-------------------

3)BLX 指令

BLX 指令的格式为:BLX 目标地址

BLX 指令从ARM 指令集跳转到指令中所指定的目标地址,并将处理器的工作状态有ARM 状态切换到Thumb 状态,该指令同时将PC 的当前内容保存到寄存器R14 中。因此,当子程序使用Thumb 指令集,而调用者使用ARM 指令集时,可以通过BLX 指令实现子程序的调用和处理器工作状态的切换。

同时,子程序的返回可以通过将寄存器R14 值复制到PC 中来完成。

-------------------

4)BX 指令和BXJ指令

BX 指令的格式为:BX{条件} 目标地址

BX 指令跳转到指令中所指定的目标地址,目标地址处的指令既可以是ARM 指令,也可以是Thumb指令。

-------------------

5)总结

语法

op1{cond}{.W} label
op2{cond} Rm

其中:

op1

是下列项之一:

B

跳转。

BL

带链接跳转

BLX

带链接跳转并切换指令集。

op2

是下列项之一:

BX

跳转并切换指令集。

BLX

带链接跳转并切换指令集。

BXJ

跳转并转换为 Jazelle 执行。

cond

是一个可选的条件代码。 cond 不能用于此指令的所有形式。

.W

是一个可选的指令宽度说明符,用于强制要求在 Thumb-2 中使用 32 位 B 指令。

label

是一个程序相对的表达式。

Rm

是一个寄存器,包含要跳转到的目标地址。

操作

所有这些指令均会引发跳转,或跳转到 label,或跳转到包含在 Rm 中的地址处。 此外:

BL 和 BLX 指令可将下一个指令的地址复制到 lr(r14,链接寄存器)中。

BX 和 BLX 指令可将处理器的状态从 ARM 更改为 Thumb,或从 Thumb 更改为 ARM。

BLX label 无论何种情况,始终会更改处理器的状态。

BX Rm 和 BLX Rm 可从 Rm 的位 [0] 推算出目标状态:

如果 Rm 的位 [0] 为 0,则处理器的状态会更改为(或保持在)ARM 状态

如果 Rm 的位 [0] 为 1,则处理器的状态会更改为(或保持在)Thumb 状态。

 

BXJ 指令会将处理器的状态更改为 Jazelle


-------------------------------------------------------------------------------------------------------


关键字:ARM  单片机  汇编指令 引用地址:ARM单片机汇编指令使用一

上一篇:STM32标准库编译成lib库文件
下一篇:ARM单片机汇编指令使用二

推荐阅读最新更新时间:2024-03-16 16:14

基于MCU实现蓝牙与PC机之间HCI层传输
摘要:分析了蓝牙HCI层的主要功能,并简述了蓝牙HCI层数据传输的单片机控制方案。HCI指令从RS232串口通过单片机的UART输入,经校验后发送至蓝牙模块,蓝牙模块返回的HCI事件在单片机内进行分组打包后发送至PC机。 关键词:蓝牙协议HCI 单片机 UART蓝牙模块 蓝牙是正在兴起的短距离无线通信技术,工作在2.4GHz ISM频段。蓝牙技术可在各种移动设备、计算机外设等数字设备间实现廉价的无线连接,灵活便捷地实现设备间的数据交换。本文介绍利用双串口单片机在PC机与蓝牙模块间实现蓝牙HCI层数据传输。 1 系统的硬件组成 采用爱立信生产的ROK 101 007蓝牙模块,使用51增强型单片机W77E58,用MAX3222
[单片机]
基于单片机的IC卡智能水表控制系统设计
第1章 绪论 本章介绍了本研究课题的背景及意义,阐述了其发展状况。对当前水资源形势、传统水表和IC卡智能水表的特点及其水表的未来发展趋势作了概况。另外,简要说明了本文所做的工作。 1.1 本研究课题的背景及意义 环境与发展,是当今国际社会普遍关注的重大问题,保护环境是全人类的共同任务。水资源作为生态环境中的重要资源,是人类生活的生产中不可取代的资源,对一个国家的生存和发展也是极为重要的。水资源是一切生命的源泉,是人类不可缺少的物质条件,没有水人类就不能生存,没有水人类赖以自下而上的物质生产就不能发展。 由于历史的原因,我国大部分城市居民使用自来水,都是在区域性水站供水基础上,逐步发展成为以单位住宅区或以楼栋、单元为一户由自
[单片机]
基于<font color='red'>单片机</font>的IC卡智能水表控制系统设计
PC机与单片机多机主从互通的实现
  PC机与单片机组成的主从系统很常见,在很多领域中都得到了应用。在这些系统中,PC机与单片机之间一般采用串行通信方式,按照一定的格式,进行数据、指令的交换,完成PC机对单片机的控制、数据前送,或者单片机上数据、状态等信息的回送。   当单片机数量较多时,比较容易实现PC机对所有单片机的控制。一般在这种情况下,采用广播的方式。   所有单片机都挂在一条串行数据总线上,只需对单片机进行地址编码,PC机将地址数据和控制报文进行广播,单片机接收广播数据后进行地址比对,筛选出所需的数据,完成相应的数据传送。   如果PC机要对单片机多机进行广播,并回传所有单片机的信息,即单片机还要发送数据至PC机,再加上单片机数量较多(大于100个单片机
[电源管理]
PC机与<font color='red'>单片机</font>多机主从互通的实现
[单片机框架][bsp层][AT32F415][bsp_flash] flash(EFC)配置和使用
4 内嵌闪存控制器(EFC) 4.1 EFC简介 内嵌的闪存存储器可以用于在线编程(ICP)或在程序中编程(IAP)烧写。 在线编程 (In-Circuit Programming - ICP) 方式用于更新闪存存储器的全部内容, 它通过 JTAG、 SWD协议或系统加载程序(Bootloader)下载用户应用程序到微控制器中。ICP 是一种快速有效的编程方法,消除了封装和管座的困扰。 与 ICP 方式对应,在程序中编程(In-Application Programming - IAP)可以使用微控制器支持的任一种通信接口(如 I/O 端口、USB、CAN、UART、I2C、SPI 等)下载程序或数据到存储器中。IAP 允
[单片机]
单片机驱动 DS1302时钟+1602液晶
程序参考C语言代码如下: #include REGX52.H #include “LCD1602.h” #include “DS1302.h” void Delay1ms(unsigned int count) { unsigned int i,j; for(i=0;i count;i++) for(j=0;j 120;j++); } main() { SYSTEMTIME CurrentTime; LCD_Initial(); Initial_DS1302(); GotoXY(0,0); Print( www.ourhc.cn ); GotoXY(0,1); Print( Time: ); whil
[单片机]
<font color='red'>单片机</font>驱动 DS1302时钟+1602液晶
基于数字PID和89C52单片机的温度控制系统
在工业生产过程中,温度是工业生产过程中常见的工艺参数之一,对温度控制的好坏直接影响产品的质量。及时准确地得到温度信息并对其进行适当的控制,在许多工业场合中都是重要的环节。对于不同生产情况和工艺要求下的温度控制,所采用的加热方式和控制方式均不同。本文介绍了一种基于89C52单片机的温度控制系统,本系统的任务是对温度进行实时监控与控制。它以温度传感器DSl820对温度进行测量、采样与转换,并将测量结果送给单片机;单片机将输人的温度值与内部指定单元的给定温度值进行比较,根据比较结果,通过一个执行机构(可控硅)对加热源(加热炉的温度)的开关状态进行控制。在控制环节中,本系统采用的是数字PID控制算法来实现上述功能。传统的PID控制电路结
[单片机]
基于数字PID和89C52<font color='red'>单片机</font>的温度控制系统
单片机系统中法拉电容的数据保护研究
引 言 在测量、控制等领域的嵌入式系统应用中,常要求系统内部和外部数据存储器(RAM)中的数据在电源掉电时不丢失,重新加电时RAM中的数据能够保存完好,以保证系统稳定、可靠地工作和数据信息处理的安全。这就要求对系统加接掉电保护措施。掉电保护可采用以下三种方法: 一是加接不问断电源。由于这种方法体积大、成本高,对单片机系统来说,不宜采用。 二是采用EEPROM来保存数据。但由于其读写速度与读写次数的限制,使得EEPROM不能完全代替RAM。 三是采用备份电池,掉电后保护系统中全部或部分数据存储单元的内容。 显然,上述第三种方法是比较可行的。实际应用中,往往采用内置锂电池的非易失性静态随机存取存储器(nonvola
[单片机]
<font color='red'>单片机</font>系统中法拉电容的数据保护研究
inDART-One正式支持飞思卡尔最新的RS08单片机
SofTec Microsystems表示inDART-One(飞思卡尔单片机的通用开发工具)已俱备编程及除错飞思卡尔最新发表的RS08单片机系列的功能。 RS08系列的单片机使用简化的S08内核及较少的管脚数目,针对着重成本效益的嵌入式应用而设计。 InDART-One不但提供高速编程 (High-speed) 的生产模式,而且拥有高度防御电击的可靠结构,使它可以应用在最严峻的生产环境。 与此同时,透过USB 2.0界面,一台主电脑能连接最多三十二部inDART-One,整合为一套量产型的编程工具。 InDART-One 附有两套图像操作接口: DataBlaze及MultiBlaze。前者主要为生产及测试工程师提供全面
[新品]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved