您的位置 首页 元件

ARM体系结构学习4

ARM指令教程ARM汇编程序特点:l所有运算处理都是发生通用寄存器(一般是R0~R14)的之中所有存储器空间(如C语言变量的本质就是一个存储器空间

ARM指令教程

ARM汇编程序特色:

l一切运算处理都是产生通用寄存器(一般是R0~R14)的之中.一切存储器空间(如C言语变量的实质便是一个存储器空间上的几个BYTE).的值的处理,都是要传送到通用寄存器来完结.因而代码中许多看到LDR,STR指令来传送值.

lARM汇编句子中.当时句子许多时分要隐含的运用上一句的履行成果.而且上一句的履行成果,是放在CPSR寄存器里,(比方说进位,为0,为负…)

CMP R0,R1

BNE NoMatch

比方上一句,BNE隐含的运用的上一句CMP履行成果.NE后缀表明运用Z标志位.两句合起来的意思便是,假如R0,R1的值不相等,就跳转到NoMatch处履行.

留意,PC=R15,CPSR=R16,

ARM伪指令不是有必要的,可是一个完好没有伪指令简直很难写出来.

n比方一个程序至少包括READONLY AREA和ENTRY,不然CPU都无法知道从哪里开端运转

lARM的归于RISC,指令并不多,可是能够带后缀表明扩展出不同用法,这儿与X86汇编彻底不同风格

n如BNE实际上是B指令的变种,实质还同一类指令.仅仅多一个对CPSR的Z标志位的判别。

ARM常用指令,伪指令

ARM常用指令并不太多,因而运用阅览ARM汇编代码,并不太困难.以下是运用频率最高的指令和伪指令,并不是完好的指令集的教材。具体指令拜见参考资料。

lB,BL

lMOV,MVN

lLDR,STR

lADD,SUB,ADC,SBC,MUL

lAND,ORR,XOR,TST,BIC

lCMP

lLDM/STM

lnop

1.跳转句子B,BL

程序流程的跳转,在ARM程序中有两种办法能够完结程序流程的跳转指令用于完结

l运用专门的跳转指令B

l直接向程序计数器PC写入跳转地址值

n这是简直是任何一种CPU必备的机器,PC表明CPU当时履行句子方位,改动PC的值,相当于完结程序跳转

n如完结相似C言语的Return句子,便是用MOV PC,LR

n这儿能够在恣意4G的空间进行跳转

B指令(Branch)表明无条件跳转.

B main;跳转到标号为main地代码处

BL指令(Branch with Link)表明带回来值的跳转.

BL比B多做一步,在跳转前,BL会把当时方位保存在R14(即LR寄存器),当跳转代码完毕后,用MOV PC,LR指令跳回来,这实际上便是C言语履行函数的用法,

汇编里调子程序都用BL,履行完子函数后,能够用MOV PC,LR跳回来.

BL delay;履行子函数或代码段delay ,delay能够为C函数.

与MOV PC,XXX能在4G空间跳转不同,B句子只能32M空间跳转,(由于偏移量是一个有符号26bit的数值=32M)

2.传输数据指令MOV,MVN

nMOV(MOVE)指令可完结从另一个寄存器、被移位的寄存器或将一个当即数加载到意图寄存器

MOV R0,R1;把R1的值传到R0

MOV R3,#3;把常数3传给R3,MOV顶用#表明常数,这个值不能超越

nMVN( MOVE Negative)取反后再传值,比MOV多了一步取反

MVN R0, #0;把0取反(即-1)传给R0

MVN R1,R2;把R2的值取反传给R1

3.加载/存储指令,LDR,STR

nLDR,STR是用于寄存器和外部存储器交流数据指令,留意与MOV的差异,后边只在寄存器或常数交流.

uLDR/STR能够选用多种寻址办法,以下只举出运用频率最高几种用法

nLDR(load)用于把一个32Bit的WORD数据从外部存储空间装入到寄存器中

LDR R0,[R1]; R1的值当成地址,再从这个地址装入数据到R0 (R0=*R1)

LDR R1,=0x30008000;把地址0x30008000的值装入到R1中,LDR顶用常数要用=打头.(留意跟MOV的差异,MOV是#)

ldrr0, =(0<<13)|(0<<12)|(0<<10)|(0<<9)|(0<<8)|(1<<6)|(1<<5)|(1<<4)|(1<<1)|(1<<0)

用位与的办法赋值

nSTR(Store)用于把一个寄存器的值存入外部存储空间,是LDR的逆操作.

STR R0,[R1];把R0的值,存入到R1对应地址空间上(*R1 = R0)

STR R0,=0x30008000;把R0中值存入到地址0x30008000

S2C2440的中CPU内核以外的模块的操控寄存器空间也是归于外部空间,所以也得用如下指令LDR R0,=GPFDAT

4.算术运算指令,ADD/ADC,SUB/SBC ,MUL

nADD加法指令

ADD R0,R1,R2; R0=R1+R2

ADD R0,R1,#3;R0=R1+3

nADC带进位加法指令,即除了加两个数以外,还要把CPSR的C值也要带进来

u一般用于大数(超越32Bit整数)相加,这时单用ADD不能处理,有必要折成两步,其间一步用ADC.

u以下是做64Bit的加法

ADDS R0,R1,R2; R0=R1+R2,ADDS中S表明把进位成果写入CPSR

ADC R5,R3,R4;R5=R3+R4+C

nSUB减法指令

SUB R0,R1,R2; R0=R1-R2

SUB R0,R1,#3;R0=R1-3

nSBC带进位减法指令,即除了加两个数以外,还要把CPSR的C值也要带进来,相似ADC

u以下是做64Bit的减法

SUBS R0,R1,R2; R0=R1-R2,SUBS中S表明把进位成果写入CPSR

SBC R5,R3,R4;R5=R3-R4-C

nMUL乘法指令

MUL R0,R1,R2; R0=R1*R2

MUL R0,R1,#3;R0=R1*3

5.位操作指令AND,ORR, TST,BIC

nAND位与指令

AND R0,R1,R2; R0=R1 & R2

AND R0,R1,#0xFF;R0=R1 & 0xFF

nORR位或指令

ORR R0,R1,R2; R0=R1 | R2

ORR R0,R1,#0xFF;R0=R1 | 0xFF

nTST测验某一位是否为1,并把成果写入CPSR,供下一句运用

TST R1,#0xffe;等同于if(R1 & 0xffe)

TST R1,#%1;测验最低位是否为1,%表明二进制

nBIC清位操作

BICR0,R0,#0xF等同于R0&=~(0xF)

BICR0,R0,#%1011该指令铲除R0中的位0 13,其他的位坚持;%表明是二进制,0x表明十六进制

6.比较指令CMP

nCMP比较两个操作数,并把成果存入CPSR供下一句句子运用

CMP R0,R1;比较R0,R1

7.多寄存器句子传输指令,LDM,STM

相似于一次传一个BUFFER到寄存器傍边,或反过来.后边一般要接一个地址改动办法

nLDM从BUFFER传数据多个寄存器传输数据到

LDMIA R0! ,{R3-R9};加R0指向的地址上接连空间的数据,保存到R3-R9傍边,!表明R0值更新,IA后缀表明按WORD递加

LDMFD SP!,{R0-R7,PC}^;康复现场,反常处理回来,^表明不允许在用户形式下运用。

nSTM从寄存器列表向存储空间传值。

STMIA R1!,{R3-R9};将R3-R9的数据存储到R1指向的地址上,R1值更新。

STMFD SP!,{R0-R7,LR};现场保存,将R0~R7,LR入栈

stmfdsp!,{r8-r9},把SP寄存器对庆的地址的值存到R8,R9傍边.!表明最终的值写入SP中。Fd表明

8.ARM指令的变形

大部分指令后位能够接与S两个特别位来表明,对CPSR特别的一些判别

S,表明当时指令履行后把成果改写CPSR

subs,Adds

取决于具体条件,只要CPSR满意指定条件时才指这一指令

BEQ实际上B+ EQ的条件履行.

addne表明ADD +NE才开端加.

9.ARM指令的寻址办法

寻址办法是依据指令中给出的地址码来定位实在的地址,ARM中有9种寻址办法

l寄存器寻址

直接用寄存器编号来寻址,最为常用

MOV R1,R2;R2->R1

l当即数寻址

即指令中的地址码是操作数自身,能够当即取出运用,当即数前带一个#表明,不然表明一个地址

SUBS R0,R0,#1;R0 -1 ->R0

留意与SUBS R0,R0,1差异

l寄存器偏移寻址

这是ARM特有的寻址形式,当第2操作数是寄存器,在履行操作之前,能够做一次移位操作

MOV R0,R2,LSL #3;R2的逻辑左移3位,成果放入R0,即R0=R2*8

ANDS R1,R1,R2,LSL R3;RS的值左移R3位,然后和R1相与操作,成果放入R1

移位操作有LSL (逻辑左移),LSR(逻辑右移) ,ASR(算术右移),ROR(循环右移)RRX带扩展的循环右移

l寄存器直接寻址

即寄存器中值是一个地址,用[]来取出定位到地址傍边

LDR R2,[R0];把R0的值当成地址,取出相应值,赋给R2

l基址寻址

把寄存器的地址值加上一个偏移量

LDR R2,[R3,#0x0F]; R3中的值加上0x0F,从这个地址取出值赋给R@

l相对寻址

基址寻址的变形,由PC寄存器供给基准地址,指令中地址段作为偏移量.两者相加便是有用地址,以下是BL选用相对寻址

BL NEXT

NEXT

MOV PC,LR;从子程序回来

10.ADS ARM的伪指令

相似于C言语的宏,由汇编程序预处理.

l符号界说指令

大局变量界说GBLA ,GBLL,GBLS

局域变量界说LCLA,LCLL,LCLS

变量赋值SETA,SETL,SETS

其间上述伪指令中,最终边的A表明给一个算术变量赋值,L表明用于给一个逻辑变量赋值,s表明给一个字符串赋值

GBLL codedbg;声明一个大局的逻辑变量

Codebg SETL{TRUE};设置变量为{TRUE}

LCLA bitno;声明一个算术变量

Bitno SETA 8;设变量值为8

l数据界说伪指令

nSPACE界说一个内存空间,并用0初始化

{label }SPACE expr

DataBuf SPACE 100;界说100字节长空间, unsigned char DataBuf[100];

nDCB界说一个接连字节内存空间,用伪指令的表达式expr来初始化.一般能够用界说数据表格,或文字字符串.(这时等同于SETS),用于初始二进制BUFFER

{label} DCB expr{,expr …}

Dest DCB -120,20,36,55;等同于unsigned char Dest[]={-120,20,36,55};

nDCU界说的一段字的内存空间(DCB是字节),并用后边表达式初始化

_RESET DCU Reset;等同于DWORD _RESET[]={Reset};

nMAP定一个结构化内存,相当于界说一个C结构

nFILED界说一个结构化内存的成员

MAP 0x00,R9;界说内存表,地址为R9

TimerFIELD 4;界说数据域Timer,长为4字

AttribFIELD 4;界说数据域Attrib,长为4字

StringFILED 100;界说数据域String ,长为100字

相当于C言语的界说:

struct {

DWORD Timer ;

DWORD Attrib ;

Char String[100];

} R9;

11.杂项的伪指令

n字节对齐ALIGN

ALIGN;声明4字节对齐

n界说一个数字常量界说EQU

NAME EQU expr {type}

PLLCON EQU 0xE01FC080;界说PLLCON,相似于C的宏或C++的常量

n包括文件GET和INCLUDE

INCLUDE lpc2106.inc

nNOP空指令

在汇编时会被ARM的空操作替代,比方MOV R0,R0,一般用于延时与占位。

n声明一个外部符符号IMPORT,EXTERN

IMPORT,EXTERN向外部导入一个符号,一般是外部程序大局变量

n条件编译:[]。相似于C的#ifdef之类界说。

格局:[条件表达式

满意条件分支

|

不满意条件分支

]

示例1:

[ ENTRY_BUS_WIDTH=32;相似#if ENTRY_BUS_WIDTH=32

bChangeBigEndian;DCD 0xea000007

] ;相似#endif

示例2:[ CLKDIV_VAL>1;相似#if CLKDIV_VAL>1

blMMU_SetAsyncBusMode

|;相似#else

bl MMU_SetFastBusMode; default value.

];相似#endif

示例3[ THUMBCODE相似#ifdefTHUMBCODE

bx lr

| ;相似#else

movpc,lr

];相似#endif

n段界说AREA

n指令集界说CODE16和CODE32

指示是Thumb指令集(紧缩指令集,每个指令16位)。仍是一般32位指令集

n汇编完毕:END

n程序进口ENTRY

一个根本ARM程序结构

ARM汇编程序结构

源代码由文本文件组成.依照汇编的编译器不同,分为两许多,一类是ADS的汇编程序,一类是GNU汇编格局,两者在指令集是完结相同,可是在伪指令.程序结构等办法各不同相同.本节首要是解说ADS汇编格局.

ADS汇编程序,首要包括如下几类程序

n汇编源程序,后缀名是.S

n汇编包括文件,后缀名是.inc

n假如是与C混和编程..C,.h也能辨认

ARM汇编句子格局

[标号]<指令|条件|S> <操作数> [;注释]

l一切标号顶格写,而指令和伪指令不能顶格写

l标识符(标号,指令)大小写灵敏,所以要在标号和指令时书写共同,一般伪指令,指令,寄存器名能够悉数为大写

l注释以;最初,能够顶格写

l能够运用\来分行写太长句子

l变量,常量的界说有必要在一行顶格写

常量的书写

l数字常量

在程序中直接写数字,十进制12,256,十六进制0x1228,

l字符常量

相似于C的界说,用SETS来界说字符常量

HELLO SETS “hello,the world!”

l逻辑常量

逻辑真为{TRUE},逻辑假为{FLASE}

Testno SETS {TURE}

汇编程序的段界说

任何一个程序都要分段,C言语一般由编译器主动分段,(分红.Text,.Data段之类),但在汇编程序这样的底层程序中,由开发者自行分段.它包括如下段

l至少一个代码段,而且代码段是只读的,对应(.Text)

l数据段能够没有,也能够有多个.

l每一个段用END完毕

AREA界说一个段

AREA段名特点1,特点2,

比如:AREAInit,CODE,READONLY

lENTRY指明一个段的进口

lEND完毕一个段

ABC EQU 0x12

AREA Example,CODE,READONLY

ENTRY

START MOV R7,#10

MOV R6,#5

ADD R6,R6,R7

B

END

ADS ARM汇编程序格局要求

1.一切标号要顶格写.

2.一切指令不能顶格写,一般刺进Tab键内行首

3.ADS ARM中,是大小写灵敏的.主张标号,指令,伪指令,寄存器名悉数为大写

4.注释选用;打头

5.每个程序至少有一个AREA在代码里(READONLY)

6.每个段都要用END完毕(不能顶格)

最常见几个伪指令AREA,EQU,DCB,END ,ENTRY,EXPORT,GOBEL,IMPORT,

常见伪界说

lDCB界说字符中

Str DCB “hello, world “

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

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

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

微信扫一扫关注我们

返回顶部