如何在编译器不知道的情况下更改变量的值?

How to change the value of a variable without the compiler knowing?

我想通过这个方法验证一下volatile的作用。但是我的内联汇编代码似乎无法在编译器不知情的情况下修改 i 的值。根据我看的文章,我只需要写出像 __asm { mov dword ptr [ebp-4], 20h }这样的汇编代码,我觉得我写的和他写的一样

实际输出:

before = 10
after = 123

预期输出:

before = 10
after = 10

文章link:https://www.runoob.com/w3cnote/c-volatile-keyword.html

#include <stdio.h>

int main() {
    int a, b;
    // volatile int i = 10;
    int i = 10;

    a = i;
    printf("before = %d\n", a);

    // Change the value of i in memory without letting the compiler know.
    // I can't run the following statement here, so I wrote one myself
    // mov dword ptr [ebp-4], 20h
    asm("movl 3, -12(%rbp)");

    b = i;
    printf("after = %d\n", b);
}

I want to verify the role of volatile ...

你不能。

如果一个变量不是volatile,编译器可能优化;它确实不需要这样做。

编译器可能总是将 任何 变量视为 volatile.

How to change the value of a variable without the compiler knowing?

创建第二个写入变量的线程。

例子

以下示例适用于 Linux(在 Windows 下,您需要与 pthread_create() 不同的函数):

#include <stdio.h>
#include <pthread.h>

int testVar;
volatile int waitVar;

void * otherThread(void * dummy)
{
    while(waitVar != 2) { /* Wait */ }
    testVar = 123;
    waitVar = 3;
    return NULL;
}

int main()
{
    pthread_t pt;
    waitVar = 1;
    pthread_create(&pt, 0, otherThread, NULL);
    testVar = 10;
    waitVar = 2;
    while(waitVar != 3) { /* Wait */ }
    printf("%d\n", testVar - 10);
    return 0;
}

如果您使用 gcc -O0 -o x x.c -lpthread 进行编译,编译器不会进行优化,并且像所有变量都是 volatile 一样工作。 printf() 打印 113。

如果使用 -O3 而不是 -O0 进行编译,printf() 将打印 0。

如果将 int testVar 替换为 volatile int testVarprintf() 始终打印 113(独立于 -O0/-O3)。

(使用 GCC 9.4.0 编译器测试。)