新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > ARM應用系統開發詳解:第3章 ARM微處理器的指令系統

        ARM應用系統開發詳解:第3章 ARM微處理器的指令系統

        作者: 時間:2016-11-20 來源:網絡 收藏

        3.1ARM微處理器的指令集概述

        3.1.1ARM微處理器的指令的分類與格式

        本文引用地址:http://www.104case.com/article/201611/318749.htm

        助記符

        指令功能描述

        ADC

        帶進位加法指令

        ADD

        加法指令

        AND

        邏輯與指令

        B

        跳轉指令

        BIC

        位清零指令

        BL

        帶返回的跳轉指令

        BLX

        帶返回和狀態切換的跳轉指令

        BX

        帶狀態切換的跳轉指令

        CDP

        協處理器數據操作指令

        CMN

        比較反值指令

        CMP

        比較指令

        EOR

        異或指令

        LDC

        存儲器到協處理器的數據傳輸指令

        LDM

        加載多個寄存器指令

        LDR

        存儲器到寄存器的數據傳輸指令

        MCR

        從ARM寄存器到協處理器寄存器的數據傳輸指令

        MLA

        乘加運算指令

        MOV

        數據傳送指令

        MRC

        從協處理器寄存器到ARM寄存器的數據傳輸指令

        MRS

        傳送CPSR或SPSR的內容到通用寄存器指令

        MSR

        傳送通用寄存器到CPSR或SPSR的指令

        MUL

        32位乘法指令

        MLA

        32位乘加指令

        MVN

        數據取反傳送指令

        ORR

        邏輯或指令

        RSB

        逆向減法指令

        RSC

        帶借位的逆向減法指令

        SBC

        帶借位減法指令

        STC

        協處理器寄存器寫入存儲器指令

        STM

        批量內存字寫入指令

        STR

        寄存器到存儲器的數據傳輸指令

        SUB

        減法指令

        SWI

        軟件中斷指令

        SWP

        交換指令

        TEQ

        相等測試指令

        TST

        位測試指令

        3.1.2指令的條件域

        當處理器工作在ARM狀態時,幾乎所有的指令均根據CPSR中條件碼的狀態和指令的條件域有條件的執行。當指令的執行條件滿足時,指令被執行,否則指令被忽略。

        每一條ARM指令包含4位的條件碼,位于指令的最高4位[31:28]。條件碼共有16種,每種條件碼可用兩個字符表示,這兩個字符可以添加在指令助記符的后面和指令同時使用。例如,跳轉指令B可以加上后綴EQ變為BEQ表示“相等則跳轉”,即當CPSR中的Z標志置位時發生跳轉。

        在16種條件標志碼中,只有15種可以使用,如表3-2所示,第16種(1111)為系統保留,暫時不能使用。

        表3-2指令的條件碼

        條件碼

        助記符后綴

        標志

        含義

        0000

        EQ

        Z置位

        相等

        0001

        NE

        Z清零

        不相等

        0010

        CS

        C置位

        無符號數大于或等于

        0011

        CC

        C清零

        無符號數小于

        0100

        MI

        N置位

        負數

        0101

        PL

        N清零

        正數或零

        0110

        VS

        V置位

        溢出

        0111

        VC

        V清零

        未溢出

        1000

        HI

        C置位Z清零

        無符號數大于

        1001

        LS

        C清零Z置位

        無符號數小于或等于

        1010

        GE

        N等于V

        帶符號數大于或等于

        1011

        LT

        N不等于V

        帶符號數小于

        1100

        GT

        Z清零且(N等于V)

        帶符號數大于

        1101

        LE

        Z置位或(N不等于V)

        帶符號數小于或等于

        1110

        AL

        忽略

        無條件執行

        3.2ARM指令的尋址方式

        所謂尋址方式就是處理器根據指令中給出的地址信息來尋找物理地址的方式。目前ARM指令系統支持如下幾種常見的尋址方式。

        3.2.1立即尋址

        立即尋址也叫立即數尋址,這是一種特殊的尋址方式,操作數本身就在指令中給出,只要取出指令也就取到了操作數。這個操作數被稱為立即數,對應的尋址方式也就叫做立即尋址。例如以下指令:

        ADDR0,R0,#1;R0←R0+1

        ADDR0,R0,#0x3f;R0←R0+0x3f

        在以上兩條指令中,第二個源操作數即為立即數,要求以“#”為前綴,對于以十六進制表示的立即數,還要求在“#”后加上“0x”或“&”。

        3.2.2寄存器尋址

        寄存器尋址就是利用寄存器中的數值作為操作數,這種尋址方式是各類微處理器經常采用的一種方式,也是一種執行效率較高的尋址方式。以下指令:

        ADDR0,R1,R2;R0←R1+R2

        該指令的執行效果是將寄存器R1和R2的內容相加,其結果存放在寄存器R0中。

        3.2.2寄存器間接尋址

        寄存器間接尋址就是以寄存器中的值作為操作數的地址,而操作數本身存放在存儲器中。例如以下指令:

        ADD R0,R1,[R2];R0←R1+[R2]

        LDRR0,[R1];R0←[R1]

        STRR0,[R1];[R1]←R0

        在第一條指令中,以寄存器R2的值作為操作數的地址,在存儲器中取得一個操作數后與R1相加,結果存入寄存器R0中。

        第二條指令將以R1的值為地址的存儲器中的數據傳送到R0中。

        第三條指令將R0的值傳送到以R1的值為地址的存儲器中。

        3.2.3基址變址尋址

        基址變址尋址就是將寄存器(該寄存器一般稱作基址寄存器)的內容與指令中給出的地址偏移量相加,從而得到一個操作數的有效地址。變址尋址方式常用于訪問某基地址附近的地址單元。采用變址尋址方式的指令常見有以下幾種形式,如下所示:

        LDR R0,[R1,#4];R0←[R1+4]

        LDR R0,[R1,#4]!;R0←[R1+4]、R1←R1+4

        LDR R0,[R1],#4;R0←[R1]、R1←R1+4

        LDR R0,[R1,R2];R0←[R1+R2]

        在第一條指令中,將寄存器R1的內容加上4形成操作數的有效地址,從而取得操作數存入寄存器R0中。

        在第二條指令中,將寄存器R1的內容加上4形成操作數的有效地址,從而取得操作數存入寄存器R0中,然后,R1的內容自增4個字節。

        在第三條指令中,以寄存器R1的內容作為操作數的有效地址,從而取得操作數存入寄存器R0中,然后,R1的內容自增4個字節。

        在第四條指令中,將寄存器R1的內容加上寄存器R2的內容形成操作數的有效地址,從而取得操作數存入寄存器R0中。

        3.2.4多寄存器尋址

        采用多寄存器尋址方式,一條指令可以完成多個寄存器值的傳送。這種尋址方式可以用一條指令完成傳送最多16個通用寄存器的值。以下指令:

        LDMIA R0,{R1,R2,R3,R4};R1←[R0]

        ;R2←[R0+4]

        ;R3←[R0+8]

        ;R4←[R0+12]

        該指令的后綴IA表示在每次執行完加載/存儲操作后,R0按字長度增加,因此,指令可將連續存儲單元的值傳送到R1~R4。

        3.2.5相對尋址

        與基址變址尋址方式相類似,相對尋址以程序計數器PC的當前值為基地址,指令中的地址標號作為偏移量,將兩者相加之后得到操作數的有效地址。以下程序段完成子程序的調用和返回,跳轉指令BL采用了相對尋址方式:

        BLNEXT;跳轉到子程序NEXT處執行

        ……

        NEXT

        ……

        MOVPC,LR;從子程序返回

        3.2.6堆棧尋址

        堆棧是一種數據結構,按先進后出(First In Last Out,FILO)的方式工作,使用一個稱作堆棧指針的專用寄存器指示當前的操作位置,堆棧指針總是指向棧頂。

        當堆棧指針指向最后壓入堆棧的數據時,稱為滿堆棧(Full Stack),而當堆棧指針指向下一個將要放入數據的空位置時,稱為空堆棧(Empty Stack)。

        同時,根據堆棧的生成方式,又可以分為遞增堆棧(AscendingStack)和遞減堆棧(Decending Stack),當堆棧由低地址向高地址生成時,稱為遞增堆棧,當堆棧由高地址向低地址生成時,稱為遞減堆棧。這樣就有四種類型的堆棧工作方式,ARM微處理器支持這四種類型的堆棧工作方式,即:

        -滿遞增堆棧:堆棧指針指向最后壓入的數據,且由低地址向高地址生成。

        -滿遞減堆棧:堆棧指針指向最后壓入的數據,且由高地址向低地址生成。

        -空遞增堆棧:堆棧指針指向下一個將要放入數據的空位置,且由低地址向高地址生成。

        -空遞減堆棧:堆棧指針指向下一個將要放入數據的空位置,且由高地址向低地址生成。

        3.3ARM指令集

        本節對ARM指令集的六大類指令進行詳細的描述。

        3.3.1跳轉指令

        跳轉指令用于實現程序流程的跳轉,在ARM程序中有兩種方法可以實現程序流程的跳轉:

        —使用專門的跳轉指令。

        —直接向程序計數器PC寫入跳轉地址值。

        通過向程序計數器PC寫入跳轉地址值,可以實現在4GB的地址空間中的任意跳轉,在跳轉之前結合使用

        MOVLR,PC

        等類似指令,可以保存將來的返回地址值,從而實現在4GB連續的線性地址空間的子程序調用。

        ARM指令集中的跳轉指令可以完成從當前指令向前或向后的32MB的地址空間的跳轉,包括以下4條指令:

        —B跳轉指令

        —BL帶返回的跳轉指令

        —BLX帶返回和狀態切換的跳轉指令

        —BX帶狀態切換的跳轉指令

        1、B指令

        B指令的格式為:

        B{條件}目標地址

        B指令是最簡單的跳轉指令。一旦遇到一個B指令,ARM處理器將立即跳轉到給定的目標地址,從那里繼續執行。注意存儲在跳轉指令中的實際值是相對當前PC值的一個偏移量,而不是一個絕對地址,它的值由匯編器來計算(參考尋址方式中的相對尋址)。它是24位有符號數,左移兩位后有符號擴展為32位,表示的有效偏移為26位(前后32MB的地址空間)。以下指令:

        BLabel;程序無條件跳轉到標號Label處執行

        CMPR1,#0;當CPSR寄存器中的Z條件碼置位時,程序跳轉到標號Label處執行

        BEQLabel

        2、BL指令

        BL指令的格式為:

        BL{條件}目標地址

        BL是另一個跳轉指令,但跳轉之前,會在寄存器R14中保存PC的當前內容,因此,可以通過將R14的內容重新加載到PC中,來返回到跳轉指令之后的那個指令處執行。該指令是實現子程序調用的一個基本但常用的手段。以下指令:

        BLLabel;當程序無條件跳轉到標號Label處執行時,同時將當前的PC值保存到R14中

        3、BLX指令

        BLX指令的格式為:

        BLX目標地址

        BLX指令從ARM指令集跳轉到指令中所指定的目標地址,并將處理器的工作狀態有ARM狀態切換到Thumb狀態,該指令同時將PC的當前內容保存到寄存器R14中。因此,當子程序使用Thumb指令集,而調用者使用ARM指令集時,可以通過BLX指令實現子程序的調用和處理器工作狀態的切換。同時,子程序的返回可以通過將寄存器R14值到PC中來完成。

        4、BX指令

        BX指令的格式為:

        BX{條件}目標地址

        BX指令跳轉到指令中所指定的目標地址,目標地址處的指令既可以是ARM指令,也可以是Thumb指令。

        3.3.2數據處理指令

        數據處理指令可分為數據傳送指令、算術邏輯運算指令和比較指令等。

        數據傳送指令用于在寄存器和存儲器之間進行數據的雙向傳輸。

        算術邏輯運算指令完成常用的算術與邏輯的運算,該類指令不但將運算結果保存在目的寄存器中,同時更新CPSR中的相應條件標志位。

        比較指令不保存運算結果,只更新CPSR中相應的條件標志位。

        數據處理指令包括:

        —MOV數據傳送指令

        —MVN數據取反傳送指令

        —CMP比較指令

        —CMN反值比較指令

        —TST位測試指令

        —TEQ相等測試指令

        —ADD加法指令

        —ADC帶進位加法指令

        —SUB減法指令

        —SBC帶借位減法指令

        —RSB逆向減法指令

        —RSC帶借位的逆向減法指令

        —AND邏輯與指令

        —ORR邏輯或指令

        —EOR邏輯異或指令

        —BIC位清除指令

        1、MOV指令

        MOV指令的格式為:

        MOV{條件}{S}目的寄存器,源操作數

        MOV指令可完成從另一個寄存器、被移位的寄存器或將一個立即數加載到目的寄存器。其中S選項決定指令的操作是否影響CPSR中條件標志位的值,當沒有S時指令不更新CPSR中條件標志位的值。

        指令示例:

        MOVR1,R0;將寄存器R0的值傳送到寄存器R1

        MOVPC,R14;將寄存器R14的值傳送到PC,常用于子程序返回

        MOVR1,R0,LSL#3;將寄存器R0的值左移3位后傳送到R1

        2、MVN指令

        MVN指令的格式為:

        MVN{條件}{S}目的寄存器,源操作數

        MVN指令可完成從另一個寄存器、被移位的寄存器、或將一個立即數加載到目的寄存器。與MOV指令不同之處是在傳送之前按位被取反了,即把一個被取反的值傳送到目的寄存器中。其中S決定指令的操作是否影響CPSR中條件標志位的值,當沒有S時指令不更新CPSR中條件標志位的值。

        指令示例:

        MVNR0,#0;將立即數0取反傳送到寄存器R0中,完成后R0=-1

        3、CMP指令

        CMP指令的格式為:

        CMP{條件}操作數1,操作數2

        CMP指令用于把一個寄存器的內容和另一個寄存器的內容或立即數進行比較,同時更新CPSR中條件標志位的值。該指令進行一次減法運算,但不存儲結果,只更改條件標志位。標志位表示的是操作數1與操作數2的關系(大、小、相等),例如,當操作數1大于操作操作數2,則此后的有GT后綴的指令將可以執行。

        指令示例:

        CMPR1,R0;將寄存器R1的值與寄存器R0的值相減,并根據結果設置CPSR的標志位

        CMPR1,#100;將寄存器R1的值與立即數100相減,并根據結果設置CPSR的標志位

        4、CMN指令

        CMN指令的格式為:

        CMN{條件}操作數1,操作數2

        CMN指令用于把一個寄存器的內容和另一個寄存器的內容或立即數取反后進行比較,同時更新CPSR中條件標志位的值。該指令實際完成操作數1和操作數2相加,并根據結果更改條件標志位。

        指令示例:

        CMNR1,R0;將寄存器R1的值與寄存器R0的值相加,并根據結果設置CPSR的標志位

        CMNR1,#100;將寄存器R1的值與立即數100相加,并根據結果設置CPSR的標志位

        5、TST指令

        TST指令的格式為:

        TST{條件}操作數1,操作數2

        TST指令用于把一個寄存器的內容和另一個寄存器的內容或立即數進行按位的與運算,并根據運算結果更新CPSR中條件標志位的值。操作數1是要測試的數據,而操作數2是一個位掩碼,該指令一般用來檢測是否設置了特定的位。

        指令示例:

        TSTR1,#%1;用于測試在寄存器R1中是否設置了最低位(%表示二進制數

        TSTR1,#0xffe;將寄存器R1的值與立即數0xffe按位與,并根據結果設置CPSR的標志位

        6、TEQ指令

        TEQ指令的格式為:

        TEQ{條件}操作數1,操作數2

        TEQ指令用于把一個寄存器的內容和另一個寄存器的內容或立即數進行按位的異或運算,并根據運算結果更新CPSR中條件標志位的值。該指令通常用于比較操作數1和操作數2是否相等。

        指令示例:

        TEQR1,R2;將寄存器R1的值與寄存器R2的值按位異或,并根據結果設置CPSR的標志位

        7、ADD指令

        ADD指令的格式為:

        ADD{條件}{S}目的寄存器,操作數1,操作數2

        ADD指令用于把兩個操作數相加,并將結果存放到目的寄存器中。操作數1應是一個寄存器,操作數2可以是一個寄存器,被移位的寄存器,或一個立即數。

        指令示例:

        ADDR0,R1,R2;R0 = R1 + R2

        ADDR0,R1,#256;R0 = R1 + 256

        ADDR0,R2,R3,LSL#1;R0 = R2 + (R3 << 1)

        8、ADC指令

        ADC指令的格式為:

        ADC{條件}{S}目的寄存器,操作數1,操作數2

        ADC指令用于把兩個操作數相加,再加上CPSR中的C條件標志位的值,并將結果存放到目的寄存器中。它使用一個進位標志位,這樣就可以做比32位大的數的加法,注意不要忘記設置S后綴來更改進位標志。操作數1應是一個寄存器,操作數2可以是一個寄存器,被移位的寄存器,或一個立即數。

        以下指令序列完成兩個128位數的加法,第一個數由高到低存放在寄存器R7~R4,第二個數由高到低存放在寄存器R11~R8,運算結果由高到低存放在寄存器R3~R0:

        ADDSR0,R4,R8;加低端的字

        ADCSR1,R5,R9;加第二個字,帶進位

        ADCSR2,R6,R10;加第三個字,帶進位

        ADCR3,R7,R11;加第四個字,帶進位

        9、SUB指令

        SUB指令的格式為:

        SUB{條件}{S}目的寄存器,操作數1,操作數2

        SUB指令用于把操作數1減去操作數2,并將結果存放到目的寄存器中。操作數1應是一個寄存器,操作數2可以是一個寄存器,被移位的寄存器,或一個立即數。該指令可用于有符號數或無符號數的減法運算。

        指令示例:

        SUBR0,R1,R2;R0 = R1 - R2

        SUBR0,R1,#256;R0 = R1 - 256

        SUBR0,R2,R3,LSL#1;R0 = R2 - (R3 << 1)

        10、SBC指令

        SBC指令的格式為:

        SBC{條件}{S}目的寄存器,操作數1,操作數2

        SBC指令用于把操作數1減去操作數2,再減去CPSR中的C條件標志位的反碼,并將結果存放到目的寄存器中。操作數1應是一個寄存器,操作數2可以是一個寄存器,被移位的寄存器,或一個立即數。該指令使用進位標志來表示借位,這樣就可以做大于32位的減法,注意不要忘記設置S后綴來更改進位標志。該指令可用于有符號數或無符號數的減法運算。

        指令示例:

        SUBSR0,R1,R2;R0 = R1 - R2 -!C,并根據結果設置CPSR的進位標志位

        11、RSB指令

        RSB指令的格式為:

        RSB{條件}{S}目的寄存器,操作數1,操作數2

        RSB指令稱為逆向減法指令,用于把操作數2減去操作數1,并將結果存放到目的寄存器中。操作數1應是一個寄存器,操作數2可以是一個寄存器,被移位的寄存器,或一個立即數。該指令可用于有符號數或無符號數的減法運算。

        指令示例:

        RSBR0,R1,R2;R0 = R2 – R1

        RSBR0,R1,#256;R0 = 256 – R1

        RSBR0,R2,R3,LSL#1;R0 = (R3 << 1) - R2

        12、RSC指令

        RSC指令的格式為:

        RSC{條件}{S}目的寄存器,操作數1,操作數2

        RSC指令用于把操作數2減去操作數1,再減去CPSR中的C條件標志位的反碼,并將結果存放到目的寄存器中。操作數1應是一個寄存器,操作數2可以是一個寄存器,被移位的寄存器,或一個立即數。該指令使用進位標志來表示借位,這樣就可以做大于32位的減法,注意不要忘記設置S后綴來更改進位標志。該指令可用于有符號數或無符號數的減法運算。

        指令示例:

        RSCR0,R1,R2;R0 = R2 – R1 -!C

        13、AND指令

        AND指令的格式為:

        AND{條件}{S}目的寄存器,操作數1,操作數2

        AND指令用于在兩個操作數上進行邏輯與運算,并把結果放置到目的寄存器中。操作數1應是一個寄存器,操作數2可以是一個寄存器,被移位的寄存器,或一個立即數。該指令常用于屏蔽操作數1的某些位。

        指令示例:

        ANDR0,R0,#3;該指令保持R0的0、1位,其余位清零。

        14、ORR指令

        ORR指令的格式為:

        ORR{條件}{S}目的寄存器,操作數1,操作數2

        ORR指令用于在兩個操作數上進行邏輯或運算,并把結果放置到目的寄存器中。操作數1應是一個寄存器,操作數2可以是一個寄存器,被移位的寄存器,或一個立即數。該指令常用于設置操作數1的某些位。

        指令示例:

        ORRR0,R0,#3;該指令設置R0的0、1位,其余位保持不變。

        15、EOR指令

        EOR指令的格式為:

        EOR{條件}{S}目的寄存器,操作數1,操作數2

        EOR指令用于在兩個操作數上進行邏輯異或運算,并把結果放置到目的寄存器中。操作數1應是一個寄存器,操作數2可以是一個寄存器,被移位的寄存器,或一個立即數。該指令常用于反轉操作數1的某些位。

        指令示例:

        EORR0,R0,#3;該指令反轉R0的0、1位,其余位保持不變。

        16、BIC指令

        BIC指令的格式為:

        BIC{條件}{S}目的寄存器,操作數1,操作數2

        BIC指令用于清除操作數1的某些位,并把結果放置到目的寄存器中。操作數1應是一個寄存器,操作數2可以是一個寄存器,被移位的寄存器,或一個立即數。操作數2為32位的掩碼,如果在掩碼中設置了某一位,則清除這一位。未設置的掩碼位保持不變。

        指令示例:

        BICR0,R0,#%1011;該指令清除R0中的位0、1、和3,其余的位保持不變。

        3.3.3乘法指令與乘加指令

        ARM微處理器支持的乘法指令與乘加指令共有6條,可分為運算結果為32位和運算結果為64位兩類,與前面的數據處理指令不同,指令中的所有操作數、目的寄存器必須為通用寄存器,不能對操作數使用立即數或被移位的寄存器,同時,目的寄存器和操作數1必須是不同的寄存器。

        乘法指令與乘加指令共有以下6條:

        —MUL32位乘法指令

        —MLA32位乘加指令

        —SMULL64位有符號數乘法指令

        —SMLAL64位有符號數乘加指令

        —UMULL64位無符號數乘法指令

        —UMLAL64位無符號數乘加指令

        1、MUL指令

        MUL指令的格式為:

        MUL{條件}{S}目的寄存器,操作數1,操作數2

        MUL指令完成將操作數1與操作數2的乘法運算,并把結果放置到目的寄存器中,同時可以根據運算結果設置CPSR中相應的條件標志位。其中,操作數1和操作數2均為32位的有符號數或無符號數。

        指令示例:

        MULR0,R1,R2;R0 = R1×R2

        MULSR0,R1,R2;R0 = R1×R2,同時設置CPSR中的相關條件標志位

        2、MLA指令

        MLA指令的格式為:

        MLA{條件}{S}目的寄存器,操作數1,操作數2,操作數3

        MLA指令完成將操作數1與操作數2的乘法運算,再將乘積加上操作數3,并把結果放置到目的寄存器中,同時可以根據運算結果設置CPSR中相應的條件標志位。其中,操作數1和操作數2均為32位的有符號數或無符號數。

        指令示例:

        MLAR0,R1,R2,R3;R0 = R1×R2 + R3

        MLASR0,R1,R2,R3;R0 = R1×R2 + R3,同時設置CPSR中的相關條件標志位

        3、SMULL指令

        SMULL指令的格式為:

        SMULL{條件}{S}目的寄存器Low,目的寄存器低High,操作數1,操作數2

        SMULL指令完成將操作數1與操作數2的乘法運算,并把結果的低32位放置到目的寄存器Low中,結果的高32位放置到目的寄存器High中,同時可以根據運算結果設置CPSR中相應的條件標志位。其中,操作數1和操作數2均為32位的有符號數。

        指令示例:

        SMULLR0,R1,R2,R3;R0 =(R2×R3)的低32位

        ;R1 =(R2×R3)的高32位

        4、SMLAL指令

        SMLAL指令的格式為:

        SMLAL{條件}{S}目的寄存器Low,目的寄存器低High,操作數1,操作數2

        SMLAL指令完成將操作數1與操作數2的乘法運算,并把結果的低32位同目的寄存器Low中的值相加后又放置到目的寄存器Low中,結果的高32位同目的寄存器High中的值相加后又放置到目的寄存器High中,同時可以根據運算結果設置CPSR中相應的條件標志位。其中,操作數1和操作數2均為32位的有符號數。

        對于目的寄存器Low,在指令執行前存放64位加數的低32位,指令執行后存放結果的低32位。

        對于目的寄存器High,在指令執行前存放64位加數的高32位,指令執行后存放結果的高32位。

        指令示例:

        SMLALR0,R1,R2,R3;R0 =(R2×R3)的低32位+R0

        ;R1 =(R2×R3)的高32位+R1

        5、UMULL指令

        UMULL指令的格式為:

        UMULL{條件}{S}目的寄存器Low,目的寄存器低High,操作數1,操作數2

        UMULL指令完成將操作數1與操作數2的乘法運算,并把結果的低32位放置到目的寄存器Low中,結果的高32位放置到目的寄存器High中,同時可以根據運算結果設置CPSR中相應的條件標志位。其中,操作數1和操作數2均為32位的無符號數。

        指令示例:

        UMULLR0,R1,R2,R3;R0 =(R2×R3)的低32位

        ;R1 =(R2×R3)的高32位

        6、UMLAL指令

        UMLAL指令的格式為:

        UMLAL{條件}{S}目的寄存器Low,目的寄存器低High,操作數1,操作數2

        UMLAL指令完成將操作數1與操作數2的乘法運算,并把結果的低32位同目的寄存器Low中的值相加后又放置到目的寄存器Low中,結果的高32位同目的寄存器High中的值相加后又放置到目的寄存器High中,同時可以根據運算結果設置CPSR中相應的條件標志位。其中,操作數1和操作數2均為32位的無符號數。

        對于目的寄存器Low,在指令執行前存放64位加數的低32位,指令執行后存放結果的低32位。

        對于目的寄存器High,在指令執行前存放64位加數的高32位,指令執行后存放結果的高32位。

        指令示例:

        UMLALR0,R1,R2,R3;R0 =(R2×R3)的低32位+R0

        ;R1 =(R2×R3)的高32位+R1

        3.3.4程序狀態寄存器訪問指令

        ARM微處理器支持程序狀態寄存器訪問指令,用于在程序狀態寄存器和通用寄存器之間傳送數據,程序狀態寄存器訪問指令包括以下兩條:

        —MRS程序狀態寄存器到通用寄存器的數據傳送指令

        —MSR通用寄存器到程序狀態寄存器的數據傳送指令

        1、MRS指令

        MRS指令的格式為:

        MRS{條件}通用寄存器,程序狀態寄存器(CPSR或SPSR)

        MRS指令用于將程序狀態寄存器的內容傳送到通用寄存器中。該指令一般用在以下幾種情況:

        -當需要改變程序狀態寄存器的內容時,可用MRS將程序狀態寄存器的內容讀入通用寄存器,修改后再寫回程序狀態寄存器。

        -當在異常處理或進程切換時,需要保存程序狀態寄存器的值,可先用該指令讀出程序狀態寄存器的值,然后保存。

        指令示例:

        MRSR0,CPSR;傳送CPSR的內容到R0

        MRSR0,SPSR;傳送SPSR的內容到R0

        2、MSR指令

        MSR指令的格式為:

        MSR{條件}程序狀態寄存器(CPSR或SPSR)_<域>,操作數

        MSR指令用于將操作數的內容傳送到程序狀態寄存器的特定域中。其中,操作數可以為通用寄存器或立即數。<域>用于設置程序狀態寄存器中需要操作的位,32位的程序狀態寄存器可分為4個域:

        位[31:24]為條件標志位域,用f表示;

        位[23:16]為狀態位域,用s表示;

        位[15:8]為擴展位域,用x表示;

        位[7:0]為控制位域,用c表示;

        該指令通常用于恢復或改變程序狀態寄存器的內容,在使用時,一般要在MSR指令中指明將要操作的域。

        指令示例:

        MSRCPSR,R0;傳送R0的內容到CPSR

        MSRSPSR,R0;傳送R0的內容到SPSR

        MSRCPSR_c,R0;傳送R0的內容到SPSR,但僅僅修改CPSR中的控制位域

        3.3.5加載/存儲指令

        ARM微處理器支持加載/存儲指令用于在寄存器和存儲器之間傳送數據,加載指令用于將存儲器中的數據傳送到寄存器,存儲指令則完成相反的操作。常用的加載存儲指令如下:

        —LDR字數據加載指令

        —LDRB字節數據加載指令

        —LDRH半字數據加載指令

        —STR字數據存儲指令

        —STRB字節數據存儲指令

        —STRH半字數據存儲指令

        1、LDR指令

        LDR指令的格式為:

        LDR{條件}目的寄存器,<存儲器地址>

        LDR指令用于從存儲器中將一個32位的字數據傳送到目的寄存器中。該指令通常用于從存儲器中讀取32位的字數據到通用寄存器,然后對數據進行處理。當程序計數器PC作為目的寄存器時,指令從存儲器中讀取的字數據被當作目的地址,從而可以實現程序流程的跳轉。該指令在程序設計中比較常用,且尋址方式靈活多樣,請讀者認真掌握。

        指令示例:

        LDRR0,[R1];將存儲器地址為R1的字數據讀入寄存器R0。

        LDRR0,[R1,R2];將存儲器地址為R1+R2的字數據讀入寄存器R0。

        LDRR0,[R1,#8];將存儲器地址為R1+8的字數據讀入寄存器R0。

        LDRR0,[R1,R2]!;將存儲器地址為R1+R2的字數據讀入寄存器R0,并將新地址R1+R2寫入R1。

        LDRR0,[R1,#8]!;將存儲器地址為R1+8的字數據讀入寄存器R0,并將新地址R1+8寫入R1。

        LDRR0,[R1],R2;將存儲器地址為R1的字數據讀入寄存器R0,并將新地址R1+R2寫入R1。

        LDRR0,[R1,R2,LSL#2]!;將存儲器地址為R1+R2×4的字數據讀入寄存器R0,并將新地址R1+R2×4寫入R1。

        LDRR0,[R1],R2,LSL#2;將存儲器地址為R1的字數據讀入寄存器R0,并將新地址R1+R2×4寫入R1。

        2、LDRB指令

        LDRB指令的格式為:

        LDR{條件}B目的寄存器,<存儲器地址>

        LDRB指令用于從存儲器中將一個8位的字節數據傳送到目的寄存器中,同時將寄存器的高24位清零。該指令通常用于從存儲器中讀取8位的字節數據到通用寄存器,然后對數據進行處理。當程序計數器PC作為目的寄存器時,指令從存儲器中讀取的字數據被當作目的地址,從而可以實現程序流程的跳轉。

        指令示例:

        LDRBR0,[R1];將存儲器地址為R1的字節數據讀入寄存器R0,并將R0的高24位清零。

        LDRBR0,[R1,#8];將存儲器地址為R1+8的字節數據讀入寄存器R0,并將R0的高24位清零。

        3、LDRH指令

        LDRH指令的格式為:

        LDR{條件}H目的寄存器,<存儲器地址>

        LDRH指令用于從存儲器中將一個16位的半字數據傳送到目的寄存器中,同時將寄存器的高16位清零。該指令通常用于從存儲器中讀取16位的半字數據到通用寄存器,然后對數據進行處理。當程序計數器PC作為目的寄存器時,指令從存儲器中讀取的字數據被當作目的地址,從而可以實現程序流程的跳轉。

        指令示例:

        LDRHR0,[R1];將存儲器地址為R1的半字數據讀入寄存器R0,并將R0的高16位清零。

        LDRHR0,[R1,#8];將存儲器地址為R1+8的半字數據讀入寄存器R0,并將R0的高16位清零。

        LDRHR0,[R1,R2];將存儲器地址為R1+R2的半字數據讀入寄存器R0,并將R0的高16位清零。

        4、STR指令

        STR指令的格式為:

        STR{條件}源寄存器,<存儲器地址>

        STR指令用于從源寄存器中將一個32位的字數據傳送到存儲器中。該指令在程序設計中比較常用,且尋址方式靈活多樣,使用方式可參考指令LDR。

        指令示例:

        STRR0,[R1],#8;將R0中的字數據寫入以R1為地址的存儲器中,并將新地址R1+8寫入R1。

        STRR0,[R1,#8];將R0中的字數據寫入以R1+8為地址的存儲器中。

        5、STRB指令

        STRB指令的格式為:

        STR{條件}B源寄存器,<存儲器地址>

        STRB指令用于從源寄存器中將一個8位的字節數據傳送到存儲器中。該字節數據為源寄存器中的低8位。

        指令示例:

        STRBR0,[R1];將寄存器R0中的字節數據寫入以R1為地址的存儲器中。

        STRBR0,[R1,#8];將寄存器R0中的字節數據寫入以R1+8為地址的存儲器中。

        6、STRH指令

        STRH指令的格式為:

        STR{條件}H源寄存器,<存儲器地址>

        STRH指令用于從源寄存器中將一個16位的半字數據傳送到存儲器中。該半字數據為源寄存器中的低16位。

        指令示例:

        STRHR0,[R1];將寄存器R0中的半字數據寫入以R1為地址的存儲器中。

        STRHR0,[R1,#8];將寄存器R0中的半字數據寫入以R1+8為地址的存儲器中。

        3.3.6批量數據加載/存儲指令

        ARM微處理器所支持批量數據加載/存儲指令可以一次在一片連續的存儲器單元和多個寄存器之間傳送數據,批量加載指令用于將一片連續的存儲器中的數據傳送到多個寄存器,批量數據存儲指令則完成相反的操作。常用的加載存儲指令如下:

        —LDM批量數據加載指令

        —STM批量數據存儲指令

        LDM(或STM)指令

        LDM(或STM)指令的格式為:

        LDM(或STM){條件}{類型}基址寄存器{!},寄存器列表{∧}

        LDM(或STM)指令用于從由基址寄存器所指示的一片連續存儲器到寄存器列表所指示的多個寄存器之間傳送數據,該指令的常見用途是將多個寄存器的內容入棧或出棧。其中,{類型}為以下幾種情況:

        IA每次傳送后地址加1;

        IB每次傳送前地址加1;

        DA每次傳送后地址減1;

        DB每次傳送前地址減1;

        FD滿遞減堆棧;

        ED空遞減堆棧;

        FA滿遞增堆棧;

        EA空遞增堆棧;

        {!}為可選后綴,若選用該后綴,則當數據傳送完畢之后,將最后的地址寫入基址寄存器,否則基址寄存器的內容不改變。

        基址寄存器不允許為R15,寄存器列表可以為R0~R15的任意組合。

        {∧}為可選后綴,當指令為LDM且寄存器列表中包含R15,選用該后綴時表示:除了正常的數據傳送之外,還將SPSR到CPSR。同時,該后綴還表示傳入或傳出的是用戶模式下的寄存器,而不是當前模式下的寄存器。

        指令示例:

        STMFDR13!,{R0,R4-R12,LR};將寄存器列表中的寄存器(R0,R4到R12,LR)存入堆棧。

        LDMFDR13!,{R0,R4-R12,PC};將堆棧內容恢復到寄存器(R0,R4到R12,LR)。

        3.3.7數據交換指令

        ARM微處理器所支持數據交換指令能在存儲器和寄存器之間交換數據。數據交換指令有如下兩條:

        —SWP字數據交換指令

        —SWPB字節數據交換指令

        1、SWP指令

        SWP指令的格式為:

        SWP{條件}目的寄存器,源寄存器1,[源寄存器2]

        SWP指令用于將源寄存器2所指向的存儲器中的字數據傳送到目的寄存器中,同時將源寄存器1中的字數據傳送到源寄存器2所指向的存儲器中。顯然,當源寄存器1和目的寄存器為同一個寄存器時,指令交換該寄存器和存儲器的內容。

        指令示例:

        SWPR0,R1,[R2];將R2所指向的存儲器中的字數據傳送到R0,同時將R1中的字數據傳送到R2所指向的存儲單元。

        SWPR0,R0,[R1];該指令完成將R1所指向的存儲器中的字數據與R0中的字數據交換。

        2、SWPB指令

        SWPB指令的格式為:

        SWP{條件}B目的寄存器,源寄存器1,[源寄存器2]

        SWPB指令用于將源寄存器2所指向的存儲器中的字節數據傳送到目的寄存器中,目的寄存器的高24清零,同時將源寄存器1中的字節數據傳送到源寄存器2所指向的存儲器中。顯然,當源寄存器1和目的寄存器為同一個寄存器時,指令交換該寄存器和存儲器的內容。

        指令示例:

        SWPBR0,R1,[R2];將R2所指向的存儲器中的字節數據傳送到R0,R0的高24位清零,同時將R1中的低8位數據傳送到R2所指向的存儲單元。

        SWPBR0,R0,[R1];該指令完成將R1所指向的存儲器中的字節數據與R0中的低8位數據交換。

        3.3.8移位指令(操作)

        ARM微處理器內嵌的桶型移位器(Barrel Shifter),支持數據的各種移位操作,移位操作在ARM指令集中不作為單獨的指令使用,它只能作為指令格式中是一個字段,在匯編語言中表示為指令中的選項。例如,數據處理指令的第二個操作數為寄存器時,就可以加入移位操作選項對它進行各種移位操作。移位操作包括如下6種類型,ASL和LSL是等價的,可以自由互換:

        —LSL邏輯左移

        —ASL算術左移

        —LSR邏輯右移

        —ASR算術右移

        —ROR循環右移

        —RRX帶擴展的循環右移

        1、LSL(或ASL)操作

        LSL(或ASL)操作的格式為:

        通用寄存器,LSL(或ASL)操作數

        LSL(或ASL)可完成對通用寄存器中的內容進行邏輯(或算術)的左移操作,按操作數所指定的數量向左移位,低位用零來填充。其中,操作數可以是通用寄存器,也可以是立即數(0~31)。

        操作示例:

        MOVR0, R1, LSL#2;將R1中的內容左移兩位后傳送到R0中。

        2、LSR操作

        LSR操作的格式為:

        通用寄存器,LSR操作數

        LSR可完成對通用寄存器中的內容進行右移的操作,按操作數所指定的數量向右移位,左端用零來填充。其中,操作數可以是通用寄存器,也可以是立即數(0~31)。

        操作示例:

        MOVR0, R1, LSR#2;將R1中的內容右移兩位后傳送到R0中,左端用零來填充。

        3、ASR操作

        ASR操作的格式為:

        通用寄存器,ASR操作數

        ASR可完成對通用寄存器中的內容進行右移的操作,按操作數所指定的數量向右移位,左端用第31位的值來填充。其中,操作數可以是通用寄存器,也可以是立即數(0~31)。

        操作示例:

        MOVR0, R1, ASR#2;將R1中的內容右移兩位后傳送到R0中,左端用第31位的值來填充。

        4、ROR操作

        ROR操作的格式為:

        通用寄存器,ROR操作數

        ROR可完成對通用寄存器中的內容進行循環右移的操作,按操作數所指定的數量向右循環移位,左端用右端移出的位來填充。其中,操作數可以是通用寄存器,也可以是立即數(0~31)。顯然,當進行32位的循環右移操作時,通用寄存器中的值不改變。

        操作示例:

        MOVR0, R1, ROR#2;將R1中的內容循環右移兩位后傳送到R0中。

        5、RRX操作

        RRX操作的格式為:

        通用寄存器,RRX操作數

        RRX可完成對通用寄存器中的內容進行帶擴展的循環右移的操作,按操作數所指定的數量向右循環移位,左端用進位標志位C來填充。其中,操作數可以是通用寄存器,也可以是立即數(0~31)。

        操作示例:

        MOVR0, R1, RRX#2;將R1中的內容進行帶擴展的循環右移兩位后傳送到R0中。

        3.3.9協處理器指令

        ARM微處理器可支持多達16個協處理器,用于各種協處理操作,在程序執行的過程中,每個協處理器只執行針對自身的協處理指令,忽略ARM處理器和其他協處理器的指令。

        ARM的協處理器指令主要用于ARM處理器初始化ARM協處理器的數據處理操作,以及在ARM處理器的寄存器和協處理器的寄存器之間傳送數據,和在ARM協處理器的寄存器和存儲器之間傳送數據。ARM協處理器指令包括以下5條:

        —CDP協處理器數操作指令

        —LDC協處理器數據加載指令

        —STC協處理器數據存儲指令

        —MCRARM處理器寄存器到協處理器寄存器的數據傳送指令

        —MRC協處理器寄存器到ARM處理器寄存器的數據傳送指令

        1、CDP指令

        CDP指令的格式為:

        CDP{條件}協處理器編碼,協處理器操作碼1,目的寄存器,源寄存器1,源寄存器2,協處理器操作碼2。

        CDP指令用于ARM處理器通知ARM協處理器執行特定的操作,若協處理器不能成功完成特定的操作,則產生未定義指令異常。其中協處理器操作碼1和協處理器操作碼2為協處理器將要執行的操作,目的寄存器和源寄存器均為協處理器的寄存器,指令不涉及ARM處理器的寄存器和存儲器。

        指令示例:

        CDPP3,2,C12,C10,C3,4;該指令完成協處理器P3的初始化

        2、LDC指令

        LDC指令的格式為:

        LDC{條件}{L}協處理器編碼,目的寄存器,[源寄存器]

        LDC指令用于將源寄存器所指向的存儲器中的字數據傳送到目的寄存器中,若協處理器不能成功完成傳送操作,則產生未定義指令異常。其中,{L}選項表示指令為長讀取操作,如用于雙精度數據的傳輸。

        指令示例:

        LDCP3,C4,[R0];將ARM處理器的寄存器R0所指向的存儲器中的字數據傳送到協處理器P3的寄存器C4中。

        3、STC指令

        STC指令的格式為:

        STC{條件}{L}協處理器編碼,源寄存器,[目的寄存器]

        STC指令用于將源寄存器中的字數據傳送到目的寄存器所指向的存儲器中,若協處理器不能成功完成傳送操作,則產生未定義指令異常。其中,{L}選項表示指令為長讀取操作,如用于雙精度數據的傳輸。

        指令示例:

        STCP3,C4,[R0];將協處理器P3的寄存器C4中的字數據傳送到ARM處理器的寄存器R0所指向的存儲器中。

        4、MCR指令

        MCR指令的格式為:

        MCR{條件}協處理器編碼,協處理器操作碼1,源寄存器,目的寄存器1,目的寄存器2,協處理器操作碼2。

        MCR指令用于將ARM處理器寄存器中的數據傳送到協處理器寄存器中,若協處理器不能成功完成操作,則產生未定義指令異常。其中協處理器操作碼1和協處理器操作碼2為協處理器將要執行的操作,源寄存器為ARM處理器的寄存器,目的寄存器1和目的寄存器2均為協處理器的寄存器。

        指令示例:

        MCRP3,3,R0,C4,C5,6;該指令將ARM處理器寄存器R0中的數據傳送到協處理器P3的寄存器C4和C5中。

        5、MRC指令

        MRC指令的格式為:

        MRC{條件}協處理器編碼,協處理器操作碼1,目的寄存器,源寄存器1,源寄存器2,協處理器操作碼2。

        MRC指令用于將協處理器寄存器中的數據傳送到ARM處理器寄存器中,若協處理器不能成功完成操作,則產生未定義指令異常。其中協處理器操作碼1和協處理器操作碼2為協處理器將要執行的操作,目的寄存器為ARM處理器的寄存器,源寄存器1和源寄存器2均為協處理器的寄存器。

        指令示例:

        MRCP3,3,R0,C4,C5,6;該指令將協處理器P3的寄存器中的數據傳送到ARM處理器寄存器中。

        3.3.10異常產生指令

        ARM微處理器所支持的異常指令有如下兩條:

        —SWI軟件中斷指令

        —BKPT斷點中斷指令

        1、SWI指令

        SWI指令的格式為:

        SWI{條件} 24位的立即數

        SWI指令用于產生軟件中斷,以便用戶程序能調用操作系統的系統例程。操作系統在SWI的異常處理程序中提供相應的系統服務,指令中24位的立即數指定用戶程序調用系統例程的類型,相關參數通過通用寄存器傳遞,當指令中24位的立即數被忽略時,用戶程序調用系統例程的類型由通用寄存器R0的內容決定,同時,參數通過其他通用寄存器傳遞。

        指令示例:

        SWI0x02;該指令調用操作系統編號位02的系統例程。

        2、BKPT指令

        BKPT指令的格式為:

        BKPT16位的立即數

        BKPT指令產生軟件斷點中斷,可用于程序的調試。

        3.4Thumb指令及應用

        為兼容數據總線寬度為16位的應用系統,ARM體系結構除了支持執行效率很高的32位ARM指令集以外,同時支持16位的Thumb指令集。Thumb指令集是ARM指令集的一個子集,允許指令編碼為16位的長度。與等價的32位代碼相比較,Thumb指令集在保留32代碼優勢的同時,大大的節省了系統的存儲空間。

        所有的Thumb指令都有對應的ARM指令,而且Thumb的編程模型也對應于ARM的編程模型,在應用程序的編寫過程中,只要遵循一定調用的規則,Thumb子程序和ARM子程序就可以互相調用。當處理器在執行ARM程序段時,稱ARM處理器處于ARM工作狀態,當處理器在執行Thumb程序段時,稱ARM處理器處于Thumb工作狀態。

        與ARM指令集相比較,Thumb指令集中的數據處理指令的操作數仍然是32位,指令地址也為32位,但Thumb指令集為實現16位的指令長度,舍棄了ARM指令集的一些特性,如大多數的Thumb指令是無條件執行的,而幾乎所有的ARM指令都是有條件執行的;大多數的Thumb數據處理指令的目的寄存器與其中一個源寄存器相同。

        由于Thumb指令的長度為16位,即只用ARM指令一半的位數來實現同樣的功能,所以,要實現特定的程序功能,所需的Thumb指令的條數較ARM指令多。在一般的情況下,Thumb指令與ARM指令的時間效率和空間效率關系為:

        —Thumb代碼所需的存儲空間約為ARM代碼的60%~70%

        —Thumb代碼使用的指令數比ARM代碼多約30%~40%

        —若使用32位的存儲器,ARM代碼比Thumb代碼快約40%

        —若使用16位的存儲器,Thumb代碼比ARM代碼快約40%~50%

        —與ARM代碼相比較,使用Thumb代碼,存儲器的功耗會降低約30%

        顯然,ARM指令集和Thumb指令集各有其優點,若對系統的性能有較高要求,應使用32位的存儲系統和ARM指令集,若對系統的成本及功耗有較高要求,則應使用16位的存儲系統和Thumb指令集。當然,若兩者結合使用,充分發揮其各自的優點,會取得更好的效果。

        3.5本章小節

        本章系統的介紹了ARM指令集中的基本指令,以及各指令的應用場合及方法,由基本指令還可以派生出一些新的指令,但使用方法與基本指令類似。與常見的如X86體系結構的匯編指令相比較,ARM指令系統無論是從指令集本身,還是從尋址方式上,都相對復雜一些。

        Thumb指令集作為ARM指令集的一個子集,其使用方法與ARM指令集類似,在此未作詳細的描述,但這并不意味著Thumb指令集不如ARM指令集重要,事實上,他們各自有其自己的應用場合。



        評論


        技術專區

        關閉
        主站蜘蛛池模板: 仪征市| 策勒县| 万源市| 陇西县| 法库县| 海门市| 化德县| 崇文区| 会昌县| 历史| 阿拉尔市| 肥乡县| 如皋市| 鄂托克前旗| 额敏县| 张北县| 霍城县| 金沙县| 湘潭市| 汉寿县| 富裕县| 青海省| 安多县| 渝中区| 平阴县| 黑山县| 凤庆县| 大关县| 信丰县| 石林| 赤壁市| 九江市| 双流县| 香港 | 洛阳市| 揭阳市| 垣曲县| 新兴县| 桂林市| 大方县| 黄陵县|