对volatile认识

对volatile认识

 

from MSDN:

The volatile keyword is a type qualifier used to declare that an object can be modified in the program by something other than statements, such as the operating system, the hardware, or a concurrently executing thread.

The following example declares a volatile integer nVint whose value can be modified by external processes:

int volatile nVint;

Objects declared as volatile are not used in optimizations because their value can change at any time. The system always reads the current value of a volatile object at the point it is requested, even if the previous instruction asked for a value from the same object. Also, the value of the object is written immediately on assignment.

One use of the volatile qualifier is to provide access to memory locations used by asynchronous processes such as interrupt handlers.

This means a value that can automatically change at any given instance. This is usually in reference to a hardware register that often has a different value ever time you read it. Specifically, it is useful to define some values as volatile so that a C compiler will not cache that value, but rather, get a fresh copy every time you request it's value. Otherwise, the compiler may return values which are inaccurate because it doesn't realized the value can change.

 

C:\tmp>type honor_volatile.c

#if !defined(VOLATILE)

#error

#endif

void test_one()

{

VOLATILE int x = 5;

}

void test_two(VOLATILE int x)

{

   x = 5;

}

 

C:\tmp>cl -O2 -c -Fa -DVOLATILE= honor_volatile.c

Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 17.00.40308 for 80x86

Copyright (C) Microsoft Corporation.  All rights reserved.

 

honor_volatile.c

 

C:\tmp>type honor_volatile.asm

; Listing generated by Microsoft (R) Optimizing Compiler Version 17.00.40308.0

 

        TITLE   C:\tmp\honor_volatile.c

        .686P

        .XMM

        include listing.inc

        .model  flat

 

INCLUDELIB LIBCMT

INCLUDELIB OLDNAMES

 

PUBLIC  _test_one

PUBLIC  _test_two

; Function compile flags: /Ogtpy

;       COMDAT _test_two

_TEXT   SEGMENT

_x$ = 8                                                 ; size = 4

_test_two PROC                                          ; COMDAT

; File c:\tmp\honor_volatile.c

; Line 15

        ret     0

_test_two ENDP

_TEXT   ENDS

; Function compile flags: /Ogtpy

;       COMDAT _test_one

_TEXT   SEGMENT

_test_one PROC                                          ; COMDAT

; File c:\tmp\honor_volatile.c

; Line 10

        ret     0

_test_one ENDP

_TEXT   ENDS

END

 

C:\tmp>cl -O2 -c -Fa -DVOLATILE=volatile honor_volatile.c

Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 17.00.40308 for 80x86

Copyright (C) Microsoft Corporation.  All rights reserved.

 

honor_volatile.c

 

C:\tmp>type honor_volatile.asm

; Listing generated by Microsoft (R) Optimizing Compiler Version 17.00.40308.0

 

        TITLE   C:\tmp\honor_volatile.c

        .686P

        .XMM

        include listing.inc

        .model  flat

 

INCLUDELIB LIBCMT

INCLUDELIB OLDNAMES

 

PUBLIC  _test_one

PUBLIC  _test_two

; Function compile flags: /Ogtpy

;       COMDAT _test_two

_TEXT   SEGMENT

_x$ = 8                                                 ; size = 4

_test_two PROC                                          ; COMDAT

; File c:\tmp\honor_volatile.c

; Line 14

        mov     DWORD PTR _x$[esp-4], 5

; Line 15

        ret     0

_test_two ENDP

_TEXT   ENDS

; Function compile flags: /Ogtpy

;       COMDAT _test_one

_TEXT   SEGMENT

_x$ = -4                                                ; size = 4

_test_one PROC                                          ; COMDAT

; File c:\tmp\honor_volatile.c

; Line 8

        push    ecx

; Line 9

        mov     DWORD PTR _x$[esp+4], 5

; Line 10

        pop     ecx

        ret     0

_test_one ENDP

_TEXT   ENDS

END

 

And this is assembly code from VS:

#include <stdio.h>
void main()
{
 volatile int i=10;
 int a = i;

 printf("i= %d\n",a);
 __asm {
  mov         dword ptr [ebp-4], 20h
 }

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

 

Release:

009C1002  in          al,dx 

009C1003  push        ecx 

009C1004  push        esi 

 volatile int i=10;

int a = i;

 

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

009C1005  mov         esi,dword ptr [__imp__printf (9C20A0h)] 

009C100B  mov         dword ptr [i],0Ah 

009C1012  mov         eax,dword ptr [i] 

009C1015  push        eax 

009C1016  push        offset string "i= %d\n" (9C20F4h) 

009C101B  call        esi 

009C101D  add         esp,8 

 __asm {

  mov         dword ptr [ebp-4], 20h

009C1020  mov         dword ptr [i],20h 

 }

 

int b = i;

009C1027  mov         eax,dword ptr [i] 

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

009C102A  push        eax 

009C102B  push        offset string "i= %d\n" (9C20F4h) 

009C1030  call        esi 

009C1032  add         esp,8 

009C1035  pop         esi 

}

009C1036  mov         esp,ebp 

009C1038  pop         ebp 

009C1039  ret 

 

 

Debug:

#include <stdio.h>

void main()

{

001B13B0  push        ebp 

001B13B1  mov         ebp,esp 

001B13B3  sub         esp,0E4h 

001B13B9  push        ebx 

001B13BA  push        esi 

001B13BB  push        edi 

001B13BC  lea         edi,[ebp-0E4h] 

001B13C2  mov         ecx,39h 

001B13C7  mov         eax,0CCCCCCCCh 

001B13CC  rep stos    dword ptr es:[edi] 

 volatile int i=10;

001B13CE  mov         dword ptr [i],0Ah 

 int a = i;

001B13D5  mov         eax,dword ptr [i] 

001B13D8  mov         dword ptr [a],eax 

 

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

001B13DB  mov         esi,esp 

001B13DD  mov         eax,dword ptr [a] 

001B13E0  push        eax 

001B13E1  push        offset string "i= %d\n" (1B573Ch) 

001B13E6  call        dword ptr [__imp__printf (1B82D4h)] 

001B13EC  add         esp,8 

001B13EF  cmp         esi,esp 

001B13F1  call        @ILT+300(__RTC_CheckEsp) (1B1131h) 

 __asm {

  mov         dword ptr [ebp-4], 20h

001B13F6  mov         dword ptr [ebp-4],20h 

 }

 

int b = i;

001B13FD  mov         eax,dword ptr [i] 

001B1400  mov         dword ptr [b],eax 

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

001B1403  mov         esi,esp 

001B1405  mov         eax,dword ptr [b] 

001B1408  push        eax 

001B1409  push        offset string "i= %d\n" (1B573Ch) 

001B140E  call        dword ptr [__imp__printf (1B82D4h)] 

001B1414  add         esp,8 

001B1417  cmp         esi,esp 

001B1419  call        @ILT+300(__RTC_CheckEsp) (1B1131h) 

}

 

C:\Temp>type meow.cpp

#include <stdio.h>

 

int main() {

    MEOW int i = 10;

    int a = i;

 

    printf("a: %d\n", a);

 

    __asm {

        mov dword ptr [ebp - 4], 20h

    }

 

    int b = i;

 

    printf("b: %d\n", b);

}

 

C:\Temp>cl /EHsc /nologo /W4 /MTd /DMEOW= meow.cpp && meow

meow.cpp

a: 10

b: 32

 

C:\Temp>cl /EHsc /nologo /W4 /MT /O2 /DMEOW= meow.cpp && meow

meow.cpp

a: 10

b: 10

 

C:\Temp>cl /EHsc /nologo /W4 /MTd /DMEOW=volatile meow.cpp && meow

meow.cpp

a: 10

b: 32

 

C:\Temp>cl /EHsc /nologo /W4 /MT /O2 /DMEOW=volatile meow.cpp && meow

meow.cpp

a: 10

b: 32

 

Volatility inhibits optimizations, as expected.

你可能感兴趣的:(对volatile认识)