C語言內聯彙編

2021-10-24 09:14:01 字數 1900 閱讀 1504

開門見山,組合語言和c語言混合程式設計可分為兩大類:

單獨的彙編**檔案與單獨的c語言分別編譯成目標檔案後,一起鏈結成可執性檔案

在c語言中嵌入彙編**,直接編譯生成可執行程式

今天主要介紹第二種

內聯彙編稱為inline assembly, gcc支援在c**中直接嵌入彙編**,所以稱為gcc inline assembly.

內聯彙編按格式分為兩大類,一類是最簡單的基本內聯彙編,另一類是複雜一些的擴充套件內聯彙編.(內聯彙編中所用的組合語言是at&t,並不是咋們熟悉的intel語法,gcc只支援它, at&t是組合語言的一種語法風格,格式.在某一處理器平台上,無論彙編**是什麼語法,其編譯出來的**是一樣的,所以不要誤以為at&t是一種新的機器語言.它僅僅是表達方式不同,意思是一樣的)

基本內聯彙編

格式:asm[volatile] ("assembly code")

gcc有個優化選項 -o,可以指定優化級別.當用-o來編譯時,gcc按照自己的意圖優化**,說不定就會把自己所寫的**修改了. 關鍵字volatile是可選項,它告訴gcc:「不要修改我的彙編**,請原樣保留」

"assembly code"是咱們所寫的彙編**,他必須位於圓括號中,而且必須用雙引號引起來.這是格式要求,可以為空.規則:

(1) 指令必須用雙引號引起來,無論雙引號中是一條指令或多條指令

(2) 一對引號不能跨行,如果跨行需要在結尾用反斜槓\轉義

(3) 指令之間用;, 換行符\n或 換行符加製表符\n\t分隔

char *str = "hello world\n";

int count = 0;

void main()

擴充套件內聯彙編

gcc本身是個c編譯器, 要讓其支援組合語言,必然牽扯以下問題:

暫存器約束

a : %eax, %ax, %al

b : %ebx, %bx, %bl

c : %ecx, %cx, %cl

d : %edx, %dx, %dl

s : %esi, %si

d : %edi, %di

//  基本內聯彙編

int in_a = 1, in_b = 2, out_sum;

void main()

//擴充套件內聯彙編

void main()

記憶體運算元約束(memory operand constraint, m)

當我們不想通過暫存器中轉,而是直接操作記憶體時,可以用"m"來約束。例如:

asm volatile ( 「lock; decl %0」 : 「=m」 (counter) : 「m」 (counter));

立即數約束(不太常用)

通用約束

為方便對運算元的引用,擴充套件內聯彙編提供了佔位符,它的作用是代表約束指定的運算元(暫存器, 記憶體, 立即數).

佔位符分為序號佔位符和名稱佔位符兩種序號佔位符是對output和input中的運算元,按照他們從左到右出現的次序從0開始編寫.引用它的格式是%0~9

asm("addl %%ebx, %%eax" : "=a"(out_sum) : "a"(in_a), "b"(in_b));

等價於asm("addl %2, %1" : "=a"(out_sum) : "a"(in_a), "m"(in_b));

可以通過gcc -s -o filename.s filename.ccat filename.s來檢視暫存器的使用情況,你就會明白擴充套件內聯彙編的具體優異之處

Linux C語言內聯彙編使用

最近要改個c語言演算法的關鍵部分用組合語言實現,linux裡嵌入彙編基本使用at t彙編,比如linux系統的啟動部分用的就是at t彙編 以前學過at t彙編,但學過一段時間就忘了,但對intel彙編基礎比較熟悉,兩者使用方法基本相似,所以對著intel彙編,花點時間看at t彙編也就容易了。下面...

Linux C語言內聯彙編使用

最近要改個c語言演算法的關鍵部分用組合語言實現,linux裡嵌入彙編基本使用at t彙編,比如linux系統的啟動部分用的就是at t彙編 以前學過at t彙編,但學過一段時間就忘了,但對intel彙編基礎比較熟悉,兩者使用方法基本相似,所以對著intel彙編,花點時間看at t彙編也就容易了。下面...

AT T學習筆記彙編之內聯c語言

asm assembly code ansi c將asm用於其它用途,用 asm 替換 在asm後面加上 volatile可以禁止編譯器優化 asm volatile pusha n tpopa asm volatile pushl 1 n t 擴充套件asm asm asm code output...