彙編語言的指令格式目前有兩種不一樣的標準:Windows下的彙編語言基本上都遵循Intel風格的語法,好比:MASM、NASM,Unix/Linux下的彙編語言基本上都遵循AT&T風格的語法。 下面主要介紹Unix/Linux下的彙編,具體格式以下:express
[名稱[:]] 指令碼 源操做數SRC,目的操做數DST ;註釋函數
開發一個OS,儘管絕大部分代碼只須要用C/C++等高級語言,可是和硬件相關部分的代碼須要使用匯編語言;因爲啓動部分的代碼有大小限制,使用精練的彙編能夠縮小目標代碼的Size;另外,對於某些須要被常常調用的代碼,使用匯編能夠提升性能。
若是咱們選擇的OS開發工具是GCC以及GAS的話,就必須瞭解AT&T彙編語言語法,由於GCC/GAS只支持這種彙編語法。下面介紹GCC的內嵌彙編語法。
GCC 支持在C/C++代碼中嵌入彙編代碼,這些彙編代碼被稱做GCC Inline ASM——GCC內聯彙編。這是一個很是有用的功能,有利於咱們將一些C/C++語法沒法表達的指令直接潛入C/C++代碼中,另外也容許咱們直接寫 C/C++代碼中使用匯編編寫簡潔高效的代碼。工具
基本格式以下:性能
__asm__ [__volatile__] ( assembler template : [output operand list] /* optional */ : [input operand list] /* optional */ : [clobbered register list] /* optional */ );
(1)關鍵字「__asm__」,其實也能夠寫成「asm」。可是「asm」並非全部版本的GCC編譯器都支持的,並且有可能和程序中別的地方定義的變量或函數名衝突,因此用「__asm__」的話,兼容性會好一點。 開發工具
(2)「__volatile__」關鍵字,這個是可選的,其做用是禁止編譯器對後面編寫的彙編指令再進行優化。通常狀況下,本身寫的彙編代碼確定是本身進行設計優化過了的,若是編譯器再進行優化的話,頗有可能效果還不如不優化,並且也有可能會出現奇怪的錯誤,因此一般都會帶上這個關鍵字。一樣,「__volatile__」也能夠寫成「volatile」,但可能兼容性會沒那麼好。優化
(3)彙編代碼由4部分組成,分別是彙編代碼模板、輸出操做數列表、輸入操做數列表和修改寄存器列表,下面進行介紹。.net
1)彙編代碼模板設計
彙編代碼部分是必需的,因此即便一行彙編代碼沒有也須要傳入空字符串(""),不然會報錯。全部的彙編代碼必須用雙引號括起來。若是有多行彙編代碼的話,每一條語句都要用雙引號括起來,而且在代碼後面要加上換行符(「\n」或者「\n\t」)。這樣作是由於GCC會將彙編代碼部分做爲字符串形式直接傳給彙編器,加上換行符後,彙編器就能準確知道哪些字符串表示的是一條彙編語句。同時,爲了增長可讀性,每條彙編語句均可以換行。blog
2)輸入操做數列表與輸出操做數列表開發
前面介紹了,第二部分和第三部分分別表示輸出操做數列表和輸入操做數列表。
輸入操做數表示要做爲彙編代碼輸入的C表達式,而輸出操做數恰好相反,表示彙編代碼處理完後要輸出結果的C表達式。若是有多個輸出或輸入表達式,須要用逗號(「,」)將它們分隔開來。
能夠再前面的彙編代碼模板中直接應用定義的輸出操做數和輸入操做數,其用法是使用百分號(「%」)後面接一個數字,0表示定義的第一個操做數,1表示定義的第二個操做數,依次類推。下面舉個例子:
__asm__("mov %0, %1, ror #1" : "=r" (result) : "r" (value) );
這裏%0表明後面定義的第一個操做數,即輸出操做數,表明C語言中的result變量。%1表明定義的第二個操做數,即輸入操做數,表明C語言中的value變量。其做用是將value的值右移一位,而後保存到result中。
每個操做數由三部分組成,分別是修改符(Modifier),限定符(Constraint)和C表達式,其中修改符是可選的。具體形式以下:
"[modifier]constraint" (C expression)
修改符和限定符要用雙引號括起來,而C表達式要用括號括起來。那麼這些修改符和限定符又是什麼呢?有什麼做用呢?
咱們接下來先來講說所謂的限定符。能夠看出,操做數在這裏的做用是將C語言定義的變量與彙編語言中要使用到的變量進行一一對應。但並非全部的彙編指令均可以接受任何類型的變量做爲輸入或輸出變量的,所以彙編器須要知道這些變量到底用在什麼地方,從而幫助在傳遞以前作一些轉換。經常使用的限定符主要有如下一些,並且彙編語句究竟是ARM的仍是Thumb的,對限定符的定義也會不一樣:
參考文章 :
(1)如何在C或C++代碼中嵌入ARM彙編代碼 https://blog.csdn.net/Roland_Sun/article/details/42921131
(2)彙編與C/C++內聯嵌入彙編 https://blog.csdn.net/Levet/article/details/78516307