ARM Cortex-M0 汇编指令 总结
重点看 ------
立即数 是以 “#”为前缀
MOV R0,#0xFF00
MOV R1,#1
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
Load from memory into register
LDR指令用于从内存中读取数据放入寄存器中;
LDR{cond}{T} Rd,<地址>;加载指定地址上的数据(字),放入Rd中
STR : Store From a Register into memory
STR指令用于将寄存器中的数据保存到内存
STR{cond}{T} Rd,<地址>;存储数据(字)到指定地址的存储单元,要存储的数据在Rd中
数据传送指令.将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伪指令用于加载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的参数有“=”号
将一个 8位的立即数 加载到 一个寄存器中
大于8位的立即数,使用LDR
MOVS R0 , #0x12
MOVS R1 , #‘A’
https://download.csdn.net/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
比较,为零则跳转;比较,为非零则跳转。
语法
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 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保存到栈中