在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,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) > 設(shè)計(jì)應(yīng)用 > 嵌入式Linux+ARMARM體系結(jié)構(gòu)與編程(ARM匯編指令)

            嵌入式Linux+ARMARM體系結(jié)構(gòu)與編程(ARM匯編指令)

            作者: 時(shí)間:2016-11-09 來源:網(wǎng)絡(luò) 收藏
            自己的一些簡(jiǎn)單的總結(jié),也是最常用的ARM匯編指令,之后也會(huì)不斷的補(bǔ)充完善。

            1.匯編系統(tǒng)預(yù)定義的段名

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

            .text @代碼段
            .data @初始化數(shù)據(jù)段
            .bss @未初始化數(shù)據(jù)段
            需要注意的是,源程序中.bss段應(yīng)該在.text之前。

            2.定義入口點(diǎn)
            編程序的缺省入口是 start標(biāo)號(hào),用戶也可以在連接腳本文件中用ENTRY標(biāo)志指明其它入口點(diǎn)。

            .text

            .global _start

            _start:

            3 .word用法

            word expression就是在當(dāng)前位置放一個(gè)word型的值,這個(gè)值就是expression
            舉例來說,

            _rWTCON:

            .word 0x15300000
            就是在當(dāng)前地址,即_rWTCON處放一個(gè)值0x15300000

            4.equ賦值操作,相當(dāng)于c語言的宏定義

            .equ MEM_CTRL_BASE, 0x48000000 //注意要加,號(hào)

            5. 邏輯指令

            AND―――――邏輯"與"操作指令

            指令格式:
            AND{cond}{S} Rd,Rn,operand2
            AND指令將操作數(shù)operand2 與Rn 的值按位邏輯"與",結(jié)果存放到目的寄存器Rd 中。若設(shè)置S,則根據(jù)運(yùn)算結(jié)果影響N、Z位,在計(jì)算第二操作數(shù)時(shí),更新C位,不影響V位(指令ORR、EOR、BIC 對(duì)標(biāo)志位的影響同AND 指令)。
            指令示例:
            ANDS R1,R1,R2 ;R1=R1&R2,并根據(jù)運(yùn)算的結(jié)果更新標(biāo)志位
            AND R0,R0,#0x0F ;R0=R0&0x0F,取出R0最低4位數(shù)據(jù)。
            ORR―――――邏輯"或"操作指令
            指令格式:ORR{cond}{S} Rd,Rn,operand2 ORR指令將操作數(shù)operand2 與Rn 的值按位邏輯"或",結(jié)果存放到目的寄存器Rd 中。指令示例:
            ORRS R1,R1,R2 ;R1=R1|R2,并根據(jù)運(yùn)算的結(jié)果更新標(biāo)志位
            ORR R0,R0,#0x0F ;R0=R0|0x0F,將R0最低4位置1,其余位不變。
            BIC―――――位清除指令
            指令格式:
            BIC{cond}{S} Rd,Rn,operand2
            BIC指令將Rn 的值與操作數(shù)operand2 的反碼按位邏輯"與",結(jié)果存放到目的寄存器Rd 中。
            指令示例:BIC R0,R0,#0x0F ;將R0最低4位清零,其余位不變。
            CMP―――――比較指令
            指令格式:
            CMP{cond} Rn,operand2
            CMP指令用Rn的值減去操作數(shù)operand2 ,并將結(jié)果的狀態(tài)(Rn 與operand2比較是大、小、相等)反映在CPSR中,以便后面的指令根據(jù)條件標(biāo)志決定程序的走向。CMP指令與SUBS指令完成的操作一樣,只是CMP指令只減,不存結(jié)果。
            指令示例:
            cmp R0,R1 ;比較R0,R1
            beq stop ;R0=R1跳到stop
            blt less ;R0
            Less:...
            Stop:...

            參考:

            http://blog.csdn.net/denlee/article/details/2501182

            嵌入式開發(fā)中,匯編程序常常用于非常關(guān)鍵的地方,比如系統(tǒng)啟動(dòng)時(shí)的初始化,進(jìn)出中斷時(shí)的環(huán)境保存、恢復(fù),對(duì)性能要求非常苛刻的函數(shù)等。

            1、相對(duì)跳轉(zhuǎn)指令:b、bl
            不同之處在于:bl指令除了跳轉(zhuǎn)之外,還將返回地址(bl的下一條指令的地址)保存在lr寄存器中。
            跳轉(zhuǎn)范圍:當(dāng)前指令的前后32M。
            它們是與位置無關(guān)的指令。
            示例:
            b fun1
            ......
            fun1:
            bl fun2
            ......
            fun2:
            ......


            2、數(shù)據(jù)傳送指令:mov,地址讀取偽指令:ldr
            mov指令可以把一個(gè)寄存器的值賦給另一個(gè)寄存器,或者把一個(gè)常數(shù)賦給寄存器。
            例:
            mov r1, r2
            mov r1, #4096
            mov指令傳送的常數(shù)必須能用立即數(shù)來表示。
            當(dāng)不知道一個(gè)數(shù)能否用立即數(shù)來表示時(shí),可以使用ldr命令來賦值。ldr是偽指令,它不是真實(shí)存在的指令,編譯器會(huì)把它擴(kuò)展成真正的指令:如果該常數(shù)能用立即數(shù)來表示,則使用mov指令;否則編譯時(shí)將該常數(shù)保存在某個(gè)位置,使用內(nèi)存讀取指令把它讀出來。
            例:
            ldr r1, =4097
            ldr本意為“大范圍的地址讀取偽指令”,以下是獲得代碼的絕對(duì)地址:
            例:
            ldr r1, =label
            label:
            ......


            3、內(nèi)存訪問指令:ldr、str、ldm、stm
            ldr指令既可能是大范圍的地址讀取偽指令,也可能是內(nèi)存訪問指令。當(dāng)它的第二個(gè)參數(shù)前面有“ = ”時(shí),表示偽指令,否則表示內(nèi)存訪問指令。
            ldr指令是從內(nèi)存中讀取數(shù)據(jù)到寄存器,str指令把寄存器的值存儲(chǔ)到內(nèi)存中,它們操作的數(shù)據(jù)都是32位的。
            例:
            ldr r1, [r2, #4] // 將地址為r2+4的內(nèi)存單元數(shù)據(jù)讀取到r1中
            ldr r1, [r2] // 將地址為r2的內(nèi)存單元數(shù)據(jù)讀取到r1中
            ldr r1, [r2], #4 // 將地址為r2的內(nèi)存單元數(shù)據(jù)讀取到r1中,然后r2=r2+4
            str r1, [r2, #4] // 將r1的數(shù)據(jù)保存到地址為r2+4的內(nèi)存單元中
            str r1, [r2] // 將r1的數(shù)據(jù)保存到地址為r2的內(nèi)存單元中
            str r1, [r2], #4 // 將r1的數(shù)據(jù)保存到地址為r2的內(nèi)存單元中,然后r2=r2+4
            ldm和stm屬于批量內(nèi)存訪問指令,只用一條指令就可以讀寫多個(gè)數(shù)據(jù)。格式為:
            ldm {cond} { ! } { ^ }
            stm {cond} { ! } { ^ }
            其中,{cond}表示指令的執(zhí)行條件有:

            條件碼(cond)

            助記符

            含義

            cpsr中條件標(biāo)志位

            0000

            eq

            相等

            Z = 1

            0001

            ne

            不相等

            Z = 0

            0010

            cs/hs

            無符號(hào)數(shù)大于/等于

            C = 1

            0011

            cc/lo

            無符號(hào)數(shù)小于

            C = 0

            0100

            mi

            負(fù)數(shù)

            N = 1

            0101

            pl

            非負(fù)數(shù)

            N = 0

            0110

            vs

            上溢出

            V = 1

            0111

            vc

            沒有上溢出

            V = 0

            1000

            hi

            無符號(hào)數(shù)大于

            C = 1或Z = 0

            1001

            ls

            無符號(hào)數(shù)小于等于

            C = 0或Z = 1

            1010

            ge

            帶符號(hào)數(shù)大于等于

            N = 1, V = 1或N = 0, V = 0

            1011

            lt

            帶符號(hào)數(shù)小于

            N = 1, V = 0或N = 0, V = 1

            1100

            gt

            帶符號(hào)數(shù)大于

            Z = 0且N = V

            1101

            le

            帶符號(hào)數(shù)小于/等于

            Z = 1或N! = V

            1110

            al

            無條件執(zhí)行

            -

            1111

            nv

            從不執(zhí)行

            -

            大多數(shù)ARM指令都可以條件執(zhí)行,即根據(jù)cpsr寄存器中的條件標(biāo)志位決定是否執(zhí)行該指令:如果條件不滿足,該指令相當(dāng)于一條nop指令。
            每條ARM指令包含4位的條件碼域,這表明可以定義16個(gè)執(zhí)行條件。
            cpsr條件標(biāo)志位N、Z、C、V分別表示Negative、Zero、Carry、oVerflow。

            表示地址變化模式,有4種方式:
            ia (Increment After) :事后遞增方式。
            ib (Increment Before) :事先遞增方式。
            da (Decrement After) :事后遞減方式。
            db (Decrement Before):事先遞減方式。
            中保存內(nèi)存的地址,如果后面加上感嘆號(hào),指令執(zhí)行后,rn的值會(huì)更新,等于下一個(gè)內(nèi)存單元的地址。
            表示寄存器列表,對(duì)于ldm指令,從所對(duì)應(yīng)的內(nèi)存塊中取出數(shù)據(jù),寫入這些寄存器;對(duì)于stm指令,把這些寄存器的值寫入所對(duì)應(yīng)的內(nèi)存塊中。
            {^}有兩種含義:
            如果中有pc寄存器,它表示指令執(zhí)行后,spsr寄存器的值將自動(dòng)到cpsr寄存器中——這常用于從中斷處理函數(shù)中返回;
            如果中沒有pc寄存器,{^}表示操作的是用戶模式下的寄存器,而不是當(dāng)前特權(quán)模式的寄存器。
            例:
            HandleIRQ: @中斷入口函數(shù)
            sub lr, lr, #4 @計(jì)算返回地址
            stmdb sp!, { r0 - r12, lr } @保存使用的寄存器
            @r0 - r12, lr被保存在sp表示的內(nèi)存中
            @“!”使得指令執(zhí)行后sp = sp - 14 * 4

            ldr lr, =int_return @設(shè)置調(diào)用IRQ_Handle函數(shù)后的返回地址
            ldr pc, =IRQ_Handle @調(diào)用中斷分發(fā)函數(shù)
            int_return:
            ldmia sp!, { r0 - r12, pc }^ @中斷返回,“^”表示將spsr的值到cpsr
            @于是從irq模式返回被中斷的工作模式
            @“!”使得指令執(zhí)行后sp = sp + 14 * 4


            4、加減指令:add、sub
            例:
            add r1, r2, #1 // r1 = r2 + 1
            sub r1, r2, #1 // r1 = r2 - 1


            5、程序狀態(tài)寄存器的訪問指令:msr、mrs
            ARM處理器有一個(gè)程序狀態(tài)寄存器(cpsr),它用來控制處理器的工作模式、設(shè)置中斷的總開關(guān)。
            例:
            msr cpsr, r0 // r0到cpsr中
            mrs r0, cpsr // cpsr到r0中

            6、其他偽指令
            .extern : 定義一個(gè)外部符號(hào)(可以是變量也可以是函數(shù))
            .text : 表示現(xiàn)在的語句都屬于代碼段
            .global : 將本文件中的某個(gè)程序標(biāo)號(hào)定義為全局的


            ARM-THUMB子程序調(diào)用規(guī)則:ATPCS
            為了使C語言程序和匯編程序之間能夠互相調(diào)用,必須為子程序間的調(diào)用制定規(guī)則,在ARM處理器中,這個(gè)規(guī)則被稱為ATPCS:ARM程序和THUMB程序中子程序調(diào)用的規(guī)則?;镜腁TPCS規(guī)則包括寄存器使用規(guī)則、數(shù)據(jù)棧使用規(guī)則、參數(shù)傳遞規(guī)則。

            1、寄存器使用規(guī)則
            子程序間通過寄存器r0 ~ r3來傳遞參數(shù),這時(shí)可以使用它們的別名a1 ~ a4。被調(diào)用的子程序返回前無需恢復(fù)r0 ~ r3的內(nèi)容。
            在子程序中,使用r4 ~ r11來保存局部變量,這時(shí)可以使用它們的別名v1 ~ v8。如果在子程序中使用了它們的某些寄存器,子程序進(jìn)入時(shí)要保存這些寄存器的值,在返回前恢復(fù)它們;對(duì)于子程序中沒有使用到的寄存器,則不必進(jìn)行這些操作。在THUMB程序中,通常只能使用寄存器r4 ~ r7來保存局部變量。
            寄存器r12用作子程序間scratch寄存器,別名為ip。
            寄存器r13用作數(shù)據(jù)棧指針,別名為sp。在子程序中寄存器r13不能用作其他用途。它的值在進(jìn)入、退出子程序時(shí)必須相等。
            寄存器r14稱為連接寄存器,別名為lr。它用于保存子程序的返回地址。如果在子程序中保存了返回地址(比如將lr值保存到數(shù)據(jù)棧中),r14可以用作其他用途。
            寄存器r15是程序計(jì)數(shù)器,別名為pc。它不能用作其他用途。

            寄存器

            別名

            使用規(guī)則

            r15

            pc

            程序計(jì)數(shù)器

            r14

            lr

            連接寄存器

            r13

            sp

            數(shù)據(jù)棧指針

            r12

            ip

            子 程序內(nèi)部調(diào)用的scratch寄存器

            r11

            v8

            ARM狀態(tài)局部變量寄存器8

            r10

            v7、s1

            ARM狀態(tài)局部變量寄存器7、在支持?jǐn)?shù)據(jù)棧檢查的ATPCS中為數(shù)據(jù)棧限制指針

            r9

            v6、sb

            ARM狀態(tài)局部變量寄存器6、在支持RWPI的ATPCS中為靜態(tài)基址寄存器

            r8

            v5

            ARM狀態(tài)局部變量寄存器5

            r7

            v4、wr

            ARM狀態(tài)局部變量寄存器4、THUMB狀態(tài)工作寄存器

            r6

            v3

            ARM狀態(tài)局部變量寄存器3

            r5

            v2

            ARM狀態(tài)局部變量寄存器2

            r4

            v1

            ARM狀態(tài)局部變量寄存器1

            r3

            a4

            參數(shù)/結(jié)果/scratch寄存器4

            r2

            a3

            參數(shù)/結(jié)果/scratch寄存器3

            r1

            a2

            參數(shù)/結(jié)果/scratch寄存器2

            r0

            a1

            參數(shù)/結(jié)果/scratch寄存器1


            2、數(shù)據(jù)棧使用規(guī)則
            數(shù)據(jù)棧有兩個(gè)增長方向:向內(nèi)存地址減小的方向增長時(shí),稱為DESCENDING棧;向內(nèi)存地址增加的方向增長時(shí),稱為ASCENDING棧。
            所謂數(shù)據(jù)棧的增長就是移動(dòng)棧指針。當(dāng)棧指針指向棧頂元素(最后一個(gè)入棧的數(shù)據(jù))時(shí),稱為FULL棧;當(dāng)棧指針指向棧頂元素(最后一個(gè)入棧的數(shù)據(jù))相鄰的一個(gè)空的數(shù)據(jù)單元時(shí),稱為EMPTY棧。
            則數(shù)據(jù)??梢苑譃?種:
            FD:Full Descending 滿遞減
            ED:Empty Descending 空遞減
            FA :Full Ascending 滿遞增
            EA:Empty Ascending 空遞增
            ATPCS規(guī)定數(shù)據(jù)棧為FD類型,并且對(duì)數(shù)據(jù)棧的操作是8字節(jié)對(duì)齊的。使用stmdb / ldmia批量內(nèi)存訪問指令來操作FD數(shù)據(jù)棧。
            使用stmdb命令往數(shù)據(jù)棧中保存內(nèi)容時(shí),先遞減sp指針,再保存數(shù)據(jù),使用ldmia命令從數(shù)據(jù)棧中恢復(fù)數(shù)據(jù)時(shí),先獲得數(shù)據(jù),再遞增sp指針,sp指針總是指向棧頂元素,這剛好是FD棧的定義。

            3、參數(shù)傳遞規(guī)則
            一般地,當(dāng)參數(shù)個(gè)數(shù)不超過4個(gè)時(shí),使用r0 ~ r3這4個(gè)寄存器來傳遞參數(shù);如果參數(shù)個(gè)數(shù)超過4個(gè),剩余的參數(shù)通過數(shù)據(jù)棧來傳遞。
            對(duì)于一般的返回結(jié)果,通常使用r0 ~ r3來傳遞。
            例:
            假設(shè)CopyCode2SDRAM函數(shù)是用C語言實(shí)現(xiàn)的,它的數(shù)據(jù)原型如下:
            int CopyCode2SDRAM( unsigned char *buf, unsigned long start_addr, int size )
            在匯編代碼中,使用下面的代碼調(diào)用它,并判斷返回值:
            ldr r0, =0x30000000 @1. 目標(biāo)地址 = 0x30000000,這是SDRAM的起始地址
            mov r1, #0 @2. 源地址 = 0
            mov r2, #16*1024 @3. 長度 = 16K
            bl CopyCode2SDRAM @調(diào)用C函數(shù)CopyCode2SDRAM
            cmp a0, #0 @判斷函數(shù)返回值



            評(píng)論


            技術(shù)專區(qū)

            關(guān)閉