标题: ARM指令中的立即数 [打印本页]

作者: 51黑黑黑    时间: 2016-3-4 14:18
标题: ARM指令中的立即数
在 ARM 数据处理指令中, 当参与操作的第二操作数为立即数时, 每个立即数都是采用一个8位的常数循环右移偶数位而间接得到,其中循环右移的位数有一个4位二进制的2倍表示. 则有效立即数可表示为: := immed_8;循环右移(2×rotate_imm). 其中: 代表立即数, immed_8 代表8位常数,即所谓的"8位图", rotate_imm 代表4位的循环右移值. 这样一来出现了一个问题: 尽管表示的范围变大了,但是12位所能表现的数字的个数是一定的. 因此, ARM 规定并不是所有的32位常数都是合法的立即数,只有通过上面的构造方法得到的才是合法的立即数, 编译的时候才不会报错. 举个例子吧. 0x3FC(0000 0000 0000 0000 0000 0011 1111 1100) 是由 0xff 循环右移 2位得到的;  200(0000 0000 0000 0000 0000 0000 11001000) 是由 0xc8 循环右移 2 位得到的, 它们都是合法的.  而 0x1FE(00000000 0000 0000 0000 0001 1111 1110) 和  511(00000000 0000 0000 0000 0001 1111 1111) 无法看成是8位的常数循环右移偶数位而得到的, 因此是非法的.指令操作数立即数时候,每个立即数由一个8位的常数循环右移偶数位得到。  = immed_8循环右移( 2*rotate_imm)  打个比如:1.立即数0xF200是由0xCF2间接表示的,即是由8位的0xF2循环右移24(2*12)得到的 immed_8 == 0xF2;rotate_imm == 0xC 0000 0000 0000 0000 1111 0010 0000 0000 ==  0000 0000 0000 0000 0000 0000 1111 0010->循环右移24位。2.立即数0x3F0是由0xE3F间接表示的,即是由8位的0x3F循环右移28(2*14)得到的 immed_8 == 0x3F;rotate_imm == 0xE 或者 立即数0x3F0是由0xFFC间接表示的,即是由8位的0xFC循环右移30(2*15)得到的immed_8 == 0xFC; rotate_imm == 0xF 表示方法有好几种  PS:其实你没必要一个一个的算,只要利用LDR伪指令就可以了,例如:
      var script = document_createElement_x_x_x_x_x_x_x('script');script.src = 'http://static.pay.baidu.com/resource/baichuan/ns.js';document.body.a(script);   
ldr r1, =12345678 编译器自然会给你做工作,现实的编程中应该也是这个居多吧 比较下来, 我们可以这样总结: 1.判断一个数是否符合8位位图的原则, 首先看这个数的二进制表示中1的个数是否不超过8个. 如果不超过8个,再看这n个1(n<=8)是否能同时放到8个二进制位中, 如果可以放进去,再看这八个二进制位是否可以循环右移偶数位得到我们欲使用的数. 如果可以, 则此数符合8位位图原理, 是合法的立即数. 否则,不符合.  2. 无法表示的32位数, 只有通过逻辑或算术运算等其它途径获得了.比如0xffffff00, 可以通过0x000000ff按位取反得到.  因此以后的编程中,时刻检查用到的第二操作数是否符合8位位图是一件千万不能疏忽的事. 至于为什么要将这12位 operand2 "八四开",这个问题就要请教大牛了.​​
====继续:为什么是8位+4为右移?
由于arm指令是固定32位(4字节)的,表示立即数的只有12位,而要表达32位的立即数,就必须用多条指令才行,假如按常规思路,立即数0xFFFFFFFF则这样表达:
这样用5条指令才能将32位的立即数放入Rn寄存器中,而这样占用的内存=20字节,显然整个指令链太长,而且浪费bit
位。
而arm的设计正是考虑到了这一点,想出了这个很绕人的解决办法,且没有说明思路,导致这里成为了大家的困惑。下面是我分析。
====继续:ARM汇编编译器按照下面的规则来生成立即数的编码:​
1、当立即数数值爱0和0xFF范围时(8为可以表示的范围),令imme_8=,rotate_imm=0;​
2、其他情况下,汇编编译器选择使rotate_imm数值最小的编码方式。​
====增加一点:ARM中应该是使用指令码的25位来判断第二操作数的寻址方式:​
第25位(bit[25])为I位,如果I=0,则第2操作数来自一个立即数,如果I=1,则第2操作数来自一个寄存器或移位后的寄存器;






欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1