

下載本文檔
版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、_asm_ volatile_嵌匯編用法簡(jiǎn)述在閱讀 C/C+原碼時(shí)經(jīng)常會(huì)遇到內(nèi)聯(lián)匯編的情況,下面簡(jiǎn)要介紹下_asm_ volatile_嵌匯編用法。帶有 C/C+表達(dá)式的內(nèi)聯(lián)匯編格式為:_asm_ volatile_(I nstruction List : Output : In put : Clobber/Modify;其中每項(xiàng)的概念及功能用法描述如下:1、_asm_asm 是 GCC 關(guān)鍵字 asm 的宏定義:#defi ne _asm_ asm_asmasm 用來(lái)聲明一個(gè)內(nèi)聯(lián)匯編表達(dá)式,所以任何一個(gè)內(nèi)聯(lián)匯編表達(dá)式 都是以它開頭的,是必不可少的。2、Instruction ListIn s
2、tructio n List 是匯編指令序列。它可以是空的,比如: _asm_volatile_(;或_asm_ (;都是完全合法的內(nèi)聯(lián)匯編表達(dá)式,只不過(guò)這兩條語(yǔ) 句沒有什么意義。但并非所有 In structi on List 為空的內(nèi)聯(lián)匯編表達(dá)式都是沒有意義 的,比如:_asm_(:memory;就非常有意義,它向 GCC 聲明:內(nèi)存作了改動(dòng)” GCC 在編譯的時(shí)候,會(huì)將 此因素考慮進(jìn)去。當(dāng)在Instruction List中有多條指令的時(shí)候,可以在一對(duì)引號(hào)中 列出全部指令,也可以將一條 或幾條指令放在一對(duì)引號(hào)中,所有指令放在多對(duì)引 號(hào)中。如果是前者,可以將每一條指令放在一行,如果要將多條
3、指令放在一行,則 必須用分號(hào)(;)或換行符(n)將它們分開.綜上述:(1)每條指令都必須被雙 引號(hào)括起來(lái)(2 兩條指令必須用換行或分號(hào)分開。例如:在 ARM 系統(tǒng)結(jié)構(gòu)上關(guān)閉中斷的操作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 關(guān)鍵字 volatile 的宏定
4、義#defi nevolatile volatile_volatile_或 volatile 是可選的。 如果用了它, 則是向 內(nèi)聯(lián)匯編優(yōu)化,否則當(dāng) 使用了優(yōu)化選項(xiàng)(-0 進(jìn)行編譯時(shí), 斷決定是否將這個(gè)內(nèi)聯(lián)匯編表達(dá)式中的指令優(yōu)化掉。4、OutputOutput 用來(lái)指定當(dāng)前內(nèi)聯(lián)匯編語(yǔ)句的輸出GCC 聲明不允許對(duì)該GCC 將會(huì)根據(jù)自己的判例如:從 arm 協(xié)處理器 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 編譯器選擇一個(gè) R*寄存器:memory;#ifdef MMU_DEBUGprintf (p15/c1 is = %08lxn, value;#en difreturn value;5、In putIn put 域的內(nèi)容用來(lái)指定當(dāng)前內(nèi)聯(lián)匯編語(yǔ)句的輸入形如 “constraint ” (var 的列 e 表 (逗號(hào)分隔例如:向 arm 協(xié)處理器 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 編譯器選擇一個(gè) R*寄存器:memory;read_p15_c1 (;6.、Clobber/Modify有時(shí)候,你想通知 GCC 當(dāng)前內(nèi)聯(lián)匯編語(yǔ)句可能會(huì)對(duì)某些寄存器或內(nèi)存進(jìn)行修 改,希望 GCC 在編譯時(shí)能夠?qū)⑦@一點(diǎn)考慮進(jìn)去。那么你就可以在Clobber/Modify域聲明這些寄存器或內(nèi)存。這種情況一般發(fā)生在一個(gè)寄存器出現(xiàn)在I nstructio nList,但卻不是由 Input/
7、Output 操作表達(dá)式所指定的,也不是在一些Input/Output操作表達(dá)式使用r約束時(shí)由 GCC 為其選擇的,同時(shí)此寄存器被Instruction List中 的指令修改,而這個(gè)寄存器只是供當(dāng)前內(nèi)聯(lián)匯編臨時(shí)使用的情況。例如:_asm_ (mov R0, #0 x34 : : : R0;寄存器 RO 出現(xiàn)在Instruction List 中,并且被 mov 指令修改,但卻未被任何Input/Output 操作表達(dá)式指定,所以你需要在 Clobber/Modify 域指定R0,以讓 GCC知道這一點(diǎn)。因?yàn)槟阍?Input/Output 操作表達(dá)式所指定的寄存器,或當(dāng)你為 一些Input/O
8、utput 操作表達(dá)式使用r約束,讓 GCC 為你選擇一個(gè)寄存器時(shí),GCC 對(duì)這些寄存器是非常清楚的一一它知道這些寄存器是被修改的,你根本不需要在Clobber/Modify 域再聲明它們。但除此之外,GCC 對(duì)剩下的寄存器中哪些會(huì)被當(dāng)前的內(nèi)聯(lián)匯編修改一無(wú)所 知。所以如果你真的在當(dāng)前內(nèi)聯(lián)匯編指令中修改了它們,那么就最好在 Clobber/Modify 中聲明它們,讓 GCC 針對(duì)這些寄存器做相應(yīng)的處理。否則有可能 會(huì)造成寄存器的不一致,從而造成程序執(zhí)行錯(cuò)誤。如果一個(gè)內(nèi)聯(lián)匯編語(yǔ)句的Clobber/Modify 域存在memory,那么 GCC 會(huì)保證在此內(nèi)聯(lián)匯編之前,如果某個(gè) 內(nèi)存的內(nèi)容被裝入了
9、寄存器,那么在這個(gè)內(nèi)聯(lián)匯編之后,如果需要使用這個(gè)內(nèi)存處 的內(nèi)容,就會(huì)直接到這個(gè)內(nèi)存處重新讀取,而不是使用被存放在寄存器中的拷貝。 因?yàn)檫@個(gè) 時(shí)候寄存器中的拷貝已經(jīng)很可能和內(nèi)存處的內(nèi)容不一致了。這只是使用memory時(shí),GCC 會(huì)保證做到的一點(diǎn),但這并不是全部。因?yàn)槭?用memory是向 GCC 聲明內(nèi)存發(fā)生了變化,而內(nèi)存發(fā)生變化帶來(lái)的影響并不止這 一點(diǎn)。例如:int main (i nt _argc, char* _argvint* _p = (int*_argc;(*_p = 9999;_asm_(:memory;if(*_p = 9999return 5;return (*_p;本例中,如果沒有那條內(nèi)聯(lián)匯編語(yǔ)句,那個(gè)if 語(yǔ)句的判斷條件就完全是一句廢話。GCC 在優(yōu)化時(shí)會(huì)意識(shí)到這一點(diǎn),而直接只生成return 5 的匯編代碼,而不會(huì)再生成 if 語(yǔ)句的相關(guān)代碼,而不會(huì)生成 return (*_p 的相關(guān)代碼。但你加上了這條 內(nèi)聯(lián)匯編語(yǔ)句,它除了聲明內(nèi)存變化之外,什么都沒有做。但GCC 此時(shí)就不能簡(jiǎn)單的認(rèn)為它不需要判斷都知道(*_p 定與 9999 相等,它只有老老實(shí)實(shí)生成這條 if 語(yǔ)句的匯編代碼,一起相關(guān)的兩個(gè)return 語(yǔ)句
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 中國(guó)功夫美術(shù)課件
- 腫瘤免疫治療藥物作用機(jī)理
- 大單元課堂活動(dòng)設(shè)計(jì)
- 中國(guó)制度面對(duì)面課件
- 2025屆福建省漳州市龍文區(qū)龍文中學(xué)英語(yǔ)八下期中質(zhì)量檢測(cè)模擬試題含答案
- ICU患者的護(hù)理常規(guī)
- 莒縣招工作總結(jié)與計(jì)劃
- 公交機(jī)動(dòng)車運(yùn)行技術(shù)課件
- 義工服務(wù)技能培訓(xùn)
- 走好人生第一步廉政教育
- 中國(guó)石油集團(tuán)寶石管業(yè)有限公司招聘筆試題庫(kù)2025
- 2025春季學(xué)期國(guó)開河南電大專科《舞蹈與兒童舞蹈創(chuàng)編(1)-》一平臺(tái)無(wú)紙化考試(作業(yè)練習(xí)+我要考試)試題及答案
- 湖南省湘鄉(xiāng)市中考各科試卷及答案
- 留置輔警面試題目及答案
- 成人腦室外引流護(hù)理-中華護(hù)理學(xué)會(huì)團(tuán)體標(biāo)準(zhǔn)解讀
- 2025年河南省鄭州市中考二模道德與法治試題(原卷版+解析版)
- 電力系統(tǒng)電壓穩(wěn)定與無(wú)功補(bǔ)償考核試卷
- 江蘇省南通市2023-2024學(xué)年高一物理下學(xué)期6月期末考試含答案
- 2025春季學(xué)期國(guó)開河南電大??啤峨姍C(jī)拖動(dòng)應(yīng)用技術(shù)》一平臺(tái)無(wú)紙化考試(作業(yè)練習(xí)+我要考試)試題及答案
- 石料供銷合同協(xié)議
- 數(shù)值修約試題及答案
評(píng)論
0/150
提交評(píng)論