彙編與C混合程式設計(6.19)
阿新 • • 發佈:2019-02-17
一 異常放回
<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
修改列表
練習:實現以下函式
<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);