gcc - 如何生成未对齐的访问条件以及如何使用 gcc 检测它?

标签 gcc arm memory-alignment

我目前正在研究堆内存分配方案。我想在没有实际硬件的情况下检测未对齐的访问(使用 gcc )。

首先,我使用arm-none-eabi-gcc作为编译器,我的工作站是ubuntu 16.04。我尝试使用此编译器来检测未对齐的访问。

我希望以下代码在对齐方面是有效的。

int main ( int argc, char ** argv )
{
    int32_t volatile * const ptr = ( int32_t volatile * ) 0x20000000;
    *ptr = 3;
    *(ptr + 1 ) = 4;
    *(ptr + 2 ) = 5;
    *(ptr + 3 ) = 6;

    return 0;
}

但我预计以下代码在对齐方面无效。

int main ( int argc, char** argv )
{
    int32_t volatile * const ptr = ( int32_t volatile * ) 0x20000003;
    *ptr = 3;
    *(ptr + 1 ) = 4;
    *(ptr + 2 ) = 5;
    *(ptr + 3 ) = 6;

    return 0;
}

我分别使用以下几行将这些 C 代码转换为汇编代码: arm-none-eabi-gcc -O0 -o main_0.s -S ../main.c, arm-none-eabi-gcc -O0 -o main_3.s -S ../main.c

当我比较汇编代码时,这些汇编代码之间没有区别。 GCC 也不显示任何警告。

那么,为什么这些汇编代码是相同的?如何生成未对齐的访问条件?有没有办法使用 GCC 检测未对齐的访问条件?

谢谢

最佳答案

由于在 ARM 中,数据地址始终是一个寄存器值(除非您正在执行 PC 相对加载,并且在 PC 的情况下,低位是特殊的),因此程序集中没有任何内容可以区分单词负载和另一个。

未对齐访问的“问题”源于架构的实现以及处理器与其内存接口(interface)的交互。即使支持未对齐访问,速度也会变慢,因此可以将处理器配置为在运行时捕获它们。

您提供的代码将执行未对齐的访问,但这将在许多内核上运行良好。这是假设编译器没有检测到未定义的行为(显然没有)。我假设在编译示例时指针实际上以不同的方式初始化。

您可以使用 -munaligned-access 开关 see the Keil description here 启用或禁用库内未对齐访问功能的使用。 ,但所做的只是定义一个宏,而不启用任何运行时或编译时检查。

一般来说,对齐问题在运行时会像在编译时一样出现 - 为了在运行时检测它们,您将需要一个指令集模拟器(带有可以启用的陷阱)。

关于gcc - 如何生成未对齐的访问条件以及如何使用 gcc 检测它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55951714/

相关文章:

c++ - 更新 glibc 后 std::tan() 非常慢

assembly - THUMB 推/弹出指令

c - 将 sbrk 的结果分配给指针时的对齐问题 - K&R

C 未定义的行为。严格的别名规则,还是不正确的对齐方式?

c++ - 使用alignas来对齐结构体

gcc - 涉及一堆明显存在的未解析 OpenSSL 符号的错误?

c - 使用C编程打开不同的文件

c - 显式忽略来自 -Wcast-qual : cast discards ‘__attribute__((const))’ qualifier from pointer target type 的警告

android - 在 ARM 上网本 (Ubuntu) 上运行 Android SDK

linux - ARM ARM1176JZF -- JZF