Chinaunix首页 | 论坛 | 博客
  • 博客访问: 21025
  • 博文数量: 10
  • 博客积分: 400
  • 博客等级: 下士
  • 技术积分: 110
  • 用 户 组: 普通用户
  • 注册时间: 2009-09-15 10:14
文章分类

全部博文(10)

文章存档

2010年(2)

2009年(8)

我的朋友

分类: 嵌入式

2009-09-17 15:06:59

    这几天忙着玩裸机,其实是为了把汇编搞熟悉了.呵呵!闲话不说,开始:
 
早上一来写了这样几语句
 
MOV R0,#20000 ;0x4E20 - 100111010000000
 
Error   : A1170E: Immediate 0x00004E20 out of range for this operation
mini2440Init.S line 184  
  184 00000198    MOV  R0,#20000
1 Error, 0 Warnings
 
看英文的解释意思是立即数超出范围
 
MOV R0,#20096 ;0x4E80 - 100111010000000
 
Error   : A1170E: Immediate 0x00004E80 out of range for this operation
mini2440Init.S line 184  
  184 00000198    MOV  R0,#20096
1 Error, 0 Warnings
 
MOV R0,#26368 ;0x6700 - 110011100000000
矛盾出现了,这个居然编译通过了?
   不明白看资料上怎么说:
An immdediate operand value is formed by rotating an 8-bit constant (in a 32-bit word) by an even number of bits (0,2,4,8,26,28,30). Therefore, each instruction contains an 8-bit constant and a 4-bit rotate to be applied to that constant.
Some valid constants are:
0xFF, 0x104, 0xFF0, 0xFF00, 0xFF000, 0xFF000000, 0xF000000F
Some invalid constants are:
0x101, 0x102, 0xFF1, 0xFF04, 0xFF003, 0xFFFFFFFF, 0xF000001F
 
在A5-6页中有这样一段话
Specifies the immediate constant wanted. It is encoded in the instruction as an 8-bit immediate (immed_8) and a 4-bit immediate (rotate_imm), so that is equal to the result of rotating immed_8 right by (2*rotate_imm) bits.
shifter_operand = immed_8 Rotate_Right (rotate_imm * 2)
以及
Some values of have more than one possible encoding. When more than one encoding is available, an assembler needs to choose the correct one to use. For more precise control of the encoding, the instruction fields can be specified directly by using the syntax: #,
 
你就能得到这样一个公式:
shifter_operand = immed_8 Rotate_Right (rotate_imm * 2)
 
不难理解20000、20096为什么会出现错误了,因为按照算法根本得不到rotate_imm,实际上immed_8也是无法生成的。
 
   一个立即数是否合法,得把他先转换成二进制,看最高位的‘1’和最低位的‘1’之间的距离在不在8位的范围,如果超过了8位,即为不合法。如果等于8位,那这个立即数也未必一定是合法的。还得看最低位的‘1’后面还跟着的‘0’的个数,如果是偶数个则这个立即数合法的。否则,不是合法的。
   注意:前后也算,看下面的问题。应该就能明白:
  

Q:请教:MOV中的8位图立即数,是怎么一回事 0xF0000001是怎么来的

A:是循环右移,就是一个0—255 之间的数左移或右移偶数位的来的,也就是这个数除以4一直除, 直到在0-255的范围内它是整数就说明是可以的!

A:8位数(0-255)循环左移或循环右移偶数位得到的,F0000001既是0x1F循环右移4位,符合规范,所以是正确的。这样做是因为指令长度的限制,不可能把32位立即数放在32位的指令中。移位偶数也是这个原因。可以看一看arm体系结构(ADS自带的英文文档)的相关部分。

好了!相信大家看了这个也应该明白了立即数的合法性了!呵呵
 
阅读(3205) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2010-03-19 20:39:44

精辟