【ARM汇编】第三章:ARM指令系统

文章目录

指令基础

指令周期和时序

时钟信号:是一个周期性的脉冲信号
时钟周期(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处理指令、协处理器指令、异常产生指令
[,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ULuzORYx-1587825834457)(en-resource://database/892:1)]

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出栈

数据处理指令

数据处理指令对存放在寄存器中的数据进行操作,分为

  • 数据传送指令
  • 算术指令
  • 逻辑运算指令
  • 比较指令
  • 乘法指令
    [败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EhTlPnIy-1587825834458)(en-resource://database/894:1)]

ARM数据处理指令机器编码格式如下:
[,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UC4P9enj-1587825834460)(en-resource://database/896:1)]

  • 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位组成一个循环右移
[,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KUdPGkn6-1587825834462)(en-resource://database/898:1)]

算术指令

主要是加减法,实现两个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

  • 6
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值