第2、3章 ARM指令和汇编语言设计03

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
ldrrdconst产生一条mov或者mvn指令或者产生一条pc相对寻址的ldr指令将立即数从literalpool嵌入在代码中的常数域里读出来ldrr00xffmovr00xffldrr00x55555555ldrr0pcimm12dcd0x55555555推荐用这种方式将常数加载到寄存器加载32位的常数有两类乘法分别产生32位和64位的结果32位的这类乘法在arm7tdmi会执行25时钟周期mulr0r1r2mlar0r1r2r3usmullr4r5r2r3usmlalr4r5r2r3大多数的arm核不提供整数除法指令除法操作由c的库函数例程或者移位操作实现乘法和除法分支指令blcondlabel在指令编码中存在一个24位的地址域在执行时它被左移两位因为arm指令是字对齐的产生一个26位的偏移地址由此可知跳转的范围大体在32mb32mb之startpc相对寻址的标号start跳转到此处继续执行blfunc2bxlrfunc1func2voidfunc1void这些步骤可以由一条指令完成bl分支跳转到32mb范围内的任何地址重新加载链接寄存器的内容至pc寄存器即可实现返回转移类型返回指令推荐blmovpcr14此时pc具有blswiundpabt指令的地址undmovspcr14undswimovspcr14svcpabtsubspcr14abt4irqsubspcr14irq4此时pc从irq或fiq处取得断点地址fiqsubspcr14fiq4dabtsubspcr14abt8pc是产生dabt指令预取的地址resetr14的内容未知各种子程序的返回指令单寄存器数据传输加载存储指令ldrstrldrbstrb字节ldrhstrhldrsb有符号的字节加载ldrsh有符号的半字加载ldrcondsizerdaddressstrcondsizerdaddress举例ldreqb地址寻址方式对于后索引)寻址

前序寻址: STR r0, [r1, #8] ; 计算地址并传送,地址寄存器不更新
偏移量 8
0x308
r0 0x7 0x7
0x300
源寄存器
基址 寄存器
r1 0x300
更新基址寄存器形式: STR r0,[r1,#8]!

;计算地址并传送,地址寄存器也更新
ARM指令集

ARM指令集的特点


所有ARM指令都是32位定长的 加载-存储(Load-Store)架构 提供功能强大的一次加载和存储多个寄存器的指令 CPU内核硬件中提供了桶型(barrel)移位器,移 位操作可以内嵌在其他指令中 所有的ARM指令都是可以条件执行的
ARM指令集:示例

64位的乘法提供了两种乘法指令:无符号和有符号乘 这类指令有两个目标寄存器

[U|S]MULL r4, r5, r2, r3 [U|S]MLAL r4, r5, r2, r3
; r5:r4 = r2 * r3 ; r5:r4 = (r2 * r3) + r5:r4

大多数的 ARM 核不提供整数除法指令 除法操作由c的库函数例程或者移位操作实现
相当于除以2
Destination
CF
最低有效位旋转至最高有效位
RRX: 扩展的循环右移
Destination
CF
寄存器数值右移一位,C标志位填补空出的位,移出的位代替C标志位
立即数常数

ARM 指令不能包含一个 32位的立即数常数

ARM 指令都是32 位定长的

在数据处理指令的格式中,第二个操作数有12位来对应
操作数
1 操作数
寄存器方式, 可附加移位操作

2
桶型移位器

移位的值可为以下的两种: 5位的无符号整数(0-31) 其它寄存器的最低字节 用来实现乘以一个常数 ADD r0, r5, r5 LSL 1 r0 = r5 x 3
立即数
ALU

结果

范围在 0-255的8位立即数 或者该8位立即数循环右移偶数位得 到的数 允许32位的常数直接加载到寄存器中
MOVS PC,R14_und MOVS PC,R14_svc SUBS PC,R14_abt,#4 SUBS PC,R14_irq,#4 SUBS PC,R14_fiq,#4 SUBS PC,R14_abt,#8
此时PC从IRQ或FIQ处取 得断点地址 PC是产生Dabt指令(预取) 的地址 R14的内容未知
;先直接传送数据,后更新地址寄存器
ADDLE

r3, r3, #1
默认情况下,数据处理指令不会影响条件标志位,但是,可在指令后加“s‖(或其 它条件位)后缀,以实现标志位的置位。
loop ADD SUBS BNE r2, r2, r3 r1, r1, #0x01 loop
r2=r2+r3 r1 减1并设置标志位 如果 Z 标志清除则分支跳转

这些步骤可以由一条指令完成, BL


重新加载链接寄存器的内容至PC寄存器即可实现返回
void func1 (void) { : func2(); : }
func2
: BX lr
各种子程序的返回指令
转移 类型
BL
und SWI Pabt IRQ FIQ Dabt

返回指令(推荐)
MOV PC,R14
条件执行和标志位

通过在指令后加上合适的条件标志位,ARM指令可以条件执行

通过减少前向的分支数目,增强了指令的代码密度和指令性能
CMP ADDGT r0, r1 r2, r2, #1
r0 - r1, 比较 r0 和 r1 并设置标志位 if > r2=r2+1 标志位保持不变 if <= r3=r3+1 标志位保持不变
数据处理指令


由以下指令组成 : 算术运算: ADD ADC SUB SBC RSB 逻辑运算: AND ORR EOR BIC 比较运算: CMP CMN TST TEQ 数据传送: MOV MVN 这些指令仅对存放于寄存器的数据操作,对内存数据是无效的. 语法: <Operation>{<cond>}{S} Rd, Rn, Operand2

推荐用这种方式将常数加载到寄存器
乘法和除法

有两类乘法 -分别产生 32位和 64位 的结果 32位的这类乘法在 ARM7TDMI 会执行 2- 5 时钟周期

MUL r0, r1, r2 MLA r0, r1, r2, r3
; r0 = r1 * r2 ; r0 = (r1 * r2) + r3
举例 LDREQB
地址寻址方式

被LDR/STR指令访问的地址通过一个基址寄存器和一个偏移量来指定 对于字和无符号的字节访问, 偏移量可以为: 一个无符号的12位立即数 (i.e. 0 - 4095 bytes) LDR r0, [r1, #8]

寄存器, 可附加的对其进行移位 LDR r0, [r1, r2] LDR r0, [r1, r2, LSL#2]

LDR rd, =const 产生一条 MOV 或者 MVN 指令

这将:

或者 产生一条 PC相对寻址的LDR 指令将立即数从literal pool (嵌入 在代码中的常数域)里读出来

举例

LDR r0, =0xFF => LDR r0, =0x55555555 =>
MOV r0, #0xFF LDR r0, [PC, #Imm12] … … DCD 0x55555555
THUMB-2指令集

Thumb-2 指令集主要是对Thumb指令集架构的扩展, 其设计目标是以Thumb的指令密度达到ARM的性能。 它具有如下特性



增加了32位的指令,因而实现了几乎ARM指令集架构的所有 功能 完整保留了16位的Thumb指令集 编译器可以自动地选择16位和32位指令的混合 具有ARM态的行为,包括可以直接处理异常、访问协处理器 以及完成v5TE的高级数据处理功能 通过If-Then (IT) 指令,1-4条紧邻的指令可以条件执行
THUMB指令集

Thumb指令集是16位的指令集,它对C代码的密度进 行了优化,平均达到约ARM代码大小的65%。为了 尽量降低指令编码长度,Thumb指令集具体采用了 如下约束:


不能使用条件执行,而对于标志则一直都是根据指令结果进 行设置的 源寄存器和目标寄存器是相同的 只使用低端寄存器,即不使用寄存器R8-R12 对指令中出现的常量有大小的限制 不能在指令中使用内嵌的桶型移位器(inline barrel shifter)
条件执行 CMP r0, #0 ADDEQ r1, r1, #1 ADDNE r2, r2, #1 ...
3 条指令 占据3 个字 3 个时钟周期
指令条件码

可能的指令条件码如下所示

注意: AL 是默认的,不需要被特别指出。
后缀 EQ NE CS/HS CC/LO MI PL VS VC HI LS GE LT GT LE AL 描述 相等 不相等 无符号高于或相同 无符号低于 为负 为正或零 溢出 无溢出 无符号高于 无符号低于或相同 大于或等于 小于 大于 小于或等于 总是 被测试的标志 Z=1 Z=0 C=1 C=0 N=1 N=0 V=1 V=0 C=1 & Z=0 C=0 or Z=1 N=V N!=V Z=0 & N=V Z=1 or N=!V
移位操作

以下的移位操作是数据处理指令的一部分.

移位的范围为0-31位,对指令的性能不会造成太大的影响
LSL: 逻辑左移 ASR: 算术右移
0
CF
Destination
相当于乘2
Destination
CF
相当于除以2, 保留符号位
LSR: 逻辑右移
...0
ROR: 循环右移
CF
Destination
start
PC 相对寻址的标号 “start”

B . . start
跳转到此处继续执行
子程序

实现一个传统的子程序调用需要两个步骤:


保存返回地址 跳转到子程序的首地址 返回地址被保存在链接寄存器 (lr/r14) 分支跳转到 +/- 32MB 范围内的任何地址 func1
: BL func2 :
11 rot x2 8 7 immed_8 0
小测试:
Shifter ROR
指令:0xe3a004ff MOV r0, #???

4 位的移位数乘以2组成了步长为2,范围在0-30的移位值 立即数法则: “8 位的常数循环右移偶数位得到”
加载32位的常数

为了加载更大的立即数, 汇编器提供了伪指令:
条件执行的例子
C 代码 if (r0 == 0) { r1 = r1 + 1; } else { r2 = r2 + 1; } ARM 指令
非条件执行 CMP r0, #0 BNE else ADD r1, r1, #1 B end else ADD r2, r2, #1 end ...
5 条指令 占据 5 个字 5个或者6个时钟周期

RSC
第二个操作数可以为一个寄存器或者一个立即数 SUB r0, r1, r2 AND r1, r4, #0xFF

比较指令仅仅设置了条件标志位 –无需指定Rd CMP r0, r3
数据传送指令并不指定Rd MOV r0, r1


第二个操作数通过桶型移位器传输到ALU
第二个操作数

可以直接控制在C语言编程时不能有效使用的3个优化工 具:



指令调整-----调整一段代码中的指令序列,以避免处理 器的暂停等待。ARM指令执行是在指令流水线中进行 的,所以一条指令执行的时间会受其相邻指令的影响。 寄存器分配-----决定如何分配变量给ARM寄存器或者堆 栈,以获得最好的性能。目标是要使访问存储器的次数 降到最少。 条件执行-----可以使用ARM条件代码和条件指令的全部 功能。
此时PC具有BL/SWI/und/ Pabt指令的地址
Reset
--
单寄存器数据传输(加载 / 存储指令)
LDR LDRB LDRH LDRSB LDRSH

STR STRB STRH
字 字节 半字 有符号的字节加载 有符号的半字加载
存储系统必须支持所有的访问尺寸 语法:


LDR{<cond>}{<size>} Rd, <address> STR{<cond>}{<size>} Rd, <address>


对于半字和有符号的字节访问, 偏移量可以为: 一个8位的立即数 (i.e. 0 - 255 bytes) 一个寄存器 (不可以被移位) 基址寄存器的地址可加也可减: LDR r0, [r1, #-8] LDR r0, [r1, -r2, LSL#2]
是前序还是后序寻址 是否更新基址寄存器 (仅限于前序寻址) LDR r0, [r1, #-8]!
分支指令

分支跳转指令有如下的格式:



B{L}{<cond>} label 子函数调用可加上 {L}实现 在指令编码中,存在一个 24 位的地址域 在执行时它被左移两位 (因为 ARM 指令是字对齐的),产生一个 26位的偏移地址,由此可知跳转的范围大体在-32MB~+32MB之 间 引起了流水线清空
主要内容

1 ARM 指令集概述 2 ARM 汇编语言设计
ARM指令集

ARM指令集主要包括6大类指令:

数据处理指令:如ADD、SUB、AND等 加载-存储(Load-Store)指令:如LDR等 分支指令:如B、BL等 状态寄存器访问指令:如MRS、MSR等 协处理器指令:如LDC、STC等 异常处理指令:如SWI等
JAZELLE

Jazelle技术使得ARM核可以执行8位的Java字 节码,约95%的JAVA字节码可以由硬件执行, 从而使效率显著提高。
汇编指令用处




嵌入式系统的初始化代码需要用汇编指令来编写。初始化 代码通常包括处理器的初始化、内存初始化等,其中涉及 一些比较特殊的操作,比如设置处理器在不同工作模式下 的堆栈指针,需要使用特殊的访问处理器状态寄存器的指 令,强制处理器切换到不同模式下进行操作; 一些中断例程尤其是作为一种异常被响应的第一级中断派 发程序需要用汇编指令来编写,以提高效率; 在软件的调试过程中,熟悉汇编指令更有助于查找疑难问 题; 某些指令本身就是不能直接由编译器产生的,而需要人工 编写。
相关文档
最新文档