新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > ARM Cortex-M3 學習筆記(4-2)

        ARM Cortex-M3 學習筆記(4-2)

        作者: 時間:2016-11-20 來源:網絡 收藏
        最近在學ARM Cortex-M3,找了本號稱很經典的書“An Definitive Guide to The ARM Cortex-M3”在看。這個系列學習筆記其實就是在學習這本書的過程中做的讀書筆記。

        第四章 指令系統
        數據傳送類指令
        寄存器到寄存器傳送:MOV 指令、MVN指令
        MOV R8, R3; R8 = R3
        MVN R8, R3; R8 = -R3
        學過微機原理的都應記得,x86中一條MOV 指令存儲器和寄存器間的任意傳送。ARM 中是不行的,這也是CISC和RISC 內核的一個比較明顯的區別。

        存儲器到寄存器傳送:LDRx 指令、LDMxy指令
        寄存器到存儲器:STRx 指令、STMxy指令

        LDRx 指令的x可以是B(byte)、H(half word)、D(Double word)或者省略(word),具體的用法如下:

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

        示例

        功能描述

        LDRB Rd, [Rn, #offset]

        從地址Rn+offset處讀取一個字節送到Rd

        LDRH Rd, [Rn, #offset]

        從地址Rn+offset處讀取一個半字送到Rd

        LDR Rd, [Rn, #offset]

        從地址Rn+offset處讀取一個字送到Rd

        LDRD Rd1, Rd2, [Rn, #offset]

        從地址Rn+offset處讀取一個雙字(64位整數)送到Rd1(低32位)和Rd2(高32位)中。

        STRx 指令的x同樣可以是B(byte)、H(half word)、D(Double word)或者省略(word),具體的用法如下:

        示例

        功能描述

        STRB Rd, [Rn, #offset]

        把Rd中的低字節存儲到地址Rn+offset處

        STRH Rd, [Rn, #offset]

        把Rd中的低半字存儲到地址Rn+offset處

        STR Rd, [Rn, #offset]

        把Rd中的低字存儲到地址Rn+offset處

        STRD Rd1, Rd2, [Rn, #offset]

        把Rd1(低32位)和Rd2(高32位)表達的雙字存儲到地址Rn+offset處

        LDRx和STRx指令還有一種帶預索引的格式,下面舉個例子(注意語句中的“!”):

        LDR.W R0,[R1, #20]! ;預索引

        上面語句的意思是先把地址R1+offset處的值加載到R0,然后,R1 ßR1+ 20

        還有一種后索引形式,注意與上面的預索引的區別(還要注意語句中沒有“!”):

        STR.W R0, [R1], #-12 ;把R0的值存儲到地址R1處。完畢后, R1ßR1+(-12)

        LDMxy指令和STMxy指令可以一次傳送更多的數據。

        X可以為要I或D,I表示自增(Increment),D表示自減(Decrement)。

        Y可以為A或B,表示自增或自減的時機是在每次訪問前(Before)還是訪問后(After)。

        另外,指令帶有“.W”后綴表示這條指令是32位的Thumb-2指令,否則是16位的指令。

        示例

        功能描述

        LDMIA Rd!, {寄存器列表}

        從Rd處讀取多個字,并依次送到寄存器列表中的寄存器。每讀一個字后Rd自增一次,16位指令

        LDMIA.W Rd!, {寄存器列表}

        從Rd處讀取多個字,并依次送到寄存器列表中的寄存器。每讀一個字后Rd自增一次

        STMIA Rd!, {寄存器列表}

        依次存儲寄存器列表中各寄存器的值到Rd給出的地址。每存一個字后Rd自增一次,16位指令

        STMIA.W Rd!, {寄存器列表}

        依次存儲寄存器列表中各寄存器的值到Rd給出的地址。每存一個字后Rd自增一次

        LDMDB.W Rd!, {寄存器列表}

        從Rd處讀取多個字,并依次送到寄存器列表中的寄存器。每讀一個字前Rd自減一次

        STMDB.W Rd!, {寄存器列表}

        存儲多個字到Rd處。每存一個字前Rd自減一次

        這里需要特別注意!的含義,它表示要自增(Increment)或自減(Decrement)基址寄存器Rd的值,時機是在每次訪問前(Before)或訪問后(After)。比如:

        假設 R8=0x8000,則

        STMIA.W R8!, {R0-R3} ; R8值變為0x8010

        STMIA.W R8, {R0-R3} ; R8值不變

        上面兩行代碼都是將R0-R3共16個字節的數據存儲到從0x8000開始的16個字節空間中,唯一的區別是第一條指令執行完后R8被更新為0x8010,而第二條指令不更新R8。

        立即數的加載

        MOV支持8位立即數加載,比如:

        MOV R0, #0x12

        32位指令MOVW(加載到寄存器的低16位)和MOVT(加載到寄存器的高16位)可以支持16位立即數加載。如果要加載32位的立即數,必須先使用MOVW,再使用MOVT,因為MOVW會清零高16位。

        LDR 和ADR的區別

        LDR和ADR都是偽指令,都可以用來加載一個立即數(也可以是一個地址),如果加載的是程序地址,LDR會自動地把LSB置位,ADR則不會:

        LDR R0, =address1 ; R0= 0x4000 | 1

        ADR R1, address1 ; R1= 0x4000。注意:沒有“=”號

        address1

        0x4000: MOV R0, R1

        特殊功能寄存器只能用MSR/MRS指令訪問:

        MRS , ;讀特殊功能寄存器的值到通用寄存器

        MSR , ;寫通用寄存器的值到特殊功能寄存器

        下面是兩個例子:

        MRS R0, PRIMASK ; 讀取PRIMASK到R0中

        MSR BASEPRI, R0 ;寫入R0到BASEPRI中

        但是需要注意大多數的特殊功能寄存器都只能在特權級下訪問,非特權級下只能訪問APSR


        關鍵詞: ARMCortex-M3學習筆

        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 浦城县| 巴林左旗| 古田县| 阿合奇县| 西峡县| 肥西县| 崇文区| 英德市| 香港| 南充市| 济阳县| 佛坪县| 衢州市| 江川县| 阿克陶县| 高淳县| 临沂市| 荣昌县| 巴马| 临潭县| 永年县| 大城县| 明溪县| 新建县| 岢岚县| 沁源县| 会宁县| 兴义市| 海阳市| 顺昌县| 定州市| 恩平市| 慈溪市| 淳化县| 铜梁县| 昭苏县| 涪陵区| 兰州市| 曲周县| 蚌埠市| 桂阳县|