简体   繁体   English

具有递增全局变量的循环如何在没有volatile修饰符的情况下工作?

[英]How do loops with incrementing global variables work without volatile modifier?

I have been working on MSP430G2553 using using the mspgcc compiler and as an introductory program I have begun with blinking an LED. 我使用mspgcc编译器一直在研究MSP430G2553,作为一个介绍性的程序,我已经开始使用闪烁的LED。 The code that I have used is as follows: 我使用的代码如下:

#include <msp430.h> 
unsigned int i;
void main(void) 
{
    WDTCTL = WDTPW | WDTHOLD;   // Stop watchdog timer
    P1DIR |= 0x01; //Set P1.0 to output
    for(;;)
    {
        P1OUT ^= 0x01;
        i=0;
        while(i<50000)
        {
            i++;
        }
    }
}

where while loop does the work of providing delay. while循环在哪里提供延迟的工作。

I thought that since the above while loop in which i increments from 0 to a certain value, why can't I use a decrementing loop. 我认为,由于上面的while循环,其中i从0递增到某个值,为什么我不能使用递减循环。 So I tried the following code. 所以我尝试了以下代码。

#include <msp430.h> 
unsigned int i;
void main(void) 
{
    WDTCTL = WDTPW | WDTHOLD;   // Stop watchdog timer
    P1DIR |= 0x01; //Set P1.0 to output
    for(;;)
    {
        P1OUT ^= 0x01;
        i=50000
        while(i>0)
        {
            i--;
        }
    }
}

This code didn't work and on finding the reason, I came to know that the global variable i needs to be provided with "volatile" so as to prevent the optimization of compiler because here the value of i can change at any time. 这段代码没有用,在查找原因后,我开始知道全局变量i需要提供“volatile”以防止编译器的优化,因为这里i的值可以随时改变。

My question is in the first case also the value of i was changing from 0 to 49999 then why didn't we use "volatile" modifier in that case? 我的问题是在第一种情况下, i的值也从0变为49999,那么为什么我们在这种情况下不使用“volatile”修饰符呢?

The assembler code for each of the cases above is as follows: 上述每种情况的汇编代码如下:

Case 1 (Incrementing loop) 案例1(递增循环)

main:
   40B2 5A80 0120      MOV.W   #0x5a80,&Watchdog_Timer_WDTCTL
   P1DIR |= 0x01; //Set P1.0 to output
   D3D2 0022           BIS.B   #1,&Port_1_2_P1DIR
   P1OUT ^= 0x01;
$C$L1:
   E3D2 0021           XOR.B   #1,&Port_1_2_P1OUT
   i=0;
   4382 0200           CLR.W   &i
   while(i<50000)
      90B2 C350 0200      CMP.W   #0xc350,&i
      2FF8                JHS     ($C$L1)
      i++;
$C$L2:
   5392 0200           INC.W   &i
   90B2 C350 0200      CMP.W   #0xc350,&i
   2FF2                JHS     ($C$L1)
   3FF9                JMP     ($C$L2)

Case 2 (Decrementing loop) 案例2(减少循环)

main:
   40B2 5A80 0120      MOV.W   #0x5a80,&Watchdog_Timer_WDTCTL
   P1DIR |= 0x01; //Set P1.0 to output
   D3D2 0022           BIS.B   #1,&Port_1_2_P1DIR
   P1OUT ^= 0x01;
$C$L1:
   E3D2 0021           XOR.B   #1,&Port_1_2_P1OUT
   i=50000;
   40B2 C350 0200      MOV.W   #0xc350,&i
   while(i>0)
      9382 0200           TST.W   &i
      27F8                JEQ     ($C$L1)
      i--;
      4382 0200           CLR.W   &i
      3FF5                JMP     ($C$L1)

Briefly, the volatile qualifier tells the compiler an object has side-effects beyond its "vision". 简而言之, volatile限定符告诉编译器一个对象具有超出其“视觉”的副作用。 So it must not optimise out accesses to it. 所以它不能优化对它的访问。

Without this the compiler is free to optimise-out the whole loop if it can proof this will not change the observable behaviour of the program. 如果没有这个,编译器可以自由地优化掉整个循环,如果它可以证明这不会改变程序的可观察行为 Note that this is not guaranteed and in your case the compiler seems to recognise one code pattern, but not the other. 请注意,这不能得到保证,在您的情况下,编译器似乎识别出一种代码模式,而不是另一种代码模式。 But you must not rely on this (and whoever wrote that code lacks fundamental coding practice). 但是你不能依赖于这个(而且编写代码的人缺乏基本的编码实践)。

In both cases, volatile is necessary though to be on the safe side. 在这两种情况下,虽然为了安全起见,但volatile是必要的。 Note that the compiler still might be able to optimise the code; 请注意,编译器仍然可以优化代码; best is to additionally put a NOP assembler intrinsic into the loop. 最好的是另外将NOP汇编器固有地放入循环中。


Note: see the generated Assembler code. 注意:请参阅生成的汇编程序代码。 It is likely the optimised code will include something like i = 0 instead of the loop or just leave i at the default value for static variables (which is 0 , too). 优化代码可能包含类似i = 0而不是循环的东西,或者只是将i保留为静态变量的默认值(也是0 )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM