arm字节对齐
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
arm中的字节对齐问题
(2011-04-02 11:03:56)
转载
标签:
杂谈
昨天调程序,发现一个不得解的问题,传过来的地址明明是正确的,可是一读却是一条非法指令。不写操作。很长时间不能解决,师兄过来看了一下,才现是字节对齐的问题。唉,终于碰到对齐问题了,那就好好解决一下吧。先说下我遇到的问题
typedef sturct
{
char a;
char b;
char c[255];
} FS;
FS fs;
....
disk_read(...,fs->c,...)
....
void disk_read(...,int* p,...)
{
....
*p++=0x01010101; //error:
....
}
到了这一步,也就可以看一下问题发生的原因了,在结构体中,对将c做到字节对齐,这样
和disk_read中的P的四字节对齐是不同的,这样写的时候由于不是四字节对齐,就会出错
下面转两篇字节对齐的文章。戒之戒之
=====================================================
有了上面的基础后,在一些数据结构中就要消除这些字节带来的影响,特别是在文件访问的过程中,在各个平台上都会遇到。
文件为了保持最小,利用空间的原则,会按照字节来存储的,但是我们在内存中定义的结构会按最优原则使效率最大,这样会保持边界对齐。那么如何消除影响呢,
先看在 vc中如保操作
#pragma pack(push, 1) == #paragma pack(push) #paragma pack(1) struct T
{
int a;
char b;
}
#paragma pack(pop)
再来看看ads 在arm平台是如何操作的
__packed
struct T
{
int a;
char b;
}
最后来看看gcc下面的操作
__attribute__((__packed__))
struct T
{
int a;
char b;
}
最后,让我们来看看怎么定义一个结构才是移植性够好的结构
PACK_STRUCT_BEGIN
struct ip_hdr {
PACK_STRUCT_FIELD(u16_t _id);
PACK_STRUCT_FIELD(struct ip_addr src);
} PACK_STRUCT_STRUCT;
PACK_STRUCT_END
通过引个宏来改变这些相应的结构
#ifdef __GNU_C__
#define PACK_STRUCT_FIELD(x) x
#define PACK_STRUCT_STRUCT __attribute__((__packed__))
#define PACK_STRUCT_BEGIN
#define PACK_STRUCT_END
#elif__ADS__
#define PACK_STRUCT_FIELD(x) __packed x
#define PACK_STRUCT_STRUCT
#define PACK_STRUCT_BEGIN __packed
#define PACK_STRUCT_END
#elif __VC__
#define PACK_STRUCT_FIELD(x) x
#define PACK_STRUCT_STRUCT
#define PACK_STRUCT_BEGIN #pargma pack (push, 1) (问题代码) #define PACK_STRUCT_END #pargma pack (pop) (问题代码)
#else
#define PACK_STRUCT_FIELD(x)
#define PACK_STRUCT_STRUCT
#define PACK_STRUCT_BEGIN
#define PACK_STRUCT_END
#endif
好啦,到此为止一切都结束了,这就是相关的字节对齐的一些操作,原来我只以为只有最后这一种情况才是呢,最上面的那种情况是后来调试才遇到的,至于以后,可能还会有,再做补充了
ps:上面有两行问题代码,自己用的时候才发现,宏定义中出现"#",几乎不可能,所以放弃这样的想法
宏定义中的#可以把一个数字变成字串 ##则代表字符串连接。
所以想要实现就要麻烦一些了,最后我是这样实现的,不好看但管用。
#if defined _ADS_
#elif defined _GCC_
__attribute__((__packed__))
#elif defined _VC_
#pargma pack(push, 1)
#endif
struct a
{...};
#ifdef _VC_
#pargma pack(pop)
#endif
===================================================================== ========
/u1/36006/showart_569730.ht ml
一.什么是字节对齐,为什么要对齐?
现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定类型变量的时候经常在特
定的内存地址访问,这就需要各种类型数据按照一定的规则在空间上排列,而不是顺序的一个接一个的排放,这就是对齐。
对齐的作用和原因:各个硬件平台对存储空间的处理上有很大的不同。一些平台对某些特定类型的数据只能从某些特定地址开始存取。比如有些架构的CPU在访问
一个没有进行对齐的变量的时候会发生错误,那么在这种架构下编程必须保证字节对齐.其他平台可能没有这种情况,但是最常见的是如果不按照适合其平台要求对
数据存放进行对齐,会在存取效率上带来损失。比如有些平台每次读都是从偶地址开始,如果一个int型(假设为32位系统)如果存放在偶地址开始的地方,那
么一个读周期就可以读出这32bit,而如果存放在奇地址开始的地方,就需要2个读周期,并对两次读出的结果的高低字节进行拼凑才能得到该32bit数
据。显然在读取效率上下降很多。
二.字节对齐对程序的影响:
先让我们看几个例子吧(32bit,x86环境,gcc编译器):
设结构体如下定义:
struct A
{
int a;
char b;
short c;
};
struct B
{
char b;
int a;