1. 程式人生 > >GCC內聯彙編(INLINE ASSEMBLY) 轉

GCC內聯彙編(INLINE ASSEMBLY) 轉

GCC內聯彙編(INLINE ASSEMBLY)   什麼是內聯彙編(Inline assembly)?

1、這是GCC對C語言的擴張,就是在C程式碼裡面去寫彙編程式碼

2、可以直接在C的語句中插入彙編指令

有何用處?

1、C語言不足以完成所有CPU的指令, 特別是有一些特權指令,比如載入gdt表(Global Descriptor Table 全域性描述符表),從而使用匯編程式碼來完成

2、用匯編在C語言中手動優化,特別是在作業系統當中,使用匯編對作業系統的掌控更為精準,更加準確。

如何工作?

1、用給定的模板和約束來生成彙編指令

2、才C函式內形成彙編程式碼

下面一個小例子,簡單看一下彙編程式碼和內聯彙編的不同:

GCC內聯彙編-Example 1

彙編程式碼 Assembly(*.S):

movl $0xffff, %eax //把0xffff給eax

內聯彙編 Inline assembly(*.c):

asm(“movl $0xffff, %%eax\n”) //1、加了一個內聯彙編關鍵字asm,把彙編程式碼括起來然後用引號表示一個字串 2、暫存器前變為%%

GCC內聯彙編-語法   asm(“assmbler template” //assmbler template就是example 1 的那個字串的內容(彙編語句)

:output operands (optional)  //可選的輸出運算元(輸出暫存器)

:input operands (optional)  //可選的輸入運算元(輸入暫存器)

:clobbers (optional)  //會被修改的暫存器

);

GCC內聯彙編-Example2 Inline assembly(*.c)

uint32_t cr0;                  //一個叫cr0的變數

asm volatile(“movl %%cr0, %0\n” :"=r"(cr0));   //把cr0裡面的內容讀到%0這個暫存器當中, =r這個暫存器的內容會賦給cr0這個變數(輸出操作)

cr0 |= 0x80000000;              //把某一個位設成1

asm volatile(“movl %0, %%cr0\n” ::“r”(cr0));   //再把cr0變數裡的內容寫回到cr0暫存器當中。把cr0給一個暫存器,然後這個暫存器再把他裡面的內容賦給cr0暫存器(輸入操作)

一些關鍵字的含義

volatile:No reordering; No elimination. 不需要進一步的優化,不需要進一步的調整順序

%0  :The first constraint following. 第一個用到的暫存器

r    :A constraint; GCC is free to use any register. 任意一個暫存器

上面的內聯彙編所對應的彙編程式碼如下

Generated assembly code(*.s):

movl %cr0, %ebx //cr0 --> ebx

movl %ebx, 12(%esp) //ebx賦給一個區域性變數12(%esp)

orl $-2147483648, 12(%esp) //或操作

movl 12(%esp), %eax //再給eax

movl %eax, %cr0        //再把eax暫存器裡面的內容賦給cr0

GCC內聯彙編-Example3 Inline assembly(*.c)

long _res, arg1 = 2, arg2 = 22, arg3 = 222, arg4 = 233;

_asm_volatile(“int $0x80”

:"=a"(_res)

:“0”(11), “b”(arg1), “c”(arg2), “d”(arg3), “S”(arg4)); //把arg1給ebx, arg2給ecx,arg3給edx, arg4給esi

在內聯彙編當中

a = %eax, b = %ebx, c = %ecx, d = %edx, S = %esi, D = %edi, 0 = same as the first 第一個出現的暫存器

Generated assembly code(*.s):

mov $11, %eax

movl-28(%ebp), %ebx

movl-24(%ebp), %ecx

movl-20(%ebp), %edx

movl-16(%ebp), %esi

int $0x80

movl %edi, -12(%ebp)

如果想要了解GCC內聯彙編更多的知識,請訪問