CSAPP 关于数据对齐

来源:互联网 发布:淘宝女装宣传语 编辑:程序博客网 时间:2024/06/05 16:20

强制对齐的

          对于大多数IA32指令来说,保持数据对齐能够提高效率,但是它不会影响程序的行为。另一方面,如果数据未对齐,有些实现多媒体操作的SSE指令就无法正确地工作。这些指令对16字节数据块进行操作,在SSE单元和存储器之间传送数据的指令要求存储器地址必须是16的倍数。任何试图以不满足对齐要求的地址来访问存储器都会导致异常(exception),默认的行为是终止程序。

       因此IA32的一个惯例是,确保每个栈帧的长度都是16的整数倍。编译器就可以在栈帧中以每块的存储都是16字节对齐的方式来分配存储。

Microsoft Windows的对齐

    Microsoft Windows对齐的要求更严格------任何K字节基本对象的地址都必须是K的倍数,K=2,4或者8。特别地,他要求一个double 或者long long 类型数据的地址应该是8的倍数。这种要求提高了存储器的性能,而代价则是浪费了一些空间。linux的惯例是8字节数据在4字节边界上对齐,这可能对i386很好,因为过去存储器十分缺乏,而存储器接口只有4字节宽。对于现代处理器来说,Microsoft的对齐策略就是更好的选择。在windows和linux上,数据类型long double都有4字节对齐的要求,为此GCC产生的IA32代码分配12个字节(虽然实际的数据类型只需10个字节)。

Microsoft Windows下结构体对齐一般而言应满足一下3个准则;

    Microsoft Windows下任何K字节基本对象的地址都必须是K的倍数,K=2,4或者8。

    1 结构体变量的首地址能够被其最宽基本类型成员的大小所整除;

     2 结构体每个成员相对于结构首地址的偏移量(offset)都是成员大小的整数倍,如有需要编译器会在成员之间填充字节(internal adding);

     3 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员后面加上填充字节(trailing adding);

     对于上面的准则,有2点需要说明:

     1 结构体某个成员相对于结构体首地址的偏移量可以通过宏offsetof()来获取,这个宏在stddef.h中定义如下:

     #define offsetof(s,m) (size_t)&(((s *)0)->m)

     2 基本类型是指如char,short,int,float,double这样的内置类型,这里所说的“数据宽度“是指sizeof的大小。由于结构体的成员可以是复合类型,比如另外一个结构体,所以在寻找最宽基本类型成员是,应当包括复合类型成员的子成员,而不是把复合成员看成是一个整体。但在确定复合类型成员的偏移位置时则是将复合类型作为整体来看待。

LINUX下结构体对齐和Microsoft Windows的不同

   linux下任何K字节基本对象的地址都必须是K的倍数,K=2或者4。由于linux的惯例是8字节数据在4字节边界上对齐,所以linux下的准则和Microsoft Windows下有所不同:

   1 如果结构体的最宽基本类型成员不为8,则结构体变量的首地址能够被其最宽基本类型成员的大小所整除

   2 如果结构体的最宽基本类型成员为8,则结构体变量的首地址能够被4整除

    3  结构体每个成员相对于结构首地址的偏移量(offset)都是成员大小的整数倍(除8字节数据类型外),8字节数据类型的成员以4字节对齐

     4 结构体的总大小为4的整数倍


EXAMPLE:

   对于结构体声明

   struct {

         char      a;

         short    b;

         double c;

         char    *d;

   }foo;

   A  这个结构体中所有字段的字节偏移量是多少?

   B  这个结构体总的大小是多少?


   在考虑这两个问题时需要对不同的操作系统进行分析

   在Windows机器上编译它:

   A 这里是对象大小和字节偏移量

字段  a  b  c  d大小  1  2 8  4偏移量  0  2 8 16    B 这个结构体总的大小为24个字节。结构的结尾必须填充4个字节来满足8个字节对齐的要求。

  在Linux上编译它:

   A 这里是对象大小和字节偏移量
字段  a  b  c  d大小  1  2 8  4偏移量  0  2 4
 12
   B 这个结构体总的大小为16个字节。


X86-64中的数据结构遵循的原则:

    X86-64遵循的原则与IA32一样:数组是作为同样大小的块的序列来分配,这块中保存这数组元素;结构体则作为变长的块来分配,块中保存这街头体中的元素;联合体是作为一个单独的块来分配,这个块足够大,能够装下联合体中最大的元素。

     区别是X86-64遵循严格的对齐要求。对于任何需要K字节的标量数据类型来说,它的起始地址必须是K的倍数。因此数据类型long 和double以及指针,都必须在8字节边界上对齐。此外,数据类型long double使用16字节对齐(分配也是16个字节大小),虽然实际表示只需10个字节。强加上这些对齐是为了提高存储器系统性能-----最新的处理器中,存储器接口被设计成读或写对齐的块,这些块是8或16字节长。



 

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 点击订阅号所收到内容字太大怎么办 我的小叶栀子花老是黄叶该怎么办? 联币金融倒闭了我投资的钱怎么办 新单位交养老保险不接收档案怎么办 高铁发车十小时没赶上怎么办 饿了么被阿里收购员工怎么办? 爱疯4s密码忘了怎么办 研究生论文盲审一直不出结果怎么办 查重报告有疑似剽窃观点怎么办 成绩考的不好怎么办读技校有用吗 孩子大学挂科太多家长应该怎么办 中专升大专的入学考没考上怎么办 小孩摔跤额头出了个包怎么办 小孩摔跤后脑勺出了个包怎么办 结婚后疏于关心老婆寒心了怎么办 江苏取消小高考高二学生怎么办 上海学而思家长陪读听不懂怎么办 高考报名的电话号码填错了怎么办 高考报名用的电话号码变换了怎么办 弟媳妇一个月就大闹一次怎么办 丈夫出轨我亲弟媳妇我怎么办 被山西博大泌尿医院坑了怎么办 家长反应孩子学校受欺负老师怎么办 白色衣服和牛仔裤洗变色了怎么办 生完孩子肚子上的松皮怎么办 xp电脑玩cf进入地图黑屏怎么办 爸妈吵架妈妈走了爸爸哭了该怎么办 总担心旅馆被拍视频传上网怎么办 微博买了猜冠军现在停了怎么办 脸上毛孔大有黑头怎么办小窍门去 进去精神病院出来真的疯了怎么办 房子已过户新业主不交物业费怎么办 村委会欠百姓征地补偿款不给怎么办 因为近亲人人都不看好的婚姻怎么办 碰到工作中特别积极的同事怎么办 丈夫车祸死亡妻子和孩子以后怎么办 丈夫死后妻子改嫁儿子不同意怎么办 满了60岁社保没满15年怎么办 捷豹的dpf灯亮了怎么办 朋友如新直销产品是你该怎么办 传福音接受了却被家人拦阻该怎么办