当前位置:首页 > 嵌入式 > 嵌入式教程
[导读]根据内存访问指令的分类,内存访问指令的寻址方式可以分为以下几种。 ① 字及无符号字节的Load/Store指令的寻址方式。 ② 杂类Load/Store指令的寻址方式。 ③ 批量Load/Store指令的寻址方式。 ④ 协处理器Load/Store指令的寻址方式。

4.2 内存访问指令寻址

根据内存访问指令的分类,内存访问指令的寻址方式可以分为以下几种。

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

② 杂类Load/Store指令的寻址方式。

③ 批量Load/Store指令的寻址方式。

④ 协处理器Load/Store指令的寻址方式。

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

字及无符号字节的Load/Store指令语法格式如下:

LDR|STR{<cond>}{B}{T} <Rd>,<addressing_mode>

其中<addressing_mode>共有9种寻址方式,如表4.2所示。

表4.2 字及无符合字节的Load/Store指令的寻址方式

格 式

模 式

1

[Rn,#±<offset_12>]

立即数偏移寻址

(Immediate offset)

2

[Rn,±Rm]

寄存器偏移寻址

(Register offset)

3

[Rn,Rm,<shift>#< offset_12>]

带移位的寄存器偏移寻址

(Scaled register offset)

4

[Rn,#±< offset_12>]!

立即数前索引寻址

(Immediate pre-indexed)

5

[Rn,±Rm]!

寄存器前索引寻址

(Register post-indexed)

6

[Rn,Rm,<shift>#< offset_12>]!

带移位的寄存器前索引寻址

(Scaled register pre-indexed)

7

[Rn],#±< offset_12>

立即数后索引寻址

(Immediate post-indeded)

8

[Rn],±<Rm>

寄存器后索引寻址

(Register post-indexed)

9

[Rn],±<Rm>,<shift>#< offset_12>

带移位的寄存器后索引寻址

(Scaled register post-indexed)

字及无符号字节的Load/Store指令的解码格式如图4.13所示。

图4.13 字及无符号字节的Load/Store指令的解码格式

编码格式中各位的含义如表4.3所示。

表4.3 字和无符号半字Load/Store指令编码格式各位含义

位 标 识

取 值

含 义

P

P=0

使用后索引寻址

P=1

使用偏移地址或前索引寻址(由W位决定)

U

U=0

访问的地址=基址寄存器的值-偏移量(offset)

U=1

访问的地址=基址寄存器的值+偏移量(offset)

B

B=0

字访问Load/Store

B=1

无符号字节访问Load/Store

W

W=0

如果P=0,该指令为LDR、LDRB、STR或STRB指令,且内存访问指令为正常访问指令;如果P=1,指令执行不更新基地址

W=1

如果P=0,该指令为LDRBT、LDRT、STRBT或STRT,且指令为非特权(用户模式)访问指令;如果P=1,计算内存地址并更新基地址

L

L=0

Store指令

L=1

Load指令

1.[Rn,#±<offset_12>]

(1)编码格式

指令的编码格式如图4.14所示。

图4.14 内存访问指令——立即数偏移寻址编码格式

内存访问地址为基址寄存器Rn的值加(或减)立即数offset_12。

编程中,在访问结构体或记录(record)类型的变量时,这些内存的操作指令是十分有效的。另外,在子程序中也常用这些指令访问本地变量和堆栈。

(2)语法格式

LDR|STR{<cond>}{B}{T} <Rd>,[<Rn>,#±<offset_12>]

其中:

· Rn为基址寄存器,该寄存器包含内存访问的基地址;

· <offset_12>为12位立即数,内存访问地址偏移量。

(3)操作伪代码

If U = = 1 then

Address = Rn + offset_12

Else

Address = Rn – offset_12

(4)说明

① 如果指令中没有指定立即数,使用[<Rn>],编译器按[<Rn>,#0]形式编码。

② 如果Rn被指定为程序计数器r15,其值为当前指令地址加8。

2.[Rn,±Rm]

(1)编码格式

指令的编码格式如图4.15所示。

图4.15 内存访问指令——寄存器偏移寻址编码格式

内存访问地址为基址寄存器Rn的值加(或减)偏移寄存器Rm的值。

该寻址方式适合使用指针访问字节数组中的数据成员。

(2)语法格式

LDR|STR{<cond>}{B}{T} <Rd>,[<Rn>,±<Rm>]

其中:

· Rn为基址寄存器,该寄存器包含内存访问的基地址;

· <Rm>为偏移地址寄存器,包含内存访问地址偏移量。

(3)操作伪代码

If U = = 1 then

Address = Rn + Rm

Else

Address = Rn – Rm

(4)说明

如果Rn被指定为程序计数器r15,其值为当前指令地址加8;如果r15被用作偏移地址寄存器Rm的值,指令的执行结果不可预知。

3.[Rn,Rm,<shift>#< offset_12>]

(1)编码格式

指令的编码格式如图4.16所示。

图4.16 内存访问指令——带移位的寄存器偏移寻址编码格式

内存地址为Rn的值加/减通过移位操作后的Rm的值。

当数组中的成员长度大于1个字节时,使用该寻址方式可高效率地访问数组成员。

(2)语法格式

语法格式有以下5种。

LDR|STR{<cond>}{B}{T} <Rd>,[<Rn>,±<Rm>,LSL #< offset_12>]

LDR|STR{<cond>}{B}{T} <Rd>,[<Rn>,±<Rm>,LSR #< offset_12>]

LDR|STR{<cond>}{B}{T} <Rd>,[<Rn>,±<Rm>,ASR #< offset_12>]

LDR|STR{<cond>}{B}{T} <Rd>,[<Rn>,±<Rm>,ROR #< offset_12>]

LDR|STR{<cond>}{B}{T} <Rd>,[<Rn>,±<Rm>,RRX]

其中:

· Rn为基址寄存器,该寄存器包含内存访问的基地址;

· <Rm>为偏移地址寄存器,包含内存访问地址偏移量;

· LSL表示逻辑左移操作;

· LSR表示逻辑右移操作;

· ASR表示算术右移操作;

· ROR表示循环右移操作;

· RRX表示扩展的循环右移。

· <shift_imm>为移位立即数。

(3)操作伪代码

Case shift of

0b00 /*LSL*/

Index = Rm logic_shift_left shift_imm

0b01 /*LSR*/

If shift_imm = = 0 then /*LSR #32*/

Index = 0

Else

Index = Rm logical_shift_right shift_imm

0b10 /*ASR*/

If shift_imm = = 0 then /*ASR #32*/

If Rm[31] = = 1 then

Index = 0xffffffff

Else

Index = 0

Else

Index = Rm Arithmetic_shift_Right shift_imm

0b11 /* ROR or RRX*/

If shift_imm = = 0 then /*RRX*/

Index = (C flag Logical_shift_left 31) OR

(Rm logical_shift_Right 1)

Else /*ROR*/

Index = Rm Rotate_Right shift_imm

Endcase

If U = = 1 then

Address = Rn + index

Else /*U = = 0*/

Address = Rn – index

(4)说明

如果Rn被指定为程序计数器r15,其值为当前指令地址加8;如果r15被用作偏移地址寄存器Rm的值,指令的执行结果不可预知。

4.[Rn,#±< offset_12>]!

(1)编码格式

指令的编码格式如图4.17所示。

图4.17 内存访问指令——前索引立即数偏移寻址编码格式

内存地址为基址寄存器Rn加/减立即数offset_8的值。当指令执行的条件<cc>满足时,生成的地址写回基址寄存器Rn中。

该寻址方式适合访问数组自动进行数组下标的更新。

(2)语法格式

LDR|STR{<cond>}{B}{T} <Rd>,[<Rn>,±<offset_12>] !

其中:

· Rn为基址寄存器,该寄存器包含内存访问的基地址;

· <offset_12>为12位立即数,内存访问地址偏移量;

· !设置指令编码中的W位,更新指令基址寄存器。

(3)操作伪代码

If U == 1 then

Address = Rn + offset_12

Else

Address = Rn – offset_12

If ConditionPassed{cond} then

Rn = address

(4)说明

① 如果指令中没有指定立即数,使用[<Rn>],编译器按[<Rn>,#0] ! 形式编码。

② 如果Rn被指定为程序计数器r15,指令的执行结果不可预知。

5.[Rn,±Rm]!

(1)编码格式

指令的编码格式如图4.18所示。

图4.18 内存访问指令——前索引寄存器偏移寻址编码格式

内存访问地址为基址寄存器Rn的值加(或减)偏移寄存器Rm的值。当指令的执行条件<cc>满足时,生成地地址将写回基址寄存器。

(2)语法格式

LDR|STR{<cond>}{B}{T} <Rd>,[<Rn>,±<Rm>]

其中:

· Rn为基址寄存器,该寄存器包含内存访问的基地址;

· <Rm>为偏移地址寄存器,包含内存访问地址偏移量;

· !设置指令编码中的W位,更新指令基址寄存器。

(3)操作伪代码

If U = = 1 then

Address = Rn + Rm

Else

Address = Rn – Rm

If ConditionPassed{cond} then

Rn = address

(4)说明

如果Rn和Rm指定为同一寄存器,指令的执行结果不可预知。

6.[Rn,±Rm,<shift>#< offset_12>]!

(1)编码格式

指令的编码格式如图4.19所示。

图4.19 内存访问指令——带移位的前索引寄存器偏移寻址编码格式

内存地址为Rn的值加/减通过移位操作后的Rm的值。当指令的执行条件<cc>满足时,生成地地址将写回基址寄存器。

(2)语法格式

语法格式有以下5种。

LDR|STR{<cond>}{B}{T} <Rd>,[<Rn>,±<Rm>,LSL #< offset_12>] !

LDR|STR{<cond>}{B}{T} <Rd>,[<Rn>,±<Rm>,LSR #< offset_12>] !

LDR|STR{<cond>}{B}{T} <Rd>,[<Rn>,±<Rm>,ASR #< offset_12>] !

LDR|STR{<cond>}{B}{T} <Rd>,[<Rn>,±<Rm>,ROR #< offset_12>] !

LDR|STR{<cond>}{B}{T} <Rd>,[<Rn>,±<Rm>,RRX] !

其中:

· Rn为基址寄存器,该寄存器包含内存访问的基地址;

· <Rm>为偏移地址寄存器,包含内存访问地址偏移量;

· LSL表示逻辑左移操作;

· LSR表示逻辑右移操作;

· ASR表示算术右移操作;

· ROR表示循环右移操作;

· RRX表示扩展的循环右移。

· <shift_imm>为移位立即数。

· !设置指令编码中的W位,更新指令基址寄存器。

(3)操作伪代码

Case shift of

0b00 /*LSL*/

Index = Rm logic_shift_left shift_imm

0b01 /*LSR*/

If shift_imm = = 0 then /*LSR #32*/

Index = 0

Else

Index = Rm logical_shift_right shift_imm

0b10 /*ASR*/

If shift_imm = = 0 then /*ASR #32*/

If Rm[31] = = 1 then

Index = 0xffffffff

Else

Index = 0

Else

Index = Rm Arithmetic_shift_Right shift_imm

0b11 /* ROR or RRX*/

If shift_imm = = 0 then /*RRX*/

Index = (C flag Logical_shift_left 31) OR

(Rm logical_shift_Right 1)

Else /*ROR*/

Index = Rm Rotate_Right shift_imm

Endcase

If U = = 1 then

Address = Rn + index

Else /*U = = 0*/

Address = Rn – index

If ConditionPassed{cond} then

Rn = address

(4)说明

① 当PC用作基址寄存器Rn或Rm时,指令执行结果不可预知。

② 当Rn和Rm是同一个寄存器时,指令的执行结果不可预知。

7.[Rn],#±< offset_12>

(1)编码格式

指令的编码格式如图4.20所示。

图4.20 内存访问指令——后索引立即数偏移寻址编码格式

指令使用基址寄存器Rn的值作为实际内存访问地址。当指令的执行条件满足时,将基址寄存器的值加/减偏移量产生新的地址值回写到Rn寄存器中。

(2)语法格式

LDR|STR{<cond>}{B}{T} <Rd>,[<Rn>],±<offset_12>

其中:

· Rn为基址寄存器,该寄存器包含内存访问的基地址;

· <offset_12>为12位立即数,内存访问地址偏移量。

(3)操作伪代码

Address = Rn

If conditionPassed{cond} then

If U = = 1 then

Rn = Rn + offset_12

Else

Rn = Rn – offset_12

(4)说明

① LDRBT、LDRT、STRBT和STRT指令只支持后索引寻址。

② 如果Rn被指定为程序计数器r15,指令的执行结果不可预知。

8.[Rn],±<Rm>

(1)编码格式

指令的编码格式如图4.21所示。

图4.21 内存访问指令——后索引寄存器偏移寻址编码格式

指令访问地址为实际的基址寄存器的值。当指令的执行条件满足时,将基址寄存器的值加/减索引寄存器Rm的值回写到Rn基址寄存器。

(2)语法格式

LDR|STR{<cond>}{B}{T} <Rd>,[Rn],±<Rm>

其中:

· Rn为基址寄存器,该寄存器包含内存访问的基地址;

· <Rm>为偏移地址寄存器,包含内存访问地址偏移量。

(3)操作伪代码

Address = Rn

If conditionPassed{cond} then

If U = = 1 then

Rn = Rn + Rm

Else

Rn = Rn – Rm

(4)说明

① LDRBT、LDRT、STRBT和STRT指令只支持后索引寻址。

② 如果Rm和Rn指定为同一寄存器,指令的执行结果不可预知。

9.[Rn],±Rm,<shift>#< offset_12>]

(1)编码格式

指令的编码格式如图4.22所示。

图4.22 内存访问指令——带移位的后索引寄存器偏移寻址编码格式

实际的内存访问地址为寄存器Rn的值。当指令的执行条件满足时,将基址寄存器值加/减一个地址偏移量产生新的地址值。

(2)语法格式

语法格式有以下5种。

LDR|STR{<cond>}{B}{T} <Rd>,[<Rn>],±<Rm>,LSL #< offset_12>

LDR|STR{<cond>}{B}{T} <Rd>,[<Rn>],±<Rm>,LSR #< offset_12>

LDR|STR{<cond>}{B}{T} <Rd>,[<Rn>],±<Rm>,ASR #< offset_12>

LDR|STR{<cond>}{B}{T} <Rd>,[<Rn>],±<Rm>,ROR #< offset_12>

LDR|STR{<cond>}{B}{T} <Rd>,[<Rn>],±<Rm>,RRX

其中:

· Rn为基址寄存器,该寄存器包含内存访问的基地址;

· <Rm>为偏移地址寄存器,包含内存访问地址偏移量;

· LSL表示逻辑左移操作;

· LSR表示逻辑右移操作;

· ASR表示算术右移操作;

· ROR表示循环右移操作;

· RRX表示扩展的循环右移。

· <shift_imm>为移位立即数。

(3)操作伪代码

Address = Rn

Case shift of

0b00 /*LSL*/

Index = Rm logic_shift_left shift_imm

0b01 /*LSR*/

If shift_imm = = 0 then /*LSR #32*/

Index = 0

Else

Index = Rm logical_shift_right shift_imm

0b10 /*ASR*/

If shift_imm = = 0 then /*ASR #32*/

If Rm[31] = = 1 then

Index = 0xffffffff

Else

Index = 0

Else

Index = Rm Arithmetic_shift_Right shift_imm

0b11 /* ROR or RRX*/

If shift_imm = = 0 then /*RRX*/

Index = (C flag Logical_shift_left 31) OR

(Rm logical_shift_Right 1)

Else /*ROR*/

Index = Rm Rotate_Right shift_imm

Endcase

If ConditionPassed{cond} then

If U = = 1 then

Rn = Rn + index

Else /*U = = 0*/

Rn = Rn – index

(4)说明

① LDRBT、LDRT、STRBT和STRT指令只支持后索引寻址。

② 当PC用作基址寄存器Rn或Rm时,指令执行结果不可预知。

③ 当Rn和Rm是同一个寄存器时,指令的执行结果不可预知。

4.2.2 杂类Load/Store指令的寻址方式

使用该类寻址方式的指令的语法格式如下。

LDR|STR{<cond>}H|SH|SB|D <Rd>,<addressing_mode>

使用该类寻址方式的指令包括:(有符号/无符号)半字Load/Store指令、有符号字节Load/Store指令和双字Load/Store指令。

该类寻址方式分为6种类型,如表4.4所示。

表4.4 杂类Load/Store指令的寻址方式

格 式

模 式

1

[Rn,#±<offset_8>]

立即数偏移寻址

(Immediate offset)

2

[Rn,±Rm]

寄存器偏移寻址

(Register offset)

3

[Rn,#±< offset_8>]!

立即数前索引寻址

(Immediate pre-indexed)

4

[Rn,±Rm]!

寄存器前索引寻址

(Register post-indexed)

5

[Rn],#±< offset_8>

立即数后索引寻址

(Immediate post-indeded)

6

[Rn],±<Rm>

寄存器后索引寻址

(Register post-indexed)

杂类Load/Store指令的解码格式如图4.23所示。

图4.23 杂类Load/Store指令解码格式

编码格式中各标志位的含义如表4.5所示。

表4.5 杂类Load/Store指令编码格式各标志位含义

位 标 识

取 值

含 义

P

P=0

使用后索引寻址

P=1

使用偏移地址或前索引寻址(由W位决定)

续表

位 标 识

取 值

含 义

U

U=0

访问的地址=基址寄存器的值-偏移量(offset)

U=1

访问的地址=基址寄存器的值+偏移量(offset)

W

W=0

如果P=0,使用后索引寻址;P=1,指令不改变基址寄存器的值

W=1

如果P=0,未定义指令;如果P=1,将计算的内存访问地址回写到基址寄存器

L

L=0

Store指令

L=1

Load指令

S

S=0

无符号半字内存访问

S=1

有符号半字内存访问

H

H=0

字节访问

H=1

半字访问

注意

当S=0并且H=0时,并非无符号的字节内存访问指令。无符号的内存访问指令不使用该种寻址方式,详见本章上一节。

当S=1并且L=0时,并非是有符号的存储指令,而是未定义指令。ARM指令并未区分有符号和无符号的字节和半字存储。

1.[Rn,#±<offset_8>]

(1)编码格式

指令的编码格式如图4.24所示。

图4.24 杂项内存访问指令——立即数偏移寻址编码格式

内存访问地址为基址寄存器Rn的值加(或减)立即数offset_8。

编程中,在访问结构体或记录(record)类型的变量时,这些内存的操作指令是十分有效的。另外,在子程序中,也常用这些指令访问本地变量和堆栈。当offset_8=0时,内存访问地址即基址寄存器Rn的值。

(2)语法格式

LDR|STR{<cond>}H|SH|SB|D <Rd>,[<Rn>,#±<offset_12>]

其中:

· Rn为基址寄存器,该寄存器包含内存访问的基地址。

· <offset_8>为8位立即数,内存访问地址偏移量。

(3)操作伪代码

offset_8 = (immedH << 4) OR immedL

If U = = 1 then

Address = Rn + offset_8

Else

Address = Rn – offset_8

(4)说明

① 如果指令中没有指定立即数,使用[<Rn>],编译器按[<Rn>,#0]形式编码。

② 如果Rn被指定为程序计数器r15,其值为当前指令地址加8。

2.[Rn,±Rm]

(1)编码格式

指令的编码格式如图4.25所示。

图4.25 杂项内存访问指令——寄存器偏移寻址编码格式

内存访问地址为基址寄存器Rn的值加(或减)偏移寄存器Rm的值。

该寻址方式适合使用指针访问数组中的单个数据成员。

(2)语法格式

LDR|STR{<cond>}H|SH|SB|D <Rd>,[<Rn>,±<Rm>]

其中:

· Rn为基址寄存器,该寄存器包含内存访问的基地址;

· <Rm>为偏移地址寄存器,包含内存访问地址偏移量。

(3)操作伪代码

If U = = 1 then

Address = Rn + Rm

Else

Address = Rn – Rm

(4)说明

如果Rn被指定为程序计数器r15,其值为当前指令地址加8;如果r15被用作偏移地址寄存器Rm的值,指令的执行结果不可预知。

3.[Rn,#±< offset_8>]!

(1)编码格式

指令的编码格式如图4.26所示。

图4.26 杂类内存访问指令——前索引立即数偏移寻址编码格式

内存地址为基址寄存器Rn加/减立即数offset_8的值。当指令执行的条件<cc>满足时,生成的地址写回基址寄存器Rn中。

该寻址方式适合访问数组自动进行数组下标的更新。

(2)语法格式

LDR|STR{<cond>}H|SH|SB|D <Rd>,[<Rn>,±<offset_8>] !

其中:

· Rn为基址寄存器,该寄存器包含内存访问的基地址;

· <offset_8>为8位立即数,内存访问地址偏移量,在指令编码格式中被拆为immedH和immedL两部分;

· !设置指令编码中的W位,更新指令基址寄存器。

(3)操作伪代码

offset_8 = (immedH) << 4 OR immedL

If U == 1 then

Address = Rn + offset_8

Else

Address = Rn – offset_8

If ConditionPassed{cond} then

Rn = address

(4)说明

① 如果指令中没有指定立即数,使用[<Rn>],编译器按[<Rn>,#0] ! 形式编码。

② 如果Rn被指定为程序计数器r15,指令的执行结果不可预知。

4.[Rn,±Rm] !

(1)编码格式

指令的编码格式如图4.27所示。

图4.27 杂项内存访问指令——前索引寄存器偏移寻址编码格式

内存访问地址为基址寄存器Rn的值加(或减)偏移寄存器Rm的值。当指令的执行条件<cc>满足时,生成地地址将写回基址寄存器。

(2)语法格式

LDR|STR{<cond>}H|SH|SB|D <Rd>,[<Rn>,±<Rm>]

其中:

· Rn为基址寄存器,该寄存器包含内存访问的基地址;

· <Rm>为偏移地址寄存器,包含内存访问地址偏移量;

· !设置指令编码中的W位,更新指令基址寄存器。

(3)操作伪代码

If U = = 1 then

Address = Rn + Rm

Else

Address = Rn – Rm

If ConditionPassed{cond} then

Rn = address

(4)说明

① 如果Rn和Rm指定为同一寄存器,指令的执行结果不可预知。

② 如果程序计数器r15被用作Rm或Rn,则指令的执行结果不可预知。

5.[Rn],#±< offset_8>

(1)编码格式

指令的编码格式如图4.28所示。

图4.28 杂项内存访问指令——后索引立即数偏移寻址编码格式

指令使用基址寄存器Rn的值作为实际内存访问地址。当指令的执行条件满足时,将基址寄存器的值加/减偏移量生产新的地址值回写到Rn寄存器中。

(2)语法格式

LDR|STR{<cond>}H|SH|SB|D <Rd>,[<Rn>],±<offset_8>

其中:

· Rn为基址寄存器,该寄存器包含内存访问的基地址;

· <offset_8>为8位立即数,内存访问地址偏移量。

(3)操作伪代码

Address = Rn

Offset_8 = (immedH << 4) OR immedL

If conditionPassed{cond} then

If U = = 1 then

Rn = Rn + offset_8

Else

Rn = Rn – offset_8

(4)说明

① 当指令中没有指定立即数时,汇编器按“[<Rn>],#0”编码。

② 如果Rn被指定为程序计数器r15,指令的执行结果不可预知。

6.[Rn],±<Rm>

(1)编码格式

指令的编码格式如图4.29所示。

图4.29 杂项内存访问指令——后索引寄存器偏移寻址编码格式

指令访问地址为实际的基址寄存器的值。当指令的执行条件满足时,将基址寄存器的值加/减索引寄存器Rm的值回写到Rn基址寄存器。

(2)语法格式

LDR|STR{<cond>}H|SH|SB|D <Rd>,[Rn],±<Rm>

其中:

· Rn为基址寄存器,该寄存器包含内存访问的基地址;

· <Rm>为偏移地址寄存器,包含内存访问地址偏移量。

(3)操作伪代码

Address = Rn

If conditionPassed{cond} then

If U = = 1 then

Rn = Rn + Rm

Else

Rn = Rn – Rm

(4)说明

① 程序寄存器r15被指定为Rm或Rn,指令的执行结果不可预知。

② 如果Rm和Rn指定为同一寄存器,指令的执行结果不可预知。

4.2.3 批量Load/Store指令寻址方式

批量Load/Store指令将一片连续内存单元的数据加载到通用寄存器组中或将一组通用寄存器的数据存储到内存单元中。

批量Load/Store指令的寻址模式产生一个内存单元的地址范围,指令寄存器和内存单元的对应关系满足这样的规则,即编号低的寄存器对应于内存中低地址单元,编号高的寄存器对应于内存中的高地址单元。

指令的语法格式如下。

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

指令的寻址方式如表4.6所示。

表4.6 批量Load/Store指令的寻址方式

格 式

模 式

1

IA(Increment After)

后递增方式

2

IB(Increment Before)

先递增方式

3

DA(Decrement After)

后递减方式

4

DB(Decrement Before)

先递减方式

指令的编码格式如图4.30所示。

图4.30 批量Load/Store指令编码格式

编码格式中各标志位的含义如表4.7所示。

表4.7 批量Load/Store指令编码格式各标志位含义

位标识

取 值

含 义

P

P=0

Rn包含的地址,是所要访问的内存块的高地址(U=0)还是低地址(U=1)

P=1

标识Rn所指向的内存单元是否被访问

U

U=0

Rn所指内存单元为所要访问的内存单元块的高地址

U=1

Rn所指内存单元为所要访问的内存单元块的低地址

S

S=0

当程序计数器PC作为要加载的寄存器之一时,S标识是否将spsr内容拷贝到cpsr;对于不加载PC的load指令和所有store指令,S标识特权模式下,使用用户模式寄存器组代替当前模式下寄存器组

S=1

W

W=0

数据传送完毕,更新地址寄存器内容

W=1

L

L=0

Store指令

L=1

Load指令

1.IA寻址

(1)编码格式

指令的编码格式如图4.31所示。

该寻址方式指定一片连续的内存地址空间,地址空间的大小<address_length>等于寄存器列表中寄存器数目的4倍。内存地址范围起始地址<start_address>等于基址寄存器Rn的值。结束地址<end_address>等于起始地址<start_address>加上地址空间大小<address_length>。

图4.31 批量Load/Store指令——后增加寻址

地址空间中的每个内存单元对应寄存器列表中的一个寄存器。编号低的寄存器对应于内存中低地址单元,编号高的寄存器对应于内存中的高地址单元。

当指令执行条件满足并且指令编码格式中W位置位,基址寄存器Rn的值等于内存地址范围结束地址<end_address>加4。

(2)语法格式

LDM|STM{<cond>}IA <Rn>{!},<registers><^>

其中:

· IA标识指令使用“后增加”寻址方式;

· Rn为基址寄存器,包含内存访问的基地址;

· <registers>为指令操作的寄存器列表;

· <^>表示如果寄存器列表中包含程序计数器PC,是否将spsr拷贝到cpsr。

(3)操作伪代码

Start_address = Rn

End_address = Rn + (Number_of_Set_Bits_In(register_list)*4) – 4

If conditionPassed(cond) and W = = 1 then

Rn = Rn + (Number_of_Set_Bits_In(register_list)*4)

2.DA寻址

(1)编码格式

指令的编码格式如图4.32所示。

图4.32 批量Load/Store指令——后递减寻址

该寻址方式指定一片连续的内存地址空间,地址空间的大小<address_length>等于寄存器列表中寄存器数目的4倍。内存地址范围起始地址<start_address>等于基址寄存器Rn的值减去地址空间大小<address_length>并加4。结束地址<end_address>等于基址寄存器的值。

地址空间中的每个内存单元对应寄存器列表中的一个寄存器。编号低的寄存器对应于内存中低地址单元,编号高的寄存器对应于内存中的高地址单元。

当指令执行条件满足并且指令编码格式中W位置位时,基址寄存器Rn的值等于内存地址范围起始地址<start_address>减4。

(2)语法格式

LDM|STM{<cond>}IA <Rn>{!},<registers><^>

其中:

· DA标识指令使用“后递减”寻址方式;

· Rn为基址寄存器,包含内存访问的基地址;

· <registers>为指令操作的寄存器列表;

· <^>表示如果寄存器列表中包含程序计数器PC,是否将spsr拷贝到cpsr。

(3)操作伪代码

Start_address = Rn – (Number_of_Set_Bits_In(register_list)*4) + 4

End_address = Rn

If conditionPassed(cond) and W = = 1 then

Rn = Rn - (Number_of_Set_Bits_In(register_list)*4)

3.IB寻址

(1)编码格式

指令的编码格式如图4.33所示。

图4.33 批量Load/Store指令——前增加寻址

该寻址方式指定一片连续的内存地址空间,地址空间的大小<address_length>等于寄存器列表中寄存器数目的4倍。内存地址范围起始地址<start_address>等于基址寄存器Rn的值加4。结束地址<end_address>等于起始地址<start_address>加上地址空间大小<address_length>。

地址空间中的每个内存单元对应寄存器列表中的一个寄存器。编号低的寄存器对应于内存中低地址单元,编号高的寄存器对应于内存中的高地址单元。

当指令执行条件满足并且指令编码格式中W位置位,基址寄存器Rn的值等于内存地址范围结束地址<end_address>。

(2)语法格式

LDM|STM{<cond>}IB <Rn>{!},<registers><^>

其中:

· IB标识指令使用“前增加”寻址方式;

· Rn为基址寄存器,包含内存访问的基地址;

· <registers>为指令操作的寄存器列表;

· <^>表示如果寄存器列表中包含程序计数器PC,是否将spsr拷贝到cpsr。

(3)操作伪代码

Start_address = Rn + 4

End_address = Rn + (Number_of_Set_Bits_In(register_list)*4)

If ConditionPassed(cond) and W= = 1 then

Rn = Rn + (Number_Of_Set_Bits_In(register_list)*4)

4.DB寻址

(1)编码格式

指令的编码格式如图4.34所示。

图4.34 批量Load/Store指令——前递减寻址

该寻址方式指定一片连续的内存地址空间,地址空间的大小<address_length>等于寄存器列表中寄存器数目的4倍。内存地址范围起始地址<start_address>等于基址寄存器Rn的值减地址空间的大小<address_length>。结束地址<end_address>等于基址寄存器的值减4。

地址空间中的每个内存单元对应寄存器列表中的一个寄存器。编号低的寄存器对应于内存中低地址单元,编号高的寄存器对应于内存中的高地址单元。

当指令执行条件满足并且指令编码格式中W位置位,基址寄存器Rn的值等于内存地址范围起始地址<address_address>。

(2)语法格式

LDM|STM{<cond>}DB <Rn>{!},<registers><^>

其中:

· DB标识指令使用“前递减”寻址方式;

· Rn为基址寄存器,包含内存访问的基地址;

· <registers>为指令操作的寄存器列表;

· <^>表示如果寄存器列表中包含程序计数器PC,是否将spsr拷贝到cpsr。

(3)操作伪代码

Start_address = Rn - (Number_Of_Set_Bits_In(register_list)*4)

End_address = Rn - 4

If ConditionPassed(cond) and W = = 1 then

Rn = Rn – (Number_Of_Set_Bits_In(register_list)*4)

4.2.4 堆栈操作寻址方式

堆栈操作寻址方式和批量Load/Store指令寻址方式十分类似。但对于堆栈的操作,数据写入内存和从内存中读出要使用不同的寻址模式,因为进栈操作(pop)和出栈操作(push)要在不同的方向上调整堆栈。

下面详细讨论如何使用合适的寻址方式实现数据的堆栈操作。

根据不同的寻址方式,将堆栈分为以下4种。

① Full栈:堆栈指针指向栈顶元素(last used location)。

② Empty栈:堆栈指针指向第一个可用元素(the first unused location)。

③ 递减栈:堆栈向内存地址减小的方向生长。

④ 递增栈:堆栈向内存地址增加的方向生长。

根据堆栈的不同种类,将其寻址方式分为以下4种。

① 满递减FD(Full Descending)。

② 空递减ED(Empty Descending)。

③ 满递增FA(Full Ascending)。

④ 空递增EA(Empty Ascending)。

注意

如果程序中有对协处理器数据的进栈/出栈操作,最好使用FD或EA类型堆栈。这样可以使用一条STC或LDC指令将数据进栈或出栈。

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

Arm CPU正在从根本上推动AI变革,并造福地球。Arm架构是未来AI计算的基石。​

关键字: ARM AI

近日,Arm推出了Arm® Ethos™-U85神经网络处理器(NPU)和Arm Corstone™-320物联网参考设计平台,旨在满足海量的数据处理和大规模计算,加速推进边缘AI的发展进程。

关键字: ARM

为了赶超云计算市场上的竞争对手,谷歌正试图通过定制的Arm服务器芯片降低云计算服务成本。

关键字: 谷歌 ARM 定制芯片

嵌入式开发作为一个融合了计算机软硬件和系统工程的综合性领域,其成功与否往往取决于三个核心要素的有效整合与协调。这三个要素分别是:硬件平台的选择与设计、软件开发及其优化、以及系统级的设计与集成。深入理解并熟练掌握这三个方面...

关键字: 嵌入式开发 ARM

随着汽车软件数量爆发式的增长,整个行业都需要重新思考汽车产品的开发流程。为此,Arm推出了丰富的硬件IP、新的系统IP,以及全新的汽车计算与计算子系统产品路线图,旨在为各种汽车应用实现性能、功能安全、可扩展等方面的支持。

关键字: ARM 汽车电子

知名移动芯片设计公司ARM最近迈出重要一步,它正式推出汽车芯片设计。ARM推出的芯片设计方案名叫Neoverse,随同芯片一起推出的还有面向汽车制造商、汽车供应商的新系统。

关键字: ARM 汽车芯片 芯片

随着通用人工智能的发展,数据中心的计算需求逐步提高。针对多模态数据、大模型的推理和训练需要更高的算力支持,而随着算力提升与之而来的还需更关注在功耗方面的优化。对于头部云计算和服务厂商而言,针对专门用例提高每瓦性能变得至关...

关键字: ARM 服务器 AI Neoverse CSS

一直以来,riscv架构都是大家的关注焦点之一。因此针对大家的兴趣点所在,小编将为大家带来riscv架构的相关介绍,详细内容请看下文。

关键字: riscv ARM riscv架构

最新消息报道,知情人士透露Arm近日裁掉了中国70多名软件工程师,并会将部分职位转移到中国以外的地区。Arm通过“全球服务”部门已经将支持其中国客户的工作外包给安谋科技,该部门曾经拥有约200名员工。

关键字: ARM 裁员

凭借着在个人计算机领域的广泛应用打下的坚实基础,X86自始至终统治着整个服务器生态。而这并不是业界希望看到的,因此Arm服务器被给予厚望。业界期盼Arm能够带来新的服务器CPU替代:打破一个同质化的数据中心架构,实现更高...

关键字: ARM 服务器 AI
关闭
关闭