阳光网驿-企业信息化交流平台【DTC零售连锁全渠道解决方案】

 找回密码
 注册

QQ登录

只需一步,快速开始

扫描二维码登录本站

手机号码,快捷登录

老司机
查看: 2010|回复: 2

我眼中的数据对齐

[复制链接]
  • TA的每日心情
    开心
    2017-1-9 22:59
  • 签到天数: 229 天

    [LV.7]常住居民III

    发表于 2008-2-19 00:21:11 | 显示全部楼层 |阅读模式
    眼中的数据对齐
                        作者:溟初

        在看雪论坛关于memcpy的帖子 (<memcpy应该怎样写,同时庆祝新版开张>http://bbs.pediy.com/showthread.php?s=&amp;threadid=14128) 中谈及了数据对齐的话题,重新唤起了我对它的思考(以前一直都似懂非懂,逐渐淡忘了^_^),纯属个人见解,请批评指正!
    [url=mkMSITStore:\软件\安装软件\新建文件夹\crack7.chm::/pediy7-739/ms%27code.rar]相关附件下载[/url]。

    一、什么是数据对齐?请看官方的解释:
    Note that words need not be aligned at even-numbered addresses and doublewords need not be aligned at addresses evenly divisible by four. This allows maximum

    flexibility in data structures (e.g., records containing mixed byte, word, and doubleword items) and efficiency in memory utilization. When used in a

    configuration with a 32-bit bus, actual transfers of data between processor and memory take place in units of doublewords beginning at addresses evenly

    divisible by four; however, the processor converts requests for misaligned words or doublewords into the appropriate sequences of requests acceptable to the

    memory interface. Such misaligned data transfers reduce performance by requiring extra memory cycles. For maximum performance, data structures (including

    stacks) should be designed in such a way that, whenever possible, word operands are aligned at even addresses and doubleword operands are aligned at

    addresses evenly divisible by four.
        数据对齐是指W O R D变量应该总是存放在2的倍数的地址处,而D W O R D变量应该总是存放在4的倍数的地址处,等等。

    二、数据对齐随处理器和编译器的不同而不同,处理好数据对齐可以提高程序的时空效率(节省空间,提高效率),特别是在汇编程序中。

    1、在处理器方面:
    从486起EFLAGS寄存器的第18位(AC),CR0寄存器的第18位(AM)用于数据对齐检查,只有当AC=1,AM=1,处理器工作在保护模式或者虚拟86模式的Ring3时,才进行数据对齐检查,

    若不对齐发中断0x11。windows系列没有设置AC(AC=0)位,所以无论数据对齐与否均不会发中断,总是可以存取到正确的数据,但是存取不对齐的数据要比对齐的慢,因为80386dx

    之后处理器的地址线只接受4的倍数的地址(数据线为32位),如果提供的地址不是4的倍数,处理器会转化为若干个4的倍数的地址去存取,每次存取4个字节的数据。比如:
    (1)Mov ax,word ptr[3],会先把dword ptr [0]提取出来,然后从dword ptr[4]提取出来,把所需数据组装后放到数据线,如下图。

    [img=522,88]mkMSITStore:\软件\安装软件\新建文件夹\crack7.chm::/pediy7-739/hejiwen.gif[/img]

    (2)Mov eax,dword ptr[2],与上面一样的提取,只是组装的数据不同。

    2、在编译器方面(以微软的ml、link为例):  

    (1)全局变量:
    在.data,.data?,.const,.code中存放的数据都是紧挨在一起的,变量之间不会留有任何空隙,所以极易发生数据不对齐的现象,特别是定义数组,数据不对齐更会降低存取效

    率。
    VC编译器的全局变量使用COMM,(好像能自动align,谁知道COMM的具体细节请告知谢谢) .c文件全局变量反汇编后是这样的:
    _DATA SEGMENT
    COMM _x:BYTE
    COMM _yWORD
    _DATA ENDS

    当然我们也可以在MASM中显示的使用COMM。

    建议:根据变量的大小合理的安排它们之间的前后关系,使之对齐,必要时可使用align,even,org,$等强制执行对齐,特别是结构体变量和数组。
    比如:
    .code
    test1 db ?
    test2 dw ?
    test3 db ?
    改为:
    test1 db ?
    test3 db ?
    test2 dw ?

    (2)函数参数和局部变量:
    函数参数和局部变量存放在堆栈中,以ebp(mov ebp,esp,其实是esp)为基准,自动进行偏移量的对齐(相对于ebp的偏移量),而恰好ebp的值都是4的倍数,所以这些变量都是自动

    对齐的。
    经测验,dq,dd, real8,real4以双字对齐,dw,df,dt,real10以字对齐,db以字节对齐。
    我是根据下图测验的:
    楼主热帖
    启用邀请码注册,提高发帖质量,建设交流社区

    该用户从未签到

    发表于 2008-2-19 16:14:36 | 显示全部楼层
    我三,我怎么看不懂呢,不过还是要谢谢!
    启用邀请码注册,提高发帖质量,建设交流社区

    该用户从未签到

    发表于 2009-8-9 13:55:08 | 显示全部楼层
    我也是看不懂。。太乱了
    启用邀请码注册,提高发帖质量,建设交流社区
    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    快速回复 返回顶部 返回列表