在驱动程序开发方面,64位Windows的数据对齐

时间:2010-11-04 07:57:54

标签: windows driver 32bit-64bit

我在MSDN上找到了this

  

在32位Windows平台上,操作系统会自动修复内核模式内存对齐错误,并使其对应用程序不可见。它为调用进程和任何后代进程执行此操作。此功能通常会大幅降低性能,但尚未在64位Windows中实现。因此,如果您的32位驱动程序包含错位错误,则在移植到64位Windows时需要修复它们。

我对此感到有些害怕。有人能告诉我一个错位错误的例子吗?

编辑:我基本上知道对齐的概念及其原因。我只想弄清楚win32和win64之间在对齐的“自动修复”方面的差异以及对我的驱动程序的影响。

3 个答案:

答案 0 :(得分:2)

考虑以下结构,其中ac是32位字,b是字节。

|-----------a-----------|--b--|-----------c-----------|
|     :     :     :     :     :     :     :     |     :

如果在64位边界上分配此结构,则ab将正确对齐,但c不会,因为它跨越64位字边界。实际上,如果不将ac推到这样的边界上,就不可能布局这个结构。

在实践中,编译器通常会采用这样的定义:

struct {
    int a;
    char b;
    int c;
};

并安排如下:

|-----------a-----------|--b--|     padding     |-----------c-----------|
|     :     :     :     :     :     :     :     |     :     :     :     :

这样,没有任何值穿过对齐边界。但是在驱动程序编程中,通常必须打包结构(即,没有填充)以匹配线上或盘上数据结构格式。除非你手工拆开字边界,否则就会陷入冲突。

答案 1 :(得分:1)

我手边没有示例,但解释的问题很简单 - 您只能在64位边界上访问64位数据。在数据为32位(或更小)对齐的情况下,您无法以64位值的形式可靠地访问它,因为每个第二个值都不会在64位边界上,并且此访问将产生异常。

WIntel机器对这些故障非常宽容,但大多数其他架构(如ARM)会在所有对齐问题上抛出异常,因此所有指针转换都会受到极大的怀疑。小心,非常小心,是前进的唯一方法,使用像Lint和Klocwork这样的静态分析工具可以提供很多帮助。

答案 2 :(得分:0)

引用this文件以防有人有同样的担忧:

  

如果处理器尝试读取或   写不正确的对齐数据,   可能发生对齐故障。在x86上   硬件,对齐故障是   对用户不可见。硬件   修复故障,如中所述   前一段。在x64硬件上,   对齐故障被禁用   默认和硬件类似   解决了这个问题。在Intel Itanium上   但是,如果是一个对齐的架构   64位内核模式时发生故障   代码正在运行,硬件引发   一个例外。 (对于用户模式代码,   这是一个默认设置   个人申请可以改变,   虽然禁用对齐故障   Itanium会严重降级   性能。)