ARM汇编语言编码

(1)数据处理指令的编码格式

cond:   指令的条件码
I:           用于区别operand2是立即数(I=1)还是寄存器(I=0)
opcode:指令操作码
S:          操作是否影响cpsr,S=0不影响,S=1影响
Rn:        包含第一个操作数的寄存器编码
Rd:        目标寄存器编码
operand2:第二操作数,有三种方式:立即数方式,寄存器方式,寄存器移位方式。每种方式下的编码格式不一样    
    
立即数方式:

如图所示,在ARM的指令系统中,每个32位的立即数被编码成一个12位的数。这个32位的数是由一个8位的常数循环右移偶数位得到。其中循环右移的位数由一个4位二进制数的两倍表示,如图,8位常数加4位循环右移位数构成了一个12位数。

设立即数为immediate,8位常数便为immed8,4位的循环右移值为rotate,则:
immediate = immed8 循环右移 rotate*2
所以并不是每一个32位的常数都是合法的立即数,只有能通过上面的构造方法得到的才是合法的立即数。但是若当把一个数按位取反后,则得到一个合法的立即数时,这个数为有效数。此时将mov指令换成mvn指令执行

ARM汇编编译器按照下面的规则来生成立即数的编码
  • 当立即数在0—0xFF范围时,令immediate = immed8 ,rotate = 0;
  • 其他情况下,汇编编译器选择rotate数值最小的编码方式
例:MOV   R0,#0xFC0
         ADD   R0,R1,#0x66

 寄存器方式:

Rm:寄存器编码

例:MOV  R3,R2(Rn)
         ADD   R0,R1,R2(Rm)


寄存器移位方式:

Rm:寄存器编码,
r:为1时,说明移位指令后面使用的是寄存器,为0时,说明移位指令后面使用的是立即数
shift:移位方式,00:LSL    01: LSR  10:ASR  11:ROR
shift_imm:要移动的位数大小。当r为1时,存放移动位数的寄存器的编码,当r为0时,为移位所使用的立即数大小。注:图中为立即数的方式,当为寄存器时,shift的范围是第8位—第9位

例: MOV  R0,R0(Rm),LSL  #6(shift_imm)
          MOV  R0,R0(Rm),LSL  R1(shift_imm)
           ADD   R0,R1(Rn),R3(Rm),LSL  #6(shift_imm)
          ADD   R0,R1(Rn),R3(Rm),LSL  R6(shift_imm)


(2)Load/Store指令编码

cond:   指令的条件码
I:           用于区别operand2是立即数(I=1)还是寄存器(I=0)
P:            这个位基本在非批量中一直为1.具体内容不清楚
U:            U=1时,要访问的地址为基址寄存器加上偏移量Address。U=0时, 要访问的地址为基址寄存器减去偏移量Address.
B:            当B=1时,指令访问的是无符号的字节数据;当B=0时,指令访问的是字数据
W:           当W=1时,将更新基址寄存器的内容(针对事先更新方式)
L:            当L=1时,指令执行Load操作。当L=0时,指令执行Store操作
Rn:       基址寄存器
Rd:       目标寄存器
Address:地址偏移量。有三种方式:立即数方式,寄存器方式,寄存器移位方式。每种方式下的编码格式不一样    
注:26,27位用来区别是批量Load/Store还是非批量的。当为10时,为批量的。为00时,非批量的

立即数方式:
 
offset12: 地址偏移量

LDR  R1,[R0,#6]
        LDR  R1,[R0,# -6]

寄存器方式:

Rm:存放偏移量寄存器

例:LDR R0,[R1,R2(Rm)]
         LDR R0,[R1,-R2(Rm)]

寄存器移位方式:

Rm:存放偏移量寄存器
shift:移位方式,00:LSL    01: LSR  10:ASR  11:ROR
shift_imm:要移动的位数大小

例:LDR  R0,[R1,R2(Rm),LSL  #6]
         LDR  R0,[R1,-R2(Rm),LSL  #6]


(3)批量Load/Store指令编码

cond:   指令的条件码      
P:         P位表示基址寄存器Rn所指向的内存单元是否包含在指令所使用的内存块内。P=0时,不包含。P=1时,包含    
U:         U=1时,基址寄存器所指向的内存单元向地址增加的方向变化。U=0时,基址寄存器所指向的内存单元向地址减小的方向变化。
S:          S对于不同指令有不同的含义。当LDMS指令的寄存器列表中包含PC寄存器时,S=1表示指令同时将SPSR的数值复制到CPSR中。对于寄存器列表中不包含PC寄存器的LDMS指令以及STMS指令,S=1表示当处理器模式为特权模式时,指令操作的寄存器时用户模式下的寄存器,而不是当前特权模式下的寄存器。
W:           表示指令执行后,基址寄存器Rn的值是否更新。当W=1时,指令执行后,基址寄存器的值会更新。
L:            当L=1时,指令执行Load操作。当L=0时,指令执行Store操作
Rn:       基址寄存器
reglist:
注:26,27位用来区别是批量Load/Store还是非批量的。当为10时,为批量的。为00时,非批量的

指令中寄存器和内存单元的对应关系满足这样的规则,即编号低的寄存器对应于内存中低地址单元,编号高的寄存器对应于内存中高地址单元。
地址变化方式有四种:
IA            事后递增方式
IB            事先递增方式
DA          事后递减方式
DB          事先递减方式

栈指针通常可以指向不同的位置。栈指针指向栈顶元素时称为FULL栈,栈指针指向于栈顶元素相邻的一个可用数据单元时称为EMPTY栈。
数据栈的增长方向也可以不同。当数据栈向内存地址减小的方向增长时,称为DESCENDING栈;当数据栈向内存地址增加的方向增长时,称为ASCENDING栈
综合这里两种特点,可以有以下四种数据栈:
FD       满堆栈递减
ED       空堆栈递减
FA       满堆栈递增
EA       空堆栈递增

不同数据栈对应的批量Load/Store指令的寻址方式如下表所示


(4)跳转指令

cond:   指令的条件码      
L:           决定是否保存返回地址。当L=1时,当前PC寄存器的值会被保存到LR寄存器中
signed_24: 为指令跳转的目标地址。这个地址的计算方法是:将指令中的24位带符号的补码立即扩展到32位(扩展其符号位);并将此32位数左移两位,将得到的值与当前PC值相加,即得到跳转地址。

注:
  • 因为24位数中有一位是符号位,所以可用为23位,跳转范围为8M。但是将其左移两位后,也就是乘以四,所以跳转范围变为32M。
  • BX与BLX的编码格式于此有些不一样(详细看《ARM体系结构与编程》)
  • 跳转指令为相对跳转,跳转时,是以PC为基址寄存器,然后将目标地址与PC的差值作为偏移量,将偏移量加到PC上,最后跳转


































你可能感兴趣的:(ARM,arm处理器,微处理器)