您的位置 首页 芯闻

ARM Cortex-M3 学习笔记(4-2)

最近在学ARMCortex-M3,找了本号称很经典的书AnDefinitiveGuidetoTheARMCortex-M3在看。这个系列学习笔记其实就是在学习这本…

最近在学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),详细的用法如下:

示例

功用描绘

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

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/news/xinwen/264253.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部