如何为gcc指定默认的全局变量对齐?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何为gcc指定默认的全局变量对齐?相关的知识,希望对你有一定的参考价值。
默认情况下,如何使用GCC摆脱所有全局变量的对齐(下面的.align 4
),而不必为每个变量指定__attribute__((aligned(1)))
?
我知道我所要求的是普遍应用的一个坏主意,因为在一些架构上,1的对齐不起作用,因为例如CPU无法取消引用未对齐的指针。在我的情况下,我正在编写一个i386引导加载程序,并且未对齐的指针在那里很好(但速度较慢)。
源代码(a.c
):
__attribute__((aligned(1))) int answer0 = 41;
int answer = 42;
编译: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
标志gcc -fpack-struct=1
将所有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 };
编译为变量x' and
z'没有对齐,但它仍然有变量.align 4
(类型为i
)的int
。我需要一个解决方案,它也使int i = 42;
不对齐,而不必为每个这样的变量指定额外的东西。
答案
使用压缩结构来保存空间的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
", &byte_int.x1, &byte_int.x2, &byte_int.x3, &byte_int.x4);
printf("%u %u %u %u
", (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;
}
另一答案
很可能gcc没有这样的标志,可以改变全局变量的默认对齐方式。
gcc -fpack-struct=1
可以是一种解决方法,但仅适用于恰好是struct
类型的全局变量。
同时后处理gcc的.s
输出并删除(某些).align
线可以作为一种解决方法。
以上是关于如何为gcc指定默认的全局变量对齐?的主要内容,如果未能解决你的问题,请参考以下文章
如何为 Tailwindcss 全局更改默认、活动和悬停状态的链接颜色?