4

我正在为 Microblaze 处理器使用 GCC 编译器。最近我遇到了一个变量对齐的问题。我注意到有时编译器会将静态变量分配给未对齐的地址(该地址不能被 4 整除),因此如果我将未对齐变量的指针发送给任何函数,我都会得到未对齐的访问硬件异常。

关于该主题,我有两个问题:

  • 如何确保所有静态变量都对齐?有没有强制要求的标志?目前我正在使用变量属性:

    __attribute__((aligned(4)))
    

    但这很不舒服,因为我需要为我拥有的每个静态变量定义它,这没有意义。

  • 有没有办法确保我的函数局部变量(在堆栈中分配)将对齐?我的意思是有没有办法确保我的堆栈头对齐,每个函数都使用堆栈的对齐部分,并且在堆栈中分配的任何变量都是对齐的。

谢谢。

4

1 回答 1

1

AFAIK there is no way to tell GCC that you want to enforce a certain alignment for the entire compilation unit. That is there is no compiler flag that goes something like "alignment_unit 4".

I'm no expert on the topic (and especially not on the Microblaze soft-core) but I did a little experimentation with GCC targeting the Intel x64 CPU of my PC and with IAR C targeting an ARM Cortex-M4 microcontroller.

SETUP 1 : global(file-level) variables

static uint64_t a = 0;
static uint8_t b = 0;
static uint16_t c = 0;
static uint16_t d = 0;
static uint8_t e = 0;

int main()
{   
    printf("&a = %u\n", &a);
    printf("&b = %u\n", &b);
    printf("&c = %u\n", &c);
    printf("&d = %u\n", &d);
    printf("&e = %u\n", &e);

    return 0;
}

SETUP 2 : local(function-level) variables

void some_func()
{    
    uint64_t a = 0;
    uint8_t b = 0;
    uint16_t c = 0;
    uint16_t d = 0;
    uint8_t e = 0;

    printf("&a = %u\n", &a);
    printf("&b = %u\n", &b);
    printf("&c = %u\n", &c);
    printf("&d = %u\n", &d);
    printf("&e = %u\n", &e);
}

int main()
{   
    some_func();    
    return 0;
}

I turned of all optimizations.

Neither setup resulted in 4 byte (or 8 byte for the PC) aligned variable addresses. That was the case for both compiler/platform combinations.

The only possible solution I can think of (as inelegant as it may be) is to create a header for custom types and put the following typedefs in there:

typedef __attribute__((aligned(4))) uint64_t ui64_aligned;
typedef __attribute__((aligned(4))) uint32_t ui32_aligned;
typedef __attribute__((aligned(4))) uint16_t ui16_aligned;
typedef __attribute__((aligned(4))) uint8_t ui8_aligned;

Then just use the "aligned types" whenever you need them. This way you'll have both "custom-aligned" and "auto-aligned" types and you won't compromise code readability either (too much..).

I know it's not exactly the solution you were looking for but this at least works (as far as my testing goes).

于 2019-06-26T13:54:15.167 回答