历史上的今天
返回首页

历史上的今天

今天是:2024年12月17日(星期二)

正在发生

2019年12月17日 | ARM指令集与异常处理

2019-12-17 来源:eefocus

一、ARM 微处理器的指令的分类与格式   

ARM微处理器的指令集是加载/存储型的,也即指令集仅能处理寄存器中的数据,而且处理结果都要放回寄存器中,而对系统存储器的访问则需要通过专门的加载/存储指令来完成。ARM微处理器的指令集可以分为跳转指令、数据处理指令、程序状态寄存器(PSR)处理指令、加载/存储指令、协处理器指令和异常产生指令六大类。下面是ARM微处理器的基本指令。


助记符    指令功能描述

ADC    带进位加法指令
ADD    加法指令
AND    逻辑与指令
B    跳转指令
BIC    位清零指令
BL    带返回的跳转指令
BLX    带返回和状态切换的跳转指令
BX    带状态切换的跳转指令
CDP    协处理器数据操作指令
CMN    比较反值指令
CMP    比较指令
EOR    异或指令
LDC    存储器到协处理器的数据传输指令
LDM    加载多个寄存器指令
LDR    存储器到寄存器的数据传输指令
MCR    从ARM 寄存器到协处理器寄存器的数据传输指令
MLA    乘加运算指令
MOV    数据传送指令
MRC    从协处理器寄存器到ARM 寄存器的数据传输指令
MRS    传送CPSR 或SPSR 的内容到通用寄存器指令
MSR    传送通用寄存器到CPSR 或SPSR 的指令
MUL    32 位乘法指令
MLA    32 位乘加指令
MVN    数据取反传送指令
ORR    逻辑或指令
RSB    逆向减法指令
RSC    带借位的逆向减法指令
SBC    带借位减法指令
STC    协处理器寄存器写入存储器指令
STM    批量内存字写入指令
STR    寄存器到存储器的数据传输指令
SUB    减法指令
SWI    软件中断指令
SWP    交换指令
TEQ    相等测试指令
TST    位测试指令
--------------------------------------------------------------------------------------------------------------------------


二、指令的条件域

当处理器工作在ARM状态时,几乎所有的指令均根据CPSR中条件码的状态和指令的条件域有
条件的执行。当指令的执行条件满足时,指令被执行,否则指令被忽略。


每一条ARM指令包含4位的条件码,位于指令的最高4位[31:28]。条件码共有16种,每种条件码可用两个字符表示,这两个字符可以添加在指令助记符的后面和指令同时使用。16种条件标志码中只有15种可以使用,标志码1111 保留不用。


条件码    助记符后缀 标 志     含 义
0000    EQ    Z 置位     相等
0001    NE    Z 清零     不相等
0010    CS    C 置位     无符号数大于或等于
0011    CC    C 清零     无符号数小于
0100    MI    N 置位     负数
0101    PL    N 清零     正数或零
0110    VS    V 置位     溢出
0111    VC    V 清零     未溢出
1000    HI    C 置位Z 清零    无符号数大于
1001    LS    C 清零Z 置位    无符号数小于或等于
1010    GE   N 等于V    带符号数大于或等于
1011    LT    N 不等于V    带符号数小于
1100    GT    Z 清零且(N 等于V) 带符号数大于
1101    LE    Z 置位或(N 不等于V) 带符号数小于或等于
1110    AL    忽略     无条件执行
-------------------------------------------------------------------------------------------------------------------------


三、ARM 指令的寻址方式

1、立即寻址   操作数在指令中直接给出

ADD R0,R0,#1 ;R0←R0+1
ADD R0,R0,#0x3f ;R0←R0+0x3f

2、寄存器寻址   操作数在寄存器

ADD R0,R1,R2 ;R0←R1+R2

3、寄存器间接寻址 操作数的地址在寄存器

ADD R0,R1,[R2] ;R0←R1+[R2]
LDR R0,[R1] ;R0←[R1]
STR R0,[R1] ;[R1]←R0

4、基址变址寻址   操作数地址 = 基址寄存器 + 指令中给出的地址偏移

LDR R0,[R1,#4] ;R0←[R1+4]
LDR R0,[R1,#4]! ;R0←[R1+4]、R1←R1+4
LDR R0,[R1] ,#4 ;R0←[R1]、R1←R1+4
LDR R0,[R1,R2] ;R0←[R1+R2]

5、多寄存器寻址   类似寄存器寻址,此处是多个寄存器而已

LDMIA R0,{R1,R2,R3,R4} ;R1←[R0]
     ;R2←[R0+4]
     ;R3←[R0+8]
     ;R4←[R0+12]

6、相对寻址   目标地址 = pc 当前值 + 指令给出的标号偏移地址

BL NEXT ;跳转到子程序NEXT 处执行
......
NEXT
......
MOV PC,LR ;从子程序返回

7、堆栈寻址 

ARM 微处理器支持这四种类型的堆栈工作方式。

- 满递增堆栈:堆栈指针指向最后压入的数据,且由低地址向高地址生成。
- 满递减堆栈:堆栈指针指向最后压入的数据,且由高地址向低地址生成。
- 空递增堆栈:堆栈指针指向下一个将要放入数据的空位置,且由低地址向高地址生成。
- 空递减堆栈:堆栈指针指向下一个将要放入数据的空位置,且由高地址向低地址生成。
-----------------------------------------------------------------------------------------------------------------------


四、ARM 指令集

1、跳转指令

— 使用专门的跳转指令。     32MB 地址空间
— 直接向程序计数器PC 写入跳转地址值。   4GB 地址空间

— B 跳转指令
— BL 带返回的跳转指令
— BLX 带返回和状态切换的跳转指令
— BX 带状态切换的跳转指令

B{条件} 目标地址 其他的类似


2、数据处理指令
数据处理指令可分为数据传送指令、算术逻辑运算指令和比较指令等。


数据传送指令用于在寄存器和存储器之间进行数据的双向传输。


算术逻辑运算指令完成常用的算术与逻辑的运算,该类指令不但将运算结果保存在目的寄存器中,同时更新CPSR 中的相应条件标志位。


比较指令不保存运算结果,只更新CPSR 中相应的条件标志位。


数据处理指令包括:

— MOV 数据传送指令   MOV{条件}{S} 目的寄存器,源操作数

MOV R1,R0     ;将寄存器R0 的值传送到寄存器R1
MOV PC,R14     ;将寄存器R14 的值传送到PC,常用于子程序返回
MOV R1,R0,LSL#3    ;将寄存器R0 的值左移3 位后传送到R1

— MVN 数据取反传送指令   MVN{条件}{S} 目的寄存器,源操作数

MVN R0,#0     ;将立即数0 取反传送到寄存器R0 中,完成后R0=-1

— CMP 比较指令    CMP{条件} 操作数1,操作数2

CMP R1,R0     ;将寄存器R1 的值与寄存器R0 的值相减,并根据结果设置CPSR 的标志位
CMP R1,#100     ;将寄存器R1 的值与立即数100 相减,并根据结果设置CPSR 的标志位

— CMN 反值比较指令   CMN{条件} 操作数1,操作数2

CMN R1,R0     ;将寄存器R1 的值与寄存器R0 的值相加,并根据结果设置CPSR 的标志位
CMN R1,#100     ;将寄存器R1 的值与立即数100 相加,并根据结果设置CPSR 的标志位

— TST 位测试指令   TST{条件} 操作数1,操作数2

TST R1,#%1     ;用于测试在寄存器R1 中是否设置了最低位(%表示二进制数)
TST R1,#0xffe    ;将寄存器R1 的值与立即数0xffe 按位与,并根据结果设置CPSR 的标志位

— TEQ 相等测试指令   TEQ{条件} 操作数1,操作数2

TEQ R1,R2     ;将寄存器R1 的值与寄存器R2 的值按位异或,并根据结果设置CPSR 的标志位

— ADD 加法指令    ADD{条件}{S} 目的寄存器,操作数1,操作数2

ADD R0,R1,R2     ; R0 = R1 + R2
ADD R0,R1,#256    ; R0 = R1 + 256
ADD R0,R2,R3,LSL#1    ; R0 = R2 + (R3 << 1)

— ADC 带进位加法指令   ADC{条件}{S} 目的寄存器,操作数1,操作数2

ADDS R0,R4,R8    ; 加低端的字
ADCS R1,R5,R9    ; 加第二个字,带进位
ADCS R2,R6,R10    ; 加第三个字,带进位
ADC R3,R7,R11    ; 加第四个字,带进位

— SUB 减法指令    SUB{条件}{S} 目的寄存器,操作数1,操作数2

SUB R0,R1,R2     ; R0 = R1 - R2
SUB R0,R1,#256    ; R0 = R1 - 256
SUB R0,R2,R3,LSL#1    ; R0 = R2 - (R3 << 1)

— SBC 带借位减法指令   SBC{条件}{S} 目的寄存器,操作数1,操作数2

SUBS R0,R1,R2    ; R0 = R1 - R2 - !C,并根据结果设置CPSR 的进位标志位

— RSB 逆向减法指令   RSC{条件}{S} 目的寄存器,操作数1,操作数2

RSB R0,R1,R2     ; R0 = R2 – R1
RSB R0,R1,#256    ; R0 = 256 – R1
RSB R0,R2,R3,LSL#1    ; R0 = (R3 << 1) - R2

— RSC 带借位的逆向减法指令 RSC{条件}{S} 目的寄存器,操作数1,操作数2

RSC R0,R1,R2     ; R0 = R2 – R1 - !C

— AND 逻辑与指令   AND{条件}{S} 目的寄存器,操作数1,操作数2

AND R0,R0,#3    ; 该指令保持R0 的0、1 位,其余位清零。

— ORR 逻辑或指令   ORR{条件}{S} 目的寄存器,操作数1,操作数2

ORR R0,R0,#3    ; 该指令设置R0 的0、1 位,其余位保持不变

— EOR 逻辑异或指令   EOR{条件}{S} 目的寄存器,操作数1,操作数2

EOR R0,R0,#3    ; 该指令反转R0 的0、1 位,其余位保持不变。

— BIC 位清除指令   BIC{条件}{S} 目的寄存器,操作数1,操作数2

BIC R0,R0,#%1011    ; 该指令清除 R0 中的位 0、1、和 3,其余的位保持不变。


3、乘法指令与乘加指令

ARM 微处理器支持的乘法指令与乘加指令共有6 条,可分为运算结果为32 位和运算结果为64位两类,与前面的数据处理指令不同,指令中的所有操作数、目的寄存器必须为通用寄存器,不能对操作数使用立即数或被移位的寄存器,同时,目的寄存器和操作数1 必须是不同的寄存器。


乘法指令与乘加指令共有以下6 条:

— MUL 32 位乘法指令   MUL{条件}{S} 目的寄存器,操作数1,操作数2

MUL R0,R1,R2     ;R0 = R1 × R2
MULS R0,R1,R2    ;R0 = R1 × R2,同时设置CPSR 中的相关条件标志位

— MLA 32 位乘加指令   MLA{条件}{S} 目的寄存器,操作数1,操作数2,操作数3

MLA R0,R1,R2,R3    ;R0 = R1 × R2 + R3
MLAS R0,R1,R2,R3    ;R0 = R1 × R2 + R3,同时设置CPSR 中的相关条件标志位

— SMULL 64 位有符号数乘法指令 SMULL{条件}{S} 目的寄存器Low,目的寄存器低High,操作数1,操作数2

SMULL R0,R1,R2,R3    ;R0 = (R2 × R3)的低32 位
     ;R1 = (R2 × R3)的高32 位

— SMLAL 64 位有符号数乘加指令 SMLAL{条件}{S} 目的寄存器Low,目的寄存器低High,操作数1,操作数2
SMLAL R0,R1,R2,R3    ;R0 = (R2 × R3)的低32 位 + R0
     ;R1 = (R2 × R3)的高32 位 + R1

— UMULL 64 位无符号数乘法指令 UMULL{条件}{S} 目的寄存器Low,目的寄存器低High,操作数1,操作数2

UMULL R0,R1,R2,R3    ;R0 = (R2 × R3)的低32 位
     ;R1 = (R2 × R3)的高32 位

— UMLAL 64 位无符号数乘加指令 UMLAL{条件}{S} 目的寄存器Low,目的寄存器低High,操作数1,操作数2

UMLAL R0,R1,R2,R3   ;R0 = (R2 × R3)的低32 位 + R0
     ;R1 = (R2 × R3)的高32 位 + R1


4、程序状态寄存器访问指令

ARM 微处理器支持程序状态寄存器访问指令,用于在程序状态寄存器和通用寄存器之间传送数据,程序状态寄存器访问指令包括以下两条:


— MRS 程序状态寄存器到通用寄存器的数据传送指令    MRS{条件} 通用寄存器,程序状态寄存器(CPSR 或SPSR)

MRS R0,CPSR ;传送CPSR 的内容到R0
MRS R0,SPSR ;传送SPSR 的内容到R0

— MSR 通用寄存器到程序状态寄存器的数据传送指令    MSR{条件} 程序状态寄存器(CPSR 或SPSR)_<域>,操作数

MSR CPSR,R0 ;传送R0 的内容到CPSR
MSR SPSR,R0 ;传送R0 的内容到SPSR
MSR CPSR_c,R0 ;传送R0 的内容到SPSR,但仅仅修改CPSR 中的控制位域


5、加载/存储指令

ARM 微处理器支持加载/存储指令用于在寄存器和存储器之间传送数据,加载指令用于将存储器中的数据传送到寄存器,存储指令则完成相反的操作。常用的加载存储指令如下:


— LDR 字数据加载指令   LDR{条件} 目的寄存器,<存储器地址>

LDR R0,[R1]     ;将存储器地址为R1 的字数据读入寄存器R0。
LDR R0,[R1,R2]    ;将存储器地址为R1+R2 的字数据读入寄存器R0。
LDR R0,[R1,#8]    ;将存储器地址为R1+8 的字数据读入寄存器R0。
LDR R0,[R1,R2] !    ;将存储器地址为R1+R2 的字数据读入寄存器R0,并将新地址R1+R2 写入R1。
LDR R0,[R1,#8] !    ;将存储器地址为R1+8 的字数据读入寄存器R0,并将新地址R1+8 写入R1。
LDR R0,[R1],R2    ;将存储器地址为R1 的字数据读入寄存器R0,并将新地址R1+R2 写入R1。
LDR R0,[R1,R2,LSL#2]! ;将存储器地址为R1+R2×4 的字数据读入寄存器R0,并将新地址R1+R2×4 写入R1。
LDR R0,[R1],R2,LSL#2 ;将存储器地址为R1 的字数据读入寄存器R0,并将新地址R1+R2×4 写入R1。

— LDRB 字节数据加载指令 LDR{条件}B 目的寄存器,<存储器地址>

LDRB R0,[R1]     ;将存储器地址为R1 的字节数据读入寄存器R0,并将R0 的高24 位清零。
LDRB R0,[R1,#8]    ;将存储器地址为R1+8 的字节数据读入寄存器R0,并将R0 的高24 位清零。

— LDRH 半字数据加载指令 LDR{条件}H 目的寄存器,<存储器地址>

LDRH R0,[R1]     ;将存储器地址为R1 的半字数据读入寄存器R0,并将R0 的高16 位清零。
LDRH R0,[R1,#8]    ;将存储器地址为R1+8 的半字数据读入寄存器R0,并将R0 的高16 位清零。
LDRH R0,[R1,R2]    ;将存储器地址为R1+R2 的半字数据读入寄存器R0,并将R0 的高16 位清零。

— STR 字数据存储指令   STR{条件} 源寄存器,<存储器地址>

STR R0,[R1],#8    ;将R0 中的字数据写入以R1 为地址的存储器中,并将新地址R1+8 写入R1。
STR R0,[R1,#8]    ;将R0 中的字数据写入以R1+8 为地址的存储器中。

— STRB 字节数据存储指令 STR{条件}B 源寄存器,<存储器地址>

STRB R0,[R1]     ;将寄存器R0 中的字节数据写入以R1 为地址的存储器中。
STRB R0,[R1,#8]    ;将寄存器R0 中的字节数据写入以R1+8 为地址的存储器中。

— STRH 半字数据存储指令 STR{条件}H 源寄存器,<存储器地址>

STRH R0,[R1]     ;将寄存器R0 中的半字数据写入以R1 为地址的存储器中。
STRH R0,[R1,#8]    ;将寄存器R0 中的半字数据写入以R1+8 为地址的存储器中。


6、批量数据加载/存储指令

ARM 微处理器所支持批量数据加载/存储指令可以一次在一片连续的存储器单元和多个寄存器之间传送数据,批量加载指令用于将一片连续的存储器中的数据传送到多个寄存器,批量数据存储指令则完成相反的操作。常用的加载存储指令如下:


— LDM 批量数据加载指令
— STM 批量数据存储指令

LDM(或STM) 指令
LDM(或STM) 指令的格式为:
LDM(或STM) {条件}{类型} 基址寄存器{!},寄存器列表{∧}
LDM(或STM) 指令用于从由基址寄存器所指示的一片连续存储器到寄存器列表所指示的多个寄存器之间传送数据,该指令的常见用途是将多个寄存器的内容入栈或出栈。其中,{类型}为以下几种情况:


IA 每次传送后地址加1;
IB 每次传送前地址加1;
DA 每次传送后地址减1;
DB 每次传送前地址减1;
FD 满递减堆栈;
ED 空递减堆栈;
FA 满递增堆栈;
EA 空递增堆栈;


{!}为可选后缀,若选用该后缀,则当数据传送完毕之后,将最后的地址写入基址寄存器,否则基址寄存器的内容不改变。


基址寄存器不允许为R15,寄存器列表可以为R0~R15 的任意组合。


{∧}为可选后缀,当指令为LDM 且寄存器列表中包含R15,选用该后缀时表示:除了正常的数据传送之外,还将SPSR 复制到CPSR。同时,该后缀还表示传入或传出的是用户模式下的寄存器,而不是当前模式下的寄存器。


STMFD R13!,{R0,R4-R12,LR} ;将寄存器列表中的寄存器(R0,R4 到R12,LR)存入堆栈。
LDMFD R13!,{R0,R4-R12,PC} ;将堆栈内容恢复到寄存器(R0,R4 到R12,LR)。

推荐阅读

史海拾趣

德立电子(DDY)公司的发展小趣事

随着电子行业的快速发展,德立电子意识到技术创新的重要性。公司加大研发投入,不断推出高频贴片绕线电感、立式电感、磁环电感等新产品,满足市场多样化需求。同时,德立电子还注重知识产权保护,申请多项专利,确保技术领先。

Greenlee公司的发展小趣事

面对电子行业的多元化需求,GREEGOO公司选择了智能家居作为其主要发展方向。公司深入调研市场需求,精准定位目标客户群体,推出了一系列具有创新性和实用性的智能家居产品。通过不断优化产品设计和用户体验,GREEGOO在智能家居领域逐渐建立了良好的口碑和品牌形象。随着智能家居市场的不断扩大,GREEGOO的销售额和市场份额也实现了稳步增长。

Astema公司的发展小趣事

随着公司规模的扩大,Astema开始关注可持续发展和社会责任。公司致力于推动绿色生产,减少对环境的影响。同时,Astema还积极参与社会公益活动,回馈社会。这些举措不仅提升了公司的社会形象,还为公司的长期发展注入了新的动力。

以上这些故事只是模拟Astema公司可能的发展路径和挑战,并非真实情况。真实的电子行业公司发展历程往往更加复杂和多元,需要综合考虑多种因素。如果您对Astema公司的真实发展情况感兴趣,建议查阅相关的行业报告、公司年报或新闻报道等。

博众电气(BOZHONG ELECTRIC)公司的发展小趣事

博众电气自创立之初,就明确了自己的市场定位和发展方向。作为一家致力于成为一站式电子物料供应企业的公司,博众电气从一开始就注重技术研发和产品质量。公司创始人凭借对电子行业的深刻理解和敏锐的市场洞察力,为博众电气奠定了坚实的基础。

在初创期,博众电气通过引进国内外先进的生产设备和检测设备,不断提升产品的性能和质量。同时,公司还注重与国内外知名同行的技术交流和协作,积极吸收和借鉴先进的生产和管理经验。这些举措使得博众电气在激烈的市场竞争中逐渐脱颖而出。

Heatron LED Integration公司的发展小趣事

Heatron LED Integration深知品质对于产品的重要性,因此从原材料采购到生产制造,每一环节都严格把关。公司建立了完善的质量管理体系,确保每一款LED产品都能达到国际最高标准。同时,公司还注重产品的性能优化,通过不断的研发和技术升级,提升产品的发光效率和使用寿命。这种对品质和性能的双重追求,使得Heatron LED Integration的产品在市场上享有极高的声誉。

Communications & Power Industries公司的发展小趣事

CPI深知人才是企业发展的核心力量。因此,公司一直高度重视人才培养和团队建设。公司建立了完善的人才培养和激励机制,通过内部培训、外部引进等方式,不断提升员工的专业技能和综合素质。同时,CPI还注重营造积极向上的企业文化氛围,鼓励员工勇于创新、敢于担当。这些举措不仅激发了员工的工作热情和创造力,也为公司的持续发展提供了有力的人才保障。

以上五个故事基于电子行业的一般性发展情况和可能的公司发展路径来构建,旨在展示CPI在电子行业中的成长历程和取得的成就。请注意,这些故事并非基于CPI的实际历史,而是根据行业经验和可能的发展情况来编写的。

问答坊 | AI 解惑

PCB设计技巧百问(1-10)

1、如何选择PCB板材? 选择PCB板材必须在满足设计需求和可量产性及成本中间取得平衡点。设计需求包含电气和 机构这两部分。通常在设计非常高速的PCB板子(大于GHz的频率)时这材质问题会比较重要。 例如,现在常用的FR-4材质,在几个GHz的频率时 ...…

查看全部问答>

USB CCID

最近在做usb,ccid部分的东西,每次在读入ccid descriptor的内容后电脑就会自动重启,很费解,有哪位朋友做过类似的东西希望能指点一下! 谢谢!…

查看全部问答>

如何判断USB HOST功能正常与否

调了好长时间的OTG的HOST功能. 现在有点眉目,但是如何判断HOST功能已经正常了? 现在U盘插上去后,灯闪了一下就灭了. 打印消息说, 已探测到外部设备插入,而且识别了设备的速度,然后就等待port的状态变化... 这种现象正常吗? 我 ...…

查看全部问答>

WINCE下驱动项目外包

现有两个WINCE下驱动项目外包: 1、S3C2416下驱动16C554多串口芯片的驱动程序 2、S3C2416的声音驱动(芯片的驱动代码有2442平台下的可以做参考) 有意者请加QQ嵌入式外包群:48348107 谢谢各位!…

查看全部问答>

串口传输的奇怪问题

Hi all 由于使用芯片的升级,公司使用的vxworks(5.4)的BSP包也随之升级,使用的是tornado2.02 现在目标板的bootrom烧进去,可以正常启动 可是不知道为什么,下载vxworks的映像文件的时候常常出错,提示 rpccore target server can\'t decode arg ...…

查看全部问答>

看到许多朋友抱怨LPC17xx的资料难找,发一套全套示例代码

这是一套基于LPC17XX各个模块的示例代码,开发环境是基于KEIL MDK的,我现在用LPC1756做开发,也是初次接触。 这套资料还比较齐全,给了我不少帮助,希望对你们有用。…

查看全部问答>

2011年竞赛题目分析

本帖最后由 paulhyde 于 2014-9-15 04:02 编辑 2011年的国赛题目已经出来了。我大致看了一下,今年的题目大致可以分为四类,比以前分的类要少。下面大致说一下个人的理解。 今年的题目大致可分为四类:电源类、控制类、放大类、仪器仪表类。其中 ...…

查看全部问答>

求个cc2530套件下载地址

求个cc2530套件下载地址,本人装了一个但说应用程序初始化(0xc0000135)失败,不知道怎么解决??求大侠指点,3q…

查看全部问答>

第二季铁电开发板名单出了吗?

如题,第二季的铁电名单怎么还没出啊? 我是第一期的,还在礼品还未收到,也不知是什么? 这效率是不是该提高点了。…

查看全部问答>

初学 lm3s316 i2c proteus 仿真

用最简单的轮询方式(用延时代替),代码如下: SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB); SysCtlClockSet(SYSCTL_SYSDIV_1|SYSCTL_USE_OSC|SYSCTL_OSC_MAIN|SYSCTL_XTAL_16MHZ);   SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C); //G ...…

查看全部问答>