1. 程式人生 > >彙編與C混合程式設計(6.19)

彙編與C混合程式設計(6.19)

一  異常放回


<1>IRQ/FIRQ 
pc <- lr - 4
 
<2>軟中斷異常
pc <- lr
 
<3>預取指令終止異常
 
指令1
指令2 <-沒有取到指令
指令3
指令4 <-pc
 
lr : 儲存的是指令3的地址
 
pc <- lr - 4 [沒有取到指令,需要再次去取]
 


<4>取資料終止異常
 
指令1
指令2 <-沒有取到資料 (在指令2執行結束的時候,產生異常)
指令3
指令4 
指令5 <- pc 
 
lr : 儲存的是指令4的地址
 
pc <- lr - 8  [沒有取到資料,需要再次去取]
 
<5>未定義異常


指令1
指令2 <-無法識別,產生未定義異常
指令3
指令4 <-pc
 
lr : 儲存的是指令3的地址
 
pc <- lr 



二、彙編與C混合程式設計


1.ATPCS標準


[1]引數的傳遞
函式引數傳遞的時候,前4個引數通過r0-r3來傳遞,超過4個的引數通過堆疊來傳遞
 
 
[2]函式返回值
通過r0帶回
 
注意:呼叫C語言之前,必須先設定sp


 
2.內聯彙編(在C語言中內嵌一段彙編程式碼)


asm(
"指令1\n"
"指令2\n"
...
:輸出列表
:輸入列表
:修改列表

);



[1]輸出列表: 將暫存器值輸出到c變數
int c;
int d;

輸出列表
:"=r"(c),"=r"(d)


[2]輸入列表 : 將c變數輸入到暫存器
int a = 10;
int b = 20;

輸入列表
:"r"(a),"r"(b)


[3]修改列表:在內聯彙編的時候,發生修改的暫存器


例如:在指令中使用了r0,r1,r2

修改列表

:"r0","r1","r2"

int  add(int a,int b)
{
		int c;
	
		asm(
			"add r0,%1,%2\n"
			"mov %0,r0\n"
			:"=r"(c)
			:"r"(a),"r"(b)
			:"r0"
		);
}
注意:C變數的引用,從輸入列表、輸出列表開始編號:第一個C變數 %0,第二個c變數%1,...


練習:實現以下函式
int disable_irq(void)
{
	int statu;
	
	return statu;
}

int enable_irq(void)
{
	int statu;
	
	return statu;
}

int main()
{
	disable_irq();//cpsr I:7bit -> 1
	enable_irq(); //cpsr I:7bit -> 0
	
	return 0;
}

三、volatile 含義 


volatile 修飾一個變數,防止編譯器優化,告訴編譯器每次在使用這個變數的時候,必須從變數所在的記憶體中重新讀值。


面試問題:在有中斷處理函式程式碼中使用全域性變數,有什麼需要注意的地方?
         定義全域性變數的時候,需要加volatile修飾
                 
                 
四、思考:如何判斷資料指定為是否為0?

	   int flag = 0;
	   
	   flag = data & (1 << 1);
	   
	   data的第1位為0
	   flag = 0
	   
	   data的第1位為1
	   flag = 2
	   
	        1 
	   0000010
		 
		 迴圈判斷第1位是否為0
		 do{
		 		flag = data & (1 << 1);
		 }while(!flag);