__asm__ volatile 之 C語言嵌入式彙編

來源:互聯網
上載者:User

在linux/include/unistd.h中定義的系統調用嵌入彙編宏函數_syscall0。

其實展開不難發現就是一個函數,只不過用宏定義了。其中關鍵的是怎麼理解 __asm__ volatile這個文法。對於__asm__ volatile這個固定形式,我們暫且不理會它(可參考http://blog.csdn.net/robbie1314/archive/2011/04/17/6329880.aspx),關鍵看懂()裡面的含義。

 

以下面這個為例子先簡要介紹一下這個用法。

插入C語言的一個組合語言程式碼片段可以分成4部分,以“:”號加以分隔,其一般形式為:

指令部:輸出部:輸入部:損壞部

 

static __inline__ void atomic_add(int i, atomic_t *v)

{

    __asm_volatile__(

               LOCK "addl %1, %0"

               : "=m" (v->counter)

               : "ir" (i), "m" (v->counter));

}

 

當組合語言代碼嵌入到C代碼時,解決運算元和C代碼中的變數結合是一個問題。我們無法確切知道gcc在嵌入點的前後會把哪個寄存器分配給哪個變數等,所以gcc採用一種方法:程式員只提供具體的指令,而對寄存器的使用則一般只提供一個“樣板”和一些約束條件,而到底如何把變數和運算元結合的問題留給gcc和gas去處理。

 

指令部

數字加上首碼%,如%1、%0等,表示需要使用寄存器的樣板運算元。可以使用的此類運算元的總數取決於具體CPU中通用寄存器的數量。

 

輸出部

規定對輸出變數,即目標運算元如何結合的約束條件。每個這樣的條件稱為一個“約束條件”。必要時輸出部可以有多個約束條件,互相以逗號分隔。每個輸出約束以“=”號開頭,然後是一個字母表示對運算元類型的說明,然後是關於變數結合的約束。例子中:

: “=m”  (v->counter)

這裡只有一個約束條件,“=m”表示相應的目標運算元(指令中的%0)是一個記憶體單元v->counter。

 

輸入部

輸入部約束的格式和輸出約束相似,但不帶“=”號。例子中:

第1個為"ir" (i),表示指令中的%1可以是一個在寄存器中的“直接運算元”(i表示immediate),並且該運算元來自於C代碼中的變數名(這裡是調用參數)i。

第2個約束條件“m” (v->counter)意義與輸入約束相同。

 

損壞部

有些操作中,除了用於輸入運算元和輸出運算元的寄存器外,還要將若干個寄存器用於計算或者操作的中間結果。這樣,這些寄存器原有的內容就損壞了,所以要在損壞部對操作的副作用加以說明,讓gcc採取相應的措施。不過,有的時候就直接把這些說明放在輸出部了,那也並無不可。

 

運算元的編號從輸出部的第一個約束(序號為0)開始,順序數下來,每個約束計數加1次。在指令部中引用這些運算元或分配用於這些運算元的寄存器時,就在序號前面加上%號。

表示約束條件的字母有很多,主要有:

"m"、"v"和"o"    ---- 表示記憶體單元

"r"                     ---- 表示任何寄存器

"q"                    ---- 表示寄存器eax,ebx,ecx,edx之一

"i"和"h"             ---- 表示直接運算元

"E"和"F"            ---- 表示浮點數

"g"                    ---- 表示任意

"a","b", "c" "d" ---- 分別表示要使用寄存器eax ebx ecx和edx

"S"和"D"            ---- 分別表示要使用寄存器esi和edi

"I"                     ---- 表示常數(0至31)

 

回到上面的例子,這段代碼的作用是將參數i的值加到v->counter上。代碼的關鍵字LOCK表示在執行addl指令時要把系統匯流排鎖住,不讓別的CPU打擾,以保證原子性操作。

 

下面就可以照著上面的說明把下面代碼看懂吧。

代碼:

/* 以下定義系統調用嵌入式彙編宏函數 */

/* 不帶參數的系統調用宏函數。type name(void)。
 * %0 -eax(__res), %1 - eax(__NR_##name)。其中name是系統調用的名稱
 * 與 __NR_ 組合形成上面的系統調用符號常用,從而用來對系統調用表中函數指標定址
 * 調用系統中斷0x80,傳回值->eax(_res), 輸入為系統中斷調用號__NR_name
 * 返回: 如果傳回值大於等於0,則返回該值,否則置出錯號errno,並返回-1
 */
#define _syscall0(type, name)/
type name(void)/
{/
    long __res;/
    __asm__ volatile ("int $0x80" /
                      : "=a" (__res) /
                      : "" (__NR_##name));/
    if (__res >= 0)/
    {/
        return (type)__res;/
    }/
    errno = -__res;/
    return -1;/
}

/* 有1個參數的系統調用宏函數。type name(atype a)
 * %0 - eax(__res), %1 - eax(__NR_name), %2 - ebx(a)
 */
#define _syscall1(type, name, atype, a) /
type name(atype a)/
{/
    long __res;/
    __asm__ volatile ("int $0x80"/
                      : "=a" (_res)/
                      : "" (__NR_#name), "b" ((long)(a)));/
    if (__res >= 0)/
    {/
        return (type)__res;/
    }/
    errno = -__res;/
    return -1;/
}

/* 有2個參數的系統調用宏函數。type name(atype a, btype b)
 * %0 - eax(__res), %1 - eax(__NR_name), %2 - ebx(a), %3 - ecx(b)
 */
#define _syscall2(type, name, atype, a, btype, b)/
type name(atype a, btype b)/
{/
    long __res;/
    __asm__ volatile ("int $0x80"/
                      : "=a" (__res)/
                      : "" (__NR_##name), "b" ((long)(a)), "c" ((long)(b)));/
    if (__res >= 0)/
    {/
        return (type)__res;/
    }/
    errno = -__res;/
    return -1/
}

/* 有3個參數的系統調用宏函數。type name(atype a, btype b, ctype c)
 * %0 - eax(__res), %1 - eax(__NR_name), %2 - ebx(a), %3 - ecx(b), %4 - edx(c)
 */
#define _syscall3(type, name, atype, a, btype, b, ctype, c) /
type name(atype a, btype b, ctype c)/
{/
    long __res;/
    __asm__ volatile ("int $0x80"/
                      : "=a" (__res) /
                      : "" (__NR_##name), "b" ((long)(a)), /
                        "c" ((long)(b)), "d" ((long)(c)));/
    if (__res >= 0)/
    {/
        return (type)__res;/
    }/
    errno = -__res;/
    return -1;/
}

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.