1. 程式人生 > >C語言與組合語言相互呼叫

C語言與組合語言相互呼叫

   在使用C語言時,要用到和組合語言的混合程式設計。若彙編程式碼較為簡潔,則可使用直接內嵌彙編的方法;否則要將彙編程式以檔案的形式加入到專案中,按照ATPCS(ARM/Thumb過程呼叫標準,ARM/Thumb Procedure Call Standard)的規定與C程式相互呼叫與訪問。
    在C程式和ARM彙編程式之間相互呼叫時必須遵守ATPCS規則。ATPCS規定了一些子程式間呼叫的基本規則,暫存器的使用規則,堆疊的使用規則和引數的傳遞規則等。

1)暫存器的使用規則
    子程式之間通過暫存器r0~r3來傳遞引數,當引數個數多於4個時,使用堆疊來傳遞引數。此時r0~r3可記作A1~A4。
    在子程式中,使用暫存器r4~r11儲存區域性變數。因此當進行子程式呼叫時要注意對這些暫存器的儲存和恢復。此時r4~r11可記作V1~V8。
    暫存器r12用於儲存堆疊指標SP,當子程式返回時使用該暫存器出棧,記作IP。
    暫存器r13用作堆疊指標,記作SP。暫存器r14稱為連結暫存器,記作LR。該暫存器用於儲存子程式的返回地址。
   暫存器r15稱為程式計數器,記作PC。
2)堆疊的使用規則
ATPCS規定堆疊採用滿遞減型別(FD,Full Descending),即堆疊通過減小儲存器地址而向下增長,堆疊指標指向內含有效資料項的最低地址。
3)引數的傳遞規則
整數引數的前4個使用r0~r3傳遞,其他引數使用堆疊傳遞;浮點引數使用編號最小且能夠滿足需要的一組連續的FP暫存器傳遞引數。
子程式的返回結果為一個32位整數時,通過r0返回;返回結果為一個64位整數時,通過r0和r1返回;依此類推。結果為浮點數時,通過浮點運算部件的暫存器F0、D0或者S0返回。
2、彙編程式呼叫C程式的方法
彙編程式的書寫要遵循ATPCS規則,以保證程式呼叫時引數正確傳遞。在彙編程式中呼叫C程式的方法為:首先在彙編程式中使用IMPORT偽指令事先宣告將要呼叫的C語言函式;然後通過BL指令來呼叫C函式。
例如在一個C原始檔中定義瞭如下求和函式:
int add(int x,int y){
return(x+y);
}
呼叫add()函式的彙編程式結構如下:
IMPORT add ;宣告要呼叫的C函式
……
MOV r0,#1
MOV r1,#2
BL add ;呼叫C函式add
……
當進行函式呼叫時,使用r0和r1實現引數傳遞,返回結果由r0帶回。函式呼叫結束後,r0的值變成3。
3、C程式調用匯程式設計序的方法
C程式調用匯程式設計序時,彙編程式的書寫也要遵循ATPCS規則,以保證程式呼叫時引數正確傳遞。在C程式中調用匯編子程式的方法為:首先在彙編程式中使用EXPORT偽指令宣告被呼叫的子程式,表示該子程式將在其他檔案中被呼叫;然後在C程式中使用extern關鍵字宣告要呼叫的彙編子程式為外部函式。
例如在一個彙編原始檔中定義瞭如下求和函式:
EXPORT add ;宣告add子程式將被外部函式呼叫
……
add ;求和子程式add
ADD r0,r0,r1
MOV pc,lr
……
在一個C程式的main()函式中對add彙編子程式進行了呼叫:
extern int add (int x,int y); //宣告add為外部函式
void main(){
int a=1,b=2,c;
c=add(a,b); //呼叫add子程式
……
}
當main()函式呼叫add彙編子程式時,變數a、b的值會給了r0和r1,返回結果由r0帶回,並賦值給變數c。函式呼叫結束後,變數c的值變成3。
4、C程式中內嵌彙編語句
在C語言中內嵌彙編語句可以實現一些高階語言不能實現或者不容易實現的功能。對於時間緊迫的功能也可以通過在C語言中內嵌彙編語句來實現。內嵌的彙編器支援大部分ARM指令和Thumb指令,但是不支援諸如直接修改PC實現跳轉的底層功能,也不能直接引用C語言中的變數。
嵌入式彙編語句在形式上獨立定義的函式體,其語法格式為:
__asm
{
指令[;指令]
……
[指令]
}
其中“__asm”為內嵌彙編語句的關鍵字,需要特別注意的是前面有兩個下劃線。指令之間用分號分隔,如果一條指令佔據多行,除最後一行外都要使用連字元“\”。
5、基於ARM的C語言與組合語言混合程式設計舉例
下面給出了一個向串列埠不斷髮送0x55的例子:
該工程的啟動程式碼使用匯編語言編寫,向串列埠傳送資料使用C語言實現,下面是啟動程式碼的整體框架:
……
IMPORT Main
AREA Init,CODE,READONLY;
ENTRY
……
BL Main ;跳轉到Main()函式處的C/C++程式
……
END ;標識彙編程式結束
 
下面是使用C語言編寫的主函式:
#include "..\inc\config.h" //將有關硬體定義的標頭檔案包含進來
unsigned char data; //定義全域性變數
 
void main(void){
Target_Init(); //對目標板的硬體初始化
Delay(10); //延時
data=0x55; //給全域性變數賦值
while(1) {
Uart_Printf("%x",data); //向串列埠送數
Delay(10);
}
}

相關推薦

C語言組合語言相互呼叫

在使用C語言時,要用到和組合語言的混合程式設計。若彙編程式碼較為簡潔,則可使用直接內嵌彙編的方法;否則要將彙編程式以檔案的形式加入到專案中,按照ATPCS(ARM/Thumb過程呼叫標準,ARM/Thumb Procedure Call Standard)的規定與C程

C語言組合語言之間的函式呼叫

教材:嵌入式系統及應用,羅蕾、李允、陳麗蓉等,電子工業出版社 ARM 程式設計 C與彙編之間的函式呼叫 ATPCS簡介 ARM-Thumb 過程呼叫標準 ATPC

C語言C++語言相互呼叫

                                          &

Thrift 的Cgolang語言實現以及相互呼叫方式

Thrift 的Go與C語言實現 Thrift 是Facebook為了解決各系統間大資料量的傳輸通訊以及系統之間語言環境不同而設計的一種傳輸框架。目前來看常用的主流語言Thrift都已經很好地支援,並且github上已經有很多實現,除了C語言之外。T

C語言匯編語言相互調用原理以及實例

這一 參數表 想要 return urn 類型 ring 符號表 參數 C語言與匯編語言相互調用原理以及實例 1.原理 其實不管是C語言還是匯編語言想要執行都是最終編譯鏈接成為二進制文件。 這裏一定要明確編譯和鏈接是兩個步驟,生成的文件格式也是不一樣的。 編譯生成的文件是一

ARM基礎:為何C語言(的函式呼叫)需要堆疊,而組合語言卻不需要堆疊

https://www.cnblogs.com/liuchengchuxiao/p/4113233.html 為何C語言(的函式呼叫)需要堆疊,而組合語言卻不需要堆疊 之前看了很多關於uboot的分析,其中就有說要為C語言的執行,準備好堆疊。 而自己在Uboot的start.S彙編程

Unity3D 預備知識:C#Lua相互呼叫

public class CSharpLuaTest : MonoBehaviour { private LuaState luaState = new LuaState(); // 建立lua虛擬機器 void Start () { //

C語言中函式的呼叫棧幀

int main() { 002233C0  push        ebp   002233C1  mov         ebp,esp   002233C3  sub         esp,0E4h   002233C9  push        

javaC/C++之間通過jni相互呼叫

一、jni簡介: 企業應用 JNI一直以來都很少去關注,但卻是我心中的一個結,最近這幾天剛好手頭有點時間,因此抽空看了一下這方面的東西,整理了一份文件,JNI技術的出現主要是基於三個方面的應用需求: 1. 解決效能問題 Java具有平臺

1、在C#Lua相互呼叫

一、利用LuaInterface呼叫lua程式碼 1、下載luainterface,這裡用的luainterface-1.5.3版本。 2、新增 LuaInterface.dll的引用。 3、利用直譯器進行呼叫 using System;   using L

C#語言變量、數據類型

使用 賦值 轉換成 運算 命名規範 ole 字符 書寫格式 double類型 1.代碼的運用 計算機語言:C、PHP、Ruby、Java、C#、Basic、JS、C++ 源代碼:就是用某種計算機語言編寫的內容 編譯:用編譯器將源代碼轉換成機器代碼 機器語言:機器語言就是能夠

C語言C++ <string.h> memchr出現的問題

TP png c++編譯 c語言 原因 bsp ima svc .cpp 相同的如下代碼 #include <stdio.h> #include <string.h> int main() { const char str[] = "http

OCswift相互呼叫

OC與swift相互呼叫 一、OC呼叫swift檔案 二、swift呼叫OC檔案 三、注意和總結 新增: 四、自定義橋接檔案  一、OC呼叫swift檔案   在OC專案中建立一個swift檔案的時候,Xcode 會提示 需要建立一個橋接檔案,點

swift專案中 OCswift相互呼叫

swift呼叫oc的方法: 1、橋接檔案,一般是swift工程,在建立一個oc檔案時,系統自動新增(不用改名,直接預設即可) 2、將需要引用的oc檔案 .h標頭檔案 新增到橋接類中。 具體方法可以參考我的這篇部落格,裡面進行了詳細講解 oc呼叫swift 1、首先設定一

C語言常見的函式呼叫

C語言常見的函式呼叫 isatty,函式名,主要功能是檢查裝置型別,判斷檔案描述詞是否為終端機。 函式名: isatty 用 法: int isatty(int desc); 返回值:如果引數desc所代表的檔案描述詞為一終端機則返回1,否則返回0。 程式例: #include <s

字串操作---C語言C++

字串在儲存上類似與字元陣列,它的每一位的單個元素都是可以提取的。字串操作就是一串為整體作為操作物件。例如:查詢某個子串、刪除某個子串等等。 一、C語言中的字串操作 strcpy(str1,str2); 複製字串 strncpy(str1,str2,n); 複製指定長度的字串 strc

Go 語言智慧合約呼叫

2017年由於比特幣的瘋狂上漲,讓大家見識到了其背後技術區塊鏈的能量。比特幣是區塊鏈的第一個產品,代表了區塊鏈1.0時代的到來。而以太坊則代表了區塊鏈2.0時代的到來,以太坊比比特幣的改進地方就是在區塊鏈上還可以程式設計!這個區塊鏈上執行的程式碼我們給它叫做智慧合約!而基於以太坊平臺的 ICO 模式

C/C++ 字串數字相互轉換

https://www.cnblogs.com/happygirl-zjj/p/4633789.html 一.利用stringstream類 字串到整數 stringstream sstr(str); int x; sstr >> x;(即從sstr中提取資料)

[轉]在C#中呼叫C語言函式(靜態呼叫Native DLL,Windows & Microsoft.Net平臺)

原文:https://blog.csdn.net/yapingxin/article/details/7288325   對於不太瞭解.Net的人,如果想要了解.Net,我必須給他介紹P/Invoke。P/Invoke是什麼呢?簡單地說,就是在.Net中呼叫原生代碼(Native code)的一

繪製數字濾波器的頻域響應,對比C語言MATLAB的結果

設傳遞函式H(z)H(z)H(z)的分子分母系數為: b=[0.0563 -0.0009 -0.0009 0.0563];%分子 a=[1.0000 -2.1291 1.7834 -0.5435];%分母 MATLAB程式碼 b=[