默认情况下,如何使用GCC删除所有全局变量的对齐(下面为.align 4
),而不必为每个变量指定__attribute__((aligned(1)))
?
我知道我所要求的是普遍适用的一个坏主意,因为在某些架构中,1的对齐不会起作用,因为例如CPU无法取消引用未对齐的指针。在我的情况下,我正在编写一个i386引导加载程序,并且未对齐的指针在那里很好(但速度较慢)。
源代码(a.c
):
__attribute__((aligned(1))) int answer0 = 41;
int answer = 42;
编译:{{1}}
装配输出(gcc -m32 -Os -S a.c
):
a.s
标志 .file "a.c"
.globl answer
.data
.align 4
.type answer, @object
.size answer, 4
answer:
.long 42
.globl answer0
.type answer0, @object
.size answer0, 4
answer0:
.long 41
.ident "GCC: (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4"
.section .note.GNU-stack,"",@progbits
将所有struct成员和结构的对齐方式更改为1.例如,使用该标志
gcc -fpack-struct=1
编译为变量struct x { char a; int b; };
struct y { int v : sizeof(char) + sizeof(int) == sizeof(struct x); };
struct z { int b; };
struct x x = { 1, 1 };
int i = 42;
struct z z = { 2 };
z'没有对齐,但变量x' and
(类型.align 4
)仍然有i
。我需要一个解决方案,它也使int
不对齐,而不必为每个这样的变量指定额外的东西。
答案 0 :(得分:1)
使用打包结构来保存空间的IMO打包变量是最简单,最安全的方法。
示例:
#include <stdio.h>
#include <stdint.h>
#define _packed __attribute__((packed))
_packed struct
{
uint8_t x1;
_packed int x2;
_packed uint8_t x3[2];
_packed int x4;
}byte_int;
int main(void) {
printf("%p %p %p %p\n", &byte_int.x1, &byte_int.x2, &byte_int.x3, &byte_int.x4);
printf("%u %u %u %u\n", (unsigned int)&byte_int.x1, (unsigned int)&byte_int.x2, (unsigned int)&byte_int.x3, (unsigned int)&byte_int.x4); // I know it is an UB just to show the op in dec - easier to spot the odd and the even addresses
return 0;
}
答案 1 :(得分:0)
很可能gcc没有这样的标志,可以改变全局变量的默认排列。
gcc -fpack-struct=1
可以是一种解决方法,但仅适用于恰好是struct
类型的全局变量。
同时对gcc的.s
输出进行后期处理并删除(部分).align
行可以作为解决方法。