volatile 的疑惑

作系统能力课设时,选题为学校采用的南京大学 ICS2018。

其中有一个地方谈到 volatile,demo 如下。

void volatile_demo () {
  extern unsigned char _end;
  volatile unsigned char *p = &_end;

  *p = 0;
  while (*p != 0xff);

  *p = 0x33;
  *p = 0x34;
  *p = 0x86;
}

维基百科一个形象的定义为:

volatile 会阻止编译器对它认为的无法“被代码本身”改变的代码进行优化。

中文维基

关于优化,参考 GCC man:

  • -O1 Optimize. Optimizing compilation takes somewhat more time, and a lot more memory for a large function.
  • -O2 Optimize even more. GCC performs nearly all supported optimizations that do not involve a space-speed tradeoff. The compiler does not perform loop unrolling or function inlining when you specify -O2. As compared to -O, this option increases both compilation time and the performance of the generated code.
  • -O3 Optimize yet more. -O3 turns on all optimizations specified by -O2 and also turns on the -finline-functions, -funswitch-loops, -fpredictive-commoning, -fgcse-after-reload and -ftree-vectorize options.
  • -O0 Reduce compilation time and make debugging produce the expected results. This is the default.
  • -Os Optimize for size. -Os enables all -O2 optimizations that do not typically increase code size. It also performs further optimizations designed to reduce code size.

对编译时加上 -O2 与不加,分别反汇编,然后通过比较汇编代码来粗略理解。

不带 -O2:

volatile-demo.o:     file format elf64-x86-64

Disassembly of section .text:

0000000000000000 <volatile_demo>:
   0:	55                   	push   %rbp
   1:	48 89 e5             	mov    %rsp,%rbp
   4:	48 8d 05 00 00 00 00 	lea    0x0(%rip),%rax        # b <volatile_demo+0xb>
   b:	48 89 45 f8          	mov    %rax,-0x8(%rbp)
   f:	48 8b 45 f8          	mov    -0x8(%rbp),%rax
  13:	c6 00 00             	movb   $0x0,(%rax)
  16:	90                   	nop
  17:	48 8b 45 f8          	mov    -0x8(%rbp),%rax
  1b:	0f b6 00             	movzbl (%rax),%eax
  1e:	3c ff                	cmp    $0xff,%al
  20:	75 f5                	jne    17 <volatile_demo+0x17>
  22:	48 8b 45 f8          	mov    -0x8(%rbp),%rax
  26:	c6 00 33             	movb   $0x33,(%rax)
  29:	48 8b 45 f8          	mov    -0x8(%rbp),%rax
  2d:	c6 00 34             	movb   $0x34,(%rax)
  30:	48 8b 45 f8          	mov    -0x8(%rbp),%rax
  34:	c6 00 86             	movb   $0x86,(%rax)
  37:	90                   	nop
  38:	5d                   	pop    %rbp
  39:	c3                   	retq

带 -O2:

volatile-demo-o2.o:     file format elf64-x86-64

Disassembly of section .text:

0000000000000000 <volatile_demo>:
   0:	48 8d 15 00 00 00 00 	lea    0x0(%rip),%rdx        # 7 <volatile_demo+0x7>
   7:	c6 05 00 00 00 00 00 	movb   $0x0,0x0(%rip)        # e <volatile_demo+0xe>
   e:	66 90                	xchg   %ax,%ax
  10:	0f b6 02             	movzbl (%rdx),%eax
  13:	3c ff                	cmp    $0xff,%al
  15:	75 f9                	jne    10 <volatile_demo+0x10>
  17:	c6 05 00 00 00 00 33 	movb   $0x33,0x0(%rip)        # 1e <volatile_demo+0x1e>
  1e:	c6 05 00 00 00 00 34 	movb   $0x34,0x0(%rip)        # 25 <volatile_demo+0x25>
  25:	c6 05 00 00 00 00 86 	movb   $0x86,0x0(%rip)        # 2c <volatile_demo+0x2c>
  2c:	c3                   	retq

参考:

  1. https://en.wikipedia.org/wiki/Volatile_(computer_programming)
  2. https://barrgroup.com/Embedded-Systems/How-To/C-Volatile-Keyword

作者: YanWen

Web 开发者

发表评论

Fill in your details below or click an icon to log in:

WordPress.com 徽标

You are commenting using your WordPress.com account. Log Out /  更改 )

Google photo

You are commenting using your Google account. Log Out /  更改 )

Twitter picture

You are commenting using your Twitter account. Log Out /  更改 )

Facebook photo

You are commenting using your Facebook account. Log Out /  更改 )

Connecting to %s