ARM基础
ARM汇编:(APCS过程调用标准)
汇编:用助记符(如$ # .)代替操作码,用地址符号或标签代替地址码的编程语言
特点:
优点:可以直接访问硬件,目标代码简短,执行速度快(CPU启动时需要直接操作,所以用汇编)
缺点:可移植性差,可阅读性差(不同平台指令有差别)
ARM指令集特点
1 指令码长度固定,如32bit
2 几乎所有指令都是有条件执行
3 寄存器与内存之间交换数据采用专用指令集
CPU内部有很多通用寄存器,如R0-R15,R0-R12可以随便存储数据,寄存器中的数据主要是从外存取出来的,所以为了提高效率把寄存器和寄存器里面交互使用专用指令,寄存器与内存之间交互也使用另一种专用指令,这样就可以把他们分离开,让数据操作变的效率更高。
指令格式:
opcode:指令助记符
cond:执行条件
s:是否影响CPSR寄存器的值
Rd:目标寄存器
Rn:第一个操作数的寄存器
operand2:第二个操作数
指令编码格式:
32-28 |
27-25 |
24-21 |
20 |
19-16 |
15-12 |
11-0 |
|
cond |
001 |
opcode |
S |
Rn |
Rd |
11-8(移位) |
7-0(数据) |
operand2 |
代码格式:
数据运算指令:
指令 |
功能 |
实例 |
注释 |
mov |
给一个寄存器赋值 |
mov r0,#10 |
r0=10 |
mov r0,r1 |
r0=r1 |
||
mvn |
把一个数值按位取反后赋值给一个寄存器 |
mvn r0,#0xff |
r0=~0xff |
mvn r0,r1 |
r0=~r1 |
||
add |
计算两个数值的加法 |
add r0,r0,#10 |
r0=r0+10 |
add r0,r0,r1 |
r0=r0+r1 |
||
sub |
计算两个数值的减法 |
sub r0,r0,#10 |
r0=r0-10 |
sub r0,r0,r1 |
r0=r0-r1 |
||
mul |
乘法 |
mul r0,r1,r2 |
r0=r1*r2 |
cmp |
比较 |
cmp r0,r1 |
r0-r1影响CPSR标志位 |
cmp r0,#10 |
r0-10影响CPSR标志位 |
ldr r5,=20008000 ;20008000不是立即数,而是将它赋值为r5,此条指令是伪指令:伪指令在编译器编译的时候把伪指令分解为几条指令实现;
往寄存器中存放数据有三种方式:
1 mov 有效立即数
2 mvn 立即数按位取反的数
3 ldr 任何数
数据运算指令:
指令 |
功能 |
实例 |
注释 |
orr |
按位或 |
orr r0,r0,r1 |
r0=r0|r1 |
orr r0,r0,#10 |
r0=r0|10 |
||
and |
按位与 |
and r0,r0,r1 |
r0=r0&r1 |
and r0,r0,#10 |
r0=r0&10 |
||
bic |
位取反 |
bic r0,r0,r1 |
r0=r0&(~r1) |
bic r0,r0,#10 |
r0=r0&(~10) |
内存操作指令
指令 |
功能 |
实例 |
注释 |
swp Rd,Rm,[Rn] |
将寄存器中的值与内存地址中的值交换 注:Rn不能与Rd和Rm相同 |
swp r0,r1,[r2] |
r0=*r2 *r2=r1 |
ldr |
把数据从内存加载到寄存器 |
ldr r0,=addr |
r0=addr |
ldr r1,[r0] |
r1=*r0 |
||
ldr r1,[r0,#4] |
r1=*(r0+4) |
||
ldr r1,[r0,#4]! |
r1=*(r0+4);r0+=4 |
||
ldr r1,[r0],#4 |
r1=*r0;r0+=4 |
||
str |
把数据从寄存器保存到内存 |
str r1,[r0] |
*r0=r1 |
str r1,[r0,#4] |
*(r0+4)=r1 |
||
str r1,[r0,#4]! |
*(r0+4)=r1;r0+=4 |
||
str r1,[r0],#4 |
*r0=r1;r0+=4 |
str r1,[r0] 把r1存储到r0指向的内存地址(r0指向的地址是0x40000000)
ldr r1,[r0] 把r0指向的内存地址中的数据存储到r1寄存器中
/******************
r1、r2、r3、r4四个数据存储到0x20000000为首的地址空间 *****************/
mov r0,#0x20000000
mov r1,#0x11
mov r2,#0x22
mov r3,#0x33
mov r4,#0x44 str r1,[r0]
add r0,r0,#
str r2,[r0]
add r0,r0,#
str r3,[r0]
add r0,r0,#
str r4,[r0]
add r0,r0,#
内存连续操作指令
指令 |
功能 |
实例 |
ldmfd |
把数据从内存加载到寄存器 |
ldmfd sp!,{r0-r12,lr} |
stmfd |
把数据从寄存器保存到内存 |
stmfd sp!,{r0-r12,lr} |
ldr r0,=0x20000100
mov r1,#0x11
mov r2,#0x22
mov r3,#0x33
mov r4,#0x44
stmfd r0! ,{r1-r4} ;r0向下存储,先减4,在存储
ldmfd r0! ,{r5-r8} ;r0向上读取,先读取,再加4
实际中什么时候用到连续的存储数据或者读取数据?
在函数发生跳转或标签发生跳转的时候,我们需要保存现场和恢复现场。
CPU当前工作在一种模式下,比如SVC管理模式下,管理模式操作寄存器只有这么多,当发生函数跳转的时候,当前函数肯定有一些变量存到寄存器。跳转到另一个函数也有一些变量要存到寄存器,有可能冲突。所以需要保存现场
保存现场:保存到内存中stmfd
恢复现场:从内存恢复到寄存器ldmfd
保存现场
apcs规定r13(sp):指向内存地址
ldr sp,=0x20000100
mov r1,#0x11
mov r2,#0x22
stmfd sp! ,{r0-r12,r14} ;已经保存现场可以跳转到其他函数
ldmfd sp!,{r0-r12,r14};恢复现场
;可以跳转到其他函数
;函数不管跳转几次,始终要保证跳转之前和执行完毕,sp保持不变
跳转指令
指令 |
功能 |
实例 |
注释 |
b |
跳转 |
b lable |
跳转lable处执行 |
bl |
跳转并保存返回地址 |
bl lable |
保存下一条指令的地址到lr,并跳转到lable处执行 |
mov r0.#0x01
mov lr,pc ;lr专门用于备份pc,保存下一条指令(保存了mov r2,#0x02的地址)
b func1 ;如果没有mov lr,pc和mov pc,lr 函数就不会运行mov r2,#0x02
mov r2,#0x02
func1
mov r1,#0x03
mov pc,lr ;手动修改pc内容,函数返回返回
程序运行到mov lr,pc时,pc指针已经指向了mov r2,#0x02
mov lr,pc
b func1
这两天语句可以写为:bl funcl
注:b,bl都是相对跳转,通过偏移量跳转,最大跳转距离是±32MB,实现长跳转可以通过修改pc实现(绝对跳转)
;mov pc,#0x10 ;0x10代表func1所在地址
ldr pc,=0x10
总结:
1 b bl(相对跳转)短跳转
2 mov ldr修改pc实现长跳转(绝对跳转)
3 b mov ldr都不会保存返回地址,bl会保存返回地址
ARM基础的更多相关文章
- ARM基础知识
ARM处理器模式: 模式可以理解为 工作环境. 异常模式:SVC管理模式. FIQ 快速中断模式 . IRQ中断模式.Abort中止.Undef 未定义模式: 正常模式:System系统模式. Use ...
- Ok6410裸机驱动学习(二)ARM基础知识
1.ARM工作模式 ARM微处理器支持7种工作模式,分别为: l 用户模式(usr):ARM处理器正常的程序执行状态(Linux用户态程序) l 快速中断模式(fiq):用于高速数据传输或通道处理 ...
- arm指令bne.w改成b,即无条件跳转
近期逆向一个程序,需要把bne.w改成b,无条件跳转.由于ios逆向不像pc上,可以在od里直接改汇编指令,这篇文章给了我很大的帮助.通过memory write 修改后,验证可行后,再用ultrae ...
- 【ARM】arm系列知识框架
[ARM编程模型] 硬件: 电路原理图 软件: 体系结构, 指令集, 寄存器组 [ARM编程技术] 汇编/C语言 编译, 链接, 烧写和调试 windows: MDK linux : gcc [AR ...
- Rancher与ARM深化战略合作,“软硬结合”加速边缘计算时代
时至今日,许多企业已将边缘计算列为战略目标,对于部分企业而言,边缘计算则已成为它们势在必行的部分.而随着对应用软件和硬件能力的需求不断增长,容器和Kubernetes已发展为边缘计算领域备受瞩目的一项 ...
- 嵌入式Linux学习路线
最近比较忙,对于嵌入式的相关学习一直没有很好的开展.今天也看了不少的嵌入式Linux的学习路线,也和几个工作过的朋友聊了聊,想把之后的学习过程记录下来. 自己以后想从事驱动开发这方面的工作,因为大多数 ...
- 适合初学者的嵌入式Linux计划
俗话说万事开头难,刚开始的时候,你是否根本就不知如何开始,上网查资料被一堆堆新名词搞的找不到北,去图书馆看书也是找不到方向?又是arm,又是linux,又是uboot头都大了,不知道自己究竟从哪里开始 ...
- (翻译)与.NET容器映像保持同步
原文:https://blogs.msdn.microsoft.com/dotnet/2018/06/18/staying-up-to-date-with-net-container-images/ ...
- 1.ARM的基础知识
ARM简述 ARM公司既不生产芯片也不销售芯片,它只出售芯片技术授权.ARM技术具有很高的性能和功效,因而容易被厂商接受.同时,合作伙伴的增多,可获得更多的第三方工具.制造和软件支持,这又会使整个系统 ...
随机推荐
- css的position中absolute和fixed的区别
fixed:固定定位 absolute:绝对定位 区别很简单: 1.没有滚动条的情况下没有差异 2.在有滚动条的情况下,fixed定位不会随滚动条移动而移动,而absolute则会随滚动条移动 常用场 ...
- python set和get实现
import math class Square: # 正方形 def __init__(self, l): self.length = l # 边长 def __setattr__(self, ke ...
- python基础类型—数字(Number)
Python3 支持 int.float.bool.complex(复数). 在Python 3里,只有一种整数类型 int,表示为长整型,没有 python2 中的 Long. 像大多数语言一样,数 ...
- Q - Girls and Boys
来源poj1068 In the second year of the university somebody started a study on the romantic relations be ...
- redis操作封装类
class Redis { // 默认配置名称(使用load_config加载) private $_default_config_path = 'package/cache/redis'; ...
- react+dva+antd项目构建
一:版本升级 首先说明一下这里的dva是最新版: 2.3.2 1.初始化项目构建 npm install dva-cli -g dva -v dva-cli version 注:通过 npm 安装 d ...
- mui APP与服务器之间的交互原理
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name ...
- Apache ab并发负载压力测试(python+django+mysql+apache)
如标题,大家都知道秒杀中存在高并发使库存骤然为0,但在我们个人PC或小区域内是模拟不出这样的情景 现在利用 Apache ab并发负载压力测试 1,数据库建入库存字段并映射模型 2,view编写脚本 ...
- android studio/Intellij IDEA(MAC OSX)中android模拟器无法启动的一种原因
翻了stackoverflow上好多方式,各种重装重启清理缓存,都没有效果. 后来发现,用IDEA创建的模拟器的路径是 /Users/xirtam/.android/avd 而IDE使用的路径是 AN ...
- git的简单玩法
本篇笔记参考廖雪峰的git教程,为方便查看将命令部分提取并记录下来. 无意对原作的版权侵犯,如需要学习请到廖雪峰网站学习git 创建git仓库 # mkdir learngit && ...