ARM汇编指令

发布时间:2024年01月11日

数据和指令类型

ARM采用的是32位架构
ARM约定:
Byte:8 bits
Halfword:16 bits (2 byte)
Word:32 bits (4 byte)
Doubleword:64-bits(8byte) (Cortex-A处理器)
大部分ARM core 提供:
ARM 指令集(32-bit)
Thumb 指令集(16-bit )
Cortex-A 处理器
16 位和 32 Thumb-2 指令集
16 位和 32 ThumbEE 指令集
Jazelle cores 支持 Java bytecode
ARM有7个基本工作模式
User:非特权模式,大部分任务执行在这种模式
FIO:当一个高优先级 (fast) 中断产生时将会进入这种模式
IRQ:当一个低优先级(normal) 中断产生时将会进入这种模式
Supervisor:当复位或软中断指令执行时将会进入这种模式
Abort:当存取异常时将会进入这种模式
Undef:当执行未定义指令时会进入这种模式
System:使用和User模式相同寄存器集的特权模式
Cortex-A特有模式:
Monitor:是为了安全而扩展出的用于执行安全监控代码的模式;也是一种特权模式
异常处理
当异常产生时 , ARM core:
????????拷贝 CPSR SPSR_<mode>
????????设置适当的 CPSR 位: 偏移向量表
????????改变处理器状态进入 ARM
????????改变处理器模式进入相应的异常模式
????????设置中断禁止位禁止相应中断 (如果需要)
????????保存返回地址到 LR_<mode>
????????设置 PC 为相应的异常向量
返回时, 异常处理需要:
????????从 SPSR_<mode>恢复CPSR
????????从LR_<mode>恢复PC
????????Note:这些操作只能在 ARM 态执行
偏移向量表
0x1C? ? ? ? ? ? ? ?FIQ
0x18? ? ? ? ????????IRQ
0x14? ? ? ? ????????Reserved
0x10? ? ? ? ????????Data Abort
0x0C????????????????Prefetch Abort
0x08? ? ? ? ????????Software Interrupt
0x04? ? ? ? ????????Undefined Instruction
0x00? ? ? ? ????????Reset
指令流水线
为增加处理器指令流的速度,ARM7 系列使用3级流水线
允许多个操作同时处理,而非顺序执行
PC指向正被取指的指令,而非正在执行的指令
对齐
存储器访问必须始终适当地保持地址对齐
????????非对齐地址将产生不可预测的/未定义的结果
用‘Data Abort’ 异常来检测无效的非对齐数据存取
????????需要额外的扩展逻辑,或者MMU来实现
????????谨防指令读取时出现非对齐
非对齐数据存取能够完成, 但不是用 LDR
????????使用 LDRB, STRB 传递字节,或使用LDM 加移位/屏蔽
ARM汇编中的文件格式
基于ARM的工程源代码由以文件形式组织。
ARM源程序文件(可简称为源文件)可以由任意一种文本编辑器来编写程序代码,它一般为文本格式。在ARM程序设计中,常用的源文件可简单分为以下几种:
源程序文件文件名说明
汇编程序文件*.S *.s
用ARM汇编语言编写的ARM程序
或Thumb程序( 汇编代码可直接操作CPU内部的REG)
C程序文件*.C *.c用C语言编写的程序代码
头文件*.H *.h
为了简化源程序,把程序中常用到的常量命名、宏定义、
数据结构定义等等单独放在一个文件中,一般称为头文件
ARM汇编语言程序格式
???????
????????ARM汇编语言是以段(section)为单位来组织源文件的。段是相对独立的、具有特定名称的、不可分割的指令或者数据序列。
????????段又可以分为代码段和数据段,代码段存放执行代码,数据段存放代码运行时需要的数据。
????????一个ARM源程序至少需要一个代码段,大的程序可以包含多个代码段和数据段。
????????在汇编文件中,我们需要先定义一个段,在段中添加我们实现的汇编程序语句。
ARM汇编语言中常用的伪操作
伪操作语法格式作用
CODE16CODE16告诉汇编编译器后面的指令序列为16位的Thumb指令
CODE32
CODE32
告诉汇编编译器后面的指令序列为 32 位的ARM 指令
AREA
AREA sectionname {,attr} {,attr}
定义一个代码段或者数据段
ENTRYENTRY指定程序的入口点
ENDEND告诉编译器已经到了源程序结尾
EXPORTEXPORT symbol {[WEAK]}声明一个符号可以被其他文件引用
SPACE {label} SPACE expr
分配一块连续内存单元,并用 0 初始化
DCD{label} DCD expr {expr}分配一段字内存单元
ARM汇编语言语句格式如下所示:
????????{symbol<instruction | directive | pseudo-instruction> {;comment
其中:
????????instruction? ? ? ? ? ? ? ? ? ? ? ? ? ? ?为指令。
????????directive ???????????????????????????????为伪操作。
????????pseudo-instruction ?????????????为伪指令。
????????symbol? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 为标号。
????????comment ?????????????????????????????为语句的注释。
ARM汇编语言的伪指令
伪指令语法格式作用
ADR
ADR{cond} register, expr
将基于 PC 或基于寄存器的地址值读取到
寄存器中。小范围的地址读取。
ADRL
ADRL{cond} register, expr
将基于 PC 或基于寄存器的地址值读取到
寄存器中。中等范围的地址读取。
LDR
LDR {cond} register,? =[ expr | label-expr]
将一个 32 位的立即数或者一个地址值读取到
寄存器中。大范围的地址读取。
NOPNOP在汇编时将被替换成ARM中的空操作。
指令分类及指令格式
ARM 指令集可以分为六大类
????????1.分别为数据处理指令 ( 完成 CPU 内部的计算)
????????2. Load/Store指令 ( 完成 CPU 与内存 IO 外设之间的数据传输)
????????3. 跳转指令 ( 完成程序的跳转)
????????4. 程序状态寄存器处理指令 ( 完成 CPSR 的管理 )
????????5. 协处理器指令 ( 完成 CPU 扩展功能的实现 )
????????6. 异常产生指令 ( 用户程序异常触发 )
指令格式中符号说明
????????〈opcode〉{cond}{S} Rd〉,〈Rn{,〈operand2〉}
opcode? ? ? ? ?操作码;指令助记符,如 LDR STR 等。
cond? ? ? ? ? ? ?可选的条件码;执行条件,如EQ、NE 等。
S? ? ? ? ? ? ? ? ? 可选后缀;若指定“S”,则根据指令执行结果更新CPSR中的条件码。
Rd? ? ? ? ? ? ? ? 目标寄存器。
Rn????????????????存放第1操作数的寄存器。
Operan? ? ? ? ?d2 第 2 个操作数
数据处理指令
? 算术指令:
ADD????????ADC????????SUB????????SBC????????RSB????????RSC
位运算指令:
AND????????ORR????????EOR????????BIC
比较指令:
CMP????????CMN????????TST????????TEQ
数据搬移:
MOV????????MVN
上述指令只能对寄存器操作,不能针对存储器。
语法:
????????<操作>{<cond>}{S} Rd, Rn, Operand2
? ????????只有比较指令影响标志位 -不指定Rd
????????数据搬移(MOV指令)不指定Rn
第二个操作数通过桶型移位器送到ALU中。 ? ?
条件码
下表为所有可能的条件码:
注意:AL为默认状态,不需要单独指出
Suffix
描述
测试的标志位
EQ
等于(Equal)
Z=1
NE不等于(Not Equal)Z=0
CS/HS
无符号的大于或等于
C=1
CC/LO
无符号的小于
C=0
MI
负数(Minus)
N=1
PL
正数或零
N=0
VS
溢出(Overflow)
V=1
VC
没溢出
V=0
HI
无符号的大于
C=1?&?Z=0
LS
无符号的小于或大于
C=0 |?Z=1
GE
大于等于
N=V
LT
小于(Less Than)
N!=V
GT
大于(Greater Than)
Z=0 & N=V
LE
小于等于
Z=1 |?N=!V
AL
总是执行(Always)
立即数
没有任何一条 ARM 指令可包括一个 32 bit 的立即数
?????? ??所有的ARM指令都是32 bits固定长度
数据处理指令格式中,第二个操作数有 12
4 bit 移位值 (0-15) 乘于 2 ,得到一个范围在 0-30 ,步长为 2 的移位值
记住一条准则:“最后 8 位一定要移动偶数位”
? 下列命令中,汇编器把立即数转换为移位操作:
????????MOV r0, #4096? ? ? ? ? ? ? ? ? ? ? ? ? ? ;uses 0x40 ror 26
????????ADD? r1, r2, #0xFF0000? ? ? ? ? ? ? ?;uses 0xFF ror 16
也可使用 MVN来进行位反转:
????????MOV r0, #0xFFFFFFFF ??????????????;assembles to MVN r0 , # 0
立即数不能使用上述方法产生,否则将导致错误。 ?
装载32 bit常数
? ? 为允许装载大常数,汇编器提供了一条伪指令:
????????LDR rd, =const
它可能汇编成下列指令:
????????MOV or MVN
????????LDR 指令,从数据池(Literal pools)读取常数。
For example
????????LDR r0, =0xFF => MOV r0,#0xFF
????????LDR r0, =0x55555555 => LDR r0,[PC,#Imm12]
????????…
????????…
? ? ? ? DCD 0x55555555
建议把常数装载到寄存器中时一律使用该伪指令。 ? ?
文章来源:https://blog.csdn.net/qq_58687815/article/details/135537613
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。