天天看點

【ARM彙編學習執行個體】彙編語言與C語言混合程式設計

實驗内容

(1)在C程式中調用彙編語言子程式addt,實作三個數的加法運算。

(2)在彙程式設計式中調用C語言函數

int addt(int x,int y,int z)

,實作三個數的加法運算。

(3)在C程式中内嵌彙程式設計式,由内嵌彙編實作三個數的加法運算。

實驗原理

  1. 參數傳遞規則
  • 根據ATPCS規則,C語言與彙編語言混合程式設計時,當參數不超過4個時使用寄存器R0~R3,依次将各字資料傳送到寄存器;參數超過4個時将剩餘的字資料傳送到資料棧,入棧的順序與參數順序相反,即最後一個參數先入棧。
  1. 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
	//···
}
           
  1. 彙程式設計式調用C程式
  • 為保證調用時參數能夠正确的傳遞,彙程式設計式的設計要遵守基本的ATPCS規則,在彙編語言程式中應該使用

    IMPORT

    僞操作來聲明要引用的C語言程式,并通過BL指令來調用子程式。
  • 在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

           
  1. 内嵌彙編
  • 所謂内嵌彙程式設計式,就是在C程式中直接編寫彙程式設計式段而形成一個語句塊,這個語句塊可以使用除了

    BX

    BLX

    之外的全部ARM指令來編寫,進而可以使程式實作一些不能從C獲得的底層功能。
  • 在使用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語言代碼的互相調用