ARM汇编指令

数据和指令类型

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_
        设置适当的 CPSR 位: 偏移向量表
        改变处理器状态进入 ARM
        改变处理器模式进入相应的异常模式
        设置中断禁止位禁止相应中断 (如果需要)
        保存返回地址到 LR_
        设置 PC 为相应的异常向量
返回时, 异常处理需要:
        从 SPSR_恢复CPSR
        从LR_恢复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汇编语言中常用的伪操作
伪操作 语法格式 作用
CODE16 CODE16 告诉汇编编译器后面的指令序列为16位的Thumb指令
CODE32
CODE32
告诉汇编编译器后面的指令序列为 32 位的ARM 指令
AREA
AREA sectionname {,attr} {,attr}
定义一个代码段或者数据段
ENTRY ENTRY 指定程序的入口点
END END 告诉编译器已经到了源程序结尾
EXPORT EXPORT symbol {[WEAK]} 声明一个符号可以被其他文件引用
SPACE {label} SPACE expr
分配一块连续内存单元,并用 0 初始化
DCD {label} DCD expr {expr} 分配一段字内存单元
ARM汇编语言语句格式如下所示:
        {symbol {;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 位的立即数或者一个地址值读取到
寄存器中。大范围的地址读取。
NOP NOP 在汇编时将被替换成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
上述指令只能对寄存器操作,不能针对存储器。
语法:
        <操作>{}{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=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
建议把常数装载到寄存器中时一律使用该伪指令。    

你可能感兴趣的:(arm开发,汇编)