在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            新聞中心

            EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > ARM體系結構學習4

            ARM體系結構學習4

            作者: 時間:2016-11-21 來源:網(wǎng)絡 收藏

            ARM指令教程

            本文引用地址:http://www.biyoush.com/article/201611/319365.htm

            ARM匯編程序特點:

            l所有運算處理都是發(fā)生通用寄存器(一般是R0~R14)的之中.所有存儲器空間(如C語言變量的本質(zhì)就是一個存儲器空間上的幾個BYTE).的值的處理,都是要傳送到通用寄存器來完成.因此代碼中大量看到LDR,STR指令來傳送值.

            lARM匯編語句中.當前語句很多時候要隱含的使用上一句的執(zhí)行結果.而且上一句的執(zhí)行結果,是放在CPSR寄存器里,(比如說進位,為0,為負…)

            CMP R0,R1

            BNE NoMatch

            比如上一句,BNE隱含的使用的上一句CMP執(zhí)行結果.NE后綴表示使用Z標志位.兩句合起來的意思就是,如果R0,R1的值不相等,就跳轉(zhuǎn)到NoMatch處執(zhí)行.

            注意,PC=R15,CPSR=R16,

            ARM偽指令不是必須的,但是一個完整沒有偽指令幾乎很難寫出來.

            n比如一個程序至少包含READONLY AREA和ENTRY,否則CPU都無法知道從哪里開始運行

            lARM的屬于RISC,指令并不多,但是可以帶后綴表示擴展出不同用法,這里與X86匯編完全不同風格

            n如BNE實際上是B指令的變種,本質(zhì)還同一類指令.只是多一個對CPSR的Z標志位的判斷。

            ARM常用指令,偽指令

            ARM常用指令并不太多,因此使用閱讀ARM匯編代碼,并不太困難.以下是使用頻率最高的指令和偽指令,并不是完整的指令集的教材。詳細指令參見參考資料。

            lB,BL

            lMOV,MVN

            lLDR,STR

            lADD,SUB,ADC,SBC,MUL

            lAND,ORR,XOR,TST,BIC

            lCMP

            lLDM/STM

            lnop

            1.跳轉(zhuǎn)語句B,BL

            程序流程的跳轉(zhuǎn),在ARM程序中有兩種方法可以實現(xiàn)程序流程的跳轉(zhuǎn)指令用于實現(xiàn)

            l使用專門的跳轉(zhuǎn)指令B

            l直接向程序計數(shù)器PC寫入跳轉(zhuǎn)地址值

            n這是幾乎是任何一種CPU必備的機器,PC表示CPU當前執(zhí)行語句位置,改變PC的值,相當于實現(xiàn)程序跳轉(zhuǎn)

            n如實現(xiàn)類似C語言的Return語句,就是用MOV PC,LR

            n這里可以在任意4G的空間進行跳轉(zhuǎn)

            B指令(Branch)表示無條件跳轉(zhuǎn).

            B main;跳轉(zhuǎn)到標號為main地代碼處

            BL指令(Branch with Link)表示帶返回值的跳轉(zhuǎn).

            BL比B多做一步,在跳轉(zhuǎn)前,BL會把當前位置保存在R14(即LR寄存器),當跳轉(zhuǎn)代碼結束后,用MOV PC,LR指令跳回來,這實際上就是C語言執(zhí)行函數(shù)的用法,

            匯編里調(diào)子程序都用BL,執(zhí)行完子函數(shù)后,可以用MOV PC,LR跳回來.

            BL delay;執(zhí)行子函數(shù)或代碼段delay ,delay可以為C函數(shù).

            與MOV PC,XXX能在4G空間跳轉(zhuǎn)不同,B語句只能32M空間跳轉(zhuǎn),(因為偏移量是一個有符號26bit的數(shù)值=32M)

            2.傳輸數(shù)據(jù)指令MOV,MVN

            nMOV(MOVE)指令可完成從另一個寄存器、被移位的寄存器或?qū)⒁粋€立即數(shù)加載到目的寄存器

            MOV R0,R1;把R1的值傳到R0

            MOV R3,#3;把常數(shù)3傳給R3,MOV中用#表示常數(shù),這個值不能超過

            nMVN( MOVE Negative)取反后再傳值,比MOV多了一步取反

            MVN R0, #0;把0取反(即-1)傳給R0

            MVN R1,R2;把R2的值取反傳給R1

            3.加載/存儲指令,LDR,STR

            nLDR,STR是用于寄存器和外部存儲器交換數(shù)據(jù)指令,注意與MOV的區(qū)別,后面只在寄存器或常數(shù)交換.

            uLDR/STR可以采用多種尋址方式,以下只舉出使用頻率最高幾種用法

            nLDR(load)用于把一個32Bit的WORD數(shù)據(jù)從外部存儲空間裝入到寄存器中

            LDR R0,[R1]; R1的值當成地址,再從這個地址裝入數(shù)據(jù)到R0 (R0=*R1)

            LDR R1,=0x30008000;把地址0x30008000的值裝入到R1中,LDR中用常數(shù)要用=打頭.(注意跟MOV的區(qū)別,MOV是#)

            ldrr0, =(0<<13)|(0<<12)|(0<<10)|(0<<9)|(0<<8)|(1<<6)|(1<<5)|(1<<4)|(1<<1)|(1<<0)

            用位與的方法賦值

            nSTR(Store)用于把一個寄存器的值存入外部存儲空間,是LDR的逆操作.

            STR R0,[R1];把R0的值,存入到R1對應地址空間上(*R1 = R0)

            STR R0,=0x30008000;把R0中值存入到地址0x30008000

            S2C2440的中CPU內(nèi)核以外的模塊的控制寄存器空間也是屬于外部空間,所以也得用如下指令LDR R0,=GPFDAT

            4.算術運算指令,ADD/ADC,SUB/SBC ,MUL

            nADD加法指令

            ADD R0,R1,R2; R0=R1+R2

            ADD R0,R1,#3;R0=R1+3

            nADC帶進位加法指令,即除了加兩個數(shù)以外,還要把CPSR的C值也要帶進來

            u通常用于大數(shù)(超過32Bit整數(shù))相加,這時單用ADD不能處理,必須折成兩步,其中一步用ADC.

            u以下是做64Bit的加法

            ADDS R0,R1,R2; R0=R1+R2,ADDS中S表示把進位結果寫入CPSR

            ADC R5,R3,R4;R5=R3+R4+C

            nSUB減法指令

            SUB R0,R1,R2; R0=R1-R2

            SUB R0,R1,#3;R0=R1-3

            nSBC帶進位減法指令,即除了加兩個數(shù)以外,還要把CPSR的C值也要帶進來,類似ADC

            u以下是做64Bit的減法

            SUBS R0,R1,R2; R0=R1-R2,SUBS中S表示把進位結果寫入CPSR

            SBC R5,R3,R4;R5=R3-R4-C

            nMUL乘法指令

            MUL R0,R1,R2; R0=R1*R2

            MUL R0,R1,#3;R0=R1*3

            5.位操作指令AND,ORR, TST,BIC

            nAND位與指令

            AND R0,R1,R2; R0=R1 & R2

            AND R0,R1,#0xFF;R0=R1 & 0xFF

            nORR位或指令

            ORR R0,R1,R2; R0=R1 | R2

            ORR R0,R1,#0xFF;R0=R1 | 0xFF

            nTST測試某一位是否為1,并把結果寫入CPSR,供下一句使用

            TST R1,#0xffe;等同于if(R1 & 0xffe)

            TST R1,#%1;測試最低位是否為1,%表示二進制

            nBIC清位操作

            BICR0,R0,#0xF等同于R0&=~(0xF)

            BICR0,R0,#%1011該指令清除R0中的位0 13,其余的位保持;%表示是二進制,0x表示十六進制

            6.比較指令CMP

            nCMP比較兩個操作數(shù),并把結果存入CPSR供下一句語句使用

            CMP R0,R1;比較R0,R1

            7.多寄存器語句傳輸指令,LDM,STM

            類似于一次傳一個BUFFER到寄存器當中,或反過來.后面一般要接一個地址改變方法

            nLDM從BUFFER傳數(shù)據(jù)多個寄存器傳輸數(shù)據(jù)到

            LDMIA R0! ,{R3-R9};加R0指向的地址上連續(xù)空間的數(shù)據(jù),保存到R3-R9當中,!表示R0值更新,IA后綴表示按WORD遞增

            LDMFD SP!,{R0-R7,PC}^;恢復現(xiàn)場,異常處理返回,^表示不允許在用戶模式下使用。

            nSTM從寄存器列表向存儲空間傳值。

            STMIA R1!,{R3-R9};將R3-R9的數(shù)據(jù)存儲到R1指向的地址上,R1值更新。

            STMFD SP!,{R0-R7,LR};現(xiàn)場保存,將R0~R7,LR入棧

            stmfdsp!,{r8-r9},把SP寄存器對慶的地址的值存到R8,R9當中.!表示最后的值寫入SP中。Fd表示

            8.ARM指令的變形

            大部分指令后位可以接與S兩個特殊位來表示,對CPSR特殊的一些判斷

            S,表示當前指令執(zhí)行后把結果改寫CPSR

            subs,Adds

            取決于具體條件,只有CPSR滿足指定條件時才指這一指令

            BEQ實際上B+ EQ的條件執(zhí)行.

            addne表示ADD +NE才開始加.

            9.ARM指令的尋址方式

            尋址方式是根據(jù)指令中給出的地址碼來定位真實的地址,ARM中有9種尋址方法

            l寄存器尋址

            直接用寄存器編號來尋址,最為常用

            MOV R1,R2;R2->R1

            l立即數(shù)尋址

            即指令中的地址碼是操作數(shù)本身,可以立即取出使用,立即數(shù)前帶一個#表示,否則表示一個地址

            SUBS R0,R0,#1;R0 -1 ->R0

            注意與SUBS R0,R0,1區(qū)別

            l寄存器偏移尋址

            這是ARM特有的尋址模式,當?shù)?操作數(shù)是寄存器,在執(zhí)行操作之前,可以做一次移位操作

            MOV R0,R2,LSL #3;R2的邏輯左移3位,結果放入R0,即R0=R2*8

            ANDS R1,R1,R2,LSL R3;RS的值左移R3位,然后和R1相與操作,結果放入R1

            移位操作有LSL (邏輯左移),LSR(邏輯右移) ,ASR(算術右移),ROR(循環(huán)右移)RRX帶擴展的循環(huán)右移

            l寄存器間接尋址

            即寄存器中值是一個地址,用[]來取出定位到地址當中

            LDR R2,[R0];把R0的值當成地址,取出相應值,賦給R2

            l基址尋址

            把寄存器的地址值加上一個偏移量

            LDR R2,[R3,#0x0F]; R3中的值加上0x0F,從這個地址取出值賦給R@

            l相對尋址

            基址尋址的變形,由PC寄存器提供基準地址,指令中地址段作為偏移量.兩者相加即是有效地址,以下是BL采用相對尋址

            BL NEXT

            NEXT

            MOV PC,LR;從子程序返回

            10.ADS ARM的偽指令

            類似于C語言的宏,由匯編程序預處理.

            l符號定義指令

            全局變量定義GBLA ,GBLL,GBLS

            局域變量定義LCLA,LCLL,LCLS

            變量賦值SETA,SETL,SETS

            其中上述偽指令中,最后面的A表示給一個算術變量賦值,L表示用于給一個邏輯變量賦值,s表示給一個字符串賦值

            GBLL codedbg;聲明一個全局的邏輯變量

            Codebg SETL{TRUE};設置變量為{TRUE}

            LCLA bitno;聲明一個算術變量

            Bitno SETA 8;設變量值為8

            l數(shù)據(jù)定義偽指令

            nSPACE定義一個內(nèi)存空間,并用0初始化

            {label }SPACE expr

            DataBuf SPACE 100;定義100字節(jié)長空間, unsigned char DataBuf[100];

            nDCB定義一個連續(xù)字節(jié)內(nèi)存空間,用偽指令的表達式expr來初始化.一般可以用定義數(shù)據(jù)表格,或文字字符串.(這時等同于SETS),用于初始二進制BUFFER

            {label} DCB expr{,expr …}

            Dest DCB -120,20,36,55;等同于unsigned char Dest[]={-120,20,36,55};

            nDCU定義的一段字的內(nèi)存空間(DCB是字節(jié)),并用后面表達式初始化

            _RESET DCU Reset;等同于DWORD _RESET[]={Reset};

            nMAP定一個結構化內(nèi)存,相當于定義一個C結構

            nFILED定義一個結構化內(nèi)存的成員

            MAP 0x00,R9;定義內(nèi)存表,地址為R9

            TimerFIELD 4;定義數(shù)據(jù)域Timer,長為4字

            AttribFIELD 4;定義數(shù)據(jù)域Attrib,長為4字

            StringFILED 100;定義數(shù)據(jù)域String ,長為100字

            相當于C語言的定義:

            struct {

            DWORD Timer ;

            DWORD Attrib ;

            Char String[100];

            } R9;

            11.雜項的偽指令

            n字節(jié)對齊ALIGN

            ALIGN;聲明4字節(jié)對齊

            n定義一個數(shù)字常量定義EQU

            NAME EQU expr {type}

            PLLCON EQU 0xE01FC080;定義PLLCON,類似于C的宏或C++的常量

            n包含文件GET和INCLUDE

            INCLUDE lpc2106.inc

            nNOP空指令

            在匯編時會被ARM的空操作代替,比如MOV R0,R0,一般用于延時與占位。

            n聲明一個外部符符號IMPORT,EXTERN

            IMPORT,EXTERN向外部導入一個符號,一般是外部程序全局變量

            n條件編譯:[]。類似于C的#ifdef之類定義。

            格式:[條件表達式

            滿足條件分支

            |

            不滿足條件分支

            ]

            示例1:

            [ ENTRY_BUS_WIDTH=32;類似#if ENTRY_BUS_WIDTH=32

            bChangeBigEndian;DCD 0xea000007

            ] ;類似#endif

            示例2:[ CLKDIV_VAL>1;類似#if CLKDIV_VAL>1

            blMMU_SetAsyncBusMode

            |;類似#else

            bl MMU_SetFastBusMode; default value.

            ];類似#endif

            示例3[ THUMBCODE類似#ifdefTHUMBCODE

            bx lr

            | ;類似#else

            movpc,lr

            ];類似#endif

            n段定義AREA

            n指令集定義CODE16和CODE32

            指示是Thumb指令集(壓縮指令集,每個指令16位)。還是普通32位指令集

            n匯編結束:END

            n程序入口ENTRY

            一個基本ARM程序結構

            ARM匯編程序結構

            源代碼由文本文件組成.按照匯編的編譯器不同,分為兩大量,一類是ADS的匯編程序,一類是GNU匯編格式,兩者在指令集是完成一樣,但是在偽指令.程序結構等方法各不同相同.本節(jié)主要是講解ADS匯編格式.

            ADS匯編程序,主要包含如下幾類程序

            n匯編源程序,后綴名是.S

            n匯編包含文件,后綴名是.inc

            n如果是與C混和編程..C,.h也能識別

            ARM匯編語句格式

            [標號]<指令|條件|S> <操作數(shù)> [;注釋]

            l所有標號頂格寫,而指令和偽指令不能頂格寫

            l標識符(標號,指令)大小寫敏感,所以要在標號和指令時書寫一致,一般偽指令,指令,寄存器名可以全部為大寫

            l注釋以;開頭,可以頂格寫

            l可以使用來分行寫太長語句

            l變量,常量的定義必須在一行頂格寫

            常量的書寫

            l數(shù)字常量

            在程序中直接寫數(shù)字,十進制12,256,十六進制0x1228,

            l字符常量

            類似于C的定義,用SETS來定義字符常量

            HELLO SETS “hello,the world!”

            l邏輯常量

            邏輯真為{TRUE},邏輯假為{FLASE}

            Testno SETS {TURE}

            匯編程序的段定義

            任何一個程序都要分段,C語言一般由編譯器自動分段,(分成.Text,.Data段之類),但在匯編程序這樣的底層程序中,由開發(fā)者自行分段.它包含如下段

            l至少一個代碼段,并且代碼段是只讀的,對應(.Text)

            l數(shù)據(jù)段可以沒有,也可以有多個.

            l每一個段用END結束

            AREA定義一個段

            AREA段名屬性1,屬性2,

            例子:AREAInit,CODE,READONLY

            lENTRY指明一個段的入口

            lEND結束一個段

            ABC EQU 0x12

            AREA Example,CODE,READONLY

            ENTRY

            START MOV R7,#10

            MOV R6,#5

            ADD R6,R6,R7

            B

            END

            ADS ARM匯編程序格式要求

            1.所有標號要頂格寫.

            2.所有指令不能頂格寫,一般插入Tab鍵在行首

            3.ADS ARM中,是大小寫敏感的.建議標號,指令,偽指令,寄存器名全部為大寫

            4.注釋采用;打頭

            5.每個程序至少有一個AREA在代碼里(READONLY)

            6.每個段都要用END結束(不能頂格)

            最常見幾個偽指令AREA,EQU,DCB,END ,ENTRY,EXPORT,GOBEL,IMPORT,

            常見偽定義

            lDCB定義字符中

            Str DCB “hello, world “




            關鍵詞: ARM體系結

            評論


            技術專區(qū)

            關閉