64位Windows在驱动程序开发方面的数据alignment

我在MSDN上find了这个 :

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

我有点害怕。 任何人都可以给我看一个错位错误的例子吗?

编辑:我基本上知道alignment的概念和原因。 我只是想弄清楚在win32和win64之间的alignment方式上的“自动修复”和对我的驱动程序的影响。

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

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

如果你在64位边界上分配这个结构,那么ab都将被正确对齐,但c不会,因为它跨越了64位的字边界。 事实上,如果不把ac推到这个边界上,就不可能对这个结构进行布局。

实际上,编译器通常会这样定义:

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

并像这样安排它:

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

所以没有一个值跨越一个对齐边界。 但是在驱动程序编程中,为了与线上或者磁盘上的数据结构格式相匹配,结构通常必须被打包(即没有填充)。 那就是除非你用手解开字界,否则你就会陷入争斗。

我没有一个例子,但是这个问题很简单,只能在64位边界上访问64位数据。 如果数据是32位(或更小)对齐,则不能以64位值的形式可靠地访问这些数据,因为每个第二个值不会位于64位边界上,并且此访问将产生一个异常。

WIntel机器非常容忍这些故障,但是像ARM这样的大多数其他体系结构都会在所有的对齐问题上抛出异常,因此所有指针都会被怀疑地看到。 小心,小心,是唯一的出路,使用静态分析工具,如林特和Klocwork帮助了很多。

如果有人有同样的担忧,请引用此文档:

如果处理器尝试读取或写入不正确的对齐数据,则会发生对齐错误。 在x86硬件上,对齐错误对用户是不可见的。 硬件如前段所述修复故障。 在x64硬件上,默认情况下,对齐错误被禁用,硬件也类似地修复错误。 但是,在Intel Itanium体系结构中,如果在运行64位内核模式代码时发生对齐错误,则硬件会引发异常。 (对于用户模式代码,这是单个应用程序可以更改的默认设置,但在Itanium上禁用对齐错误会严重降低性能。)