微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > arm汇编指令整理

arm汇编指令整理

时间:11-09 来源:互联网 点击:

ed_24操作数的内容就保存到了R0:

BIC R0,R0,#0xFF000000

该指令将R0的高8位清零,并把结果保存到R0,意思就是取R0的低24位。

可能还是有人会问:为什么在SWI异常处理子程序中执行这两条指令后,immed_24操作数的内容就保存到了R0寄存器呢?之所以会有这样的疑问,基本都是因为对LR寄存器的作用没了解清楚。下面介绍一下链接寄存器LR(R14)的作用。

寄存器R14(LR寄存器)有两种特殊功能:

·在任何一种处理器模式下,该模式对应的R14寄存器用来保存子程序的返回地址。当执行BL或BLX指令进行子程序调用时,子程序的返回地址被放置在R14中。这样,只要把R14内容拷贝到PC中,就实现了子程序的返回(具体的子程序返回操作,这里不作详细介绍)。

·当某异常发生时,相应异常模式下的R14被设置成异常返回的地址(对于某些异常,可能是一个偏移量,一个较小的常量)。异常返回类似于子程序返回,但有小小的不同(这里不作详细介绍)。

所谓的子程序的返回地址,实际就是调用指令的下一条指令的地址,也就是BL或BLX指令的下一条指令的地址。所谓的异常的返回的地址,就是异常发生前,CPU执行的最后一条指令的下一条指令的地址。

例如:(子程序返回地址示例)

指令 指令所在地址

ADD R2,R1,R3 ;0x300000

BL subC ;0x300004

MOV R1,#2 ;0x300008

BL指令执行后,R14中保存的子程序subC的返回地址是0x300008。

再例如:(异常返回地址示例)

指令 指令所在地址

ADD R2,R1,R3 ;0x300000

SWI 0x98 ;0x300004

MOV R1,#2 ;0x300008

SWI指令执行后,进入SWI异常处理程序,此时R14中保存的返回地址为0x300008。

所以,在SWI异常处理子程序中执行LDR R0,[LR,#-4]语句,实际就是把产生本次SWI异常的SWI指令的内容(如:SWI 0x98)装进R0寄存器。又因为SWI指令的低24位保存了指令的操作数(如:0x98),所以再执行BIC R0,R0,#0xFF000000语句,就可以获得immed_24操作数的实际内容。

二、方法2:使用参数寄存器。

实际上,在SWI异常处理子程序的实现时,还可以绕开immed_24操作数的获取操作,这就是说,我们可以不去获取immed_24操作数的实际内容,也能实现SWI异常的分支处理。这就需要使用R0-R4寄存器,其中R0-R4可任意选择其中一个,一般选择R0,遵从ATPCS原则。

具体方法就是,在执行SWI指令之前,给R0赋予某个数值,然后在SWI异常处理子程序中根据R0值实现不同的分支处理。例如:

指令 指令所在地址

MOV R0,#1 ; #1给R0

SWI 0x98 ; 产生SWI中断,执行异常处理程序SoftwareInterrupt

ADD R2,R1,R3 ;

;SWI异常处理子程序如下

SoftwareInterrupt

CMP R0, #6 ; if R0 < 6

LDRLO PC, [PC, R0, LSL #2] ; if R0 < 6,PC = PC + R0*4,else next //PC-8处的指令

MOVS PC, LR //PC-4处的指令

SwiFunction

DCD function0 ;0//PC处的指令

DCD function1 ;1

DCD function2 ;2

DCD function3 ;3

DCD function4 ;4

DCD function5 ;5

Function0

异常处理分支0代码

Function1

异常处理分支1代码

function2

异常处理分支2代码

function3

异常处理分支3代码

function4

异常处理分支4代码

function5

异常处理分支5代码

在ARM体系结构中,当正确读取了PC的值时,该值为当前指令地址值加8字节,也就是说,对于ARM指令集来说,读出的PC值指向当前指令的下两条指令的地址,本例中就是指向SwiFunction 表头DCD function0这个地址,在该地址中保存了异常处理子分支function0的入口地址。所以,当进入SWI异常处理子程序SoftwareInterrupt时,如果R0=0,执行LDRLO PC, [PC, R0, LSL #2]语句后,PC的内容即为function0的入口地址,即程序跳转到了function0执行。在本例中,因为R0=1,所以,实际程序是跳转到了function1执行。R0左移2位(LDRLO PC, [PC,R0, LSL #2]),即R0*4,是因为ARM指令是字(4个字节)对齐的DCD function0等伪指令也是按4字节对齐的。

在本方法的实现中,实际指令中的24位立即数(immed_24域)被忽略了, 就是说immed_24域可以为任意合法的值。如在本例中,不一定使用SWI 0x98,还可以为SWI 0x00或者SWI 0x01等等,程序还是会进入SWI异常处理子程序SoftwareInterrupt,然后根据R0的内容跳转到相应的子分支。

ARM处理器使用流水线来增加处理器指令流的速度,这样可使几个操作同时进行,并使处理与存储器系统之间的操作更加流畅,连续,能提供0.9MIPS/MHZ的指令执行速度。 PC代表程序计数器,流水线使用三个阶段,因此指令分为三个阶段执行:

1.取指(从存储器装载一条指令);

2.译码(识别将要被执行的指令);

3.执行(处理指令

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top