精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

內(nèi)聯(lián)匯編很可怕嗎?看完這篇文章,終結(jié)它!

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

[[396083]]

在 Linux 代碼中,經(jīng)常可以看到在 C 代碼中,嵌入部分匯編代碼,這些代碼要么是與硬件體系相關(guān)的,要么是對(duì)性能有關(guān)鍵影響的。

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

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

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

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

PS:

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

一、基本 asm 格式

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

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

1. 語(yǔ)法規(guī)則

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

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

2. test1.c 插入空指令

  1. #include <stdio.h> 
  2. int main() 
  3.     asm ("nop"); 
  4.     printf("hello\n"); 
  5.     asm ("nop\n\tnop\n\t" 
  6.      "nop"); 
  7.     return 0; 

注意:C語(yǔ)言中會(huì)自動(dòng)把兩個(gè)連續(xù)的字符串字面量拼接成一個(gè),所以"nop\n\tnop\n\t" "nop"這兩個(gè)字符串會(huì)自動(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 語(yǔ)句生成的代碼。 
  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)包裹起來(lái)。在源碼中嵌入了兩個(gè)匯編代碼,因此可以看到 gcc 編譯器生成的匯編代碼中包含了這兩部分代碼。

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

3. test2.c 操作全局變量

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

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

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

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

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

代碼說(shuō)明:

  • 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 的名稱來(lái)操作。執(zhí)行 test2,可以得到正確的結(jié)果。

思考一個(gè)問(wèn)題:為什么在匯編代碼中,可以使用變量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)出為全局的,所以可以在匯編代碼中使用。

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

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

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

  1. #include <stdio.h> 
  2. int main() 
  3.     int a = 1; 
  4.     int b = 2; 
  5.     int c; 
  6.  
  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; 

生成匯編代碼指令:

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

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

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

 

我們來(lái)嘗試編譯成可執(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ò):找不到對(duì) a,b,c 的引用!那該怎么辦,才能使用局部變量呢?擴(kuò)展 asm 格式!

二、擴(kuò)展 asm 格式

1. 指令格式

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

格式說(shuō)明

  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è)冒號(hào)可以不要,但是前面的冒號(hào)必須保留,即使輸出/輸入操作數(shù)列表為空。

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

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

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

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

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

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

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

(1)約束

就是通過(guò)不同的字符,來(lái)告訴編譯器使用哪些寄存器,或者內(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)輸出修飾符

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

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

語(yǔ)言描述比較抽象,直接看例子!

3. test4.c 通過(guò)寄存器操作局部變量

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

有 2 個(gè)地方需要注意一下啊:

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

代碼解釋:

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

通過(guò)上面的這種格式,內(nèi)聯(lián)匯編代碼中,就可以使用指定的寄存器來(lái)操作局部變量了,稍后將會(huì)看到局部變量是如何從經(jīng)過(guò)棧空間,復(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)入手寫(xiě)的內(nèi)聯(lián)匯編代碼之前:

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

這 2 個(gè)操作正是對(duì)應(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 中,我們沒(méi)有聲明改動(dòng)的寄存器,所以編譯器可以任意選擇使用哪些寄存器。從生成的匯編代碼 test4.s 中可以看到,gcc 使用了 %edx 寄存器。

那么我們來(lái)測(cè)試一下:告訴 gcc 不要使用 %edx 寄存器。

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

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

生成匯編代碼指令:

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

來(lái)看一下生成的匯編代碼 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 沒(méi)有選擇使用寄存器 %edx。

三、使用占位符來(lái)代替寄存器名稱

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

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

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

還是看例子比較直接!

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

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

代碼說(shuō)明:

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

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

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

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

還是看代碼!

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

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

代碼說(shuō)明:

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

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

生成匯編代碼指令:

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

再來(lái)看一下生成的匯編代碼 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è)寄存器,也可以交給編譯器來(lái)選擇使用哪些寄存器,通過(guò)寄存器來(lái)操作數(shù)據(jù),速度會(huì)更快一些。

如果我們?cè)敢獾脑挘部梢灾苯邮褂米兞康膬?nèi)存地址來(lái)操作變量,此時(shí)就需要使用約束字符 m。

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

  1. #include <stdio.h> 
  2. int main() 
  3.     int data1 = 1; 
  4.     int data2 = 2; 
  5.     int data3; 
  6.  
  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.  
  13.     printf("data3 = %d \n", data3); 
  14.     return 0; 

代碼說(shuō)明:

  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í),使用的仍然是按順序編號(hào)的占位符。

生成匯編代碼指令:

  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é)

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

 

責(zé)任編輯:姜華 來(lái)源: IOT物聯(lián)網(wǎng)小鎮(zhèn)
相關(guān)推薦

2019-01-30 13:44:34

JVM內(nèi)存服務(wù)器

2017-03-07 15:35:26

Android適配 界面

2017-03-10 21:04:04

Android適配

2020-11-17 07:43:24

互聯(lián)網(wǎng)MVC服務(wù)類

2019-05-30 09:32:49

2019-08-01 11:04:10

Linux磁盤(pán)I

2019-07-10 15:15:23

JVM虛擬機(jī)Java

2018-03-29 22:50:50

2017-08-09 15:07:08

大數(shù)據(jù)數(shù)據(jù)分析戶畫(huà)像

2023-10-08 19:06:41

2021-02-24 07:38:50

Redis

2018-07-31 14:03:09

JVM內(nèi)存數(shù)據(jù)

2022-02-18 06:56:18

Wi-Fi路由器局域網(wǎng)

2021-10-14 06:36:38

存儲(chǔ)云存儲(chǔ)本地存儲(chǔ)

2018-10-21 15:36:13

UI適配iOS

2019-11-28 18:36:00

華為MateBook

2015-12-02 18:11:06

百度地圖/地圖軟件

2024-11-19 18:03:04

2022-02-22 11:17:31

Kafka架構(gòu)代碼

2020-10-20 10:53:01

5G套餐運(yùn)營(yíng)商5G
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

亚洲免费大片在线观看| 日本怡春院一区二区| 亚洲成人xxx| 干日本少妇首页| 日韩免费啪啪| 成熟亚洲日本毛茸茸凸凹| 欧美有码在线视频| 五月天色婷婷丁香| 欧美一区二区三区红桃小说| 欧美最猛黑人xxxxx猛交| 黄色一级视频播放| 四虎精品成人免费网站| 韩国成人福利片在线播放| 欧美激情综合色综合啪啪五月| 国产白嫩美女无套久久| 欧洲精品久久久久毛片完整版| 一卡二卡三卡日韩欧美| 日韩av电影免费观看| 精品人妻一区二区三区换脸明星 | 尤物国产精品| 日韩一区二区三区在线观看视频| 日韩不卡免费视频| 久久久天堂国产精品女人| 最新日韩免费视频| 亚洲制服一区| 欧美一级久久久| 国产福利影院在线观看| 99re6在线精品视频免费播放| 国产精品色在线观看| 国内精品久久国产| 国内精品国产成人国产三级| 三级在线观看一区二区| 高清欧美性猛交xxxx黑人猛交| 林心如三级全黄裸体| 婷婷五月色综合香五月| 欧美成人精品1314www| 黄色手机在线视频| 91精品韩国| 亚洲国产日日夜夜| 91制片厂免费观看| 成人高清免费在线播放| 久久综合狠狠综合| 国产亚洲欧美一区二区| 国产色片在线观看| 美美哒免费高清在线观看视频一区二区| 91精品国产乱码久久久久久蜜臀| 欧美日韩在线观看成人| 日韩精品第一区| 亚洲一级一级97网| 中文幕无线码中文字蜜桃| 福利欧美精品在线| 精品国产露脸精彩对白| 麻豆短视频在线观看| 国产亚洲字幕| 日韩一区二区在线观看视频| 57pao国产成永久免费视频| 性欧美freehd18| 在线观看亚洲精品视频| 成人免费无码av| 深夜成人福利| 91成人免费在线| 韩国日本美国免费毛片| 欧美国产大片| 在线免费不卡电影| 日韩av片网站| 日韩精品第二页| 欧美群妇大交群的观看方式| 成年人三级黄色片| 国内精品视频| 精品久久久久av影院| 中文字幕永久免费| 欧美美女在线直播| 亚洲男人av在线| 永久免费av无码网站性色av| 欧美性感美女一区二区| 久久精品免费播放| 欧美爱爱小视频| 亚洲三级免费| 国产成人高清激情视频在线观看 | 欧美日韩久久一区二区| 污污的视频免费| 日韩欧美激情电影| 亚洲成人精品久久| 亚洲一区视频在线播放| 午夜影院欧美| 欧美精品第一页在线播放| 日本三级一区二区| 免费的成人av| 91大片在线观看| 日韩av资源站| 亚洲欧美一区二区视频| 欧美这里只有精品| sm捆绑调教国产免费网站在线观看 | 51成人做爰www免费看网站| 亚洲爆乳无码一区二区三区| 99国产一区二区三精品乱码| 神马影院午夜我不卡| 成人在线免费看片| 高跟丝袜一区二区三区| 在线观看免费污视频| 一区二区三区高清在线观看| 日韩精品免费在线观看| 久草手机视频在线观看| 9色国产精品| 国产精品爽黄69| 日本加勒比一区| 国产精品高清亚洲| 欧美视频免费看欧美视频| 成人在线黄色| 亚洲国产99精品国自产| 成人在线观看免费高清| 在线精品福利| 亚洲一区二区三区xxx视频| 桃花色综合影院| 一区二区三区美女视频| 美女喷白浆视频| 久久中文字幕导航| 久久影院资源网| 中文字幕男人天堂| 99久久免费视频.com| 中文字幕第50页| 99久久婷婷国产综合精品首页| 精品99久久久久久| 日韩影院一区二区| 日本视频一区二区| 久久久综合香蕉尹人综合网| av毛片在线| 欧美疯狂性受xxxxx喷水图片| 青青草视频成人| 亚洲国产精品第一区二区| 成人xvideos免费视频| 日本午夜在线| 午夜精品一区二区三区免费视频| 久久婷婷中文字幕| 国产在线日韩精品| 国产91精品视频在线观看| 亚洲国产精彩视频| 亚洲精品免费在线| 男人午夜视频在线观看| 精品国产欧美日韩| 日韩美女在线观看一区| 神马午夜精品95| 亚洲电影第三页| 国产成人av片| 欧美日韩18| 99超碰麻豆| 在线观看三级视频| 欧美一区二区三区播放老司机| 国产精品久久久久久成人| 日韩电影在线观看网站| 麻豆av福利av久久av| 亚洲美女炮图| 亚洲女人天堂成人av在线| 毛片基地在线观看| 99国产麻豆精品| 狠狠97人人婷婷五月| 欧美午夜寂寞| 奇米4444一区二区三区| 噜噜噜在线观看播放视频| 一本到高清视频免费精品| 亚洲不卡在线观看| 亚洲一区二区在线免费| 国产精品腿扒开做爽爽爽挤奶网站| 国产一区免费观看| 综合毛片免费视频| 亚洲无亚洲人成网站77777| 区一区二在线观看| 欧美国产激情一区二区三区蜜月| 天天爽天天爽夜夜爽| 99tv成人| 91精品国产91久久久久青草| 日本高清成人vr专区| 精品国产91洋老外米糕| 欧美日韩精品区| 国产三级精品三级| 亚洲 激情 在线| 亚洲一区 二区 三区| 国产精品成人观看视频免费| 久久影院午夜精品| 国产亚洲激情在线| 国产毛片毛片毛片毛片| 亚洲国产精品综合小说图片区| 国产又黄又粗又猛又爽的视频| 天堂在线亚洲视频| 欧美日韩视频免费在线观看| 成人精品动漫一区二区三区| 欧美中文字幕在线观看| 中文日本在线观看| 精品日韩一区二区三区| 台湾佬中文在线| 日韩理论片在线| 国产人成视频在线观看| 日韩中文字幕一区二区三区| eeuss中文| 亚洲肉体裸体xxxx137| 国产美女扒开尿口久久久| 在线午夜影院| 亚洲夜晚福利在线观看| 99热这里只有精品在线| 欧美日韩亚洲精品内裤| 中文字幕资源站| 91伊人久久大香线蕉| 日韩欧美国产片| 91久久夜色精品国产九色| 亚洲国产精品视频一区| 国产一区调教| 91深夜福利视频| 黄色亚洲网站| 欧美激情一区二区三级高清视频 | 91视频91自| 亚欧美一区二区三区| 视频在线在亚洲| 黄色一级在线视频| 一本精品一区二区三区| 神马影院一区二区| 色狼人综合干| 国产精品v欧美精品v日韩| 久久伊人国产| 欧美综合国产精品久久丁香| 天使と恶魔の榨精在线播放| 在线日韩日本国产亚洲| 五月婷婷狠狠干| 精品少妇一区二区三区日产乱码 | 激情五月激情综合| 久久婷婷国产综合国色天香| 宇都宫紫苑在线播放| 全部av―极品视觉盛宴亚洲| 91好吊色国产欧美日韩在线| 欧美另类专区| 欧美少妇在线观看| 天天色综合色| 视频一区视频二区视频三区高| 欧美调教在线| 狠狠色伊人亚洲综合网站色 | 国外成人在线视频网站| 久久精品免视看国产成人| 国产精品直播网红| 成人mm视频在线观看| 国产成人精品视频| 蜜桃视频www网站在线观看| 色综合91久久精品中文字幕 | 孩xxxx性bbbb欧美| 欧美videossex| 欧美激情国产精品| 日本伦理一区二区| 欧美丰满少妇xxxxx做受| www.久久ai| 久久亚洲精品成人| 国产婷婷视频在线| 欧美精品免费在线| 污视频免费在线观看| 欧美高清激情视频| heyzo在线欧美播放| 久久久久国产精品免费网站| 国产亚av手机在线观看| 国内外成人免费激情在线视频| 国产桃色电影在线播放| 98精品国产自产在线观看| bbw在线视频| 91精品国产色综合| 欧美理论影院| 国产精品偷伦视频免费观看国产| 日本精品在线中文字幕| 国产噜噜噜噜噜久久久久久久久| 久久伊人国产| 51成人做爰www免费看网站| 99re8这里有精品热视频8在线| av一本久道久久波多野结衣| 国产成人精品亚洲线观看| 久精品国产欧美| 精品国产精品| 91制片厂免费观看| 在线观看亚洲| 99久久国产宗和精品1上映| 日本v片在线高清不卡在线观看| 色综合五月婷婷| 成人午夜电影小说| 在线免费观看麻豆| 亚洲欧洲日产国码二区| 久久久久97国产| 色婷婷av久久久久久久| 91麻豆国产视频| 精品国产91久久久久久久妲己| 欧洲天堂在线观看| 中文字幕一区二区三区电影| 国产三级在线播放| 8x海外华人永久免费日韩内陆视频 | 美日韩中文字幕| 一级一片免费播放| 99精品国产99久久久久久福利| 成人性做爰aaa片免费看不忠| 久久97超碰国产精品超碰| 日本精品一二三| 国产日韩欧美亚洲| 久久精品免费在线| 欧美日韩综合不卡| 日韩一区二区三区在线观看视频| 亚洲片av在线| 日本一本在线免费福利| 国产精品女人网站| 国产精品成人自拍| 亚洲一区综合| 国产日韩精品视频一区二区三区| 日本黄大片一区二区三区| 99久久精品免费看国产 | 一区二区三区.www| 亚洲高清在线看| 亚洲第一精品福利| 黄网站在线播放| 日韩免费在线视频| 成人高潮视频| 欧美性受xxxx黑人猛交88| 久久亚洲欧洲| 国产视频精品视频| 亚洲欧美成人一区二区三区| 亚洲 欧美 中文字幕| 欧美成人一区二区三区| 日韩欧美小视频| 国产精品劲爆视频| 自拍视频一区| 免费毛片网站在线观看| 国内精品不卡在线| 亚洲精品成人av久久| 福利二区91精品bt7086| 秋霞网一区二区| 欧美精品一区二区免费| 91九色综合| 日本一区不卡| 麻豆9191精品国产| 99re这里只有| 亚洲午夜精品久久久久久久久| 国产精品毛片久久久久久久av| 亚洲午夜精品久久久久久性色| 欧美巨大丰满猛性社交| 国产精品手机视频| 国产一区清纯| 国产精品二区视频| 亚洲精品国产品国语在线app| 又污又黄的网站| 在线看欧美日韩| 日韩网站中文字幕| 日韩jizzz| 日韩高清在线一区| 真实乱视频国产免费观看| 欧美天天综合色影久久精品| 色婷婷av一区二区三区之红樱桃| 九色精品美女在线| 99国产精品久久一区二区三区| 欧美另类videosbestsex日本| 国产一区二区在线视频| 婷婷伊人五月天| 91精品国产综合久久久久| 麻豆免费在线视频| 91在线观看免费高清完整版在线观看| 欧美顶级大胆免费视频| 91av视频免费观看| 亚洲欧美乱综合| 亚洲黄色在线播放| 午夜精品一区二区三区在线 | 国产盗摄一区二区三区在线| 91精品国产美女浴室洗澡无遮挡| 国产激情在线观看| 成人三级在线| 99伊人成综合| 性の欲びの女javhd| 欧美美女一区二区三区| av理论在线观看| 国产尤物99| 日韩一区精品视频| 日韩精品一区二区亚洲av性色| 日韩精品一区二区三区在线播放| gratisvideos另类灌满| 欧美日韩一区二区三| 奇米影视在线99精品| 性欧美疯狂猛交69hd| 精品奇米国产一区二区三区| 丝袜老师在线| 亚洲午夜在线观看| 成人性视频免费网站| caoporn国产| 日韩性xxxx爱| 久久97久久97精品免视看秋霞| 狠狠爱免费视频| 亚洲欧美在线aaa| 天天色综合av| 国产日韩欧美影视| 亚洲激情综合| 美国一级黄色录像| 欧美xxxxxxxx| 成人国产精品入口免费视频| 永久免费网站视频在线观看| 91麻豆国产精品久久| 亚洲一区二区激情| 69久久夜色精品国产7777| av伊人久久| 污污内射在线观看一区二区少妇 | 久久午夜夜伦鲁鲁一区二区| 亚洲欧美日本在线| 福利视频在线看| 国产精品国产精品|