通過SWI異常中斷指令,在使用者模式下應用程式可以調用系統模式下的代碼,在作業系統中表現為系統調用,
那這個過程又是如何?的呢?帶著疑問讓我們來學習吧!
在SWI指令中包括一個24位的立即數(中斷調用號),該立即數指示了使用者要請求的特定的調用功能,所以在SWI的異常中斷中要讀取這個中斷調用號,然後根據中斷號,來調用相應的處理常式。這個過程可以分兩個步驟:
1.SWI異常中斷處理常式
由於是在底層操作所以這個異常中斷處理常式得用組合語言編寫,描述如下:
area top_swi code readonly
export swi_headler
swi_headler
stmfd sp!, {r0-r12, lr} ; 儲存r0至r12,lr的寄存器值
ldr r0, [lr, #-4] ; 從儲存空間中取得SWI指令的所在地址
bic r0, r0, #FF000000 ; 讀取24位中斷調用號
mov r1, sp
;================================================
bl swi_service_func ; 調用功能服務函數,見下面
; 中斷調用號通過r0寄存器傳入
; 參數通過r1寄存器傳入
;================================================
ldmfd sp!, {r0-r12, pc}^ ;恢複調用前的r0至r12,離開中斷處理常式
end
2.功能服務程式
編寫利用從中斷處理函數獲得的中斷調用號我們可以寫出如下服務函數(為了簡單我們用C語言)
void swi_service_func(unsigned int number, unsigned int *reg)
{
unsigned int reg1, reg2, reg3, reg4;
//擷取SWI前傳入的參數
reg1 = reg[0];
reg2 = reg[1];
reg3 = reg[2];
reg4 = reg[3];
switch (number) {
case 0:
// do something
break;
case 1:
// do something
break;
.
.
.
case n:
// do something
break;
default:
// do something
}
}
// 更新結果存入r0-r3
reg[0] = updata_reg1;
reg[1] = updata_reg2;
reg[2] = updata_reg3;
reg[3] = updata_reg4;
}
這樣一來只要中調用斷號不同就可以實現不同的功能調用了,是不是很簡單?