成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Linux下的匯編語言之GCC 內聯匯編

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

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

  GCC 內聯匯編

  用匯編編寫的程序雖然運行速度快,但開發速度非常慢,效率也很低。如果只是想對關鍵代碼段進行優化,或許更好的辦法是將匯編指令嵌入到 C 語言程序中,從而充分利用高級語言和匯編語言各自的特點。但一般來講,在 C 代碼中嵌入匯編語句要比"純粹"的匯編語言代碼復雜得多,因為需要解決如何分配寄存器,以及如何與C代碼中的變量相結合等問題。

  GCC 提供了很好的內聯匯編支持,最基本的格式是:

  1.   __asm__("asm statements");  

  例如:

  1.   __asm__("nop");  

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

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

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

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

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

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

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

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

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

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

  下面是一個內聯匯編的簡單例子:

  例4.內聯匯編

  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,有幾點需要說明:

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

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

  在內聯匯編語句中使用寄存器eax時,寄存器名前應該加兩個'%',即%%eax。內聯匯編中使用%0、%1等來標識變量,任何只帶一個'%'的標識符都看成是操作數,而不是寄存器。

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

  由于變量b被指定成輸出操作數,當內聯匯編語句執行完畢后,它所保存的值將被更新。

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

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

【編輯推薦】

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

 

責任編輯:zhaolei 來源: 網絡轉載
相關推薦

2011-01-14 14:08:17

Linux匯編語言

2011-01-14 14:15:11

Linux匯編語言

2011-01-14 14:22:50

Linux匯編語言

2011-01-14 13:44:45

Linux匯編語言

2016-09-22 09:37:14

GCC內聯語法

2012-02-09 09:00:54

匯編語言

2021-03-25 13:05:56

網絡安全寄存器匯編語言

2021-06-11 10:02:39

語言編程開發

2010-11-09 09:51:52

匯編語言

2013-01-08 11:02:26

IBMdW

2018-01-11 14:58:40

2011-01-04 17:08:10

匯編語言

2022-10-31 14:02:24

匯編語言神經網絡

2023-11-23 08:25:40

開發人員SmaliAndroid

2011-07-21 09:59:26

JavaScript

2017-01-12 22:36:30

2023-06-01 16:27:34

匯編語言函數

2010-06-04 17:56:22

Linux 常用工具

2010-06-13 15:35:01

2021-04-27 07:59:11

內聯匯編 C 語言 asm 關鍵字
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 久久99这里只有精品 | 青青草一区二区 | 日韩免费在线视频 | 秋霞影院一区二区 | 欧美日韩在线观看视频 | 久久国产综合 | 国产精品久久久 | 韩日av片| 精品一二三 | 成人免费在线观看 | 欧美电影免费观看 | 91社影院在线观看 | 久久综合av | 日韩一区二区三区视频 | 欧美一级二级视频 | 日韩a在线| 国产成人在线视频播放 | 欧美日韩亚洲成人 | 中文字幕日韩一区二区 | 国产九九九九 | 欧美在线高清 | 户外露出一区二区三区 | 91视视频在线观看入口直接观看 | 国产最新网址 | 91啪亚洲精品| 久久91精品国产 | 亚洲国产一区二区三区四区 | av中文天堂 | 国产美女黄色片 | 亚洲一区二区三区久久 | 天天干天天干 | 亚洲一区成人 | 九九免费视频 | 涩涩99| 久久精品小视频 | 久久毛片 | 欧美精品一区在线发布 | 久久久久久久久久久91 | 亚洲成人在线免费 | 成人午夜视频在线观看 | www日|