ARM架构汇编系列教程:
ARM简介
ARM是Advanced RISC Machines的缩写,更早称作Acorn RISC Machine,ARM架构,过去称作高级精简指令集机器,是一个32位精简指令集处理器架构,广泛的应用于许多嵌入式系统设计。由于节能的特点,ARM处理器非常适合移动通信领域,符合其主要设计目标为低成本、高性能、低功耗的特性。ARM公司的特点是只设计芯片,而不生产。它将技术授权给世界上许多著名的半导体、软件和OEM厂商,并为其提供服务。
数据类型
与高级语言类似,ARM支持对不同数据类型的操作。我们可以加载(或存储)的数据类型可以是有符号和无符号字,半字或字节。 这些数据类型的扩展名为:-h 或 -sh 表示半字,-b 或 -sb 表示字节,没有字的扩展名。 有符号和无符号数据类型之间的区别是:
- 有符号数据类型可以包含正值和负值,因此范围较小。
- 无符号数据类型可以保存大的正值(包括“零”),但不能保持负值,因此范围更宽。
以下是一些示例,说明如何将这些数据类型与加载和存储指令一起使用:
ldr = Load Word
ldrh = Load unsigned Half Word
ldrsh = Load signed Half Word
ldrb = Load unsigned Byte
ldrsb = Load signed Bytes
str = Store Word
strh = Store unsigned Half Word
strsh = Store signed Half Word
strb = Store unsigned Byte
strsb = Store signed Byte
字节存储方式
在内存中存储数据有两种基本方法:Little-Endian(LE)或Big-Endian(BE)。
区别在于对象的每个字节存储在内存中的字节顺序。 在像Intel x86这样的小端机器上,最低有效字节存储在最低地址(最接近零的地址)。 在big-endian机器上,最重要的字节存储在最低地址。 ARM体系结构在版本3之前是小端的,因为它是双端的,这意味着它具有允许可切换字节序的设置。 例如,在ARMv6上,指令是固定的little-endian,数据访问可以是little-endian或big-endian,由程序状态寄存器(CPSR)的第9位(E位)控制。
处理器模式
ARM体系结构支持7种处理器模式,分别是:用户模式(usr)、系统模式(sys)、快速中断模式(fiq)、中断模式(irq)、管理模式(svc)、中止模式(abt)和未定义模式(und),如下表所示。这样做的好处是可以更好的支持操作系统并提高工作效率。
处理器模式 | 说明 | 备注 |
---|---|---|
用户(usr) | 正常程序工作模式 | 不能直接切换到其它模式 |
系统(sys) | 用于支持操作系统的特权任务等 | 但具有直接切换到其他模式等特权 |
快速中断(fiq) | 支持高速数据传输及通道处理 | FIQ异常响应时进入此模式 |
中断(irq) | 用于通用中断处理 | IRQ异常响应时进入此模式 |
管理(svc) | 操作系统保护代码 | 系统复位和软件中断响应时进入此模式 |
中止(abt) | 用于支持虚拟内存和存储器保护 | 用于MMU(内存管理单元) |
未定义(und) | 支持硬件协处理器的软件仿真 | 未定义指令异常响应时进入此模式 |
- 用户模式,限制程序的内存访问并且不能直接读取硬件设备。主要防止应用程序不当或恶意操作对系统的破坏。
- 系统模式和管理模式,主要用于SWI(软件中断)和OS(操作系统)。这个模式有额外的特权,允许你进一步控制计算机。例如,你比如进入超级用户来读取一个插件(podule)。但是不能在用户模式下完成。
- 中断模式,用来处理发生中断的外设。这个模式也是有特权的。导致中断的设备有键盘、串口、硬盘等等。
- 快速中断模式,用处理发起快速中断的外设。这个模式是有特权的
- IRQ和FIQ之间的区别是,对于FIQ,你必须尽快处理你的事情并离开这个模式。IRQ可以被FIQ所中断,但是IRQ不能中断FIQ。为了使FIQ更快,所以有更多的影子寄存器。FIQ不能调用SWI。FIQ还必须禁用中断。简言之,一切为了提高速度。
内部寄存器
在ARM处理器内部有37个用户可见的寄存器。其中31个通用寄存器,6个状态寄存器。
在不同的工作模式和处理器状态下,程序可访问的寄存器也不相同。
通用寄存器
R0~R12是普通寄存器。
R13是堆栈寄存器(SP,stack pointer),用于存放堆栈的栈顶指针。
R14是连接寄存器(LR, Linker Register),用于存放子程序的返回地址。
R15是程序计数器(PC,Program Counter),它的值是当前正在执行的指令的内存地址(每执行一条指令后+1)。
状态寄存器
CPSR寄存器(程序状态寄存器)
CPSR寄存器的格式:
- CPSR条件代码标志: 在做运算和条件判断时使用
寄存器位简称 | 说明 |
---|---|
N | 在结果是有符号的二进制补码情况下,如果结果为负数,则N=1;如果结果为非负数,则N=0 |
Z | 如果结果为0,则Z=1;如果结果为非零,则Z=0。 |
C | 其设置分一下几种情况:对于加法指令,如果产生进位,则C=1;对于减法指令(包括比较指令CMP),如果产生借位,则C=0;对于有移位操作的非法指令,C为移位操作中最后移出位的值;对于其他指令,C通常不变。 |
V | 对于加减法指令,在操作数和结果是有符号的整数时,如果发生溢出,则V=1;如果无溢出发生,则V=0;对于其他指令,V通常不发生变化。 |
Q | 在ARMv5及以上版本的E系列处理器中,用来指示增强的DSP运算指令是否发生了溢出 |
- CPSR模式位设置表:
M[4:0] | 模式 | 可见的Thumb状态寄存器 | 可见的ARM状态寄存器 |
---|---|---|---|
10000 | usr | R0-R7,SP,LR,PC,CPSR | R0-R14,PC,CPSR |
10001 | fiq | R0-R7,SP_fiq,LR_fiq,PC,CPSR,SPSR_fiq | R0-R7,R8_fiq-R14_fiq,PC,CPSR,SPSR_fiq |
10010 | irq | R0-R7,SP_irq,LR_irq,PC,CPSR,SPSR_irq | R0-R12,R13_irq,R114_irq,PC,CPSR,SPSR_irq |
10011 | scv | R0-R7,SP_svc,LR_svc,PC,CPSR,SPSR_svc | R0-R12,R13_scv,R114_scv,PC,CPSR,SPSR_scv |
10111 | abt | R0-R7,SP_abt,LR_abt,PC,CPSR,SPSR_abt | R0-R12,R13_abt,R114_abt,PC,CPSR,SPSR_abt |
11011 | und | R0-R7,SP_und,LR_und,PC,CPSR,SPSR_und | R0-R12,R13_und,R114_und,PC,CPSR,SPSR_und |
SPSR寄存器(保存程序状态寄存器)
与SPSR的值一样,由硬件自动讲异常发生前的CPSR的值存放到SPSR中,以便在异常处理结束后,程序可能恢复到原来的CPSR的值。