ARM常用汇编指令

在网上看到一篇关于ARM常用指令的介绍,其实ARM启动流程的精髓全在那些一开始的汇编代码中,所以掌握一些ARM常用汇编指令还是十分重要的

(1)GBLL 伪指令用于定义一个全局的逻辑变量,并初始化为{False}。
GBLL BOOTLOADER
BOOTLOADER SETL {TRUE}

(2)GET(或 INCLUDE)
GET 伪指令用于将一个源文件包含到当前的源文件中,并将被包含的源文件在当前位置进行汇编处理。可以使用 INCLUDE 代替 GET。
INCLUDE ..\\..\\kernel\\oal\\startup.s

(3)IMPORT 伪指令用于通知编译器要使用的标号在其他的源文件中定义,但要在当前源文件中引用,而且无论当前源文件是否引用该标号,该标号均会被加入到当前源文件的符号表中。
IMPORT BootloaderMain
IMPORT MMUSetup
(4)BL 带返回的跳转指令
(5)BEQ表示“相等则跳转”,即当CPSR中的Z标志置位时发生跳转
B Label ;程序无条件跳转到标号Label处执行 
CMP R1,#0 ;当CPSR寄存器中的Z条件码置位时,程序跳转到标号Label处执行 
BEQ Label

(6)LDR 指令的格式为: 
LDR{条件} 目的寄存器,<存储器地址>
LDR 指令用于从存储器中将一个 32 位的字数据传送到目的寄存器中。该指令通常用于从存储器中读取 32 位的字数据到通用寄存器,然后对数据进行处理。当程序计数器 PC 作为目的寄存器时,指令从存储器中读取的字数据被当作目的地址,从而可以实现程序流程的跳转。
指令示例: 
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。 
LDR R0,[R1,R2,LSL#2]! ;将存储器地址为R1+R2×4的字数据读入寄存器R0,并将新地址R1+R2×4写入R1。 
LDR R0,[R1],R2,LSL#2 ;将存储器地址为R1的字数据读入寄存器R0,并将新地址R1+R2×4写入R1。

(7)STR 指令的格式为: 
STR{条件} 源寄存器,<存储器地址>
STR 指令用于从源寄存器中将一个 32 位的字数据传送到存储器中。与LDR对应

(8)采用多寄存器寻址方式,一条指令可以完成多个寄存器值的传送。这种寻址方式可以用一条指令完成传送最多 16 个通用寄存器的值。以下指令: 
LDMIA R0,{R1,R2,R3,R4} ;R1←[R0]
;R2←[R0+4]
;R3←[R0+8]
;R4←[R0+12]
该指令的后缀 IA表示在每次执行完加载/存储操作后,R0 按字长度增加,因此,指令可将连续存储单元的值传送到 R1~R4。

(9)SBC 指令的格式为: 
SBC{条件}{S} 目的寄存器,操作数 1,操作数 2
SBC指令用于把操作数1减去操作数2,再减去 CPSR 中的C 条件标志位的反码,并将结果存放到目的寄存器中。操作数1应是一个寄存器,操作数2可以是一个寄存器,被移位的寄存器,或一个立即数。该指令使用进位标志来表示借位,这样就可以做大于 32 位的减法。注意不要忘记设置 S后缀来更改进位标志。该指令可用于有符号数或无符号数的减法运算。
指令示例: 
SUBS R0,R1,R2 ; R0 = R1 - R2 - !C,并根据结果设置CPSR的进位标志位

(10)BX 带状态切换的跳转指令

(11)MCR 指令的格式为: 
MCR{条件} 协处理器编码,协处理器操作码 1,源寄存器,目的寄存器 1,目的寄存器 2,协处理器操作码 2
MCR 指令用于将 ARM 处理器寄存器中的数据传送到协处理器寄存器中,若协处理器不能成功完成操作,则产生未定义指令异常。其中协处理器操作码1和协处理器操作码2为协处理器将要执行的操作,源寄存器为 ARM 处理器的寄存器,目的寄存器1和目的寄存器2均为协处理器的寄存器。
指令示例: 
MCR P3,3,R0,C4,C5,6 ;该指令将ARM处理器寄存器R0中的数据传送到协处理器P3的寄存器C4和C5中。

(12)CMP 指令的格式为: 
CMP{条件} 操作数 1,操作数 2 
CMP 指令用于把一个寄存器的内容和另一个寄存器的内容或立即数进行比较,同时更新 CPSR 中条件标志位的值。该指令进行一次减法运算,但不存储结果,只更改条件标志位。标志位表示的是操作数 1 与操作数 2 的关系(大、小、相等),例如,当操作数 1 大于操作操作数 2,则此后的有 GT 后缀的指令将可以执行。
指令示例: 
CMP R1,R0 ;将寄存器R1的值与寄存器R0的值相减,并根据结果设置CPSR的标志位 
CMP R1,#100 ;将寄存器R1的值与立即数100相减,并根据结果设置CPSR的标志位

(13)批量数据加载/存储指令LDM(或 STM)指令的格式为: 
LDM(或 STM){条件}{类型} 基址寄存器{!},寄存器列表{∧}
LDM(或 STM)指令用于从由基址寄存器所指示的一片连续存储器到寄存器列表所指示的多个寄存器之间传送数据,该指令的常见用途是将多个寄存器的内容入栈(SDM)或出栈(LDM)。其中,{类型}为以下几种情况:
IA 每次传送后地址加 1; 
IB 每次传送前地址加 1; 
DA 每次传送后地址减 1; 
DB 每次传送前地址减 1; 
FD 满递减堆栈; 
ED 空递减堆栈; 
FA 满递增堆栈; 
EA 空递增堆栈; 
{!}为可选后缀,若选用该后缀,则当数据传送完毕之后,将最后的地址写入基址寄存器,否则基址寄存器的内容不改变。

STMFD R13!,{R0,R4-R12,LR} ;将寄存器列表中的寄存器(R0,R4 到R12,LR)存入堆栈
LDMFD R13!,{R0,R4-R12,PC} ;将堆栈内容恢复到寄存器(R0,R4到R12,LR)

(14)ORR 指令的格式为: 
ORR{条件}{S} 目的寄存器,操作数 1,操作数 2
ORR 指令用于在两个操作数上进行逻辑或运算,并把结果放置到目的寄存器中。操作数 1
应是一个寄存器,操作数 2 可以是一个寄存器,被移位的寄存器,或一个立即数。该指令常用于设置操作数 1 的某些位。 
指令示例: 
ORR R0,R0,#3 ; 该指令设置R0的0、1位,其余位保持不变。

(15)BIC 指令的格式为: 
BIC{条件}{S} 目的寄存器,操作数 1,操作数 2 
BIC指令用于清除操作数1 的某些位,并把结果放置到目的寄存器中。操作数 1 应是一个寄存器,操作数 2 可以是一个寄存器,被移位的寄存器,或一个立即数。操作数 2 为 32 位的掩码,如果在掩码中设置了某一位,则清除这一位。未设置的掩码位保持不变。
指令示例: 
BIC R0,R0,#%1011 ; 该指令清除 R0 中的位 0、1、和 3,其余的位保持不变。

(16)
ADR(小范围的地址读取伪指令)
ADRL(中等范围的地址读取伪指令)
LDR(大范围的地址读取伪指令)
ldr r0, =0xFFFFC000
用于将基于PC的地址或基于寄存器的地址读取到寄存器中。
///伪指令通过汇编编译器替换成对应的ARM/Thumb 指令。

银火虫 发表于06-03 10:12 浏览65535次
分享到:

已有0条评论

暂时还没有回复哟,快来抢沙发吧

添加一条新评论

只有登录用户才能评论,请先登录注册哦!

话题作者

银火虫
银火虫(中将)
金币:5919个|学分:6733个
立即注册
畅学电子网,带你进入电子开发学习世界
专业电子工程技术学习交流社区,加入畅学一起充电加油吧!

x

畅学电子网订阅号