首页 嵌入式系统概论

嵌入式系统概论

举报
开通vip

嵌入式系统概论ARM的字对齐问题总结 一、啥是字对齐?为啥要字对齐?       现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问都可以从任何地址开始,但实际情况是在访问特定类型变量的时候经常在特定的内存地址访问,这就是对齐。 字节对齐的原因大致是如下两条: 1、平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。 2、性能原因:数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内...

嵌入式系统概论
ARM的字对齐问题 总结 初级经济法重点总结下载党员个人总结TXt高中句型全总结.doc高中句型全总结.doc理论力学知识点总结pdf 一、啥是字对齐?为啥要字对齐?       现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问都可以从任何地址开始,但实际情况是在访问特定类型变量的时候经常在特定的内存地址访问,这就是对齐。 字节对齐的原因大致是如下两条: 1、平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。 2、性能原因:数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。 二、对齐规则        每个特定平台上的编译器都有自己的默认“对齐系数”(也叫对齐模数)。程序员可以通过预编译命令#pragma pack(n),n=1,2,4,8,16来改变这一系数,其中的n就是你要指定的“对齐系数”。 规则: 1. 数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员的对齐按照#pragma pack指定的数值和这个数据成员自身长度中,比较小的那个进行。 2. 结构(或联合)的整体对齐规则:在数据成员完成各自对齐之后,结构(或联合)本身也要进行对齐,对齐将按照#pragma pack指定的数值和结构(或联合)最大数据成员长度中,比较小的那个进行。 3. 结合1、2可推断:第一、如果n大于等于该变量所占用的字节数,那么偏移量必须满足默认的对齐方式,第二、如果n小于该变量的类型所占用的字节数,那么偏移量为n的倍数,不用满足默认的对齐方式。 三、X86对齐实验        下面再简要回顾解释一下上述的对齐规则,结合实例进行分析: 1. 数据类型自身的对齐值:对于char型数据,其自身对齐值为1字节,对于short型为2字节,对于int,float,double类型,其自身对齐值为4字节。 2. 结构体的自身对齐值:其成员中自身对齐值最大的那个值。 3. 指定对齐值:#pragma   pack(n)来设定变量以n字节对齐方式。n字节对齐就是说变量存放的起始地址的偏移量有两种情况,第一、如果n大于等于该变量所占用的字节数,那么偏移量必须满足默认的对齐方式,第二、如果n小于该变量的类型所占用的字节数,那么偏移量为n的倍数,不用满足默认的对齐方式。 4. 数据成员和结构体的有效对齐值:数据成员(数据类型)和数据结构的自身对齐值和指定对齐值中小的那个值,数据成员对齐了数据结构自然也就对齐了。 了解上述四个基本概念,我们开始讨论具体数据结构的成员和其自身的对齐方式。有效对齐值N是最终用来决定数据存放地址方式的值。有效对齐N,就是 关于同志近三年现实表现材料材料类招标技术评分表图表与交易pdf视力表打印pdf用图表说话 pdf 示“对齐在N上”,也就是说该数据的"存放起始地址%N=0"。而数据结构中的数据变量都是按定义的先后顺序来排放的。第一个数据变量的起始地址就是数据结构的起始地址。结构体的成员变量要对齐排放,结构体本身也要根据自身的有效对齐值圆整(结构体成员变量占用总长度需要是对结构体有效对齐值的整数倍)。下面结合VS2005中编译环境的例子进行深入了解: 例子B分析: struct B { char b; int a; short c; }; 假设B从地址空间0x0000开始排放。该例中没有显式指定对齐值N,VS2005默认值为4。 成员变量b自身对齐值是1,比指定或默认指定对齐值4小,故有效对齐值为1,其存放地址0x0000符合0x0000%1=0,满足字节对齐原则。 成员变量a自身对齐值为4,和指定或默认指定对齐值4相等,故有效对齐值也为4,为了保证字节对齐,成员变量a只能存放在起始地址为0x0004到0x0007这四个连续的字节空间中,复核0x0004%4=0。 成员变量c自身对齐值为2,比指定或默认指定对齐值4小,故有效对齐值为2,可顺序存放在0x0008至0x0009两个字节空间中,符合0x0008%2=0。 至此满足了数据成员的字节对齐,接着看数据结构B的对齐。数据结构B的自身对齐值为其变量中最大对齐值(也就是成员变量b)4,故结构体B的有效对齐值也是4。根据结构体圆整的要求, 0x0009到0x0000=10字节,(10+2)%4=0。所以0x0000A到0x000B也为结构体B所占用。故B从0x0000到0x000B 共有12个字节,sizeof(struct B)=12。 之所以在变量C补充2字节,是因为要实现编译器快速有效的存取结构数组,试想如果定义B结构数组,第一个结构起始地址是0没有问题,但是第二个结构呢?按照数组的定义,数组中所有元素都是紧挨着的,如果不把结构的大小补充为对齐值(4)的整数倍,那下一个结构的起始地址将是0x0000A,这显然不能满足结构的地址对齐了。 例子C分析: /*指定按2字节对齐*/ __align(2) struct C { char b; int a; short c; };/*取消指定对齐,恢复缺省对齐*/    同理,例子C中成员变量b自身对齐值为1,指定对齐值为2,故效对齐值为1,假设C从0x0000开始,那么b存放在0x0000,符合0x0000%1= 0,满足字节对齐原则。    成员变量a自身对齐值为4,指定对齐值为2,故有效对齐值为2,顺序存放在0x0002、0x0003、0x0004、0x0005四个连续字节中,符合0x0002%2=0,满足字节对齐原则。    成员变量c的自身对齐值为2,与指定对齐值相等,故有效对齐值为2,顺序存放在0x0006、0x0007中,符合 0x0006%2=0,满足字节对齐原则。    从0x0000到0x00007共八字节存放的是结构体C的变量。结构体C自身对齐值为4,比指定对齐值2大,故C的有效对齐值为2,因8%2=0,C只占用0x0000到0x0007的八个字节。所以sizeof(struct C)=8,完全满足字节对齐原则。    除了指定的对齐值不同能导致数据结构的地址存放不同外, 编译器不同存放结构体方式也可能不同。 四、ARM平台的对齐问题 在ARM中,有ARM和Thumb两种指令。 ARM指令:每执行一条指令,PC的值加4个字节(32bits).一次访问4字节内容,该字节的起始地址必须是4字节对齐的位置上,即地址的低两位为bits[0b00],也就是说地址必须是4的倍数。 Thumb指令:每执行一条指令,PC的值加2个字节(16bits).).一次访问2字节内容,该字节的起始地址必须是2字节对齐的位置上,即地址的低两位为bits[0b0],也就是说地址必须是2的倍数。      遵循以上方式叫对齐(aligned)方式,不遵守这样方式称为非对齐(unaligned)的存储访问操作。 五、ARM平台字节对齐关键字 1. __align(num)    用于修改最高级别对象的字节边界。 A、在汇编中使用LDRD或者STRD时,就用到此命令__align(8)进行修饰限制。来保证数据对象是相应对齐。 B、该修饰对象的命令最大是8个字节限制,可让2字节的对象进行4字节    对齐,但是不能让4字节的对象2字节对齐。 C、 __align是存储类修改,他只修饰最高级类型对象不能用于结构或者函数对象。    2. __packed __packed是进行一字节对齐。 A、不能对packed的对象进行对齐; B、所有对象的读写访问都进行非对齐访问; C、float及包含float的结构联合及未用__packed的对象将不能字节对齐; D、__packed对局部整形变量无影响; D、强制由unpacked对象向packed对象转化是未定义,整形指针可以合法定 义为packed __packed int* p; //__packed int 则没有意义。 3. __unaligned    用于修饰该变量可按照非对齐访问。 六、如何查找与字节对齐方面的问题 如果出现对齐或者赋值问题首先查看: 1. 编译器的big little端设置; 2. 看这种体系本身是否支持非对齐访问; 3. 如果支持看设置了对齐与否,如果没有则看访问时需要加某些特殊的修饰来标志其特殊访问操作。 七、结论    针对于32位处理器对于本地使用的数据结构,为提高内存访问效率,采用四字节对齐方式;同时为了减少内存的开销,合理安排结构成员的位置,减少四字节对齐导致的成员之间的空隙,降低内存开销。    对于处理器之间的数据结构,需要保证消息的长度不因为在不同编译平台和不同处理器导致消息结构的长度发生变化,使用一字节对齐方式对消息结构进行紧缩;为保证处理器之间的消息的数据结构的内存访问效率,采用字节填充的方式自己对消息中成员进行四字节对齐。    数据结构的成员位置要兼顾成员之间的关系、数据访问效率和空间利用率。顺序安排的原则是:四字节的放在最前面,两字节的紧接最后一个四字节成员,一字节紧接最后一个两字节成员,填充字节放在最后。举例如下: typedef struct tag_T_MSG{ long ParaA; long ParaB; short ParaC; char ParaD; char Pad; /* 填充字节 */ } T_MSG; ARM处理器CPSR标志位和条件符之间的关系 类别:嵌入式系统   阅读:862   本文目的是要理清ARM处理器的CPSR状态标志和ARM指令的条件符之间的关系。   一、CPSR寄存器   ARM V4的CPSR寄存器(和保存它的SPSR寄存器)中的位分配如下图1所示。   图1 程序状态寄存器格式   状态标志位含义:(其它位的含义和本文主题无关,此处不多介绍)   N   N=1 表示运算的结果为负数;N=0 表示运算的结果为正数或零;   Z   Z=1 表示运算的结果为零;Z=0表示运算的结果为非零;   C   可以有4种方法设置C的值:   ─ 加法运算(包括比较指令CMN):当运算结果产生了进位时(无符号数溢出),C=1,否则C=0。   ─ 减法运算(包括比较指令CMP):当运算时产生了借位,C=0,否则C=1。   ─ 对于包含移位操作的非加/减运算指令,C为移出值的最后一位。   ─ 对于其他的非加/减运算指令,C的值通常不改变。   V   可以有2种方法设置V的值:   ─ 对于加/减法运算指令,当操作数和运算结果为二进制的补码表示的带符号数时,V=1表示符号位溢出。   ─ 对于其他的非加/减运算指令,V的值通常不改变   二、条件符及对应的标志位   表1 条件符描述表   三、关于C、V值更多的解释   处理器内部以补码表示有符号数,8个二制位能够表达的整数范围是:+127 ~ -128,16位表达的范围是:+32767 ~ -32768。如果运算结果超出了这个范围,就是产生了溢出,有溢出,说明有符号数的运算结果需要考虑溢出情况。   溢出标志V和进位标志C是两个意义不同的标志。进位标志表示无符号数运算结果是否超出范围;溢出标志表示有符号数运算结果是否超出范围。   处理器对两个操作数进行运算时,按照无符号数求得结果,并相应设置进位标志C;同时,根据是否超出有符号数的范围设置溢出标志V。   应该利用哪个标志,则由程序员来决定。也就是说,如果将参加运算的操作数认为是无符号数,就应该关心进位;认为是有符号数,则要注意是否溢出。   判断运算结果是否溢出有一个简单的规则:只有当两个相同符号数相加,而运算结果的符号与原数据符号相反时,产生溢出;其他情况下,则不会产生溢出。   代码举例1:   LDR r0, =0x7fffffff   LDR r1, =0x70000000;   ADDS r0, r0, r1; //结果=0xefffffff   对于无符号数运算来说,没有进位。   对于有符号数运算来说,溢出。   此时C=0 V=1;   代码举例2:   LDR r0, =0xffffffff   LDR r1, =0x70000000;   ADDS r0, r0, r1; //结果=0x6fffffff   对于无符号数运算来说,有进位。   对于有符号数运算来说,无溢出。   此时C=1 V=0;   代码举例3:   LDR r0, =0x8fffffff   LDR r1, =0xf0000000 ;   ADDS r0, r0, r1; //结果=0x7fffffff   此时C=? V=?;(思考一下,然后在ARM模拟器中验证下)   代码举例4://思考减法时,C值的影响   LDR r0, =0x3   LDR r1, =0x2   SUBS r0, r0, r1   对比:   LDR r0, =0x3   LDR r1, =-2;(-2的补码0xfffffffe会送到r1)   ADDS r0, r0, r1   四、CPSR状态标志和ARM指令的条件符之间的关系   有了上面的背景知识以后,接下来思考表1中CPSR状态标志和ARM指令的条件符之间的关系,下面选取其中的一项来分析。   如:GE:(有符号数大于等于)   N=0 V=0:结果是大于等于0的数,且无符合溢出,所以大于等于关系成立   N=1 V=1:结果小于0,但有符号溢出   考虑以下情况:c=a-b   1.a<0, b<0   减法操作时不可能符号溢出   2.a>0, b<0   可能出现N=V=1?? 如(8位数):100-(-100)=200   显然a>b   3.a<0, b>0   参照上面提到过的判断溢出标志的简单规则,可以得出:在此情况下,   减法操作时如果结果小于0 (N=1),则不会出现符号溢出   所以(在N=1 V=1前提下a<0,b>0)这种情况不可能出现   4.a>0, b>0   减法操作不可能出现符号溢出。   其它项的分析过程类似。   五、总结   尽管以上分析看起来有点复杂,但使用时在大多数情况下用一个简单的条件测试指令即可,不需要程序员计算出条件码的精确值即可得到需要的结果。 寄存器:用途   1.可将寄存器内的数据执行算术及逻辑运算   2.存于寄存器内的地址可用来指向内存的某个位置,即寻址   3.可以用来读写数据到电脑的周边设备。 控制寄存器(CR0~CR3)用于控制和确定处理器的操作模式以及当前执行任务的特性。 基于arm内核的芯片具有许多的外设,这些外设访问的标准方法是使用存储器映射的I/O,为外设的每个寄存器都分配一个地址。通常,从这些地址装载数据用于读入,向这些地址保存数据用于输出。有些地址的装载和保存用于外设的控制功能,而不是输入或输出功能。 注意:存储器映射的I/O位置的操作不同于正常的存储器位置的操作。通常,存储器映射的I/O位置没有高速缓存和无缓存区。
本文档为【嵌入式系统概论】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_658864
暂无简介~
格式:doc
大小:182KB
软件:Word
页数:7
分类:工学
上传时间:2011-12-01
浏览量:37