Closed. This question needs to be more focused。它当前不接受答案。
                            
                        
                    
                
                            
                                
                
                        
                            
                        
                    
                        
                            想改善这个问题吗?更新问题,使其仅通过editing this post专注于一个问题。
                        
                        在8个月前关闭。
                                                                                            
                
        
LPC_PINCON->PINSEL1=0x00;


我想知道程序员方法而不是嵌入式系统设计人员方法的解释。

我知道我们将PINSEL寄存器设置为0
但是在编译器的那一行中到底发生了什么呢?

最佳答案

LPC_PINCON是指向结构的指针(可能是语法上的并集,但在这种情况下更可能是结构)。结构只是数据布局。它包含各种类型的几个成员。指针的值是一个内存地址。

LPC_PINCON->表示访问结构的成员。它实际上是*.这两个操作的组合,如(*LPC_PINCON).所示,其中*表示引用指针地址处的结构,而.表示引用成员。在那个结构中。

LPC_PINCON->PINSEL1通过指定要引用的成员来完成此操作。为此,计算机将获取指针LPC_PINCON的值并向其添加PINSEL1的偏移量,即它将从结构开始到成员。 (至少,从概念上讲,这是要执行的操作。由于优化和编译的其他复杂性,实际操作可能会有所不同,但会产生同等的效果。)

然后PINSEL1将零分配给LPC_PINCON->PINSEL1=0x00成员。名义上,这里发生的是生成了一条存储指令。实际发生的情况取决于PINSEL1的类型(未显示)。可能它只是指向普通对象的指针,在这种情况下,编译器仅需要“概念上”为LPC_PINCON分配零-它可以通过各种方式优化该操作,例如将其与其他存储区组合到结构上,甚至如果可以确定完全删除它对程序的“可观察到的行为”没有影响。但是,在这种情况下,PINSEL1并非是指向LPC_PINCON对象或包含volatile成员的结构的指针。为了分配给volatile对象,(根据C标准)要求编译器生成存储指令(或任何实现定义为对实际对象的写操作)。因此,产生的代码将有效地类似于(随硬件架构和其他一些情况而变化):


获取volatile的值。
添加LPC_PINCON的偏移量。
准备一个零。
将零存储到计算出的地址。


我们可能还注意到,PINSEL1可能已设置为映射设备寄存器以显示在内存中的特定地址,而不是普通的内存地址。此外,LPC_PINCON可以是普通变量(标识符和对象),也可以是由表达式替换的某些宏。 (例如,它可能是LPC_PINCON,它以旨在用作内存地址的数字开头并将其转换为指针。)如果是这样的宏,则编译器可能会计算((volatile struct foo *) 0x1234000)的值加上LPC_PINCON在编译时的偏移量,因此生成的汇编代码将仅包含准备零的指令和存储至固定地址的指令。

关于c++ - 这条线是如何工作的? ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/56514312/

10-11 22:42