有關GCC內嵌彙編的總結

2021-07-11 14:00:11 字數 1642 閱讀 7156

在gcc中共包括兩種方法嵌入彙編,分別是:基本內聯彙編語句(basic inline asm statement)和擴充套件內聯彙編語句(extended inline asm statement)。基本內聯彙編不包括運算元(operand),而擴充套件內聯彙編語句乙個或多個運算元(operands)。

先來看看基本內聯彙編語句的形式如下:

asm("assembly code");

asm("movl %ecx %eax");

這個例子的形式非常簡單,就是將ecx的值移入eax中。通過以上例子我們可以發現,基本內聯彙編語句首先由「__asm__」或「asm」關鍵字開始,通過括號指明彙編語句的範圍,可用雙引號與\n\t的方式對彙編語句進行分隔,形式如下:

__asm__ ("movl %eax, %ebx\n\t"

"movl $56, %esi\n\t"

"movl %ecx, $label(%edx,%ebx,$4)\n\t"

"movb %ah, (%ebx)");

還可以將以上彙編語句通過「;」進行分隔,上述彙編語句還可以改寫為以下形式:

__asm__ ("movl %eax, %ebx;"

"movl $56, %esi;"

"movl %ecx, $label(%edx,%ebx,$4);"

"movb %ah, (%ebx);");

但上述彙編語句在使用過程中存在問題,乙個主要的問題就是gcc並不知道暫存器的值改變了, 特別是編譯器對**進行優化的時候. 編譯器會認為,那些存放變數的暫存器,我們並沒有改變它,然後繼續自己的優化. 為了避免這種情況, 要麼, 我們不改變暫存器的值, 要麼, 彙編函式返回之前, 還原暫存器使用前的值, 或者 等著**崩潰(wait for something to crash). 

正是由於上述問題的存在,才引出了我們接下來的主題:擴充套件內聯彙編語句

首先來看擴充套件彙編語句的形式:

asm ( assembler template   

: output operands /* optional */

: input operands /* optional */

: list of clobbered registers /* optional */

);

擴充套件彙編語句共包括四個引數,分別是彙編語句模板、輸出運算元、輸入運算元以及

被破壞暫存器的列表,其中除第乙個外,後三個均可以省略。雖然引數可以不填,位置卻要留在那(就像for迴圈那樣),乙個最簡單的擴充套件內聯彙編語句形式如下:

asm ( assembler template   

: :

:

);

通過以上形式的分析可以發現,擴充套件內聯彙編語句有些類似於函式呼叫,輸入運算元類似於函式引數,輸出運算元類似於函式返回值。

在此還要向大家提醒的一點是輸入、輸出運算元不需要加入被破壞暫存器列表。

GCC內嵌彙編

gcc內嵌彙編 限制字元 限制字元有很多種,有些是與特定體系結構相關,此處僅列出常用的限定字元和i386中可能用到的一些常用的限定符。它們的作用是指示編譯器如何處理其後的c語言變數與指令運算元之間的關係,例如是將變數放在暫存器中還是放在記憶體中等,下表列出了常用的限定字母。b 將輸入變數放入ebx ...

GCC內嵌彙編語法

內嵌彙編語法如下 asm 彙編語句模板 輸出部分 輸入部分 破壞描述部分 共四個部分 彙編語句模板,輸出部分,輸入部分,破壞描述部分,各部分使用 格開,彙編語句模板必不可少,其他三部分可選,如果使用了後面的部分,而前面部分為空,也需要用 格開,相應部分內容為空。例如 asm volatile cli...

GCC內嵌彙編學習筆記

本文主要對gcc內嵌彙編一文的簡要總結,試著用自己的話把gcc彙編的關鍵點描述出來,以驗證自己是否真正理解。本文將以 linux核心完全注釋 v3 中的乙個例子進行描述,這個例子我看的時候是非常的懵逼,直到看了gcc內嵌彙編一文。gcc內嵌彙編的基本結構 asm 彙編語句列表 輸出暫存器 輸入暫存器...