如何为gcc指定默认的全局变量对齐?

问题描述 投票:0回答:2

默认情况下,如何使用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' andz'没有对齐,但它仍然有变量.align 4(类型为i)的int。我需要一个解决方案,它也使int i = 42;不对齐,而不必为每个这样的变量指定额外的东西。

c gcc alignment
2个回答
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;
}

https://ideone.com/bY1soH


0
投票

很可能gcc没有这样的标志,可以改变全局变量的默认对齐方式。

gcc -fpack-struct=1可以是一种解决方法,但仅适用于恰好是struct类型的全局变量。

同时后处理gcc的.s输出并删除(某些).align线可以作为一种解决方法。

© www.soinside.com 2019 - 2024. All rights reserved.