嵌入式系统技术与设计_第1页
嵌入式系统技术与设计_第2页
嵌入式系统技术与设计_第3页
嵌入式系统技术与设计_第4页
嵌入式系统技术与设计_第5页
已阅读5页,还剩94页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第3章

ARM汇编语言程序设计

在第2章中阐述的体系结构及指令集理论的基础上,本章主要介绍利用ARM汇编语言进行

编程。ARM编译器可以支持汇编语言、C/C++、汇编语言与C/C++的混合编程等,本章将介绍相

关的编程方法。

本章主要内容:

I带格式的:项目符号和编号

—•ARM/Thumb混合编程

—•ARM汇编器支持的伪操作

—•ARM汇编器支持的伪指令

-•ARM汇编器的使用

—•汇编语言与C/C++的混合编程

343.1ARM/Thumb混合编程

a4m3.1.1Thumb指令的特点及实现

Thumb指令集把32位ARM指令集的一个子集编码为一个16位的指令集。在16位外部数据

总线宽度下,ARM处理器上使用Thumb指令的性能要比使用ARM指令的性能更好;而在32位

外部数据总线宽度下,使用Thumb指令的性能要比使用ARM指令的性能差。因此,Thumb指令

多用于存储器受限的一些系统中。Thumb指令集并没有改变ARM系统底层的程序设计模型,只

是在该模型上增加了一些限制条件。Thumb指令集中的数据处理指令的操作数仍然是32位,指

令寻址地址也是32位的。

代码密度高是Thumb指令集的一个主要优势。对于同一个程序而言,使用Thumb指令实现

所需的存储空间,要比等效的ARM指令实现少30%左右。例3-1和例3-2介绍的是使用ARM指

令和Thumb指令实现相同的除法操作。从例子中可以看出,虽然Thumb指令的实现使用了更多

的指令,但是它占用的总的存储空间却比较小。

【例3-1]使用ARM指令实现除法运算。

MOVR3,#0

loop

SUBRO,RO,RI

ADDGER3ZR3Z#1

BGEloop

ADDR2,RO/R1

RO存放被除数,RI存放除数,R2和R3分别存放余数和商。完成整个除法运算使用了5条

指令,每一条指令所占的字节数为4,所以实现一个除法运算,ARM指令所占有的字节数为20。

【例3-2]使用Thumb指令实现除法运算。

MOVR3,#0

loop

ADDR3,#1

SUBRO,RI

BGEloop

SUBR3,#1

ADDR2,RO,R1

例3-2使用Thumb指令完成了和例3-1完全相同的功能。Thumb指令虽然使用了6条指令,

但其每条指令占用2个字节,所以总的字节数为6x2=12,小于ARM指令所占用的2()个字节。

嵌入式系统技术与设计

Thumb指令是ARM指令的一个受限子集。在Thumb状态下,不能直接访问所有的处理器寄

存器,只有R0~R7是可以被任意访问的。在Thumb状态下,使用该8个寄存器和在ARM状态

下使用没有区别。寄存器R8~R12只能通过MOV、ADD或CMP指令访问。CMP指令和所有操

作R0~R7的数据处理指令都会影响CPSR中的条件标志位。一些Thumb指令还使用到了程序计

数器PC(R15X链接地址寄存器LR(R14)和堆栈指针寄存器SP(R13卜在Thumb状态下,

读取R15寄存器时,bil[0]值为0,bUbjts包含了PC的值。当对R15进行写入时,bit[O]被忽

略,出也1国31:1]被设置成当前程序计数器的值。

表3-1列出了在Thumb状态下,各个寄存器的使用情况。

表3-1Thumb寄存器的使用

寄存器访问

R0-R7完全访问

R8-R12只能通过MOV、ADD及CMP访问

R13限制访问

R14限制访问

R15限制访问

CPSR间接访问

SPSR不能访问

从表3-1可以看出,在Thumb状态下不能直接访问CPSR和SPSR。也就是没有和MSR和

MRS等价的指令。为了改变CPSR和SPSR的值,必须使处理器状态切换到ARM状态,再使用

指令MSR和MRS来实现。同样,在Thumb状态下也没有协处理器访问指令,要访问协处理器

寄存器来配置Cache和进行内存管理,也必须使处理器切换到ARM状态。

〔带格式的:项目符号和编号

4433.1.2ARM/Thumb交互工作基础

Thumb以其较高的代码密度和在窄存储器上的性能,使得它在很多系统中得到广泛应用。但

54

在很多情况下,必须使用ARM指令,主要是由于下列原因。

(1)ARM代码比Thumb代码有更快的执行速度。

(2)ARM处理器的一些特定功能必须由ARM指令实现,例如,PSR指令、协处理器指令。

(3)异常发生时,处理器自动进入ARM状态,如果异常处理程序需要使用Thumb指令也必

须通用一个ARM程序头(ARMassemblerheaderb

基于以上原因即使程序需要由Thumb代码实现也必须通过ARM-Thumb互交(ARM-Thumb

interworking)进入Thumb状态。

ARM-Thumb互交是指对汇编语言和C/C++语言的ARM和Thumb代码进行连接的方法,它

进行两种状态(ARM和Thumb状态)间的切换。在进行这种切换时,有时需使用额外的代码,

这些代码被称为Veneer。AAPCS定义了ARM和Thumb过程调用的标准。

从一个ARM例程调用一个Thumb例程,内核必须进行状态切换。状态的变化由CPSR的T

位来显示。跳转到一个例程时,BX指令可用于ARM和Thumb状态切换,具体用法如下。

在Thumb状态调用ARM例程时,采用:

BXRn

在ARM状态调用Thumb例程时,采用:

BXfcond}Rn

其中,Rn可以是R0~R15中的任意寄存器。

这种带状态切换的跳转指令BX,将寄存器Rn的内容复制到程序计数寄存器PC中,因此可

以实现4G空间的跳转。指令根据寄存器Rn的bit[O]来决定处理器是否进行状态切换,详细内容

参见ARM指令一节。

下面是一段ARM程序,该程序调用虚拟的SWI_writeC子程序从存储器的固定地址取出字符

嵌入式系统技术与设计

串“helloworld”并输出。

AREAHello,CODE,READONLY

SWI_WriteCEQU&0;软中断调用参数

SWI_ExitEQUill;程序退出软中断调用参数

ENTRY

STARTADRRIzTEXT,・取字符串地址

;取下一字节内容

LOOPLDRBR0r[Rl],#1

CMPRO,80,•判断是否为字符串尾

SWINESWI_WriteC;软中断调用打印字符

BENLOOP;循环

SWISWI_Exit;软中断调用退出程序执行

TEXT="HelloWorld",60a,50d,0

END

下面的代码将上面的ARM代码转换成等价的Thumb代码。

AREAHelloW^humb,CODE,READONLY

SWI_WriteCEQU&0;软中断调用参数

SWI_ExitEQU611,・程序退出软中断调用参数

ENTRY;程序入口点

CODE32;进入ARM状态

ADRRO,START+1;取得Thumb代码入口地址

BXRO;进入Thumb代码

CODEI6;Thumb代码入口点

STARTADRRI,TEXT;R1->"HelloWorld"

LOOPLDRBRO,(RI];取下一字节内容

ADDRI,Rlz#1;地址指针加1**T

CMPRO,10;判断是否为字符串尾

BEQDONE;完成?**T

SWISWI_WriteC;如果不是字符串尾

BLOOP,・继续循环

DONESWISWI_Exit;程序退出

ALIGN;字对齐

TEXTDATA

"HelloWorld'1,,&0a,&0d,&00

END

上例中,ARM代码到Thumb代码转换过程中新增加的指令用蜂*T”标注。

在实现ARM代码和Thumb代码转换时,大部分的ARM指令有等价的Thumb指令,只有少

数指令没有。如加载字节指令(LDR)不支持自动变址,软中断指令不能条件执行。

在编写Thumb代码时要注意以下几点。

(1)汇编器需要知道什么时候产生ARM代码,什么时候产生Thumb代码,程序中使用

CODE32和C0DE16伪操作提供给编译器这些信息。

(2)由于处理器上的执行是在ARM状态下完成的,所以,要使用Thumb指令必须由ARM

指令调用Thumb指令,这一过程是通过“BXLR”指令来实现的。需要注意的是,在使用“BXLR”

指令之前,要对寄存器LR做正确的初始化。

(3)在ARM和Thumb混合编程时,常使用ALIGN伪操作保证内存地址对齐。

(带格式的:项目符号和编号

"33.1.3ARM/Thumb交互子程序

编写ARM/Thumb互交代码时,需要注意下面两点。

(1)对于CC++子程序而言,只要在编译时指定-apcs/interwork选项,汇编器会生成合适的

返回代码,使得程序返回到和调用程序相同的状态。

(2)在汇编语言子程序中,用户必须自己编写相应的返回代码,使得程序返回到和调用程序

相同的状态。

如果目标代码包含以下内容,应该在编译或汇编时使用-apcs/inierwork选项,使处理器能够

在ARM和Thumb代码间进行正确的切换,这种情况包含以下4种。

(1)需要返回到ARM状态的Thumb子程序。

(2)需要返回到Thumb状态的ARM子程序。

(3)间接调用ARM子程序的Thumb子程序。

(4)间接调用Thumb子程序的ARM子程序。

嵌入式系统技术与设计

如果在程序连接阶段,连接器发现ARM子程序和Thumb子程序间存在相互调用,而源文件

在编译时没有使用--apcs/interwork选项,则连接器将报告以下错误。

Error:L6239E:CannotcallARMsymbol,arm_function'innon-interworkingobject

armsub.ofromTHUMBcodeinthumbmain.o(.text)

其中:arm_funclion”是需要进行状态切换的子程序名。

在这种情况下,用户必须使用-apcs/interwork选项重新对源文件进行编译。但在下面两种情

况下,不必指定-apcs/interwork选项。

(I)在Thumb状态下,发生异常中断时,处理器自动切换到ARM状态,这时不需要添加状

态切换代码。

(2)当异常发生在Thumb状态时,从异常返回不需要添加状态切换的Veneer代码。

[带格式的:项目符号和编号

-1.使用汇编语言实现互交

对于汇编程序来说,可以有两种方法来实现程序状态的切换。第一种方法是利用连接器提供

的交互子程序Veneer来实现程序状态的切换,这时用户可以使用指令BL来调用子程序;第二种

方法是用户自己编写状态切换的程序h本节主要介绍第二种方法。

在ARMv4版本及其以前的版本中,可以使用BX指令实现程序状态的切换。

从ARMv5版本开始,下面的指令也可以用来实现程序的状态切换。

•BX(Branchandexchange)

•BLX、LDR、LDM和POP下面的两个伪操作用来区分源程序中的FQ"代码和二hu:nb代码。

—VK/IV?

下面简单介绍用于状态切换的指令和伪操作,更详细的信息请分别参见相关章节。

(I)BX指令

58

ARM状态下的BX指令,使程序跳转到指令中指定的参数Rm所指定的地址执行程序,Rin

的第。位复制到CPSR中的T位,bits[31:l]移入PC。若Rm的bit⑼为1,则跳转时自动将CPSR

中的标志位T置位,即把目标地址的代码解释为Thumb代码;若Rm的位bit[O]为0,则跳转时

自动将CPSR中的标志位T复位,即把目标地址代码解释为ARM代码。

指令的语法格式如下:

BX{<cond>}<Rm>

①<cond>

cond为指令编码中的条件域。它指示指令在什么条件下执行。当cond忽略时,指令为无条

件执行(cond=AL(Alway)卜

②<Rm>

Rm包含跳转指令的目标地址。如果Rm的bit[O]=O,目标地址处指令为ARM指令;如果

Rm的bit[O]=1,目标地址处指令为Thumb指令。指令操作的钩代码l

指令操作的伪代码如下面程序段所示6

IV_condilionPassed{cond)——then

TFlng=Rm[O]

Thumb状态下的BX指令,也用于ARM和Thumb代码间的相互调用。

指令的语法格式如下:

BX<Rm>

其中,<Rm>为目标地址寄存器,包含程序的跳转地址。BX指令的目标地址寄存器可以是R0~

RI5中的任意寄存器。

嵌入式系统技术与设计——

ARM指令集中的BX指令和Thumb指令集中的BX指令相差较大,它们分别为不同方向的

跳转。当R15作为目的寄存器使用时,要特别注意该指令在两个指令集中的区别。—砾某指令

ARM-状态下的gJ指令使用一个寄存器中的绝对地址或标号,用于使程序跳转到旧wn由

状态或从■饵中由状态返回,该指令用分支寄存器的最低位来更新CPSR中的F位,并将返回地址

写入到连接寄存器中b

OBLX-—检喀&_&ddr>

②BLX[〈cond>]——<Rm>

第一种格式4T标按下述方法洋第-将指令中指定的"24隹偏移盘进行符号护层并移

两位形成字偏移量「然后将其累加进程序计数翳PG中。一逆时二程序计数器的内容为-BX-指令地

址加■字节p*Hfbk®4)也加到结果地址的第一位(bit|l|),使目标地址为半字地址,以执行

接下来的琮申/指令。计算偏移量的工作一般由ARM汇编器来完成°这种形式的跳转指令只能

实现±势毋■空间的跳转。

第二种格式中,寄存器Rm指定转移目标,Rm的第()-位拷贝到CPSR中的T位,bii[3l—用

♦—如果~Rw■的■阳。曰,则跳转时自动将GPSR■中的标志位不置位,即把目标地址的代码解

释为~知出》由4^%-

♦—如果•的硼0K4跳转眸自动将£PSR■中的标志位干要位丁即把目标地址的代码解

^-ARM-4^^O-

的/状种带返回链接的跳转指令BLX㈠银供子T^TIHH由状态下无条件调用T舟I

子程序的方法,当从子程序返回时,通常使用下面的方式之一—

•BXLR

•—•海

期*指令不可条件执行,可以实现在大约±4MB的地址空间范围内跳转,实现方法是将e月

8LX指令编译成旃条16位的-Thumb指令,从而实现上述跳转°对编译后的两条指令说明如下广

@*想卜什么意思?->的跳转指令L该跳转包含跳转偏移量的高位部分。

②TU*的跳转指令。该跳转包含跳转偏移量的低位部分「

BL~~<E&Fgel;address〉

<targel_uddress>

指定程序跳转的目标地址6指令通过下面的方法计算目标地址6

―~#44M4)^BL指令的()住心」I域左移

•—将结果符号扩展为功缶L

一将得到的值加到P€~寄存器中「

♦—与404的"八节令的域相加―

因膨小指令可以实现在大约±4MB的地址空间范围内跳转。

另外LThumb状态下-包含另一种格■式的BLX指令,该BLX(2)指令用于ARM和Thumbm

程序间的相互调用。程序状态号的F标志位根据目的寄存器的bil|O|位而改变。

指令的语法格式为:

BLX<Rm>

嵌入式系统技术与设计

其中为目标地址寄存器,K)「14寄存器均可以作为目标地址寄存器6

LR一(address6fIheinsruciionafterthisBLX)|1

T44ag^RfRfO|

PC=Rm[34用《』

T)汇编伪指令

汇编编译器可以产生ARM代码也可以产生Thumb代码。使用ihumb或一6选项指示编译

须夬为地使用”五风*指令换到状态并使用正面的伪操作使编铎器

产生'油出他•代码b*

«-cX.-Vn_ZJnL^Ar_*■if\J\

•—^OD£^2

ARM■和《ODE32伪操作的意义相同°

语法格式如下--

ARM

CODE32

使用在同忖包含ARA44的和中HHttb指令的源文件中莒需要从ARM指令序列切换郅RIHM)

指令序列时,使用伪操作■ARM(或CODE32);当需要从Thumb指令序列切换到ARM指令序列

时使用-Thun由伪操脩ARMf~^8DE^例操作只提指示汇编器后面的指令类型息ARM书令,

81兆48例指令通知编译需丁其^»«令序列为将住的Wn心指令l

语法格式如下。

CODE16

若在汇编源程序中同时包含ARM指令和Thumb指令时,可用CODE16伪指令通知编译器其

后的指令序列为16位的Thumb指令。

下面通过一个实例,说明ARM和Thumb之间的状态切换过程。

(42)编程实例

PRESERVES

AREAAddReg,CODE,READONLY;段名为AddReg,属性为READONLY

ENTRY;程序入口

;SECTION1

main

ADRRO,ThumbProg+1;确定跳转地址

;并将bit[0]置1

,•使程序切换到Thumb状态

BXRO;程序跳转并执行状态切换

;SECTION2

CODE16/Thumb代码指示伪操作

ThumbProg

MOVR2,42;R2=2

MOVR3,#3;R2=3

ADDR2,R2,R3;R2=R2+R3

ADRRO,ARMProg

BXRO;程序跳转并执行状态切换

;SECTION3

CODE32;ARM代码指示伪操作

嵌入式系统技术与设计I

ARMProg

MOVR4,#4

MOVR5Z#5

ADDR4,R4,R5

;SECTION4

stopMOVRO,#0x18;设置.semihosting软中断号

LDRRI,=0x20026;ADP_Stopped_ApplicationExit

SWI0x123456;ARMsemihostingSWI软中断调用

END;文件结束

上面的例子分为4部分,通过下面的步骤编译和运行。

①使用文本编辑器,如notepad,输入上面的代码,并保存成文件addreg.s。

②在命令行中键入汇编命令annasm-gaddrcg.s©

③在命令行中键入链接命令armlinkaddreg.o-oaddrego

④使用调试器(Debugger)(如RealViewDebuggerorAXD)运行映像文件。可以使用单步

执行,观察代码在Thumb状态下的执行。

6Thumb代码的地址标号如果用伪操作export声明为“外部的”,则连接器会自动调整

®该地址标号使其bit[O]等于1;如果该地址标号没有被声明为“外部的”,则使用者必须手

薄"®动地对标号进行调整,如上例中的ThumProg+1。

(3)ARMv5架构下的状态切换

在ARMv5体系结构的指令集中,增加了下面两条指令用于ARM代码和Thumb代码之间的

互交。

①BLXaddress

该指令跳转到指令中指定的地址处执行程序并进行程序状态切换,该地址是“PC相关的",地

址范围为-32~32MB(ARM状态)或-4~4MB(Thumb状态卜

②BLXregister

在该格式的跳转指令中,寄存器Rm指定转移目标,Rm的第0位复制到CPSR中的T位,

64

bi®31:0]移入PCo

使用上面两条指令,在执行程序跳转之前,处理器自动将返回连接寄存器LR的bit[O]位更新

为CPSR寄存器的T位,所以,无论处理器状态是否发生变化,程序都能正确返回。

当使用LDR、LDM及POP指令向PC寄存器中赋值时,寄存器CPSR中的Thumb位将被设

置成PC寄存器的配血⑼,这时就实现了程序状态的切换。这种方法在子程序的返回时非常有效,

同样的指令可以根据需要返回到ARM状态或Thumb状态。

连接器在对目标代码进行链接时,将代码中的地址标号分为3类。

①ARM指令地址标号。

②Thumb指令地址标号。

③数据(Data)地址标号。

当连接器重定位Thumb代码中的地址标号时,地址标号的由也110]位将被自动设置为lo

就意味着跳转指令(包括BX、BLX和LDR)可以根据目标地址正确地进行状态切换。

a上面提到的连接器自动设置目的地址的行为,只有在ARMv5及其以上版本中支持。

1带格式的:项目符号和编号

一2.使用C和C++语言实现互交

对于不同的C和C++源程序,可能有些程序中包含ARM指令,有些程序中包含Thumb指令,

这些程序可以相互调用,只是在编译这些程序时指定-apcs/interwork选项。当使用了

--apcs/interwork选项,编译器会自动进行一些相应处理;连接器在检测到程序中存在互交工作时,

会生成一些用于程序状态切换的代码。

(1)代码编译

嵌入式系统技术与设计——

可以使用下面的指令,将C或C++程序编译为可以执行互交的目标代码。

armcc--c90--thumb--apes/interwork

armcc--c90-arm--apes/interwork

armcc--epp--thumb--apes/interwork

armcc--epp--arm--apes/interwork

使用-apcs/in【erwork选项对文件进行编译时,编译器会进行如下处理。

①对于叶子程序(LeafFunction,即程序中没有其他子程序调用的程序),编译器将程序中

的“MOVPC,LR”指令替换成“BXLR”指令,因为“MOVPC”指令不能进行状态切换。

②对于非叶子程序,要进行一系列的指令替换,如:

POP{R4,R5,pc}

替换为:

POP(R4ZR5)

POP{R3}

BXR3

下面的例子显示了一段带子程序调用的C语言程序,使用-apcs/inierwork选项进行编译时,

对代码产生的影响。

C语言源程序。

Voidfunc(void)

(

SubO

}

使用armcc--apcs/interwork选项进行编译产生结果如下。

Func

STMFDsp!,{R4-R7zlr!

BLsub

LDMFDsp!,{R4-R7zlr)

BXlr

使用tee--apcs/interwork选项进行编译产生结果如下。

PUSH(R4-R7Zlr)

BLsub

POP{R4-R7}

POP{R3}

BX

(2)C语言的互交实例

下面的例子显示了一个Thumb状态下的代码通过互交调用ARM子程序,然后又在ARM子

程序中调用Thumb指令集的库函数printf()o

thumbmain.c

**********************/

♦include<stdio.h>

externvoidarm_function(void);

intmain(void)

(

printf("HellofromThumbWorld\nn);

arm_function();

printf(MAndgoodbyefromThumbWorld\nM);

return(0);

}

y***********»»********

armsub.c

4include<stdio.h>

voidarm_function(void)

(

printfandGoodbyefromARMworld\nn);

使用下面的命令对程序进行编译连接。

①编译生成带互交的Thumb代码。

armcc--thumb-c-g--apes/interwork-othumbmain.othumbmain.c

②编译生成带互交的ARM代码。

armcc-c-g-apes/interwork-oarmsub.oarmsub.c

③连接目标文件。

armlinkthumbmain.oarmsub.o-othumbtoarm.axf

另外,可以使用-info选项使连接器输出由于互交所增加的代码大小。

armlinkarmsub.othumbmain.o-othumbtoarm.axf——infoveneers

输出信息如下所示。

嵌入式系统技术与设计

AddingVeneerstotheimage

AddingTAveneer(4bytes,Inline)forcallto'artn_function'fromthumbmain.o(.text).

AddingATveneer(8bytes,Inline)forcallto'Oprintf1fromarmsub.o(.text).

AddingATveneer(8bytes,Inline)forcallto*_rt_lib_init'fromkernel.o(.text).

AddingATveneer(12bytes,Long)forcallto*_rt_lib_shutdown*fromkernel,o(.text).

AddingTAveneer(4bytes.Inline)forcallto1_rt_memclr_w*fromstdio.o(.text).

AddingTAveneer(4bytes.Inline)forcallto'__rt_raise*fromstdio.o(.text).

AddingTAveneer(8bytes.Short)forcallto'.rtexit*fromexit.o(.text).

AddingTAveneer(4bytes,Inline)forcallto*_user_libspace*fromfree.o(.text).

AddingTAveneer(4bytes,Inline)forcallto*_fp_init*fromlib_init.o(.text).

AddingTAveneer(4bytes,Inline)forcallto'_heap_extend*frommalloc.o(.text).

AddingATveneer(8bytes,Inline)forcallto'_raise*fromrt_raise.o(.text).

AddingTAveneer(4bytes,Inline)forcallto1rterrnoaddr*fromftell.o(.text).

12Veneer(s)(total72bytes)addedtotheimage.

(3)Thumb状态下的功能指针

任何指向Thumb函数(由Thumb指令完成的功能函数并且其返回状态也为Thumb状态)的

指针,其最低有效位(LSB)必为1。

当重定位Thumb代码中的地址标号时,连接器将自动设置地址的最低有效位。如果在程序中

使用绝对地址,连接器将无法完成该设置。因此,在Thumb代码中使用绝对地址时,必须手工设

置为其地址加lo

下面的例子显示了Thumb代码的功能指针的使用。

typedefint(*FN)();

myfunc(){

FNfnptrs[]={

(FN)(0x8084+1),//有效的Thumb地址

(FN)(0x8074)//无效的Thumb地址

);

FN*myfunctions=fnptrs;

myfunctions(0]();//调用成功

myfunctions[1]();//调用失败

68

(带格式的:项目符号和编号

323.2ARM汇编器支持的伪操作

4233.2.1伪擅但指令概述

在ARM汇编语言程序中,有一些特殊指令助记符,这些助记符与指令系统的助记符不同,

没有相对应的操作码,通常称这些特殊指令助记符为伪操作标识符(directive)①,它们所完成的

操作称为伪操作。伪操作在源程序中的作用是为了完成汇编程序做各种准备工作的,这些伪操作

仅在汇编过程中起作用,一旦汇编结束,伪操作的使命就完成。®

在ARM的汇编程序中,伪操作主要有符号定义伪操作、数据定义伪操作、汇编控制伪操作

及其杂项伪提作用指令等。

I带格式的:项目符号和编号

电322符号定义伪操作

符号定义伪操作用于定义ARM汇编程序中的变量、对变量赋值及定义寄存器的别名等操作。

常见的符号定义伪操作有如下几种。

(I)用于定义全局变量的GBLA、GBLL和GBLSo

(2)用于定义局部变量的LCLA、LCLL和LCLSo

(3)用于对变量赋值的SETA、SETL和SETS。

(4)为通用寄存器列表定义名称的RLISK

一为协处理器寄存器定义别名的6b

①有里整蝴中麟翦操作标语

嵌入式系统技术与设计

,f

—1.全局变量定义伪操作GBLA、GBLL和GBLS'

(I)语法格式

GBLA、GBLL和GBLS伪操作用于定义一个ARM程序中的全局变量并将其初始化。其中:

①GBLA伪操作用于定义一个全局的数字变量并初始化为Oo

②GBLL伪操作用于定义一个全局的逻辑变量并初始化为F(假卜

③GBLS伪操作用于定义一个全局的字符串变量并初始化为空。

由于以上3条伪指令用于定义全局变量,因此在整个程序范围内变量名必须唯一。

语法格式如下:

<gblx><variable>

①<gblx>

取值为GBLA、GBLL、GBLS三者中的之一。

②〈variable〉

定义的全局变量名,在其作用范围内必须唯一。全局变量的作用范围为包含该变量的源程序。

(2)使用说明

如果用这些伪操作重新声明已经声明过的变量,变量的值将被初始化成后一次声明语句中

的值。

(3)示例

①使用伪操作声明全局变量。

Testi;定义一个全局的数字变量,变■名为Testi

TestiSETAOxaa;将该变量赋值为Oxaa

GBLLTest2;定义一个全局的逻辑变量,变量名为Test2

Test2SETL{TRUE);将该变量赋值为真

GBLSTest3;定义一个全局的字符串变量,变量名为Test3

Test3SETS"Testing";将该变量赋值为"Testing”

②声明变量Objecisize并设置其值为Oxff,为“SPACE”操作做准备。

GBLAobjectsize

ObjectsizeSETAoxff

SPACEobjectsize

③下面的例子显示如何使用汇编命令设置变量的值。具体做法是使用“-pd”选项。

Armasm-pd''objectsizeSETAoxff"-oobjectfilesourcefile

1带格式的:项目符号和编号

—2.局部变量定义伪操作LCLA、LCLL和LCLS

(1)语法格式

LCLA、LCLL和LCLS伪指令用于定义一个ARM程序中的局部变量并将其初始化。其中:

①LCLA伪操作用于定义一个局部的数字变量并初始化为Oo

②LCLL伪操作用于定义一个局部的逻辑变量并初始化为F(假卜

③LCLS伪操作用于定义一个局部的字符串变量并初始化为空。

以上3条伪操作用于声明局部变量,在其作用范围内变量名必须唯一。

语法格式如下:

<lclx><variable>

①<LClx>

取值为LCLA、LCLL、LCLS三者中的之一。

②<variable>

所定义的局部变量名,在其作用范围内必须唯一。局部变量作用范围为包含该局部变量的宏。

(2)使用说明

嵌入式系统技术与设计

如果用这些伪操作重新声明已经声明过的变量,则变量的值将被初始化成后一次声明语句中

的值。

(3)示例

①使用伪操作声明局部变量。

LCLATest4,・声明一个局部的数字变量,变量名为Test4

Test3SETAOxaa;将该变量赋值为Oxaa

LCLLTest5,・声明一个局部的逻辑变量,变量名为Test5

Test4SETL{TRUE};将该变量鼠值为真

LCLSTest6;定义一个局部的字符串变量,变量名为Test6

Test6SETSnTesting”;将该变量赋值为"Testing"

②下面的例子定义一个宏,显示了局部变量的作用范围。

MACRO;声明一个宏

$labelmessage$a;宏原型

LCLSerr,・声明局部字符串变量

$label

INFOO/'err'^CC::STR:$a

MEND;宏结束,局部变量不再起作用

1带格式的:项目符号和编号

—3.变量赋值伪操作SETA、SETL和SETS

(I)语法格式

伪指令SETA,SETL和SETS用于给一个已经定义的全局变量或局部变量赋值。

①SETA伪操作用于给一个数学变量赋值。

②SETL伪操作用于给一个逻辑变量赋值。

③SETS伪操作用于给一个字符串变量赋值。

语法格式如下:

Variable<setx>expr

①Variable

72

变量名为已经定义过的全局变量或局部变量,表达式为将要赋给变量的值。

②<setx>

取值为SETA、SETL、SETS三者中的之一。

数学、逻辑或字符串表达式,也就是将要赋予变量的值。

(2)使用说明

在向变量赋值前必须先声明变量。也可以在汇编指令中预定义变量,如:

"Armasm--pd"objectsizeSETAoxff*'--oobjectfilesourcefile"

(3)示例

①为预先定义的变量赋值。

LCLATest3;声明一个局部的数字变量,变量名为Test3

Test3SETAOxaa;将该变量赋值为Oxaa

LCLLTest4;声明一个局部的逻辑变量.变量名为Test4

Test4SETL{TRUE};将该变量赋值为真

LCLSTest6;定义一个局部的字符串变量,,变量名为Test6

Test6SETS"Testing";将该变量赋值为"Testing"

②使用变量赋值伪操作,定义一些程序相关内容。

GBLAversionNumber

VersionNumberSETA21

GBLLDebug

DebugSETL{TRUE}

GBLSversionstring

VersionstringSETS"version1.

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论