大多数数据处理指令有一个灵活的第二操作数。
主要有3种形式:
1 立即数,#imme
2 寄存器,Rm
3 寄存器移位,Rm, shift
移位方式有:算术右移,逻辑左移,逻辑右移,循环右移,扩展循环右移1位。
移位的数位可以是数字,也可以寄存器指定,寄存器的话,只使用least significant byte。
ASR n
LSL n
LSR n
ROR n
RRX
ASR Rs
LSL Rs
LSR Rs
ROR Rs
共9种。
算术右移ASR arithmetic shift right
算术右移,高位空出来的位全部填充原来的最高位。算术右移等价于有符号数除2的移位次方,如下述例子证明:
1 2 3 4 5 6 7 8 9 10 11 | #include <stdio.h> void main() { int a = 0x80f00000; int b = a >> 8; int c = a / (1 << 8); printf ( "0x%08x(%d) arithmetic shift 8 is: 0x%08x(%d)\n" , a, a, b, b); printf ( "c: %d\n" , c); } |
编译后,执行结果:
1 2 3 4 | herbert@herbert-pc: /work/code/arithmetic_shift $ cc -m32 test .c herbert@herbert-pc: /work/code/arithmetic_shift $ . /a .out 0x80f00000(-2131755008) arithmetic shift 8 is: 0xff80f000(-8327168) c: -8327168 |
逻辑移位 logical shift,大家都懂的,空出来的位全部填充0。
循环右移 ROR rotate right
右移后,被挤出的位填充到高位。
扩展循环右移1位,RRX
右移1位,高位用CPSR的carry标志位填充,如果指令使用了S后缀,则被移出的位,填充到carry位。
the carry flag
在下述指令中,最后一个被移出的位更新到carry标志位。
MOV, MVN, AND, ORR, EOR, BIC,在设置s后缀时。
TEQ, TST
指令替换
如果立即数不能表示,汇编器会尝试使用指令对的另一个指令,如MOV可能改为使用MVN。