linux0 11 C嵌入彙編

2021-08-21 12:45:35 字數 1577 閱讀 8542

概述:linux核心原始碼中,有很多c語言中嵌入了彙編語句,如何理解這些彙編語句,對理解核心有很重要的作用。

具有輸入和輸出引數的嵌入式彙編語句的基本格式為:

asm("彙編語句"

:輸出暫存器

:輸入暫存器

:會被修改的暫存器);

1       #define   get_seg_byte(seg,addr)  \

2       ( )

這段**定義了乙個嵌入式組合語言函式。通常使用組合語言最方便的方法是把他們放在乙個巨集內。用圓括號括住的組合語句(花括號中的語句)「({})」可以作為表示式使用,其中最後一行的變數_res是該表示式的輸出值。

因為巨集語句需要定義在一行上,因此這裡使用反斜槓「\」將這些語句連成一行。這條紅第一將被替換到程式中引用改巨集名稱的地方。第一行定義了巨集的名稱,即巨集函式名稱get_seg_byte(seg,addr)。第三行定義了乙個暫存器變數_res。該變數將被儲存在乙個暫存器中,以便快速訪問和操作。如果想指定暫存器(如eax),那麼我們可以把改句寫成"register char _res asm("ax");",其中asm也可以寫成_asm_。第四行上的_asm_表示嵌入式彙編語句的開始。第4-7行的4條語句是at&t格式的彙編語句。另外,為了讓gcc編譯產生的組合語言程式中暫存器名稱前有乙個百分號「%」,在嵌入彙編語句暫存器名稱前就必須寫上兩個百分號「%%」。

第8行即輸出暫存器,該語句的含義是在這段**執行結束後將eax所代表的的暫存器的值放入_res變數中,作為本函式的輸出值,「=a」中的「a」稱為載入**,「=」表示這是輸出暫存器,並且其中的值將被輸出值替代。載入**是cpu暫存器,記憶體位址以及一些數值的簡寫字母代號。第9行表示在這段**開始執行時將seg放到eax暫存器中,「0」表示使用與上面相同位置上的輸出暫存器。而((*addr))表示乙個記憶體偏移位址值。為了在上面彙編語句中使用該位址值,嵌入式匯程式設計序規定把輸出和輸入暫存器按統一順序編號,順序是從輸出暫存器序列從左到右從上到下以「%0」開始,分別記為%0、%1···%9.因此,輸出暫存器的編號是%0(這裡只有乙個輸出暫存器),輸入暫存器前一部分(「0」(seg))的編號是%1,而後部分的編號是%2。上面第6行上的%2即代表(*(addr))這個記憶體偏移量。

常用暫存器載入**說明

**說明

**說明

a使用暫存器eax

m使用記憶體位址

b使用暫存器ebx

o使用記憶體位址並可以加偏移值

c使用暫存器ecx

i使用常數0-31

d使用暫存器edx

j使用常數0-63

s使用esi

k使用常數0-255

d使用edi

l使用常數0-65535

q使用動態分配位元組可定址暫存器(eax,ebx,ecx或edx)

m使用常數0-3

r使用任意動態分配的暫存器

n使用1位元組常數(0-255)

g使用通用有效的位址即可(eax,ebx,ecx,edx或記憶體變數)

o使用常數0-31

a使用eax與edx聯合(64位)

=輸出運算元,輸出值將替換前值

+表示運算元可讀可寫

&早期彙編的運算元。表示在使用完運算元之前,內容會被修改

C嵌入彙編

概述 linux核心原始碼中,有很多c語言中嵌入了彙編語句,如何理解這些彙編語句,對理解核心有很重要的作用。具有輸入和輸出引數的嵌入式彙編語句的基本格式為 asm 彙編語句 輸出暫存器 輸入暫存器 會被修改的暫存器 1 define get seg byte seg,addr 2 這段 定義了乙個嵌...

C 嵌入彙編

1.include include using namespace std int main cout 直接在watch裡面輸入暫存器的名字就可以 如,eax,ax,ah,al 3.函式呼叫,引數及返回值 具體例子 這篇中有的例子不是很好,比如第五個例子,只用暫存器就可以控制迴圈,不知道為什麼要加上...

Linux 0 11彙編的語法問題

define set tssldt desc n,addr,type asm movw 104,1 n t movw ax,2 n t rorl 16,eax n t movb al,3 n t movb type 4 n t 這裡用了 type 後面用了 0x89 type 在這裡為何要加上雙引號...