查看完整版本: Thumb指令集之: 单寄存器数据传送指令

admin 发表于 2014-10-10 07:28:09

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

        11.5单寄存器数据传送指令

        Thumb指令集支持寄存器的装载和存储,即LDR和STR指令。8和类型的Load/Store指令在Thumb指令集中可用。这些指令使用两种寻址模式:寄存器偏移和立即数偏移。指令所能存取的数据包括字、半字和字节,同时半字和字节可以为有符号数或无符号数。
       
        表11.4总结了Thumb状态下可用的数据传送指令。
        表11.4 Thumb状态数据传送指令
                                                                                                                        助记符
                                                                                                                        说    明
                                                                                                                        操    作
                                                                                                                                                        LDR
                                                                                                                        传送32位字到寄存器
                                                                                                                        Rd<- mem32
                                                                                                                                                        STR
                                                                                                                        存储32位寄存器的值
                                                                                                                        Rd-> mem32
                                                                                                                                                        LDRB
                                                                                                                        传送8位字节到寄存器
                                                                                                                        Rd<- mem8
                                                                                                                                                        STRB
                                                                                                                        保存寄存器中的字节
                                                                                                                        Rd-> mem8
                                                                                                                                                        LDRH
                                                                                                                        传送16位半字到寄存器
                                                                                                                        Rd<- mem16
                                                                                                                                                        STRH
                                                                                                                        保存寄存器中的半字
                                                                                                                        Rd-> mem16
                                                                                                                                                        LDRSB
                                                                                                                        装载有符号字节到寄存器
                                                                                                                        Rd<- sighExtend(mem8)
                                                                                                                                                        STRSB
                                                                                                                        装载有符号半字到寄存器
                                                                                                                        Rd<- sighExtend(mem16)
                                                       
        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>,
        ④ <opcode3><Rd>,
       
        其中,<opcode3>:= LDR|STR
        下面详细介绍各数据传送指令的语法和使用。
       
        11.5.1寄存器装载指令LDR(1)

        (1)编码格式
        寄存器装载指令LDR(1)的编码格式如图11.42所示。
       
        图11.42LDR(1)指令的编码格式
       
        这种形式的LDR指令将32位内存数据装载到通用寄存器。常用于结构体的数据访问。域的基地址放在Rn寄存器中。
       
        (2)指令的语法格式
       
        LDR<Rd>,[<Rn>,#<immed_5>*4]
       
        ① <Rd>
        目的寄存器。用于存放从内存中取出的数据。
        ② <Rn>
        基址寄存器,用于存放所取数据的基地址。
        ③ <immed_5>
        5位立即数。该立即数的4倍加上基址寄存器的值形成目标地址。
       
        (3)指令操作的伪代码
       
        Address = Rn + (immed_5 * 4)
        Ifaddress = = 0b00
             Data = Memory
        Else
             Data = UNPREDICTABLE
        Rd = data
       
        (4)对应的ARM指令
       
        LDR<Rd>,[<Rn>,#<immed_5>*4]
       
                                                                                                                       
                                                                                                                        注意
                                                                                                                        如果指令访问地址非字对齐,则指令的执行结果不可预知。
                                                       
        11.5.2寄存器装载指令LDR(2)

        (1)编码格式
        寄存器装载指令LDR(2)的编码格式如图11.43所示。
       
        图11.43LDR(2)指令的编码格式
       
        寄存器装载指令LDR(2)允许将一个32位内存数据装载到通用寄存器。此种形式的LDR指令常被用于访问数组中的元素。
       
        (2)指令的语法格式
       
        LDR<Rd>,[<Rn>,<Rm>]
       
        ① <Rd>
        目的寄存器。
        ② <Rn>
        寄存器存放内存访问基地址。
        ③ <Rm>
        寄存器存放内存访问偏移地址。
       
        (3)指令操作的伪代码
       
        Address = Rn + Rm
        Ifaddress = = 0b00
             Data = Memory
        Else
             Data = UNPREDICTABLE
        Rd = data
       
        (4)对应的ARM指令
       
        LDR<Rd>,[<Rn>,<Rm>]
       
        11.5.3寄存器装载指令LDR(3)

        (1)编码格式
        寄存器装载指令LDR(3)的编码格式如图11.44所示。
       
        图11.44LDR(3)指令的编码格式
       
        寄存器装载指令LDR(3)允许将一个32位内存数据装载到通用寄存器。此种形式的LDR指令常被用于访问PC相关(PC-relative)数据。
       
        (2)指令的语法格式
       
        LDR<Rd>,
       
        ① <Rd>
        目的寄存器。
        ② PC
        程序指针寄存器,用于计算内存访问的地址。计算地址时,PC值的bit被系统默认为0进行计算,所以产生的内存访问地址必为字对齐。
        ③ <immed_8>
        8位立即数。该立即数的4倍将和PC值相加,形成内存访问地址。
       
        (3)指令操作的伪代码
       
        Address = (PC << 2) + (immed_8*4)
        Rd = Memory
       
        (4)对应的ARM指令
       
        LDR<Rd>,
       
        11.5.4寄存器装载指令LDR(4)

        (1)编码格式
        寄存器装载指令LDR(4)的编码格式如图11.45所示。
       
        图11.45LDR(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)
        Ifaddress = = 0b00
             Data = memory
        Else
             Data = UNPREDICTABLE
        Rd = data
       
        (4)对应的ARM指令
       
        LDR<Rd>,
       
        11.5.5字节加载指令LDRB(1)

        (1)编码格式
        字节加载指令LDRB(1)的编码格式如图11.46所示。
       
        图11.46LDRB(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
       
        (4)对应的ARM指令
       
        LDRB<Rd>,[<Rn>,#<immed_5>]
       
        11.5.6字节加载指令LDRB(2)

        (1)编码格式
        字节加载指令LDRB(2)的编码格式如图11.47所示。
       
        图11.47LDRB(2)指令的编码格式
       
        LDRB(2)字节数据加载指令用于从内存中将一个8位的字节数据读取到指令中的目标寄存器中,并将寄存器的高24位清零。此种形式的LDRB(2)指令常用于数组元素的访问。
       
        (2)指令的语法格式
       
        LDRB<Rd>,[<Rn>,<Rm>]
       
        ① <Rd>
        目的寄存器。
        ② <Rn>
        存放形成内存访问地址的第一个寄存器。
        ③ <Rm>
        存放形成内存访问地址的第二个寄存器。
       
        (3)指令操作的伪代码
       
        address = Rn + Rm
        Rd = Memory
       
        (4)对应的ARM指令
       
        LDRB<Rd>,[<Rn>,<Rm>]
       
        11.5.7半字加载指令LDRH(1)

        (1)编码格式
        半字数据加载指令LDRH(1)的编码格式如图11.48所示。
       
        图11.48LDRH(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)
        ifaddress = = 0
             data = Memory
        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.49LDRH(2)指令的编码格式
       
        (2)指令的语法格式
       
        LDRB<Rd>,[<Rn>,<Rm>]
       
        ① <Rd>
        目的寄存器。
        ② <Rn>
        此寄存器存放内存访问基地址。
        ③ <Rm>
        此寄存器存放内存访问偏移地址。
       
        (3)指令操作的伪代码
       
        address = Rn + Rm
        ifaddress = = 0
             data = memory
        else
             data = UNPREDICTABLE
        Rd = data
       
        (4)对应的ARM指令
       
        LDRH<Rd>,[<Rn>,<Rm>]
       
        11.5.9有符号字节数据加载指令LDRSB

        (1)编码格式
        有符号字节数据加载指令LDRSB的编码格式如图11.50所示。
       
        图11.50LDRSB指令的编码格式
       
        LDRSB指令用于从内存中将一个8位的字节数据读取到指令中的目标寄存器中,并将寄存器的高24位设置成该字节数据的符号位的值(即将该8位字节数据进行符号位扩展,生成32位字数据)。
       
        (2)指令的语法格式
       
        LDRSB<Rd>,[<Rn>,<Rm>]
        ① <Rd>
        目的寄存器。
        ② <Rn>
        此寄存器存放内存访问基地址。
        ③ <Rm>
        此寄存器存放内存访问偏移地址。
       
        (3)指令操作的伪代码
       
        address = Rn + Rm
        Rd = SignExtend(Memory)
       
        (4)对应的ARM指令
       
        LDRSB<Rd>,[<Rn>,<Rm>]
       
        11.5.10有符号半字数据加载指令LDRSH

        (1)编码格式
        有符号字节数据加载指令LDRSH的编码格式如图11.51所示。
       
        图11.51LDRSH指令的编码格式
       
        LDRSH指令用于从内存中将一个16位的半字数据读取到指令中的目标寄存器中,并将寄存器的高16位设置成该半字数据的符号位的值(即将该16位半字数据进行符号位扩展,生成32位字数据)。
       
        (2)指令的语法格式
       
        LDRBH<Rd>,[<Rn>,<Rm>]
       
        ① <Rd>
        目的寄存器。
        ② <Rn>
        此寄存器存放内存访问基地址。
        ③ <Rm>
        此寄存器存放内存访问偏移地址。
       
        (3)指令操作的伪代码
       
        address = Rn + Rm
        ifaddress = = 0
             data = memory
        else
             data = UNPREDICTABLE
        Rd = SignExtend
        (4)对应的ARM指令
       
        LDRSH<Rd>,[<Rn>,<Rm>]
       
        11.5.11寄存器存储指令STR(1)

        (1)编码格式
        寄存器存储指令STR(1)的编码格式如图11.52所示。
       
        图11.52STR(1)指令的编码格式
       
        这种形式的STR指令将32位通用寄存器的数值存储到内存中。该指令常用于结构体的数据访问。域的基地址放在Rn寄存器中。
       
        (2)指令的语法格式
       
        STR<Rd>,[<Rn>,#<immed_5>*4]
       
        ① <Rd>
        目的寄存器。用于存放从内存中取出的数据。
        ② <Rn>
        基址寄存器,用于存放所取数据的基地址。
        ③ <immed_5>
        5位立即数。该立即数的4倍加上基址寄存器的值为目标地址。
       
        (3)指令操作的伪代码
       
        address = Rn + (immed_5*4)
        ifaddress = = 0b00
              Memory = Rd
        Else
              Memory = UNPREDICTABLE
       
        (4)对应的ARM指令
       
        STR<Rd>,[<Rn>,#<immed_5>*4]
       
        11.5.12寄存器存储指令STR(2)

        (1)编码格式
        寄存器存储指令STR(2)的编码格式如图11.53所示。
       
        图11.53STR(2)指令的编码格式
       
        寄存器装载指令STR(2)将一个32位通用寄存器数据存储到内存单元中。此种形式的STR指令常被用于访问数组中的元素。
       
        (2)指令的语法格式
       
        LDR<Rd>,[<Rn>,<Rm>]
       
        ① <Rd>
        目的寄存器。
        ② <Rn>
        存放形成内存访问地址的第一个寄存器。
        ③ <Rm>
        存放形成内存访问地址的第二个寄存器。
       
        (3)指令操作的伪代码
       
        address = Rn + Rm
        ifaddress = = 0b00
              Memory = = Rd
        Else
              Memory = = UNPREDICTABLE
       
        (4)对应的ARM指令
       
        STR<Rd>,[<Rn>,<Rm>]
       
        11.5.13寄存器存储指令STR(3)

        (1)编码格式
        寄存器存储指令STR(3)的编码格式如图11.54所示。
       
        图11.54STR(3)指令的编码格式
       
        寄存器存储指令STR(3)允许将一个32位通用寄存器的值存储到内存。此种形式的STR指令常被用于访问堆栈数据。
       
        (2)指令的语法格式
       
        STR<Rd>,
       
        ① <Rd>
        目的寄存器。
        ② SP
        堆栈指针寄存器,用于计算内存访问的地址。
        ③ <immed_8>
        8位立即数。该立即数的4倍将和堆栈指针寄存器SP的值相加,形成内存访问地址。
       
        (3)指令操作的伪代码
       
        address = SP + (immed_8 * 4)
        ifaddress = = 0b00
              Memory = Rd
        Else
              Memory = UNPREDICTABLE
       
        (4)对应的ARM指令
       
        STR<Rd>,
       
        11.5.14字节存储指令STRB(1)

        (1)编码格式
        字节存储加载指令STRB(1)的编码格式如图11.55所示。
       
        图11.55STRB(1)指令的编码格式
       
        STRB(1)字节数据存储指令用于将一个8位的字节数据写入到指令中指定的内存单元,该字节数据为指令中存放源操作数寄存器的低8位。常用于结构体的数据访问。域的基地址放在Rn寄存器中。
       
        (2)指令的语法格式
       
        STRB<Rd>,[<Rn>,#<immed_5>]
       
        ① <Rd>
        目的寄存器。
        ② <Rn>
        指令的基址寄存器。
        ③ <immed_5>
        5位立即数。用于与<Rn>寄存器中的数值相加,形成内存访问地址。
       
        (3)指令操作的伪代码
       
        address = Rn + immed_5
        Memory = Rd
       
        (4)对应的ARM指令
       
        STRB<Rd>,[<Rn>,#<immed_5>]
       
        11.5.15寄存器存储指令STRB(2)

        (1)编码格式
        寄存器存储指令STRB(2)的编码格式如图11.56所示。
       
        图11.56STRB(2)指令的编码格式
       
        寄存器存储指令STRB(2)用于将一个8位的字节数据写入到指令中指定的内存单元。此种形式的LDRB指令常被用于访问数组中的元素。
       
        (2)指令的语法格式
       
        STRB<Rd>,[<Rn>,<Rm>]
       
        ① <Rd>
        目的寄存器。
        ② <Rn>
        此寄存器存放内存访问基地址。
        ③ <Rm>
        此寄存器存放内存访问偏移地址。
       
        (3)指令操作的伪代码
       
        address = Rn + Rm
        Memory = Rd
       
        (4)对应的ARM指令
       
        STRB<Rd>,[<Rn>,<Rm>]
       
        11.5.16半字存储指令STRH(1)

        (1)编码格式
        半字存储加载指令STRH(1)的编码格式如图11.57所示。
       
        图11.57STRH(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)
        ifaddress = = 0
              Memory = Rd
        Else
              Memory = UNPREDICTABLE
       
        (4)对应的ARM指令
       
        STRH<Rd>,[<Rn>,#<immed_5>*2]
       
        11.5.17寄存器存储指令STRH(2)

        (1)编码格式
        寄存器存储指令STRH(2)的编码格式如图11.58所示。
       
        图11.58STRH(2)指令的编码格式
       
        寄存器存储指令STRH(2)用于将一个8位的半字数据写入到指令中指定的内存单元。此种形式的STRH指令常被用于访问数组中的元素。
       
        (2)指令的语法格式
       
        STRH<Rd>,[<Rn>,<Rm>]
       
        ① <Rd>
        目的寄存器。
        ② <Rn>
        存放形成内存访问地址的第一个寄存器。
        ③ <Rm>
        存放形成内存访问地址的第二个寄存器。
       
        (3)指令操作的伪代码
       
        address = Rn + Rm
        ifaddress = = 0
              Memory = Rd
        Else
              Memory = UNPREDICTABLE
        (4)对应的ARM指令
       
        STRH<Rd>,[<Rn>,<Rm>]
       
        11.5.18数据传送指令举例

        下面的例子程序综合使用了各种数据传送指令,通过该例可以对Thumb状态下数据传送指令有更深入的了解。
       
        LDRr4, ;将地址单元字数据加载到寄存器r4
        LDRr4, ;将地址单元字数据加载到寄存器r4
        STRr0, ;将r0中的字数据存储到的内存地址单元中
        STRBr1, ;将r1的低8位数据存储到的内存地址单元中
        STRHr4, ;将r4的低16位数据存储到的内存地址单元中
        LDRHr3, ;将地址单元低16位数据加载到寄存器r3中
        LDRBr2, ;将地址单元低8位数据加载到寄存器r2中
        LDRr6, ;将地址单元数据加载到寄存器r6中
        LDRr5, ;将地址单元数据加载到寄存器r5中
        STRr4, ;将寄存器r4中的数据存储到内存地址单元中
页: [1]
查看完整版本: Thumb指令集之: 单寄存器数据传送指令