ARM汇编语言伪指令
ARM汇编伪指令与伪操作
应用示例:
GBLA Test1 Test1 SETA 0xaa GBLL Test2 Test2 SETL {TRUE} GBLS Test3 Test3 SETS “Testing”
4.给通用寄存器列表定义名称RLIST
RLIST伪操作用于给一个通用寄存器列表定义名称, 使用该伪操作定义的名称可以在LDM/STM中使用。
ADRL{cond}
register,expr
目标寄存器
地址表达式
地址表达式expr的取指范围: ➢当地址值是字节对齐时,其取指范围为-64K~64K; ➢当地址值是字对齐时,其取指范围为-256K~256K;
3.小范围地址读取伪指令ADR
ADR伪指令将基于PC相对偏移的地址值或基于寄 存器相对偏移的地址值读取到寄存器中。
操作符
语法格式
ARM 或 ARM
CODE32
CODE32
THUMB 或 THUMB
CODE16
CODE16
功能描述 指示编译器将要处理的是 32 位的 ARM 指令 指示编译器将要处理的是 16 位的 Thumb 指令
[例6-35]
AREA ToThumb,CODE,READONLY ENTRY ARM start ADR R0,into_thumb+1 BX R0 THUMB into_thumb MOVS R0,#10 …
[例6-36]:
AREA Example,CODE,READONLY GET include_s.s GET C:\test\include_init.s …
2.文件原样包含INCBIN
INCBIN伪操作将一个文件包含到当前源 文件中,该文件按原样包含,不进行汇编处理。 可以使用INCBIN来包含可执行文件、文字或 其他数据。
第4章 ARM伪指令及程序设计
1.1 ARM汇编伪指令--ADR
ARM中伪指令不是真正的ARM指令或Thumb指令,这些伪指令在编译器 对源程序进行汇编处理时被替换成相应的ARM或Thumb指令序列.ARM 伪指令包括ADR,ADRL,LDR和NOP. ADR--小范围的地址读取伪指令 该指令将基于PC的地址值或基于寄存器的地址值读取到寄存器 中.当地址值是字对齐时,地址的取址范围是-1020~1020字节. 在处理源程序时,ADR伪指令通常被编译器替换成一条ADD指令或 SUB指令来实现该ADR伪指令的功能.读取的地址必须和ADR指令在 同一个代码段中. 语法格式: ADR{cond} register,expr 例:start MOV r0,#10 ADR r4,start ; SUB r4,pc,#0xc
语法 LDR rd, =const For example LDR r0, =0xFF => LDR r0, =0x55555555=>
MOV r0, #0xFF LDR r0, [PC, #Imm12] … … DCD 0x55555555
1.3 ARM汇编伪指令--NOP
NOP--空操作伪指令 NOP伪指令在汇编时将被替换成ARM中的空操 作,如可能为 " MOV R0 ,R0 "等.NOP伪指令不 影响CPSR中的条件标志位.
2.1ARM汇编语言语句格式(1)
ARM 汇编语言程序中符号的定义规则: 符号区分大小写,同名的大,小写符号会被编译器认为是两 个不同的符号. 符号由大小写字母,数字以及下划线组成. 符号在其作用范围内必须唯一. 自定义的符号名不能与系统的保留字相同. 符号名不应与指令或伪操作同名. 程序中的变量和常量 变量;变量有数字变量,逻辑变量和串变量3种类型 数字常量;使用EQU伪操作来定义数字常量. 标号;标号代表一个地址,段内标号的地址在汇编时确定, 而段外标号的地址在连接时确定.
ARM编程进阶之一-ARM汇编伪指令
ARM编程进阶之一-ARM汇编伪指令到目前为止,我们已经具备编写较为复杂的ARM 汇编程序的能力,但要编写较为复杂且实用的程序,我们就不得不掌握ARM 汇编的伪指令(pseudo- instruction)。
千万别把汇编伪操作(directive)与汇编伪指令(pseudo- instruction)弄混了,directive 不会被编译器编译为机器指令,但pseudo- instruction 会。
而pseudo-instruction 与指令(instruction)的区别在于,1 条instruction 与1 条机器指令对应,而编译器会把1 条pseudo-instruction 编译为1 条或多条机器指令。
ARM 汇编伪指令共4 条:ldr、adr、adrl、nop1、ldr首先我们来回答基本寻址模式与基本指令一文中提出的问题。
如果我们需要mov r0, #10000 这样的指令,应该怎么办?(常数10000 不能在机器指令32bit 中的低12bit 中被表示出来)。
当你进行编译的时候,Error:All70E 的错误就会出现,如下图。
其实,这个问题很容易解决,只需要将mov r0, #10000 换为ldr r0, =10000 即可。
为什么这样就可以了呢?因为,这里的ldr r0, =10000 并非我们已经学过的ldr 指令,而是一条伪指令,编译器会将这条伪指令替换为:ldr r0, [pc, #-4]DCD 10000DCD 所分配的内存空间中存放了整数10000,该内存空间被称为literal pool,中文名称文字池。
由于整个程序都是由编译器编译的(包括文字池的分配),所以很显然编译器能够知道ldr 指令在内存中的地址与文字池在内存中的位置之间的偏移量,因此编译器就可以正确地使用以pc 为基址,采用相对寻址的ldr 指令将文字池中的数取出加载到寄存器r0 中。
由此可见,编译器对于ldr r0, =10000 这条伪指令的处理,其实质是:。
ARM汇编伪指令详解
ARM汇编伪指令详解(转载)2007-09-13 00:40ARM汇编程序分析过程中,比较难理解的是他的伪操作、宏指令和伪指令。
在读vivi时遇到很多不懂的,所以在此对引导程序中出现伪操作、宏指令和伪指令进行总结,*****************************************************一、GET option.s// GET和INCLUDE功能相同功能:引进一个被编译过的文件。
格式:GET filename其中:fiename 汇编时引入的文件名,可以有路径名。
GET符号在汇编时对宏定义,EQU符号以及存储映射时是很有用的,在引入文件汇编完以后,汇编将从GET符号后开始。
在被引入的文件中可能有GET符号再引入其他的文件。
GET符号不能用来引入目标文件。
*****************************************************二、INTPND EQU 0x01e00004//EQU可以用“*”代替,在阅读源程序时注意。
功能:对一个数字常量赋予一个符号名。
格式:name EQU expression其中:name 符号名。
Expression 寄存器相关或者程序相关的固定值。
使用EQU定义常量,与C语言中用#define定义一个常量相同。
例:num EQU 2 ;数字2赋予符号num*****************************************************三、GBLL THUMBCODE[ {CONFIG} = 16THUMBCODE SETL {TRUE}CODE32|THUMBCODE SETL {FALSE}][ THUMBCODECODE32 ;for start-up code for Thumb mode]//其中[=IF ,|=ELSE ,]= ENDIF, CODE32 表明一下操作都在ARM状态。
ARM汇编语言伪指令
鲁东大学 LUDONG UNIVERSITY
VersionNumber
Example
GBLA VersionNumber SETA 21
Debug
GBLL Debug SETL {TRUE}
GBLS VersionString VersionString SETS "Version 1.0"
鲁东大学 LUDONG UNIVERSITY
MEND
数据定义伪指令
鲁东大学 LUDONG UNIVERSITY
数据定义指令(Data definition directives):用于进行 数据空间分配。
SPACE DCB DCD, DCDU
MAP, FIELD
SPACE
鲁东大学 LUDONG UNIVERSITY
The SPACE directive reserves a zeroed block of memory.
伪指令举例
鲁东大学 LUDONG UNIVERSITY
AREA ThumbSub, CODE, READONLY ENTRY CODE32 ;ARM
header ADR r0, start + 1 CODE16 ;Thumb.
start MOV r0, #10
doadd MOV pc, lr
END
GBLA, GBLL, GBLS LCLA, LCLL, LCLS SETA, SETL,SETS
全局变量声明
鲁东大学 LUDONG UNIVERSITY
GBLA, GBLL, GBLS
-- 声明一个全局的算术、逻辑和串变量
Directives GBLA
Variable Type arithmetic
第6讲ARM汇编伪指令与伪操作
n ARM 将Keil 公司收购之后,正式推出了针对ARM 微控制器的开发工具RealView Microcontroller Development Kit ( 简称Real View MDK 或者 MDK) ,它将ARM 开发工具RealView Development Suite (简称RVDS) 的编译器RVCT 与Keil的工程管理、调试仿真工具集成在一起,是 一款非常强大的ARM 微控制器开发工具。
•ADR伪指令格式 •ADR{cond} register,expr
•指令执行的条件码 •加 载 的 目 标 寄 存 •地 址 表 达
器
式
• 地址表达式expr的取指范围:
▪当地址值是字节对齐时,其取指范围为-255~255;
▪当地址值是字对齐时,其取指范围为-1020~1020;
第6讲ARM汇编伪指令与伪操作
•应用示例(源程序):
• ...
• ADR
R0,Delay
• ...
•Delay
• MOV
R0,r14
• ...
•使用伪指令将程序标号 Delay的地址存入R0
第6讲ARM汇编伪指令与伪操作
• ARM伪指令——小范围的地址读取
• ADR伪指令将基于PC相对偏移的地址值或基于寄存器相对偏移的地 址值读取到寄存器中。在汇编编译器编译源程序时,ADR伪指令被编译器 替换成一条合适的指令。通常,编译器用一条ADD指令或SUB指令来实现 该ADR伪指令的功能,若不能用一条指令实现,则产生错误,编译失败。
• ARM伪指令——小范围的地址读取
• ADR伪指令将基于PC相对偏移的地址值或基于寄存器相对偏移的地 址值读取到寄存器中。在汇编编译器编译源程序时,ADR伪指令被编译器 替换成一条合适的指令。通常,编译器用一条ADD指令或SUB指令来实现 该ADR伪指令的功能,若不能用一条指令实现,则产生错误,编译失败。
ARM伪指令
ARM伪指令.txt珍惜生活——上帝还让你活着,就肯定有他的安排。
雷锋做了好事不留名,但是每一件事情都记到日记里面。
在 ARM 汇编语言程序里,有一些特殊指令助记符,这些助记符与指令系统的助记符不同,没有相对应的操作码,通常称这些特殊指令助记符为伪指令,他们所完成的操作称为伪操作。
伪指令在源程序中的作用是为完成汇编程序作各种准备工作的,这些伪指令仅在汇编过程中起作用,一旦汇编结束,伪指令的使命就完成。
在 ARM 的汇编程序中,有如下几种伪指令:符号定义伪指令、数据定义伪指令、汇编控制伪指令、宏指令以及其他伪指令。
符号定义( Symbol Definition )伪指令符号定义伪指令用于定义 ARM 汇编程序中的变量、对变量赋值以及定义寄存器的别名等操作。
常见的符号定义伪指令有如下几种:—用于定义全局变量的 GBLA 、 GBLL 和 GBLS 。
—用于定义局部变量的 LCLA 、 LCLL 和 LCLS 。
—用于对变量赋值的 SETA 、 SETL 、 SETS 。
—为通用寄存器列表定义名称的 RLIST 。
1、 GBLA、GBLL 和GBLS语法格式:GBLA ( GBLL 或 GBLS )全局变量名GBLA 、 GBLL 和 GBLS 伪指令用于定义一个 ARM 程序中的全局变量,并将其初始化。
其中:GBLA 伪指令用于定义一个全局的数字变量,并初始化为 0 ;GBLL 伪指令用于定义一个全局的逻辑变量,并初始化为 F (假);GBLS 伪指令用于定义一个全局的字符串变量,并初始化为空;由于以上三条伪指令用于定义全局变量,因此在整个程序范围内变量名必须唯一。
使用示例:GBLA Test1 ;定义一个全局的数字变量,变量名为 Test1Test1 SETA 0xaa ;将该变量赋值为 0xaaGBLL Test2 ;定义一个全局的逻辑变量,变量名为 Test2Test2 SETL ;将该变量赋值为真GBLS Test3 ;定义一个全局的字符串变量,变量名为 Test3Test3 SETS “ Testing ”;将该变量赋值为“ Testing ”2、 LCLA、LCLL 和LCLS语法格式:LCLA ( LCLL 或 LCLS )局部变量名LCLA 、 LCLL 和 LCLS 伪指令用于定义一个 ARM 程序中的局部变量,并将其初始化。
嵌入式系统原理与应用常用Arm汇编伪指令
常用Arm汇编伪指令
在Arm汇编语言程序中,有一些特殊指令用于对汇编过程进行控制,这些指令不是可执行指令也没有对应的机器码,只用于汇编过程中为汇编程序提供汇编信息,这些指令称为伪指令,它们所完成的操作称为伪操作。
常用的伪指令有以下几种:符号定义伪指令、数据定义伪指令、汇编控制伪指令、信息报告伪指令以及杂项伪指令。
下面列出了上述几种常用的Arm汇编伪指令。
1. 符号定义伪指令
符号定义伪指令用于定义汇编程序中的变量、对变量赋值以及定义寄存器别名等操作。
表2.1 符号定义伪指令
2. 数据定义伪指令
数据定义伪指令一般用于为特定的数据分配存储单元,并可对分配的存储单元进行初始化。
表2.2 数据定义伪指令
3. 汇编控制伪指令
汇编控制伪指令用于控制汇编程序的执行流程。
表2.3 汇编控制伪指令
4. 信息报告伪指令
报告伪指令用于汇编报告指示。
表2.4 信息报告伪指令
5. 杂项伪指令
杂项伪指令是未包含在表2.1至2.4中且在汇编程序设计中常用的伪指令。
表2_5 杂项伪指令。
第4章 ARM程序设计基础-伪指令2
操作结果为{FALSE}或{TRUE}
Assemble Language of ARM
17
3、 字符串表达式及运算符
第4章 ARM程序设计基础
4.2 汇编语言的语句格式
ARM(Thumb)汇编语言的语句格式为: {标号} {指令或伪指令} {;注释} 标号必须从一行的行头开始,并且符号中不能包含空格。 指令不能从一行的行头开始,即在一行语句中,指令的前面必须有 空格或者标号。 在汇编语言程序设计中,每一条指令的助记符可以全部用大写、或 全部用小写,但不允许在一条指令中大、小写混用。 寄存器可以大写或小写。 伪指令有些必须在一行的开头顶格书写,另外一些必须留有空格。 注释以分号“;”开头,到行末结束。 如果一条语句太长,可将该长语句分为若干行来书写,在行的末尾 用“\”表示下一行与本行为同一条语句。 在源程序中,语句之间可以插入空行,增强可读性。
Assemble Language of ARM 8
变量替换的特殊情况: 如果需要字符$,则用$$来表示。 包含在两个竖线(|)之间的$不进行变量替换,但如果竖线是 在双引号内,则将进行变量替换。 使用“.”来表示变量名称的结束。
例如 STR1
SETS
“STRING”
STR2
SETS
X X X X X X X
= Y > Y < Y >= Y <= Y /= Y <> Y
;表示X等于Y ;表示X大于Y ;表示X小于Y ;表示X大于等于Y ;表示X小于等于Y ;表示X不等于Y ;表示X不等于Y
ARM汇编语言伪指令
ARM汇编语言伪指令ARM汇编语言伪指令ARM中伪指令不是真正的ARM指令或者Thumb指令,这些伪指令在汇编编译时对源程序进行汇编处理时被替换成对应的ARM或Thumb指令(序列)。
ARM伪指令包括ADR、ADRL、LDR和NOP等。
1、ADR(小范围的地址读取伪指令)该指令将基于PC的地址值或基于寄存器的地址值读取到寄存器中。
语法格式ADR{cond} register, expr其中,cond为可选的指令执行的条件register为目标寄存器expr为基于PC或者基于寄存器的地址表达式,其取值范围如下:当地址值不是字对齐时,其取值范围为-255~255.当地址值是字对齐时,其取值范围为-1020~1020当地址值是16字节对齐时,其取值范围将更大在汇编编译器处理源程序时,ADR伪指令被编译器替换成一条合适的指令。
通常,编译器用一条ADD指令或SUB指令来实现该ADR伪指令的功能。
因为ADR伪指令中的地址是基于PC或者基于寄存器的,所以ADR读取到的地址为位置无关的地址。
当ADR伪指令中的地址是基于PC时,该地址与ADR伪指令必须在同一个代码段中。
示例start MOV r0,#10 ;因为PC值为当前指令地址值加8字节ADR r4, start ;本ADR伪指令将被编译器替换成SUB r4,pc,#0xc2、ADRL(中等范围的地址读取伪指令)该指令将基于PC或基于寄存器的地址值读取到寄存器中。
ADRL伪指令比ADR伪指令可以读取更大范围的地址。
ADRL伪指令在汇编时被编译器替换成两条指令,即使一条指令可以完成该伪指令的功能。
语法格式ADRL{cond} register,expr示例start MOV r0,#10 ;因为PC值为当前指令地址值加8字节ADRL r4,start+60000 ;本ADRL伪指令将被编译器替换成下面两条指令ADD r4,pc,#0xe800ADD r4,r4,#0x2543、LDR(大范围的地址读取伪指令)LDR伪指令将一个32位的常数或者一个地址值读取到寄存器中语法格式LDR{cond} register, =[expr|label-expr]其中,expr为32位的常量。
四、ARM汇编语言伪指令
字节对准。例如,expression等于10,该段将按1KB对
准。 • CODE 代码段,缺省为READONLY • COMDEF 通用段定义。该段可包括代码和数据,在多 个源文件中同名的COMDEF段必须相同 • COMMON 通用数据段,不能定义任何代码和数据, 通常由链接器初始化为零
TM
12
指导性伪指令
(1)AREA
• DATA 包含数据,但不包含指令,缺省READWRIT。 • INTERWORK 表明代码段可以适用ARM/Thumb
interworking功能。
• NOINIT 表明数据段初始化为零,只为指示符保留空间 • READONLY 表明该段只读。 • READWRITE 表明该段可读可写。
Development Suite (简称RVDS) 的编译器RVCT
与Keil的工程管理、调试仿真工具集成在一起,是 一款非常强大的ARM 微控制器开发工具。
TM
4
2. GNU ARM开发工具
GNU是“GNU„s Not Unix”的递归缩写。在1983年
9月27日由Richard Stallman公开发起GNU计划,
TM
16
数据定义伪指令
(1)DATA 定义此标号是程序内的数据区
例: Thumb-fn AREA example ,CODE ; ; MOV pc ,lr
Thumb-Data
DATA
DCB 1,3,4
TM
17
数据定义伪指令
(2)DCB或“=”
功能:分配一个或多个字节.
(3)DCD或“&” 功能:分配一个或多个字,从4个字节边界开始. (4)DCW 功能:分配一个或多个半字以半字边界开始的内存 区域.
ARM汇编语言伪指令
ARM汇编语言伪指令ARM汇编语言伪指令ARM汇编语言ARM汇编语言源程序语句,一般由指令,伪操作,宏指令和伪指令作成.ARM汇编语言的设计基础是汇编伪指令,汇编伪操作和宏指令.伪操作,是ARM汇编语言程序里的一些特殊的指令助记符,其作用主要是为完成汇编程序做各种准备工作,在源程序运行汇编程序处理,而不是在计算机运行期间有机器执行.也就是说,这些伪操作只是汇编过程中起作用,一旦汇编结束,伪操作的使命也就随之消失.宏指令,是一段独立的程序代码,可以插在程序中,它通过伪操作来定义,宏在被使用之前必须提前定义好,宏之间可以互相调用,也可自己递归调用.通过直接书写宏名来使用宏.并本具宏指令的格式输入输出参数.宏定义本身不产生代码,只是在调用它时把宏体插入到原程序中.宏与C语言中的子函数形参和实参的调用相似,调用宏时通过实际的指令来代替宏体实现相关的一段代码,但宏的调用与子程序的调用有本质的区别,既宏并不会节省程序的空间,其优点是简化程序代码,提高程序的可读性以及宏内容可以同步修改.伪操作,宏指令一般与编译程序有关,因此ARM汇编语言的伪操作,宏指令在不同的编译环境下有不同的编写形式和规则.伪指令也是ARM汇编语言程序里的特殊助记符,也不在处理器运行期间由机器执行,他们在汇编时将被合适的机器指令代替成ARM或Thumb指令,从而实现真正的指令操作.目前常用的ARM编译环境有2种.1. ADS/SDT IDE:ARM公司开发,使用了CodeWarrior公司的编译器.2. 集成了GNU开发工具的IDE开发环境;它由GNU的汇编器as,交叉汇编器gcc和连接器id组成.ADS编译环境下的ARM伪操作和宏指令,可参考北航出版社的<<ARM微控制器基础与实践》(周立功)这里主要讲述ARM GNU常用汇编语言4 ARM GNU常用汇编语言介绍4.1 ARM GNU常用汇编伪指令介绍1. abort.abort: 停止汇编.align absexpr1,absexpr2:以某种对齐方式,在未使用的存储区域填充值. 第一个值表示对齐方式,4, 8,16或32. 第二个表达式值表示填充的值.2. if...else...endif.if.else.endif: 支持条件预编译3. include.include "file": 包含指定的头文件, 可以把一个汇编常量定义放在头文件中.4. comm.comm symbol, length:在bss段申请一段命名空间,该段空间的名称叫symbol, 长度为length. Ld连接器在连接会为它留出空间.5. data.data subsection: 说明接下来的定义归属于subsection数据段.6. equ.equ symbol, expression: 把某一个符号(symbol)定义成某一个值(expression).该指令并不分配空间.7. global.global symbol: 定义一个全局符号, 通常是为ld使用.8. ascii.ascii "string": 定义一个字符串并为之分配空间.9. byte.byte expressions: 定义一个字节, 并为之分配空间.10. short.short expressions: 定义一个短整型, 并为之分配空间.11. int.int expressions: 定义一个整型,并为之分配空间.12 long.long expressions: 定义一个长整型, 并为之分配空间.13 word.word expressions: 定义一个字,并为之分配空间, 4bytes.14. macro/endm.macro: 定义一段宏代码, .macro表示代码的开始, .endm表示代码的结束.15. reqname .req register name: 为寄存器定义一个别名.16. code.code [16|32]: 指定指令代码产生的长度, 16表示Thumb指令, 32表示ARM指令.17. ltorg.ltorg: 表示当前往下的定义在归于当前段,并为之分配空间.4.2 ARM GNU专有符号1. @表示注释从当前位置到行尾的字符.2. #注释掉一整行.3. ;新行分隔符.4.3 操作码1. NOPnop空操作, 相当于MOV r0, r02. LDRldr <register> , = <expression>相当于PC寄存器或其它寄存器的长转移.3.ADRadr <register> <label>相于PC寄存器或其它寄存器的小范围转移. ADRLadrl <register> <label>相于PC寄存器或其寄存器的中范围转移.5 可执行生成说明5.1 lds文件说明5.1.1 主要符号说明1. OUTPUT_FORMAT(bfdname)指定输出可执行文件格式.2. OUTPUT_ARCH(bfdname)指定输出可执行文件所运行CPU平台3. ENTRY(symbol)指定可执行文件的入口段5.1.2 段定义说明1. 段定义格式SECTIONS { ...段名 :{内容}...}文章出处:。
ARM汇编伪指令
ARM汇编伪指令在ARM汇编语言源程序中有些特殊助记符,它们没有相对应的操作码或者机器码,通常称为伪指令,它们所完成的操作称为伪操作。
伪指令在源程序中的作用是为完成汇编程序作各种准备工作的,由汇编程序在源程序的汇编期间进行处理,仅在汇编过程中起作用。
在ARM的汇编程序中,有以下几种伪指令:符号定义伪指令、数据定义伪指令、汇编控制伪指令、宏指令以及其他伪指令。
一、符号定义伪指令作用:用于定义ARM汇编程序中的变量、对变量赋值以及定义寄存器的别名等。
符号定义有如下几种伪指令:用于定义局部变量的LCLA、LCLL和LCLS。
用于定义全局变量的GBLA、GBLL和GBLS。
用于对变量赋值的SETA、SETL和SETS。
为通用寄存器列表定义名称的RLIST。
(1)LCLA、LCLL和LCLS格式:LCLA/LCLL/LCLS 局部变量名说明:LCLA、LCLL和LCLS伪指令用于定义一个汇编程序中的局部变量并初始化。
其中:LCLA定义一个局部的数字变量,初始化为0。
LCLL定义一个局部的逻辑变量,初始化为F。
LCLS定义一个局部的字符串变量,初始化为空串。
这3条伪指令用于声明局部变量,在其局部作用范围内变量名必须惟一,例如在宏内。
例:LCLA num1 ;定义一个局部数字变量,变量名为num1 LCLL I2 ;定义一个逻辑变量,变量名为I2LCLS str3 ;定义一个字符串变量,变量名为str3num1 SETA 0xabcd ;将该变量赋值为0xabcdI2 SETL {FALSE} ;将该变量赋值为真str3 SETS “HELLO”;将该变量赋值为“HELLO”(2)GBLA、GBLL和GBLS格式:GBLA/GBLL/GBLS 变量名说明:GBLA、GBLL和GBLS伪操作定义一个汇编程序中的全局变量并初始化。
其中:GBLA定义一个全局数字变量,并初始化为0。
GBLL定义一个全局逻辑变量,并初始化为F。
arm伪操作-伪指令-宏指令
可通过下面的 指令访问数据结构中的信息: LDR R0, b ;LDR R0, Datastruc+4
例:判断当前内存的使用情况是否超过程序 分配的可用内存的方法。
startofmem EQU 1000 ;分配内存首地址 endofmem EQU 2000 ;分配内存末地址 MAP startofmem ;内部首地址为startofmem a FIELD 4 ;字段a长度为4,相对位置为0 b FIELD 4 ;字段b长度为4,相对位置为4 x FIELD 8 ;字段x长度为8,相对位置为8 y FIELD 8 ;字段y长度为8,相对位置为16 s FIELD max ;字段s长度为max,相对位置为24 endofstru ASSERT FIELD 0 ;endofstru用于检查内存是否越界
1.1.1两种常见的ARM编译开发环境
ADS/SDT IDE开发环境:它由ARM公司开 发,使用了CodeWarrior公司的编译器; EmbestIDE开发环境:集成了GNU开发工具 的IDE开发环境,由GNU的汇编器as、交叉 编译器gcc、和链接器ld等组成。 这两种开发环境的编译器都完全支持ARM 指令集,但伪指令不同,代码风格不同。
数据定义伪操作
LTORG:声明一个数据缓冲池的开始。 SPACE:分配一块内存单元,并用0初始化。 MAP:定义一个结构化的内存表的首地址。 FIELD:定义结构化内存表中的一个数据域。 DCB:分配一段字节内存单元,并初始化。 DCD、DCDU:分配一段字内存单元,并初始 化。
1、 LTORG 用于声明一个数据缓冲池(文字池)的开始。 语法格式:
LTORG 例:start BL func …… func LDR R1,=0x8000 …… MOV PC,LR LTORG Data SPACE 4200 END 默认数据缓冲池为空
第6章 ARM汇编伪指令与伪操作(2)
TM
35
35
6.4.3汇编与反汇编代码控制伪操作
指令集类型标识伪操作
.arm
.code 32
.thumb .code 16
TM
36
36
示例解析
此示例演示从32位的 ARM 指令跳转到 16 位 Thumb 指令: .arm _start: ADR R0, into_thumb + 1 BX R0 Thumb状态 … … @通知编译器其后的指令为16位的Thumb指令 @处理器当前处理ARM 状态 @程序跳转到into_thumb并使处理器切换到 @ 通知编译器其后的指令为32位的ARM指令
.org 0x1000 , 0xAA
TM
43
43
6.4.4预定义控制伪操作
汇编器在对程序代码进行编译时,会根据汇 编控制伪操作的定义情况对程序进行编译, 常用的有条件编译、宏定义和文件包含
TM
44
44
1.条件编译伪操作.if
语法格式:
.if logical_expression
TM
50
50
思考与练习题
MOV
R0,
#0x0F
…
…
编译时会出错
TM
8
8
3.声明全局常量伪操作.global或.globl
语法格式:
.global symbol .globl symbol
其中:
symbol 为要声明的全局变量名称
TM
99示例解析 声明全局变量MAIN .global start 也可以用.globl来实现:
ARM汇编器所支持的伪指令
MEXIT用于从宏定义中跳转出去。
其他常用的伪指令
AREA段名属性1,属性2,……
AREA伪指令用于定义一个代码段或数据段。其中,段名若以数字开头,则该段名需用“|”括起来,属性字段表示该代码段(或数据段)的相关属性,多个属性用逗号分隔。常用的属性如下:CODE属性:用于定义代码段,默认为READONLY。DATA属性:用于定义数据段,默认为READWRITE。READONLY属性:指定本段为只读,代码段默认为READONLY。READWRITE属性:指定本段为可读可写,数据段的默认属性为READWRITE。ALIGN属性:使用方式为ALIGN表达式。在默认时,ELF(可执行连接文件)的代码段和数据段是按字对齐的,表达式的取值范围为0~31,相应的对齐方式为2表达式次方。COMMON属性:该属性定义一个通用的段,不包含任何的用户代码和数据。各源文件中同名的COMMON段共享同一段存储单元。
当前位置的对齐方式为:2的表达式次幂+偏移量。
AREA Init,CODE,READONLY,ALIEN=3;指定后面的指令为8
;字节对齐。
指令序列
END
CODE16
(或CODE32)
CODE16伪指令通知编译器,其后的指令序列为16位的Thumb指令。CODE32伪指令通知编译器,其后的指令序列为32位的ARM指令。若在汇编源程序中同时包含ARM指令和Thumb指令时,可用CODE16伪指令通知编译器其后的指令序列为16位的Thumb指令,CODE32伪指令通知编译器其后的指令序列为32位的ARM指令。因此,在使用ARM指令和Thumb指令混合编程的代码里,可用这两条伪指令进行切换,但注意他们只通知编译器其后指令的类型,并不能对处理器进行状态的切换。
ARM·汇编伪指令
ARM·汇编伪指令在ARM 汇编程序中,有如下几种伪指令*符号定义伪指令*数据定义伪指令*汇编控制伪指令*信息报告伪指令*宏指令以及其他伪指令【符号定义伪指令】定义局部变量LCLA,LCLL,LCLS 定义全局变量GBLA,GBLL,GBLS对变量赋值SETA,SETL,SETS【数据定义伪指令】DCBDCW/DCWUDCD/DCDUDCQ/DCDUDCFS/DCFSUDCFD/DCFDUSPACEF IELDMAP*DCB 表达式用于分配一片连续的字节*DCW/DCWU 表达式用于分配一片连续的半字*DCD/DCDU 表达式用于分配一篇连续的字*DCQ/DCQU 表达式用于分配连续的8 个字节*DCFD/DCFDU 表达式用于为双精度浮点数分配一片连续的字存储单元*DCFS/DCFSU 表达式用于为单精度浮点数分配一片连续的字存储单元*SPACE 表达式用于分配一片连续的存储区域并初始化为0,表达式是要分配的字节数*MAP FILEDMAP 定义一个结构化的内存表的首地址[MAP 0x100, R0] 首地址0x100+R0FILED 定义一个结构化内存表中的数据域[MAP 0x30000000A FILED 4B FILED 4C FILED 4] 【汇编控制伪指令】*MACRO MEND 宏名*IF---ELSE---ENDIF [ | ]*WHILE---- WEND*NEXIT 从宏中退出【一些其他的伪指令】*ASSERT 逻辑表达式必须满足这一条件才可以进行编译*ALIGN [表达式[,偏移量]]AREA Init, CODE, READONLY, ALIGN=3*AREA 段名属性DATA 数据段默认READWRITECODE 代码段默认READONLY*NOINIT 内存单元初始化0*ALIGN*COMMON 通用段(不包括数据段和代码段)*ENTRY*END*EQU (NUM EQU 100)(相当于c 语言中的#define)*EXPORT 声明一个全局变量IMPORT IMPORT Main (引用Main 变量,但Main 不是在这个程序中定义的)EXPORT 和IMPORT 一样,但是源文件中若没有引用,则该标号。
第4章 ARM伪指令
用DCFS伪指令分配的字存储单元是字对齐的,而用DCFSU伪指 令分配的字存储单元并不严格要求字对齐。
(9)DCQ(或DCQU)伪指令
DCQ(或DCQU)伪指令用于分配一片以8字节为单位的连续存 储区域,并用伪指令中指定的表达式初始化。其语法格式如下。
4.3.2 定义寄存器列表伪指令
LDM/STM指令需要使用一个比较长的寄存器列表,使用伪指令 RLIST可对一个列表定义一个统一的名称。其格式如下。 <Name> RLIST <{List}>
4.3.3 数据定义伪指令
(1)LTORG伪指令 LTORG伪指令用来说明某个存储区域为一个用来暂存数据的数
<Label> DCQ(或DCQU) <Expr>
用DCQ伪指令分配的存储单元是字对齐的,而用DCQU分配的字 存储单元并不严格要求字对齐。
(10)DCW(或DCWU)伪指令
DCW(或DCWU)伪指令用于为数据分配一片连续的半字存储单 元,并用表达式对其进行初始化。
<Label> DCW(或DCWU) <Expr>
(1)近地址读取宏指令ADR ADR宏指令用于将一个近地址值传递到一个寄存器中,指令格
式如下。 ADR{Cond} <Reg>, <Expr> Reg为目标寄存器名称。 Expr为表达式。该表达式通常在一个程序中表示一条指令存储
位置的地址标号。
该宏指令的功能是把标号所表示的地址传递到目标寄存器中。 汇编器在汇编时,将把ADR宏指令替换成一条真正的ADD或SUB指令, 将当前的PC值减去或加上Expr与PC之间的偏移量得到标号的地址, 并将其传输到目标寄存器。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
ARM汇编语言伪指令ARM汇编语言伪指令ARM中伪指令不是真正的ARM指令或者Thumb指令,这些伪指令在汇编编译时对源程序进行汇编处理时被替换成对应的ARM或Thumb指令(序列)。
ARM伪指令包括ADR、ADRL、LDR和NOP等。
1、ADR(小范围的地址读取伪指令)该指令将基于PC的地址值或基于寄存器的地址值读取到寄存器中。
语法格式ADR{cond} register, expr其中,cond为可选的指令执行的条件register为目标寄存器expr为基于PC或者基于寄存器的地址表达式,其取值范围如下:当地址值不是字对齐时,其取值范围为-255~255.当地址值是字对齐时,其取值范围为-1020~1020当地址值是16字节对齐时,其取值范围将更大在汇编编译器处理源程序时,ADR伪指令被编译器替换成一条合适的指令。
通常,编译器用一条ADD指令或SUB指令来实现该ADR伪指令的功能。
因为ADR伪指令中的地址是基于PC或者基于寄存器的,所以ADR读取到的地址为位置无关的地址。
当ADR伪指令中的地址是基于PC时,该地址与ADR伪指令必须在同一个代码段中。
示例start MOV r0,#10 ;因为PC值为当前指令地址值加8字节ADR r4, start ;本ADR伪指令将被编译器替换成SUB r4,pc,#0xc2、ADRL(中等范围的地址读取伪指令)该指令将基于PC或基于寄存器的地址值读取到寄存器中。
ADRL伪指令比ADR伪指令可以读取更大范围的地址。
ADRL伪指令在汇编时被编译器替换成两条指令,即使一条指令可以完成该伪指令的功能。
语法格式ADRL{cond} register,expr示例start MOV r0,#10 ;因为PC值为当前指令地址值加8字节ADRL r4,start+60000 ;本ADRL伪指令将被编译器替换成下面两条指令ADD r4,pc,#0xe800ADD r4,r4,#0x2543、LDR(大范围的地址读取伪指令)LDR伪指令将一个32位的常数或者一个地址值读取到寄存器中语法格式LDR{cond} register, =[expr|label-expr]其中,expr为32位的常量。
编译器将根据expr的取值情况,如下处理LDR伪指令:当expr表示的地址值没有超过MOV或MVN指令中地址的取值范围时,编译器用合适的MOV或MVN指令代替该LDR伪指令当expr表示的地址值超过了MOV或者MVN指令中地址的取值范围时,编译器将该常数放在数据缓冲区中,同时用一条基于PC的LDR指令读取该常数。
label-expr为基于PC的地址表达式或者是外部表达式。
当label-expr为基于PC的地址表达式时,编译器将label-expr表示的数值放在数据缓冲区(literal pool)中,然后将该LDR伪指令处理成一条基于PC到该数据缓冲区单元的LDR指令,从而将该地址值读取到寄存器中。
这时,要求该数据缓冲区单元到PC的距离小于4KB。
当label-expr为外部表达式,或者非当前段的表达式时,汇编编译器将在目标文件中插入一个地址重定位伪操作,这样连接器将在连接时生成该地址。
LDR伪指令主要有以下两种用途:当需要读取到寄存器中的数据超过了MOV及MVN指令可以操作的范围时,可以使用LDR 伪指令将该数据读取到寄存器中。
将一个基于PC的地址值或者外部的地址值读取到寄存器中。
由于这种地址值是在连接时确定的,所以这种代码不是位置无关的。
同时LDR伪指令的PC值到数据缓冲区中的目标数据所在的地址的偏移量要小于4KB。
示例将0xff0读取到R1中LDR R1,=0xFF0汇编后将得到:MOV R1,0xFF0将0xfff读取到R1中LDR R1,=0xFFF汇编后将得到:LDR R1,[PC,OFFSET_TO_LPOOL]…LPOOL DCD 0xFFF将外部地址ADDR1读取到R1中LDR R1,=ADDR1汇编后将得到:LDR R1,[PC,OFFSET_TO_LPOOL]…LPOOL DCD ADDR14、NOP空操作伪指令在汇编时将被替换成ARM中的空操作,如MOV R0,R0NOP伪指令不影响CPSR中的条件标志位ARM汇编程序中的符号在ARM汇编语言中,符号(symbols)可以代表地址(addresse)、变量(variables)和数字常量(numeric constants)。
当符号代表地址时,又称为标号(lable)。
当标号以数字开头时,其作用范围为当前段(当前段没有使用ROUT伪操作时),这种标号又称为局部标号(lacal lable)。
符号变量包括变量、数字常量、标号和局部标号。
1、变量在程序中,变量的值在汇编处理过程中可能会发生改变。
在ARM汇编中变量有数字变量、逻辑变量和串变量3种类型。
变量的类型在程序中是不可以改变的。
数字变量的取值范围为数字常量和数字表达式所能表示的数值;逻辑变量的取值范围为{true}和{flash};串变量的取值范围为串表达式可以表达的范围。
在ARM汇编语言中,使用GBLA、GBLL及GBLS声明全局变量;使用LCLA、LCLL及LCLS声明局部变量;使用SETA、SETL及SETS为这些变量赋值。
2、数字常量数字常量是32位的整数。
在ARM汇编语言中,使用EQU来定义数字常量。
数字常量一经定义就不可修改。
进行大小比较时,认为数字常量都是无符号数。
3、汇编时变量的替换如果在串变量前有一个$字符,在汇编时编译器将用改串的数值来取代该串变量。
对于数字变量来说,如果该变量前面有一个$字符,在汇编时编译器将该数字变量的数值转换成十六进制的串,然后用该十六进制的串取代$字符后的数字变量。
对于逻辑变量来说,如果该逻辑变量前面有一个$字符,在汇编时编译器将该逻辑变量替换成它的取值(T或者F)如果程序中需要字符$,则用$$来表示,编译器将不进行变量替换,而是将$$当作$.通常情况下,包含在两个竖线(|)之间的$并不表示进行变量替换。
但是如果竖线(|)是在双引号内,则将进行变量替换。
使用“.”来表示变量名称的结束。
4、标号标号是表示程序中的指令或者数据地址的符号。
根据标号的生成方式可分为3种:基于PC的标号。
基于PC的标号是位于目标指令前或者程序中数据定义伪操作前的标号。
这种标号在汇编时将被处理成PC值加上(或减去)一个数字常量。
常用于表示跳转指令的目标地址,或者代码段中所嵌入的少量数据。
基于寄存器的标号。
基于寄存器的标号常用MAP和FIELD未定义操作,也可以该用EQU 伪定义。
这种标号在汇编时将被处理成寄存器的值加上(或减去)一个数据常量。
常用于访问数据段中的数据。
绝对地址。
绝对地址是一个32位数据。
它可以寻址232 -1,即直接可以寻址整个内存空间。
5、局部标号局部标号主要在局部范围内使用。
它由两部组成:开头是一个0-99直接的数字,后面紧接一个通常表示该局部变量作用范围的符号。
局部变量的作用范围通常为当前段,也可以用伪操作ROUT来定义局部变量的作用范围。
局部变量定义的语法格式如下:N{routname},其中,N为0~99之间的数字。
routname为符号,通常为该变量作用范围的名称(用ROUT伪操作定义的)。
局部变量引用的语法格式如下:%{F|B}{A|T}N{routname}其中,N为局部变量的数字号。
routname 为当前作用范围的名称(用ROUT伪操作定义的)%表示引用操作F指示编译器只向前搜索B指示编译器只向后搜索A指示编译器搜索宏的所有嵌套层次T指示编译器搜索宏的当前层次如果F和B都没有指定,编译器先向前搜索,再向后搜索如果A和T都没有指定,编译器搜索所有从当前层次到宏的最高层次,比当前层次低的层次不再搜索。
如果指定了routname,编译器向前搜索最近的ROUT伪操作,若routname与该ROUT 伪操作定义的名称不匹配,编译器报告错误,汇编失败。
ARM汇编语言中的表达式表达式是由符号、数值、单目或多目操作符以及括号组成的。
1、字符串表达式字符串表达式由字符串、字符串变量、操作符以及括号组成。
字符串的最大长度为512字节,最小长度为0.下面介绍字符串表达式的组成元素。
字符串:由包含在双引号内的一系列的字符组成。
字符串的长度受到ARM汇编语言语句长度的限制。
当在字符串中包含美元符号$或者引号"时,用$$表示一个$,用""表示一个"。
字符串变量:用伪操作GBLS或者LCLS声明,用SETS赋值。
操作符:(1)LEN:返回字符串的长度:LEN:A其中,A为字符串变量(2)CHR:可以将0~255之间的整数作为含一个ASCII字符的字符串。
当有些ASCII字符不方便放在字符串中时,可以使用CHR将其放在字符串表达式中。
:CHR:A其中,A为某一字符的ASCII值(3)STR:将一个数字量或者逻辑表达式转换成串。
对于32位的数字量而言,STR将其转换成8个十六进制数组成的串;对于逻辑表达式而言,STR将其转换成字符串T或者F:STR:A其中,A为数字量或者逻辑表达式(4)LEFT:返回一个字符串最左端一定长度的子串A:LEFT:B其中,A为源字符串,B为数字量,表示LEFT将返回的字符个数(5)RIGHT:返回一个字符串最右端一定长度的子串A:RIGHT:B其中,A为源字符串,B为数字量,表示RIGHT将返回的字符个数(6)CC:用于连接两个字符串。
A:CC:B其中,A为第1个源字符串。
B为第2个源字符串。
CC操作符将字符串B连接在字符串A 的后面。
2、数字表达式数字表达式由数字常量、数字变量、操作符和括号组成数字变量用伪操作GBLA或者LCLA声明,用SETA赋值,它代表一个32位的数字量。
操作符:(1)NOT:按位取反:NOT:A其中,A为一个32位数字量(2)+、—、×、/及MOD算术操作符A+B,A-B,A×B,A/BA:MOD:B表示A除以B的余数(3)ROL,ROR,SHL,SHR移位A:ROL:B将整数A循环左移B位A:SHL:B将整数A左移B位(4)AND、OR及EOR按位逻辑操作符A:AND:B将数字表达式A和B按位作逻辑与操作3、基于寄存器和基于PC的表达式基于寄存器的表达式表示了某个寄存器的值加上(或者减去)一个数字表达式基于PC的表达式表示了PC寄存器的值加上(或减去)一个数字表达式。
基于PC的表达式通常由程序中的标号与一个数字表达式组成。
相关的操作符:(1)BASE:返回基于寄存器的表达式中的寄存器编号。
:BASE:A A为基于寄存器的表达式(2)INDEX:返回基于寄存器的表达式相对于其基址寄存器的偏移量。
:INDEX:A A为基于寄存器的表达式(3)+、﹣:正负号,可以放在数字表达式或者基于PC的表达式前面。