實驗内容
(1)在C程式中調用彙編語言子程式addt,實作三個數的加法運算。
(2)在彙程式設計式中調用C語言函數
int addt(int x,int y,int z)
,實作三個數的加法運算。
(3)在C程式中内嵌彙程式設計式,由内嵌彙編實作三個數的加法運算。
實驗原理
- 參數傳遞規則
- 根據ATPCS規則,C語言與彙編語言混合程式設計時,當參數不超過4個時使用寄存器R0~R3,依次将各字資料傳送到寄存器;參數超過4個時将剩餘的字資料傳送到資料棧,入棧的順序與參數順序相反,即最後一個參數先入棧。
- C程式調用彙編
- 在C語言程式中調用用彙編語言程式的方法是使用
關鍵詞,以聲明該彙程式設計式。在彙程式設計式中使用EXTERN
僞操作聲明該程式段可以被其它程式引用。EXPORT
- 例如
AREA StrCopy,CODE,READONLY
EXPORT strcopy ;聲明strcopy為導出符号
strcopy
LDRB R2,[R1],#1 ;R1中的值為源資料塊首位址
STRB R2,[R0],#1 ;R0中的值為目标資料塊首位址
CMP R2,#0
BEN strcopy ;未複制完,循環
MOV PC,LR ;複制完畢,傳回
END
extern void strcopy(char * d, const char * s);//聲明strcopy為外部引用符号
int main(void)
{
const char * str = "source";
char dest[10];
//···
strcopy(dest,src);//調用彙編函數strcopy
//···
}
- 彙程式設計式調用C程式
- 為保證調用時參數能夠正确的傳遞,彙程式設計式的設計要遵守基本的ATPCS規則,在彙編語言程式中應該使用
僞操作來聲明要引用的C語言程式,并通過BL指令來調用子程式。IMPORT
- 在C語言程式中不需要做特别的聲明,和編寫通常的C程式一樣。
- 例如,現在有C函數g()如下,。
int g(int a, int b, int c, int d, int e)
{
return a + b + c + d + e;
}
要求在彙編函數f中調用函數g(),以實作下面的功能
int f(int i){return -g(i, 2*i, 3*i, 4*i, 5*i);}
整個彙編函數f的代碼如下:
;-----------------------------------------------------------------------------------------------------
; 彙編函數 int f(int i){return -g(i, 2*i, 3*i, 4*i, 5*i);}
; 在彙程式設計式中調用時,預先把i的實參存入寄存器R0
;-----------------------------------------------------------------------------------------------------
EXPORT f
AREA f,CODE,READONLY
IMPORT g ;聲明g為外部引用符号
STR LR,[SP,#-4] ;斷點存入堆棧
ADD R1,R0,R0 ;(R1)=i*2
ADD R2,R1,R0 ;(R2)=I*3
ADD R3,R1,R2 ;(R3)=i*5
STR R3,[SP,#-4] ;将第5個參數i*5存入堆棧
ADD R3,R1,R1 ;(R3)=i*4
BL g ;調用C函數g(),傳回值在寄存器R0中
ADD SP,SP,#4 ;清棧
RSB R0,R0,#0 ;函數f的傳回值(R0)=0-(R0)
LDR PC,[SP],#4 ;恢複斷點并傳回
END
- 内嵌彙編
- 所謂内嵌彙程式設計式,就是在C程式中直接編寫彙程式設計式段而形成一個語句塊,這個語句塊可以使用除了
和BX
之外的全部ARM指令來編寫,進而可以使程式實作一些不能從C獲得的底層功能。BLX
- 在使用c編譯器時,定義一個内嵌彙程式設計式需要使用關鍵字
,當編譯器遇到這個關鍵字時,會啟動内嵌彙編器對關鍵字下面的程式進行彙編工作,其格式如下:__asm
__asm //聲明内嵌彙編代碼
{
//彙編語句
}
- 例如
void enable_IRQ(void)
{
int tmp;
__asm
{
MRS tmp, CPSR
BIC tmp, tmp, #0x80
MSR CPSR_c, tmp
}
}
(1)在C程式中調用彙編語言子程式addt,實作三個數的加法運算。
代碼實作
main.c
#define uint32 unsigned int
extern uint32 Addt(uint32 x,uint32 y,uint32 z);
uint32 sum;
int main(void)
{
sum=Addt(1,2,3);
}
asmfile.s
AREA addt,CODE,READONLY
EXPORT Addt
Addt ADD R0,R0,R1
ADD R0,R0,R2
MOV PC,LR
END
(2)在彙程式設計式中調用C語言函數int addt(int x,int y,int z),實作三個數的加法運算。
代碼實作
main.c
#define uint32 unsigned int
uint32 addt(uint32 x,uint32 y,uint32 z)
{
return x+y+z;
}
int main()
{
asm_main();
}
asmfile.s
EXPORT asm_main
AREA asm_main, CODE, READONLY
IMPORT addt
ENTRY
START
MOV R0,#1
MOV R1,#2
MOV R2,#3
BL addt
END
(3)在C程式中内嵌彙程式設計式,由内嵌彙編實作三個數的加法運算。
代碼實作
main.c
#define uint32 unsigned int
uint32 addt(uint32 x,uint32 y,uint32 z);
int main(void)
{
addt(1,2,3);
return 0;
}
uint32 addt(uint32 x,uint32 y,uint32 z)
{
uint32 temp;
__asm
{
add temp, x, y
add temp, temp, z
}
}
參考文章
ARM彙程式設計式設計之C程式調用彙程式設計式
C語言調用彙編函數 實作超過32位數的加法
ARM 彙編和C語言代碼的互相調用