DIY编程器网

 找回密码
 注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 1316|回复: 0
打印 上一主题 下一主题

[待整理] 数据传送指令之:单寄存器的Load/Store指令

[复制链接]
跳转到指定楼层
楼主
发表于 2014-10-10 07:31:29 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
        5.3  单寄存器的Load/Store指令

        Load/Store内存访问指令在ARM寄存器和存储器之间传送数据。ARM指令中有3种基本的数据传送指令。
         
        ① 单寄存器Load/Store指令(Single Register)
        这些指令在ARM寄存器和存储器之间提供更灵活的单数据项传送方式。数据项可以是字节、16位半字或32位字。
         
        ② 多寄存器Load/Store内存访问指令
        这些指令的灵活性比单寄存器传送指令差,但可以使大量的数据更有效地传送。它们用于进程的进入和退出、保存和恢复工作寄存器以及拷贝存储器中的一块数据。
         
        ③ 单寄存器交换指令(Single Register Swap)
        这些指令允许寄存器和存储器中的数值进行交换,在一条指令中有效地完成Load/Store操作。它们在用户级编程中很少用到。它的主要用途是在多处理器系统中实现信号量(Semaphores)的操作,以保证不会同时访问公用的数据结构。
         
        5.3.1  字数据传送指令

        这种指令用于把单一的数据传入或者传出一个寄存器。支持的数据类型有字节(8位)、半字(16位)和字(32位)。
         
        表5.1总结了所有单寄存器的Load/Store指令。
        表5.1       单寄存器Load/Store指令
                                                                        指    令
                       
                                                                        作    用
                       
                                                                        操    作
                       
                                                                        LDR
                       
                                                                        把一个字装入一个寄存器
                       
                                                                        Rd←mem32[address]
                       
                                                                        STR
                       
                                                                        将存储器中的字保存到寄存器
                       
                                                                        Rd→mem32[address]
                       
                                                                        LDRB
                       
                                                                        把一个字节装入一个寄存器
                       
                                                                        Rd←mem8[address]
                       
                                                                        STRB
                       
                                                                        将寄存器中的低8位字节保存到存储器
                       
                                                                        Rd→mem8[address]
                       
                                                                        LDRH
                       
                                                                        把一个半字装入一个寄存器
                       
                                                                        Rd←mem16[address]
                       
                                                                        STRH
                       
                                                                        将寄存器中的低16位半字保存到存储器
                       
                                                                        Rd→mem16[address]
                       
                                                                        LDRBT
                       
                                                                        用户模式下将一个字节装入寄存器
                       
                                                                        Rd←mem8[address] under user mode
                       
                                                                        STRBT
                       
                                                                        用户模式下将寄存器中的低8位字节保存到存储器
                       
                                                                        Rd→mem8[address] under user mode
                       
                                                                        LDRT
                       
                                                                        用户模式下把一个字装入一个寄存器
                       
                                                                        Rd←mem32[address]under user mode
                       
                                                                        STRT
                       
                                                                        用户模式下将存储器中的字保存到寄存器
                       
                                                                        Rd→mem32[address] ]under user mode
                       
                                                                        LDRSB
                       
                                                                        把一个有符号字节装入一个寄存器
                       
                                                                        Rd←sign{mem8[address]}
                       
                                                                        LDRSH
                       
                                                                        把一个有符号半字装入一个寄存器
                       
                                                                        Rd←sign{mem16[address]}
                       
         

        1.LDR指令

        (1)指令编码格式
        LDR指令用于从内存中将一个32位的字读取到目标寄存器。
         
        指令的编码格式如图5.3所示。
       

        图5.3  LDR指令编码格式

         
        LDR指令根据<addr_mode>所确定的地址模式将一个32位字读取到指令中的目标寄存器<Rd>。如果指令中的寻址方式确定的地址不是字对齐的,则读出的数值要进行循环右移。所移位数为寻址方式确定的地址bits[1∶0]8的倍,也就是说处理器将取到的数值作为字的最低位处理。
         
        如果设置了L位,则进行装载,否则进行存储。
        如果设置了P位,则使用预先变址寻址,否则使用过后变址寻址。
        如果设置了U位,则给出的偏移量被加到基址寄存器上,否则从中减去偏移量。
        如果设置了B位,传送内存的一个字节,否则传送一个字。这在助记符末尾添加后缀“B”,如MOV r7,r5变为MOVB r7,r5。
         
        W位的解释依赖于使用的地址模式。
        ·  对于预先变址寻址,设置W位强制把它用做地址转换的最终地址写回基址寄存器中(例如,传送的副作用是Rn:= Rn +/-offset。这在汇编器中表示为给指令加上后缀“!”。)。
        ·  对于过后变址寻址,地址总是写回,设置 W 位指示在进行传送之前强制地址转换。这在汇编器中表示为给指令加上后缀“T”。
         
        当PC作为LDR的目的寄存器<Rd>时,从存储器取得的数据将被当作目标地址值,程序将跳转到目标地址开始执行。
         
        (2)指令的语法格式
        LDR{<cond>}  <Rd>,<addr_mode>
         
        ① <cond>
        为指令编码中的条件域。它指示LDR指令在什么条件下执行。当<cond>忽略时,指令为无条件执行(cond=AL(Alway))。
         
        ② <Rd>
        确定使用哪个通用寄存器作为目标寄存器。
         
        ③ <addr_mode>
        它确定了指令编码中的I、P、U、W、Rn和<addr_mode>位。所有的寻址模式中,都会确定一个基址寄存器Rn。
         
        (3)指令操作的伪代码
        指令操作的伪代码如下面程序段所示。
         
        If  ConditionPassed{cond}  then
            If  address[1:0] == 0b00  then
                 Value = Memory[address,4]
        Else  if  address[1:0] == 0b01  then
             Value = Memory[address,4]  Rotate_Right 8
        Else  if  address[1:0] == 0b10  then
             Value = Memory[address,4]  Rotate_Right 16
        Eles  /* address[1:0] == 0b11*/
             Value = Memory[address,4]  Rotate_Right 24
        If  (Rd is R15)  then
             If (architecture version 5 or above)  then
                     PC = value AND 0xfffffffe
                     T Bit = value[0]
             Else
                     PC = value AND 0xfffffffc
        Else
             Rd = value
        (4)指令举例
         
        LDR  r1,[r0,#0x12]         ;将r0+12地址处的数据读出,保存到r1中(r0的值不变)
        LDR  r1,[r0]               ;将r0地址处的数据读出,保存到r1中(零偏移)
        LDR  r1,[r0,r2]           ;将r0+r2地址的数据读出,保存到r1中(r0的值不变)
        LDR  r1,[r0,r2,LSL #2]     ;将r0+r2×4地址处的数据读出,保存到r1中(r0,r2的值不变)
        LDR  Rd,label              ;label为程序标号,label必须是当前指令的±4KB范围内
        LDR  Rd,[Rn],#0x04        ;Rn的值用作传输数据的存储地址。在数据传送后,将偏移量0x04与
                                  Rn相加,结果写回到Rn中。Rn不允许是r15
         
                                                                       
                       
                                                                        注意
                       
                                                                        地址对齐问题:大多数情况下,必须保证用于32位传送的地址是32位对齐的。
                       
         
        2.STR指令

        (1)指令编码格式
         
        STR指令用于将一个32位的字数据写入到指令中指定的内存单元。
        指令的编码格式如图5.4所示。
       

        图5.4  STR指令编码格式

         
        (2)指令的语法格式
         
        STR{<cond>}  <Rd>,<addr_mode>
         
        ① <cond>
        为指令编码中的条件域。它指示STR指令在什么条件下执行。当<cond>忽略时,指令为无条件执行(cond=AL(Alway))。
         
        ② <Rd>
        确定使用哪个通用寄存器作为目标寄存器。
         
        ③ <addr_mode>
        它确定了指令编码中的I、P、U、W、Rn和<addr_mode>位。所有的寻址模式中,都会确定一个基址寄存器Rn。
         
        (3)指令操作的伪代码
        指令操作的伪代码如下面程序段所示。
         
        If  ConditionPassed{cond}  then
             Memory[address,4]=Rd
         
        (4)指令举例
        LDR/STR指令用于对内存变量的访问、内存缓冲区数据的访问、查表、外围部件的控制操作等等,若使用LDR指令加载数据到PC寄存器,则实现程序跳转功能,这样也就实现了程序散转。
         
        ① 变量访问
         
        NumCount  EQU  0x40003000         ;定义变量NumCount
        LDR  R0,=NumCount               ;使用LDR伪指令装载NumCount的地址到R0
        LDR  R1,[R0]                   ;取出变量值
        ADD  R1,R1,#1                 ;NumCount=NumCount+1
        STR   R1,[R0]                  ;保存变量
         
        ② GPIO设置
         
        GPIO—BASE  EQU   0xe0028000       ;定义GPIO寄存器的基地址
        ……
        LDR    R0,=GPIO—BASE
        LDR    R1,=0x00ffff00            ;将设置值放入寄存器
        STR    R1,[R0,#0x0C]             ;IODIR=0x00ffff00,IOSET的地址为0xE0028004
         
        ③ 程序散转
         
        …
        MOV  r2,r2,LSL #2                ;功能号乘以4,以便查表
        LDR  PC,[PC,r2]                 ;查表取得对应功能子程序地址,并跳转
        NOP
        FUN—TAB  DCD   FUN—SUB0
                  DCD   FUN—SUB1
                  DCD   FUN—SUB2
                    …
         
        5.3.2  字节数据传送指令(LDRB/STRB)

        1.LDRB指令

        (1)指令编码格式
         
        LDRB指令根据<addr_mode>所确定的地址模式将一个8位字节读取到指令中的目标寄存器<Rd>。
        指令的编码格式如图5.5所示。
       

        图5.5  LDRB指令编码格式

         

                               
                                       

                       
                               
                                        注意

                       
                               
                                        LDRB指令加载一个内存地址的8位字节到一个通用寄存器中。寄存器的高位数据补0。

                       
         

        (2)指令的语法格式
         
        LDR{<cond>}B  <Rd>,<addr_mode>
        ① <cond>
        为指令编码中的条件域。它指示LDRB指令在什么条件下执行。当<cond>忽略时,指令为无条件执行(cond=AL(Alway))。
         
        ② <Rd>
        确定使用哪个通用寄存器作为目标寄存器。
         
        ③ <addr_mode>
        它确定了指令编码中的I、P、U、W、Rn和<addr_mode>位。所有的寻址模式中,都会确定一个基址寄存器Rn。
         
        (3)指令操作的伪代码
         
        if  ConditionPassed{cond}  then
            Rd = Memory[address,1]
         
                                                                       
                       
                                                                        注意
                       
                                                                        当PC作为位基地址出现在指令中时,指令中将会使用PC相关地址,使用这种方法可以编写自己的位置无关(position-independ)指令。
                       
         

        2.STRB指令

        (1)指令编码格式
        STRB指令从寄存器中取出指定的8位字节放入寄存器的低8位,并将寄存器的高位补0。
         
        指令的编码格式如图5.6所示。
       

        图5.6  STRB指令编码格式

         
        (2)指令的语法格式
         
        STR{<cond>}B  <Rd>,<addr_mode>
         
        ① <cond>
        为指令编码中的条件域。它指示STRB指令在什么条件下执行。当<cond>忽略时,指令为无条件执行(cond=AL(Alway))。
         
        ② <Rd>
        确定使用哪个通用寄存器作为目标寄存器。
         
                                                                       
                       
                                                                        注意
                       
                                                                        当PC作为目标寄存器<Rd>出现在指令中时,指令的执行结果不可预知。
                       
         
        ③ <addr_mode>
        它确定了指令编码中的I、P、U、W、Rn和<addr_mode>位。所有的寻址模式中,都会确定一个基址寄存器Rn。
         
        (3)指令操作的伪代码
         
        if  ConditionPassed{cond}  then
           Memory[address,1] = Rd[7:0]
         
        5.3.3  半字数据传送指令(LDRH/STRH)

        1.LDRH指令

        (1)指令编码格式
        LDRH指令用于从内存中将一个16位的半字读取到目标寄存器。
        如果指令的内存地址不是半字节对齐的,指令的执行结果不可预知。
         
        指令的编码格式如图5.7所示。
       

        图5.7  LDRH指令的编码格式

         
        (2)指令的语法格式
         
        LDR{<cond>}H  <Rd>,<addr_mode>
         
        ① <cond>
        为指令编码中的条件域。它指示LDRH指令在什么条件下执行。当<cond>忽略时,指令为无条件执行(cond=AL(Alway))。
         
        ② <Rd>
        确定使用哪个通用寄存器作为目标寄存器。
         
                                                                       
                       
                                                                        注意
                       
                                                                        如果PC作为目标寄存器,指令的执行结果不可预知。
                       
         
        ③ <addr_mode>
        它确定了指令编码中的I、P、U、W、Rn和<addr_mode>位。所有的寻址模式中,都会确定一个基址寄存器Rn。
         
        (3)指令操作的伪代码
         
        if  ConditionPassed{cond}  then
            if address[0]==0
                 data=Memory[address,2]
            else  /*address[0]==1*/
                 data=unpredictable
            Rd=data
         
                                                                       
                       
                                                                        注意
                       
                                                                        在包含系统控制协处理器的芯片应用中,如果定义了地址对齐检测,当bit[0]!=0时,将发生地址对齐异常。
                       
         

        2.STRH指令

        (1)指令编码格式
        STRH指令从寄存器中取出指定的16位半字放入寄存器的低16位,并将寄存器的高位补0。
        指令的编码格式如图5.8所示。
         
       

        图5.8  STRH指令的编码格式

         
        (2)指令的语法格式
         
        STR{<cond>}H  <Rd>,<addr_mode>
         
        ① <cond>
        指令编码中的条件域。它指示STRH指令在什么条件下执行。当<cond>忽略时,指令为无条件执行(cond=AL(Alway))。
         
        ② <Rd>
        确定使用哪个通用寄存器作为目标寄存器。
         
                                                                       
                       
                                                                        注意
                       
                                                                        如果PC作为目标寄存器,指令的执行结果不可预知。
                       
         
        ③ <addr_mode>
        它确定了指令编码中的I、P、U、W、Rn和<addr_mode>位。所有的寻址模式中,都会确定一个基址寄存器Rn。
         
        (3)指令操作的伪代码
         
        if  ConditionPassed{cond}  then
            if address[0]==0
                 data=Rd[15:0]
            else  /*address[0]==1*/
                 data=unpredictable
            Memory[address,2]=data
         
        5.3.4  用户模式字数据传送指令(LDRT/STRT)

        1.LDRT指令

        (1)指令编码格式
        LDRT指令用于从内存中将一个32位的字读取到目标寄存器。
        指令的编码格式如图5.9所示。
         
        LDRT指令根据<addr_mode>所确定的地址模式将一个32位字读取到指令中的目标寄存器<Rd>。如果指令中的寻址方式确定的地址不是字对齐的,则读出的数值要进行循环右移。所移位数为寻址方式确定的地址bits[1∶0]的8倍。也就是说处理器将取到的数值作为字的最低位处理。
       

        图5.9  LDRT指令编码格式

         
        当处理器在特权模式下使用此指令时,内存系统将该操作当作一般用户模式下得内存访问指令。
         
                                                                       
                       
                                                                        注意
                       
                                                                        指令的编码格式中,P位指定位“0”,也就是说LDRT指令的寻址方式为固定寻址方式,即后索引编码寻址(post_indexed_addressing_mode)。
                       
         
        (2)指令的语法格式
         
        LDR{<cond>}T  <Rd>,<post_indexed_addressing_mode>
         
        ① <cond>
        为指令编码中的条件域。它指示LDRT指令在什么条件下执行。当<cond>忽略时,指令为无条件执行(cond=AL(Alway))。
         
        ② <Rd>
        确定使用哪个通用寄存器作为目标寄存器。
         
        ③ <post_indexex_address_mode>
        使用后索引地址模式寻址。
         
                                                                       
                       
                                                                        注意
                       
                                                                        后索引地址模式中P=0并且W=0(即bit[21]=0、bit[24]=0)。但此指令P=0并且W=1(即bit[21]=1、bit[24]=0)。但实际的寻址操作是一样的。
                       
         
        (3)指令操作的伪代码
         
        指令操作的伪代码如下面程序段所示。
         
        If  ConditionPassed{cond}  then
            If  address[1:0]==0b00
                  Rd=Memory[address,4]
            Else  if  address[1:0]==0b01
                  Rd=Memory[address,4]  Rotate_Right  8
            Else  if  address[1:0]==0b10
                  Rd=Memory[address,4]  Rotate_Right  16
            Else  address[1:0]==0b11
                  Rd=Memory[address,4]  Rotate_Right  24
         
        2.STRT指令

        (1)指令编码格式
        STRT指令用于将一个32位的字数据写入到指令中指定的内存单元。
        当处理器在特权模式下执行此指令时,内存系统将该操作当作一般用户模式下的内存访问操作。
         
        指令的编码格式如图5.10所示。
       

        图5.10  STR指令编码格式

         
        (2)指令的语法格式
         
        STR{<cond>}T  <Rd>,<post_indexed_addressing_mode>
         
        ① <cond>
        为指令编码中的条件域。它指示STRT指令在什么条件下执行。当<cond>忽略时,指令为无条件执行(cond=AL(Alway))。
         
        ② <Rd>
        确定使用哪个通用寄存器作为目标寄存器。
         
        ③ <post_indexed_address_mode>
        使用后索引地址模式寻址,参见LDRT指令。
         
        (3)指令操作的伪代码
        指令操作的伪代码如下面程序段所示。
         
        If  ConditionPassed{cond}  then
            Memory[address,4]=Rd
         
        5.3.5  用户模式字节数据传送指令(LDRBT/STRBT)

        1.LDRBT指令

        (1)指令编码格式
        LDRBT指令根据<post_indexed_addressing_mode>地址模式将一个8位字节读取到指令中的目标寄存器<Rd>。
         
        当处理器在特权模式下执行此指令时,内存系统将该操作当作一般用户模式下的内存访问操作。
        指令的编码格式如图5.11所示。
         
       

        图5.11  LDRBT指令编码格式

         
                                                                       
                       
                                                                        注意
                       
                                                                        LDRBT指令加载一个内存地址的8位字节到一个通用寄存器中。寄存器的高位数据补0。
                       
         
        (2)指令的语法格式
         
        LDR{<cond>}BT  <Rd>,<post_indexed_addressing_mode>
         
        ① <cond>
        为指令编码中的条件域。它指示LDRBT指令在什么条件下执行。当<cond>忽略时,指令为无条件执行(cond=AL(Alway))
        。
        ② <Rd>
        确定使用哪个通用寄存器作为目标寄存器。
         
        ③ <post_indexed_addressing_mode>
        使用后索引地址模式寻址,参见LDRT指令。
         
        (3)指令操作的伪代码
        指令操作的伪代码如下面程序段所示。
         
        If  ConditionPassed{cond}  then
            Rd=Memory[address,1]
         
        2.STRBT指令

        (1)指令编码格式
        STRBT指令用于将一个8位的字节数据写入到指令中指定的内存单元。
        当处理器在特权模式下执行此指令时,内存系统将该操作当作一般用户模式下的内存访问操作。
         
        指令的编码格式如图5.12所示。
       

        图5.12  STRBT指令编码格式

         
        (2)指令的语法格式
         
        STR{<cond>}BT  <Rd>,<addr_mode>
         
        ① <cond>
        为指令编码中的条件域。它指示LDRBT指令在什么条件下执行。当<cond>忽略时,指令为无条件执行(cond=AL(Alway))。
         
        ② <Rd>
        确定使用哪个通用寄存器作为目标寄存器。
         
        ③ <post_indexed_addressing_mode>
        使用后索引地址模式寻址,参见LDRT指令。
         
        (3)指令操作的伪代码
        指令操作的伪代码如下面程序段所示。
         
        If  ConditionPassed{cond}  then
             Memory[address,1]=Rd[7:0]
         
        5.3.6  有符号的字节/半字数据传送指令(LDRBT/STRBT)

        1.LDRSB指令

        (1)指令编码格式
        LDRSB指令根据<addr_mode>所确定的地址模式将一个8位字节读取到指令中的目标寄存器<Rd>。
         
                                                                       
                       
                                                                        注意
                       
                                                                        LDRSB与LDRB指令的不同之处在于它将寄存器的高24位设置成该字节数据的符号位的值(即将该8位字节数据进行符号位扩展,生成32位字数据)。
                       
         
        指令的编码格式如图5.13所示。
       

        图5.13  LDRSB指令编码格式

         
        (2)指令的语法格式
         
        LDR{<cond>}SB  <Rd>,<addr_mode>
         
        ① <cond>
        为指令编码中的条件域。它指示LDRSB指令在什么条件下执行。当<cond>忽略时,指令为无条件执行(cond=AL(Alway))。
         
        ② <Rd>
        确定使用哪个通用寄存器作为目标寄存器。
         
        ③ <addr_mode>
         
        它确定了指令编码中的I、P、U、W、Rn和<addr_mode>位。所有的寻址模式中,都会确定一个基址寄存器Rn。
         
        (3)指令操作的伪代码
         
        If  ConditionPassed{cond}  then
            data=Memory[address,1]
        Rd=SignExtend{data}
         
        2.LDRSH指令

        (1)指令编码格式
        LDRSH指令根据<addr_mode>所确定的地址模式将一个16位半字读取到指令中的目标寄存器<Rd>。
         
                                                                       
                       
                                                                        注意
                       
                                                                        LDRSH与LDRH指令的不同之处在于它将寄存器的高16位设置成该字节数据的符号位的值(即将该16位字节数据进行符号位扩展,生成32位字数据)。
                       
         
        指令的编码格式如图5.14所示。
       

        图5.14  LDRSH指令编码格式

         
        (2)指令的语法格式
         
        LDR{<cond>}SH  <Rd>,<addr_mode>
         
        ① <cond>
        为指令编码中的条件域。它指示LDRSH指令在什么条件下执行。当<cond>忽略时,指令为无条件执行(cond=AL(Alway))。
         
        ② <Rd>
        确定使用哪个通用寄存器作为目标寄存器。
         
        ③ <addr_mode>
        它确定了指令编码中的I、P、U、W、Rn和<addr_mode>位。所有的寻址模式中,都会确定一个基址寄存器Rn。
         
        (3)指令操作的伪代码
         
        If  ConditionPassed{cond}  then
            if  address[0]==0
                data=Memory[address,2]
           else  /*address[0] ==1*/
                data=UNPREDICTABLE
           Rd=SignExtend{data}
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
收藏收藏 分享分享 支持支持 反对反对
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|文字版|手机版|DIY编程器网 ( 桂ICP备14005565号-1 )

GMT+8, 2024-12-28 05:23 , 耗时 0.098371 秒, 21 个查询请求 , Gzip 开启.

各位嘉宾言论仅代表个人观点,非属DIY编程器网立场。

桂公网安备 45031202000115号

DIY编程器群(超员):41210778 DIY编程器

DIY编程器群1(满员):3044634 DIY编程器1

diy编程器群2:551025008 diy编程器群2

QQ:28000622;Email:libyoufer@sina.com

本站由桂林市临桂区技兴电子商务经营部独家赞助。旨在技术交流,请自觉遵守国家法律法规,一旦发现将做封号删号处理。

快速回复 返回顶部 返回列表