加入星计划,您可以享受以下权益:

  • 创作内容快速变现
  • 行业影响力扩散
  • 作品版权保护
  • 300W+ 专业用户
  • 1.5W+ 优质创作者
  • 5000+ 长期合作伙伴
立即加入
  • 正文
    • 11.5  单寄存器数据传送指令
  • 相关推荐
  • 电子产业图谱
申请入驻 产业图谱

Thumb指令集之: 单寄存器数据传送指令

2013/09/30
1
阅读需 27 分钟
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

 

11.5  单寄存器数据传送指令

Thumb指令集支持寄存器的装载和存储,即LDR和STR指令。8和类型的Load/Store指令在Thumb指令集中可用。这些指令使用两种寻址模式:寄存器偏移和立即数偏移。指令所能存取的数据包括字、半字和字节,同时半字和字节可以为有符号数或无符号数。

表11.4总结了Thumb状态下可用的数据传送指令。

表11.4 Thumb状态数据传送指令

助  记  符

说    明

操    作

LDR

传送32位字到寄存器

Rd<- mem32[address]

STR

存储32位寄存器的值

Rd-> mem32[address]

LDRB

传送8位字节到寄存器

Rd<- mem8[address]

STRB

保存寄存器中的字节

Rd-> mem8[address]

LDRH

传送16位半字到寄存器

Rd<- mem16[address]

STRH

保存寄存器中的半字

Rd-> mem16[address]

LDRSB

装载有符号字节到寄存器

Rd<- sighExtend(mem8[address])

STRSB

装载有符号半字到寄存器

Rd<- sighExtend(mem16[address])

Thumb数据传送指令的基本语法格式分为以下4种。

① <opcode1>  <Rd>,[<Rn>,#<5_bit_offset>]

其中,<opcode1>:= LDR|LDRH|LDRB|STR|STRH|STRB

② <opcode2>  <Rd>,[<Rn>,<Rm>]

其中,<opcode2>:= LDR|LDRH|LDRB|LSRSH|STR|STRH|STRB

③ LDR  <Rd>,[PC,<8_bit_offset>]

④ <opcode3>  <Rd>,[SP,#<8_bit_offset>]

其中,<opcode3>:= LDR|STR

下面详细介绍各数据传送指令的语法和使用。

11.5.1  寄存器装载指令LDR(1)

(1)编码格式

寄存器装载指令LDR(1)的编码格式如图11.42所示。

图11.42  LDR(1)指令的编码格式

这种形式的LDR指令将32位内存数据装载到通用寄存器。常用于结构体的数据访问。域的基地址放在Rn寄存器中。

(2)指令的语法格式

LDR  <Rd>,[<Rn>,#<immed_5>*4]

① <Rd>

目的寄存器。用于存放从内存中取出的数据。

② <Rn>

基址寄存器,用于存放所取数据的基地址。

③ <immed_5>

5位立即数。该立即数的4倍加上基址寄存器的值形成目标地址。

(3)指令操作的伪代码

Address = Rn + (immed_5 * 4)

If  address[1:0] = = 0b00

     Data = Memory[address,4]

Else

     Data = UNPREDICTABLE

Rd = data

(4)对应的ARM指令

LDR  <Rd>,[<Rn>,#<immed_5>*4]

注意

如果指令访问地址非字对齐,则指令的执行结果不可预知。

11.5.2  寄存器装载指令LDR(2)

(1)编码格式

寄存器装载指令LDR(2)的编码格式如图11.43所示。

图11.43  LDR(2)指令的编码格式

寄存器装载指令LDR(2)允许将一个32位内存数据装载到通用寄存器。此种形式的LDR指令常被用于访问数组中的元素。

(2)指令的语法格式

LDR  <Rd>,[<Rn>,<Rm>]

① <Rd>

目的寄存器。

② <Rn>

寄存器存放内存访问基地址。

③ <Rm>

寄存器存放内存访问偏移地址。

(3)指令操作的伪代码

Address = Rn + Rm

If  address[1:0] = = 0b00

     Data = Memory[address,4]

Else

     Data = UNPREDICTABLE

Rd = data

(4)对应的ARM指令

LDR  <Rd>,[<Rn>,<Rm>]

 

11.5.3  寄存器装载指令LDR(3)

(1)编码格式

寄存器装载指令LDR(3)的编码格式如图11.44所示。

图11.44  LDR(3)指令的编码格式

寄存器装载指令LDR(3)允许将一个32位内存数据装载到通用寄存器。此种形式的LDR指令常被用于访问PC相关(PC-relative)数据。

(2)指令的语法格式

LDR  <Rd>,[PC,#<immed_8>*4]

① <Rd>

目的寄存器。

② PC

程序指针寄存器,用于计算内存访问的地址。计算地址时,PC值的bit[1]被系统默认为0进行计算,所以产生的内存访问地址必为字对齐。

③ <immed_8>

8位立即数。该立即数的4倍将和PC值相加,形成内存访问地址。

(3)指令操作的伪代码

Address = (PC[31:2] << 2) + (immed_8*4)

Rd = Memory[address,4]

(4)对应的ARM指令

LDR  <Rd>,[PC,#<immed_8>*4]

11.5.4  寄存器装载指令LDR(4)

(1)编码格式

寄存器装载指令LDR(4)的编码格式如图11.45所示。

图11.45  LDR(4)指令的编码格式

寄存器装载指令LDR(4)允许将一个32位内存数据装载到通用寄存器。此种形式的LDR指令常被用于访问堆栈数据。

(2)指令的语法格式

LDR  <Rd>,SP,#<immed_8>*4]

① <Rd>

目的寄存器。

② SP

堆栈指针寄存器,用于计算内存访问地址。

③ <immed_8>

8位立即数。该立即数的4倍将和SP值相加,形成内存访问地址。

(3)指令操作的伪代码

Address = SP + (immed_8*4)

If  address[1:0] = = 0b00

     Data = memory[address,4]

Else

     Data = UNPREDICTABLE

Rd = data

(4)对应的ARM指令

LDR  <Rd>,[SP,#<immed_8>*4]

 

11.5.5  字节加载指令LDRB(1)

(1)编码格式

字节加载指令LDRB(1)的编码格式如图11.46所示。

图11.46  LDRB(1)指令的编码格式

LDRB(1)字节数据加载指令用于从内存中将一个8位的字节数据读取到指令中的目标寄存器中,并将寄存器的高24位清零。常用于结构体的数据访问。域的基地址放在Rn寄存器中。

(2)指令的语法格式

LDRB  <Rd>,[<Rn>,#<immed_5>]

① <Rd>

目的寄存器。

② <Rn>

指令的基址寄存器。

③ <immed_5>

5位立即数。用于与<Rn>寄存器中的数值相加,形成内存访问地址。

(3)指令操作的伪代码

address = Rn + immed_5

Rd = memory[address,1]

(4)对应的ARM指令

LDRB  <Rd>,[<Rn>,#<immed_5>]

11.5.6  字节加载指令LDRB(2)

(1)编码格式

字节加载指令LDRB(2)的编码格式如图11.47所示。

图11.47  LDRB(2)指令的编码格式

LDRB(2)字节数据加载指令用于从内存中将一个8位的字节数据读取到指令中的目标寄存器中,并将寄存器的高24位清零。此种形式的LDRB(2)指令常用于数组元素的访问。

(2)指令的语法格式

LDRB  <Rd>,[<Rn>,<Rm>]

① <Rd>

目的寄存器。

② <Rn>

存放形成内存访问地址的第一个寄存器。

③ <Rm>

存放形成内存访问地址的第二个寄存器。

(3)指令操作的伪代码

address = Rn + Rm

Rd = Memory[address,1]

(4)对应的ARM指令

LDRB  <Rd>,[<Rn>,<Rm>]

 

11.5.7  半字加载指令LDRH(1)

(1)编码格式

半字数据加载指令LDRH(1)的编码格式如图11.48所示。

图11.48  LDRH(1)指令的编码格式

LDRH(1)半字数据加载指令用于从内存中将一个16位的半字数据读取到指令中的目标寄存器中,并将寄存器的高16位清零。常用于结构体的数据访问。域的基地址放在Rn寄存器中。

(2)指令的语法格式

LDRH  <Rd>,[<Rn>,#<immed_5>*2]

① <Rd>

目的寄存器。

② <Rn>

指令的基址寄存器。

③ <immed_5>

5位立即数。该寄存器数值的2倍将与<Rn>寄存器中的数值相加,形成内存访问地址。

(3)指令操作的伪代码

address = Rn + (immed_5 *2)

if  address[0] = = 0

     data = Memory[address,2]

else

     data = UNPREDICTABLE

Rd = data

(4)对应的ARM指令

LDRH  <Rd>,[<Rn>,#<immed_5>*2]

11.5.8  半字数据加载指令LDRH(2)

(1)编码格式

半字数据加载指令LDRH(2)的编码格式如图11.49所示。

LDRH(2)字节数据加载指令用于从内存中将一个16位的半字数据读取到指令中的目标寄存器中,并将寄存器的高16位清零。此种形式的LDRH(2)指令常用于数组元素的访问。

图11.49  LDRH(2)指令的编码格式

(2)指令的语法格式

LDRB  <Rd>,[<Rn>,<Rm>]

① <Rd>

目的寄存器。

② <Rn>

此寄存器存放内存访问基地址。

③ <Rm>

此寄存器存放内存访问偏移地址。

(3)指令操作的伪代码

address = Rn + Rm

if  address[0] = = 0

     data = memory[address,2]

else

     data = UNPREDICTABLE

Rd = data

(4)对应的ARM指令

LDRH  <Rd>,[<Rn>,<Rm>]

 

11.5.9  有符号字节数据加载指令LDRSB

(1)编码格式

有符号字节数据加载指令LDRSB的编码格式如图11.50所示。

图11.50  LDRSB指令的编码格式

LDRSB指令用于从内存中将一个8位的字节数据读取到指令中的目标寄存器中,并将寄存器的高24位设置成该字节数据的符号位的值(即将该8位字节数据进行符号位扩展,生成32位字数据)。

(2)指令的语法格式

LDRSB  <Rd>,[<Rn>,<Rm>]

① <Rd>

目的寄存器。

② <Rn>

此寄存器存放内存访问基地址。

③ <Rm>

此寄存器存放内存访问偏移地址。

(3)指令操作的伪代码

address = Rn + Rm

Rd = SignExtend(Memory[address,1])

(4)对应的ARM指令

LDRSB  <Rd>,[<Rn>,<Rm>]

11.5.10  有符号半字数据加载指令LDRSH

(1)编码格式

有符号字节数据加载指令LDRSH的编码格式如图11.51所示。

图11.51  LDRSH指令的编码格式

LDRSH指令用于从内存中将一个16位的半字数据读取到指令中的目标寄存器中,并将寄存器的高16位设置成该半字数据的符号位的值(即将该16位半字数据进行符号位扩展,生成32位字数据)。

(2)指令的语法格式

LDRBH  <Rd>,[<Rn>,<Rm>]

① <Rd>

目的寄存器。

② <Rn>

此寄存器存放内存访问基地址。

③ <Rm>

此寄存器存放内存访问偏移地址。

(3)指令操作的伪代码

address = Rn + Rm

if  address[0] = = 0

     data = memory[address,2]

else

     data = UNPREDICTABLE

Rd = SignExtend[data]

(4)对应的ARM指令

LDRSH  <Rd>,[<Rn>,<Rm>]

 

11.5.11  寄存器存储指令STR(1)

(1)编码格式

寄存器存储指令STR(1)的编码格式如图11.52所示。

图11.52  STR(1)指令的编码格式

这种形式的STR指令将32位通用寄存器的数值存储到内存中。该指令常用于结构体的数据访问。域的基地址放在Rn寄存器中。

(2)指令的语法格式

STR  <Rd>,[<Rn>,#<immed_5>*4]

① <Rd>

目的寄存器。用于存放从内存中取出的数据。

② <Rn>

基址寄存器,用于存放所取数据的基地址。

③ <immed_5>

5位立即数。该立即数的4倍加上基址寄存器的值为目标地址。

(3)指令操作的伪代码

address = Rn + (immed_5*4)

if  address[1:0] = = 0b00

      Memory[address,4] = Rd

Else

      Memory[address,4] = UNPREDICTABLE

(4)对应的ARM指令

STR  <Rd>,[<Rn>,#<immed_5>*4]

 

11.5.12  寄存器存储指令STR(2)

(1)编码格式

寄存器存储指令STR(2)的编码格式如图11.53所示。

图11.53  STR(2)指令的编码格式

寄存器装载指令STR(2)将一个32位通用寄存器数据存储到内存单元中。此种形式的STR指令常被用于访问数组中的元素。

(2)指令的语法格式

LDR  <Rd>,[<Rn>,<Rm>]

① <Rd>

目的寄存器。

② <Rn>

存放形成内存访问地址的第一个寄存器。

③ <Rm>

存放形成内存访问地址的第二个寄存器。

(3)指令操作的伪代码

address = Rn + Rm

if  address[1:0] = = 0b00

      Memory[address,4] = = Rd

Else

      Memory[address,4] = = UNPREDICTABLE

(4)对应的ARM指令

STR  <Rd>,[<Rn>,<Rm>]

11.5.13  寄存器存储指令STR(3)

(1)编码格式

寄存器存储指令STR(3)的编码格式如图11.54所示。

图11.54  STR(3)指令的编码格式

寄存器存储指令STR(3)允许将一个32位通用寄存器的值存储到内存。此种形式的STR指令常被用于访问堆栈数据。

(2)指令的语法格式

STR  <Rd>,[SP,#<immed_8>*4]

① <Rd>

目的寄存器。

② SP

堆栈指针寄存器,用于计算内存访问的地址。

③ <immed_8>

8位立即数。该立即数的4倍将和堆栈指针寄存器SP的值相加,形成内存访问地址。

(3)指令操作的伪代码

address = SP + (immed_8 * 4)

if  address[1:0] = = 0b00

      Memory[address,4] = Rd

Else

      Memory[address,4] = UNPREDICTABLE

(4)对应的ARM指令

STR  <Rd>,[SP,#<immed_8>*4]

 

11.5.14  字节存储指令STRB(1)

(1)编码格式

字节存储加载指令STRB(1)的编码格式如图11.55所示。

图11.55  STRB(1)指令的编码格式

STRB(1)字节数据存储指令用于将一个8位的字节数据写入到指令中指定的内存单元,该字节数据为指令中存放源操作数寄存器的低8位。常用于结构体的数据访问。域的基地址放在Rn寄存器中。

(2)指令的语法格式

STRB  <Rd>,[<Rn>,#<immed_5>]

① <Rd>

目的寄存器。

② <Rn>

指令的基址寄存器。

③ <immed_5>

5位立即数。用于与<Rn>寄存器中的数值相加,形成内存访问地址。

(3)指令操作的伪代码

address = Rn + immed_5

Memory[address,1] = Rd[7:0]

(4)对应的ARM指令

STRB  <Rd>,[<Rn>,#<immed_5>]

11.5.15  寄存器存储指令STRB(2)

(1)编码格式

寄存器存储指令STRB(2)的编码格式如图11.56所示。

图11.56  STRB(2)指令的编码格式

寄存器存储指令STRB(2)用于将一个8位的字节数据写入到指令中指定的内存单元。此种形式的LDRB指令常被用于访问数组中的元素。

(2)指令的语法格式

STRB  <Rd>,[<Rn>,<Rm>]

① <Rd>

目的寄存器。

② <Rn>

此寄存器存放内存访问基地址。

③ <Rm>

此寄存器存放内存访问偏移地址。

(3)指令操作的伪代码

address = Rn + Rm

Memory[address,1] = Rd[7:0]

(4)对应的ARM指令

STRB  <Rd>,[<Rn>,<Rm>]

 

11.5.16  半字存储指令STRH(1)

(1)编码格式

半字存储加载指令STRH(1)的编码格式如图11.57所示。

图11.57  STRH(1)指令的编码格式

STRH(1)半字数据存储指令用于将一个16位的半字数据写入到指令中指定的内存单元,该半字数据为指令中存放源操作数寄存器的低16位。常用于结构体的数据访问。域的基地址放在Rn寄存器中。

(2)指令的语法格式

STRH  <Rd>,[<Rn>,#<immed_5>*2]

① <Rd>

目的寄存器。

② <Rn>

指令的基址寄存器。

③ <immed_5>

5位立即数。该立即数的2倍与<Rn>寄存器中的数值相加,形成内存访问地址。

(3)指令操作的伪代码

address = Rn + (immed_5*2)

if  address[1:0] = = 0

      Memory[address,2] = Rd[15:0]

Else

      Memory[address,2] = UNPREDICTABLE

(4)对应的ARM指令

STRH  <Rd>,[<Rn>,#<immed_5>*2]

11.5.17  寄存器存储指令STRH(2)

(1)编码格式

寄存器存储指令STRH(2)的编码格式如图11.58所示。

图11.58  STRH(2)指令的编码格式

寄存器存储指令STRH(2)用于将一个8位的半字数据写入到指令中指定的内存单元。此种形式的STRH指令常被用于访问数组中的元素。

(2)指令的语法格式

STRH  <Rd>,[<Rn>,<Rm>]

① <Rd>

目的寄存器。

② <Rn>

存放形成内存访问地址的第一个寄存器。

③ <Rm>

存放形成内存访问地址的第二个寄存器。

(3)指令操作的伪代码

address = Rn + Rm

if  address[1:0] = = 0

      Memory[address,2] = Rd[15:0]

Else

      Memory[address,2] = UNPREDICTABLE

(4)对应的ARM指令

STRH  <Rd>,[<Rn>,<Rm>]

 

11.5.18  数据传送指令举例

下面的例子程序综合使用了各种数据传送指令,通过该例可以对Thumb状态下数据传送指令有更深入的了解。

LDR  r4,[r2,#4] ;将[r2+4]地址单元字数据加载到寄存器r4

LDR  r4,[r2,r1] ;将[r2+r4]地址单元字数据加载到寄存器r4

STR  r0,[r7,#0x7c] ;将r0中的字数据存储到[r7+124]的内存地址单元中

STRB  r1,[r5,#31] ;将r1的低8位数据存储到[r5+31]的内存地址单元中

STRH  r4,[r2,r3] ;将r4的低16位数据存储到[r2+r3]的内存地址单元中

LDRH  r3,[r6,r5] ;将[r6+r5]地址单元低16位数据加载到寄存器r3中

LDRB  r2,[r1,#5] ;将[r1+5]地址单元低8位数据加载到寄存器r2中

LDR  r6,[PC,#0xFC] ;将[PC+0x3FC]地址单元数据加载到寄存器r6中

LDR  r5,[SP,#64] ;将[SP+64]地址单元数据加载到寄存器r5中

STR  r4,[SP,#0x260] ;将寄存器r4中的数据存储到[SP+0x260]内存地址单元中

Arm

Arm

ARM公司是一家知识产权(IP)供应商,主要为国际上其他的电子公司提供高性能RISC处理器、外设和系统芯片技术授权。目前,ARM公司的处理器内核已经成为便携通讯、手持计算设备、多媒体数字消费品等方案的RISC标准。公司1990年11月由Acorn、Apple和VLSI合并而成。

ARM公司是一家知识产权(IP)供应商,主要为国际上其他的电子公司提供高性能RISC处理器、外设和系统芯片技术授权。目前,ARM公司的处理器内核已经成为便携通讯、手持计算设备、多媒体数字消费品等方案的RISC标准。公司1990年11月由Acorn、Apple和VLSI合并而成。收起

查看更多

相关推荐

电子产业图谱

华清远见(www.farsight.com.cn)是国内领先嵌入师培训机构,2004年注册于中国北京海淀高科技园区,除北京总部外,上海、深圳、成都、南京、武汉、西安、广州均有直营分公司。华清远见除提供嵌入式相关的长期就业培训、短期高端培训、师资培训及企业员工内训等业务外,其下属研发中心还负责嵌入式、Android及物联网方向的教学实验平台的研发及培训教材的出版,截止目前为止已公开出版70余本嵌入式/移动开发/物联网相关图书。企业理念:专业始于专注 卓识源于远见。企业价值观:做良心教育、做专业教育,更要做受人尊敬的职业教育。