久久婷婷香蕉热狠狠综合,精品无码国产自产拍在线观看蜜,寡妇房东在做爰3,中文字幕日本人妻久久久免费,国产成人精品三上悠亚久久

當前位置:首頁 > 嵌入式培訓 > 嵌入式學習 > 講師博文 > ARM處(chu)理器異(yi)常處(chu)理

ARM處理器異常處理 時間:2017-11-21      來源:未知

   異常(chang)處理(li)是ARM處理(li)處理(li)日常(chang)事(shi)務的(de)(de)一種重要方式,它是ARM體(ti)系結構的(de)(de)核心(xin)組成部分,也是理(li)解(jie)上的(de)(de)一個難點,在此(ci)專門撰文講解(jie)異常(chang)處理(li)的(de)(de)原理(li)及流程,為廣大學習ARM芯片的(de)(de)愛好者提供一點借鑒,如有(you)紕漏,請給予指正,謝謝。

 一.異常(chang)分類

(1)復位異常

    當CPU剛(gang)上(shang)電時或按下reset重啟鍵(jian)之后進入該(gai)異(yi)(yi)常,該(gai)異(yi)(yi)常在管理模式(shi)下處理。

(2)一般(ban)/快速中斷請(qing)求

    CPU和外部(bu)設(she)(she)(she)備(bei)是(shi)分(fen)別獨立的(de)硬件執行(xing)單元,CPU對全部(bu)設(she)(she)(she)備(bei)進行(xing)管理(li)(li)和資源調度處(chu)理(li)(li),CPU要(yao)想知道(dao)外部(bu)設(she)(she)(she)備(bei)的(de)運行(xing)狀態,要(yao)么CPU定時的(de)去(qu)查(cha)看外部(bu)設(she)(she)(she)備(bei)特定寄存(cun)器,要(yao)么讓(rang)外部(bu)設(she)(she)(she)備(bei)在出現需要(yao)CPU干涉(she)處(chu)理(li)(li)時“打斷(duan)”CPU,讓(rang)它來處(chu)理(li)(li)外部(bu)設(she)(she)(she)備(bei)的(de)請求(qiu),毫無疑問(wen)第二(er)種方式更合理(li)(li),可以(yi)讓(rang)CPU“專心”去(qu)工(gong)作,這里的(de)“打斷(duan)”操作就(jiu)叫做中(zhong)(zhong)斷(duan)請求(qiu),根據請求(qiu)的(de)緊急(ji)情況,中(zhong)(zhong)斷(duan)請求(qiu)分(fen)一般中(zhong)(zhong)斷(duan)和快速中(zhong)(zhong)斷(duan),快速中(zhong)(zhong)斷(duan)具有高(gao)中(zhong)(zhong)斷(duan)優先級(ji)和小的(de)中(zhong)(zhong)斷(duan)延遲,通常用(yong)于(yu)處(chu)理(li)(li)高(gao)速數據傳輸(shu)及(ji)通道(dao)的(de)中(zhong)(zhong)數據恢復處(chu)理(li)(li),如DMA等,絕(jue)大部(bu)分(fen)外設(she)(she)(she)使用(yong)一般中(zhong)(zhong)斷(duan)請求(qiu)。

(3)預(yu)取(qu)指令中止異常

    該異(yi)(yi)常(chang)(chang)發(fa)生在CPU流(liu)水線取(qu)指(zhi)(zhi)階段,如(ru)果(guo)目標指(zhi)(zhi)令(ling)地(di)址是非法(fa)地(di)址進入該異(yi)(yi)常(chang)(chang),該異(yi)(yi)常(chang)(chang)在中止異(yi)(yi)常(chang)(chang)模(mo)式下處理。

(4)未定義指令異常

    該(gai)異常(chang)發生在(zai)流水(shui)線技術里的譯碼(ma)階段,如果當(dang)前(qian)指(zhi)令(ling)(ling)不能被識別為有效指(zhi)令(ling)(ling),產生未(wei)定(ding)義指(zhi)令(ling)(ling)異常(chang),該(gai)異常(chang)在(zai)未(wei)定(ding)義異常(chang)模(mo)式下處理。

(5)軟(ruan)件中斷指令(swi)異(yi)常

    該(gai)異常是(shi)(shi)應用(yong)(yong)程(cheng)(cheng)序自己(ji)調用(yong)(yong)時(shi)產生的(de)(de),用(yong)(yong)于用(yong)(yong)戶(hu)(hu)程(cheng)(cheng)序申請(qing)(qing)訪(fang)問硬(ying)件資(zi)源(yuan)時(shi),例如:printf()打(da)(da)印函數,要(yao)將(jiang)用(yong)(yong)戶(hu)(hu)數據打(da)(da)印到顯(xian)示器(qi)上,用(yong)(yong)戶(hu)(hu)程(cheng)(cheng)序要(yao)想(xiang)實現(xian)打(da)(da)印必須申請(qing)(qing)使(shi)用(yong)(yong)顯(xian)示器(qi),而用(yong)(yong)戶(hu)(hu)程(cheng)(cheng)序又沒有(you)外(wai)設(she)硬(ying)件的(de)(de)使(shi)用(yong)(yong)權(quan),只能通過使(shi)用(yong)(yong)軟件中斷指令切換到內核(he)態(tai),通過操作(zuo)系(xi)統內核(he)代碼來訪(fang)問外(wai)設(she)硬(ying)件,內核(he)態(tai)是(shi)(shi)工作(zuo)在特權(quan)模式(shi)(shi)下(xia)(xia),操作(zuo)系(xi)統在特權(quan)模式(shi)(shi)下(xia)(xia)完成將(jiang)用(yong)(yong)戶(hu)(hu)數據打(da)(da)印到顯(xian)示器(qi)上。這樣做的(de)(de)目的(de)(de)無非(fei)是(shi)(shi)為了(le)保護(hu)操作(zuo)系(xi)統的(de)(de)安全(quan)和硬(ying)件資(zi)源(yuan)的(de)(de)合理(li)使(shi)用(yong)(yong),該(gai)異常在管理(li)模式(shi)(shi)下(xia)(xia)處(chu)理(li)。

(6)數據中(zhong)止訪問異常

    該(gai)異(yi)常(chang)發生在要訪問數據地址(zhi)不(bu)存(cun)在或者為非(fei)法地址(zhi)時,該(gai)異(yi)常(chang)在中止異(yi)常(chang)模式下處理。

二. 異常發生的硬件操作

    在異常發生后(hou),ARM內核會自動做以下工作(zuo):

     a.保存執行狀態:將CPSR復制到發生的異常(chang)模式下SPSR中(zhong);

    b.模式切換(huan):將(jiang)CPSR模式位(wei)強(qiang)制設(she)置為與異常類(lei)型相對應的(de)值,同時處(chu)理器進入到ARM執行模式,禁止所有IRQ中斷,當進入FIQ快速(su)中斷模式時禁止FIQ中斷;

    c.保存返回地(di)址:將(jiang)下一(yi)條指令的(de)地(di)址(被(bei)打斷程序)保存在LR(異常模式(shi)下LR_excep)中。

    d.跳入異常向量表(biao):強(qiang)制(zhi)設置PC的值為相(xiang)應異常向量地址,跳轉到(dao)異常處理(li)程序中。

(1)保存(cun)執行狀態

    當前程序的(de)執行(xing)狀(zhuang)態是保存在(zai)CPSR里面的(de),異(yi)常(chang)(chang)發生時,要保存當前的(de)CPSR里的(de)執行(xing)狀(zhuang)態到異(yi)常(chang)(chang)模式里的(de)SPSR里,將來(lai)異(yi)常(chang)(chang)返回(hui)時,恢復回(hui)CPSR,恢復執行(xing)狀(zhuang)態。

(2)模式切(qie)換(huan)

    硬件自(zi)動(dong)根據當(dang)前(qian)的(de)異(yi)(yi)常類(lei)型(xing),將異(yi)(yi)常碼寫入CPSR里的(de)M[4:0]模式位,這樣CPU就(jiu)進入了對應異(yi)(yi)常模式下。不管(guan)是(shi)在(zai)ARM狀(zhuang)態下還是(shi)在(zai)THUMB狀(zhuang)態下發生異(yi)(yi)常,都會自(zi)動(dong)切換(huan)到ARM狀(zhuang)態下進行(xing)異(yi)(yi)常的(de)處(chu)理(li),這是(shi)由(you)硬件自(zi)動(dong)完成的(de),將CPSR[5] 設(she)置(zhi)為 0。同時(shi),CPU會關(guan)閉中(zhong)(zhong)(zhong)斷(duan)IRQ(設(she)置(zhi)CPSR 寄存器(qi)I位),防止中(zhong)(zhong)(zhong)斷(duan)進入,如果(guo)當(dang)前(qian)是(shi)快(kuai)速中(zhong)(zhong)(zhong)斷(duan)FIQ異(yi)(yi)常,關(guan)閉快(kuai)速中(zhong)(zhong)(zhong)斷(duan)(設(she)置(zhi)CPSR寄存器(qi)F位)。

(3)保存返回(hui)地址

    當前程序(xu)被異(yi)常(chang)(chang)(chang)打斷,切換(huan)到(dao)異(yi)常(chang)(chang)(chang)處理程序(xu)里(li)(li),異(yi)常(chang)(chang)(chang)處理完之(zhi)后,返(fan)回當前被打斷模式(shi)繼續(xu)執行,因此必須(xu)要(yao)保存(cun)當前執行指令的下一條指令的地址(zhi)到(dao)LR_excep(異(yi)常(chang)(chang)(chang)模式(shi)下LR,并不(bu)存(cun)在LR_excep寄存(cun)器(qi),為方(fang)便(bian)讀者理解(jie)加上(shang)_excep,以下道理相同(tong)),由(you)于(yu)異(yi)常(chang)(chang)(chang)模式(shi)不(bu)同(tong)以及ARM內核采用(yong)流(liu)水線技術(shu),異(yi)常(chang)(chang)(chang)處理程序(xu)里(li)(li)要(yao)根據異(yi)常(chang)(chang)(chang)模式(shi)計(ji)算返(fan)回地址(zhi)。

(4)跳入異常向量表(biao)

    該操作是CPU硬(ying)件(jian)自動完成的(de),當異常發生時,CPU強制將PC的(de)值修改為一個固定內存地(di)址,這個固定地(di)址叫做異常向量。

三.異常(chang)返回地址

    一(yi)條(tiao)指(zhi)(zhi)令的(de)執行分為(wei):取指(zhi)(zhi),譯碼,執行三個主要(yao)階段, CPU由(you)于(yu)使用流水線技(ji)術,造成當前(qian)執行指(zhi)(zhi)令的(de)地(di)址應該是(shi)PC – 8(32位(wei)機一(yi)條(tiao)指(zhi)(zhi)令四個字節),那么執行指(zhi)(zhi)令的(de)下條(tiao)指(zhi)(zhi)令應該是(shi)PC – 4。在異常(chang)發生時,CPU自動會將(jiang)將(jiang)PC – 4 的(de)值保存到(dao)LR里,但是(shi)該值是(shi)否正確還要(yao)看異常(chang)類型才能決(jue)定(ding)。

各(ge)模式的返回地址(zhi)說明如(ru)下:

(a)一般/快速中斷請求(qiu):

    快速中(zhong)(zhong)斷(duan)(duan)(duan)請求和一般中(zhong)(zhong)斷(duan)(duan)(duan)請求返(fan)回處(chu)(chu)理是一樣的(de)。通常處(chu)(chu)理器(qi)執行完(wan)當(dang)(dang)(dang)(dang)前(qian)指(zhi)(zhi)(zhi)(zhi)(zhi)令(ling)(ling)(ling)后(hou),查詢FIQ/IRQ中(zhong)(zhong)斷(duan)(duan)(duan)引腳,并(bing)查看是否允許(xu)FIQ/IRQ中(zhong)(zhong)斷(duan)(duan)(duan),如果(guo)某個中(zhong)(zhong)斷(duan)(duan)(duan)引腳有效,并(bing)且系統允許(xu)該中(zhong)(zhong)斷(duan)(duan)(duan)產(chan)生(sheng),處(chu)(chu)理器(qi)將(jiang)產(chan)生(sheng)FIQ/IRQ異常中(zhong)(zhong)斷(duan)(duan)(duan),當(dang)(dang)(dang)(dang)FIQ/IRQ異常中(zhong)(zhong)斷(duan)(duan)(duan)產(chan)生(sheng)時,程序(xu)計數器(qi)pc的(de)值已經更新(xin),它指(zhi)(zhi)(zhi)(zhi)(zhi)向當(dang)(dang)(dang)(dang)前(qian)指(zhi)(zhi)(zhi)(zhi)(zhi)令(ling)(ling)(ling)后(hou)面(mian)第(di)3條(tiao)指(zhi)(zhi)(zhi)(zhi)(zhi)令(ling)(ling)(ling)(對于ARM指(zhi)(zhi)(zhi)(zhi)(zhi)令(ling)(ling)(ling),它指(zhi)(zhi)(zhi)(zhi)(zhi)向當(dang)(dang)(dang)(dang)前(qian)指(zhi)(zhi)(zhi)(zhi)(zhi)令(ling)(ling)(ling)地址加12字節(jie)(jie)的(de)位置;對于Thumb指(zhi)(zhi)(zhi)(zhi)(zhi)令(ling)(ling)(ling),它指(zhi)(zhi)(zhi)(zhi)(zhi)向當(dang)(dang)(dang)(dang)前(qian)指(zhi)(zhi)(zhi)(zhi)(zhi)令(ling)(ling)(ling)地址加6字節(jie)(jie)的(de)位置),當(dang)(dang)(dang)(dang)FIQ/IRQ異常中(zhong)(zhong)斷(duan)(duan)(duan)產(chan)生(sheng)時,處(chu)(chu)理器(qi)將(jiang)值(pc-4)保存到(dao)FIQ/IRQ異常模(mo)式下的(de)寄存器(qi)lr_irq/lr_irq中(zhong)(zhong),它指(zhi)(zhi)(zhi)(zhi)(zhi)向當(dang)(dang)(dang)(dang)前(qian)指(zhi)(zhi)(zhi)(zhi)(zhi)令(ling)(ling)(ling)之后(hou)的(de)第(di)2條(tiao)指(zhi)(zhi)(zhi)(zhi)(zhi)令(ling)(ling)(ling),因此正確返(fan)回地址可以通過下面(mian)指(zhi)(zhi)(zhi)(zhi)(zhi)令(ling)(ling)(ling)算(suan)出:

SUBS    PC,LR_irq,#4        ; 一般中斷

SUBS    PC,LR_fiq,#4      ;  ; 快速中斷

注:LR_irq/LR_fiq分別為(wei)一般中(zhong)(zhong)斷和(he)快(kuai)速中(zhong)(zhong)斷異常(chang)模式下LR,并不存(cun)在LR_xxx寄存(cun)器,為(wei)方便讀者理解加上_xxx

(b)預取指(zhi)中止異常:

    在指令(ling)(ling)(ling)(ling)(ling)預(yu)取(qu)時(shi),如果(guo)目標地(di)址是(shi)非法的,該指令(ling)(ling)(ling)(ling)(ling)被(bei)標記成有(you)問題(ti)的指令(ling)(ling)(ling)(ling)(ling),這時(shi),流(liu)水線上(shang)該指令(ling)(ling)(ling)(ling)(ling)之(zhi)前的指令(ling)(ling)(ling)(ling)(ling)繼(ji)續執(zhi)行,當執(zhi)行到(dao)該被(bei)標記成有(you)問題(ti)的指令(ling)(ling)(ling)(ling)(ling)時(shi),處(chu)理器產(chan)生(sheng)指令(ling)(ling)(ling)(ling)(ling)預(yu)取(qu)中(zhong)止(zhi)異常中(zhong)斷(duan)。發生(sheng)指令(ling)(ling)(ling)(ling)(ling)預(yu)取(qu)異常中(zhong)斷(duan)時(shi),程序要返(fan)回(hui)到(dao)該有(you)問題(ti)的指令(ling)(ling)(ling)(ling)(ling)處(chu),重新讀取(qu)并(bing)執(zhi)行該指令(ling)(ling)(ling)(ling)(ling),因此指令(ling)(ling)(ling)(ling)(ling)預(yu)取(qu)中(zhong)止(zhi)異常中(zhong)斷(duan)應(ying)該返(fan)回(hui)到(dao)產(chan)生(sheng)該指令(ling)(ling)(ling)(ling)(ling)預(yu)取(qu)中(zhong)止(zhi)異常中(zhong)斷(duan)的指令(ling)(ling)(ling)(ling)(ling)處(chu),而不是(shi)當前指令(ling)(ling)(ling)(ling)(ling)的下一條指令(ling)(ling)(ling)(ling)(ling)。 

    指(zhi)(zhi)(zhi)(zhi)令(ling)(ling)(ling)預(yu)取中(zhong)止異常中(zhong)斷由當(dang)前(qian)(qian)執(zhi)(zhi)行(xing)的(de)(de)指(zhi)(zhi)(zhi)(zhi)令(ling)(ling)(ling)在ALU里執(zhi)(zhi)行(xing)時(shi)產(chan)生(sheng),當(dang)指(zhi)(zhi)(zhi)(zhi)令(ling)(ling)(ling)預(yu)取中(zhong)止異常中(zhong)斷發(fa)生(sheng)時(shi),程(cheng)序計數器(qi)pc的(de)(de)值還未(wei)更(geng)新,它(ta)指(zhi)(zhi)(zhi)(zhi)向當(dang)前(qian)(qian)指(zhi)(zhi)(zhi)(zhi)令(ling)(ling)(ling)后面第(di)2條指(zhi)(zhi)(zhi)(zhi)令(ling)(ling)(ling)(對于ARM指(zhi)(zhi)(zhi)(zhi)令(ling)(ling)(ling),它(ta)指(zhi)(zhi)(zhi)(zhi)向當(dang)前(qian)(qian)指(zhi)(zhi)(zhi)(zhi)令(ling)(ling)(ling)地址(zhi)加8字節的(de)(de)位(wei)置;對于Thumb指(zhi)(zhi)(zhi)(zhi)令(ling)(ling)(ling),它(ta)指(zhi)(zhi)(zhi)(zhi)向當(dang)前(qian)(qian)指(zhi)(zhi)(zhi)(zhi)令(ling)(ling)(ling)地址(zhi)加4字節的(de)(de)位(wei)置)。此時(shi)處理(li)器(qi)將值(pc-4)保存到lr_abt中(zhong),它(ta)指(zhi)(zhi)(zhi)(zhi)向當(dang)前(qian)(qian)指(zhi)(zhi)(zhi)(zhi)令(ling)(ling)(ling)的(de)(de)下(xia)(xia)一條指(zhi)(zhi)(zhi)(zhi)令(ling)(ling)(ling),所以返回操作可以通過(guo)下(xia)(xia)面指(zhi)(zhi)(zhi)(zhi)令(ling)(ling)(ling)實(shi)現:

SUBS  PC,LR_abt,#4

注:LR_abt為中止(zhi)模式下LR,并不存在LR_abt寄存器,為方便讀者(zhe)理解加上_abt

(c)未定義(yi)指令異(yi)常:

    未(wei)(wei)定(ding)義指(zhi)(zhi)(zhi)(zhi)令(ling)(ling)(ling)(ling)(ling)(ling)異常(chang)(chang)(chang)中斷由(you)當前(qian)執(zhi)行的(de)(de)指(zhi)(zhi)(zhi)(zhi)令(ling)(ling)(ling)(ling)(ling)(ling)在ALU里(li)執(zhi)行時(shi)產生,當未(wei)(wei)定(ding)義指(zhi)(zhi)(zhi)(zhi)令(ling)(ling)(ling)(ling)(ling)(ling)異常(chang)(chang)(chang)中斷產生時(shi),程序計(ji)數器(qi)(qi)pc的(de)(de)值還未(wei)(wei)更新(xin),它(ta)(ta)指(zhi)(zhi)(zhi)(zhi)向(xiang)當前(qian)指(zhi)(zhi)(zhi)(zhi)令(ling)(ling)(ling)(ling)(ling)(ling)后面第2條指(zhi)(zhi)(zhi)(zhi)令(ling)(ling)(ling)(ling)(ling)(ling)(對(dui)于(yu)ARM指(zhi)(zhi)(zhi)(zhi)令(ling)(ling)(ling)(ling)(ling)(ling),它(ta)(ta)指(zhi)(zhi)(zhi)(zhi)向(xiang)當前(qian)指(zhi)(zhi)(zhi)(zhi)令(ling)(ling)(ling)(ling)(ling)(ling)地(di)址加8字(zi)節的(de)(de)位(wei)(wei)置(zhi);對(dui)于(yu)Thumb指(zhi)(zhi)(zhi)(zhi)令(ling)(ling)(ling)(ling)(ling)(ling),它(ta)(ta)指(zhi)(zhi)(zhi)(zhi)向(xiang)當前(qian)指(zhi)(zhi)(zhi)(zhi)令(ling)(ling)(ling)(ling)(ling)(ling)地(di)址加4字(zi)節的(de)(de)位(wei)(wei)置(zhi)),當未(wei)(wei)定(ding)義指(zhi)(zhi)(zhi)(zhi)令(ling)(ling)(ling)(ling)(ling)(ling)異常(chang)(chang)(chang)中斷發生時(shi),處理器(qi)(qi)將(jiang)值(pc-4)保(bao)存(cun)到lr_und中,此時(shi)(pc-4)指(zhi)(zhi)(zhi)(zhi)向(xiang)當前(qian)指(zhi)(zhi)(zhi)(zhi)令(ling)(ling)(ling)(ling)(ling)(ling)的(de)(de)下一(yi)條指(zhi)(zhi)(zhi)(zhi)令(ling)(ling)(ling)(ling)(ling)(ling),所以(yi)從(cong)未(wei)(wei)定(ding)義指(zhi)(zhi)(zhi)(zhi)令(ling)(ling)(ling)(ling)(ling)(ling)異常(chang)(chang)(chang)中斷返回可以(yi)通過如下指(zhi)(zhi)(zhi)(zhi)令(ling)(ling)(ling)(ling)(ling)(ling)來實現:

MOV  PC,  LR_und

注(zhu):LR_und為(wei)未定義模式下(xia)LR,并不存(cun)(cun)在LR_und寄(ji)存(cun)(cun)器,為(wei)方便讀者理解加上_und

(d)軟中斷指令(SWI)異常:

    SWI異(yi)(yi)常(chang)中(zhong)斷(duan)和未定(ding)義(yi)異(yi)(yi)常(chang)中(zhong)斷(duan)指(zhi)(zhi)(zhi)(zhi)令(ling)(ling)(ling)一樣,也是由(you)當前執(zhi)行的(de)指(zhi)(zhi)(zhi)(zhi)令(ling)(ling)(ling)在ALU里執(zhi)行時(shi)產生(sheng),當SWI指(zhi)(zhi)(zhi)(zhi)令(ling)(ling)(ling)執(zhi)行時(shi),pc的(de)值(zhi)還未更新(xin),它(ta)指(zhi)(zhi)(zhi)(zhi)向(xiang)(xiang)當前指(zhi)(zhi)(zhi)(zhi)令(ling)(ling)(ling)后面第2條指(zhi)(zhi)(zhi)(zhi)令(ling)(ling)(ling)(對(dui)于ARM指(zhi)(zhi)(zhi)(zhi)令(ling)(ling)(ling),它(ta)指(zhi)(zhi)(zhi)(zhi)向(xiang)(xiang)當前指(zhi)(zhi)(zhi)(zhi)令(ling)(ling)(ling)地(di)址(zhi)加8字(zi)節的(de)位(wei)置(zhi);對(dui)于Thumb指(zhi)(zhi)(zhi)(zhi)令(ling)(ling)(ling),它(ta)指(zhi)(zhi)(zhi)(zhi)向(xiang)(xiang)當前指(zhi)(zhi)(zhi)(zhi)令(ling)(ling)(ling)地(di)址(zhi)加4字(zi)節的(de)位(wei)置(zhi)),當未定(ding)義(yi)指(zhi)(zhi)(zhi)(zhi)令(ling)(ling)(ling)異(yi)(yi)常(chang)中(zhong)斷(duan)發生(sheng)時(shi),處理器將值(zhi)(pc-4)保存(cun)到lr_svc中(zhong),此(ci)時(shi)(pc-4)指(zhi)(zhi)(zhi)(zhi)向(xiang)(xiang)當前指(zhi)(zhi)(zhi)(zhi)令(ling)(ling)(ling)的(de)下一條指(zhi)(zhi)(zhi)(zhi)令(ling)(ling)(ling),所以從SWI異(yi)(yi)常(chang)中(zhong)斷(duan)處理返(fan)回的(de)實現(xian)方法(fa)與從未定(ding)義(yi)指(zhi)(zhi)(zhi)(zhi)令(ling)(ling)(ling)異(yi)(yi)常(chang)中(zhong)斷(duan)處理返(fan)回一樣:

MOV  PC,  LR_svc

 注:LR_svc為管(guan)理(li)模(mo)式下(xia)LR,并不存在LR_svc寄(ji)存器,為方(fang)便(bian)讀者理(li)解加上_svc

(e)數據中止異常:

    發生(sheng)數據(ju)訪(fang)問(wen)(wen)異常中(zhong)斷時,程序要(yao)返回(hui)到(dao)(dao)該(gai)有問(wen)(wen)題的(de)指(zhi)令處,重新訪(fang)問(wen)(wen)該(gai)數據(ju),因此(ci)數據(ju)訪(fang)問(wen)(wen)異常中(zhong)斷應該(gai)返回(hui)到(dao)(dao)產生(sheng)該(gai)數據(ju)訪(fang)問(wen)(wen)中(zhong)止異常中(zhong)斷的(de)指(zhi)令處,而不是當前(qian)指(zhi)令的(de)下一條指(zhi)令。

    數據訪(fang)問異常(chang)中(zhong)斷(duan)(duan)由當(dang)前(qian)執(zhi)行的指(zhi)(zhi)令(ling)(ling)(ling)(ling)(ling)(ling)在ALU里(li)執(zhi)行時產生,當(dang)數據訪(fang)問異常(chang)中(zhong)斷(duan)(duan)發生時,程序計數器(qi)pc的值(zhi)已(yi)經更(geng)新,它(ta)指(zhi)(zhi)向當(dang)前(qian)指(zhi)(zhi)令(ling)(ling)(ling)(ling)(ling)(ling)后面第3條(tiao)指(zhi)(zhi)令(ling)(ling)(ling)(ling)(ling)(ling)(對于(yu)ARM指(zhi)(zhi)令(ling)(ling)(ling)(ling)(ling)(ling),它(ta)指(zhi)(zhi)向當(dang)前(qian)指(zhi)(zhi)令(ling)(ling)(ling)(ling)(ling)(ling)地址(zhi)加12字節的位置(zhi);對于(yu)Thumb指(zhi)(zhi)令(ling)(ling)(ling)(ling)(ling)(ling),它(ta)指(zhi)(zhi)向當(dang)前(qian)指(zhi)(zhi)令(ling)(ling)(ling)(ling)(ling)(ling)地址(zhi)加6字節的位置(zhi))。此時處理器(qi)將值(zhi)(pc-4)保存到lr_abt中(zhong),它(ta)指(zhi)(zhi)向當(dang)前(qian)指(zhi)(zhi)令(ling)(ling)(ling)(ling)(ling)(ling)后面第2條(tiao)指(zhi)(zhi)令(ling)(ling)(ling)(ling)(ling)(ling),所(suo)以返回操作可以通過(guo)下面指(zhi)(zhi)令(ling)(ling)(ling)(ling)(ling)(ling)實現:

SUBS  PC,  LR_abt,  #8

注(zhu):LR_abt為中止(zhi)模(mo)式(shi)下LR,并不存(cun)在(zai)LR_abt寄(ji)存(cun)器,為方便讀者理解加上_abt

    上述每(mei)一種異(yi)(yi)常發生(sheng)時(shi),其返(fan)(fan)回地(di)址都要(yao)根據具體異(yi)(yi)常類型進行重新(xin)修復返(fan)(fan)回地(di)址,再次強調下,被打斷程序的(de)返(fan)(fan)回地(di)址保存(cun)在對應異(yi)(yi)常模式(shi)下的(de)LR_excep里。

四.異常向量表(biao)

    異常(chang)向量(liang)表(biao)是(shi)一(yi)段特定(ding)內(nei)存(cun)地址空間,每種(zhong)ARM異常(chang)對應(ying)一(yi)個字(zi)長空間(4Bytes),正(zheng)好是(shi)一(yi)條32位指令長度,當(dang)異常(chang)發(fa)生(sheng)時,CPU強制將(jiang)PC的(de)值設置為當(dang)前異常(chang)對應(ying)的(de)固定(ding)內(nei)存(cun)地址。如表(biao)3-4所示是(shi)S3C2440的(de)異常(chang)向量(liang)表(biao)。

注:

    異常(chang)(chang)向量也可(ke)以出(chu)現在高地址(zhi)0xFFFF0000處(chu),當今操作系統為了(le)控制內存(cun)訪問權限(xian),通(tong)常(chang)(chang)會開(kai)(kai)(kai)啟虛(xu)擬(ni)內存(cun),開(kai)(kai)(kai)啟了(le)虛(xu)擬(ni)內存(cun)之(zhi)后(hou),內存(cun)的開(kai)(kai)(kai)始空(kong)(kong)間(jian)(jian)通(tong)常(chang)(chang)為內核進程空(kong)(kong)間(jian)(jian),和頁表空(kong)(kong)間(jian)(jian),異常(chang)(chang)向量表不能再安裝在0地址(zhi)處(chu)了(le)

ARM的(de)例外優先級從高到低依次為Reset→Data abort→FIQ→IRQ→Prefetch abort→Undefined instruction/SWI。

跳(tiao)入(ru)異常(chang)向(xiang)量表操(cao)作是異常(chang)發生時,硬件(jian)自(zi)動完(wan)成(cheng)的(de)(de),剩下的(de)(de)異常(chang)處(chu)理(li)任(ren)務完(wan)全交給了(le)程序(xu)員。由上(shang)表可知,異常(chang)向(xiang)量是一個固定(ding)的(de)(de)內(nei)存地址,我(wo)(wo)們(men)可以通過向(xiang)該(gai)地址處(chu)寫一條跳(tiao)轉指令,讓它跳(tiao)向(xiang)我(wo)(wo)們(men)自(zi)己定(ding)義(yi)的(de)(de)異常(chang)處(chu)理(li)程序(xu)的(de)(de)入(ru)口,就可以完(wan)成(cheng)異常(chang)處(chu)理(li)了(le)。

正是(shi)由于(yu)異(yi)(yi)常(chang)向量(liang)表(biao)的(de)存(cun)(cun)在(zai)(zai),才讓硬件(jian)異(yi)(yi)常(chang)處理(li)(li)和程序員自(zi)定義處理(li)(li)程序有機聯(lian)系起來(lai)。異(yi)(yi)常(chang)向量(liang)表(biao)里0x00000000地址(zhi)處是(shi)reset復(fu)位(wei)異(yi)(yi)常(chang),之(zhi)所以(yi)它(ta)(ta)為0地址(zhi),是(shi)因為CPU在(zai)(zai)上電時(shi)(shi)自(zi)動從0地址(zhi)處加載指令(ling),由此可(ke)(ke)見(jian)將(jiang)復(fu)位(wei)異(yi)(yi)常(chang)安(an)裝(zhuang)(zhuang)在(zai)(zai)此地址(zhi)處也(ye)是(shi)前后(hou)(hou)接合起來(lai)設計(ji)的(de),不(bu)得(de)不(bu)感嘆CPU設計(ji)師的(de)偉大(da)(da),其(qi)(qi)后(hou)(hou)面分別(bie)是(shi)其(qi)(qi)余7種(zhong)異(yi)(yi)常(chang)向量(liang),每種(zhong)異(yi)(yi)常(chang)向量(liang)都占(zhan)有四個(ge)字節(jie)(jie),正好是(shi)一(yi)(yi)(yi)條(tiao)指令(ling)的(de)大(da)(da)小,后(hou)(hou)一(yi)(yi)(yi)個(ge)異(yi)(yi)常(chang)是(shi)快(kuai)速(su)中斷異(yi)(yi)常(chang),將(jiang)其(qi)(qi)安(an)裝(zhuang)(zhuang)在(zai)(zai)此也(ye)有它(ta)(ta)的(de)意義,在(zai)(zai)0x0000001C地址(zhi)處可(ke)(ke)以(yi)直接存(cun)(cun)放(fang)快(kuai)速(su)中斷的(de)處理(li)(li)程序,不(bu)用設置跳轉指令(ling),這(zhe)樣可(ke)(ke)以(yi)節(jie)(jie)省一(yi)(yi)(yi)個(ge)時(shi)(shi)鐘(zhong)周期,加快(kuai)快(kuai)速(su)中斷處理(li)(li)時(shi)(shi)間。

 我(wo)們可以通過簡單的(de)使用下面的(de)指令來安裝異(yi)常向(xiang)量表:

b reset                    ;;跳入reset處(chu)理(li)程(cheng)序

b HandleUndef              ;跳(tiao)入未(wei)定義處理程序

b HandSWI                  ;跳入(ru)軟中斷處理程(cheng)序

b HandPrefetchAbt          ;跳入預取(qu)指令(ling)處理程序

b HandDataAbt            ;  ;跳入數據訪問中止處理(li)程(cheng)序

b HandNoUsed               ;跳入未使用程序(xu)

b HandleIRQ                ;跳入中(zhong)斷(duan)處理程序(xu)

b HandleFIQ                ;跳入快(kuai)速中斷處理程序(xu)

    通(tong)常安裝完異常向量(liang)表(biao),跳到我(wo)們自己定(ding)義的(de)處理程序(xu)入口(kou),這時我(wo)們還沒有保存被打(da)斷程序(xu)的(de)現場(chang),因(yin)此在(zai)異常處理程序(xu)的(de)入口(kou)里先要保存打(da)斷程序(xu)現場(chang)。

保(bao)存執行現場:

    異常處(chu)理程(cheng)序開始,要保(bao)存(cun)被打斷程(cheng)序的執行現場,程(cheng)序的執行現場無非就(jiu)是保(bao)存(cun)當前操(cao)作寄存(cun)器里(li)的數據(ju),可以通過下面的棧操(cao)作指令實現保(bao)存(cun)現場:

STMFD  SP_excep!,  {R0 – R12,  LR_excep}

注:LR_abt,SP_excep分別為對應異常模式下(xia)LR和(he)SP,為方便讀者理(li)解加(jia)上(shang)_abt

    需要(yao)注意的(de)是(shi)(shi),在(zai)(zai)跳(tiao)轉到異(yi)(yi)常處理程(cheng)(cheng)序入口時(shi),已經切換到對應異(yi)(yi)常模(mo)式(shi)下了,因此(ci)這里的(de)SP是(shi)(shi)異(yi)(yi)常模(mo)式(shi)下的(de)SP_excep了,所以被(bei)打(da)斷程(cheng)(cheng)序現(xian)場(chang)(寄存(cun)器數據(ju))是(shi)(shi)保存(cun)在(zai)(zai)異(yi)(yi)常模(mo)式(shi)下的(de)棧里,上述(shu)指(zhi)令將(jiang)R0~R12全部都保存(cun)到了異(yi)(yi)常模(mo)式(shi)棧,后將(jiang)修改完的(de)被(bei)打(da)斷程(cheng)(cheng)序返回地(di)址(zhi)入棧保存(cun),之所以保存(cun)該返回地(di)址(zhi)就是(shi)(shi)將(jiang)來可以通過類似:MOV  PC,  LR的(de)指(zhi)令,返回用戶(hu)程(cheng)(cheng)序繼續(xu)執行。

    異(yi)常發生后,要(yao)針對(dui)異(yi)常類型進行處(chu)理(li),因此(ci),每種異(yi)常都有自己的異(yi)常處(chu)理(li)程序,異(yi)常處(chu)理(li)過程通(tong)過下(xia)節(jie)的系統中斷(duan)處(chu)理(li)來進行分析。

異常處(chu)理的(de)返回

 

異(yi)常處理(li)完成之(zhi)后,返回(hui)被打(da)斷程序繼續(xu)執行,具體操作如(ru)下:

l  恢復被打斷(duan)程序運行時寄存器數據

l  恢復程(cheng)序運行時狀態CPSR

l  通過進入異(yi)常時保存的返(fan)回地址,返(fan)回到被打斷(duan)程序繼續(xu)執行(xing)

異(yi)(yi)(yi)常(chang)(chang)發生后,進入(ru)異(yi)(yi)(yi)常(chang)(chang)處(chu)理(li)(li)程(cheng)序時(shi)(shi),將用戶程(cheng)序寄存(cun)器R0~R12里(li)(li)(li)的(de)(de)(de)數(shu)據(ju)保存(cun)在了(le)(le)異(yi)(yi)(yi)常(chang)(chang)模(mo)(mo)(mo)式(shi)下(xia)棧里(li)(li)(li)面,異(yi)(yi)(yi)常(chang)(chang)處(chu)理(li)(li)完返回時(shi)(shi),要將棧里(li)(li)(li)保存(cun)的(de)(de)(de)的(de)(de)(de)數(shu)據(ju)再恢(hui)復(fu)(fu)回原(yuan)先R0~R12里(li)(li)(li),毫無(wu)疑問在異(yi)(yi)(yi)常(chang)(chang)處(chu)理(li)(li)過程(cheng)中(zhong)必須要保證異(yi)(yi)(yi)常(chang)(chang)處(chu)理(li)(li)入(ru)口和出口時(shi)(shi)棧指(zhi)針(zhen)SP_excep要一樣(yang),否(fou)則恢(hui)復(fu)(fu)到R0~R12里(li)(li)(li)的(de)(de)(de)數(shu)據(ju)不正確,返回被打斷程(cheng)序時(shi)(shi)執(zhi)(zhi)行現場(chang)不一致,出現問題,雖然(ran)將執(zhi)(zhi)行現場(chang)恢(hui)復(fu)(fu)了(le)(le),但(dan)是(shi)此時(shi)(shi)還是(shi)在異(yi)(yi)(yi)常(chang)(chang)模(mo)(mo)(mo)式(shi)下(xia),CPSR里(li)(li)(li)的(de)(de)(de)狀(zhuang)態(tai)(tai)是(shi)異(yi)(yi)(yi)常(chang)(chang)模(mo)(mo)(mo)式(shi)下(xia)狀(zhuang)態(tai)(tai),因(yin)此要恢(hui)復(fu)(fu)SPSR_excep里(li)(li)(li)的(de)(de)(de)保存(cun)狀(zhuang)態(tai)(tai)到CPSR里(li)(li)(li),SPSR_excep是(shi)被打斷程(cheng)序執(zhi)(zhi)行時(shi)(shi)的(de)(de)(de)狀(zhuang)態(tai)(tai),在恢(hui)復(fu)(fu)SPSR_excep到CPSR的(de)(de)(de)同(tong)時(shi)(shi),CPU的(de)(de)(de)模(mo)(mo)(mo)式(shi)和狀(zhuang)態(tai)(tai)從異(yi)(yi)(yi)常(chang)(chang)模(mo)(mo)(mo)式(shi)切換回了(le)(le)被打斷程(cheng)序執(zhi)(zhi)行時(shi)(shi)的(de)(de)(de)模(mo)(mo)(mo)式(shi)和狀(zhuang)態(tai)(tai)。此刻程(cheng)序現場(chang)恢(hui)復(fu)(fu)了(le)(le),狀(zhuang)態(tai)(tai)也恢(hui)復(fu)(fu)了(le)(le),但(dan)PC里(li)(li)(li)的(de)(de)(de)值(zhi)(zhi)仍然(ran)指(zhi)向異(yi)(yi)(yi)常(chang)(chang)模(mo)(mo)(mo)式(shi)下(xia)的(de)(de)(de)地(di)址(zhi)空間,我們要讓CPU繼續執(zhi)(zhi)行被打斷程(cheng)序,因(yin)此要再手動改變PC的(de)(de)(de)值(zhi)(zhi)為進入(ru)異(yi)(yi)(yi)常(chang)(chang)時(shi)(shi)的(de)(de)(de)返回地(di)址(zhi),該地(di)址(zhi)在異(yi)(yi)(yi)常(chang)(chang)處(chu)理(li)(li)入(ru)口時(shi)(shi)已經計算好,直接將PC = LR_excep即可(ke)。

    上述操作可以一步(bu)一步(bu)實現,但(dan)是通常我(wo)們可以通過(guo)一條指令實現上述全部操作:

LDMFD  SP_excp!,  {r0-r12,  pc}^

注:SP_excep為(wei)對應異(yi)常模(mo)式(shi)下SP,^符號表示(shi)恢復SPSR_excep到(dao)CPSR

以(yi)下是軟件中斷模(mo)擬異常處理的(de)代碼:

.text

b reset  @0x00 reset

ldr pc,_udef_handler @0x04 udef

ldr pc,_swi_handler    @0x08 swi

ldr pc,_prefetch_interrupt   @0x0c prefetch abort

nop @0x10 data abort

nop @0x14 reserved

nop @0x18 irq

nop @0x1c fiq

_udef_handler:

.word  _udef_handler

_swi_handler:

.word  swi_handler

_prefetch_interrupt:

.word  _prefetch_interrupt

swi_handler:

stmfd sp!,{r0,lr}

ldr r0,[lr,#-4]

mov r1,#0xff

bic r0,r0,r1,lsl #24

bl switch_num

mov r0,#3

ldmfd sp!,{r0,pc}^

switch_num:

cmp r0,#2

moveq r7,#2

cmp r0,#4

moveq r7,#4

mov pc,lr

reset:

ldr sp,=stack_base

msr cpsr,#0x10 @ user model

mov r0,#2

swi 2

mov r1,r0

b reset

.data

buf:

.space 32

stack_base:    

.end

上一篇:淺談字節對齊

下一篇:Linux設備驅動申請設備號過程分析

熱(re)點文章推(tui)薦(jian)
華清學員就業榜單
高薪(xin)學(xue)員經驗分享
熱點新聞推薦
前(qian)臺專線:010-82525158 企業培(pei)訓洽談(tan)專線(xian):010-82525379 院(yuan)校(xiao)合作(zuo)洽(qia)談(tan)專線:010-82525379 Copyright © 2004-2022 北京華清遠見科技集團有限公司 版權所有 ,,京公海網安備11010802025203號

回到頂部