esp32 c3 開發板樂鑫8089芯片代理商嵌入式函數調用規范,嵌入式軟件工程(project)中可以包括多個源文件和二進制庫文件。函數調用范保證不同文件之間函數的正確調用。常用的麗數調用規范有 stdcall、cdecl、fastcall 和 thiscall 等。 stdcall 函數調用式又稱為 Pascal 調用,應用于 Microsoft 的 C/C++編譯器。cdecl 調用方式又稱為(調用方式,是C語言缺省的函數調用方式。fastcall 是一種快速調用方式,在 x86臺上利用ecx和edx寄存器傳遞函數的第 1 個和第 2個32 位參數。thiscall是C++類成員函數缺省的調用方式。
ARM處理器過程調用規范(ARM Procedure Call Standard,APCS)定義ARM 處理器應用程序中的函數調用規則。使用多個通用寄存器傳遞參數,返回數結果,提高函數調用過程的速度。RISC-V gcc 編譯工具使用 RISC-V 應用程序二進制接口(Application BinarInterface,ABI)調用規范。與其他調用規范相比,esp32 c3 開發板樂鑫8089芯片代理商RISC-V ABI規范使用更多寄存器傳遞參數,調用過程更加快捷。采用 ABI規范可以實現匯編語言程序與 C 語言程序之間、匯編語言程序與C++程序之間、源程序與二進制庫文件之間函數的相互調用。
函數調用過程
示例5.7中包括函數 int max(int a,int b)和主程序 int main()。主程序 main中調用函數 max和 printf,main 是調用者,函數 max 和 printf 是被調用者。
示例 5.7: 函數調用。
1 # include <stdio.h>
2 int max(int a,int b);
3 int main() //主程序
4 {int maxvalue=0;
5 int a = 50,b = 150;
6 maxvalue = max(a,b); //調用源文件的函數
7 printf(“max=%d”,maxvalue); //調用二進制庫中的函數
8 return 1;
9 }
10 int max(int a,int b) //函數,返回大值
11 {
12 if(a>=b)
13 return a;
14 else
15 return b;
16 }
如圖 5.7 所示為函數調用過程,esp32 c3 開發板樂鑫8089芯片代理商整個過程可分為 7 個階段:
1、將參數存儲到函數能夠訪問到的數據棧,數據棧是內存或者寄存器;
2、在 RISC-V RV32I指令集中,用jal或 jalr 指令跳轉到函數開始位置;
3、函數獲取局部資源,從數據棧中提取參數,并備份函數中需要使用的寄存器;
4、執行函數中的指令;
5、將返回值存儲到調用者能夠訪問到的數據棧,恢復寄存器,釋放局部存儲資源;
6、從函數中返回,用 ret 指令回到主程序;
7、主程序從數據棧中讀取返回數據。
函數聲明和實現時必須符合調用約定,以保證函數之間的正確調用。
函數聲明
函數定義包括名稱、形式參數列表、函數主體和返回類型 4 個部分。
名稱:每個函數都必須擁有的名字。
形式參數列表:保存傳遞給函數值的變量列表。如果不需要傳輸參數,則形式參數列表為空。
主體:函數中運算或處理事務的一組語句。
返回類型:函數返回值的數據類型。
鏈接過程中,如果鏈接器掃描到新的函數名稱,則在同一個目標文件中、同一工程中的其他目標文件中,或者在與當前工程中相關的二進制庫文件中尋找同名的函數實體,然后鏈接起來。
1.文件內調用
示例 5.7 中,調用者 main 和被調用函數 max 在同一文件中。源序中第 3~9行是 main 函數體,第 10~16行是 max 函數體源序第 2行定 max 數原型。接時,鏈接器在當前文件中直接查找函數體。
對于 C/C++語言程序,如果調用者和被調用者(函數)在同一源程序文件中,則只需要在調用語句之前聲明函數原型,調用者就可以直接調用該函數了。
對于 RISC-V 匯編語言程序,esp32 c3 開發板樂鑫8089芯片代理商同一源文件內的函數調用更加簡單,不需要聲明函數原型,甚至不需要聲明函數原型,甚至不需要遵守調用規范,編譯器可以直接查找函數的名稱(標簽)。在下列幫序中,主程序直接調用函數_fini。
1 la tl,_fini //獲取函數標簽地址
2 jalr tl //調用函數
3 _fini: //函數體
4 ret //返回
2.文件之間的函數調用
如果調用者和被調用者不在同一個文件中,則需要在源程序中對函數進行聲明告訴鏈接器,文件中哪些函數的函數體在文件外部,以及文件內哪些函數體可以被外部調用。
在 RISC-V gas 匯編語言中,用命令“.global”聲明全局函數或全局符號。匯編語言文件中,先聲明文件中的外部函數和可以被外部調用的函數。在示例 5.8中,_muldf3 是外部函數,delay_lms 是可以被外部調用的函數體。
示例 5.8:聲明全局函數和符號。
1 .text //聲明外部函數全局標簽
2 .global _muldf3 //聲明為全局標簽
3 .globaldelay_lms //聲明函數類型
4 . type delay_lms,@function //函數標簽
5 delay_lms:
6 .......
7 call _muldf3 //調用外部函數
8 .......
9 .end
在C語言中,如果需要調用外部文件中的雨數,則必須在 C 語言程序的開始部分進行聲明。
如果所調用函數的函數體在同工程中的另外一個源程序文件中,則可以在調用者所在的源程序文件中添加被調用的函數原型聲明。esp32 c3 開發板樂鑫8089芯片代理商添加函數原型聲明的方式有兩種:一,在源文件中添加聲明函數原型的語句;第二,在源文件中包含有函數原型聲明的頭文件。
例如,在源文件 sourcel.c 中調用源文件 source2.c 中的函數 delay 1s,則可以在 sourcel.c 文件中添加函數原型語句:
void delay_lms(int mstimes);
或者,把聲明函數原型的語句寫到 source2.h 文件中,然后在 sourcel.c 文件前添加語句:
#include“source2.h”
如果被調用的函數體在匯編語言程序中,或者在二進制目標文件中,則在調用函數的C源程序中添加函數原型聲明語句,esp32 c3 開發板樂鑫8089芯片代理商且在函數原型前添加關鍵字“extern”說明是外部函數。例如,示例 5.9 的第 1行中,delay_lms 是在匯編語言中定義的函數。
示例 5.9:C語言外部函數聲明
1extern void delay_lms(unit32_t count); //外部函數原型
2 int main(void)
3 {
4 ......
5 delay_lms(50); //調用外部函數
6 ......
7 }