嵌入式 C 中巢狀彙編的格式

2021-06-04 11:26:37 字數 1517 閱讀 9368

在使用gcc編譯的時候,可以在c語言程式中巢狀彙編指令,這樣極大的方便在高階語言中使用跟配件相關的指令。

(1)  在gcc中巢狀的彙編指令跟純彙編檔案的語法有一點不一樣,在gcc中巢狀指令的格式是固定的:

__asm__(code : output operand list : input operand list : clobber list);

__asm__(彙編語句模板 : 輸出部分 : 輸入部分 : 破壞描述部分);

其中包括四個部分,每個部分之間使用":"分開

彙編語句模板是彙編命令的字串,

輸出部分

是需要輸出到c變數引數列表,

輸入部分

是需要從c變數輸入到asm彙編的引數列表,

破壞描述部分

是指執行彙編指令會破壞的暫存器描述。

第一部分是必須寫的,後面三部分是可以省略,但是分號":"不能省略!

例如:__asm__("cli":::);

乙個巢狀彙編塊裡面可以寫多條彙編指令,指令之間需要換行符隔開 「

\n" 或分號" 

;"隔開,如:

__asm__("mrs r0, cpsr \n" 

"orr r0, r0, #128\n" 

"msr cpsr_c, r0\n"

:

:

:);

(2)   巢狀彙編裡面可以訪問c語言所定義的變數,

可以在輸入部分,給彙編指令傳遞c語言定義的引數,也可以在輸出部分把彙編指令中得到的值傳遞到c語言所定義的變數中。

例如:  

上面**中,

%0 表示第乙個引數,

%1 表示第二個引數,依此類推,可以得到其它的引數,

這是老版本的gcc的方法了,好像只可以支援到10個引數。

新版本的是可以直接在彙編中使用引數名來訪問的,不過大部分原始碼還是使用%0的方法,這裡也只看這個方法。

-->"=r" (x), "=r" (temp)

這裡是輸出的列表,每個引數是以逗號","隔開的,

"=r"(x)表示asm中第乙個引數的值儲存到變數x中;

"=r"(temp)表示asm中第二個引數的值儲存到變數temp中.

-->如果是需要輸入引數的話,則輸入部分,把"="號去除,

unsigned long x;

__asm__ __volatile__(

"msr cpsr_c, %0 \n"

: : "r" (x)

: "memory", "cc");

上面**就是把變數x傳入到彙編指令當中去,後面的破壞描述符會告訴編譯器哪個暫存器被使用了,避免暫存器使用衝突。

(3)    "memory"描述符 表示

1.將不重新排序該段內嵌彙編指令與前面的指令。

2.不使用暫存器作為快取。

嵌入式中C和彙編的一些技巧

arm彙編部分 a.條件執行 cmp r0,5 beq bypass add r1,r1,r0 sub r1,r1,r2 bypass 可以替代為 cmp r0,5 addne r1,r1,r0 subne r1,r1,r2 如果被跳過的指令序列並不進行複雜的操作,使用條件執行都要比使用轉移好,因為...

嵌入式C中volatile和const的用法

volatile本意為 易變的 在嵌入式環境中用volatile關鍵字宣告的變數,在每次對其值進行引用的時候都會從原始位址取值,而不會將值儲存在棧或其他位置。由於該值 易變 的特性所以,針對其的任何賦值或者獲取值操作都會被執行 而不會被優化 由於這個特性,所以該關鍵字在嵌入式編譯環境中經常用來消除c...

嵌入式中C語言的位操作

位運算構建特定的二進位制數 技術公升級 使用巨集定義完成位運算 總結在操作中使用 將暫存器某些 特定位變成0,但是不影響其他位,可以進行如下操作,假設原來的暫存器reg1中的值為0xaaaaaaaa,希望將bit8 bit15清零並且其他位不進行改變,將這個數和0xffff00ff進行位與即可。re...