1. 程式人生 > >關於volatile關鍵字的用法,從彙編透視C語法操作

關於volatile關鍵字的用法,從彙編透視C語法操作

看一個簡單的c程式,p是沒加關鍵字volatile的int型指標,r是加關鍵字volatile的int型指標。

//main.c

#include <stdio.h>

void main(void)
{
int n;
int *p;
volatile int *r;   //注意,這裡加了volatile關鍵字
n=10;
*p;
n=20;
*r;
n=30;
}

看看彙編過程(arm-linux-gcc -S main.c -o main.s ):

//main.s

.arch armv4t
.fpu softvfp
.eabi_attribute 20, 1
.eabi_attribute 21, 1
.eabi_attribute 23, 3
.eabi_attribute 24, 1
.eabi_attribute 25, 1
.eabi_attribute 26, 2
.eabi_attribute 30, 6
.eabi_attribute 18, 4
.file"main.c"
.text
.align 2
.global main
.typemain, %function
main:
@ Function supports interworking.
@ args = 0, pretend = 0, frame = 16
@ frame_needed = 1, uses_anonymous_args = 0
@ link register save eliminated.
strfp, [sp, #-4]!
addfp, sp, #0
subsp, sp, #20
movr3, #10
strr3, [fp, #-16]    #[fp, #-16]即代表c程式碼中的變數n;
movr3, #20
strr3, [fp, #-16]   #注意,觀察前2行,這裡沒有對“沒加關鍵字volatile的指標p”的任何操作;
ldrr3, [fp, #-8]   #[fp, #-8]即指的是指標r的值;
ldrr3, [r3, #0]   #這裡將指標所指的記憶體讀到了r3,即“r3 = *r”;
movr3, #30     #注意,觀察前2行,這裡對加關鍵字volatile的指標r”的有讀操作;
strr3, [fp, #-16]
addsp, fp, #0
ldmfdsp!, {fp}
bxlr
.sizemain, .-main
.ident "GCC: (ctng-1.6.1) 4.4.3"
.section .note.GNU-stack,"",%progbits

從這裡,可以看出,有加關鍵字和沒加關鍵字volatile的區別。例如在讀取狀態標誌位(讀取後狀態標誌位自動“清除”),以上的兩個指標操作就會有不同。

volatile 告訴編譯器*r是隨時可能發生變化的,每次使用它的時候必須從*r的地址中讀取,因而編譯器生成的可執行碼會重新從*r的地址讀取資料。有無volatile對IO口操作,共享記憶體操作等也是有影響的。這裡不多說了。