我是靠谱客的博主 难过飞鸟,最近开发中收集的这篇文章主要介绍ARM中常用的汇编指令,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

1 处理器内部数据传输指令

MSR & MRS

用于在状态寄存器和通用寄存器之间传送数据

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

MRS R0, CPSR
@ 将特殊寄存器 CPSR 里面的数据传递给 R0,即R0=CPSR

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

MSR CPSR, R0
@ 将 R0 中的数据复制到 CPSR 中,即 CPSR=R0

MOV

MOV 指令用于将数据从一个寄存器拷贝到另外一个寄存器,或者将一个立即数传递到寄
存器里面,使用示例如下:

MOV R0, R1
@ 将寄存器 R1 中的数据传递给 R0,即 R0=R1
MOV R0, #0X12
@ 将立即数 0X12 传递给 R0 寄存器,即 R0=0X12

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 的寄存器值。

LDR R0, =0X0209C004
@ 将寄存器地址 0X0209C004 加载到 R0 中,即 R0=0X0209C004
LDR R1, [R0]
@ 读取地址 0X0209C004 中的数据到 R1 寄存器中

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

STR 指令

LDR 是从存储器读取数据, STR 就是将数据写入到存储器中

LDR R0, =0X0209C004
@ 将寄存器地址 0X0209C004 加载到 R0 中,即 R0=0X0209C004
LDR R1, =0X20000002
@ R1 保存要写入到寄存器的值,即R1=0X20000002
STR R1, [R0]
@ 将 R1 中的值写入到 R0 中所保存的地址中

LDR 和 STR 都是按照字进行读取和写入的,也就是操作的 32 位数据,如果要按照字节、半字进行操作的话可以在指令“LDR”后面加上 B 或 H,比如按字节操作的指令就是 LDRB 和
STRB,按半字操作的指令就是 LDRH 和 STRH。

3 压栈和出栈指令

我们通常会在 A 函数中调用 B 函数,当 B 函数执行完以后再回到 A 函数继续执行。要想再跳回 A 函数以后代码能够接着正常运行,那就必须在跳到 B 函数之前将当前处理器状态保存起来(就是保存 R0-R15 这些寄存器值),当 B 函数执行完成以后再用前面保存的寄存器值恢复R0-R15 即可。保存 R0-R15 寄存器的操作就叫做现场保护,恢复 R0~R15 寄存器的操作就叫做恢复现场。在进行现场保护的时候需要进行压栈(入栈)操作,恢复现场就要进行出栈操作。

指令描述
POP < reg list>出栈
PUSH < reg list>入栈

4 跳转指令

指令描述
B < LABEL >跳转到 label
BX < Rm >间接跳转,跳转到存放于 Rm 中的地址处,并且切换指令集
BL < LABEL >跳转到标号地址,并将返回地址保存在 LR 中
BLX < Rm >结合 BX 和 BL 的特点,跳转到 Rm 指定的地址,并将返回地址保存在 LR 中,切换指令集

B指令

这是最简单的跳转指令, B 指令会将 PC 寄存器的值设置为跳转目标地址, 一旦执行 B 指
令, ARM 处理器就会立即跳转到指定的目标地址。如果要调用的函数不会再返回到原来的执行
处,那就可以用 B 指令。

BL指令

BL 指令相比 B 指令,在跳转之前会在寄存器 LR(R14)中保存当前 PC 寄存器值,所以可以通过将 LR 寄存器中的值重新加载到 PC 中来继续从跳转之前的代码处运行,这是子程序调用一个基本但常用的手段。

5 算术运算指令

指令计算公式
ADD Rd, Rn, Rm / #immedRd = Rn + Rm / #immed
ADC Rd, Rn, Rm / #immed (带进位)Rd = Rn + Rm / #immed + 进位
SUB Rd, Rn, Rm / #immedRd = Rn – Rm / #immed
SUB Rd, #immedRd = Rd - #immed
SUB Rd, Rn, #immedRd = Rn - #immed
SBC Rd, Rn, Rm / #immed (带借位)Rd = Rn - Rm / #immed - 借位
MUL Rd, Rn, RmRd = Rn * Rm
UDIV Rd, Rn, Rm (无符号)Rd = Rn / Rm
SDIV Rd, Rn, Rm (有符号)Rd = Rn / Rm

6 逻辑运算指令

AND Rd, Rn, Rm
Rd = Rn & Rm
ORR Rd, Rn, Rm
Rd = Rn | Rm
BIC Rd, Rn, Rm
Rd = Rn & (~Rm)
ORN Rd, Rn, Rm
Rd = Rn | (~Rm)
EOR Rd, Rn, Rm
Rd = Rn ^ Rm

最后

以上就是难过飞鸟为你收集整理的ARM中常用的汇编指令的全部内容,希望文章能够帮你解决ARM中常用的汇编指令所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(40)

评论列表共有 0 条评论

立即
投稿
返回
顶部