新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 淺析arm匯編中^、、cxsf符號和movs等指令使用學習

        淺析arm匯編中^、、cxsf符號和movs等指令使用學習

        作者: 時間:2016-11-20 來源:網絡 收藏
        ldrr1,[sp,#S_PSR]

        ldrlr,[sp,#S_PC]!@!用來控制基址變址尋址的最終新地址是否進行回寫操作,
        @ 執行ldr之后sp被回寫成sp+#S_PC基址變址尋址的新地址
        msrspsr,r1@ 把cpsr的值保存到spsr中
        ldmdbsp,{r0-lr}^@ lr=[sp-1*4],r13=[sp-2*4],r12=[sp-3*4],......,r0=[sp-15*4]
        @ 因為沒對pc賦值,所以^的表示將數據恢復到User模式的[r0-lr]寄存器組中[gliethttp]
        movr0,r0
        addsp,sp,#S_FRAME_SIZE-S_PC
        movspc,lr
        .endm

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


        其他指令正在學習中[隨時補充gliethttp]
        -----------------------------
        1.ldrip,[sp],#4 將sp中內容存入ip,之后sp=sp+4;
        ldrip,[sp,#4]將sp+4這個新地址下內容存入ip,之后sp值保持不變
        ldrip,[sp,#4]!將sp+4這個新地址下內容存入ip,之后sp=sp+4將新地址值賦給sp
        strip,[sp],#4 將ip存入sp地址處,之后sp=sp+4;
        strip,[sp,#4]將ip存入sp+4這個新地址,之后sp值保持不變
        strip,[sp,#4]!將ip存入sp+4這個新地址,之后sp=sp+4將新地址值賦給sp
        -----------------------------
        2.movsr1,#3;movs將導致ALU被更改,因為r1賦值非0,即操作結果r0非0,所以ALU的Z標志清0
        bne 1f;因為Z=0,說明不等,所以向前跳到標號1:所在處繼續執行其他語句
        -----------------------------
        3.LDM表示裝載,STM表示存儲.
        LDMED LDMIB 預先增加裝載
        LDMFD LDMIA 過后增加裝載
        LDMEA LDMDB 預先減少裝載
        LDMFA LDMDA 過后減少裝載
        STMFA STMIB 預先增加存儲
        STMEA STMIA 過后增加存儲
        STMFD STMDB 預先減少存儲
        STMED STMDA 過后減少存儲
        注意ED不同于IB;只對于預先減少裝是相同的.在存儲的時候,ED是過后減少的.
        FD、ED、FA、和 EA 指定是滿棧還是空棧,是升序棧還是降序棧.
        對于存儲STM而言
        先加后存 FA 姑且這么來記,先加(firstadd),存數據
        后加先存 EA 姑且這么來記,存數據,后加endadd
        先減后存 FD 姑且這么來記,先減firstdec,存數據
        后減先存 ED 姑且這么來記,存數據,后減enddec
        然后記憶LDM,LDM是STM的反相彈出動作,所以
        因為是先加后存,所以后減先取 FA 就成了與STM對應的取數據,后減
        因為是后加先存,所以先減后取 EA 就成了與STM對應的先減,取數據
        因為是先減后存,所以后加先取 FD 就成了與STM對應的取數據,后加
        因為是后減先存,所以先加后取 ED 就成了與STM對應的先加,取數據
        我想通過上面的變態方式可以比較容易的記住這套指令[gliethttp]
        一個滿棧的棧指針指向上次寫的最后一個數據單元,而空棧的棧指針指向第一個空閑單元.
        一個降序棧是在內存中反向增長(就是說,從應用程序空間結束處開始反向增長)而升序棧在內存中正向增長.
        其他形式簡單的描述指令的行為,意思分別是
        IA過后增加(Increment After)、
        IB預先增加(Increment Before)、
        DA過后減少(Decrement After)、
        DB預先減少(Decrement Before).
        RISC OS使用傳統的滿降序棧.在使用符合APCS規定的編譯器的時候,它通常把你的棧指針設置在應用程序空間的
        結束處并接著使用一個FD(滿降序-Full Descending)棧.如果你與一個高級語言(BASIC或C)一起工作,你將別無選擇.
        棧指針(傳統上是R13)指向一個滿降序棧.你必須繼續這個格式,或則建立并管理你自己的棧.
        -----------------------------
        4.
        teq r1,#0//r1-0,將結果送入狀態標志,如果r1和0相減的結果為0,那么ALU的Z置位,否則Z清0
        bne reschedule//ne表示Z非0,即:不等,那么執行reschedule函數
        -----------------------------
        5.使用tst來檢查是否設置了特定的位
        tst r1,#0x80 //按位and操作,檢測r1的0x1<<7,即第7位是否置1,按位與之后結果為0,那么ALU的Z置位
        beq reset //如果Z置位,即:以上按位與操作結果是0,那么跳轉到reset標號執行
        -----------------------------
        6.^的理解
        ^是一個后綴標志,不能在User模式和Sys系統模式下使用該標志.該標志有兩個存在目的:
        6.1.對于LDM操作,同時恢復的寄存器中含有pc(r15)寄存器,那么指令執行的同時cpu自動將spsr拷貝到cpsr中
        如:在IRQ中斷返回代碼中[如下為ads環境下的代碼gliethttp]
        ldmfd {r4} //讀取sp中保存的的spsr值到r4中
        msr spsr_cxsf,r4 //對spsr的所有控制為進行寫操作,將r4的值全部注入spsr
        ldmfd {r0-r12,lr,pc}^//當指令執行完畢,pc跳轉之前,將spsr的值自動拷貝到cpsr中[gliethttp]
        6.2.數據的送入、送出發生在User用戶模式下的寄存器,而非當前模式寄存器
        如:ldmdb sp,{r0-lr}^;表示sp棧中的數據回復到User分組寄存器r0-lr中,而不是恢復到當前模式寄存器r0-lr

        當然對于User,System,IRQ,SVC,Abort,Undefined這6種模式來說[gliethttp]r0-r12是共用的,只是r13和r14
        為分別獨有,對于FIQ模式,僅僅r0-r7是和前6中模式的r0-r7共用,r8-r14都是FIQ模式下專有.

        -----------------------------
        7.spsr_cxsf,cpsr_cxsf的理解
        c - control fieldmaskbyte(PSR[7:0])
        x - extension fieldmaskbyte(PSR[15:8])
        s - status fieldmaskbyte(PSR[23:16)
        f - flags fieldmaskbyte(PSR[31:24]).
        老式聲明方式:cpsr_flg,cpsr_all在ADS中已經不在支持
        cpsr_flg對應cpsr_f
        cpsr_all對應cpsr_cxsf
        需要使用專用指令對cpsr和spsr操作:mrs,msr
        mrs tmp,cpsr //讀取CPSR的值
        bic tmp,tmp,#0x80 //如果第7位為1,將其清0
        msr cpsr_c,tmp //對控制位區psr[7:0]進行寫操作
        -----------------------------
        8.cpsr的理解
        CPSR=Current Program Status Register
        SPSR=Saved Program Status Registers
        CPSR寄存器(和保存它的SPSR寄存器)


        (上圖)
        N,Z,C,V稱為ALU狀態標志
        N:如果結果是負數則置位
        Z:如果結果是零則置位
        C:如果發生進位則置位
        V:如果發生溢出則置位
        I:置位表示禁用IRQ中斷,清0表示使能IRQ
        F:置位表示禁用FIQ中斷,清0表示使能FIQ
        T:置位表示系統運行在Thumb態,清0表示運行在ARM態
        M[4:0]:
        10000 User模式,和System系統模式一樣
        10001 FIQ模式
        10010 IRQ模式
        10011 SVC超級管理模式
        10111 Abort數據異常模式
        11011 Undefined未定義指令模式
        11111 System系統模式,和User模式一樣
        舉例:
        ands r2,r2,#7 使用運算結果改變標志位,如果運算結果r2=0,那么Z置位,EQ相等判斷成立
        subs r2,r2,#1 使用運算結果改變標志位,如果運算結果r2=0,那么Z置位,EQ相等判斷成立
        beq wordcopy
        -----------------------------
        9.指令后綴和條件判斷


        (上圖)
        EQ:等于
        NE:不等
        CS:無符號>=
        CC:無符號<
        MI:負數
        PL:非負[>=0]
        VS:溢出
        VC:無溢出
        HI:無符號>
        LS:無符號<=
        GE:有符號>=
        LT:有符號<
        GT:有符號>
        LE:有符號<=
        AL:總是[默認]

        淺析linux中r0~r15寄存器對應的別名

        r0
        r1
        r2
        r3
        r4
        r5
        r6
        r7
        r8
        r9
        r10->s1
        r11->fp
        r12->ip
        r13->sp
        r14->lr
        r15->pc

        對于arm匯編指令,可以參考linux內核的arch/arm目錄,那里的匯編指令很豐富[gliethttp_20080603]

        __CopyFromStart
        ; ldr r3, [r9], #4
        ; str r3, [r7], #4
        ; sub r8, r8, #4
        ldrb r3, [r9], #1
        strb r3, [r7], #1
        sub r8, r8, #1
        cmp r8, #0
        bgt __CopyFromStart
        b __JumpToBootImage
        __JumpToBootImage
        MOV pc, r0




        評論


        技術專區

        關閉
        主站蜘蛛池模板: 炉霍县| 门源| 松桃| 祁阳县| 锦屏县| 青阳县| 延庆县| 淮南市| 云龙县| 衡水市| 平阳县| 长沙市| 黔江区| 文山县| 武宣县| 六枝特区| 琼结县| 沾益县| 汨罗市| 惠来县| 华阴市| 海丰县| 桐柏县| 林周县| 铜鼓县| 门源| 彭阳县| 利津县| 顺义区| 大新县| 满城县| 凭祥市| 乌什县| 奉化市| 武鸣县| 锦屏县| 镇沅| 晋中市| 东辽县| 乳山市| 三台县|