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

Time:04-04

I want to verify the role of volatile by this method. But my inline assembly code doesn't seem to be able to modify the value of i without the compiler knowing. According to the articles I read, I only need to write assembly code like __asm { mov dword ptr [ebp-4], 20h }, I think I write the same as what he did.

actual output:

before = 10
after = 123

expected output:

before = 10
after = 10

Article 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 $123, -12(%rbp)");

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

CodePudding user response:

I want to verify the role of volatile ...

You can't.

If a variable is not volatile, the compiler may optimize; it does not need to do this.

A compiler may always treat any variable as volatile.

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

Create a second thread writing to the variable.

Example

The following example is for Linux (under Windows, you need a different function than 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;
}

If you compile with gcc -O0 -o x x.c -lpthread, the compiler does not optimize and works like all variables are volatile. printf() prints 113.

If you compile with -O3 instead of -O0, printf() prints 0.

If you replace int testVar by volatile int testVar, printf() always prints 113 (independent of -O0/-O3).

(Tested with the GCC 9.4.0 compiler.)

  • Related