当前位置: 首页 > news >正文

ARM的汇编指令集

一、汇编指令

1.1 指令与伪指令

汇编的指令

指令是CPU机器指令的助记符,编译后会得到一串二进制机器码,由CPU执行

汇编的伪指令

伪指令本质上不是指令,它是编译器环境提供用来指导编译过程,编译后伪指令不会生成机器码
伪指令的意义在于指导编译过程

区别

经过编译后会不会生成二进制机器码

1.2 gun汇编中的符号

符号作用
@用来做注释,可以在行首也可以在代码后面同一行直接跟,和C语言中 // 类似
以冒号结尾的是标号
.点号在gnu汇编中表示当前指令的地址
#立即数前面要加#或$,表示这是个立即数

1.3 gun汇编中的伪指令

1、ARM中有一个ldr指令,还有一个ldr伪指令,一般都使用ldr伪指令而不用ldr指令

2、adr与ldr:
① adr编译时会被sub或add指令替代,
② ldr编译时会被mov指令替代或者文字池方式处理
③ adr总是以PC为基准来表示地址,指令本身和运行地址有关,用来检测程序当前的运行地址在哪里
④ ldr加载的地址和链接时给定的地址有关,由链接脚本决定

符号作用
ldr大范围的地址加载
adr小范围的地址加载
adrl中等范围的地址加载
nop空操作
.global _start给_start外部链接属性
.section .text指定当前段为代码段
.align 4以16字节对齐
.balignl 1616字节对齐填充
.end标识文件结束
.include头文件包含
.arm / .code32声明以下为arm指令
.thumb / .code16声明以下为thubm指令
.ascii .byte .short .long定义数据
.word.quad .float .string定义数据

二、不同风格的ARM指令

ARM官方的ARM汇编风格
指令一般用大写、 Windows中IDE开发环境(如ADS、MDK等)常用。

LDR R0, [R1]

GNU风格的ARM汇编
指令一般用小写字母、 linux中常用。

 ldr r0, [r1]

三、ARM汇编的特点

3.1 LDR/STR架构

1、 ARM的CPU不能直接读取内存,需要先将内存加载到CPU通用寄存器中才能被CPU处理
2、 ldr(load register)指令将内存加载到通用寄存器
3、 str(store register)指令将寄存器内容保存到内存空间
4、 ldr/str组合用来实现 ARM CPU和内存之间数据的交换

3.2 8种寻址方式

寻址方式例子
寄存器寻址mov r1, r2
立即寻址mov r0, #0xFF00
寄存器移位寻址mov r0, r1, lsl #3
寄存器间接寻址ldr r1, [r2]
基址变址寻址ldr r1, [r2, #4]
多寄存器寻址ldmia r1!, {r2-r7,r12}
堆栈寻址stmfd sp!, {r2-r7, lr}
相对寻址beq flag flag:

3.3 指令后缀

汇编指令中,同一指令经常附带不同后缀,变成不同的指令

经常使用的后缀有:

1、B(byte)功能不变,操作长度变为8位
2、H(half word)功能不变,长度变为16位
3、S(signed)功能不变,操作数变为有符号
4、S(S标志)功能不变,影响CPSR标志位

//	B    H    SB    SH
ldr ldrb ldrh ldrsb ldrsh
//mov和movsmovs r0, #0

3.4 条件执行后缀

操作码条件码助记符标志含义
0000EQZ=1相等
0001NEZ=0不相等
0010CS/HSC=1无符号数大于或等于
0011CC/LOC=0无符号数小于
0100MIN=1负数
0101PLN=0正数或零
0110VSV=1溢出
0111VCV=0没有溢出
1000HIC=1、Z=0无符号数大于
1001LSC=0、Z=1无符号数小于或等于
1010GEN=V有符号数大于或等于
1011LTN!=V有符号数小于
1100GTZ=0、Z=V有符号数大于
1101LEZ=1、Z!=V有符号数小于或等于
1110AL任意无条件执行(指令默认条件)
1111NV任意从不执行(不要使用)

3.5 8种后缀

后缀含义
ia先传输,再地址+4
ib先地址+4,再传输
da先传输,再地址-4
db先地址-4,再传输
fd满递减堆栈
ed空递减堆栈
fa满递增堆栈
ea空递增堆栈

3.6 4种栈

空栈:栈指针指向空位,存入时可直接存入然后指针移动一格;取出时需要先移动一格才能取出

满栈:栈指针指向栈中最后一格数据,每次存入时需要先移动栈指针一格再存入;取出时可以直接取出,然后再移动栈指针

增栈:栈指针移动时向地址增加的方向移动的栈

减栈:栈指针移动时向地址减小的方向移动的栈

注意:操作栈时使用相同的后缀就不会出错

四、ARM汇编的常用指令

4.1 数据处理指令

指令类型指令
数据传输指令mov mvn
算术指令add sub rsb adc sbc rsc
逻辑指令and orr eor bic
比较指令cmp cmn tst teq
乘法指令mvl mla umull umlal smull smlal
前导零计数clz

4.2 CPSR访问指令

CPSR寄存器比较特殊,需要专门的指令进行访问

指令类型指令
mrs读取psr
msr写入psr

4.3 跳转指令

指令作用
b直接跳转(跳转后不返回)
bl跳转前把返回地址放入lr中,用于函数调用返回
bx跳转同时切换到ARM模式,用于异常处理的跳转

4.4 访存、软中断指令

ldr/str每周期只能访问4字节内存,如果需要批量读取、写入内存时太慢

stm/ldm每周期可以批量读取、写入内存

指令作用
ldr/str单个字/半字/字节访问
ldm/stm多字批量访问
swi(software interrupt)软中断指令,用来实现操作系统中系统调用

4.5 协处理器操作指令

1、SoC内部另一处理核心,协助主CPU实现某些功能,被主CPU调用执行一定任务
2、ARM设计上支持16个协处理器,一般SoC只实现其中的CP15
3、协处理器和MMU、 cache、 TLB等处理有关
4、功能上和操作系统的虚拟地址映射、cache管理等有关

指令作用
mrc用于读取CP15中的寄存器
mcr用于写入CP15中的寄存器

五、ARM汇编符号的作用

5.1 ! 的作用

ldmia r0   , {r2 - r3}
ldmia r0! , {r2 - r3}

!的作用

r0的值在ldm过程中发生的增加或者减少最后写回到r0去

也就是说ldm时会改变r0的值。

5.2 ^ 的作用

ldmfd sp!, {r0 - r6, pc}
ldmfd sp!, {r0 - r6, pc}^

^ 的作用:在目标寄存器中有pc时,会同时将spsr写入到cpsr,一般用于从异常模式返回

http://www.lryc.cn/news/22558.html

相关文章:

  • @font-face用法超详细讲解
  • [oeasy]python0095_乔布斯求职_雅达利_atari_breakout_打砖块_布什内尔_游戏机_Jobs
  • 全景极简印度史
  • 《设计模式》模板方法
  • Linux环境内存管理——链表
  • String、StringBuffer、StringBuilder类
  • 在VScode中添加Linux中的Docker容器中的Python解释器
  • 无法将“django-admin”项识别为cmdlet,函数,脚本文件或可运行程序的名称问题
  • 乐友商城学习笔记(十五)
  • 目标检测论文阅读:CBNet算法笔记
  • vue前端与Java后端进行跨域交互
  • 【设计模式】2.抽象工厂模式
  • Telnet 基础实验1: Telnet 实验
  • 机器学习经典算法——决策树(Decision Tree)
  • MySQl总结
  • 【学习笔记】NOIP爆零赛7
  • 一文读懂账号体系产品设计
  • 从“入门”到“专家”,一份3000字完整的性能测试体系的知识分享
  • 构建对话机器人:Rasa3安装和基础入门
  • Spark计算框架入门笔记
  • 入职数据分析公认的好书|建议收藏
  • Linux查找文件和目录,重定向输出 ,系统默认运行级别的查看和设置理论和练习
  • Redis源码---键值对中字符串的实现,用char*还是结构体
  • 算法 - 剑指Offer 表示数值的字符串
  • 初识机器学习
  • VsCode安装PlatformIO 开发ESP arduino,买的板子或者随便ESP,PlatformIO添加Board(不是自定义Board)
  • golang 复杂数据结构解析
  • 不怕被AirTag跟踪?苹果Find My技术越来越普及
  • Linux驱动中的open函数是如何从软件打通硬件呢?
  • Java 基础语法