基于Armv7核心架构的CPU核心基础指令集。
寄存器是CPU的内部元件之一,其作用是存储二进制代码,ARM属于精简指令集架构(RISC),共有37个寄存器,其中包括31个通用寄存器和6个状态寄存器。本文主要介绍一些常用寄存器相关的基础指令。
R0-R12为一般通用寄存器
其中,0-7为未分组寄存器,即任何工作模式下都指向同一个32为的物理寄存器。而8-12为分组寄存器,即在不同模式下,同一个寄存器的名称对应不同的物理寄存器。
R13为堆栈指针(Stack Pointer, SP)
其作用是当程序进入异常模式时,可将需要保存的寄存器数据放入R13中。当程序返回正常模式时,从对应的堆栈中恢复数据。
R14为链接寄存器(Link Regist, LR)
链接寄存器的作用有两个:
1. 存储当前子程序的返回地址。
2. 当异常或中断发生时,被设置为要返回的地址。
R15为程序计数器(Program Counter, PC)
其作用为指向下一条要读取指令的地址。
当前程序状态寄存器(Current Program Status Register, CPSR)
用于存储当前程序状态寄存器的内容,包括:条件标志位、中断禁止位、当前处理器模式和其他状态和控制信息。
存储在内存中的指令的长度通常是32位(bit),而每个内存地址值为1字节(byte)=8位。因此,一条指令的地址指向为从该地址开始的4个字节。例如,当一条指令正在执行时,程序计数器R15就会加4。
使用软件:VisUAL2
VisUAL2是一个用于编写中小型汇编程序的模拟器,作为一个跨平台工具,其提供的快速编写和调试可视化的功能可以更直观的展示寄存器在运行不同程序和指令时的内部存储的变化,帮助初学者更好地理解和学习ARM汇编。
下载链接:VisUAL2 - 用于ARM UAL的用户友好型教育汇编器和模拟器
加法(Add): ADD Rd, Rn, op2
减法(Subtract): SUB Rd, Rn, op2
逆向减法(Reverse Subtract): RSB Rd, Rn, op2
乘法(VisUAL不支持): MUL {Rd}, Rn, Rm
除法(ARMv7不支持)-------------------------------------
声明:Rd是保存的结果的目的寄存器,Rn是用于保存第一个操作数的寄存器,op2是第二操作数,可以一个是寄存器,也可以是一个立即数。(只有op2可以表示为立即数,且当其作为立即数时,需要在前面加上‘ # ’用以声明)
示例:
MOV Rd, op2
解释:将一个值从op2复制到Rd寄存器,op2可以是一个寄存器或者直接数
示例:
LSL Rd, Rm, Rs
LSL Rd, Rm, #sh
LSR Rd, Rm, Rs
LSR Rd, Rm, #sh
ASR Rd, Rm, Rs
ASR Rd, Rm, #sh
ROR Rd, Rm Rs
ROR Rd, Rm #sh
声明:Rd为保存结果的寄存器,Rm、Rs分别为第一第二操作数,#sh为一个范围在0~31之间的立即数。
其中,LSL和LSR为逻辑左移和逻辑右移,就是将操作数Rm按照操作数Rs指定的数量向左或向右移位,空位用0填充。
ASR为算数右移,对于左边的空位,如果操作数Rm最高位为1,则补1,反之补0。
ROR为循环右移,即将向右移出的每一个最低位复制到最高位。
AND Rd, Rn, op2
EOR Rd, Rn, op2
BIC Rd, Rn, op2
ORR Rd, Rn, op2
其中,AND为逻辑与,对两个操作数进行逻辑与操作(对应位数都为1则取1,其余情况取0),并把结果放到目的寄存器Rd中。
EOR为逻辑异或,即对应位数为不同值时取1,其余情况取0。
BIC为位清除,指令对Rn中的值和op2值的反码按位进行与运算,实现对需要的位清零的功能。
ORR为逻辑或,即对Rn的值和op2的值进行或运算,并将结果保存到目的寄存器中。
在第一部分的最后,我们来说明一下和指令编码相关的内容。
对于一条指令,其组成包括指令操作,条件,标志和操作数,不同的操作指令都有其相应的二进制码。寄存器用4位进行描述,共有16个。
而对于操作数op2,判断其是不是一个立即数是尤为重要的,为什么?
这是因为ARM的指令格式规定指令码中低的12位是用于表示需要操作的常数。但是12位显然无法满足操作的全部需求,因此为了将其扩展到32位,使用了一种狗仔方法将这12位分为两部分,用8位表示数据值,4位表示位移值。用8位的数据值向右循环移动(位移值*2)次,表示操作数。虽然这个方法扩大了操作数的范围,但随之产生的问题就是,并不是每个数都能通过基本数循环位移偶数次得到的,这些数就不是立即数,所以在使用之前必须进行判断。
判断立即数的步骤:
1. 将操作数用32位的二进制数表示,高位不够补0。分两次看这个数中1的最大间隔是多少,第一次按顺序看,第二次循环看,将首位相连,包括首位两位。如果两次的最大间隔都大于8,这个数即为非法操作数。如果有一次小等于8,则可能合法。
此时分情况,如果是顺序看时最大间隔等于8,就看最高位前面和最低位后是否有偶数个0,满足其中一个,这个数就是合法的。如果是循环看时最大间隔小等于8,此时可以看两端的间隔个数是否有一个为偶数,如果有,那么这个数就是合法的。