<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 嵌入式系統 > 設計應用 > ARM微處理器的編程模型之:異常中斷處理

ARM微處理器的編程模型之:異常中斷處理

作者: 時(shí)間:2013-09-13 來(lái)源:網(wǎng)絡(luò ) 收藏

本文引用地址:http://dyxdggzs.com/article/257085.htm

4.在特權模式下使用SWI異常處理

在特權模式下使用SWI異常處理,和IRQ/FIQ中斷嵌套基本類(lèi)似。當執行SWI指令后,處理器執行下面操作。

① 處理器進(jìn)入特權模式。

② 將程序狀態(tài)字內容CPSR保存到SPSR_svc。

③ 返回地址放入LR_svc。

如果處理器已經(jīng)處于特權模式,再發(fā)生SWI異常,則LR_svc和SPSR_svc寄存器的值將丟失。

所以在特權模式下,調用SWI軟中斷異常,必須先將LR_svc和SPSR_svc寄存器的值壓棧保護。下面的例子顯示了一個(gè)可以在特權模式下調用的SWI處理函數。

AREA SWI_Area, CODE, READONLY

PRESERVE8

EXPORT SWI_Handler

IMPORT C_SWI_Handler

T_bit EQU 0x20

SWI_Handler

STMFD sp!,{r0-r3,r12,lr} ;寄存器壓棧保護

MOV r1, sp ;堆棧指針?lè )舝1作為參數傳遞.

MRS r0, spsr ;讀取spsr.

STMFD sp!, {r0, r3} ;將spsr壓棧保護

;

;

LDR r0,[lr,#-4] ;計算SWI指令地址.

BIC r0,r0,#0xFF000000 ;讀取SWI中斷向量號.

; r0存放中斷向量號

; r1 堆棧指針

BL C_SWI_Handler ;調用C程序的SWI處理函數.

LDMFD sp!, {r0, r3} ;從堆棧中讀取spsr.

MSR spsr_cf, r0 ;恢復spcr

LDMFD sp!, {r0-r3,r12,pc}^ ;恢復其他寄存器并返回.

END

5.從應用程序中調用SWI

可從匯編語(yǔ)言或 C/C++ 中調用 SWI。

(1)從匯編應用程序中調用SWI

從匯編語(yǔ)言程序中調用SWI,只要遵循AAPCS標準即可。調用前,設定所有必須的值并發(fā)出相關(guān)的 SWI。例如:

MOV r0, #65 ; 將軟中斷的子功能號放到r0中

SWI 0x0

注意

SWI指令和其他所以指令一樣,可以被條件執行。

(2)從C應用程序中調用SWI

在C或C++應用程序中調用SWI,要將C語(yǔ)言的子程序用編譯器擴展_swi聲明,例如:

__swi(0) void my_swi(int);

……

……

……

my_swi(65);

編譯器擴展_swi確保了SWI以?xún)嚷?lián)方式進(jìn)行編譯,而沒(méi)有額外的開(kāi)銷(xiāo)。但有如下的AAPCS限制。

· 函數調用參數只能使用r0~r3傳遞。

· 函數返回值只能通過(guò)r0~r3傳遞。

向內聯(lián)的SWI函數傳遞參數和向實(shí)際的子函數傳遞參數基本類(lèi)似。但返回值的情況比較復雜。如果有兩到四個(gè)返回值,則必須告訴編譯程序返回值是以結構形式返回的,并使用__value_in_regs 偽操作聲明。這是因為基于結構值的函數通常被處理為一個(gè)void(空)型函數,且第一個(gè)自變量必須為存放結果結構的地址。

下面的例子顯示了對編號為0x0、0x1、0x2和0x3的SWI軟中斷的調用。其中,SWI0x0和SWI0x1傳遞兩個(gè)整型參數并返回一個(gè)單一結果;SWI0x2傳遞4個(gè)參數并返回一個(gè)單一結果;而SWI0x3傳遞4個(gè)參數并通過(guò)結構體返回4個(gè)結果。

#include stdio.h>

#include swi.h

unsigned *swi_vec = (unsigned *)0x08;

extern void SWI_Handler(void);

int main( void )

{

int result1, result2;

struct four_results res_3;

Install_Handler( (unsigned) SWI_Handler, swi_vec );

printf(result1 = multiply_two(2,4) = %dn, result1 = multiply_two(2,4));

printf(result2 = multiply_two(3,6) = %dn, result2 = multiply_two(3,6));

printf(add_two( result1, result2 ) = %dn, add_two( result1, result2 ));

printf(add_multiply_two(2,4,3,6) = %dn, add_multiply_two(2,4,3,6));

res_3 = many_operations( 12, 4, 3, 1 );

printf(res_3.a = %dn, res_3.a );

printf(res_3.b = %dn, res_3.b );

printf(res_3.c = %dn, res_3.c );

printf(res_3.d = %dn, res_3.d );

return 0;

}

__swi(0) int multiply_two(int, int);

__swi(1) int add_two(int, int);

__swi(2) int add_multiply_two(int, int, int, int);

struct four_results

{

int a;

int b;

int c;

int d;

};

__swi(3) __value_in_regs struct four_results many_operations(int, int, int, int);

(3)應用程序中動(dòng)態(tài)調用SWI

在某些情形下,需要調用直到運行時(shí)才會(huì )知道其編號的 SWI。例如,當有很多相關(guān)操作可在同一目標上執行,并且每一個(gè)操作都有其自己的 SWI 時(shí),就會(huì )發(fā)生這種情況。在此情況下,上一小節的方法不適用。

解決的方法有兩種。

· 在運行時(shí)得到SWI功能號,然后構造出相應的SWI指令的編碼,將該編碼保存在某個(gè)存儲單元中,將PC指針指向該單元,執行指令。

· 使用一個(gè)通用的SWI程序,將運行時(shí)需要調用的SWI功能號作為參數傳遞給該通用的SWI異常處理程序,通用的SWI程序根據參數值調用相應的SWI處理程序完成需要的操作。

通過(guò)匯編語(yǔ)言可以實(shí)現第二種解決辦法:通過(guò)寄存器(通常為r0或r12)傳遞所需要的操作數,這樣可以重新編寫(xiě)SWI處理程序,對相應寄存器中的值進(jìn)行處理。

但有些情況下,為了節省程序開(kāi)銷(xiāo),需要直接使用SWI中斷號對程序調用。例如,操作系統可能會(huì )使用單一的一條SWI指令并用寄存器來(lái)傳遞所需運算的編號。這使得其他SWI空間可用于特定應用程序的SWI。在一個(gè)特定的應用程序中,如果從指令中提取SWI編號的開(kāi)銷(xiāo)太大,就可使用這個(gè)方法。(0x123456)和Thumb(0xAB)半主機方式的SWI就是這樣實(shí)現的。



評論


相關(guān)推薦

技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>