文章目录
指令基础
指令周期和时序
时钟信号:是一个周期性的脉冲信号
时钟周期(clock cycle):一个时钟脉冲的时间长度,是主频的倒数
时钟频率:也称为主频,一秒内,时钟信号的个数
指令周期(instruction cycle):执行一条指令需要的时间,不同指令的指令周期不同,和操作数的寻址方式也有关,一般情况下,以访问寄存器所需的最长时间来衡量指令周期
对于ARM7而言,所有存储器的传输周期都可以被归结到以下4个类型:
- 不连续周期:上一次和本次访问的操作数地址没有联系,称为访问非顺序内存位置的周期,简称N周期
- 连续周期:上一次和本次访问的操作数地址相同或连续,称为访问顺序内存位置的周期,简称S周期
- 内部周期:ARM不请求传输,只是执行内部功能,称为内部周期,简称I周期
- 协处理器寄存器传输周期:ARM与协处理器之间的数据总线传输一个字的周期,简称C周期
程序的执行过程
执行一条指令的过程可以分为:取指、译码、执行
- 取指:CPU进入取指阶段,通过控制总线(control bus)发出读命令,并从地址总线(addr bus)所给出的地址,即存储器中取出指令代码,经过数据总线送到CPU的指令寄存器中
- 译码:翻译取出的指令代码
- 执行:执行代码指定的动作
ARM汇编语言
指令和指令格式
指令和指令系统
指令:指示计算机进行某种操作的命令
指令系统:指令的集合称为指令系统
助记符:指令的符号表示
指令的表示方法
指令在内存中,以二进制形式保存
ARM指令代码一般可以分为5个域:
- 【31:28】:条件码域
- 【27:20】:指令码域,除指令编码外,还包含几个很重要的指令特征和可选后缀的编码
- 【15:12】:地址基址Rn,为R0-R15共16个寄存器编码
- 【15:12】:目标或源寄存器Rd,为R0-R15共16个寄存器编码
- 【11:0】:地址偏移或操作寄存器、操作数区
汇编的指令格式
操作码 指令的执行条件 S 目的操作数 源操作数 源操作数2
<opcode> {
<cond>} {
S} <Rd>, <Rn> {
, <OP2>}
- <> :括号里的内容必不可少
- {} : 括号里的内容可省略
- opcode:操作码,如ADD表示加法
- cond:指令执行的条件域,如EQ,NE,省略则为默认AL,无条件执行
- S:决定指令的执行结果是否影响CPSR的值,使用该后缀则影响
- Rd:目的操作数的寄存器
- Rn:第一个操作数的寄存器
- OP2:第二个操作数,可以是立即数、寄存器、偏移地址
指令的可选后缀
ARM指令集中大多数指令,都可以加后缀,这使得指令的使用更加灵活,常见的S和!
S后缀
- 指令使用“S”后缀时,指令执行后程序状态寄存器的条件标志位被刷新
- 不使用“S”后缀时,条件标志位不改变
- “S”后缀通常用于对条件进行测试,例如是否溢出、进位等
!后缀
- 地址表达式中不含“!”,则基址寄存器中的地址值不会发生变化
- 含有“!”,基址寄存器中的地址值发生变化,基址寄存器的值,变为原来的值再加上偏移地址
例如:LDR R3,[R0,#4],关键在于R0是否发生变化
使用“!”需要注意:
- 必须紧跟在地址表达式的后面,而地址表达式要有明确的偏移量
- 不能用于R15(PC)后面
- 当用在单个地址寄存器后面时,必须确信这个寄存器有隐形的偏移量
指令的条件执行
- 程序要执行的指令都保存在存储器中,需要执行时,先产生地址,再根据地址,去存储器取出指令代码,然后译码执行
- 当工作在ARM状态时,几乎所有的指令都根据CPSR中条件码和指令的条件域,有条件的执行,不满足则忽略
- ARM指令包含4位条件码,位于【31:28】,共16种,每种可用两个字母表示,它可以添加在指令助记符后面和指令同时使用
条件后缀和S后缀的关系: - 都存在时,S写后面,如ADDEQS
- 条件后缀是要测试条件标志位,而S后缀是要刷新条件标志位
- 条件后缀要测试的是执行前的标志位,而S后缀在执行后改变标志位
ARM指令分类
ARM指令集可以分为:数据处理指令、数据加载存储指令、分支指令、程序状态寄存器PSR处理指令、协处理器指令、异常产生指令
ARM指令的寻址方式
寻址方式:根据操作数的信息,来寻找操作数对应的实际物理地址
立即寻址
MOV R0,#5
#5就是立即寻址,必须加#前缀
对于十进制,可以加0d或缺省,如:#0d5
对于十六进制,必须加0x或者&,如:#0x5
对于二进制,必须加0b,如:#0b11
寄存器寻址
寄存器寻址,就是利用寄存器中的数值作为操作数
ADD R0, R1, R2
R1+R2 -> R0
寄存器间接寻址
以寄存器的值作为操作数的地址,而操作数本身存放在存储器中
LDR R0, [R4]
以R4的值为地址,去存储器中找到对应物理地址,取出的数才是操作数
寄存器移位寻址
操作数由寄存器的值经过移位后得到,移位的方式在指令中以助记符给出
ADD R0, R1, R2, LSL #1
R1 + (R2 << 1) -> R0
MOV R0, R1, LSL R3
(R1<<3) -> R0
基址变址寻址
将寄存器的内容,与指令给出的偏移地址相加,得到操作数的地址,操作数在存储器中
LDR R0, [R1. #4]
[R1+4] -> R0
LDR R0, [R1. #4]!
[R1+4] -> R0, R1+4 -> R1
LDR R0, [R1], #4
[R1] -> R0, R1+4 -> R1
LDR R0, [R1. R2]
[R1+R2] -> R0
多寄存器寻址
一条指令可以完成多个寄存器值的传送,连续的寄存器用“-”连接,否则用“,”连接
LDMIA R0!, {R1-R4}
[R0] -> R1
[R0+4] -> R2
[R0+8] -> R3
[R0+12] -> R4
该指令的后缀IA表示,每次执行完加载/存储操作后,R0按(32位)增加
相对寻址
相对寻址以程序计数器PC的当前值为基地址,指令中的地址标号作为偏移量,相加之后,得到操作数的地址,一般用于子程序的调用,中断异常的处理
堆栈寻址
使用堆栈指针表示当前栈顶位置,R13一般为堆栈指针
ARM中采用LDMFD、STMFD指令来支持POP和PUSH操作
STMFD R13!, {R0-R4}
LDMFD R13!, {R0-R4}
S-STORE,将R0-R4压栈
L-LOAD,将R0-R4出栈
数据处理指令
数据处理指令对存放在寄存器中的数据进行操作,分为
- 数据传送指令
- 算术指令
- 逻辑运算指令
- 比较指令
- 乘法指令
ARM数据处理指令机器编码格式如下:
- cond:指令执行的条件码
- I:用于区别第二操作数是立即数(I=1)还是寄存器移位(I=0)
- opcode:数据处理指令操作码
- S:用于设置条件码,S=0时条件码不变
- Rn:第一操作数寄存器
- Rd:目标寄存器
- op2:第二操作数,该操作数可以是立即数或寄存器移位数
数据传送指令
将一个寄存器中的数据或立即数,传送到另一个寄存器
MOV
MOV {
<cont>} {
S} Rd, op2
功能:
- MOV指令将源操作数op2传送到Rd中,通常op2是立即数、寄存器Rm、或寄存器Rm移位
- S决定结果是否影响CPSR中条件标志位
MOV R1, R0
R0 -> R1
MOV PC, R14
R14 -> PC,常用于子程序返回
MOV R1, R0, LEL #3
(R0<<3) -> R1
MOV R0, #5
5 -> R0
MVN
MVN {
<cont>} {
S} Rd, op2
功能:
- 将一个寄存器、移位寄存器、立即数传送到目的寄存器Rd
- 数据在传送之前按位取反
- S决定结果是否影响CPSR中条件标志位
MVN R0, #1
MVN R1, R2
移位操作
- ARM微处理器一个特点:在操作数进入ALU之前,对操作数进行预处理,如左移和右移
- 这种处理是通过内嵌的桶形移位器(barrel shifter)实现的
- 桶形移位器支持数据的各种移位操作,移位操作在ARM指令集不再作为单独的指令使用,而是作为一个选项
- 包括逻辑左移LSL,逻辑右移LSR,算术右移ASR,循环右移ROR,带扩展的循环右移RRX
LSL
Rm, LSL<opl>
- LSL指令完成对通用寄存器Rm中的内容进行逻辑左移,按opl指定的位数移位,低位用0填充,相当于无符号数乘2^n
- opl可以是立即数,也可以是寄存器方式
LSR
Rm, LSR<opl>
- 寄存器Rm右移opl指定的次数,空位用零填充,opl的要求如同LSL
ASR
Rm, ASR<opl>
- 寄存器Rm按opl指定的次数右移,其中高位用31位原本的值填充(注意有符号数的负数,31位为1)
- opl的要求同上,但是范围限制到1-32
ROR
Rm, ROR<opl>
- 右移指定次数,其中空出来的最高位,用最低位移出去的数来补
- opl要求同上,范围限制1-31
RRX
Rm, RRX
对通用寄存器中的内容进行RRX右移一位时,该寄存器的32位+C标志位,一共33位组成一个循环右移
算术指令
主要是加减法,实现两个32位数据的加减操作,通常与桶形移位器结合起来,实现许多灵活的功能
主要包括:加法ADD,带进位加法ADC,减法SUB,带借位减法SBC,逆向减法RSB,带借位逆向减法RSC
ADD
ADD {
<cont>} {
S} Rd, Rn, op2
- 将Rn与op2相加,结果送到Rd,Rn + op2 -> Rd
- Rn要求是寄存器,op2可以是寄存器、移位寄存器、立即数
- S决定指令的操作是否影响CPSR
ADD R0, R1, R2
ADD R0, R1, #5
ADD R0. R1. R2, LSL #2
第二操作数op2的要求:
- 是一个无符号的32位数
- 由一个8位无符号数,用0填充到32位,再循环右移偶数次,得到这个操作数,例如0x8801就不符合
ADC
ADC {
<cont>} {
S} Rd, Rn, op2
- Rn + op2 + C -> Rd,需要额外加上条件标志位C的值
- Rd,Rn必须是寄存器,op2可以是寄存器、移位寄存器、立即数
- 该指令用于实现超过32位的加法
例:两个64位数相加,第一个64位数,存放在R2、R3中,第二个存放在R4,R5中,64位结果存放在R0,R1中
分析:将两个64位数中,低32位相加,结果影响C标志位,然后将64位中的高32位以及低32位产生的进位相加
ADDS R0, R2, R4
ADC R1, R3, R5