

下載本文檔
版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、_asm_ volatile_嵌匯編用法簡述在閱讀 C/C+原碼時經常會遇到內聯匯編的情況,下面簡要介紹下_asm_ volatile_嵌匯編用法。帶有 C/C+表達式的內聯匯編格式為:_asm_ volatile_(I nstruction List : Output : In put : Clobber/Modify;其中每項的概念及功能用法描述如下:1、_asm_asm 是 GCC 關鍵字 asm 的宏定義:#defi ne _asm_ asm_asmasm 用來聲明一個內聯匯編表達式,所以任何一個內聯匯編表達式 都是以它開頭的,是必不可少的。2、Instruction ListIn s
2、tructio n List 是匯編指令序列。它可以是空的,比如: _asm_volatile_(;或_asm_ (;都是完全合法的內聯匯編表達式,只不過這兩條語 句沒有什么意義。但并非所有 In structi on List 為空的內聯匯編表達式都是沒有意義 的,比如:_asm_(:memory;就非常有意義,它向 GCC 聲明:內存作了改動” GCC 在編譯的時候,會將 此因素考慮進去。當在Instruction List中有多條指令的時候,可以在一對引號中 列出全部指令,也可以將一條 或幾條指令放在一對引號中,所有指令放在多對引 號中。如果是前者,可以將每一條指令放在一行,如果要將多條
3、指令放在一行,則 必須用分號(;)或換行符(n)將它們分開.綜上述:(1)每條指令都必須被雙 引號括起來(2 兩條指令必須用換行或分號分開。例如:在 ARM 系統結構上關閉中斷的操作int disablenterrupts (voidun sig ned long old,temp;_asm_ volatile_(mrs %0, cpsr norr %1, %0, #0 x80nmsr cpsr_c, %1:=r (old, =r (temp:memory;return (old & 0 x80 = 0;3.volatilevolatile_是 GCC 關鍵字 volatile 的宏定
4、義#defi nevolatile volatile_volatile_或 volatile 是可選的。 如果用了它, 則是向 內聯匯編優化,否則當 使用了優化選項(-0 進行編譯時, 斷決定是否將這個內聯匯編表達式中的指令優化掉。4、OutputOutput 用來指定當前內聯匯編語句的輸出GCC 聲明不允許對該GCC 將會根據自己的判例如:從 arm 協處理器 p15 中讀出 C1 值static un sig ned long read_p15_c1 (voidun sig ned long value;_asm_ volatile_(mrc p15, 0, %0, c1, c0, 0 r
5、ead control regn : =r (value 編譯器選擇一個 R*寄存器:memory;#ifdef MMU_DEBUGprintf (p15/c1 is = %08lxn, value;#en difreturn value;5、In putIn put 域的內容用來指定當前內聯匯編語句的輸入形如 “constraint ” (var 的列 e 表 (逗號分隔例如:向 arm 協處理器 p15 中寫入 C1 值static void write_p15_c1 (unsigned long value#ifdef MMU_DEBUGOutput 和 In put 中,格式為prin
6、tf (write %08lx to p15/c1n, value;#en dif_asm_ volatile_(mcr p15, 0, %0, c1, c0, 0 write it backn:r (value 編譯器選擇一個 R*寄存器:memory;read_p15_c1 (;6.、Clobber/Modify有時候,你想通知 GCC 當前內聯匯編語句可能會對某些寄存器或內存進行修 改,希望 GCC 在編譯時能夠將這一點考慮進去。那么你就可以在Clobber/Modify域聲明這些寄存器或內存。這種情況一般發生在一個寄存器出現在I nstructio nList,但卻不是由 Input/
7、Output 操作表達式所指定的,也不是在一些Input/Output操作表達式使用r約束時由 GCC 為其選擇的,同時此寄存器被Instruction List中 的指令修改,而這個寄存器只是供當前內聯匯編臨時使用的情況。例如:_asm_ (mov R0, #0 x34 : : : R0;寄存器 RO 出現在Instruction List 中,并且被 mov 指令修改,但卻未被任何Input/Output 操作表達式指定,所以你需要在 Clobber/Modify 域指定R0,以讓 GCC知道這一點。因為你在 Input/Output 操作表達式所指定的寄存器,或當你為 一些Input/O
8、utput 操作表達式使用r約束,讓 GCC 為你選擇一個寄存器時,GCC 對這些寄存器是非常清楚的一一它知道這些寄存器是被修改的,你根本不需要在Clobber/Modify 域再聲明它們。但除此之外,GCC 對剩下的寄存器中哪些會被當前的內聯匯編修改一無所 知。所以如果你真的在當前內聯匯編指令中修改了它們,那么就最好在 Clobber/Modify 中聲明它們,讓 GCC 針對這些寄存器做相應的處理。否則有可能 會造成寄存器的不一致,從而造成程序執行錯誤。如果一個內聯匯編語句的Clobber/Modify 域存在memory,那么 GCC 會保證在此內聯匯編之前,如果某個 內存的內容被裝入了
9、寄存器,那么在這個內聯匯編之后,如果需要使用這個內存處 的內容,就會直接到這個內存處重新讀取,而不是使用被存放在寄存器中的拷貝。 因為這個 時候寄存器中的拷貝已經很可能和內存處的內容不一致了。這只是使用memory時,GCC 會保證做到的一點,但這并不是全部。因為使 用memory是向 GCC 聲明內存發生了變化,而內存發生變化帶來的影響并不止這 一點。例如:int main (i nt _argc, char* _argvint* _p = (int*_argc;(*_p = 9999;_asm_(:memory;if(*_p = 9999return 5;return (*_p;本例中,如果沒有那條內聯匯編語句,那個if 語句的判斷條件就完全是一句廢話。GCC 在優化時會意識到這一點,而直接只生成return 5 的匯編代碼,而不會再生成 if 語句的相關代碼,而不會生成 return (*_p 的相關代碼。但你加上了這條 內聯匯編語句,它除了聲明內存變化之外,什么都沒有做。但GCC 此時就不能簡單的認為它不需要判斷都知道(*_p 定與 9999 相等,它只有老老實實生成這條 if 語句的匯編代碼,一起相關的兩個return 語句
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 手術室護理不良事件培訓
- 3.15消費者權益保護日專題活動策劃與執行
- 幼兒平衡車培訓方案
- 2025年餐飲管理專業能力考試試題及答案
- 2025年船舶工程師職業資格考試試卷及答案
- 2025年電商運營實務能力測試卷及答案
- 2025云南省初中學業水平考試數學
- 出納半年工作總結和計劃
- 口腔疾病護理知識
- 2025年湖北出租車司機上崗證考試題
- 國家開放大學法律事務??啤睹穹▽W(2)》期末紙質考試總題庫2025春期考試版
- 音箱結構優化與音質提升-洞察分析
- 大學生應急救護知到智慧樹章節測試課后答案2024年秋西安歐亞學院
- 2024年瑜伽館瑜伽課程收費標準及退費規則合同3篇
- 互聯網營銷師技能競賽理論考試題庫及答案(濃縮300題)
- 土木工程力學(本)-001-國開機考復習資料
- 機械原理課程設計 半自動鉆床說明書(完全)
- 2024-2025年江蘇專轉本英語歷年真題(含答案)
- 遼寧大學《材料力學》2021-2022學年第一學期期末試卷
- 工業5G專網構筑新質生產力發展新優勢
- 電線電纜生產常見質量問題改善與提升
評論
0/150
提交評論