ARM 汇编指令学习:[1]ARM指令寻址方式

ARM 汇编指令学习:[1]ARM指令寻址方式


一、数据处理指令的操作数的寻址方式

{}{S} ,,

通常具有下面3种格式:

1、 立即数方式

  • #

    其中,#=immed_8循环右移(2*rotate_imm)。

    使用说明

    这里需要注意关于立即数的合法性以立即数编码的规则。

    示例

    MOV R0, #0xFC0

2、 寄存器方式

  • 其中,指定操作数所在的寄存器。

    使用说明

    当R15(PC)用作第一个源操作数Rn或者第二操作数Rm时,操作数即为当前指令地址加常数8。

    示例

    MOV R0, R1

3、 寄存器位移方式

  • , LSL #

    其中:

     为进行逻辑左移操作的寄存器。

    LSL 逻辑左移操作。

    # 逻辑左移位数,范围0~31。

    使用说明

    当R15(PC)用作第一个源操作数Rn或者第二操作数Rm时,操作数即为当前指令地址加常数8。

    示例

    MOV R0, R0, LSL #n  ;R0=R0<

  • , LSL 

    其中:

     为进行逻辑左移操作的寄存器。

    LSL 逻辑左移操作。

     包含逻辑左移位数的寄存器。

    使用说明

    当R15(PC)用作Rn、Rm、Rd及Rs时,会产生不可预知效果(跑飞)。

    示例

    MOV R0, R0, LSL R2  ;R0=R0<

  • , LSR #

    其中:

     为进行逻辑右移操作的寄存器。

    LSR 逻辑右移操作。

    # 逻辑右移位数,范围1~32,shift_imm=0时位移数为32。

    使用说明

    当R15(PC)用作第一个源操作数Rn或者第二操作数Rm时,操作数即为当前指令地址加常数8。

    示例

    MOV R0, R0, LSR #n  ;R0=R0>>n

  • , LSR 

    其中:

     为进行逻辑右移操作的寄存器。

    LSR 逻辑右移操作。

     包含逻辑右移位数的寄存器。

    使用说明

    当R15(PC)用作Rn、Rm、Rd及Rs时,会产生不可预知效果(跑飞)。

    示例

    MOV R0, R0, LSR R2  ;R0=R0>>R2

  • , ASR #

    其中:

     为进行算术右移操作的寄存器。

    ASR 算术右移操作。

    # 算术右移位数,范围1~32,shift_imm=0时位移数为32。

    使用说明

    当R15(PC)用作第一个源操作数Rn或者第二操作数Rm时,操作数即为当前指令地址加常数8。

    ASR与LSR的区别是:各位依次右移指定位数,在左侧用原符号位补齐,即保持符号位不变。

    示例

    MOV R0, R0, ASR #n

  • , ASR 

    其中:

     为进行算术右移操作的寄存器。

    ASR 算术右移操作。

     包含算术右移位数的寄存器。

    使用说明

    当R15(PC)用作Rn、Rm、Rd及Rs时,会产生不可预知效果(跑飞)。

    示例

    MOV R0, R0, ASR R2

  • , ROR #

    其中:

     为进行循环右移操作的寄存器。

    ROR 循环右移操作。

    # 循环右移位数,范围0~31,shift_imm=0时将执行RRX操作。

    使用说明

    当R15(PC)用作第一个源操作数Rn或者第二操作数Rm时,操作数即为当前指令地址加常数8。

    示例

    MOV R0, R0, ROR #n

  • , ROR 

    其中:

     为进行循环右移操作的寄存器。

    ROR 循环右移操作。

     包含循环右移位数的寄存器。

    使用说明

    当R15(PC)用作Rn、Rm、Rd及Rs时,会产生不可预知效果(跑飞)。

    示例

    MOV R0, R0, ROR R1

  • , RRX

    其中:

     为进行移位操作的寄存器。

    RRX 扩展的循环右移操作。

    使用说明

    当R15(PC)用作第一个源操作数Rn或者第二操作数Rm时,操作数即为当前指令地址加常数8。

    扩展的循环右移与循环右移的区别是:首位补的是进位。(循环右移补的是0)

    示例

    MOV R0, R0, RRX

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

1、 立即数方式

  • [, #+/-]
  • [, #+/-]!
  • [], #+/-

2、 寄存器方式

  • [, +/-]
  • [, +/-]!
  • [], +/-

3、 寄存器及一个移位常数方式

  • [, +/-,  #]
  • [, +/-,  #]!
  • [], +/-,  #

每组第2个为事先访问,第3个为事后访问。


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

操作数为半字(无符号数或者带符号数)数据的Load/Store指令;操作数为带符号的字节数据的Load指令;双字的Load/Store指令。

这类指令的语法格式为:

    LDR|STR{}H|SH|SB|B , 

其中,是指令中的内存单元的寻址方式,具体有以下6种形式:

  • [, #+/-]
  • [, #+/-]!
  • [], #+/-
  • [, +/-]
  • [, +/-]!
  • [], +/-

  • LDRH 半字无符号Load,高16位填充0
  • LDRSH 半字带符号Load,高16位填充该半字的符号位
  • LDRSB 字节带符号Load,高24位填充该字节的符号位
  • LDRB 字节无符号Load,高24位填充0

STR与此上类似。


四、批量Load/Store指令的寻址方式

一条批量Load/Store指令可以实现在一组寄存器和一块连续的内存单元之间传输数据。

这类指令的语法格式为:

    LDM|STM{} {!}, {^}

其中,表示地址的变化方式,具体有以下4种形式:

  • IA(Increment After) 事后递增方式
  • IB(Increment Before) 事先递增方式
  • DA(Decrement After) 事后递减方式
  • DB(Decrement Before) 事先递减方式

    示例
    LDMIA R0, {R5-R8} ;  将内存单元(R0)到(R0+12)4个字的数据读取到R5~R8的4个寄存器中
    LDMIB R0, {R5-R8} ;  将内存单元(R0+4)到(R0+16)4个字的数据读取到R5~R8的4个寄存器中
    LDMDA R0, {R5-R8} ;  将内存单元(R0-12)到(R0)4个字的数据读取到R5~R8的4个寄存器中
    LDMDB R0, {R5-R8} ;  将内存单元(R0-16)到(R0-4)4个字的数据读取到R5~R8的4个寄存器中

对应于栈操作的寻址方式

  • FD(Full Descending)
  • ED(Empty Descending)
  • FA(Full Ascending)
  • EB(Empty Ascending)

根据栈指针的指向:

  1. 栈指针指向栈顶元素(即最后一个入栈的数据元素)时称为FULL栈
  2. 栈指针指向与栈顶元素相邻的一个可用数据单元时称为EMPTY栈

根据数据栈的增长方向:

  1. 当数据栈向内存地址减少的方向增长时,称为DESCENDING栈
  2. 当数据栈向内存地址增加的方向增长时,称为ASCENDING栈

五、协处理器Load/Store指令的寻址方式

一条协处理器Load/Store指令可以实现在ARM处理器和协处理器之间传输数据。

这类指令的语法格式为:

    {}{L} , , 

其中,表示地址的变化方式,具体有以下4种形式:

  • [, #+/-*4]
  • [, #+/-*4]!
  • [], #+/-*4
  • [], 

参考自《ARM体系架构与编程》杜春雷


  • 我的个人主页:http://www.techping.cn/
  • 我的个人站点博客:http://www.techping.cn/blog/wordpress/
  • 我的CSDN博客:http://blog.csdn.net/techping
  • 我的:http://www.jianshu.com/users/b2a36e431d5e/timeline
  • 我的GitHub:https://github.com/techping
    欢迎相互follow~

你可能感兴趣的:(ARM 汇编指令学习:[1]ARM指令寻址方式)