Cortext-M3學習筆記-2-Thumb 指令集

摘自  http://www.eefocus.com/book/09-08/793361276059991.html


Thumb 指令集        Thumb 指令可以看作是ARM 指令壓縮形式的子集,是針對代碼密度的問題而提出的,它具有16 位的代碼密度。Thumb 不是一個完整的體系結構,不能指望處理只執行Thumb 指令而不支持ARM 指令集。因此,Thumb 指令只需要支持通用功能,必要時可以藉助於完善的ARM 指令集,比如,所有異常自動進入ARM 狀態。

        在編寫Thumb 指令時,先要使用僞指令CODE16 聲明,而且在ARM 指令中要使用BX指令跳轉到Thumb 指令,以切換處理器狀態。編寫ARM 指令時,則可使用僞指令CODE32聲明。

A.3.1  Thumb 指令集與ARM 指令集的區別
        Thumb 指令集沒有協處理器指令,信號量指令以及訪問CPSR 或SPSR 的指令,沒有乘加指令及64 位乘法指令等,且指令的第二操作數受到限制;除了跳轉指令B 有條件執行功能外,其它指令均爲無條件執行;大多數Thumb 數據處理指令採用2 地址格式。Thumb指令集與ARM 指令的區別一般有如下幾點:
        跳轉指令
        程序相對轉移,特別是條件跳轉與ARM 代碼下的跳轉相比,在範圍上有更多的限制,轉向子程序是無條件的轉移。
        數據處理指令
        數據處理指令是對通用寄存器進行操作,在大多數情況下,操作的結果須放入其中一個操作數寄存器中,而不是第3 個寄存器中。
        數據處理操作比ARM 狀態的更少,訪問寄存器R8~R15 受到一定限制。
        除MOV 和ADD 指令訪問器R8~R15 外,其它數據處理指令總是更新CPSR 中的ALU 狀態標誌。
        訪問寄存器R8~R15 的Thumb 數據處理指令不能更新CPSR 中的ALU 狀態標誌。
        單寄存器加載和存儲指令
        在Thumb 狀態下,單寄存器加載和存儲指令只能訪問寄存器R0~R7。
        批量寄存器加載和存儲指令
        LDM 和STM 指令可以將任何範圍爲R0~R7 的寄存器子集加載或存儲。
        PUSH 和POP 指令使用堆棧指令R13 作爲基址實現滿遞減堆棧。除R0~R7 外,PUSH 指令還可以存儲鏈接寄存器R14,並且POP 指令可以加載程序指令PC。

A.3.2  Thumb 存儲器訪問指令

        Thumb 指令集的LDM 和SRM 指令可以將任何範圍爲R0~R7 的寄存器子集加載或存儲。
        批量寄存器加載和存儲指令只有LDMIA、STMIA 指令,即每次傳送先加載/存儲數據,然後地址加4。對堆棧處理只能使用PUSH 指令及POP 指令。表A-9給出Thumb存儲器訪問指令。

表A-9  Thumb 存儲器訪問指令


        LDR 和STR
        立即數偏移的LDR 和STR 指令。存儲器的地址以一個寄存器的立即數偏移指明。指令格式如下:
        LDR Rd,[Rn,#immed_5×4];加載指定地址上的數據(字),放入Rd 中
        STR Rd,[Rn,#immed_5×4];存儲數據(字)到指定地址的存儲單元,要存儲數據在Rd 中
        LDRH Rd,[Rn,#immed_5×4];加載半字數據,放入Rd中,即Rd低16位有效,高16位清零
        STRH Rd,[Rn,#immed_5×4];存儲半字數據,要存儲的數據在Rd,最低16 位有效
        LDRB Rd,[Rn,#immed_5×4];加載字節數據,放入Rd中,即Rd最低字節有效,
                                                           ; 高24位清零
        STRB Rd,[Rn,#immed_5×4];存儲字節數據,要存儲的數據在Rd,最低字節有效
        其中:Rd 加載或存儲的寄存器。必須爲R0~R7。
        Rn 基址寄存器。必須爲R0~R7。
        immed_5×N 偏移量。它是一個無符立即數表達式,其取值爲(0~3)×N
        立即數偏移的半字和字節加載是無符號的。數據加載到Rd 的最低有效半字或字節,Rd 的其餘位補0。
        地址對準一一字傳送時,必須保證傳送地址爲32 位對準。半字傳送時,必須保證傳送地址爲16 位對準
        立即數偏移的LDR 和STR 指令舉例如下:
        LDR R0,[R1,#0x4]
        STR R3,[R4]
        LDRH R5,[R0,#0x02]
        STRH R1,[R0,#0x08]
        LDRB R3,[R6,#20]
        STRB R1,[R0,#31]
        寄存器偏移的LDR 和STR 指令。存儲器的地址用一個寄存器的基於寄存器偏移來指明。指令格式如下:
        LDR Rd,[Rn,Rm] ;加載一個字數據
        STR Rd,[Rn,Rm] ;存儲一個字數據
        LDRH Rd,[Rn,Rm] ;加載一個無符半字數據
        STRH Rd,[Rn,Rm] ;存儲一個無符半字數據
        LDRB Rd,[Rn,Rm] ;加載一個無符字節數據
        STRB Rd,[Rn,Rm] ;存儲一個無符字節數據
        LDRSH Rd,[Rn,Rm] ;加載一個有符半字數據
        LDRSB Rd,[Rn,Rm] ;存儲一個有符半字數據
        其中: Rd 加載或存儲的寄存器。必須爲R0~R7
        Rn 基址寄存器。必須爲R0~R7
        Rm 內含偏移量的寄存器。必須爲R0~R7。
        寄存器偏移的半字和字節加載可以是有符號或無符號的,數據加載到Rd 的其餘位拷貝符號位。
        地址對準—字傳送時,必須保證傳送地址爲32 位對準。半字傳送時,必須保證傳送地址爲16 位對準。
        寄存器偏移的LDR 和STR 指令舉例如下:
        LDR R3,[R1,R0]
        STR R1,[R0,R2]
        LDRH R6,[R0,R1]
        STRH R0,[R4,R5]
        LDRB R2,[R5,R1]
        STRB R1,[R3,R2]
        LDRSH R7,[R6,R3]
        LDRSB R5,[R7,R2]
        PC 或SP 相對偏移的LDR 和STR 指令。用PC 或SP 寄存器中的值的立即數偏移來指明存儲器的地址。指令格式如下:
        LDR Rd,[PC,#immed_8×4]
        LDR Rd,label
        LDR Rd,[SP,#immed_8×4]
        STR Rd,[SP,#immed_8×4]
        其中: Rd 加載或存儲的寄存器。必須爲R0~R7。
        immed_8×4] 偏移量。它是一個無符立即數表達式,其取值爲(0~255)×4。
        label 程序相對偏移表達式。label 必須在當前指令之後IK 字節範圍內。地址對準—地址必須是4 的整數倍。
        PC 或SP 相對偏移的LDR 和STR 指令舉例如下:
        LDR R0,[PC,#0x08] ;讀取PC+0x08 地址上的字數據,保存到R0 中
        LDR R7,LOCALDAT ;讀取LOCALDAT 地址上的字數據,保存到R7 中
        LDR R3,[SP,#1020] ;讀取SP+1020 地址上的字數據,保存到R3 中
        STR R2,[SP] ;存儲R2 寄存器的數據到SP 指向的存儲單元(偏移量爲0)

        PUSH 和POP
        寄存器入棧及出棧指令。實現低寄存器和可選的LR 寄存器入棧寄存器和可選的PC寄存器出棧操作,堆棧地址由SP 寄存設置,堆棧是滿遞減堆棧。指令格式如下:
        PUSH {reglist[,LR]}
        POP {reglist[,PC]}
        其中:reglist 入棧/出棧低寄存器列表,即R0~R7。
        LR 入棧時的可選寄存器。
        PC 出棧時的可選寄存器。
        寄存器入棧及出棧指令舉例如下:
        PUSH {R0-R7,LR} ;將低寄存器R0~R7 全部入棧,LR 也入棧
        POP {R0-R7,PC} ;將堆棧中的數據彈出到低寄存器R0~R7 及PC 中

        LDMIA 和STMIA
        批量加載/存儲指令可以實現在一組寄存器和一塊連續的內存單元之間傳輸數據。Thumb 指令集批量加載/存儲指令爲LDMIA 和STMIA,LDMIA 爲加載多個寄存器;STM爲存儲多個寄存器,允許一條指令傳送8 個低寄存器的任何子集。指令格式如下:
        LDMIA Rn!,reglist
        STMIA Rn!,reglist
        其中:Rn 加載/存儲的起始地址寄存器。Rn 必須爲R0~R7。
        Reglist 加載/存儲的寄存器列表。寄存器必須爲R0~R7。
        LDMIA/STMIA 的主要用途是數據複製,參數傳送等,進行數據傳送時,每次傳送後地址加4。若Rn 在寄存器列表中,對於LDMIA 指令,Rn 的最終值是加載的值,而不是增加後的地址;對於STMIA 指令,在Rn 是寄存器列表中的最低數字的寄存器,則Rn 存儲的值爲Rn 在初值,其它情況不可預知。
        批量加載/存儲指令舉例如下:
        LDMIA R0,{R2-R7} ;加載R0 指向的地址上的多字數據,保存到R2~R7 中,
                                           ; R0 的值更新。
        STMIA R1!,{R2-R7};將R2~R7 的數據存儲到R1 指向的地址上,R1 值更新。

A.3.3  Thumb 數據處理指令
        大多數Thumb 處理指令採用2 地址格式,數據處理操作比ARM 狀態的更少,訪問寄存器R8~R15 受到一定限制。表A-10給出Thumb數據處理指令。

表A-10  Thumb數據處理指令


        (1)數據傳送指令
        MOV
        數據傳送指令。將8 位立即數或寄存器(operand2)傳送到目標寄存器(Rd)。指令格式如下:
        MOV Rd,#expr
        MOV Rd,Rm
        其中:Rd 目標寄存器。MOV Rd#expr 時,必須在R0~R7 之間。
        exper 8 位立即數,即0~255。
        Rm 源寄存器,爲R0~R15。
        條件碼標誌:MOV Rd,#expr 指令會更新N 和Z 標誌,對標誌C 和V 無影響。而MOV,Rd,Rm 指令,若Rd 或Rm 是高寄存器(R8~R15),則標誌不受影響,若Rd 或Rm 都是低寄存器(R0~R7),則會更新N 和Z,且清除標誌C 和V。
        MOV 指令舉例如下:
        MOV R1,#0x10 ;R1=0x10
        MOV R0,R8 ;R0=R8
        MOV PC,LR ;PC=LR,子程序返回

        MVN
        數據非傳送指令。將寄存器Rm 按位取反後傳送到目標寄存器(Rd)。指令格式如下:
        MVN Rd,Rm
        其中: Rd 目標寄存器。必須在R0~R7 之間。
        Rm 源寄存器。必須在R0~R7 之間。
        條件碼標誌:指令會更新N 和Z 標誌,對標誌C 和V 無影響。
        MVN 指令舉例如下:
        MVN R1,R2 ;將R2 取反結果存到R1

        NEG
        數據取負指令。將寄存器Rm 乘以-1 後傳送到目標寄存器(Rd)。指令格式如下:
        NEG Rd,Rm
        其中: Rd 目標寄存器,必須在R0~R7 之間。
        Rm 源寄存器。必須在R0~R7 之間。
        條件碼標誌:指令會更新N、Z、C、V 和標誌。
        NEG 指令舉例如下:
        NEG R1,R0 ;R1=-R0

        (2)算術邏輯運算指令
        ADD
        加法運算指令。將兩個數據相加,結果保存到Rd 寄存器。
        低寄存器的ADD 指令的指令格式如下:
        ADD Rd,Rn,Rm
        ADD Rd,Rn,#expr3
        ADD Rd,#expr8
        其中:Rd 目標寄存器,必須在R0~R7 之間。
        Rn 第一個操作數寄存器。必須在R0~R7 之間。
        Rm 第二個操作數寄存器。必須在R0~R7 之間。
        expr3 3 位立即數,即0~7。
        expr8 8 位立即數,即0~255。
        條件碼標誌:指令會更新N、Z、C 和V 標誌。
        高或低寄存器的ADD 指令的指令格式如下:
        ADD Rd,Rm
        其中:Rd 目標寄存器,也是第一個操數寄存器。
        Rm 第二個操作數寄存器
        條件碼標誌:若Rd 或Rm 都是低寄存器(R0~R7),指令會更新N、Z、C 和V 標誌。其它情況不影響條件碼標誌。
        PC 或SP 相對偏移的ADD 指令指令格式如下:
        ADD Rd,Rp,#expr
        其中:Rd 目標寄存器,必須在R0~R7 之間。
        Rp PC 或SP,第一個操作數寄存器。
        expr 立即數,在0~1020 範圍內。
        條件碼標誌:不影響條件碼標誌。
        SP 操作的ADD 指令的指令格式如下:
        ADD SP,#expr
        ADD SP,SP,#expr
        其中:SP 目標寄存器,也是第一個操作數寄存器。
        expr 立即數,在-508~+508 之間的4 的整數倍的數。
        條件碼標誌:不影響條件碼標誌。
        ADD 指令舉例如下:
        ADD R1,R1,R0 ;R1=R1+R0
        ADD R1,R1,#7 ;R1=R1+7
        ADD R3,#200 ;R3=R3+200
        ADD R3,R8 ;R3=R3+R8
        ADD R1,SP,#1000 ;R1=SP+1000
        ADD SP,SP,#-500 ;SP=SP-500

        SUB
        減法運算指令。將兩個數相減,結果保存到Rd 中。
        低寄存器的SUB 指令的指令格式如下:
        SUB Rd,Rn,Rm
        SUB Rd,Rn,#expr3
        SUB Rd,#expr8
        其中:Rd 目標寄存器,必須在R0~R7 之間。
        Rn 第一個操作數寄存器。必須在R0~R7 之間。
        Rm 第一個操作數寄存器。必須在R0~R7 之間。
        expr3 3 位立即數,即0~7。
        expr8 8 位立即數。即0~255。
        條件碼標誌:指令會更新N、Z、C 和V 標誌。
        SP 操作的SUB 指令的指令格式如下:
        SUB SP,#expr
        SUB SP,SP,#expr
        其中:SP 目標寄存器,也是第一個操作數據寄存器。
        expr 立即數,在-508~+508 之間的4 的整數倍的數。
        條件碼標誌:不影響條件碼標誌。
        SUB 指令舉例如下:
        SUB R0,R2,R1, ;R0=R2-R1
        SUB R2,R1,#1 ;R2=R1-1
        SUB R6,#250 ;R6=R6-250
        SUB SP,#380 ;SP=SP-380

        ADC
        帶進位加法指令。將Rm 的值與Rd 的值相加,再加上CPSR 中的C 條件標誌位,結果保
        存到Rd 寄存器。指令格式如下:
        ADC Rd,Rm
        其中:Rd 目標寄存器,也是第一個操作數寄存器。必須在R0~R7 之間。
        Rm 第二個操作數寄存器。必須在R0~R7 之間。
        條件碼標誌:指令會更新N、Z、C 和V 標誌。
        ADC 指令舉例如下:
        ADD R0,R0,R2,
        ADC R1,R1,R3 ;使用ADC 實現64 位加法,(R1,R0)+(R3,R2)

        SBC
        帶進位減法指令。用寄存器Rd 減去Rm,再減去CPSR 中的C 條件標誌的非(即若C 標誌清零,則結果減去1),結果保存到Rd 中。指令格式如下:
        SBC Rd,Rm
        其中:Rd 目標寄存器,也是第一個操作數寄存器。必須在R0~R7 之間。
        Rm 第二個操作數寄存器。必須在R0~R7 之間。
        條件碼標誌:指令會更新N、Z、C 和V 標誌。
        SBC 指令舉例如下:
        SUB R0,R0,R2
        SUB R1,R1,R3 ;使用SBC 實現64 位減法,(R1,R0)=(R1,R0)-(R3,R2)

        MUL
        乘法運算指令。用寄存器Rd 乘以Rm,結果保存到Rd 中。指令格式如下:
        MUL Rd,Rm
        其中:Rd 目標寄存器,也是第一個操作數寄存器。必須在R0~R7 之間。
        Rm 第二操作數寄存器。必須在R0~R7 之間。
        條件碼標誌:指令會更新N 和Z 標誌。
        MUL 指令舉例如下:
        MUL R2,R0,R1 ;R2=R0*R1

        AND
        邏輯與操作指令。將寄存器Rd 的值與寄存器Rm 值按位作邏輯與操作,結果保存到Rd 中。指令格式如下:
        AND Rd,Rm
        其中:Rd 目標寄存器,也是第一個操作數寄存器。必須在R0~R7 之間。
        Rm 第二個操作數寄存器。必須在R0~R7 之間。
        條件碼標誌:指令會更新N 和Z 標誌
        AND 指令舉例如下:
        MOV R1,#0x0F
        AND R0,R1 ;R0=R0 & R1

        ORR
        邏輯或操作指令。將寄存器Rd 與寄存器Rn 的值按位作邏輯或操作,結果保存到Rd中。指令格式如下:
        ORR Rd,Rm
        其中:Rd 目標寄存器,也是第一個操作數寄存器。必須在R0~R7 之間。
        Rm 第二個操作數寄存器。必須在R0~R7 之間。
        條件碼標誌:指令會更新N 和Z 標誌
        ORR 指令舉例如下:
        MOV R1,#0x03
        ORR R0,R1 ;R0=R0|R1

        EOR
        邏輯異或操作指令。寄存器Rd 的值與寄存器Rn 的值按位作邏輯異或操作,結果保存到Rd 中,指令格式如下:
        EOR Rd,Rm
        其中:Rd 目標寄存器,也是第一個操作數寄存器。必須在R0~R7 之間。
        Rm 第二個操作數寄存器。必須在R0~R7 之間。
        條件碼標誌:指令會更新N 和Z 標誌
        EOR 指令舉例如下:
        MOV R2,#0Xf0
        EOR R3,R2  ;R3=R3^R2

        BIC
        位清除指令。將寄存器Rd 的值與寄存器Rm 的值反碼按位作邏輯與操作。結果保存到Rd 中,指令格式如下:
        BIC Rd,Rm
        其中:Rd 目標寄存器,也是第一個操作數寄存器。必須在R0~R7 之間。
        Rm 第二個操作數寄存器。必須在R0~R7 之間。
        條件碼標誌:指令會更新N 和Z 標誌。
        BIC 指令舉例如下:
        MOV R1,#0x80
        BIC R3,R1 ;將R1 的最高位清零,其它位不變

        ASR
        算術右移指令。數據算術右移,將符號位拷貝到空位,移位結果保存到Rd 中,指令格式如下:
        ASR Rd,Rs
        ASR Rd,Rm,#expr
        其中:Rd 目標寄存器,也是第一個操作數寄存器。必須在R0~R7 之間。
        Rs 寄存器控制移位中包含移位量的寄存器。必須在R0~R7 之間。
        Rm 立即數移位的源寄存器。必須在R0~R7 之間。
        expr 立即數移位量,值爲1~32
        條件碼標誌:指令會更新N、Z 和C 標誌(若移位量爲零,則不影響C 標誌)。
        ASR 指令舉例如下:
        ASR R1,R2
        ASR R3,R1,#2
        若移位量爲32,則Rd 清零,最後移出的位保留在標誌C 中,若移位量大於32,則Rd和標誌C 均被清零;若移位量爲0,則不影響C 標誌

        LSL
        邏輯左移指令。數據邏輯左移,空位清零,移位結果保存到Rd 中,指令格式如下:
        LSL Rd,Rs
        LSL Rd,Rm,#expr
        其中:Rd 目標寄存器,也是第一個操作數寄存器。必須在R0~R7 之間。
        Rs 寄存器控制移位中包含位量的寄存器。必須在R0~R7 之間。
        Rm 立即數移位的源寄存器。必須在R0~R7 之間。
        expr 立即數移位量,值爲1~31
        條件碼標誌:指令會更新N、Z 和C 標誌(若移位量爲零,則不影響C 標誌)。
        LSL 指令舉例如下:
        LSL R6,R7
        LSL R1,R6,#2
        若移位量爲32,則Rd 清零,最後移出的位保留在標誌C 中;若移位量大於32,則Rd和標誌C 均被清零;若移位量爲0,則不影響C 標誌

        LSR
        邏輯左移指令。數據邏輯左移,空位清零,移位結果保存到Rd 中。指令格式如下:
        LSR Rd,Rs
        LSR Rd,Rm,#expr
        其中:Rd 目標寄存器,也是第一個操作數寄存器。必須在R0~R7 之間。
        Rs 寄存器控制移位中包含移位量的寄存器。必須在R0~R7 之間。
        Rm 立即數移位的源寄存器。必須在R0~R7 之間。
        expr 立即數移位量,值爲1~32。
        條件碼標誌:指令會更新N、Z 和C 標誌(若移位量爲零,則不影響C 標誌)。
        LSR 指令舉例如下:
        LSR R3,R0
        LSR R5,R2,#2
        若移位量爲32,則Rd 清零,最後移出的位保留在標誌C 中;若移位量大於32,則Rd和標誌C 均被清零,若移位量爲0,則不影響C 標誌。

        ROR
        循環右移指令。數據循環右移,寄存器右邊移出的位循環移回到左邊,移位結果保存到Rd 中,指令格式如下:
        ROR Rd,Rs
        其中:Rd 目標寄存器。也是第一個操作數寄存器。必須在R0~R7 之間。
        Rs 寄存器控制移位中包含移位量的寄存器。必須在R0~R7 之間。
        條件標誌:指令會更新N,Z、C 的標誌(若移位量爲零,則不影響C 標誌)。
        ROR 指令舉例如下:
        ROR R2,R3

        (3)比較指令
        CMP
        比較指令。指令使用寄存器Rn 的值減去第二個操作數的值,根據操作的結果更新CPSR 中的相應條件標誌位。指令格式如下:
        CMP Rn,Rm
        CMP Rn,#expr
        其中:Rn 第一個操作數寄存器。對CMP,Rn#expr 指令,Rn 在R0~R7 之間。對於CMP,Rn,Rm 指令在Rn 在R0~R15 之間。
        Rm 第二個操作數寄存器。Rm 在R0~R15 之間。
        expr 立即數,值爲0~255
        條件碼標誌:指令會更新N、Z、C 和V 標誌。
        CMP 指令舉例如下:
        CMP R1,#10 ;R1 與10 比較,設置相關標誌位
        CMP R1,R2 ;R1 與R2 比較,設置相關標誌位

        CMN
        負數比較指令。指令使用寄存器Rn 的值加上寄存器Rm 的值,根據操作的結果更新CPSR 中的相應條件標誌。指令格式如下:
        CMN Rn,Rm
        其中:Rn 第一個操作數寄存器,必須在R0~R7 之間。
        Rm 第二個操作數寄存器。必須在R0~R7 之間。
        條件碼標誌:指令會更新N、Z、C 和V 標誌。
        CMN 指令舉例如下:
        CMM R0,R2 ;R0 與R2 進行比較

        TST
        位測試指令。指令將寄存器Rn 的值與寄存器Rm 的值按位作邏輯與操作。根據操作的結果更新CPSR 相應條件標誌位。指令格式如下:
        TST Rn,Rm
        其中:Rn 第一個操作數寄存器。必須在R0~R7 之間。
        Rm 第二個操作數寄存器。必須在R0~R7 之間。
        條件碼標誌:指令會更新N、Z、C 和V 標誌。
        TST 指令舉例如下:
        MOV R0,#x01
        TST R1,R0  ;判斷R1 的最低位是否爲0

        (4)Thumb 跳轉指令
        表A-11給出Thumb跳轉指令。

表A-11  Thumb跳轉指令


        B
        跳轉指令。跳轉到指定的地址執行程序。這是Thumb 指令集中的惟一的有條件執行指令。指令格式如下:
        B{cond} label
        跳轉指令B 舉例如下:
        B WAITB
        BEQ LOOP1
        若使用cond 則label 必須在當前指令的-252~+256 字節範圍內;若指令是無條件的,則跳轉指令label 必須在當前指令的±2K 字節範圍內。

        BL
        帶鏈接的跳轉指令。指令先將下一條指令的地址拷貝到R14(即LR)鏈接寄存器中,然後跳轉到指定地址運行程序。指令格式如下:
        BL label
        帶鏈接的跳轉指令BL 舉例如下:
        BL DELAYI
        機器級轉指令BL 限制在當前指令的±4Mb 的範圍內。(必要時,ARM 鏈接器插入代碼以允許更長的轉移。)

        BX
        帶狀態切換的跳轉指令。跳轉到Rm 指定的地址執行程序。若Rm 的位[0]爲0,則Rm的位於也必須爲0,跳轉時自動將CPSR 中的標誌T 復位,即把目標地址的代碼解釋爲ARM代碼。指令格式如下:
        BX Rm
        帶狀態切換的跳轉指令BX 舉例如下:
        ADR R0, ArmFun
        BX R0 ;跳轉到R0 指定的地址,並根據R0 的最低位來切換處理器狀態。

        (5)Thumb 雜項指令
        SWI
        軟中斷指令。SWI 指令用於產生軟中斷,從而實現在用戶模式變換到管理模式。CPSR保存到管理模式的SPSR 中,執行轉移到SWI 向量。在其它模式下也可使用SWI 指令,處理器同樣地切換到管理模式。
        指令格式如下:
        SWI immed_8
        其中:immed_8 8 位立即數,值爲0~255 之間的整數。
        SWI 指令舉例如下:
        SWI 1 ;軟中斷,中斷立即數爲0
        SWI 0x55 ;軟中斷,中斷立即數爲0x55
        使用SWI 指令時,通常使用以下兩種方法進行傳遞參數,SWI 異常中斷處理程序可以提供相關的服務,這兩種方法均是用戶軟件協定。SWI 異常中斷處理程序要通過讀取引起軟中斷的SWI 指令。以取得8 位立即數。
        (A)指令中8 位的立即數指定了用戶請求的服務類型,參數通過用寄存器傳遞。
                        MOV R0,#34 ;設置子功能號爲虎作34
                        SWI 18 ;調用18 號軟中斷
        (B)指令中的8 位立即數被忽略,用戶請求的服務類型由寄存器R0 的值決定,參數通過其它的通用寄存器傳遞。
                MOV R0,#18 ;調用18 號軟中斷
                MOV R1,#34 ;設置子功能號爲34
                SWI 0

        (6)Thumb 僞指令
        ADR
        小範圍的地址讀取僞指令。ADR 指令將基於PC 相對偏移的地址值讀取到寄存器中。ADR 僞指令格式如下:
        ADR register,expr
        其中:register 加載的目標寄存器。
        expr 地址表達式。偏移量必須是正數並小於1KB。Expr 必須局部定義,不能被導入。
        ADR 僞指令舉例如下:
        ADR register, expr
        其中:register 加載的目標寄存器。
        expr 地址表達式。偏移量必須是正數並小說於1KB。Expr 必須局部定義,不能被導入。
        ADR 僞指令舉例如下:
        ADR R0,TxtTab
        …
        TxtTab
        DCB ”ARM7TDMI”,0

        LDR
        大範圍的地址讀取僞指令。LDR 僞指令用於加載32 位的立即數或一個地址值到指定寄存器。在彙編編譯源程序時,LDR 僞指令被編譯器替換成一條合適的指令。若加載的常數未超出MOV 範圍,則使用MOV 或MVN 指令代替LDR 僞指令,否則彙編器將常量放入文字池,並使用一條程序相對偏移的LDR 指令從文字池讀出常量。LDR 僞指令格式如下:
        LDR register,=expr/label_expr
        其中:register 加載的目標寄存器
        expr 32 位立即數。
        label_expr 基於PC 的地址表達式或外部表達式。
        LADR 僞指令舉例如下:
        LDR R0,=0x12345678 ;加載32 位立即數0x12345678
        LDR R0,=DATA_BUF+60 ;加載DATA_BUF 地址+60
        …
        LTORG ;聲明文字池
        …
        從PC 到文字池的偏移量必須是正數小於是1KB。
        與Thumb 指令的LDR 相比,僞指令的LDR 的參數有“=”號。

        NOP
        空操作僞指令。NOP 僞指令在彙編時將會將會被代替成ARM 中的空操作,比如可能爲“MOV R8,R8”指令等。NOP 僞指令格式如下:
        NOP
        NOP可用於延進操作
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章