对于遇到类似情况的其他人来说,这里的问题不在于内联程序集,也不在于它的调用方式:它在于程序中的类/结构。我认为是违规者的类不是问题 - 有另一个类持有它的实例,并且由于该外部类的其他成员,内部类没有在单词边界上对齐。这导致了我遇到的“总线错误”。我以前没有遇到过这种情况,因为这些类没有__attribute__((packed))
在其他代码中声明,但它们在我的实现中。
提供类型属性 - 使用 GNU 编译器集合 (GCC)阅读实际上激发了我的答案。影响内存对齐的两个特定属性(以及我正在使用的内联汇编)是packed
和aligned
.
取自上述链接:
对齐(对齐)
此属性为指定类型的变量指定最小对齐方式(以字节为单位)。例如,声明:
struct S { short f[3]; } __attribute__ ((aligned (8)));
typedef int more_aligned_int __attribute__ ((aligned (8)));
强制编译器确保(尽可能)类型为struct S
or more_aligned_int 的每个变量都被分配并至少在 8 字节边界上对齐。在 SPARC 上,将所有类型的变量struct S
对齐到 8 字节边界允许编译器在将一个类型的变量复制到另一个类型的变量时使用ldd
and (双字加载和存储)指令,从而提高运行时效率。std
struct S
请注意,ISO C 标准要求任何给定struct
或类型的对齐方式至少是orunion
的所有成员的对齐方式的最小公倍数的完美倍数。这意味着您可以通过将属性附加到此类类型的任何一个成员来有效地调整 a or类型的对齐方式,但是上面示例中说明的符号是请求编译器的一种更明显、直观和可读的方式调整整个或类型的对齐方式。struct
union
struct
union
aligned
struct
union
与前面的示例一样,您可以显式指定希望编译器用于给定struct
或union
类型的对齐方式(以字节为单位)。或者,您可以省略对齐因子,只要求编译器将类型对齐到您正在编译的目标机器的最大有用对齐。例如,您可以编写:
struct S { short f[3]; } __attribute__ ((aligned));
每当您在对齐的属性规范中省略对齐因子时,编译器会自动将类型的对齐设置为您正在编译的目标机器上的任何数据类型曾经使用过的最大对齐。这样做通常可以使复制操作更有效,因为编译器可以使用任何指令在执行复制到或从具有您以这种方式对齐的类型的变量的变量时复制最大的内存块。
在上面的例子中,如果 each 的大小short
是 2 个字节,那么整个struct S
类型的大小是 6 个字节。大于或等于 8 的 2 的最小幂是 8,因此编译器将整个struct S
类型的对齐设置为 8 个字节。
请注意,尽管您可以要求编译器为给定类型选择一种省时的对齐方式,然后只声明该类型的单个独立对象,但编译器选择一种省时的对齐方式的能力主要仅在您计划创建具有相关(有效对齐)类型的变量数组。如果您声明或使用有效对齐类型的变量数组,那么您的程序很可能还会对指向相关类型的指针以及编译器为这些指针算术运算生成对于有效对齐的类型通常比其他类型更有效。
对齐属性只能增加对齐;但您也可以通过指定打包来减少它。见下文。
请注意,对齐属性的有效性可能会受到链接器固有限制的限制。在许多系统上,链接器只能安排变量对齐到某个最大对齐。(对于某些链接器,支持的最大对齐可能非常小。)如果您的链接器最多只能将变量对齐到 8 字节对齐,那么aligned(16)
在__attribute__
仍然指定的情况下只能为您提供 8 字节对齐。有关详细信息,请参阅您的链接器文档。
.
包装好的
这个属性,附加到struct
或union
类型定义,指定结构或联合的每个成员(除了零宽度位字段)被放置以最小化所需的内存。当附加到enum
定义时,它表示应该使用最小的整数类型。
struct
为和类型指定此属性union
等效于为每个结构或联合成员指定打包属性。-fshort-enums
在行上指定标志等效于packed
在所有enum
定义上指定属性。
在下面的示例struct my_packed_struct
中,成员紧密地打包在一起,但其s
成员的内部布局没有打包——为此,也struct my_unpacked_struct
需要打包。
struct my_unpacked_struct
{
char c;
int i;
};
struct __attribute__ ((__packed__)) my_packed_struct
{
char c;
int i;
struct my_unpacked_struct s;
};
您只能在或的定义上指定此属性enum
,而不能在未定义枚举类型、结构或联合的 a 上指定此属性。struct
union
typedef
我遇到的问题具体是由于使用packed
. 我试图简单地将aligned
属性添加到结构和类中,但错误仍然存在。只有删除packed
属性才能解决问题。现在,我将aligned
属性保留在它们上并进行测试,看看我是否发现上面提到的代码效率有任何改进,这仅仅是因为它们在字边界上对齐。应用程序使用了这些结构的数组,因此可能会有更好的性能,但只有分析代码才能确定。