C與匯編混合編程的實(shí)現(xiàn)示例
上一期中,使用鏈表的方式進(jìn)行對(duì)不同任務(wù)的調(diào)用,實(shí)現(xiàn)的效果還是不錯(cuò)的,但是,任務(wù)在進(jìn)行過(guò)程中不能進(jìn)行來(lái)回的切換,必須要執(zhí)行完,這是一個(gè)弊端,若不使用實(shí)時(shí)操作系統(tǒng)的情況下,如何切換呢,那就要說(shuō)一下萬(wàn)能的匯編了,用匯編則可以做到任務(wù)的切換
首先我們知道,c與匯編的聯(lián)合使用就三種情況,如下
1. C語(yǔ)言內(nèi)聯(lián)匯編
首先看一下代碼
__inline int ADD(int input1,int intput2) { int output; __asm{ ADD output,input1,intput2 } return output; } int Number(void); int value; int main(void) { int a = 12,b = 13; while(1) { value = ADD(a,b); } }
執(zhí)行效果
0x19的十進(jìn)制為25
2. C語(yǔ)言調(diào)用匯編函數(shù)
調(diào)用匯編函數(shù),首先創(chuàng)建一個(gè).s
匯編文件
創(chuàng)建完成后,在匯編文件中寫(xiě)入一個(gè)匯編函數(shù)
AREA |.text|,CODE,READONLY EXPORT Get_Number Get_Number MOV R0,#761 BX LR ALIGN END
然后寫(xiě)一個(gè)main
函數(shù)調(diào)用它
int Get_Number(void); int value; int main(void) { while(1) { value = Get_Number(); } }
查看執(zhí)行效果
3. 匯編代碼調(diào)用C語(yǔ)言函數(shù)
在匯編文件中,輸入如下代碼
AREA |.text|,CODE,READONLY IMPORT Get_Number IMPORT Number EXPORT __main ENTRY __main LDR R1,=Number MOV R0,#100 STR R0,[R1] BL Get_Number END
在C文件中輸入如下代碼
int Number; int Get_Number(void) { Number = Number + 32; return Number; }
看一下執(zhí)行效果吧
繼續(xù)向下執(zhí)行
數(shù)字由100變成132;實(shí)現(xiàn)功能
解釋說(shuō)明:
/* AREA 語(yǔ)法格式: AREA 段名 屬性1 ,屬性2 ,…… AREA偽指令用于定義一個(gè)代碼段或數(shù)據(jù)段。其中,段名若以數(shù)字開(kāi)頭,則該段名需用“|”括起來(lái),如:|1_test| 。 屬性字段表示該代碼段(或數(shù)據(jù)段)的相關(guān)屬性,多個(gè)屬性用逗號(hào)分隔。常用的屬性如下: — CODE 屬性:用于定義代碼段,默認(rèn)為READONLY 。 — DATA 屬性:用于定義數(shù)據(jù)段,默認(rèn)為READWRITE 。 — READONLY 屬性:指定本段為只讀,代碼段默認(rèn)為READONLY 。 — READWRITE 屬性:指定本段為可讀可寫(xiě),數(shù)據(jù)段的默認(rèn)屬性為READWRITE 。 — ALIGN 屬性:使用方式為ALIGN表達(dá)式。在默認(rèn)時(shí),ELF(可執(zhí)行連接文件)的代碼段和數(shù)據(jù)段是按字對(duì)齊的,表達(dá)式的取值范圍為0~31,相應(yīng)的對(duì)齊方式為2表達(dá)式次方。 — COMMON 屬性:該屬性定義一個(gè)通用的段,不包含任何的用戶代碼和數(shù)據(jù)。各源文件中同名的COMMON段共享同一段存儲(chǔ)單元。 */ /* MOV 傳送指令 將右邊數(shù)據(jù)移入左邊寄存器 LDR 將右值地址存的數(shù)據(jù)移入左邊寄存器 BX 通用寄存器 里面存入基地址、偏移量、臨時(shí)數(shù)據(jù) BL 跳轉(zhuǎn)指令 LR r14 (1)當(dāng)使用bl或者blx跳轉(zhuǎn)到子過(guò)程的時(shí)候,r14保存了返回地址,可以在調(diào)用過(guò)程結(jié)尾恢復(fù) (2)異常中斷發(fā)生時(shí),這個(gè)異常模式特定的物理R14被設(shè)置成該異常模式將要返回的地址 ENTRY 是程序入口偽指令。在一個(gè)完整的匯編程序中至少有一個(gè) ENTRY,編譯程序在編譯連接時(shí)依據(jù)程序入口進(jìn)行連接。 在只有一個(gè)入口時(shí),編譯程序會(huì)把這個(gè)入口的地址定義為系統(tǒng)復(fù)位后的程序起始點(diǎn)。但在一個(gè)源文件里最多只能有一個(gè) ENTRY。 ENDP 表示PROC所定義的過(guò)程結(jié)束. (end procedure) ENDS 表示SEGMENT定義的段結(jié)束. (end segment) END 程序結(jié)束. */
使用BL
跳轉(zhuǎn)
BL指令同時(shí)還將PC寄存器的值保存到LR寄存器中,是帶返回的跳轉(zhuǎn)指令
所以
假設(shè)在一個(gè)匯編程序中,要調(diào)用兩個(gè)C語(yǔ)言函數(shù)
用事實(shí)證明可以返回
將匯編代碼修改為如下
AREA |.text|,CODE,READONLY IMPORT Get_Number IMPORT Number IMPORT Get_Value IMPORT Value EXPORT __main ENTRY __main LDR R1,=Number MOV R0,#100 STR R0,[R1] BL Get_Number LDR R1,=Value MOV R0,#100 STR R0,[R1] BL Get_Value END
對(duì)應(yīng)的c文件為
int Number; int Get_Number(void) { Number = Number + 32; return Number; } int Value; int Get_Value(void) { Value = Value - 32; return Value; }
查看代碼執(zhí)行情況
首先進(jìn)行第一個(gè)函數(shù)的執(zhí)行,數(shù)字發(fā)生改變
接下來(lái)是第二個(gè)函數(shù)執(zhí)行,數(shù)字發(fā)生改變
證明BL跳轉(zhuǎn)可以返回。
可以使用匯編加C語(yǔ)言的編程思路,打破一些限制
也為后面進(jìn)行PC
的跳轉(zhuǎn)打下基礎(chǔ)
到此這篇關(guān)于C與匯編混合編程的實(shí)現(xiàn)示例的文章就介紹到這了,更多相關(guān)C與匯編混合編程 內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++實(shí)現(xiàn)LeetCode(34.在有序數(shù)組中查找元素的第一個(gè)和最后一個(gè)位置)
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(34.在有序數(shù)組中查找元素的第一個(gè)和最后一個(gè)位置),本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07C語(yǔ)言中循環(huán)語(yǔ)句練習(xí)實(shí)例
大家好,本篇文章主要講的是C語(yǔ)言中循環(huán)語(yǔ)句練習(xí)實(shí)例,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下2022-01-01基于C++實(shí)現(xiàn)的哈夫曼編碼解碼操作示例
這篇文章主要介紹了基于C++實(shí)現(xiàn)的哈夫曼編碼解碼操作,結(jié)合實(shí)例形式分析了C++實(shí)現(xiàn)的哈夫曼編碼解碼相關(guān)定義與使用技巧,需要的朋友可以參考下2018-04-04C語(yǔ)言課程設(shè)計(jì)之停車(chē)場(chǎng)管理問(wèn)題
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言課程設(shè)計(jì)之停車(chē)場(chǎng)管理問(wèn)題,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03C++中delete和delete[]的區(qū)別詳細(xì)介紹
一直對(duì)C++中的delete和delete[]的區(qū)別不甚了解,今天遇到了,上網(wǎng)查了一下,得出了結(jié)論,拿出來(lái)和大家分享一下2012-11-11LintCode-排序列表轉(zhuǎn)換為二分查找樹(shù)分析及實(shí)例
這篇文章主要介紹了LintCode-排序列表轉(zhuǎn)換為二分查找樹(shù)分析及實(shí)例的相關(guān)資料,需要的朋友可以參考下2017-04-04