日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
內(nèi)聯(lián)匯編很可怕嗎?看完這篇文章,終結(jié)它!

在 Linux 代碼中,經(jīng)??梢钥吹皆?C 代碼中,嵌入部分匯編代碼,這些代碼要么是與硬件體系相關(guān)的,要么是對性能有關(guān)鍵影響的。

創(chuàng)新互聯(lián)公司是一家專注于網(wǎng)站建設(shè)、網(wǎng)站設(shè)計(jì)與策劃設(shè)計(jì),浦城網(wǎng)站建設(shè)哪家好?創(chuàng)新互聯(lián)公司做網(wǎng)站,專注于網(wǎng)站建設(shè)10年,網(wǎng)設(shè)計(jì)領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:浦城等地區(qū)。浦城做網(wǎng)站價(jià)格咨詢:18980820575

在很久以前,我特別懼怕內(nèi)嵌匯編代碼,直到后來把匯編部分的短板補(bǔ)上之后,才徹底終結(jié)這種心理。

也許你在工作中,幾乎不會涉及到內(nèi)嵌匯編代碼的工作,但是一旦進(jìn)入到系統(tǒng)的底層,或者需要對時(shí)間關(guān)鍵場景進(jìn)行優(yōu)化,這個(gè)時(shí)候你的知識儲備就發(fā)揮重要作用了!

這篇文章,我們就來詳細(xì)聊一聊在 C 語言中,如何通過 asm 關(guān)鍵字來嵌入?yún)R編語言代碼,文中的 8 個(gè)示例代碼從簡單到復(fù)雜,逐步深入地介紹內(nèi)聯(lián)匯編的關(guān)鍵語法規(guī)則。

希望這篇文章能夠成為你進(jìn)階高手路上的墊腳石!

PS:

  1. 示例代碼中使用的是 Linux 系統(tǒng)中 AT&T 匯編語法;
  2. 文章中的 8 個(gè)示例代碼,可以在公眾號后臺回復(fù)【426】,即可收到下載地址;

一、基本 asm 格式

  1. gcc 編譯器支持 2 種形式的內(nèi)聯(lián) asm 代碼:
  2. 基本 asm 格式:不支持操作數(shù);

擴(kuò)展 asm 格式:支持操作數(shù);

1. 語法規(guī)則

asm [volatile] ("匯編指令")

  1. 所有指令,必須用雙引號包裹起來;
  2. 超過一條指令,必須用\n分隔符進(jìn)行分割,為了排版,一般會加上\t;
  3. 多條匯編指令,可以寫在一行,也可以寫在多行;
  4. 關(guān)鍵字 asm 可以使用 asm 來替換;
  5. volatile 是可選的,編譯器有可能對匯編代碼進(jìn)行優(yōu)化,使用 volatile 關(guān)鍵字之后,告訴編譯器不要優(yōu)化手寫的內(nèi)聯(lián)匯編代碼。

2. test1.c 插入空指令

 
 
 
 
  1. #include 
  2. int main()
  3. {
  4.     asm ("nop");
  5.     printf("hello\n");
  6.     asm ("nop\n\tnop\n\t"
  7.      "nop");
  8.     return 0;
  9. }

注意:C語言中會自動(dòng)把兩個(gè)連續(xù)的字符串字面量拼接成一個(gè),所以"nop\n\tnop\n\t" "nop"這兩個(gè)字符串會自動(dòng)拼接成一個(gè)字符串。

生成匯編代碼指令:

 
 
 
 
  1. gcc -m32 -S -o test1.s test1.c

test1.s 中內(nèi)容如下(只貼出了內(nèi)聯(lián)匯編代碼相關(guān)部分的代碼):

 
 
 
 
  1. #APP
  2. # 5 "test1.c" 1
  3.     nop
  4. # 0 "" 2
  5. #NO_APP
  6.     // 這里是 printf 語句生成的代碼。
  7. #APP
  8. # 7 "test1.c" 1
  9.     nop
  10.     nop
  11.     nop
  12. # 0 "" 2
  13. #NO_APP

可以看到,內(nèi)聯(lián)匯編代碼被兩個(gè)注釋(#APP ... #NO_APP)包裹起來。在源碼中嵌入了兩個(gè)匯編代碼,因此可以看到 gcc 編譯器生成的匯編代碼中包含了這兩部分代碼。

這 2 部分嵌入的匯編代碼都是空指令 nop,沒有什么意義。

3. test2.c 操作全局變量

在 C 代碼中嵌入?yún)R編指令,目的是用來計(jì)算,或者執(zhí)行一定的功能,下面我們就來看一下,如何在內(nèi)聯(lián)匯編指令中,操作全局變量。

 
 
 
 
  1. #include 
  2. int a = 1;
  3. int b = 2;
  4. int c;
  5. int main()
  6. {
  7.     asm volatile ("movl a, %eax\n\t"
  8.         "addl b, %eax\n\t"
  9.         "movl %eax, c");
  10.     printf("c = %d \n", c);
  11.     return 0;
  12. }

關(guān)于匯編指令中編譯器的基本知識:

eax, ebx 都是 x86 平臺中的寄存器(32位),在基本asm格式中,寄存器的前面必須加上百分號%。

32 位的寄存器 eax 可以當(dāng)做 16 位來使用(ax),或者當(dāng)做 8 位來使用(ah, al),本文只會按照 32 位來使用。

代碼說明:

  • movl a, %eax  // 把變量a的值復(fù)制到 %eax 寄存器中;
  • addl b, %eax // 把變量 b 的值 與 %eax 寄存器中的值(a)相加,結(jié)果放在 %eax 寄存器中;
  • movl %eax, c // 把 %eax 寄存器中的值復(fù)制到變量 c 中;

生成匯編代碼指令:

 
 
 
 
  1. gcc -m32 -S -o test2.s test2.c

test2.s 內(nèi)容如下(只貼出與內(nèi)聯(lián)匯編代碼相關(guān)部分):

 
 
 
 
  1. #APP
  2. # 9 "test2.c" 1
  3.     movl a, %eax
  4.     addl b, %eax
  5.     movl %eax, c
  6. # 0 "" 2
  7. #NO_APP

可以看到,在內(nèi)聯(lián)匯編代碼中,可以直接使用全局變量 a, b 的名稱來操作。執(zhí)行 test2,可以得到正確的結(jié)果。

思考一個(gè)問題:為什么在匯編代碼中,可以使用變量a, b, c?

查看 test2.s 中內(nèi)聯(lián)匯編代碼之前的部分,可以看到:

 
 
 
 
  1.     .file   "test2.c"
  2.     .globl  a
  3.     .data
  4.     .align 4
  5.     .type   a, @object
  6.     .size   a, 4
  7. a:
  8.     .long   1
  9.     .globl  b
  10.     .align 4
  11.     .type   b, @object
  12.     .size   b, 4
  13. b:
  14.     .long   2
  15.     .comm   c,4,4

變量 a, b 被 .globl 修飾,c 被 .comm 修飾,相當(dāng)于是把它們導(dǎo)出為全局的,所以可以在匯編代碼中使用。

那么問題來了:如果是一個(gè)局部變量,在匯編代代碼中就不會用 .globl 導(dǎo)出,此時(shí)在內(nèi)聯(lián)匯編指令中,還可以直接使用嗎?

眼見為實(shí),我們把這 3 個(gè)變量放到 main 函數(shù)的內(nèi)部,作為局部變量來試一下。

4. test3.c 嘗試操作局部變量

 
 
 
 
  1. #include 
  2. int main()
  3. {
  4.     int a = 1;
  5.     int b = 2;
  6.     int c;
  7.     asm("movl a, %eax\n\t"
  8.         "addl b, %eax\n\t"
  9.         "movl %eax, c");
  10.     printf("c = %d \n", c);
  11.     return 0;
  12. }

生成匯編代碼指令:

 
 
 
 
  1. gcc -m32 -S -o test3.s test3.c

在 test3.s 中可以看到?jīng)]有 a, b, c 的導(dǎo)出符號,a 和 b 沒有其他地方使用,因此直接把他們的數(shù)值復(fù)制到??臻g中了:

 
 
 
 
  1. movl    $1, -20(%ebp)
  2. movl    $2, -16(%ebp)

我們來嘗試編譯成可執(zhí)行程序:

 
 
 
 
  1. $ gcc -m32 -o test3 test3.c
  2. /tmp/ccuY0TOB.o: In function `main':
  3. test3.c:(.text+0x20): undefined reference to `a'
  4. test3.c:(.text+0x26): undefined reference to `b'
  5. test3.c:(.text+0x2b): undefined reference to `c'
  6. collect2: error: ld returned 1 exit status

編譯報(bào)錯(cuò):找不到對 a,b,c 的引用!那該怎么辦,才能使用局部變量呢?擴(kuò)展 asm 格式!

二、擴(kuò)展 asm 格式

1. 指令格式

asm [volatile] ("匯編指令" : "輸出操作數(shù)列表" : "輸入操作數(shù)列表" : "改動(dòng)的寄存器")

格式說明

  1. 匯編指令:與基本asm格式相同;
  2. 輸出操作數(shù)列表:匯編代碼如何把處理結(jié)果傳遞到 C 代碼中;
  3. 輸入操作數(shù)列表:C 代碼如何把數(shù)據(jù)傳遞給內(nèi)聯(lián)匯編代碼;
  4. 改動(dòng)的寄存器:告訴編譯器,在內(nèi)聯(lián)匯編代碼中,我們使用了哪些寄存器;
  5. “改動(dòng)的寄存器”可以省略,此時(shí)最后一個(gè)冒號可以不要,但是前面的冒號必須保留,即使輸出/輸入操作數(shù)列表為空。

關(guān)于“改動(dòng)的寄存器”再解釋一下:gcc 在編譯 C 代碼的時(shí)候,需要使用一系列寄存器;我們手寫的內(nèi)聯(lián)匯編代碼中,也使用了一些寄存器。

為了通知編譯器,讓它知道: 在內(nèi)聯(lián)匯編代碼中有哪些寄存器被我們用戶使用了,可以在這里列舉出來,這樣的話,gcc 就會避免使用這些列舉出的寄存器

2. 輸出和輸入操作數(shù)列表的格式

在系統(tǒng)中,存儲變量的地方就2個(gè):寄存器和內(nèi)存。因此,告訴內(nèi)聯(lián)匯編代碼輸出和輸入操作數(shù),其實(shí)就是告訴它:

  1. 向哪些寄存器或內(nèi)存地址輸出結(jié)果;
  2. 從哪些寄存器或內(nèi)存地址讀取輸入數(shù)據(jù);

這個(gè)過程也要滿足一定的格式:

"[輸出修飾符]約束"(寄存器或內(nèi)存地址)

(1)約束

就是通過不同的字符,來告訴編譯器使用哪些寄存器,或者內(nèi)存地址。包括下面這些字符:

  • a: 使用 eax/ax/al 寄存器;
  • b: 使用 ebx/bx/bl 寄存器;
  • c: 使用 ecx/cx/cl 寄存器;
  • d: 使用 edx/dx/dl 寄存器;
  • r: 使用任何可用的通用寄存器;
  • m: 使用變量的內(nèi)存位置;

先記住這幾個(gè)就夠用了,其他的約束選項(xiàng)還有:D, S, q, A, f, t, u等等,需要的時(shí)候再查看文檔。

(2)輸出修飾符

顧名思義,它使用來修飾輸出的,對輸出寄存器或內(nèi)存地址提供額外的說明,包括下面4個(gè)修飾符:

  1. +:被修飾的操作數(shù)可以讀取,可以寫入;
  2. =:被修飾的操作數(shù)只能寫入;
  3. %:被修飾的操作數(shù)可以和下一個(gè)操作數(shù)互換;
  4. &:在內(nèi)聯(lián)函數(shù)完成之前,可以刪除或者重新使用被修飾的操作數(shù);

語言描述比較抽象,直接看例子!

3. test4.c 通過寄存器操作局部變量

 
 
 
 
  1. #include 
  2. int main()
  3. {
  4.     int data1 = 1;
  5.     int data2 = 2;
  6.     int data3;
  7.     asm("movl %%ebx, %%eax\n\t"
  8.         "addl %%ecx, %%eax"
  9.         : "=a"(data3)
  10.         : "b"(data1),"c"(data2));
  11.     printf("data3 = %d \n", data3);
  12.     return 0;
  13. }

有 2 個(gè)地方需要注意一下?。?/p>

  1. 在內(nèi)聯(lián)匯編代碼中,沒有聲明“改動(dòng)的寄存器”列表,也就是說可以省略掉(前面的冒號也不需要);
  2. 擴(kuò)展asm格式中,寄存器前面必須寫 2 個(gè)%;

代碼解釋:

  1. "b"(data1),"c"(data2) ==> 把變量 data1 復(fù)制到寄存器 %ebx,變量 data2 復(fù)制到寄存器 %ecx。這樣,內(nèi)聯(lián)匯編代碼中,就可以通過這兩個(gè)寄存器來操作這兩個(gè)數(shù)了;
  2. "=a"(data3) ==> 把處理結(jié)果放在寄存器 %eax 中,然后復(fù)制給變量data3。前面的修飾符等號意思是:會寫入往 %eax 中寫入數(shù)據(jù),不會從中讀取數(shù)據(jù);

通過上面的這種格式,內(nèi)聯(lián)匯編代碼中,就可以使用指定的寄存器來操作局部變量了,稍后將會看到局部變量是如何從經(jīng)過??臻g,復(fù)制到寄存器中的。

生成匯編代碼指令:

 
 
 
 
  1. gcc -m32 -S -o test4.s test4.c

匯編代碼 test4.s 如下:

 
 
 
 
  1.     movl    $1, -20(%ebp)
  2.     movl    $2, -16(%ebp)
  3.     movl    -20(%ebp), %eax
  4.     movl    -16(%ebp), %edx
  5.     movl    %eax, %ebx
  6.     movl    %edx, %ecx
  7. #APP
  8. # 10 "test4.c" 1
  9.     movl %ebx, %eax
  10.     addl %ecx, %eax
  11. # 0 "" 2
  12. #NO_APP
  13.     movl    %eax, -12(%ebp)

可以看到,在進(jìn)入手寫的內(nèi)聯(lián)匯編代碼之前:

  1. 把數(shù)字 1 通過??臻g(-20(%ebp)),復(fù)制到寄存器 %eax,再復(fù)制到寄存器 %ebx;
  2. 把數(shù)字 2 通過??臻g(-16(%ebp)),復(fù)制到寄存器 %edx,再復(fù)制到寄存器 %ecx;

這 2 個(gè)操作正是對應(yīng)了內(nèi)聯(lián)匯編代碼中的“輸入操作數(shù)列表”部分:"b"(data1),"c"(data2)。

在內(nèi)聯(lián)匯編代碼之后(#NO_APP 之后),把 %eax 寄存器中的值復(fù)制到棧中的 -12(%ebp) 位置,這個(gè)位置正是局部變量 data3 所在的位置,這樣就完成了輸出操作。

4. test5.c 聲明改動(dòng)的寄存器

在 test4.c 中,我們沒有聲明改動(dòng)的寄存器,所以編譯器可以任意選擇使用哪些寄存器。從生成的匯編代碼 test4.s 中可以看到,gcc 使用了 %edx 寄存器。

那么我們來測試一下:告訴 gcc 不要使用 %edx 寄存器。

 
 
 
 
  1. #include 
  2. int main()
  3. {
  4.     int data1 = 1;
  5.     int data2 = 2;
  6.     int data3;
  7.     asm("movl %%ebx, %%eax\n\t"
  8.         "addl %%ecx, %%eax"
  9.         : "=a"(data3)
  10.         : "b"(data1),"c"(data2)
  11.         : "%edx");
  12.     printf("data3 = %d \n", data3);
  13.     return 0;
  14. }

代碼中,asm 指令最后部分 "%edx" ,就是用來告訴 gcc 編譯器:在內(nèi)聯(lián)匯編代碼中,我們會使用到 %edx 寄存器,你就不要用它了。

生成匯編代碼指令:

 
 
 
 
  1. gcc -m32 -S -o test5.s test5.c

來看一下生成的匯編代碼 test5.s:

 
 
 
 
  1.     movl    $1, -20(%ebp)
  2.     movl    $2, -16(%ebp)
  3.     movl    -20(%ebp), %eax
  4.     movl    -16(%ebp), %ecx
  5.     movl    %eax, %ebx
  6. #APP
  7. # 10 "test5.c" 1
  8.     movl %ebx, %eax
  9.     addl %ecx, %eax
  10. # 0 "" 2
  11. #NO_APP
  12.     movl    %eax, -12(%ebp)

可以看到,在內(nèi)聯(lián)匯編代碼之前,gcc 沒有選擇使用寄存器 %edx。

三、使用占位符來代替寄存器名稱

在上面的示例中,只使用了 2 個(gè)寄存器來操作 2 個(gè)局部變量,如果操作數(shù)有很多,那么在內(nèi)聯(lián)匯編代碼中去寫每個(gè)寄存器的名稱,就顯得很不方便。

因此,擴(kuò)展 asm 格式為我們提供了另一種偷懶的方法,來使用輸出和輸入操作數(shù)列表中的寄存器:占位符!

占位符有點(diǎn)類似于批處理腳本中,利用 2...來引用輸入?yún)?shù)一樣,內(nèi)聯(lián)匯編代碼中的占位符,從輸出操作數(shù)列表中的寄存器開始從 0 編號,一直編號到輸入操作數(shù)列表中的所有寄存器。

還是看例子比較直接!

1. test6.c 使用占位符代替寄存器

 
 
 
 
  1. #include 
  2. int main()
  3. {
  4.     int data1 = 1;
  5.     int data2 = 2;
  6.     int data3;
  7.     asm("addl %1, %2\n\t"
  8.         "movl %2, %0"
  9.         : "=r"(data3)
  10.         : "r"(data1),"r"(data2));
  11.     printf("data3 = %d \n", data3);
  12.     return 0;
  13. }

代碼說明:

  1. 輸出操作數(shù)列表"=r"(data3):約束使用字符 r, 也就是說不指定寄存器,由編譯器來選擇使用哪個(gè)寄存器來存儲結(jié)果,最后復(fù)制到局部變量 data3中;
  2. 輸入操作數(shù)列表"r"(data1),"r"(data2):約束字符r, 不指定寄存器,由編譯器來選擇使用哪 2 個(gè)寄存器來接收局部變量 data1 和 data2;
  3. 輸出操作數(shù)列表中只需要一個(gè)寄存器,因此在內(nèi)聯(lián)匯編代碼中的 %0 就代表這個(gè)寄存器(即:從 0 開始計(jì)數(shù));
  4. 輸入操作數(shù)列表中有 2 個(gè)寄存器,因此在內(nèi)聯(lián)匯編代碼中的 %1 和 %2 就代表這 2 個(gè)寄存器(即:從輸出操作數(shù)列表的最后一個(gè)寄存器開始順序計(jì)數(shù));

生成匯編代碼指令:

 
 
 
 
  1. gcc -m32 -S -o test6.s test6.c

匯編代碼如下 test6.s:

 
 
 
 
  1.     movl    $1, -20(%ebp)
  2.     movl    $2, -16(%ebp)
  3.     movl    -20(%ebp), %eax
  4.     movl    -16(%ebp), %edx
  5. #APP
  6. # 10 "test6.c" 1
  7.     addl %eax, %edx
  8.     movl %edx, %eax
  9. # 0 "" 2
  10. #NO_APP
  11.     movl    %eax, -12(%ebp)

可以看到,gcc 編譯器選擇了 %eax 來存儲局部變量 data1,%edx 來存儲局部變量 data2 ,然后操作結(jié)果也存儲在 %eax 寄存器中。

是不是感覺這樣操作就方便多了?不用我們來指定使用哪些寄存器,直接交給編譯器來選擇。

在內(nèi)聯(lián)匯編代碼中,使用 %0、%1 、%2 這樣的占位符來使用寄存器。

別急,如果您覺得使用編號還是麻煩,容易出錯(cuò),還有另一個(gè)更方便的操作:擴(kuò)展 asm 格式還允許給這些占位符重命名,也就是給每一個(gè)寄存器起一個(gè)別名,然后在內(nèi)聯(lián)匯編代碼中使用別名來操作寄存器。

還是看代碼!

2. test7.c 給寄存器起別名

 
 
 
 
  1. #include 
  2. int main()
  3. {
  4.     int data1 = 1;
  5.     int data2 = 2;
  6.     int data3;
  7.     asm("addl %[v1], %[v2]\n\t"
  8.         "movl %[v2], %[v3]"
  9.         : [v3]"=r"(data3)
  10.         : [v1]"r"(data1),[v2]"r"(data2));
  11.     printf("data3 = %d \n", data3);
  12.     return 0;
  13. }

代碼說明:

  1. 輸出操作數(shù)列表:給寄存器(gcc 編譯器選擇的)取了一個(gè)別名 v3;
  2. 輸入操作數(shù)列表:給寄存器(gcc 編譯器選擇的)取了一個(gè)別名 v1 和 v2;

起立別名之后,在內(nèi)聯(lián)匯編代碼中就可以直接使用這些別名( %[v1], %[v2], %[v3])來操作數(shù)據(jù)了。

生成匯編代碼指令:

 
 
 
 
  1. gcc -m32 -S -o test7.s test7.c

再來看一下生成的匯編代碼 test7.s:

 
 
 
 
  1.     movl    $1, -20(%ebp)
  2.     movl    $2, -16(%ebp)
  3.     movl    -20(%ebp), %eax
  4.     movl    -16(%ebp), %edx
  5. #APP
  6. # 10 "test7.c" 1
  7.     addl %eax, %edx
  8.     movl %edx, %eax
  9. # 0 "" 2
  10. #NO_APP
  11.     movl    %eax, -12(%ebp)

這部分的匯編代碼與 test6.s 中完全一樣!

四、使用內(nèi)存位置

在以上的示例中,輸出操作數(shù)列表和輸入操作數(shù)列表部分,使用的都是寄存器(約束字符:a, b, c, d, r等等)。

我們可以指定使用哪個(gè)寄存器,也可以交給編譯器來選擇使用哪些寄存器,通過寄存器來操作數(shù)據(jù),速度會更快一些。

如果我們愿意的話,也可以直接使用變量的內(nèi)存地址來操作變量,此時(shí)就需要使用約束字符 m。

1. test8.c 使用內(nèi)存地址來操作數(shù)據(jù)

 
 
 
 
  1. #include 
  2. int main()
  3. {
  4.     int data1 = 1;
  5.     int data2 = 2;
  6.     int data3;
  7.     asm("movl %1, %%eax\n\t"
  8.         "addl %2, %%eax\n\t"
  9.         "movl %%eax, %0"
  10.         : "=m"(data3)
  11.         : "m"(data1),"m"(data2));
  12.     printf("data3 = %d \n", data3);
  13.     return 0;
  14. }

代碼說明:

  1. 輸出操作數(shù)列表 "=m"(data3):直接使用變量 data3 的內(nèi)存地址;
  2. 輸入操作數(shù)列表 "m"(data1),"m"(data2):直接使用變量 data1, data2 的內(nèi)存地址;

在內(nèi)聯(lián)匯編代碼中,因?yàn)樾枰M(jìn)行相加計(jì)算,因此需要使用一個(gè)寄存器(%eax),計(jì)算這個(gè)環(huán)節(jié)是肯定需要寄存器的。

在操作那些內(nèi)存地址中的數(shù)據(jù)時(shí),使用的仍然是按順序編號的占位符。

生成匯編代碼指令:

 
 
 
 
  1. gcc -m32 -S -o test8.s test8.c

生成的匯編代碼如下 test8.s:

 
 
 
 
  1.     movl    $1, -24(%ebp)
  2.     movl    $2, -20(%ebp)
  3. #APP
  4. # 10 "test8.c" 1
  5.     movl -24(%ebp), %eax
  6.     addl -20(%ebp), %eax
  7.     movl %eax, -16(%ebp)
  8. # 0 "" 2
  9. #NO_APP
  10.     movl    -16(%ebp), %eax

可以看到:在進(jìn)入內(nèi)聯(lián)匯編代碼之前,把 data1 和 data2 的值放在了棧中,然后直接把棧中的數(shù)據(jù)與寄存器 %eax 進(jìn)行操作,最后再把操作結(jié)果(%eax),復(fù)制到棧中 data3 的位置(-16(%ebp))。

五、總結(jié)

通過以上 8 個(gè)示例,我們把內(nèi)聯(lián)匯編代碼中的關(guān)鍵語法規(guī)則進(jìn)行了講解,有了這個(gè)基礎(chǔ),就可以在內(nèi)聯(lián)匯編代碼中編寫更加復(fù)雜的指令了。


名稱欄目:內(nèi)聯(lián)匯編很可怕嗎?看完這篇文章,終結(jié)它!
文章來源:http://m.5511xx.com/article/djhdjii.html