gpt4 book ai didi

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

转载 作者:太空宇宙 更新时间:2023-11-04 01:54:08 25 4
gpt4 key购买 nike

我一直在使用 mspgcc 编译器开发 MSP430G2553,作为介绍性程序,我已经开始让 LED 闪烁。我使用的代码如下:

#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++;
}
}
}

while 循环在哪里提供延迟。

我想既然上面的while循环中i是从0递增到某个值,为什么不能使用递减循环。所以我尝试了以下代码。

#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--;
}
}
}

这段代码没有运行,找到原因后,我才知道全局变量i需要提供“volatile”,以防止编译器优化,因为这里i 的值可以随时更改。

我的问题是在第一种情况下 i 的值也从 0 变为 49999 那么为什么我们在这种情况下不使用“volatile”修饰符?

上述每种情况的汇编代码如下:

案例一(递增循环)

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)

情况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)

最佳答案

简而言之,volatile 限定符告诉编译器一个对象有超出其“视野”的副作用。所以它不能优化对它的访问。

如果没有这个,编译器可以自由优化整个循环,如果它可以证明这不会改变程序的可观察行为。请注意,这不能保证,在您的情况下,编译器似乎可以识别一种代码模式,但不能识别另一种代码模式。但是您不能依赖于此(编写该代码的人都缺乏基本的编码实践)。

在这两种情况下,volatile 都是必要的,但为了安全起见。请注意,编译器仍然可以优化代码;最好的办法是在循环中另外放入一个 NOP 汇编程序。


注意:查看生成的汇编程序代码。优化后的代码很可能会包含类似 i = 0 的内容而不是循环,或者只是将 i 保留为静态变量的默认值(即 0,也是)。

关于c - 在没有 volatile 修饰符的情况下,具有递增全局变量的循环如何工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37503357/

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