gpt4 book ai didi

c - gcc:从硬件寄存器读取时 '-fno-strict-aliasing' 的奇怪行为

转载 作者:太空宇宙 更新时间:2023-11-04 02:07:37 30 4
gpt4 key购买 nike

我正在尝试使用 gdb 调试 C 程序。我使用的编译标志如下所示

-fno-strict-aliasing -Wall -DHAVE_CONFIG_H -DNO_OLD_ERF_TYPES -Werror  -Wredundant-decls -O2 -DNDEBUG -DBYTESWAP -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -g 

我使用的编译器版本是

gcc (GCC) 4.1.2 20080704 (Red Hat 4.1.2-52)
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

有争议的代码是下面这行

spm->num_streams = (uint16_t)((MkIV->stream_counts >> 16 ) & 0xfff);

num_streams 的值 with -fno-strict-aliasing

 0xffff (4095)

num_streams 的值 WITHOUT-fno-strict-aliasing

 0x1 (1)

现在值得注意的是 mkIV->stream_counts 的实际值是 0x10020。这是从 HARDWARE REGISTER 中读取的

>

我们感兴趣的值是spm->num_streamsBIT27:BIT16。因此期望值为'1'

如果我要替换

spm->num_streams = (uint16_t)((MkIV->stream_counts >> 16 ) & 0xfff);

spm->num_streams = (uint16_t)((MkIV->stream_counts & 0xfff0000) >> 16);

然后我得到 0x1(1) 的值,有和没有 -fno-strict-aliasing

MkIV结构中的stream_counts(MkIV->stream_countsuint32_t类型)

spm->num_streams is of type uint16_t

谁能解释为什么会这样?

最佳答案

您是“假设”规则的受害者。编译器不知道您正在从硬件寄存器中读取。当你写:

spm->num_streams = (uint16_t)((MkIV->stream_counts & 0xfff0000) >> 16);

编译器完全有权这样做:

uint16_t j = MkIV->stream_counts;
MkIV->stream_counts &= 0xfff0000;
MkIV->stream_counts >>= 16;
sp->num_streams = MKIV->stream_counts;
MkIV->stream_counts = j;

最有可能的是,您可以通过使 stream_counts 可变或通过可变指针“清洗”读取来解决该问题。

使用 *(volatile uint16_t *)&MkIV->stream_counts 代替 MkIV->stream_counts

关于c - gcc:从硬件寄存器读取时 '-fno-strict-aliasing' 的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18970921/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com