最近要改個c語言演算法的關鍵部分用組合語言實現,linux裡嵌入彙編基本使用at&t彙編,比如linux系統的啟動部分用的就是at&t彙編 。以前學過at&t彙編,但學過一段時間就忘了,但對intel彙編基礎比較熟悉,兩者使用方法基本相似,所以對著intel彙編,花點時間看at&t彙編也就容易了。
下面看一下兩者的區別,然後給出linux語言中嵌入at&t彙編的具體的例子。
一、at&t彙編和intel彙編主要區別
1,兩者源和目的運算元次序相反。 at&t的源和目的是從左到右,並且其暫存器前要加「%」;intel的是右到左,不需要加"%"。
例如:at&t: movl %ecx, %eax (ecx為源運算元,eax為目的運算元)
intel: mov dx, bx (bx為源運算元,dx為目的運算元
2,at&t立即運算元前需要加"$";intel的不用
例如:at&t:movl $2, %eax
intel:mov ax, 2
3,at&t中記憶體操作的長度由操作碼最後乙個字元來確定。"b","w","l"分別表示記憶體引用為1位元組8位,2位元組16位,4位元組32位。
intel使用操作字首byte ptr, word ptr, dword ptr
例如:at&t:movl %ecx, %eax
intel:mov al, byte ptr ttt
這三點是最重要的區別,除此之外還有跳轉/呼叫時不太一樣。
二、嵌入彙編基本格式
asm("彙編語句"
"輸出暫存器"
"輸入暫存器"
"會被修改的暫存器"//告訴編譯器在執行這條__asm__語句時這裡指定的暫存器要被改寫,所以在此期間不要用這裡的暫存器儲存其它值。
)#include
unsigned int leftshift(unsigned int uinumber, unsigned char ibits)
int main(void)
[root@*** asm_study]# gcc asm.c -o app
[root@*** asm_study]# ./app
1,ret:16
以上給出乙個迴圈左移的例子,不關注迴圈左移指信rol本身,只關注at&t彙編用法。
首先定義了個暫存器變數_res,用其儲存返回值。
因為at&t彙編使用暫存器,其前面需要帶「%」,而在c語言中「%」是個特殊格式字元,所以需要兩個百分號「%%」才最終表示乙個「%」,這個和轉義字元有點類似。
:"=a"(_res)表示用暫存器eax的值輸出給_res,用%0表示此暫存器,
:"c" (ibits),"0"(uinumber),c表示輸入寄器ecx,0表示使用上面的輸出暫存器eax,所以ecx和eax分別儲存ibits和uinumber變數值。指令中的%1指暫存器ecx,所以其編號規則是從「輸出寄器」開始從左到右,從上到下進行的。
可以發現rol %1,%%eax其實可以直接寫成:rol %1, %0
三、c語言版迴圈左移
給出乙個c語言版迴圈左移**,有興趣的朋友可以和上面的彙編版進行對比。
unsigned int leftshift2(unsigned int uinumber, unsigned char ibits)
return iret;
} int main(void)
[root@*** asm_study]# gcc ori.c -o app
[root@*** asm_study]# ./app
2,ret:16
四、巨集定義版彙編
#define leftshift(uinumber, ibits) \
()和普通的彙編區別是每一行後面都要加"\",返回值寫最後,如上面最後的__res。
五、c程式轉變為匯程式設計序
1,把*.c程式轉變為at&t格式彙編*.s
[root@*** asm_study]# gcc -s asm.c -o asm.s
[root@*** asm_study]# ls -al asm.s
-rw-r--r-- 1 root root 1387 06-30 10:41 asm.s
2,把*.c程式轉變為intel格式彙編*.s
[root@*** asm_study]# gcc -masm=intel test.c -o test.s
當然,要想把c程式轉為intel彙編時,其中不能包含at&t格式的彙編,否則無法轉。
作者:rosetta
Linux C語言內聯彙編使用
最近要改個c語言演算法的關鍵部分用組合語言實現,linux裡嵌入彙編基本使用at t彙編,比如linux系統的啟動部分用的就是at t彙編 以前學過at t彙編,但學過一段時間就忘了,但對intel彙編基礎比較熟悉,兩者使用方法基本相似,所以對著intel彙編,花點時間看at t彙編也就容易了。下面...
Linux C語言內聯彙編 函式呼叫
int func int a,int b,int c,int d,int e,int x,int y,int z int main g s檢視彙編 subq 16,rsp pushq 8 pushq 7 movl 6,r9d movl 5,r8d movl 4,ecx movl 3,edx movl...
Linux C語言內聯彙編 條件跳轉
void jump 當sum的約束條件是 r 時,內聯彙編中應該初始化一下,movl 0,0 相當於初始化sum的中轉暫存器 比如下面,編譯器選擇 edx來暫存sum,如果不清零操作,其中的值是不確定的 再看看生成的.s檔案 subq 16,rsp movl 10,4 rbp movl 0,8 rb...