当前位置:首页 > 嵌入式 > 嵌入式教程
[导读]根据内存访问指令的分类,内存访问指令的寻址方式可以分为以下几种。 ① 字及无符号字节的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指令将数据进栈或出栈。

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

9月2日消息,不造车的华为或将催生出更大的独角兽公司,随着阿维塔和赛力斯的入局,华为引望愈发显得引人瞩目。

关键字: 阿维塔 塞力斯 华为

加利福尼亚州圣克拉拉县2024年8月30日 /美通社/ -- 数字化转型技术解决方案公司Trianz今天宣布,该公司与Amazon Web Services (AWS)签订了...

关键字: AWS AN BSP 数字化

伦敦2024年8月29日 /美通社/ -- 英国汽车技术公司SODA.Auto推出其旗舰产品SODA V,这是全球首款涵盖汽车工程师从创意到认证的所有需求的工具,可用于创建软件定义汽车。 SODA V工具的开发耗时1.5...

关键字: 汽车 人工智能 智能驱动 BSP

北京2024年8月28日 /美通社/ -- 越来越多用户希望企业业务能7×24不间断运行,同时企业却面临越来越多业务中断的风险,如企业系统复杂性的增加,频繁的功能更新和发布等。如何确保业务连续性,提升韧性,成...

关键字: 亚马逊 解密 控制平面 BSP

8月30日消息,据媒体报道,腾讯和网易近期正在缩减他们对日本游戏市场的投资。

关键字: 腾讯 编码器 CPU

8月28日消息,今天上午,2024中国国际大数据产业博览会开幕式在贵阳举行,华为董事、质量流程IT总裁陶景文发表了演讲。

关键字: 华为 12nm EDA 半导体

8月28日消息,在2024中国国际大数据产业博览会上,华为常务董事、华为云CEO张平安发表演讲称,数字世界的话语权最终是由生态的繁荣决定的。

关键字: 华为 12nm 手机 卫星通信

要点: 有效应对环境变化,经营业绩稳中有升 落实提质增效举措,毛利润率延续升势 战略布局成效显著,战新业务引领增长 以科技创新为引领,提升企业核心竞争力 坚持高质量发展策略,塑强核心竞争优势...

关键字: 通信 BSP 电信运营商 数字经济

北京2024年8月27日 /美通社/ -- 8月21日,由中央广播电视总台与中国电影电视技术学会联合牵头组建的NVI技术创新联盟在BIRTV2024超高清全产业链发展研讨会上宣布正式成立。 活动现场 NVI技术创新联...

关键字: VI 传输协议 音频 BSP

北京2024年8月27日 /美通社/ -- 在8月23日举办的2024年长三角生态绿色一体化发展示范区联合招商会上,软通动力信息技术(集团)股份有限公司(以下简称"软通动力")与长三角投资(上海)有限...

关键字: BSP 信息技术
关闭
关闭