新聞中心

EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > ARM Cortex-M3 學(xué)習(xí)筆記(4-2)

ARM Cortex-M3 學(xué)習(xí)筆記(4-2)

作者: 時(shí)間:2016-11-20 來源:網(wǎng)絡(luò) 收藏
最近在學(xué)ARM Cortex-M3,找了本號(hào)稱很經(jīng)典的書“An Definitive Guide to The ARM Cortex-M3”在看。這個(gè)系列學(xué)習(xí)筆記其實(shí)就是在學(xué)習(xí)這本書的過程中做的讀書筆記。

第四章 指令系統(tǒng)
數(shù)據(jù)傳送類指令
寄存器到寄存器傳送:MOV 指令、MVN指令
MOV R8, R3; R8 = R3
MVN R8, R3; R8 = -R3
學(xué)過微機(jī)原理的都應(yīng)記得,x86中一條MOV 指令存儲(chǔ)器和寄存器間的任意傳送。ARM 中是不行的,這也是CISC和RISC 內(nèi)核的一個(gè)比較明顯的區(qū)別。

存儲(chǔ)器到寄存器傳送:LDRx 指令、LDMxy指令
寄存器到存儲(chǔ)器:STRx 指令、STMxy指令

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

本文引用地址:http://m.butianyuan.cn/article/201611/318847.htm

示例

功能描述

LDRB Rd, [Rn, #offset]

從地址Rn+offset處讀取一個(gè)字節(jié)送到Rd

LDRH Rd, [Rn, #offset]

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

LDR Rd, [Rn, #offset]

從地址Rn+offset處讀取一個(gè)字送到Rd

LDRD Rd1, Rd2, [Rn, #offset]

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

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

示例

功能描述

STRB Rd, [Rn, #offset]

把Rd中的低字節(jié)存儲(chǔ)到地址Rn+offset處

STRH Rd, [Rn, #offset]

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

STR Rd, [Rn, #offset]

把Rd中的低字存儲(chǔ)到地址Rn+offset處

STRD Rd1, Rd2, [Rn, #offset]

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

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

LDR.W R0,[R1, #20]! ;預(yù)索引

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

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

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

LDMxy指令和STMxy指令可以一次傳送更多的數(shù)據(jù)。

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

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

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

示例

功能描述

LDMIA Rd!, {寄存器列表}

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

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

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

STMIA Rd!, {寄存器列表}

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

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

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

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

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

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

存儲(chǔ)多個(gè)字到Rd處。每存一個(gè)字前Rd自減一次

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

假設(shè) R8=0x8000,則

STMIA.W R8!, {R0-R3} ; R8值變?yōu)?x8010

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

上面兩行代碼都是將R0-R3共16個(gè)字節(jié)的數(shù)據(jù)存儲(chǔ)到從0x8000開始的16個(gè)字節(jié)空間中,唯一的區(qū)別是第一條指令執(zhí)行完后R8被更新為0x8010,而第二條指令不更新R8。

立即數(shù)的加載

MOV支持8位立即數(shù)加載,比如:

MOV R0, #0x12

32位指令MOVW(加載到寄存器的低16位)和MOVT(加載到寄存器的高16位)可以支持16位立即數(shù)加載。如果要加載32位的立即數(shù),必須先使用MOVW,再使用MOVT,因?yàn)镸OVW會(huì)清零高16位。

LDR 和ADR的區(qū)別

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

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

ADR R1, address1 ; R1= 0x4000。注意:沒有“=”號(hào)

address1

0x4000: MOV R0, R1

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

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

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

下面是兩個(gè)例子:

MRS R0, PRIMASK ; 讀取PRIMASK到R0中

MSR BASEPRI, R0 ;寫入R0到BASEPRI中

但是需要注意大多數(shù)的特殊功能寄存器都只能在特權(quán)級(jí)下訪問,非特權(quán)級(jí)下只能訪問APSR


評(píng)論


相關(guān)推薦

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

關(guān)閉