關於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
.type main, %function
main:
@ Function supports interworking.
@ args = 0, pretend = 0, frame = 16
@ frame_needed = 1, uses_anonymous_args = 0
@ link register save eliminated.
str fp, [sp, #-4]!
add fp, sp, #0
sub sp, sp, #20
mov r3, #10
str r3, [fp, #-16]    #[fp, #-16]即代表c代碼中的變量n;
mov r3, #20
str r3, [fp, #-16]   #注意,觀察前2行,這裏沒有對“沒加關鍵字volatile的指針p”的任何操作;
ldr r3, [fp, #-8]   #[fp, #-8]即指的是指針r的值;
ldr r3, [r3, #0]   #這裏將指針所指的內存讀到了r3,即“r3 = *r”;
mov r3, #30     #注意,觀察前2行,這裏對加關鍵字volatile的指針r”的有讀操作;
str r3, [fp, #-16]
add sp, fp, #0
ldmfd sp!, {fp}
bx lr
.size main, .-main
.ident "GCC: (ctng-1.6.1) 4.4.3"
.section .note.GNU-stack,"",%progbits


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

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

發佈了35 篇原創文章 · 獲贊 26 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章