ARM Cortex-M0 汇编指令 总结

ARM Cortex-M0 汇编指令 总结

重点看 ------ <ARM Cortex-M0权威指南.pdf> 第5章

立即数 “#”

立即数 是以 “#”为前缀

MOV R0,#0xFF00
MOV R1,#1

寄存器寻址 R1 R2

MOV   R1,R2                 ; R2  --> R1
SUB  R0,R1,R2             ;R1 - R 2 ---> R0

在这里插入图片描述

寄存器间接寻址 " [ ] "

LDR R1,[R2] ;将R2中的数值作为地址,取出此地址中的数据保存在R1中
SWP R1,R1,[R2];将如中的数值作为地址,取出此地址中的数值与R1中的值交换

基址寻址指令举例 " [ , ] "

LDR R2,[R3,#0x0F] ;将R3中的数值加0x0F作为地址,取出此地址的数值保存在R2中
STR R1,[R0,#-2] ;将R0中的数值减2作为地址,把R1中的内容保存到此地址位置
指令格式

基本格式
{}{S} ,{,}
其中,<>内的项是必须的,{}内的项是可选的,如是指令助记符,是必须的,而{}为指令执行条件,是可选的,如果不写则使用默认条件AL(无条件执行)。
opcode 指令助记符,如LDR,STR等
cond 执行条件,如EQ,NE等
S 是否影响CPSR寄存器的值,书写时影响CPSR,否则不影响
Rd 目标寄存器
Rn 第一个操作数的寄存器
operand2 第二个操作数

指令格式举例如下:

LDR R0,[R1] ;读取R1地址上的存储器单元内容,执行条件AL
BEQ DATAEVEN ;跳转指令,执行条件EQ,即相等跳转到DATAEVEN
ADDS R1,R1,#1 ;加法指令,R1+1=R1影响CPSR寄存器,带有S
SUBNES R1,R1,#0xD;条件执行减法运算(NE),R1-0xD=>R1,影响CPSR寄存器,带有S

条件码

使用指令条件码,可实现高效的逻辑操作,提高代码效率

在这里插入图片描述

对于Thumb指令集,只有B指令具有条件码执行功能,此指令条件码同表2.1,但如果为无条件执行时,条件码助记符“AL”不能在指令中书写。
条件码应用举例如下:
比较两个值大小,并进行相应加1处理,C代码为
if(a>b)a++;
else b++;
对应的ARM指令如下。其R0为a,R1为b。

CMP R0,R1 ;R0与R1比较
ADDHI R0,R0,#1 ;若R0>R1,则R0=R0+1
ADDLS R1,R1,#1 ;若R0<=R1,则R1=R1+1

若两个条件均成立,则将这两个数值相加,C代码为
If((a!=10)&&(b!=20)) a=a+b;

对应的ARM指令如下.其中R0为a,R1为b.

CMP R0,#10 ;比较R0是否为10
CMPNE R1,#20 ;若R0不为10,则比较R1是否20
ADDNE R0,R0,R1 ;若R0不为10且R1不为20,指令执行,R0=R0+R1
LDR

Load from memory into register
LDR指令用于从内存中读取数据放入寄存器中;
LDR{cond}{T} Rd,<地址>;加载指定地址上的数据(字),放入Rd中
在这里插入图片描述

STR

STR : Store From a Register into memory

STR指令用于将寄存器中的数据保存到内存

STR{cond}{T} Rd,<地址>;存储数据(字)到指定地址的存储单元,要存储的数据在Rd中
在这里插入图片描述

MOV 寄存器之间移动数据

数据传送指令.将8位图立即数或寄存器(operant2)传送到目标寄存器Rd,可用于移位运算等操作.指令格式如下:

MOV{cond}{S} Rd,operand2

MOV指令举例如下:

MOV R1#0x10 ;R1=0x10
MOV R0,R1 ;R0=R1
MOVS R3,R1,LSL #2 ;R3=R1<<2,并影响标志位
MOV PC,LR ;PC=LR ,子程序返回

在这里插入图片描述

跳转指令

在这里插入图片描述

LDR 伪指令 LDR Rn , =xxxxxx

大范围的地址读取伪指令.LDR伪指令用于加载32位的立即数或一个地址值到指定寄存器.
在汇编编译源程序时,LDR伪指令被编译器替换成一条合适的指令.若加载的常数未超出MOV或MVN的范围,则使用MOV或MVN指令代替该LDR伪指令,否则汇编器将常量放入字池,并使用一条程序相对偏移的LDR指令从文字池读出常量.LDR伪指令格式如下:
LDR{cond} register,=expr/label_expr
其中 register 加载的目标寄存器
expr 32位立即数.
label_expr 基于PC的地址表达式或外部表达式.

LDR 伪指令举例如下.

LDR R0,=0x123456 ;加载32位立即数0x12345678
LDR R0,=DATA_BUF+60 ;加载DATA_BUF地址+60
…
LTORG ;声明文字池

伪指令LDR常用于加载芯片外围功能部件的寄存器地址(32位立即数),以实现各种控制操作
加载32位立即数

加载32位立即数
…
LDR R0,=IOPIN ;加载GPIO寄存器IOPIN的地址
LDR R1,[R0] ;读取IOPIN寄存器的值
…
LDR R0,=IOSET
LDR R1,=0x00500500
STR R1,[R0] ;IOSET=0x00500500
…

从PC到文字池的偏移量必须小于4KB
与ARM指令的LDR相比,伪指令的LDR的参数有“=”号

MOVS

将一个 8位的立即数 加载到 一个寄存器中
大于8位的立即数,使用LDR

MOVS R0 , #0x12
MOVS R1 , #‘A’

MOV 是针对 8位的 立即数,LDR和STR是针对32位的立即数

参考 资料

https://download.youkuaiyun.com/download/wowocpp/10817388
包含:
20071230123408_常用ARM指令集及汇编v1.0.12发行文档.pdf
E3_PT_Migrating to Cortex-M Processors_Leon Chen_20091126.pdf cortex_m0_Technical_Reference_Manual.pdf
cortex_m0_Generic_User_Guide.pdf

CBZ和CBNZ指令使用说明《realview编译工具》

CBZ 和 CBNZ
比较,为零则跳转;比较,为非零则跳转。
语法
CBZ Rn, label
CBNZ Rn, label
其中:
Rn 是存放操作数的寄存器。
label 是跳转目标。
用法
可以使用 CBZ 或 CBNZ 指令避免更改条件代码标记并减少指令数目。
除了不更改条件代码标记外,CBZ Rn, label 与下列指令序列功能相同:
CMP Rn, #0
BEQ label
除了不更改条件代码标记外,CBNZ Rn, label 与下列指令序列功能相同:
CMP Rn, #0
BNE label
限制
跳转目标必须在指令之后的 4 到 130 个字节之内。
这些指令一定不能在 IT 块内使用。
条件标记
这些指令不更改标记。
体系结构
这些 16 位 Thumb 指令可用于 ARMv6T2 及更高版本。
这些指令没有 ARM 或 32 位 Thumb 版本。

BX

在这里插入图片描述

BL

在这里插入图片描述

BX LR

bx lr

的作用等同于

mov pc,lr

即跳转到lr中存放的地址处。

那么lr存放的是什么地址呢?

lr就是连接寄存器(Link Register, LR),在ARM体系结构中LR的特殊用途有两种:一是用来保存子程序返回地址;二是当异常发生时,LR中保存的值等于异常发生时PC的值减4(或者减2),因此在各种异常模式下可以根据LR的值返回到异常发生前的相应位置继续执行。

当通过BL或BLX指令调用子程序时,硬件自动将子程序返回地址保存在R14寄存器中。在子程序返回时,把LR的值复制到程序计数器PC即可实现子程序返回。

如,可以使用MOV PC, LR或者BX LR来完成子程序返回。另外,也可以在在子程序入口处使用下面的指令将LR保存到栈中

MRS 读状态寄存器指令

在这里插入图片描述

MSR 写状态寄存器

在这里插入图片描述

在这里插入图片描述

<think>好的,我需要帮用户找到关于ARM Cortex-M0汇编语言的例程或代码示例。首先,用户已经提供了一些参考资料,我需要先仔细看一下这些引用内容,看看有没有相关的信息可以利用。 引用[1]和[2]提到了Cortex-M0的处理器结构和内部组件,包括NVIC、调试子系统等,但没有具体的代码。引用[3]展示了一个C语言的NVIC函数,可能和中断处理有关,但用户需要的是汇编示例。引用[4]详细介绍了寄存器,特别是通用寄存器和特殊功能寄存器,这对编写汇编代码很有帮助,但同样没有直接提供例子。 接下来,我应该考虑用户可能需要的基础汇编示例,比如GPIO控制、中断处理、延时循环等。这些是嵌入式开发中常见的任务,而Cortex-M0常用于微控制器,所以GPIO操作是基础。此外,中断服务例程(ISR)在嵌入式系统中也很重要,需要汇编或与汇编相关的启动代码。 用户可能需要汇编代码的结构,比如启动文件(startup.s),这通常包含初始化和中断向量表。此外,简单的数据操作和逻辑运算可以展示汇编的基本用法。另外,考虑到C语言内嵌汇编的情况,这也是常见的使用方式,可以提供一个例子。 需要确保代码符合Cortex-M0的指令集,因为M0支持Thumb指令集,所以应该使用如MOVS、ADDS等指令,并且注意寄存器使用,如R0-R7是低寄存器,访问更高效。同时,特殊寄存器如PSR、CONTROL可能需要特定的指令来访问,但基础示例可能不需要这些。 另外,需要指导用户如何获取更多的例程,比如厂商提供的SDK、ARM的文档、开源项目等。可能还需要提醒用户关于开发环境,如Keil、IAR或GCC工具链,不同的工具可能有不同的汇编语法。 最后,生成相关问题,帮助用户深入理解汇编应用和相关知识,比如优化、启动流程、混合编程等。</think>### ARM Cortex-M0 汇编示例与资源 #### 1. 基础汇编代码结构 Cortex-M0 汇编代码通常以启动文件(startup.s)为基础,包含初始化堆栈指针、中断向量表等。以下是一个简化示例: ```assembly ; 定义堆栈大小 Stack_Size EQU 0x400 AREA STACK, NOINIT, READWRITE, ALIGN=3 Stack_Mem SPACE Stack_Size __initial_sp ; 中断向量表 AREA RESET, DATA, READONLY __Vectors DCD __initial_sp ; 栈顶地址 DCD Reset_Handler ; 复位中断 DCD 0 ; NMI_Handler DCD 0 ; HardFault_Handler ; ...其他中断向量 AREA |.text|, CODE, READONLY Reset_Handler PROC ; 初始化操作 MOVS R0, #0 LDR R1, =0x40010800 ; GPIOA基地址 STR R0, [R1, #0x10] ; 配置GPIOA模式寄存器 BX LR ENDP ``` 此代码展示了堆栈定义、中断向量表布局和复位处理函数[^2][^4]。 #### 2. GPIO控制示例 通过汇编实现 LED 闪烁(假设 GPIOA 引脚5连接 LED): ```assembly ; 配置GPIOA引脚5为输出模式 LDR R0, =0x40010800 ; R0 = GPIOA基地址 MOVS R1, #0x0400 ; 模式位掩码(推挽输出) STR R1, [R0, #0x00] ; 写入模式寄存器 ; LED闪烁循环 loop MOVS R1, #(1 << 5) ; 设置引脚5 STR R1, [R0, #0x10] ; 置位GPIOA_BSRR BL delay MOVS R1, #(1 << (16 + 5)) ; 清除引脚5 STR R1, [R0, #0x10] BL delay B loop delay MOVS R2, #0xFFFF ; 简单延时循环 delay_loop SUBS R2, #1 BNE delay_loop BX LR ``` 此代码使用直接寄存器操作控制 GPIO,适用于裸机编程。 #### 3. 内联汇编示例(C语言混合编程) 在C代码中嵌入汇编实现特定优化: ```c void enable_irq(void) { __asm volatile ( "MOVS R0, #0 \n" "MSR PRIMASK, R0 \n" // 开启全局中断 ::: "r0" ); } uint32_t read_register(void) { uint32_t result; __asm volatile ( "MRS %0, CONTROL \n" // 读取CONTROL寄存器 : "=r" (result) ); return result; } ``` 此方法常用于关键代码优化和特殊寄存器访问[^3][^4]。 #### 4. 资源获取途径 1. **芯片厂商SDK**: STM32CubeMX(ST)、NXP MCUXpresso 等开发套件包含完整的启动文件和底层驱动汇编代码。 2. **ARM官方文档**: 《Cortex-M0 Technical Reference Manual》提供指令集和编程模型说明,包含代码片段。 3. **开源项目参考**: GitHub 搜索关键词 `cortex-m0 assembly example`,可找到如: - [STM32F0 Discovery 汇编项目](https://github.com) - [Cortex-M0 裸机编程模板](https://github.com) 4. **书籍案例**: 《The Definitive Guide to ARM Cortex-M0》中文译本包含中断处理、任务切换等完整汇编案例[^1]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值