?
9.2??狀態(tài)寄存器訪問(wèn)指令
ARM指令集提供了兩條指令,可直接控制程序狀態(tài)寄存器psr。MRS指令用于把cpsr或者spsr的值傳送到一個(gè)寄存器;MSR與之相反,它將一個(gè)寄存器的內(nèi)容傳送到cpsr或者spsr。這兩條指令結(jié)合,可用于對(duì)cpsr和spsr進(jìn)行讀/寫操作。
表9.2總結(jié)了狀態(tài)寄存器訪問(wèn)指令。
表9.2 狀態(tài)寄存器訪問(wèn)指令
助??記??符 |
含????義 |
操????作 |
MRS |
將程序狀態(tài)字寄存器的值送到通用寄存器 |
Rd=spr |
MSR |
將通用寄存器的值送到程序狀態(tài)字寄存器 |
Psr[field]=Rm |
MSR |
將一個(gè)立即數(shù)送到程序狀態(tài)字 |
Psr[field]=immediate |
當(dāng)需要保存或修改當(dāng)前模式下CISR或SPSR的內(nèi)容時(shí),首先必須將這些內(nèi)容傳送到通用寄存器中,對(duì)選擇的位進(jìn)行修改,然后將數(shù)據(jù)回寫到狀態(tài)寄存器。對(duì)于ARM和Thumb的狀態(tài)切換也是如此,程序不能通過(guò)直接改寫CPSR中的T控制位直接將程序狀態(tài)切換到Thumb狀態(tài),必須通過(guò)BX等指令完成程序狀態(tài)的切換。
9.2.1??程序狀態(tài)字內(nèi)容送通用寄存器指令MRS
1.指令編碼格式
讀狀態(tài)寄存器指令MRS。在ARM寄存器中,只有MRS指令可以將狀態(tài)寄存器CPSR或SPSR讀出到通用寄存器中。將程序狀態(tài)字內(nèi)容讀取到通用寄存器中后就可以對(duì)其進(jìn)行計(jì)算、修改等操作。
指令的編碼格式如圖9.6所示。
圖9.6??MRS指令編碼格式
2.指令的語(yǔ)法格式
MRS{<cond>}??<Rd>,CPSR
MRS{<cond>}??<Rd>,SPSR
①?<cond>
為指令編碼中的條件域。它指示指令在什么條件下執(zhí)行。當(dāng)<cond>忽略時(shí),指令為無(wú)條件執(zhí)行(cond=AL(Alway))。
②?<Rd>
確定指令的目標(biāo)寄存器。如果r15被用作目標(biāo)寄存器,指令的執(zhí)行結(jié)果不可預(yù)知。
3.指令操作的偽代碼
指令操作的偽代碼如下面程序段所示。
If??ConditionPassed{cond}??then
?????If??R==1??then
??????????Rd=SPSR
?????Else
??????????Rd=CPSR
4.指令的使用
MRS指令注意用于以下3種場(chǎng)合:
·??當(dāng)需要保存或修改當(dāng)前模式下CPSR或SPSR的內(nèi)容時(shí),首先必須將這些內(nèi)容傳送到通用寄存器中,對(duì)選擇的位進(jìn)行修改,然后將數(shù)據(jù)回寫到狀態(tài)寄存器。
·??當(dāng)異常中斷允許嵌套時(shí),需要在進(jìn)入異常中斷之后,嵌套中斷發(fā)生之前保存當(dāng)前處理器模式對(duì)應(yīng)的SPSR。這時(shí)需要先通過(guò)MRS指令讀出SPSR的值,再用其他指令(如壓棧指令)將SPSR值保存起來(lái)。
·??在進(jìn)程切換時(shí)也需要保存當(dāng)前狀態(tài)寄存器的值。
注意 |
在用戶模式下對(duì)CPSR[23∶0]進(jìn)行任何修改都是無(wú)效的。另外,盡量避免在用戶模式或系統(tǒng)模式下訪問(wèn)SPSR,因?yàn)樵谶@種模式下沒(méi)有SPSR,如果執(zhí)行此操作,指令的執(zhí)行結(jié)果不可預(yù)知。 |
?
5.指令舉例
(1)將CPSR狀態(tài)寄存器讀取,保存到r1中。
MRS???r1,CPSR
(2)將SPSR狀態(tài)寄存器讀取,保存到r2中。
MRS???r2,SPSR
(3)MSR指令讀取CPSR,用來(lái)判斷ALU的狀態(tài)標(biāo)志或IRQ/FIQ中斷是否允許等;在異常處理程序中,讀SPSR可知道進(jìn)入異常前的處理器狀態(tài)等。MRS與MSR配合使用,實(shí)現(xiàn)CPSR或SPSR寄存器的讀-修改-寫操作,可用來(lái)進(jìn)行處理器模式的切換或禁止/使能IRQ/FIQ中斷等設(shè)置。另外,進(jìn)行切換或允許異常中斷嵌套時(shí),也需要使用MRS指令讀取SPSR狀態(tài)值保存起來(lái)。
下面的例子使能IRQ中斷。
ENABLE_IRQ
?????????MRS????r0,CPSR
?????????BIC????r0,r0,#0x80
?????????MSR????CPSR_c,r0
?????????MOV????PC,LR
下面的例子禁止IRQ中斷。
DISABLE_IRQ
????????MRS????r0,CPSR
????????ORR????r0,r0,#0x80
????????MSR????CPSR_c,r0
????????MOV????PC,LR
?
9.2.2??寫狀態(tài)寄存器指令MSR
1.指令編碼格式
寫狀態(tài)寄存器指令MSR(Move?to?Status?Register?from?ARM?Register)。在ARM處理器中,只有MSR指令可以直接設(shè)置狀態(tài)寄存器CPSR或SPSR。
圖9.7、圖9.8分別顯示了源操作數(shù)為立即數(shù)的MSR指令和源操作數(shù)為寄存器的MSR指令的編碼格式。
圖9.7??源操作數(shù)為立即數(shù)的MSR指令編碼格式
圖9.8??源操作數(shù)為寄存器的MSR指令編碼格式
2.指令的語(yǔ)法格式
MSR{<cond>}???CPSR_<fields>,#<immediate>
MSR{<cond>}???CPSR_<fields>,<Rm>
MSR{<cond>}???SPSR_<fields>,#<immediate>
MSR{<cond>}???SPSR_<fields>,<Rm>
①?<cond>
為指令編碼中的條件域。它指示指令在什么條件下執(zhí)行。當(dāng)<cond>忽略時(shí),指令為無(wú)條件執(zhí)行(cond=AL(Alway))。
②?<fields>
域標(biāo)志位,是下面選項(xiàng)中的一種或幾種的組合。
·??C:設(shè)置控制位掩碼域(bit[16])。
·??X:設(shè)置擴(kuò)展位掩碼域(bit[17])。
·??S:設(shè)置狀態(tài)位掩碼域(bit[18])。
·??F:設(shè)置標(biāo)志位掩碼域(bit[19])
③?<immediate>
將被傳送到CPSR和SPSR寄存器的立即數(shù)。此立即數(shù)可以為8位立即數(shù)(范圍在0x00~0xff之間)。
④?<Rm>
指定的通用寄存器,此寄存器包含將要被傳送狀態(tài)寄存器中的數(shù)據(jù)。
3.指令操作的偽代碼
指令操作的偽代碼如下面程序段所示。
If??ConditionPassed{cond}??then
?????If??opcode[25]==1
??????????Operand=8_bit_immediate??Rotate_Right{rotate_imm*2}
?????Else?/*opcode[25]==0*/
??????????Operand=Rm
?????If??R==0?then
??????????If??field_mask[0]==1?and?inAprivilegedMode()??then
????????????????CPSR[7:0]=operand[7:0]
??????????If??field_mask[1]==1?and?inAprivilegedMode()??then
????????????????CPSR[15:8]=operand[15:8]
??????????If??field_mask[2]==1?and?inAprivilegedMode()??then
????????????????CPSR[23:16]=operand[23:16]
??????????If??field_mask[3]==1?and?then
????????????????CPSR[31:24]=operand[31:24]
?????Else/*R==1*/
??????????If??field_mask[0]==1?and?CurrentModeHasSPSR()??then
????????????????SPSR[7:0]=operand[7:0]
??????????If??field_mask[1]==1?and?CurrentModeHasSPSR()??then
????????????????SPSR[15:8]=operand[15:8]
??????????If??field_mask[2]==1?and?CurrentModeHasSPSR()??then
????????????????SPSR[23:16]=operand[23:16]
??????????If??field_mask[3]==1?and?CurrentModeHasSPSR()??then
????????????????SPSR[31:24]=operand[31:24]
?
4.指令的使用
詳見(jiàn)MRS指令。
5.指令舉例
(1)使用“讀-修改-寫”模式更新CPSR寄存器。
MRS???r0,CPSR ;讀CPSR寄存器的值
BIC???r0,r0,#0xf0000000 ;清除N、Z、C、V位
MSR???CPSR_f,r0 ;更新CPSR中的標(biāo)志位
注意 |
因?yàn)镻SR狀態(tài)寄存器中存在目前沒(méi)有定義的保留位,所以在使用時(shí),最好加上“_fsxc”后綴,如上例中的“CPSR_f”。這樣做的目的是使指令只修改程序狀態(tài)寄存器的某個(gè)域,防止程序向高版本指令集移植時(shí)發(fā)生意外。 |
(2)禁止IRQ中斷。
MRS????r0,CPSR???????????????;讀CPSR狀態(tài)寄存器
ORR????r0,r0,#0x80?????????;設(shè)置IRQ中斷禁止位
MSR????CPSR_c,r0?????????????;更新CPSR狀態(tài)寄存器
(3)堆棧初始化。
INITSTACK
?????????MOV????r0,LR??????????;保存返回地址
;設(shè)置管理模式堆棧
?????????MSR????CPSR_c,#0xd3;
?????????LDR????SP,StackSvc;
;設(shè)置中斷模式堆棧
?????????MSR????CPSR_c,#0xd2;
?????????LDR????SP,StackIrq;