arm字节对齐

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 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;

相关文档
最新文档