資源描述:
《gcc內(nèi)嵌匯編58657》由會(huì)員上傳分享,免費(fèi)在線閱讀,更多相關(guān)內(nèi)容在應(yīng)用文檔-天天文庫(kù)。
1、內(nèi)核代碼絕大部分使用C語(yǔ)言編寫(xiě),只有一小部分使用匯編語(yǔ)言編寫(xiě),例如與特定體系結(jié)構(gòu)相關(guān)的代碼和對(duì)性能影響很大的代碼。GCC提供了內(nèi)嵌匯編的功能,可以在C代碼中直接內(nèi)嵌匯編語(yǔ)言語(yǔ)句,大大方便了程序設(shè)計(jì)。一、基本內(nèi)嵌匯編GCC提供了很好的內(nèi)嵌匯編支持,最基本的格式是:__asm____volatile__(匯編語(yǔ)句模板);1、__asm____asm__是GCC關(guān)鍵字asm的宏定義:#define__asm__asm__asm__或asm用來(lái)聲明一個(gè)內(nèi)嵌匯編表達(dá)式,所以任何一個(gè)內(nèi)嵌匯編表達(dá)式都是以它開(kāi)頭的,是必不可少的。2、匯編語(yǔ)句模板“匯編
2、語(yǔ)句模板”是一組插入到C程序中的匯編指令(可以是單個(gè)指令,也可以是一組指令)。每條指令都應(yīng)該由雙引號(hào)括起,或者整組指令應(yīng)該由雙引號(hào)括起。每條指令還應(yīng)該用一個(gè)定界符結(jié)尾。有效的定界符為換行符()和分號(hào)(;)。后可以跟一個(gè)制表符(t)作為格式化符號(hào),增加GCC在匯編文件中生成的指令的可讀性。上述原則可以歸結(jié)為:①任意兩個(gè)指令間要么被分號(hào)(;)分開(kāi),要么被放在兩行;②放在兩行的方法既可以通過(guò)的方法來(lái)實(shí)現(xiàn),也可以真正的放在兩行;③可以使用一對(duì)或多對(duì)雙引號(hào),每對(duì)雙引號(hào)里可以放任意多條指令,所有的指令都必須放到雙引號(hào)中。在基本內(nèi)嵌匯編
3、中,“匯編語(yǔ)句模板”的書(shū)寫(xiě)的格式和你直接在匯編文件中使用匯編語(yǔ)言編程沒(méi)有什么不同,你可以在其中定義標(biāo)號(hào)(Label),定義對(duì)齊(.alignn),定義段(.sectionname)。例如:__asm__(".align2t""movl%eax,%ebxt""test%ebx,%ecxt""jneerrort""stit""error:popl%edit""subl%ecx,%ebx");建議大家都使用這種格式來(lái)寫(xiě)內(nèi)嵌匯編代碼。3、__volatile____volatile__是GCC關(guān)鍵字volat
4、ile的宏定義:#define__volatile__volatile__volatile__或volatile是可選的。如果不想讓GCC的優(yōu)化改動(dòng)你的內(nèi)嵌匯編代碼,你最好在前面都加上__volatile__。二、帶C語(yǔ)言表達(dá)式的內(nèi)嵌匯編在內(nèi)嵌匯編中,可以將C語(yǔ)言表達(dá)式指定為匯編指令的操作數(shù),而且不用去管如何將C語(yǔ)言表達(dá)式的值讀入哪個(gè)寄存器,以及如何將計(jì)算結(jié)果寫(xiě)回C變量,你只要告訴程序中C語(yǔ)言表達(dá)式與匯編指令操作數(shù)之間的對(duì)應(yīng)關(guān)系即可,GCC會(huì)自動(dòng)插入代碼完成必要的操作。通常嵌入到C代碼中的匯編語(yǔ)句很難做到與其它部分沒(méi)有任何關(guān)系,因此更多
5、時(shí)候需要用到擴(kuò)展的內(nèi)嵌匯編格式:__asm____volatile__(匯編語(yǔ)句模板:輸出部分:輸入部分:破壞描述部分);內(nèi)嵌匯編表達(dá)式包含4個(gè)部分,各部分由“:”分隔。這4個(gè)部分都不是必須的,任何一個(gè)部分都可以為空,其規(guī)則為:①如果“破壞描述部分”為空,則其前面的“:”必須省略。比如:__asm__("mov%%eax,%%ebx"::);。②如果“匯編語(yǔ)句模板”為空,則“輸出部分”,“輸入部分”以及“破壞描述部分”可以不為空,也可以為空。比如:__asm__("":::"memory");。③如果“輸出部分”,“輸入部分”以及“破壞
6、描述部分”都為空,“輸出部分”和“輸入部分”之前的“:”既可以省略,也可以不省略。如果都省略,則此匯編退化為一個(gè)基本內(nèi)嵌匯編,否則,仍然是一個(gè)帶有C語(yǔ)言表達(dá)式的內(nèi)嵌匯編。④如果“輸入部分”和“破壞描述部分”為空,但“輸出部分”不為空,“輸入部分”前的“:”既可以省略,也可以不省略。⑤如果后面的部分不為空,而前面的部分為空,則前面的“:”都必須保留,否則無(wú)法說(shuō)明不為空的部分究竟是第幾部分。⑥如果“破壞描述部分”不為空,而“輸出部分”和“輸入部分”都為空,則“輸出部分”和“輸入部分”前的“:”都必須保留。從上面的規(guī)則可以看到另外一個(gè)事實(shí),區(qū)
7、分一個(gè)內(nèi)嵌匯編是基本格式的還是擴(kuò)展格式的,其規(guī)則在于在“匯編語(yǔ)句模板”后面是否有“:”的存在,如果沒(méi)有則是基本格式的,否則,就是擴(kuò)展格式的。這兩種格式對(duì)寄存器語(yǔ)法的要求不同:基本格式要求寄存器前只能使用一個(gè)%,這一點(diǎn)和原生匯編相同;而擴(kuò)展格式則要求寄存器前必須使用兩個(gè)%%。比如:__asm__("mov%%eax,%%ebx":)和__asm__("mov%eax,%ebx")都是正確的寫(xiě)法,而__asm__("mov%eax,%ebx":)和__asm__("mov%%eax,%%ebx")都是錯(cuò)誤的寫(xiě)法。任何只帶一個(gè)“%”的標(biāo)識(shí)符都
8、看成是操作數(shù),而不是寄存器。1、內(nèi)嵌匯編舉例使用內(nèi)嵌匯編,要先編寫(xiě)匯編語(yǔ)句模板,然后將C語(yǔ)言表達(dá)式與指令的操作數(shù)相關(guān)聯(lián),并告訴GCC對(duì)這些操作有哪些約束條件。例如在下面的匯編語(yǔ)句:__asm__("movl