ILD

arm体系结构与编程笔记
作者:HerbertYuan 邮箱:yuanjp89@163.com
发布时间:2017-9-16 站点:Inside Linux Development

1 ARM概述

1.1 ARM处理器模式

共有7种运行模式:

1 用户模式 user,用户程序执行的模式

2 快速中断模式 FIQ,用于高速数据传输和通道处理

3 外部中断模式 IRQ,用于通常的中断处理

4 特权模式 Supervisor svc,供操作系统使用的一种保护模式

5 数据访问中止模式 Abort abt,用于虚拟存储和存储保护

6 未定义指令中止模式 Undefined und,支持通过软件方针硬件的协处理

7 系统模式 System sys,用于运行特权级的操作系统任务

除了用户模式,其他6种模式称为特权模式(Privileged Modes)可以访问所有的系统资源。


1.2 ARM寄存器

ARM共有37个寄存器。31个通用寄存器,包括PC寄存器。6个状态寄存器。这些寄存器都是32位的,但是6个状态寄存器只使用了其中12位。上述这些寄存器,在不同的模式下,可能共用,或者特定模式下有它自己独有的寄存器,如表1所示。

表1 各种处理器模式下的寄存器。

用户模式

系统模式

特权模式

中止模式

未定义指令模式

外部中断模式

快速中断模式

R0

R0

R0

R0

R0

R0

R0

R1

R1

R1

R1

R1

R1

R1

R1

R1

R1

R1

R1

R1

R1

R3

R3

R3

R3

R3

R3

R3

R4

R4

R4

R4

R4

R4

R4

R5

R5

R5

R5

R5

R5

R5

R6

R6

R6

R6

R6

R6

R6

R7

R7

R7

R7

R7

R7

R7

R8

R8

R8

R8

R8

R8

R8_fiq

R9

R9

R9

R9

R9

R9

R9_fiq

R10

R10

R10

R10

R10

R10

R10_fiq

R11

R11

R11

R11

R11

R11

R11_fiq

R12

R12

R12

R12

R12

R12

R12_fiq

R13

R13

R13_svc

R13_abt

R13_und

R13_irq

R13_fiq

R14

R14

R14_svc

R14_abt

R14_und

R14_irq

R14_fiq

PC

PC

PC

PC

PC

PC

PC

CPSR

CPSR

CPSR

CPSR

CPSR

CPSR

CPSR



SPSR_svc

SPSR_abt

SPSR_und

SPSR_irq

SPSR_fiq


1.2.1 通用寄存器

包括

R0-R7,未备份寄存器 the unbanked registers,所有模式都共用。

R8-R14,备份寄存器 the banked registers。有些模式有它自己的备份寄存器。

PC,程序计数器,即R15。

R13通常用于栈指针。ARM指令集也可以用其它寄存器做栈指针,但是Thumb指令集中,某些指令强制使用R13作为栈指针。


R14又被称为连接寄存器 Link Register LR。其有两种特殊用途:

1 存放当前子程序的返回地址。

2 异常中断发生时,存放异常模式将要返回的地址。


R15 程序计数器

又被记作PC。PC的值为当前指令地址值加8个字节。也就是说,PC指向当前指令的下两条指令的地址。


1.2.2 程序状态寄存器和备份程序状态寄存器

CPSR当前程序状态寄存器,任何模式都共享这个寄存器。SPSR备份程序状态寄存器,在异常模式下用来备份CPSR,当从异常模式退出时,用SPSR来恢复CPSR。


用户模式和系统模式不是异常中断模式,所以它们没有SPSR。


CPSR的格式如下:

31

30

29

28

27

26

7

6

5

4

3

2

1

0

N

Z

C

V

Q

DNM(RAZ)

I

F

T

M4

M3

M2

M1

M0


条件标志位

N(Negative) Z(Zero) C(Carry) V(oVerflow)


Q标志位

在ARM v5的E系列处理器中,指示增强的DSP指令是否发生溢出。


控制位

低8位,I F T及M[4:0]

当异常中断发生时,这些位发生变化。在6种特权级的处理器模式下,软件可以修改这些控制位。

I 中断禁止位,设置为1,将禁止IRQ中断。

T控制位,指示是ARM指令还是Thumb指令。不同的ARM处理器,T的含义可能不同。

M控制位,控制处理器模式。

10000

user

10001

FIQ

10010

IRQ

10011

Supervisor

10111

Abort

11011

Undefined

11111

System


1.3  ARM体系的异常中断

ARM指令执行流程有3种:

1 正常执行过程,根据PC,一条条执行。

2 跳转执行。

3 异常中断执行。


ARM异常中断类型

复位 Reset,上电/硬件复位/软件复位时。

未定义指令 undefined instruction

软中断 software interrupt SWI

指令预取中止 Prefech abort

数据访问中止 Data Abort

外部中断请求 IRQ

外部快速中断请求 FIQ


进入中断要做的事情

将CPSR备份到SPSR,设置当前CPSR的相应位,如关闭中断,将返回地址存储到R14,设置PC,跳到中断处理程序处执行。


从中断返回要做的事情

恢复CPSR。返回到R14指向的地址继续执行。


1.4 ARM存储系统

ARM通常以4字节对齐,如果访问未对其的数据地址或指令地址,将导致未知的结果。


指令预取

一次取出多条指令


自修改代码

在代码的执行过程种,可能修改代码。


2 ARM指令分类及其寻址方式

ARM指令集可以分为6类:

跳转指令

数据处理指令

程序状态寄存器(PSR)传输指令

Load/Store指令

协处理器指令

异常中断产生指令


2.1  ARM指令的一般编码格式

一条典型的指令

31

27

24

20

19

15

11

cond

001

opcode

S

Rn

Rd

shifter operand


cond  指令执行的条件编码

opcode  指令操作符编码

S  指令的操作是否影响CPSR的值

Rd  目标寄存器编码

Rn  包含第一个操作数的寄存器编码

shifter_operand 表示第二个操作数


典型的ARM指令语法格式

<opcode> {<cond>} {S} <Rd>, <Rn>, <shifter operand>


2.2 条件码

ARM指令的31-28,共4位为条件码,根据CPSR中的条件标志位决定是否执行该指令。条件满足时执行,不满足时当作一条NOP指令。


表2 指令的条件码

条件码

<cond>

条件码

助记符

含义

CPSR种条件标志位值

0000

EQ

相等

Z=1

0001

NE

不相等

Z=0

0010

CS/HS

无符号数大于或等于

C=1

0011

CC/LO

无符号数小于

C=0

0100

ML

负数

N=1

0101

PL

非负数

N=0

0110

VS

上溢

V=1

0111

VC

没有上溢

V=0

1000

HI

无符号数大于

C=1且Z=0

1001

LS

无符号数小于或等于

C=0且Z=1

1010

GE

带符号数大于或等于

N=1且V=1 或 N=0且V=0

1011

LT

带符号数小于

N=1且V=0 或N=0且V=1

1100

GT

带符号数大于

Z=0且N=V

1101

LE

带符号数小于或等于

Z=1且N!=V

1110

AL

无条件执行


1111

NV

未定义

AL

从不执行

结果不可预知

无条件执行

ARM v3之前

ARM v3及v4

ARM v5及以上版本


2.3 寻址方式

不同的指令类型,其操作数有不同的寻址方式。


2.3.1 数据处理指令的操作数的寻址方式

数据处理指令的格式如下:

<opcode> {<cond>} {S} <Rd>,<Rn>,<shifter_operand>


shift operand有3种寻址方式:立即数/寄存器/寄存器移位


1 立即数

由于shift operand只有12位,它包含两个部分immed_8和immed_4。立即数的值为:

immediate = immed_8 << ( 2 * immed_4)


一个立即数可能有多种immed_8和immed_4的组合,ARM汇编器选择最小的immed_4的那种组合。


2 寄存器方式

在某些指令中,shift operand表示某个寄存器。如

ADD R0, R1, R2


3 寄存器移位方式

包含寄存器及其移位的位数,同时位数可以用立即数或者寄存器表示。移位的方式有:

ASR 算数右移

LSL 逻辑左移

LSR 逻辑右移

ROR 循环右移

RRX 扩展的循环右移

如:

MOV RO,R1,LSL #3

MOV R0,R1,ROR R2


具体的寻址方式有下面11种

#<immediate>

<Rm>

<Rm>, LSL #<shift_imm>

<Rm>, LSL <Rs>

<Rm>, LSR #<shift_imm>

<Rm>, LSR <Rs>

<Rm>, ASR #<shift_imm>

<Rm>, ASR <Rs>

<Rm>, ROR #<shift_imm>

<Rm>, ROR <Rs>

<Rm>, RRX


2.3.2  字及无符号字节的Load/Store指令的寻址方式

Load指令用于从内存中读取数据放入寄存器。Store指令用于将寄存器中的数据保存到内存中。

寻址方式分为两部分:基址寄存器,地址偏移量。

基址寄存器可以为任一个通用寄存器。


偏移量有3种格式:

立即数

寄存器

寄存器及一个移位常数


地址计算方法有3种:

偏移量方法

事先更新方法

事后更新方法


LDR指令格式:

31

27

25

24

23

22

21

20

19

15

11

cond

01

I

P

U

0

W

1

Rn

Rd

Address_mode

Rd目标期存器

Rn基址寄存器

Address_mode 偏移量


语法格式

LDR {<cond>} {B} {T} <Rd>,<address_mode>


address mode共有9种模式


1 [<Rn>, #+/-<offset_12>]

立即数做偏移量。

U:1加偏移量,0减偏移量。

B:1无符号,0有符号。

L:1执行Load,0执行Store。

示例:

LDR R0,[R1,#4]

LDR R0,[R1,#-4]


2 [<Rn>, +/-<Rm>]

寄存器做偏移量


示例

LDR R0,[R1,R2]

LDR R0,[R1,-R2]


3 [<Rn>,+/-<Rm>,<shift_typet>#<shift_imm>]

寄存器移位做偏移量,共有5种

[<Rn>,+/-<Rm>,LSL#<shift_imm>]

[<Rn>,+/-<Rm>,LSR#<shift_imm>]

[<Rn>,+/-<Rm>,ASR#<shift_imm>]

[<Rn>,+/-<Rm>,ROR#<shift_imm>]

[<Rn>,+/-<Rm>,RRX]


4 立即数方式的事先访问方式 pre-indexed

[<Rn>,#+/-<offset_12]!

指令执行完后,地址写入Rn。

LDR R0,[R1,#4]!


5 寄存器方式的事先访问方式

[<Rn>,+/-<Rm>]!


6 寄存器移位方式的事先访问方式

[<Rn>,+/-<Rm>,<shift_typet>#<shift_imm>]!


7 事后访问方式

[<Rn>],#+/-<offset_12>

如:LDR R0,[R1],#4  将地址R1的内存单元数据读取到R0中,然后R1+=4。


8 [<Rn>],+/-<Rm>

9 [<Rn>],+/-<Rm>,<shift_type>#<shift_imm>


3 ARM指令集简介

3.1 跳转指令

B跳转指令

BL 带返回的跳转指令,将PC寄存器的值保存到LR寄存器中。

B{L} {<cond>} <target_address>

将24位带符号的补码立即数扩展为32位,然后左移2位,加上PC值,得到跳转后的地址。

跳转范围:PC +/- 32MB

格式

31

27

24

23

cond

101

L

signed immed 24


L:是否保存PC到LR寄存器。


BLX跳转指令

BLX <target_address>

BLX {<cond>} <Rm>


BX指令

BX {<cond>} <Rm>


3.2 数据处理指令

分为3类:

数据传送指令,向寄存器传入一个常数。

算数逻辑运算指令

比较指令,不保存运算结果,只更新CPSR中相应的条件标志位。


1 MOV传送指令

将<shifter_operand>表示的数据传送到目标寄存器<Rd>中,并根据操作的结果更新CPSR中相应的标志位。

MOV {<cond>} {S} <Rd>,<shifter_operand>


2 MVN传送指令

数据的反码送到目标寄存器Rd。


3 ADD加法指令

ADD {<cond>} {S} <Rd>,<Rn>,<shifter_operand>

如:

ADD Rx, Rx, #1

ADD Rd, Rx, Rx, LSL #n


4 ADC带位加法

加上CPSR中的C条件标志位的值。


5 SUB减法指令

SUB {<cond>} {S} <Rd>, <Rn>, <operand>

同ADD。


6 SBC带位减法指令


7 RSB逆向减法指令

RSB {<cond>} {S} <Rd>, <Rn>, <operand>
用操作数减Rn,赋值到Rd。


8 RSC带位逆向减法。


9 AND逻辑与指令

AND {<cond> {S} <Rd>,<Rn>,<shifter_operand>


10 ORR逻辑或指令

ORR {<cond> {S} <Rd>,<Rn>,<shifter_operand>


11 EOR逻辑异或指令

EOR {<cond> {S} <Rd>,<Rn>,<shifter_operand>


12 BIC位清楚指令

BIC {<cond> {S} <Rd>,<Rn>,<shifter_operand>


13 CMP比较指令

CMP {<cond>} <Rn>, <shifter_operand>


14 CMN基于相反数的比较指令

CMN {<cond>} <Rn>, <shifter_operand>


15 TST位测试指令

TST {<cond>} <Rn>, <shifter_operand>


16 TEQ相等测试指令

TEQ {<cond>} <Rn>, <shifter_operand>


3.3 乘法指令

有两类乘法指令:32位乘法,结果为32位。另一类是64位乘法指令,结果为64位。

乘法指令的所有操作数都是寄存器。


1 MUL 32位乘法

MUL {<cond>} {S} <Rd>,<Rm>,<Rs>

Rd=Rm*Rs


2 MLA 32位乘加指令

MLA {<cond>} {S} <Rd>,<Rm>,<Rs>,<Rn>

Rd=Rm*Rs + Rn


3 SMULL 64位有符号数乘法指令

SMULL {<cond>} {S} <RdLo>,<RdHi>,<Rm>,<Rs>

实现的是两个32位有符号数的乘积


4 SMLAL 64位有符号乘加

SMLAL {<cond>} {S} <RdLo>,<RdHi>,<Rm>,<Rs>

Rd = Rd+Rm*Rs


5 UMULL 64位无符号乘法

UMULL {<cond>} {S} <RdLo>,<RdHi>,<Rm>,<Rs>


6 UMLAL

UMLAL {<cond>} {S} <RdLo>,<RdHi>,<Rm>,<Rs>


3.4 杂类指令

1 CLZ前导0个数计数

CLZ {<cond>} <Rd>,<Rm>


3.5 状态寄存器访问指令

用于在状态寄存器和通用寄存器之间传送数据


1 MRS

将状态寄存器拷贝到通用寄存器

MRS {<cond>} <Rd>, CPSR

MRS {<cond>} <Rd>, SPSR


2 MSR

将通用寄存器或者一个立即数拷贝到状态寄存器

MSR {<cond>} CPSR_<fileds> , #<immediate>

MSR {<cond>} CPSR_<fields>, #<immediate>

MSR {<cond>} CPSR_<fileds>, <Rm>

MSR {<cond>} SPSR_<fields>, #<immediate>

MSR {<cond>} SPSR_<fileds>, <Rm>


fields共4个:

31:24 条件标识域f

23:16 状态位域 s

15:8 扩展位域 x

7:0 控制位域 c


3.6 Load/Store内存访问指令

Load从内存中读取数据放入寄存。

Store将寄存器中的内容保存到内存。


1 LDR 字数据读取指令

从内存中读取32位的数据到目标寄存器。

LDR {<cond>} <Rd>, <addressing_mode>


2 LDRB 字节数据读取指令

读取8位数据到寄存器,并将寄存器的高24位清零。

LDR{<cond>}B <Rd>, <addressing_mode>


3 LDRBT 用户模式字节数据读取指令

在其它模式如特权模式下使用用户模式下的内存访问操作。

LDR{<cond>}BT <Rd>, <post_indexed_addressing_mode>


4 LDRH 16位数据存取指令

寄存器的高16位将被清0。

LDR{<cond>}H <Rd>, <addressing_mode>


5 LDRSB 有符号字节读取指令

将8位扩展为寄存器32位有符号数。

LDR{<cond>}SB <Rd>, <addressing_mode>


6 LDRSH 有好符号的半字读取指令

将16位扩展为寄存器32位有符号数。

LDR{<cond>}SH <Rd>, <addressing_mode>


7 LDRT 用户模式的字数据读取指令

LDR{<cond>}T <Rd>, <post_indexed_addressing_mode>


8 STR字数据写入指令

将寄存器的32位写入内存。

STR{<cond>} <Rd>, <addressing_mode>


9 STRB字节写入指令

将寄存器的低8位写入内存。

STR{<cond>}B <Rd>, <addressing_mode>


10 STRH 半字数据写入指令

将寄存器的低16位写入内存。

STR{<cond>}H <Rd>, <addressing_mode>


11 STRT 用户模式的字数据写入指令

STR{<cond>}T <Rd>, <post_indexed_addressing_mode>


12 STRBT用户模式的字节数据写入指令

STR{<cond>}BT <Rd>, <post_indexed_addressing_mode>


3.7 批量Load/Store内存访问指令

语法格式

LDM/STM {<cond>} <addressing_mode> Rn{!}, <registers>{^}


1 LDM(1) 批量内存字数据读取指令

LDM {<cond>} <addressing_mode> Rn{!}, <registers>


2 LDM(2) 用户模式的批量内存字数据读取指令

LDM {<cond>} <addressing_mode> Rn{!}, <registers_without_pc>^


3 LDM(3) 带状态寄存器的批量内存字数据读取指令

该指令会将SPSR寄存器的内容复制到CPSR寄存器中。

LDM {<cond>} <addressing_mode> Rn{!}, <registers_and_pc>^

该指令通常用于从中断中返回


4 STM(1) 批量内存写入指令

STM {<cond>} <addressing_mode> Rn{!}, <registers>


5 STM(2)用户模式的批量内存写入指令

STM {<cond>} <addressing_mode> Rn{!}, <registers>^


3.8 信号量操作指令

1 SWP交换指令

将一个内存单元的内容读取到一个寄存器,将另一个寄存器的内容写入到内存单元。

SWP {<cond>} <Rd>, <Rm>, [<Rn>]

将Rn表示内存的数据读取到Rd,将Rm的数据写入到内存。Rd和Rm可以为同一个寄存器。


2 SWPB 8位字节交换指令


3.9 异常中断产生指令

1 SWI软中断指令

SWI{<cond>} <immed_24>


2 BKPT断点中断指令

用于产生软件断点中断,软件调试程序可以使用该中断。

BKPT <immediate>


3.10 ARM协处理器指令

1 CDP 协处理器数据操作指令

CDP{<cond>} <coproc>, <opcode_1>, <CRd>, <CRm>, <opcode_2>

CDP2 <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>, <opcode_2>

coproc:协处理器的编码

opcode_1:协处理器的操作码

CRd:作为目标寄存器的协处理器寄存器

CRn:存放第一个操作数的协处理器寄存器。

CRm:存放第二个操作数的协处理器寄存器。

opcode_2:协处理器的操作码


2 LDC 协处理器数据读取指令

从系列连续的内存单元中读取数据到协处理器的寄存器中。

LDC{<cond>} {L} <coproc>, <CRd>, <addressing_mode>

LDC2{L} <coproc>, <CRd>, <addressing_mode>


3 STC协处理器写入指令

将协处理器的寄存器中的数据写入到一系列内存单元中

STC{<cond>} {L} <coproc>, <CRd>, <addressing_mode>

STC2{L} <corpoc>, <CRd>, <addressing_mode>


4 MCR ARM寄存器到协处理器寄存器的数据传送指令

MCR{<cond>} <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>{, <opcode_2>}

MCR2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>{,<opcode_2>}


5 MRC协处理器寄存器到ARM寄存器的数据传送指令

MRC{<cond>} <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>{, <opcode_2>}

MRC2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>{,<opcode_2>}


4 异常中断处理

ARM中断类型

中断名称

跳转入口地址

含义

复位

0x0

复位引脚有效时,系统产生复位异常中断。

未定义指令

0x4


软中断 SWI

0x8


指令预取中止 prefech abort

0x0c

预取的指令地址不存在,或不允许访问。

数据访问中止 Data abort

0x10


外部中断请求

0x18


快速中断请求

0x1c



共有8种异常中断,异常中断向量表共32个字节,每种4个字节。


Copyright © insidelinuxdev.net 2017-2021. Some Rights Reserved.