ARMC中全局变量和main中声明的变量之间的差异

ARMC中全局变量和main中声明的变量之间的差异,c,arm,global,microcontroller,keil,C,Arm,Global,Microcontroller,Keil,我一直在尝试使用Keil中的C为我的TM4C123G编写一些测试代码,它使用ARM微控制器。我对ARM汇编一无所知,但过去我为AVR微控制器编写了一些汇编代码 如果我们在C中声明变量为global,而不是在main中声明,那么存储的变量值在哪里 对于是否应该声明变量global而不是main(当为微控制器编写C时),是否有一般性的指导原则呢?Globals很好,特别是在微控制器这样的嵌入式设备中,您的资源非常紧张。Globals使管理您的资源变得容易,因为当地人非常有活力,充其量也很难避免麻烦

我一直在尝试使用
Keil
中的
C
为我的
TM4C123G
编写一些测试代码,它使用
ARM
微控制器。我对
ARM汇编
一无所知,但过去我为
AVR微控制器
编写了一些汇编代码

如果我们在C中声明变量为
global
,而不是在
main
中声明,那么存储的变量值在哪里


对于是否应该声明变量
global
而不是
main
(当为微控制器编写C时),是否有一般性的指导原则呢?

Globals很好,特别是在微控制器这样的嵌入式设备中,您的资源非常紧张。Globals使管理您的资源变得容易,因为当地人非常有活力,充其量也很难避免麻烦

但是。。。就汇编而言,并没有任何规则,也并没有真正意义上的局部与全局的概念,严格来说这是一种更高层次的语言。现在可能有一些汇编语言的实现允许/强制这样的事情,请理解C是一个跨平台的标准(和其他标准一样),并且不是特定于某个平台的。但程序集不仅没有标准,而且是特定于处理器的。汇编语言是由汇编程序(对其进行解析并将其转换为机器代码的程序)定义的。任何人和他们的兄弟都可以用汇编语言编写他们想要的任何语言或规则

通常情况下,如果您试图在汇编中手工实现C代码,而不是让编译器去做(或者不只是让编译器去做,至少看看它做了什么)。除非你的全局优化,否则你会在ram中找到一个家。局部变量可能在堆栈上占有一席之地,也可能不占有一席之地,它们可能只是暂时存在于寄存器中,取决于可用寄存器的处理器数量保留包含其他内容的寄存器与保留局部变量之间的权衡,以利于将其他内容保留在寄存器中

您应该只获取一些简单的函数(不一定是完整的程序),然后看看编译器是做什么的

如果你想用纯汇编语言编写代码,而不想转换C语言,你仍然会面临同样的困境:我是在寄存器中保存了很长一段时间,还是在这段代码中把它放在堆栈上,还是给它分配了一个永远存在的地址

我建议你开明一点,试着去理解为什么,为什么不,很多这样的规则,没有全局性,小功能等等,不是因为事实,而是因为信仰,我信任的人告诉我,所以我也这样说,不总是这样,但有时你会发现恐惧是真实的,或者恐惧不是真实的,或者也许它应用于30年前,但不再适用,等等。例如,全局的另一种选择是main()或顶层的局部,在嵌套时不断向下传递,这基本上意味着从资源的角度来看它是全局的。事实上,根据编译器(特别是一种非常流行的编译器),传递下来的一个主级本地实际上消耗了每个嵌套级的资源,消耗的ram数量远远高于刚刚声明为全局的情况。另一方面,如果不是低效的内存消耗,而是访问,谁能搞乱这个变量,谁不能,本地人让这变得很容易,相当多的懒惰,你可能会变得一团糟。必须小心全球人,不要把他们搞得一团糟。注意:从资源的角度来看,静态局部变量也是全局变量,在程序运行期间,它们位于相同的.data空间中

C不能死有一个原因,很多原因。没有任何东西可以取代它。它基本上是每个新处理器/指令集的第一个编译器,这是有原因的

写一些简单的函数,编译,反汇编,看看产生了什么。在这些平台上使用一些嵌入式/裸机应用程序,进行反汇编,看看编译器做了什么。无法优化的全局变量和静态局部变量在.data中获取地址。有时一些或所有传入参数获取堆栈位置,有时一些或所有局部变量也使用堆栈,这与编译器和优化有关(如果您选择优化)。还取决于体系结构,可以执行内存和寄存器或内存到内存操作的CISC不必总是将内容移入和移出寄存器,RISC通常需要专门使用寄存器或经常使用寄存器,但通常也有更多的可用性。因此,编译器知道这一点,并因此管理变量的主目录

每个人都会在ram中放入全局变量和静态局部变量(除非他们能够优化)。传统的x86无论如何都会在堆栈中引入参数,并且也会将局部变量放在那里,然后在那里访问它们。mips或arm将尝试最小化使用的ram量,并依赖寄存器,尝试以独占方式保留寄存器中的一些变量,而不使用堆栈

一个汇编程序员,预编译器,使用了大量等价的全局变量,为每个变量选择一个地址。现在,在编译后,您可以选择这样做设置所有变量,并且除了从调用返回之外几乎不使用堆栈,或者,您可以像编译器一样编程,制定一些规则,或者简单地遵循编译器惯例,保留一些一次性寄存器和其他寄存器,并依靠堆栈进行保存和函数项的本地

然而,在一天结束的时候,程序集并没有全局和局部的概念,就像它没有有符号和无符号的概念,指针和数组的概念一样