Chinaunix首页 | 论坛 | 博客
  • 博客访问: 180156
  • 博文数量: 31
  • 博客积分: 471
  • 博客等级: 下士
  • 技术积分: 240
  • 用 户 组: 普通用户
  • 注册时间: 2010-09-07 12:53
文章分类

全部博文(31)

文章存档

2015年(1)

2013年(1)

2012年(1)

2011年(28)

分类: LINUX

2011-07-19 15:15:49

    今天听了关于ARM汇编指令的课,其中讲到了关于ARM处理器中的“8位位图,课上听的似懂非懂,课下经过看书,又询问了老师,终于对此问题有了更加清晰的理解,下面我就把这个问题总结一下,也是对牛建伟老师今天讲课内容的一个总结吧。

一条典型的ARM指令语法格式分为如下几个部分:
   {} {S}    ,{,
}
  
其中,<>内的项是必须的,{}内的项是可选的,如是指令助记符,是必须的,而{}为指令执行条件,是可选的,如果不写则使用默认条件AL(无条件执行)
   opcode     
指令助记符,如LDRSTR
   cond       
执行条件,如EQNE
   S           
是否影响CPSR 寄存器的值,书写时影响CPSR,否则不影响
   Rd         
目标寄存器
   Rn         
第一个操作数的寄存器
  
operand2    第二个操作数

 

  其指令编码格式如下:

 31-28

 27-25

 24-21

 20  

 19-16

 15-12

 11-0 12位)

 cond

 001

 opcode

 S

 Rn

 Rd

operand2

 

对其中的operand2的常数表达式有这样的规定:该常数必须对应8位位图,即常熟是由一个8位的常熟循环右移偶数位得到的。这句话的意思是说,当用12位第二操作数来表示一个32位立即数时,采用的是将8位数通过移位的方式来实现的,其中12位第二操作数的低八位存放被移位的基本数(取值范围为0255),而高四位存放的是循环右移的位数,因为位四位二进制数,所以取值范围位为015,而对应的移位位数则为030位,也就是说若移位数为0,则表示基本数不变,若移位数位1,则表示将基本数在32位数字空间中循环右移2位,若移位数位5,则表示将基本数在32位数字空间中循环右移10位,若移位数位10,则表示将基本数在32位数字空间中循环右移20位,依次类推。举例表示:
     AND R1,R2,#0xff
    
当处理器处理这条指令的第二操作数0xff时,因为0xff8位二进制数,所以处理器就将其直接放进8基本数中,而4移位数则为0.
     AND R1,R2,#0x104
    
当处理器处理这条指令的第二操作数0x104时,因为此时0x104已经超过了8位二进制数,所以处理器就要将其改造一下,我们先把0x104转换成二进制0000 0000 0000 0000 0000 0001 0000 0100,我们可以看到,这个数是0000 0000 0000 0000 0000 0000 0100 0001通过循环右移30位得到的,因此改造后的结果是8基本数中存放0100 0001,而移位数为15

     AND R1,R2,#0xff000000
    
当处理器处理这条指令的第二操作数0xff000000时,处理器同样要对其改造,我们先把0xff000000转换成二进制1111 1111 0000 0000 0000 0000 0000 0000,我们可以看到,这个数是0000 0000 0000 0000 0000 0000 1111 1111通过循环右移8位得到的,因此改造后的结果是8基本数中存放1111 1111,而移位数为4
     
我想,通过以上的三个例子,就应该明白了8位位图的原理了。但是,有些数并不符合8位位图的原理,这样的数在进行程序编译时,系统将会提示出错,下面再举几个违反8位位图的例子:比如0x101,转换成二进制后位0000 0000 0000 0000 0000 0001 0000 0001,像这个数,无论向右循环几位,都无法将两个1同时放到低8位中,因此不符合8位位图;再比如0x102,转换成二进制后位0000 0000 0000 0000 0000 0001 0000 0010,如果将两个1同时放到低8位中,即转换成二进制后为0000 0000 0000 0000 0000 0000 1000 0001,需要将此二进制数向右移31位,这也不符合循环右移偶数位的条件,因此0x012也不符合8位位图;再举一个0xff1,转换成二进制后将会有91,不可能将其同时放入8位中,因此当然也不符合啦。
     
通过正反例的比较,可以总结如下:第一,判断一个数是否符合8位位图的原则,首先看这个数转换成二进制后1的个数是否不超过8个,如果不超过8个,再看这n1n<=8)是否能同时放到8个二进制位中,如果可以放进去,再看这八个二进制位是否可以循环右移偶数位得到起初被判断的那个数值,如果可以,则此数值即为符合8位位图原理,否则,不符合。第二,用12位的编码来表示一个任意的32位数是不可能的,只能通过循环右移八位二进制数偶数位来得到一部分32位数,其余的无法表示的32位数,只有通过其它途径获得了,比如0xffffff00,可以通过0x000000ff按位取反得到,因此在以后的编程中,一定要注意用到的第二操作数是否符合8位位图。

 


    
阅读(1704) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~