volalite到底有什么作用?

来源:互联网 发布:win7 php环境搭建教程 编辑:程序博客网 时间:2024/04/27 13:44

今天无意在的server发现一个小程序,不知道是谁写的。是关于test volatile。
于是对volalite产生了兴趣。我把那个变量加volatile修辞和不加volatile修辞反汇编了一下 。结果指令都是一样的。显然在那个程序里加
volatile是多余的。
volalite到底有什么作用?什么地方需要加?
我写了一段很简单的代码。来说明变量加修辞和不加修辞的区别
#include<stdlib.h>
#include<stdlib.h>
int main ()
{
      int i=1000;
      while(i>0){
              i--;
      }
      return 0;
}

我用了优化的选项反汇编以后代码如下:
main:
  pushl %ebp
  movl  %esp, %ebp  (设置堆栈基指针和堆栈)
  subl  $8, %esp   
  andl  $-16, %esp
  movl  $1000, %eax (把1000值放到eax寄存器里)
  .p2align 2,,3     (优化)
.L5:
  decl  %eax     (把寄存器里的值递减)
  testl %eax, %eax  (测试0)
  jg  .L5             (跳转如果大于0,到L5继续)
  xorl  %eax, %eax   (否则,exa=0,返回)
  leave        
  ret
 
  每次都从eax寄存器里取,但是这个时候
  如果i的变量别的进程修改。但是这个循环里感觉不出来。
 
  当在i前面加了volatile的时候 ,这说明这个i变量是可变的。汇编代码如下:
  main:
  pushl %ebp
  movl  %esp, %ebp
  subl  $8, %esp
  movl  $1000, -4(%ebp)  (把1000放到堆栈上,相对ebp指针4个字节)
  movl  -4(%ebp), %eax    (把这个值放到eax寄存器里)
  andl  $-16, %esp
  testl %eax, %eax    (测试0)
  jle .L7       (如果小于,等于 0,跳转到L7,推出)
  .p2align 2,,3
.L5:          (否则)
  movl  -4(%ebp), %eax  (相对ebp指针4个字节位置的值放到eax里面,也就是1000)
  decl  %eax        (把寄存器里的值递减)
  movl  %eax, -4(%ebp)     (把递减过的值在放到原来的位置)
  movl  -4(%ebp), %eax   (把这值放到eax里)
  testl %eax, %eax   
  jg  .L5       (大于0,跳转到L5继续)
.L7:
  xorl  %eax, %eax
  leave
  ret
 
  很明显当i加修辞volatile的时候,等于告诉编译器,这个值是可变的,有可能别的地方修改。所以
  以后所有用到这个值的地方,都会想这个值的地址里从新取值,以保持它的新鲜。
  上个列子,每次递减的时候,都要从-4(%ebp)这个地址里取值。而不是像没有加volatile的时候,每次都从eax寄存器里取

 
原创粉丝点击