自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Linux下的匯編語言之GCC 內(nèi)聯(lián)匯編

運(yùn)維 系統(tǒng)運(yùn)維
匯編語言是基本的語言之一,他的明顯優(yōu)勢是速度快,可以直接對硬件進(jìn)行操作。Linux下如何使用匯編語言,語法格式有哪些?需要使用哪些開發(fā)工具?本文將會為大家詳細(xì)道來。

      作為最基本的編程語言之一,匯編語言雖然應(yīng)用的范圍不算很廣,但重要性卻勿庸置疑,因?yàn)樗軌蛲瓿稍S多其它語言所無法完成的功能。就拿 Linux 內(nèi)核來講,雖然絕大部分代碼是用 C 語言編寫的,但仍然不可避免地在某些關(guān)鍵地方使用了匯編代碼,其中主要是在 Linux 的啟動部分。由于這部分代碼與硬件的關(guān)系非常密切,即使是 C 語言也會有些力不從心,而匯編語言則能夠很好揚(yáng)長避短,最大限度地發(fā)揮硬件的性能。

  GCC 內(nèi)聯(lián)匯編

  用匯編編寫的程序雖然運(yùn)行速度快,但開發(fā)速度非常慢,效率也很低。如果只是想對關(guān)鍵代碼段進(jìn)行優(yōu)化,或許更好的辦法是將匯編指令嵌入到 C 語言程序中,從而充分利用高級語言和匯編語言各自的特點(diǎn)。但一般來講,在 C 代碼中嵌入?yún)R編語句要比"純粹"的匯編語言代碼復(fù)雜得多,因?yàn)樾枰鉀Q如何分配寄存器,以及如何與C代碼中的變量相結(jié)合等問題。

  GCC 提供了很好的內(nèi)聯(lián)匯編支持,最基本的格式是:

  1.   __asm__("asm statements");  

  例如:

  1.   __asm__("nop");  

  如果需要同時執(zhí)行多條匯編語句,則應(yīng)該用"\\n\\t"將各個語句分隔開,例如:

  1.   __asm__( "pushl %%eax \\n\\t"  
  2.  
  3.   "movl $0, %%eax \\n\\t"  
  4.  
  5.   "popl %eax");  

  通常嵌入到 C 代碼中的匯編語句很難做到與其它部分沒有任何關(guān)系,因此更多時候需要用到完整的內(nèi)聯(lián)匯編格式:

  1.   __asm__("asm statements" : outputs : inputs : registers-modified); 

  插入到 C 代碼中的匯編語句是以":"分隔的四個部分,其中第一部分就是匯編代碼本身,通常稱為指令部,其格式和在匯編語言中使用的格式基本相同。指令部分是必須的,而其它部分則可以根據(jù)實(shí)際情況而省略。

  在將匯編語句嵌入到C代碼中時,操作數(shù)如何與C代碼中的變量相結(jié)合是個很大的問題。GCC采用如下方法來解決這個問題:程序員提供具體的指令,而對寄存器的使用則只需給出"樣板"和約束條件就可以了,具體如何將寄存器與變量結(jié)合起來完全由GCC和GAS來負(fù)責(zé)。

  在GCC內(nèi)聯(lián)匯編語句的指令部中,加上前綴'%'的數(shù)字(如%0,%1)表示的就是需要使用寄存器的"樣板"操作數(shù)。指令部中使用了幾個樣板操作數(shù),就表明有幾個變量需要與寄存器相結(jié)合,這樣GCC和GAS在編譯和匯編時會根據(jù)后面給定的約束條件進(jìn)行恰當(dāng)?shù)奶幚?。由于樣板操作?shù)也使用'%'作為前綴,因此在涉及到具體的寄存器時,寄存器名前面應(yīng)該加上兩個'%',以免產(chǎn)生混淆。

  緊跟在指令部后面的是輸出部,是規(guī)定輸出變量如何與樣板操作數(shù)進(jìn)行結(jié)合的條件,每個條件稱為一個"約束",必要時可以包含多個約束,相互之間用逗號分隔開就可以了。每個輸出約束都以'='號開始,然后緊跟一個對操作數(shù)類型進(jìn)行說明的字后,最后是如何與變量相結(jié)合的約束。凡是與輸出部中說明的操作數(shù)相結(jié)合的寄存器或操作數(shù)本身,在執(zhí)行完嵌入的匯編代碼后均不保留執(zhí)行之前的內(nèi)容,這是GCC在調(diào)度寄存器時所使用的依據(jù)。

  輸出部后面是輸入部,輸入約束的格式和輸出約束相似,但不帶'='號。如果一個輸入約束要求使用寄存器,則GCC在預(yù)處理時就會為之分配一個寄存器,并插入必要的指令將操作數(shù)裝入該寄存器。與輸入部中說明的操作數(shù)結(jié)合的寄存器或操作數(shù)本身,在執(zhí)行完嵌入的匯編代碼后也不保留執(zhí)行之前的內(nèi)容。

  有時在進(jìn)行某些操作時,除了要用到進(jìn)行數(shù)據(jù)輸入和輸出的寄存器外,還要使用多個寄存器來保存中間計算結(jié)果,這樣就難免會破壞原有寄存器的內(nèi)容。在GCC內(nèi)聯(lián)匯編格式中的最后一個部分中,可以對將產(chǎn)生副作用的寄存器進(jìn)行說明,以便GCC能夠采用相應(yīng)的措施。

  下面是一個內(nèi)聯(lián)匯編的簡單例子:

  例4.內(nèi)聯(lián)匯編

  1.   /* inline.c */  
  2.  
  3.   int main()  
  4.  
  5.   {  
  6.  
  7.   int a = 10b = 0;  
  8.  
  9.   __asm__ __volatile__("movl %1, %%eax;\\n\\r"  
  10.  
  11.   "movl %%eax, %0;"  
  12.  
  13.   :"=r"(b) /* 輸出 */  
  14.  
  15.   :"r"(a) /* 輸入 */  
  16.  
  17.   :"%eax"); /* 不受影響的寄存器 */  
  18.  
  19.   printf("Result: %d, %d\\n", a, b);  
  20.  
  21.   } 

  上面的程序完成將變量a的值賦予變量b,有幾點(diǎn)需要說明:

  變量b是輸出操作數(shù),通過%0來引用,而變量a是輸入操作數(shù),通過%1來引用。

  輸入操作數(shù)和輸出操作數(shù)都使用r進(jìn)行約束,表示將變量a和變量b存儲在寄存器中。輸入約束和輸出約束的不同點(diǎn)在于輸出約束多一個約束修飾符'='。

  在內(nèi)聯(lián)匯編語句中使用寄存器eax時,寄存器名前應(yīng)該加兩個'%',即%%eax。內(nèi)聯(lián)匯編中使用%0、%1等來標(biāo)識變量,任何只帶一個'%'的標(biāo)識符都看成是操作數(shù),而不是寄存器。

  內(nèi)聯(lián)匯編語句的最后一個部分告訴GCC它將改變寄存器eax中的值,GCC在處理時不應(yīng)使用該寄存器來存儲任何其它的值。

  由于變量b被指定成輸出操作數(shù),當(dāng)內(nèi)聯(lián)匯編語句執(zhí)行完畢后,它所保存的值將被更新。

  在內(nèi)聯(lián)匯編中用到的操作數(shù)從輸出部的第一個約束開始編號,序號從0開始,每個約束記數(shù)一次,指令部要引用這些操作數(shù)時,只需在序號前加上'%'作為前綴就可以了。需要注意的是,內(nèi)聯(lián)匯編語句的指令部在引用一個操作數(shù)時總是將其作為32位的長字使用,但實(shí)際情況可能需要的是字或字節(jié),因此應(yīng)該在約束中指明正確的限定符:

限定符 意義
"m"、"v"、"o" 內(nèi)存單元
"r" 任何寄存器
"q" 寄存器eax、ebx、ecx、edx之一
"i"、"h" 直接操作數(shù)
"E"和"F" 浮點(diǎn)數(shù)
"g" 任意
"a"、"b"、"c"、"d" 分別表示寄存器eax、ebx、ecx和edx
"S"和"D" 寄存器esi、edi
"I"

【編輯推薦】

  1. 2.3 用匯編語言編寫程序
  2. 術(shù)語匯編 基本CSS濾鏡概述
  3. 琢石成器—Windows環(huán)境下32位匯編語言程序設(shè)計
  4. 3.1.3 as86匯編語言程序的編譯和鏈接
  5. 3.1.2 as86匯編語言程序
  6. 3.1.1 as86匯編語言語法
  7. 3.2.6 as匯編命令

 

責(zé)任編輯:zhaolei 來源: 網(wǎng)絡(luò)轉(zhuǎn)載
相關(guān)推薦

2011-01-14 14:08:17

Linux匯編語言

2011-01-14 14:22:50

Linux匯編語言

2011-01-14 14:15:11

Linux匯編語言

2011-01-14 13:44:45

Linux匯編語言

2016-09-22 09:37:14

GCC內(nèi)聯(lián)語法

2012-02-09 09:00:54

匯編語言

2021-03-25 13:05:56

網(wǎng)絡(luò)安全寄存器匯編語言

2021-06-11 10:02:39

語言編程開發(fā)

2018-01-11 14:58:40

2010-11-09 09:51:52

匯編語言

2013-01-08 11:02:26

IBMdW

2011-01-04 17:08:10

匯編語言

2023-11-23 08:25:40

開發(fā)人員SmaliAndroid

2022-10-31 14:02:24

匯編語言神經(jīng)網(wǎng)絡(luò)

2011-07-21 09:59:26

JavaScript

2023-06-01 16:27:34

匯編語言函數(shù)

2017-01-12 22:36:30

2010-06-04 17:56:22

Linux 常用工具

2010-06-13 15:35:01

2022-03-25 21:57:49

匯編Go語言
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號