您的位置 首页 开关

ARM汇编语言中的伪操作(一)

伪操作(derective)是ARM汇编语言程序里的一些特殊的指令助记符,其作用主要是为完成汇编程序做各种准备工作,在源程序运行汇编程序处理,而…

伪操作(derective)是ARM汇编语言程序里的一些特别的指令助记符,其效果首要是为完结汇编程序做各种准备工作,在源程序运转汇编程序处理,而不是在计算机运转期间有机器履行.也就是说,这些伪操作只是汇编过程中起效果,一旦汇编完毕,伪操作的任务也就随之消失.

符号界说( Symbol Definition )伪操作
符号界说伪操效果于界说 ARM 汇编程序中的变量、对变量赋值以及界说寄存器的别号。
包括以下伪操作:
— 用于声明大局变量 GBLA 、 GBLL 和 GBLS 。
— 用于声明部分变量 LCLA 、 LCLL 和 LCLS 。
— 用于对变量赋值 SETA 、 SETL 、 SETS 。
— 为通用寄存器列表界说称号 RLIST 。

—为协处理器的寄存器界说称号 CN
— 为协处理器界说称号 CP
— 为VFP的寄存器界说称号 DN、SN
— 为FPA的浮点寄存器界说称号 FN

1、 GBLA、GBLL 和GBLS
语法格局:
GBLA ( GBLL 或 GBLS ) 大局变量名
GBLA 、 GBLL 和 GBLS 伪操效果于声明一个 ARM 程序中的大局变量,并将其初始化。其间:
GBLA 伪操效果于声明一个大局的算术变量,并初始化为 0 ;
GBLL 伪操效果于声明一个大局的逻辑变量,并初始化为 {FALSE};
GBLS 伪操效果于声明一个大局的字符串变量,并初始化为空串;
大局变量名在其效果规模内有必要仅有。 假如用这些伪操作从头声明现已声明过的变量,则变量的值将 被初始化成后一次声明语句中的值。
运用示例:
GBLA Test1 ;声明一个大局的算术变量,变量名为 Test1
Test1 SETA 0xaa ;将该变量赋值为 0xaa
SPACE Test1 ;引证该变量

GBLL Test2 ;声明一个大局的逻辑变量,变量名为 Test2
Test2 SETL {TRUE} ;将该变量赋值为真
GBLS Test3 ;声明一个大局的字符串变量,变量名为 Test3
Test3 SETS “ Testing ” ;将该变量赋值为 “ Testing ”

2、 LCLA、LCLL 和LCLS
语法格局:
LCLA ( LCLL 或 LCLS ) 部分变量名
LCLA 、 LCLL 和 LCLS 伪操效果于声明一个 ARM 程序中的部分变量,并将其初始化。其间:
LCLA 伪操效果于声明一个部分的数字变量,并初始化为 0 ;
LCLL 伪操效果于声明一个部分的逻辑变量,并初始化为 {FALSE};
LCLS 伪操效果于声明一个部分的字符串变量,并初始化为空串;
运用示例:
MACRO ;声明一个宏

$label message $a ;宏的原型

LCLS err ;声明一个部分串变量err

err SETS “error no: “ ;向该变量赋值

$label ;代码

INFO 0, “err”:CC: :STR: $a ;运用该串变量

MEND ;宏界说完毕

3、 SETA、SETL 和SETS
语法格局:
变量名 SETA ( SETL 或 SETS ) 表达式
伪操作 SETA 、 SETL 、 SETS 用于给一个ARM程序中的变量赋值。
SETA 伪操效果于给一个算术变量赋值;
SETL 伪操效果于给一个逻辑变量赋值;
SETS 伪操效果于给一个字符串变量赋值;
其间,变量名为现已界说过的大局变量或部分变量,表达式为即将赋给变量的值。 在向变量赋值前,有必要先声明该变量。

4 、 RLIST
语法格局:
称号 RLIST { 寄存器列表 }
RLIST 伪操效果于对一个通用寄存器列表界说称号,界说的称号可在LDM/STM指令中运用。在 LDM/STM 指令中,寄存器列表中的寄存器的拜访次第总是先拜访编号较低的寄存器,再拜访编号较高的寄存器,而不论寄存器列表中各寄存器的摆放次序。

运用示例:
RegList RLIST {R0-R5 , R8 , R10} ;将寄存器列表称号界说为 RegList ,可在 ARM 指令 LDM/STM中经过该称号拜访寄存器列表。

5 、 CN

语法格局:

name CN expr

其间:name 是该寄存器的称号

expr为协处理器的寄存器的编号,数值规模为0~15。

CN伪操效果于给一个协处理器的寄存器界说称号。便利程序员回忆该寄存器的功用

示例

Power CN 6 ;将协处理器的寄存器6称号界说为Power

注:以下的伪操作相似(可参阅CN)

数据界说( Data Definition )伪操作
数据界说伪操作包括以下伪操作:

LTORG 声明一个数据缓冲池的开端;

MAP 界说一个结构化的内存表首地址;

FIELD 界说结构化的内存表中的一个数据域;

SPACE 分配一块内存单元,并用0初始化;

DCB 分配一段字节的内存单元,并用指定的数据初始化;

DCD及DCDU 分配一段字的内存单元,并用指定的数据初始化;

DCDO 分配一段字的内存单元,并将每个单元的内容初始化成该单元相对于基态值的寄存器的偏移量;

DCFD及DCFDU 分配一段双字的内存单元,并用双精度的浮点数据初始化;

DCFS及DCFSU 分配一段字的内存单元, 并用单精度的浮点数据初始化;

DCI 分配一段字节的内存单元,用指定的数据初始化,指定内存单元中寄存的是代码,而不是数据;

DCQ及DCQU 分配一段双字的内存单元,并用64位的整数数据初始化;

DCW及DCWU 分配一段半字的内存单元,并用指定的数据初始化;

DATA 在代码段中运用数据(现在已不再运用,仅用于坚持向前兼容)。

以下首要介绍几种常用的:
1、 DCB (“ = ”)
语法格局:
标号 DCB 表达式
用于分配一段字节内存单元并用伪操作中指定的表达式初始化。其间,表达式可认为 -128~ 255 的数值或字符串。
运用示例:
Str DCB “ This is a test ! ” ;分配一片接连的字节存储单元并初始化。

2、DCD “ &”(或DCDU)
语法格局:
标号 DCD (或 DCDU ) 表达式
用于分配一段字内存单元并用伪操作中指定的表达式初始化。其间,表达式可认为程序中的标号或数字表达式。

用DCD 分配的字存储单元是字对齐的,而用 DCDU 分配的字存储单元并不严厉字对齐。
运用示例:
DataTest DCD 4,5,6 ;其值分别为4,5和6。
data2 DCD memaddr+4 ;分配一个字单元,其值为程序中标号memaddr加4个字节
3、DCQ(或DCQU)
语法格局:
标号 DCQ (或 DCQU ) 表达式
用于分配一段以8个字节为单位的内存并用伪操作中指定的表达式初始化。
用 DCQ 分配的存储单元是字对齐的,而用 DCQU 分配的存储单元并不严厉字对齐。
运用示例:
DataTest DCQ -255,2_101 ;2_101指的是二进制的101

4、 SPACE (“ % ”)
语法格局:
标号 SPACE 表达式
用于分配一块内存单元,并初始化为 0 。其间,表达式为要分配的字节数。
运用示例:
DataSpace SPACE 100 ;分配接连 100 字节的存储单元并初始化为 0 。

5、 MAP (“ ^ ”)
语法格局:
MAP 表达式 { ,基址寄存器 }
用于界说一个结构化的内存表的首地址。
表达式可认为程序中的标号或数字表达式,基址寄存器为可选项,当基址寄存器选项不存在时,表达式的值即为内存表的首地址,当该选项存在时,内存表的首地址为表达式的值与基址寄存器的和。
MAP 伪操作一般与 FIELD 伪操作合作运用来界说结构化的内存表。
运用示例:
MAP 0x100 , R9;界说结构化内存表首地址的值为 0x100 + R9 。

6、 FILED (“ # ” )
语法格局:
标号 FIELD 表达式
用于界说一个结构化内存表中的数据域。
表达式的值为当时数据域在内存表中所占的字节数。
FIELD 伪操作常与 MAP 伪操作合作运用来界说结构化的内存表结构。 MAP 伪操作界说内存表的首地址, FIELD 伪操作界说内存表中的各数据域的字节长度,并可认为每个数据域指定一个标号供其他的指令引证。
留意 MAP 和 FIELD 伪操作仅用于界说数据结构,并不实践分配存储单元。
示例1:
下面的伪操作序列界说一个内存表,其首地址为固定地址4096,该内存表中包括5个数据域:consta长度为4个字节;constb长度为4个字节;x长度为8个字节;y长度为8个字节;string长度为256个字节。这种内存表称为依据肯定地址的内存表。

MAP 4096 ;内存表的首地址为4096(0x1000)

consta FIELD 4 ;consta长度为4个字节,相对方位为0

constb FIELD 4 ;constb长度为4个字节,相对方位为5000

x FIELD 8 ;x长度为4个字节,相对方位为5004

y FIELD 8 ;y长度为4个字节,相对方位为5012

string FIELD 256 ;string长度为256字节,相对方位为5020

;在指令中能够这样引证内存表中的数据域:

LDR R6,consta

上面的指令只是能够拜访LDR指令前面(或后边)4KB地址规模的数据域

示例2:

下面的伪操作序列界说一个内存表,其首地址为0,该内存表中包括5个数据域:consta长度为4个字节;constb长度为4个字节;x长度为8个字节;y长度为8个字节;string长度为256个字节。这种内存表称为依据相对地址的内存表。

MAP 4096 ;内存表的首地址为0

consta FIELD 4 ;consta长度为4个字节,相对方位为0

constb FIELD 4 ;constb长度为4个字节,相对方位为4

x FIELD 8 ;x长度为4个字节,相对方位为8

y FIELD 8 ;y长度为4个字节,相对方位为16

string FIELD 256 ;string长度为256字节,相对方位为24

;能够经过下面的指令便利地拜访地址规模超越4KB的数据

MOV R9,#4096

LDR R5,[R9,constb] ;将内存表中数据域constb读取到R5中

在这里,内存表中各数据域的实践内存地址不是依据一个固定地址,而是依据LDR指令履行时R9寄存器中的内容。这样经过上面办法界说的内存表结构能够在程序中有多个实例(经过在LDR指令中指定不同的基址寄存器值来完成)。一般用R9作为静态基址寄存器。

7、LTORG

用于声明一个数据缓冲池(literal pool)的开端

一般ARM汇编编译器把数据缓冲池放在代码段的最后边,即下一个代码段开端之前,或许END伪操作之前。

当程序中运用LDFD之类的指令时,数据缓冲池的运用或许越界。这时能够运用LTORG伪操作界说数据缓冲池,已越界产生。一般大的代码段能够运用多个数据缓冲池。

LTORG伪操作一般放在无条件跳转指令之后,或许子程序回来指令之后,这样处理器就不会过错地将数据缓冲池中的数据当作指令来履行。

汇编操控( Assembly Control )伪操作
汇编操控伪操效果于操控汇编程序的履行流程,常用的汇编操控伪操作包括以下几条:
— IF 、 ELSE 、 ENDIF
— WHILE 、 WEND
— MACRO 、 MEND
— MEXIT
1、 IF、ELSE、ENDIF
语法格局:
IF 逻辑表达式
指令序列 1
ELSE
指令序列 2
ENDIF
IF 、 ELSE 、 ENDIF 伪操作能依据条件把一段源代码包括在汇编程序内或许将其扫除在程序之外。[是IF伪操作的近义词,|是ELSE伪操作的近义词,]是ENDIF伪操作的近义词。
IF 、 ELSE 、 ENDIF 伪指令能够嵌套运用。
运用示例:
MACRO
MOV_PC_LR
[ THUMBCODE
bx lr
|
mov pc,lr
]
MEND
2、 WHILE、WEND
语法格局:
WHILE 逻辑表达式
指令序列
WEND
WHILE 、 WEND 伪操作能依据条件重复汇编相同的或许简直相同的一段源代码。 WHILE 、 WEND 伪操作能够嵌套运用。
运用示例:
GBLA Counter ;声明一个大局的算术变量,变量名为 counter
counter SETA 3 ;设置循环计数变量counter初始值为3
WHILE counter <=10 ;由counter操控循环履行的次数
counter SETA counter+1 ;将循环计数变量加1
;代码 ;代码
WEND

3、 MACRO、MEND
语法格局:
MACRO
[$ label] macroname{ $ parameter1, $ parameter,…… }
指令序列
MEND
MACRO伪操作标识宏界说的开端,MEND标识宏界说的完毕。用MACRO及MEND界说一段代码,称为宏界说体,这样在程序中就能够经过宏指令屡次调用该代码段。
其间, $ label在宏指令被打开时,label会被替换成相应的符号,一般是一个标号。在一个符号前运用$表明程序被汇编时将运用相应的值来替代$后的符号。
macroname为所界说的宏的称号。
$parameter为宏指令的参数。当宏指令被打开时将被替换成相应的值,相似于函数中的形式参数,能够在宏界说时为参数指定相应的默认值。
宏指令的运用方法和功用与子程序有些相似,子程序能够供给模块化的程序设计、节约存储空间并进步运转速度。但在运用子程序结构时需求维护现场,然后增加了体系的开支,因而,在代码较短且需求传递的参数较多时,能够运用宏汇编技能。
首要运用MACRO和MEND等伪操作界说宏。包括在 MACRO 和 MEND 之间的代码段称为宏界说体,在MACRO伪操作之后的一行声明宏的原型(包括宏名、所需的参数),然后就能够在汇编程序中经过宏名来调用它。在源程序被汇编时,汇编器将宏调用打开,用宏界说体替代源程序中的宏界说的称号,并用实践参数值替代宏界说时的形式参数。
宏界说中的$label是一个可选参数。当宏界说体中用到多个标号时,能够运用相似$label.$internallabel的标号命名规矩使程序易读。
MACRO 、 MEND 伪操作能够嵌套运用。
运用示例:
MACRO
$HandlerLabel HANDLER $HandleLabel ;宏的称号为HANDLER,有1个参数$HandleLabel

$HandlerLabel
sub sp,sp,#4 ;decrement sp(to store jump address)
stmfd sp!,{r0} ;PUSH the work register to stack(lr does not push because it return to original address)
ldr r0,=$HandleLabel;load the address of HandleXXX to r0
ldr r0,[r0] ;load the contents(service routine start address) of HandleXXX
str r0,[sp,#4] ;store the contents(ISR) of HandleXXX to stack
ldmfd sp!,{r0,pc} ;POP the work register and pc(jump to ISR)
MEND
;在程序中调用该宏
HandlerFIQ HANDLER HandleFIQ ;经过宏的称号HANDLER调用宏,其间宏的标号为HandlerFIQ,参数为HandleFIQ
HandlerIRQ HANDLER HandleIRQ
HandlerUndef HANDLER HandleUndef
HandlerSWI HANDLER HandleSWI
HandlerDabort HANDLER HandleDabort
HandlerPabort HANDLER HandlePabort
;程序被汇编后,宏打开的成果
HandlerFIQ
sub sp,sp,#4 ;decrement sp(to store jump address)
stmfd sp!,{r0} ;PUSH the work register to stack(lr does not push because it return to original address)
ldr r0,=HandleFIQ;load the address of HandleXXX to r0
ldr r0,[r0] ;load the contents(service routine start address) of HandleXXX
str r0,[sp,#4] ;store the contents(ISR) of HandleXXX to stack
ldmfd sp!,{r0,pc} ;POP the work register and pc(jump to ISR)

b HandlerUndef ;handler for Undefined mode
b HandlerSWI ;handler for SWI interrupt
b HandlerPabort ;handler for PAbort
b HandlerDabort ;handler for DAbort
b . ;reserved
b HandlerIRQ ;handler for IRQ interrupt
b HandlerFIQ ;handler for FIQ interrupt

4、 MEXIT
语法格局:
MEXIT
MEXIT 用于从宏界说中跳转出去。
信息陈述伪操作
ASSERT 断语过错伪操作;
INFO 汇编确诊信息显现伪操作;
OPT 设置列表选项伪操作;
TTL及SUBT 用于在列表文件每一项的最初刺进一个标题和子标题

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

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

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

微信扫一扫关注我们

返回顶部