ARM汇编伪指令宏的用法详解_MACRO-MEND_.
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来包含可执行文件、文字或 其他数据。
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状态。
第一讲伪操作、宏指令与伪指令
三、ADS环境下的伪操作和宏指令
➢ADS编译环境下的伪操作可分为以下几类:
符号定义(Symbol Definition)伪操作 数据定义(Data Definition)伪操作 汇编控制(Assembly Control)伪操作 信息报告(Reporting)伪操作 其他(Miscellaneous)伪操作
IMPORT symbol {[WEAK]} EXTERN symbol {〔WEAK〕} GET
告诉编译器当前的符号不是在本源文件中定义的,而是在其他源文件中定义的,在本源 文件中可能引用该符号。
告诉编译器当前的符号不是在本源文件中定义的,而是在其他源文件中定义的,在本源 文件中可能引用该符号。
将一个源文件包含到当前源文件中,并将被包含的文件在其当前位置进行汇编处理。
化 • .hword 21,25,89,0x1133,0x77FF • .short 236,0xF4F
第一讲伪操作、宏指令与伪指令
常量编译控制伪操作 • .ascii • .ascii expr {,expr}….. • 定义字符串expr(非零结束符) • .ascii “How are you” • /*不是以“/0”结束*/
CP
name CP expr
为一个协处理器定义名称。
DN/SN FN
name DN/SN expr name FN expr
DN/SN为一个双精度/单精度的VFP寄存器定义名称。 第一讲伪操作、宏指令与伪指令
为一个FPA浮点寄存器定义名称。
数据定义伪操作
伪操作 LTORG
语法格式 LTORG
作用 声明一个数据缓冲池(也称为文字池)的开始。
伪操作
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
ARM GUN 伪指令
1.宏定义.macro 宏名 参数名列表 @伪指令.macro定义一个宏宏体.endm @.endm表示宏结束如果宏使用参数,那么在宏体中使用该参数时添加前缀“\”。
宏定义时的参数还可以使用默认值。
可以使用.exitm伪指令来退出宏。
2.段定义section伪操作用户可以通过.section伪操作来自定义一个段,格式如下:.section section_name [, "flags"[, %type[,flag_specific_arguments]]]flag的值为 a 允许段 w 可写段 x 执行段预定义的段名 .text @代码段 .data @初始化数据段 .bss @未初始化数据段定义入口点 :.globl _start_start:注意: 源程序中.bss段应该在.text之前当用预定义段名可以直接使用,当是自定义时段定义要完整。
3.数据定义伪操作: .byte 1b,.short 2b,.long 4b,.quad 8b,.float,.string/.asciz/. ascii,重复定义伪操作.rept,赋值语句.equ/.set注意:.ascii伪操作定义的字符串需要自行添加结尾字符'\0'4. 函数定义伪操作:格式函数名:函数体返回语句一般的,函数如果需要在其他文件中调用, 需要用到.global伪操作将函数声明为全局函数。
为了不至于在其他程序在调用某个C函数时发生混乱,对寄存器的使用我们需要遵循APCS准则。
函数编译器将处理为函数代码为一段.global的汇编码。
5.常数1)十进制数以非0数字开头,如:123和9876;2)二进制数以0b开头,其中字母也可以为大写;3)八进制数以0开始,如:0456,0123;4)十六进制数以0x开头,如:0xabcd,0X123f;5)字符串常量需要用引号括起来,中间也可以使用转义字符,如: "You are welcome!\n";6)当前地址以"."表示,在汇编程序中可以使用这个符号代表当前指令的地址;7)表达式:在汇编程序中的表达式可以使用常数或者数值, "-"表示取负数, "~"表示取补,"<>"表示不相等,其他的符号如:+、-、*、/、%、<、<<、>、>>、|、&、^、!、==、>=、<=、&&、||跟C语言中的用法相似。
四、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 功能:分配一个或多个半字以半字边界开始的内存 区域.
第6章 ARM汇编伪指令与伪操作(1)
TM
全局变量定义GCLA、GCLL及GCLS 、 全局变量定义 及 语法格式 GCLA variable GCLL variable GCLS variable 其中: 其中: variable 所说明的全局变量名称。 所说明的全局变量名称。
TM
23
23
全局变量定义GCLA、GCLL及GCLS 、 全局变量定义 及
TM
SETA expr_a SETL expr_l SETS expr_s
26
26
其中 variable_a 算术变量.用GBLA,LCLA伪指令定义的 算术变量 用 伪指令定义的 变量.expr_a 赋值的常数. 变量 赋值的常数 variable_l 逻辑变量 用GBLL,LCLL伪指令定义的变量 逻辑变量.用 伪指令定义的变量 .expr_l 逻辑值 即{TRUE}或{FALSE}. 逻辑值,即 或 variable_s 字符串变量 用GBLS,LCLS伪指令定义的变量 字符串变量.用 伪指令定义的变量 .expr_s 赋值的字符串 赋值的字符串.
ARM公司推出的开发工具所支持的汇编伪操作包括符号定义 伪操作、数据定义伪操作、汇编信息报告控制伪操作、汇编 代码控制伪操作、文件包含伪操作、指令集类型标识伪操作 以及其他功能伪操作。
TM
19
19
符号定义伪操作
符号定义伪指令用于定义ARM汇编程序的变量,对变量进行赋值以及 定义寄存器名称,该类伪指令包括: 全局变量声明:GBLA,GBLL和GBLS 局部变量声明:LCLA,LCLL和LCLS 变量赋值: SETA,SETL和SETS : SETA,SETL SETS 为一个通用寄存器列表定义名称:RLIST 为一个协处理器的寄存器定义名称:CN 为一个协处理定义名称: CP 为一个VFP寄存器定义名称:DN和SN 为一个FPA浮点寄存器定义名称:FN
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中的宏定义
语法格式如下:MACRO [$ label] macroname{ $ parameter1,$ parameter,} 其他指令MEND MACRO 伪操作标识宏定义的开始,MEND 标
识宏定义的结束。
用MACRO 及MEND 定义一段代码,称为宏定义体,这样
在程序中就可以通过宏指令多次调用该代码段。
其中,$ label 在宏指令被展
开时,label 会被替换成相应的符号,通常是一个标号。
宏定义中的$label 是一
个可选参数,在一个符号前使用$表示程序被汇编时将使用相应的值来替代$后
的符号。
macroname 为所定义的宏的名称。
$parameter 为宏指令的参数。
当宏指令被展开时将被替换成相应的值,类似于函数中的形式参数,可以在宏定
义时为参数指定相应的默认值。
例如:
定义宏如下:
MACRO
$label TestBranch$dest, $reg, $cc
$label
CMP $reg,#0
B$cc $dest
MEND
调用宏的过程如下:
testTestBranch Nonzero,r0, NE
Nonzero
............
程序汇编后,宏展开如下:。
ARM汇编伪指令(计科)
S FIELD 256 ;定义S的长度为256 字节,位置为0x130
4.5.3 汇编控制伪指令
汇编控制伪指令用于控制汇编程序的执行流程, 常用的汇编控制伪指令包括以下几条:
— IF、ELSE、ENDIF — WHILE、WEND — MACRO、MEND — MEXITFra bibliotek
GBLS伪指令用于定义一个全局的字符串变量,并初始化为空;
由于是定义全局变量,因此在整个程序范围内变量名必须唯一。 GBLA Test1 ;定义一个全局的数字变量,变量名为Test1 Test1 SETA 0xaa;将该变量赋值为0xaa GBLL Test2;定义一个全局的逻辑变量,变量名为Test2 Test2 SETL {TRUE};将该变量赋值为真 GBLS Test3;定义一个全局的字符串变量,变量名为Test3 Test3 SETS “Testing”;将该变量赋值为“Testing ”
4.5.2 数据定义伪指令
1、DCB 语法格式:标号 DCB 表达式 DCB 伪指令用于分配一片连续的字节存储单元并用伪 指令中指定的表达式初始化。 其中,“标号”表示内存起始地址标号,“表达式” 可以为-0~255 的数字或字符串,同时,内存分配的 字节数由表达式决定。 DCB 也可用“=”代替。 Str DCB 0x33,0x45,0x12;分配一片连续的字节存储 单元并初始化。
4.5.3 汇编控制伪指令
1、 IF、ELSE、ENDIF 语法格式: IF 逻辑表达式 指令序列1 { ELSE 指令序列2 } ENDIF IF、ELSE、ENDIF根据条件的成立与否决定是否执行某个指令序列。 IF、ELSE、ENDIF伪指令可以嵌套使用。 GBLL Test ;声明一个全局的逻辑变量,变量名为Test .. IF Test = TRUE 指令序列1 ELSE 指令序列2 ENDIF
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 默认数据缓冲池为空
arm 汇编指令macro mend用法
ARM 汇编指令宏指令的使用方法一、ARM 汇编指令概述1. ARM 汇编指令是一种低级语言,用于编写嵌入式系统和嵌入式软件。
它是 ARM 处理器的指令集体系结构的一部分,可以直接控制处理器的行为。
2. ARM 汇编指令可以分为数据处理指令、分支指令、访存指令、特权指令等多种类型,其中宏指令是一种特殊的汇编指令,可以简化汇编语言的编写。
二、ARM 汇编宏指令概述1. ARM 汇编宏指令是一种用于编写汇编程序的高级语言结构,它可以通过宏展开的方式,将一组汇编指令替换成一个复杂的指令序列,从而提高程序的可读性和可维护性。
2. ARM 汇编宏指令在汇编程序中起到了类似函数的作用,可以实现代码的重用,降低了程序开发的难度。
三、ARM 汇编宏指令的基本语法1. ARM 汇编宏指令的语法包括宏定义和宏使用两个部分,宏定义用于定义一个宏指令,宏使用则用于在程序中使用定义好的宏指令。
2. ARM 汇编宏指令的基本语法如下:宏定义:.macro 宏名称参数列表宏内容.endm宏使用:宏名称参数列表四、ARM 汇编宏指令的定义与使用实例1. 定义一个简单的宏指令,用于实现两个寄存器的相加:.macro add_regs reg1, reg2, resultadd \result, \reg1, \reg2.endm2. 在程序中使用定义好的宏指令:mov r0, #1mov r1, #2add_regs r0, r1, r2五、ARM 汇编宏指令的高级用法1. 在实际的软件开发中,宏指令可以实现更加复杂的功能,例如实现循环、条件判断、异常处理等。
2. 通过合理的设计和使用宏指令,可以使汇编程序更加模块化和灵活,提高软件开发的效率和质量。
六、总结在 ARM 汇编程序中,宏指令是一种非常有用的工具,通过合理的设计和使用,可以使程序更加易读易维护,提高开发效率和质量。
掌握ARM 汇编宏指令的使用方法对于 ARM 汇编程序员来说是非常重要的一项技能。
ARM汇编伪指令MACR
MACRO伪操作标识宏定义的开始,MEND标识宏定义的结束。
用MACRO 及MEND定义一段代码,称为宏定义体,这样在程序中就可以通过宏指令多次调用该代码段语法格式MACRO{$label} macroname {$parameter {,$parameter}...};code...;codeMEND其中:$labelz在宏指令被展开时,label可被替换成相应的符号,通常是一个标号。
在一个符号前使用$标识程序被汇编时将使用相应的值来替代$后的符号Macroname为所定义的宏的名称$parameter为宏指令的参数。
当宏指令被展开时将被替换成相应的值,类似于函数中的形式参数。
可以在宏定义时为参数指定相应的默认值。
MACRO$HandlerLabel HANDLER $HandleLabel$HandlerLabelsub 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 r0ldr r0,[r0] ;load the contents(service routine start address) of HandleXXXstr 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 HandleFIQHandlerIRQ HANDLER HandleIRQHandlerUndef HANDLER HandleUndefHandlerSWI HANDLER HandleSWIHandlerDabort HANDLER HandleDabortHandlerPabort HANDLER HandlePabort比如第一个为例说明 HandlerFIQ HANDLER HandleFIQ;;程序被汇编后,宏展开的结果HandlerFIQsub sp,sp,#4stmfd sp!,{r0}ldr r0,=HandleFIQldr r0,[r0]str r0,[sp,#4]ldmfd sp!,{r0,pc}下面一句一句分析一下,为了便于分析,假设sp = 0x33ff8000,$HandleLabel = 0x33ffff00,[0x33ffff00] = 0x10000000,r0 = 0x56001234:$HandlerLabel HANDLER $HandleLabel宏的名字叫HANDLER ,有两个参数$HandlerLabel定义一个标号sub sp,sp,#4把栈顶指针减4,留出一个字的空间(用于保存跳转地址的值),sp=0x33ff7ffcstmfd sp!,{r0}首先把sp减4 (sp=0x33ff7ff8),然后把将要使用的r0寄存器入栈,此时[0x33ff7ff8]=0x56001234ldr r0,=$HandleLabel给寄存器r0赋值,r0=0x33ffff00ldr r0,[r0]给寄存器r0赋值,r0=0x10000000str r0,[sp,#4];把寄存器r0保存到0x33ff7ffc (0x33ff7ff8+4),sp没有改变sp=0x33ff7ff8,如果str r0,[sp,#4]!sp 改变此时;[0x33ff7ffc] = 0x10000000ldmfd sp!,{r0,pc}把栈顶的两个字弹出,分别保存到r0、pc,此时sp=0x33ff8000,r0=0x56001234,pc=0x10000000 ,通过比较不难发现,sp和r0在执行前后都没有变化,程序就跳转到0x10000000处执行。
ARM汇编指令集详解
ARM汇编指令集一、跳转指令跳转指令用于实现程序流程的跳转,在ARM程序中有两种方法可以实现程序流程的跳转:Ⅰ.使用专门的跳转指令。
Ⅱ.直接向程序计数器PC写入跳转地址值。
通过向程序计数器PC写入跳转地址值,可以实现在4GB的地址空间中的任意跳转,在跳转之前结合使用MOV LR,PC等类似指令,可以保存将来的返回地址值,从而实现在4GB连续的线性地址空间的子程序调用。
ARM指令集中的跳转指令可以完成从当前指令向前或向后的32MB的地址空间的跳转,包括以下4条指令:1、B指令B指令的格式为:B{条件} 目标地址B指令是最简单的跳转指令。
一旦遇到一个B 指令,ARM 处理器将立即跳转到给定的目标地址,从那里继续执行。
注意存储在跳转指令中的实际值是相对当前PC值的一个偏移量,而不是一个绝对地址,它的值由汇编器来计算(参考寻址方式中的相对寻址)。
它是24 位有符号数,左移两位后有符号扩展为32 位,表示的有效偏移为26 位(前后32MB的地址空间)。
以下指令:B Label ;程序无条件跳转到标号Label处执行CMP R1,#0 ;当CPSR寄存器中的Z条件码置位时,程序跳转到标号Label 处执行BEQ Label2、BL指令BL指令的格式为:BL{条件} 目标地址BL 是另一个跳转指令,但跳转之前,会在寄存器R14中保存PC的当前内容,因此,可以通过将R14 的内容重新加载到PC中,来返回到跳转指令之后的那个指令处执行。
该指令是实现子程序调用的一个基本但常用的手段。
以下指令:BL Label ;当程序无条件跳转到标号Label处执行时,同时将当前的PC值保存到R14中3、BLX指令BLX指令的格式为:BLX 目标地址BLX指令从ARM指令集跳转到指令中所指定的目标地址,并将处理器的工作状态有ARM 状态切换到Thumb状态,该指令同时将PC的当前内容保存到寄存器R14中。
因此,当子程序使用Thumb指令集,而调用者使用ARM指令集时,可以通过BLX指令实现子程序的调用和处理器工作状态的切换。
汇编语言伪指令
汇编语言伪指令在汇编语言程序里,有一些特殊的助记符,这些助记符与指令系统的助记符不同,它们没有对应的机器码。
这些助记符在源程序中的作用是完成汇编程序的各种准备工作,包括定义变量、分配数据存储空间、控制汇编过程、定义程序入口等。
它们仅仅在汇编的过程中起作用,一旦汇编过程结束,它们的使命也就完成了。
这些助记符称为伪指令,它们所完成的操作称为伪操作。
不同汇编器的伪指令可能存在少量的区别,并非所有的伪指令在任何编译器上都能被识别。
一、符号定义伪指令符号定义(Symbol Definition)伪指令用于定义ARM汇编程序中的变量,对变量赋值和定义寄存器别名等,如表1所列。
表1 符号定义伪指令实例:GBLL P_ON ; 定义全局逻辑变量P_ON P_ON SETL {TRUE} ; 给全局逻辑变量P_ON赋值为真LCLA NUM ; 定义局部数字变量NUM NUM SETA 100 ; 给全局数字变量NUM赋值为100RegList RLIST {R0-R5,R8,R10} ; 定义一个寄存器列表RegList,可用微处理器系统结构与嵌入式系统设计(第3版)2; LDM/STM指令访问该列表二、数据定义伪指令数据定义(Data Denfinition)伪指令一般用于为特定的数据分配存储单元,同时完成对已分配存储单元的初始化工作。
数据定义伪指令如表2所示。
表2 数据定义伪指令从使用方法上来讲,数据定义伪指令可以分为以下3类。
1.SPACE伪指令SPACE用于分配一片连续的存储区,并初始化为0。
其中表达式中的数字表示分配的字节数。
SPACE也可以用%代替。
实例:DataSpace SPACE 100 ; 分配连续100字节的存储单元并初始化为0 2.MAP和FIELD伪指令MAP和伪指令FIELD经常结合在一起使用。
MAP用于定义一个结构化的内存表的首地址,可以用“^”替代。
FIELD用于定义一个结构化的内存表中的数据域,可以用“#”代替。
第一讲_伪操作、宏指令与伪指令讲义
GET/ INCLUDE INCBIN KEEP NOFP REQUIRE RN ROUT
语法格式 CODE16 CODE32 name EQU expr{,type} AREA sectionname{,attr}{,attr}… ENTRY END ALIGN {expr{,offset}} EXPORT symbol {[WEAK]} IMPORT symbol {[WEAK]} EXTERN symbol {〔WEAK〕}
FN
name FN expr
为一个FPA浮点寄存器定义名称。
数据定义伪操作
伪操作 LTORG
语法格式 LTORG
作用 声明一个数据缓冲池(也称为文字池)的开始。
MAP
MAP expr{,base-register}
定义一个结构化的内存表(Storage Map)的首地址。
FIELD
{label} FIELD expr
操作报告诊断信息。
OPT n
通过OPT伪操作可以在源程序中设置列表选项。
TTL
TTL title
在列表文件的每一页的开头插入一个标题。
SUBT
SUBT subtitle
在列表文件的每一页的开头插入一个子标题。
其他伪操作
伪操作 CODE16 CODE32 EQU AREA ENTRY END ALIGN EXPORT/ GLOBAL IMPORT
常量编译控制伪操作
• .byte • .byte expr {,expr}….. • 分配一段字节内存单元(字节对齐),
并用expr初始化 • .byte 21,48,89,0x13,0xff
常量编译控制伪操作 • .hword和.short • .hword expr {,expr}….. • .short expr {,expr}….. • 分配一段半字的单元,并用expr 初始
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。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
HandlerDabort HANDLER HandleDabort
HandlerPabort HANDLER HandlePabort
也许我们会问想格式中的[$ label]到底有什么作用?
当宏定义体内部跳转时,这个参数会起到至关重要的作用。要想在宏内部跳转,就必须在宏定义体内部有程序标号如(LOOP),如果不使用参数($ label),当在一个程序段内调用两次宏的时候,编译器就会出现错误,因为当汇编时产生了两个相同名字的程序标号。
MEND
;在程序中调用该宏
HandlerFIQ HANDLER HandleFIQ;通过宏的名称HANDLER调用宏,其中宏的标号为HandlerFIQ,参数为HandleFIQ HandlerIRQ HANDLER HandleIRQ
HandlerUndef HANDLER HandleUndef
例子:
宏的定义体:
MACRO
$PM DELAY $CanShu
$PM
LDR R7,=$CanShu ;
;LDR R7,[R7] ;此时参数是一个立即数如果是变量的话是会用到这一句
$PM.LOOP
SUBS R7,R7,#0X01
BNE $PM.LOOP
MEND
在程序段中的使用:(使用两次)
...
AA DELAY 0X000005F0
指令序列
MEND
MACRO伪操作标识宏定义的开始,MEND标识宏定义的结束。用MACRO及MEND定义一段代码,称为宏定义体,这样在程序中就可以通过宏指令多次调用该代码段。
其中,$ label在宏指令被展开时,label会被替换成相应的符号,通常是一个标号。在一个符号前使用$表示程序被汇编时将使用相应的值来替代$后的符号。
$HandlerLabel
sub sp,sp,#4
stmfd sp!,{r0}
;decrement sp(to store jump address ;PUSH the work register to stack(lr does not push because it return to original address ;load the address of HandleXXX to r0 ;load the contents(service routine start address of HandleXXX ;store the contents(ISR of HandleXXX to stack ;POP the work register and pc(jump to ISR ldr r0,=$HandleLabel ldr r0,[r0] str r0,[sp,#4] ldmfd sp!,{r0,pc}
macroname为所定义的宏的名称。
$parameter为宏指令的参数。当宏指令被展开时将被替换成相应的值,类似于函数中的形式参数,可以在宏定义时为参数指定相应的默认值。
宏指令的使用方式和功能与子程序有些相似,子程序可以提供模块化的程序设计、节省存储空间并提高运行速度。但在使用子程序结构时需要保护现场,从而增加了系统的开销,因此,在代码较短且需要传递的参数较多时,可以使用宏汇编技术。首先使用MACRO和MEND等伪操作定义宏。包含在MACRO和MEND之间的代码段称为宏定义体,在MACRO伪操作之后的一行声明宏的原型(包含宏名、所需的参数),然后就可以在汇编程序中通过宏名来调用它。在源程序被汇编时,汇编器将宏调用展开,用宏定义体代替源程序中的宏定义的名称,并用实际参数值代替宏定义时的形式参Байду номын сангаас。
ARM汇编伪指令宏的用法详解(MACRO-MEND
宏是一段独立的程序代码,它是通过伪指令定义的,在程序中使用宏指令即可调用宏。当程序被汇编时,汇编程序将对每个调用进行展开,用宏定义取代源程序中的宏指令。
MACRO、MEND
语法格式:
MACRO
[$ label] macroname{ $ parameter1,$ parameter,…… }
...
BB DELAY 0X00000FF0
...
此时调用多次,编译器就不会出现问题,例子中的AA和BB仅仅是一个标号,用户可以自行书写,因为在宏指令呗展开时,这个符号在汇编时将使用相应的值替代
0x00000FF0是一个参数在此处是一个立即数,用户可自行使用为变量等
宏定义中的$label是一个可选参数。当宏定义体中用到多个标号时,可以使用类似$label.$internallabel的标号命名规则使程序易读。
MACRO、MEND伪操作可以嵌套使用。
使用示例:
MACRO
$HandlerLabel HANDLER $HandleLabel;宏的名称为HANDLER,有1个参数$HandleLabel