ARM的狀態(tài)寄存器CPSR中的狀態(tài)控制位T決定了當(dāng)前處理器的運行狀態(tài),因此,,可通過MSR和MRS指令來直接修改CPSR的狀態(tài)位,也能夠改變處理器運行狀態(tài),。但由于ARM采用多級流水線的結(jié)構(gòu),這樣做會造成流水線上預(yù)取指令的執(zhí)行錯誤,,而如果用BX指令,,則不會出現(xiàn)這樣的問題。
在同一狀態(tài)下的子程序調(diào)用,,由于它不需要狀態(tài)的切換,,所以其過程相對比較簡單,通常只需一條指令實現(xiàn)調(diào)用:
BL function
實現(xiàn)返回也只需從LR恢復(fù)PC即可:
MOV PC,,LR
在不同狀態(tài)下的子程序調(diào)用中,,就需要進(jìn)行狀態(tài)之間的切換,所以其過程相對復(fù)雜一些,,需要考慮到以下幾點:
需要由BX來切換狀態(tài),,因為BL不能完全成狀態(tài)切換。
需要在BX之前先保存好LR,,BX不能自動保存返回地址到LR,。
需要用“BX LR”來返回,不能使用“MOV PC,LR”,,返回時要仔細(xì)考慮保存在LR中最低位的內(nèi)容是否正確,。
在這里需要注意的是:
函數(shù)func1()和func2()位于2個不同的源文件中。
在圖中,,func1()使用BL指令調(diào)用func2(),,而返回時直接使用“BX LR”。這是因為當(dāng)執(zhí)行BL指令對LR進(jìn)行保存時,,其最低位會被自動設(shè)置,,以滿足返回時狀態(tài)切換的需要,。
編譯時必須告訴編譯器和鏈接器足夠的信息,一方面讓編譯器能夠使用正確的指令碼進(jìn)行編譯,;另一方面,,當(dāng)在不同的狀態(tài)之間發(fā)生函數(shù)調(diào)用時,,鏈接器插入一段鏈接代碼來實現(xiàn)狀態(tài)轉(zhuǎn)換,。