C 访问全局变量会给出垃圾值

C 访问全局变量会给出垃圾值,c,x86,global,C,X86,Global,我试图用下面的C代码通过UART打印变量 处理器-英特尔80486 编译器-IC编译器(来自英特尔,1990年发布) UartWrite()是串行端口驱动程序。UartWrite的参数是32位的,它在内部打印每个字符 在这里,局部变量打印正确,但打印全局变量会给出垃圾值无法获取全局变量值的原因是什么。 有人能帮我吗?UartWrite原型中的参数可能不够大,无法包含全局变量的值。我没有原型,但是对于函数(毫无疑问是不同的库),参数类型是char。如果原型中也是char,那么传递unsigned

我试图用下面的C代码通过UART打印变量

处理器-英特尔80486

编译器-IC编译器(来自英特尔,1990年发布)


UartWrite()是串行端口驱动程序。UartWrite的参数是32位的,它在内部打印每个字符

在这里,局部变量打印正确,但打印全局变量会给出垃圾值无法获取全局变量值的原因是什么。 有人能帮我吗?

UartWrite原型中的参数可能不够大,无法包含全局变量的值。我没有原型,但是对于函数(毫无疑问是不同的库),参数类型是
char
。如果原型中也是
char
,那么传递
unsigned int
的值可能是问题的根源

以下说明了一种情况,即函数将接受一个大小对于原型来说太大的变量,而不会出现错误,但随后可能会产生意外的结果:

int func(char a)
{
    a = 10000;
    return a;
}

int main(void)
{
    int a = 10000;
    int b;
    b = func(a);// note int type, or 10000 does not fit into a char type
                // b is returned, but not with the expected value.
    printf("%d" b);
    return 0;
}
结果:b=-24

发布UartWrite(???)的原型

编辑(新信息)

我发现可能是您正在使用的编译器的近亲。请看第68页开始的部分:

编译单元中的每个全局符号定义或引用都有一个 可见性属性,用于控制如何(或是否)引用它 从定义它的组件外部。有五个 可见性的可能值:
•外部–编译器必须处理 符号,就好像它是在另一个组件中定义的一样。暂时 定义,这意味着编译器必须假定符号 将被中相同名称的定义覆盖(抢占) 另一个组成部分。请参阅符号优先权。如果一个功能符号 外部能见度, 编译器知道它必须被间接调用,并且可以内联调用 间接呼叫存根。
•默认值–其他组件可以参考 象征。此外,可以覆盖符号定义 (优先)由另一个组件中相同名称的定义所取代。
•受保护–其他组件可以引用符号,但不能 被另一个组件中相同名称的定义抢占。
•隐藏–其他组件不能直接引用符号。 但是,它的地址可能会间接传递给其他组件 (例如,作为调用另一个函数的参数) 组件,或通过将其地址存储在数据项引用中 另一个组件中的函数)。
•内部–符号不能为空 在其定义组件外部直接或间接引用 间接地

再向下一点例如:

int i __attribute__ ((visibility("default")));
void __attribute__ ((visibility("hidden"))) x () {...}
extern void y() __attribute__ ((visibilty("protected");  

还有很多。希望这能有所帮助。

C关键字volatile表示“某个值在不同的访问之间可能会发生变化,即使它看起来没有被修改”。试试这个,看看是否适合您。

问题在于静态初始化。因为在运行时重新初始化全局变量会给出正确的值。
谢谢Ryker、@Lundin和所有人

你尝试过其他价值观吗?如果切换全局变量和局部变量的值,是否会改变行为?如果交换写行并首先打印全局变量,会发生什么情况?如果更改这些值使全局值为0x12345678,会发生什么情况?来吧-进行一些调试。尝试一些东西,看看会发生什么,而不是毫无意义地发布两行内容:((什么是垃圾值?它总是一样的吗?交换顺序,更改值不会更改行为。全局值仍然没有正确打印。OP在帖子中没有使用此关键字,因此声明变量的值不太可能被其他进程更改。如果使用过,这(您的答案)很可能会出现这样的情况,因为每个对变量的引用都会从内存中重新加载内容,而不是从某个注册表中重新加载内容。嗨,rykker。我的意思是他应该添加此修饰符。如果不使用此修饰符,编译器可能会优化此变量的使用,因此可能会给出意外的值。是的,我在站在那里。但这真的能解决问题吗?OP没有提供一些未知数,例如UartWrite(?)的参数是什么大小(类型)如果是
char
,则传递
uint
将是一个问题。UartWrite的参数为32位,在内部打印每个字符。没有其他进程/函数访问全局变量,也没有在程序外部对其进行修改。void UartWrite(uint32_t)@Anantha-嗯,我对此感到困惑。不幸的是,我对IC编译器不够熟悉,而且我对
UartWrite()
的实现一无所知。显然,变量大小本身并不是问题的原因,因为
uint32_t
应该处理高达4294967295的值,而您的全局(您文章中两个值中较大的一个)以十进制形式显示,等于该值(2882400144)的一半多一点。我希望您在发现该解决方案时发布该解决方案。UartWrite()使用char write函数打印每个字节。IC编译器非常旧,可能在C90 std之前。问题可能与x486分段或堆栈中的局部和数据段中的全局或其他类型有关?@Anantha-32位int不太可能导致与i486分段问题相关的问题。但是,我已经为Rabbit uP编写了代码s、 还有一种初始化全局变量的特殊方法,可能在某种程度上类似于您在环境中必须执行的操作。有关详细信息,请参阅上面的“我的编辑”。(对于注释来说太详细了)问题是,初始值不包括在
int i __attribute__ ((visibility("default")));
void __attribute__ ((visibility("hidden"))) x () {...}
extern void y() __attribute__ ((visibilty("protected");