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

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


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

<opcode>{<cond>}{S} <Rd>,<Rn>,<shifter_operand>

<shifter_operand>通常具有下面3种格式:

1、 立即数方式

  • #<immediate>

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

    使用说明

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

    示例

    MOV R0, #0xFC0

2、 寄存器方式

  • <Rm>

    其中,<Rm>指定操作数所在的寄存器。

    使用说明

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

    示例

    MOV R0, R1

3、 寄存器位移方式

  • <Rm>, LSL #<shift_imm>

    其中:

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

    LSL 逻辑左移操作。

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

    使用说明

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

    示例

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

  • <Rm>, LSL <Rs>

    其中:

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

    LSL 逻辑左移操作。

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

    使用说明

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

    示例

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

  • <Rm>, LSR #<shift_imm>

    其中:

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

    LSR 逻辑右移操作。

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

    使用说明

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

    示例

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

  • <Rm>, LSR <Rs>

    其中:

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

    LSR 逻辑右移操作。

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

    使用说明

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

    示例

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

  • <Rm>, ASR #<shift_imm>

    其中:

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

    ASR 算术右移操作。

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

    使用说明

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

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

    示例

    MOV R0, R0, ASR #n

  • <Rm>, ASR <Rs>

    其中:

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

    ASR 算术右移操作。

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

    使用说明

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

    示例

    MOV R0, R0, ASR R2

  • <Rm>, ROR #<shift_imm>

    其中:

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

    ROR 循环右移操作。

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

    使用说明

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

    示例

    MOV R0, R0, ROR #n

  • <Rm>, ROR <Rs>

    其中:

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

    ROR 循环右移操作。

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

    使用说明

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

    示例

    MOV R0, R0, ROR R1

  • <Rm>, RRX

    其中:

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

    RRX 扩展的循环右移操作。

    使用说明

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

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

    示例

    MOV R0, R0, RRX

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

1、 立即数方式

  • [<Rn>, #+/-<offset_12>]
  • [<Rn>, #+/-<offset_12>]!
  • [<Rn>], #+/-<offset_12>

2、 寄存器方式

  • [<Rn>, +/-<Rm>]
  • [<Rn>, +/-<Rm>]!
  • [<Rn>], +/-<Rm>

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

  • [<Rn>, +/-<Rm>, <shift> #<shift_imm>]
  • [<Rn>, +/-<Rm>, <shift> #<shift_imm>]!
  • [<Rn>], +/-<Rm>, <shift> #<shift_imm>

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


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

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

这类指令的语法格式为:

    LDR|STR{<cond>}H|SH|SB|B <Rd>, <addressing_mode>

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

  • [<Rn>, #+/-<offset_8>]
  • [<Rn>, #+/-<offset_8>]!
  • [<Rn>], #+/-<offset_8>
  • [<Rn>, +/-<Rm>]
  • [<Rn>, +/-<Rm>]!
  • [<Rn>], +/-<Rm>

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

STR与此上类似。


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

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

这类指令的语法格式为:

    LDM|STM{<cond>}<addressing_mode> <Rn>{!}, <registers>{^}

其中,<addressing_mode>表示地址的变化方式,具体有以下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处理器和协处理器之间传输数据。

这类指令的语法格式为:

    <opcode>{<cond>}{L} <coproc>, <CRd>, <addressing_mode>

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

  • [<Rn>, #+/-<offset_8>*4]
  • [<Rn>, #+/-<offset_8>*4]!
  • [<Rn>], #+/-<offset_8>*4
  • [<Rn>], <option>

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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值