如何通過asm關鍵字嵌入?yún)R編語言代碼?
一、基本 asm 格式
1. 語法規(guī)則
2. test1.c 插入空指令
3. test2.c 操作全局變量
4. test3.c 嘗試操作局部變量
二、擴展 asm 格式
1. 指令格式
2. 輸出和輸入操作數(shù)列表
3. test4.c 通過寄存器操作局部變量
4. test5.c 聲明使用的寄存器
三、使用占位符來代替寄存器名稱
1. test6.c 使用占位符代替寄存器名
2. test7.c 給寄存器起別名
四、使用內(nèi)存地址
1. test8.c 使用內(nèi)存地址來操作數(shù)據(jù)
五、總結
在 Linux 代碼中,經(jīng)?梢钥吹皆 C 代碼中,嵌入部分匯編代碼,這些代碼要么是與硬件體系相關的,要么是對性能有關鍵影響的。
在很久以前,我特別懼怕內(nèi)嵌匯編代碼,直到后來把匯編部分的短板補上之后,才徹底終結這種心理。
也許你在工作中,幾乎不會涉及到內(nèi)嵌匯編代碼的工作,但是一旦進入到系統(tǒng)的底層,或者需要對時間關鍵場景進行優(yōu)化,這個時候你的知識儲備就發(fā)揮重要作用了!
這篇文章,我們就來詳細聊一聊在 C 語言中,如何通過 asm 關鍵字來嵌入?yún)R編語言代碼,文中的 8 個示例代碼從簡單到復雜,逐步深入地介紹內(nèi)聯(lián)匯編的關鍵語法規(guī)則。
希望這篇文章能夠成為你進階高手路上的墊腳石!
PS:
示例代碼中使用的是 Linux 系統(tǒng)中 AT&T 匯編語法;
一、基本 asm 格式
gcc 編譯器支持 2 種形式的內(nèi)聯(lián) asm 代碼:
基本 asm 格式:不支持操作數(shù);
擴展 asm 格式:支持操作數(shù);
1. 語法規(guī)則
asm [volatile] ("匯編指令")
所有指令,必須用雙引號包裹起來;
超過一條指令,必須用分隔符進行分割,為了排版,一般會加上 ;
多條匯編指令,可以寫在一行,也可以寫在多行;
關鍵字 asm 可以使用 asm 來替換;
volatile 是可選的,編譯器有可能對匯編代碼進行優(yōu)化,使用 volatile 關鍵字之后,告訴編譯器不要優(yōu)化手寫的內(nèi)聯(lián)匯編代碼。
2. test1.c 插入空指令#include <stdio.h>
int main()
{
asm ("nop");
printf("hello");
asm ("nop nop "
"nop");
return 0;
}
注意:C語言中會自動把兩個連續(xù)的字符串字面量拼接成一個,所以"nop nop " "nop" 這兩個字符串會自動拼接成一個字符串。
生成匯編代碼指令:
gcc -m32 -S -o test1.s test1.c
test1.s 中內(nèi)容如下(只貼出了內(nèi)聯(lián)匯編代碼相關部分的代碼):
#APP
# 5 "test1.c" 1
nop
# 0 "" 2
#NO_APP
// 這里是 printf 語句生成的代碼。
#APP
# 7 "test1.c" 1
nop
nop
nop
# 0 "" 2
#NO_APP
可以看到,內(nèi)聯(lián)匯編代碼被兩個注釋(#APP ... #NO_APP)包裹起來。在源碼中嵌入了兩個匯編代碼,因此可以看到 gcc 編譯器生成的匯編代碼中包含了這兩部分代碼。
這 2 部分嵌入的匯編代碼都是空指令 nop,沒有什么意義。
3. test2.c 操作全局變量
在 C 代碼中嵌入?yún)R編指令,目的是用來計算,或者執(zhí)行一定的功能,下面我們就來看一下,如何在內(nèi)聯(lián)匯編指令中,操作全局變量。
#include <stdio.h>
int a = 1;
int b = 2;
int c;
int main()
{
asm volatile ("movl a, %eax "
"addl b, %eax "
"movl %eax, c");
printf("c = %d ", c);
return 0;
}
關于匯編指令中編譯器的基本知識:
eax, ebx 都是 x86 平臺中的寄存器(32位),在基本asm格式中,寄存器的前面必須加上百分號%。
32 位的寄存器 eax 可以當做 16 位來使用(ax),或者當做 8 位來使用(ah, al),本文只會按照 32 位來使用。
代碼說明:
movl a, %eax // 把變量a的值復制到 %eax 寄存器中;
addl b, %eax // 把變量 b 的值 與 %eax 寄存器中的值(a)相加,結果放在 %eax 寄存器中;
movl %eax, c // 把 %eax 寄存器中的值復制到變量 c 中;
生成匯編代碼指令:
gcc -m32 -S -o test2.s test2.c
test2.s 內(nèi)容如下(只貼出與內(nèi)聯(lián)匯編代碼相關部分):
#APP
# 9 "test2.c" 1
movl a, %eax
addl b, %eax
movl %eax, c
# 0 "" 2
#NO_APP
可以看到,在內(nèi)聯(lián)匯編代碼中,可以直接使用全局變量 a, b 的名稱來操作。執(zhí)行 test2,可以得到正確的結果。
思考一個問題:為什么在匯編代碼中,可以使用變量a, b, c?
請輸入評論內(nèi)容...
請輸入評論/評論長度6~500個字
最新活動更多
-
即日-10.29立即報名>> 2024德州儀器嵌入式技術創(chuàng)新發(fā)展研討會
-
10月31日立即下載>> 【限時免費下載】TE暖通空調(diào)系統(tǒng)高效可靠的組件解決方案
-
即日-11.13立即報名>>> 【在線會議】多物理場仿真助跑新能源汽車
-
11月14日立即報名>> 2024工程師系列—工業(yè)電子技術在線會議
-
12月19日立即報名>> 【線下會議】OFweek 2024(第九屆)物聯(lián)網(wǎng)產(chǎn)業(yè)大會
-
即日-12.26火熱報名中>> OFweek2024中國智造CIO在線峰會
推薦專題
-
10 百度搜索,正在被平替
- 1 Intel宣布40年來最重大轉(zhuǎn)型:年底前裁員15000人、拋掉2/3房產(chǎn)
- 2 因美封殺TikTok,字節(jié)股價骨折!估值僅Meta1/5
- 3 宏山激光重磅發(fā)布行業(yè)解決方案,助力智能制造產(chǎn)業(yè)新飛躍
- 4 國產(chǎn)AI芯片公司破產(chǎn)!白菜價拍賣
- 5 具身智能火了,但規(guī)模落地還需時間
- 6 三次錯失風口!OpenAI前員工殺回AI編程賽道,老東家捧金相助
- 7 國產(chǎn)英偉達們,抓緊沖刺A股
- 8 英特爾賦能智慧醫(yī)療,共創(chuàng)數(shù)字化未來
- 9 英偉達的麻煩在后頭?
- 10 將“網(wǎng)紅”變成“商品”,AI“爆改”實力拉滿
- 高級軟件工程師 廣東省/深圳市
- 自動化高級工程師 廣東省/深圳市
- 光器件研發(fā)工程師 福建省/福州市
- 銷售總監(jiān)(光器件) 北京市/海淀區(qū)
- 激光器高級銷售經(jīng)理 上海市/虹口區(qū)
- 光器件物理工程師 北京市/海淀區(qū)
- 激光研發(fā)工程師 北京市/昌平區(qū)
- 技術專家 廣東省/江門市
- 封裝工程師 北京市/海淀區(qū)
- 結構工程師 廣東省/深圳市