|
引言 在前面的文章中提到過,很多情況下應(yīng)用程序需要在ARM跟Thumb狀態(tài)之間相互切換,這部分就討論交互工作的實(shí)現(xiàn)方法和一些注意問題。 1 需要交互的原因 前面提到過,Thumb指令在某些特殊情況下具有比ARM指令更為出色的表現(xiàn),主要是在代碼長(zhǎng)度和窄帶寬存儲(chǔ)器系統(tǒng)性能兩方面。正是因?yàn)門humb指令在特定環(huán)境下的優(yōu)勢(shì),它在很多方面得到了廣泛應(yīng)用。但是因?yàn)橄旅嬉恍┰?Thumb又不可能獨(dú)立地組成一個(gè)應(yīng)用系統(tǒng)。 ◇ Thumb指令集在功能上只是ARM指令集的一個(gè)子 集,某些功能只能在ARM狀態(tài)下執(zhí)行,如CPSR和 協(xié)處理器的訪問。 ◇ 進(jìn)行異常響應(yīng)時(shí),處理器會(huì)自動(dòng)進(jìn)入ARM狀態(tài)。 ◇ 從系統(tǒng)優(yōu)化考慮,在寬帶存儲(chǔ)器上不應(yīng)該放置 Thumb代碼,很多窄帶系統(tǒng)具有寬帶的內(nèi)部存儲(chǔ)器。 ◇ 即使是一個(gè)單純的Thumb應(yīng)用系統(tǒng),也必須加一 個(gè)匯編的交互頭程序,因?yàn)橄到y(tǒng)總是自動(dòng)從ARM 開始啟動(dòng)。 所以,不可避免地會(huì)產(chǎn)生ARM與Thumb之間交互的問題。 2 狀態(tài)切換的實(shí)現(xiàn) 處理器在 ARM/Thumb之間的狀態(tài)切換是通過一條專用的跳轉(zhuǎn)交換指令BX來實(shí)現(xiàn)的。BX指令以通用寄存器(R0~R15)為操作數(shù),通過拷貝Rn到PC來實(shí)現(xiàn) 4GB空間范圍內(nèi)的一個(gè)絕對(duì)跳轉(zhuǎn)。BX利用Rn寄存器中存儲(chǔ)的目標(biāo)地址值的最后一位來判斷跳轉(zhuǎn)后的狀態(tài)。如圖1所示,是用BX指令實(shí)現(xiàn)狀態(tài)切換。
無論ARM還是Thumb,其指令存儲(chǔ)在存儲(chǔ)器中都是邊界對(duì)齊的(4字節(jié)或2字節(jié)對(duì)齊)。因此,在執(zhí)行跳轉(zhuǎn)過程中,PC寄存器中的最低位肯定被舍棄,不起作用。在BX指令的執(zhí)行過程中,最低位正好被用作狀態(tài)判斷的標(biāo)識(shí),不會(huì)造成存儲(chǔ)器訪問不對(duì)齊的錯(cuò)誤。 圖 2 中是一段直接進(jìn)行狀態(tài)切換的例程:
下面是一段直接進(jìn)行狀態(tài)切換的例程。 ;從ARM狀態(tài)開始 CODE32 ;匯編關(guān)鍵字 ADR R0, Into_Thumb+1 ;得到目標(biāo)地址,末位置1, ;轉(zhuǎn)向Thumb BX R0 ;執(zhí)行 ? ;其它代碼 CODE16 ;匯編關(guān)鍵字 Into_Thumb ;Thumb代碼段起始地址 … ;Thumb代碼 ADR R5, Back_to_ARM ;得到目標(biāo)地址,末位缺 ;省為0,轉(zhuǎn)向ARM BX R5 ;執(zhí)行 … ;其它代碼 CODE32 ;匯編關(guān)鍵字 Back_to_ARM ;ARM代碼段起始地址 我們知道,在ARM的狀態(tài)寄存器CPSR 中,bit-5是狀態(tài)控制位T-bit,決定當(dāng)前處理器的運(yùn)行狀態(tài)。如果直接修改CPSR的狀態(tài)位,也能夠達(dá)到改變處理器運(yùn)行狀態(tài)的目的。但是這樣會(huì)帶來一個(gè)問題,因?yàn)锳RM采用多級(jí)流水線的結(jié)構(gòu),所以在程序執(zhí)行過程中,指令流水線上會(huì)存在幾條預(yù)取指令(具體數(shù)目視流水線級(jí)數(shù)而不同)。當(dāng)修改CPSR的 T-bit后,狀態(tài)的轉(zhuǎn)變會(huì)造成流水線上預(yù)取指令的執(zhí)行錯(cuò)誤。而如果用BX指令,則執(zhí)行后會(huì)進(jìn)行流水線的刷新動(dòng)作,清除流水線上的殘余指令,在新的狀態(tài)下重新開始指令預(yù)取,從而保證狀態(tài)轉(zhuǎn)變時(shí)指令流的正確銜接。 3 ARM/Thumb之間的函數(shù)調(diào)用 在無交互的子程序調(diào)用中,其過程比較簡(jiǎn)單。實(shí)現(xiàn)調(diào)用通常只需要一條指令: BL function 實(shí)現(xiàn)返回也只需要從LR恢復(fù)PC即可: MOV PC, LR 函數(shù)的調(diào)用過程如圖3所示。
如果子函數(shù)和父函數(shù)不在同一種狀態(tài)下執(zhí)行,因?yàn)闋顟B(tài)切換,需要對(duì)函數(shù)調(diào)用作更多的考慮。 ① BL不能完成狀態(tài)切換,需要由BX來切換狀態(tài)。 ② BX不能自動(dòng)保存返回地址到LR,需要在BX之前先保存好LR。 ③ 用“BX LR”來返回,不能使用“MOV PC, LR”,因?yàn)檫@條指令同樣不能實(shí)現(xiàn)狀態(tài)切換。返回時(shí)要仔細(xì)考慮保存在LR中最低位的內(nèi)容是否正確。 假如用戶直接使用匯編語言進(jìn)行狀態(tài)交互跳轉(zhuǎn),上述的幾個(gè)問題都需要用手工編碼加以處理。如果用戶使用高級(jí)語言進(jìn)行開發(fā),不需要為ARM/Thumb之間的相互調(diào)用增加額外編碼,但是最好要對(duì)其調(diào)用過程加以了解。下面以ARM ADS中的編譯工具為例進(jìn)行說明,如圖4所示。
① 兩個(gè)函數(shù)func1()和func2()被編譯成不同的指令集(ARM或Thumb)。 注意:func1()和 func2()在這里位于二個(gè)不同的源文件中。 ② 編譯時(shí)必須告訴編譯器和鏈接器足夠的信息,一方面讓編譯器能夠使用正確的指令碼進(jìn)行編譯,另一方面,當(dāng)在不同的狀態(tài)之間發(fā)生函數(shù)調(diào)用時(shí),鏈接器將插入一段鏈接代碼(veneers)來實(shí)現(xiàn)狀態(tài)轉(zhuǎn)換。 上述過程中的一個(gè)特點(diǎn)是:func1()還是使用通常的BL指令來進(jìn)行子程序調(diào)用,而 func2()返回時(shí)則直接使用“BX LR”,沒有對(duì)LR進(jìn)行判斷和最低位的設(shè)置。這是因?yàn)楫?dāng)執(zhí)行BL指令對(duì)LR進(jìn)行保存時(shí),其最低位會(huì)被自動(dòng)設(shè)置,以滿足返回時(shí)狀態(tài)切換的需要,可直接使用 “BX LR”。 在上面的例子中,為了讓編譯器在編譯函數(shù)func2()時(shí)使用BX而不是BL進(jìn)行返回,必須告訴編譯器要按照滿足交互工作要求的方式進(jìn)行編譯。在ARM的編譯器選項(xiàng)設(shè)置中,應(yīng)選擇“-apcs /interwork”。這樣,函數(shù)的返回指令會(huì)被正確設(shè)置,并且當(dāng)鏈接器進(jìn)行目標(biāo)代碼的鏈接時(shí),能夠在需要的地方插入正確的鏈接代碼實(shí)現(xiàn)狀態(tài)切換。 當(dāng)然,插入了鏈接代碼會(huì)相應(yīng)地增加代碼長(zhǎng)度,通常一段veneer包含3條指令,即12B字節(jié)長(zhǎng)度。可以用“-info veneers”選項(xiàng)使鏈接器輸出所有veneers的位置和長(zhǎng)度信息。 4 交互程序之間的兼容性 因?yàn)樵谥付ń换ミx項(xiàng)后,編譯及鏈接后的輸出代碼跟在無交互情況下不同,所以當(dāng)多個(gè)源文件如果使用了不同的設(shè)置進(jìn)行編譯,相互之間的調(diào)用可能產(chǎn)生兼容性問題。圖5說明了這些關(guān)系。
在一個(gè)使用交互工作的項(xiàng)目工程管理中,對(duì)此要加以仔細(xì)考慮。 5 V5架構(gòu)的擴(kuò)展 ARM在V5版本的架構(gòu)中,對(duì)ARM/Thumb的交互增加了新的支持。針對(duì)前面第3節(jié)中提到的函數(shù)調(diào)用和返回問題,V5版本中專門對(duì)指令做了擴(kuò)展。 ① 增加了新指令BLX,解決了原來BX和BL指令各自的欠缺。使交互的函數(shù)調(diào)用可以由一條指令實(shí)現(xiàn),省去了跳轉(zhuǎn)代碼的開銷。 ② 擴(kuò)展了以PC為目標(biāo)地址的數(shù)據(jù)傳輸指令功能。PC加載值的最低位將被自動(dòng)送到狀態(tài)寄存器CPSR的T狀態(tài)位。也就是說,通過給PC賦值的方法也能實(shí)現(xiàn)狀態(tài)的切換,這樣就使習(xí)慣的函數(shù)返回方法——從堆棧中恢復(fù)寄存器,也能實(shí)現(xiàn)交互調(diào)用函數(shù)的正確返回了。 所以,V5架構(gòu)以后的代碼,不再需要額外的鏈接代碼,縮小了代碼長(zhǎng)度,提高了狀態(tài)切換時(shí)的執(zhí)行效率。當(dāng)然,在V5及以后的架構(gòu)中,繼續(xù)保持了對(duì)以前代碼的良好兼容性。 6 Thumb-2 ARM和Thumb因?yàn)槠涓髯缘膬?yōu)勢(shì),都得到了極為廣泛的應(yīng)用。在一個(gè)應(yīng)用程序中,用戶要根據(jù)系統(tǒng)的具體情況靈活分配,使用不同的編譯器,把不同的代碼編譯成ARM或Thumb,以希望得到最優(yōu)的代碼長(zhǎng)度和性能平衡。這樣做能夠達(dá)到系統(tǒng)優(yōu)化的目的,但是也給設(shè)計(jì)人員帶來了額外的交互處理工作。最近,ARM公司公布了一項(xiàng)新的發(fā)明——Thumb-2指令集,該指令集同時(shí)包含32位和16位指令,在代碼長(zhǎng)度和性能之間作了最佳的平衡。這樣,以后用戶就可以用一個(gè)統(tǒng)一的Thumb-2編譯器來解決現(xiàn)在面臨的很多問題了。 如圖6所示,是Thumb-2指令集跟ARM和Thumb之間的比較。
引證文獻(xiàn) 1. 楊志強(qiáng) 嵌入式系統(tǒng)設(shè)計(jì)與發(fā)展 [期刊論文] -青海師范大學(xué)學(xué)報(bào)(自然科學(xué)版)2005(03) 2. 劉志勇 基于ARM的無線視頻傳輸硬件系統(tǒng)的初步研究與開發(fā) [學(xué)位論文] 碩士2005 3. 李晶 基于 LINUX的無線局域網(wǎng)芯片驅(qū)動(dòng)程序的設(shè)計(jì)與開發(fā) [學(xué)位論文] 碩士2005 作 者:ARM中國(guó) 費(fèi)浙平 來 源:單片機(jī)與嵌入式系統(tǒng)應(yīng)用 2003(12) |