MPASM 的伪指令
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编程进阶之一-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状态。
asm汇编伪指令大全

在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 {TRUE} ;将该变量赋值为真GBLS Test3 ;定义一个全局的字符串变量,变量名为Test3Test3 SETS “ Testing ” ;将该变量赋值为“ Testing ”2、LCLA、LCLL 和LCLS语法格式:LCLA (LCLL 或LCLS )局部变量名LCLA 、LCLL 和LCLS 伪指令用于定义一个ARM 程序中的局部变量,并将其初始化。
over lable是什么意思

over lable是什么意思MPASM是Microchip公司推出的可适用于其PIC16/17全部单片机的宏汇编器,功能齐全,全屏幕操作。
§4.1启动和操作MPASM的启动很简单,在DOS状态下:> MPASM <Enter> (注意MPASM后面不要跟文件名)屏幕上即显示:MPASM 01.11 Released (c)1993,94 Byte Craft Limited/Microchip Technology Inc. Source File : SAMPLE.ASM Processor Type : 12C509 Error File : Yes Cross Refernece File : No Listing File : Yes Hex Dump Type : INHX8M .HEX Assemble to Object File : No━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━↑↓,Tab : Move Cursor Esc : Quit Press Enter to change value. F1 : Help F10 : Assemble 图4.1 MPASM画面Source File: 源程序文件名。
可以带路径和通配符(*)。
Processor Type: 芯片型号。
可通过Enter键来选择用户所需的型号。
Error File: 汇编后自动产生一个.ERR文件,该文件记录了汇编中产生的错误语句和警告信息。
Cross Reference File: 产生一个参考文件.XRF。
Listing File: 产生一个列表文件.LST。
该文件中包含了各种仿真环境中需要的参数,主要用于仿真调试。
Hex Dump Type: 产生的代码烧写文件,一般选择INHX8M格式,可适应众多的烧写器。
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伪指令的功能,若不能用一条指令实现,则产生错误,编译失败。
MPLAB伪指令介绍
3.2.3MPASM的伪指令我们在第一章中已经详细介绍了中档PIC单片机的35条指令,源程序的编写主要就是用这些基本的指令实现你的控制任务。
但为了增加源程序的可读性和可维护性,我们引入了伪指令的概念。
伪指令本身不会产生可执行的汇编指令,但它们可以帮组“管理”你编写的程序,其实用性和必要性绝不亚于35条正真的汇编指令。
我们在此着重介绍最常用的几种伪指令。
z#include 或 include#include伪指令的作用是把另外一个文件的内容全部包含复制到本伪指令所在的位置。
被包含复制的文件可以是任何形式的文本文件,当然文件中的内容和语法结构必须是MPASM能够识别的。
最经常被“include”的是针对PIC单片机内部特殊功能寄存器定义的包含头文件,在MPLAB安装后它们全部放在路径“C:\Program Files\MPLAB IDE\MCHIP_Tools”下,每一个型号的PIC单片机都有一个对应的预定义包含头文件,扩展名是“.inc”。
除了一些符号预定义文件,你也可以把现有的其它程序文件作为一个代码模块直接“包含”进来作为自己程序的一部分。
见例3-01。
#include <p16f877a.inc> ;把预定义的PIC16F877A寄存器符号包含到此处#include ”math.asm” ;把现有的程序文件包含进来作为自己代码的一部分例3-01请注意被包含文件的引用方式。
一种是<>尖括号引用,这种引用意味着让编译器去默认的路径下寻找该文件,MPASM默认的寄存器预定义文件存放路径即为上面提及的MPLAB安装后的目录;另一种是””双引号引用,这种引用方式的意思是指示编译器从引号中指定的全程文件路径下寻找该文件。
例3-01中”math.asm”没有指定路径,即意味着在当前项目路径下寻找math.asm文件。
如果编译器找不到被包含的文件,将会有错误信息告知。
请在你的源程序中尽量用MPLAB标准头文件定义的寄存器符号。
第四章 伪指令
数据定义伪指令的格式为: [变量名] DB(DW、DD、DQ、DT) 表达式1,表达式2,… 表达式1,表达式2……是给变量或指定的存储单元赋予初值,它们有以下几种形式: (a)数值表达式 数据定义伪指令可以为一个或连续的存储单元设置数值初值。 (b)字符串表达式 对于DB伪指令,字符串的长度允许超过2个字符,但不能超过255个字符,字符 串必须用单引号括起来,它可为字符串中的每个字符分配1字节单元,字符串 从左至右以字符的ASCII码形式按地址递增的顺序依次存放。 (c)?表达式 不带引号的?,用于为变量预留内存单元,暂时不存入数据,即表示所定义的 变量无确定的初值。 例如:A DW ?,?为变量A预留2个字单元。 (d)地址表达式 操作数为地址表达式时,只适用于DW和DD这两种数据定义伪指令。如果地址表 达式为一变量(标号)名,用DW伪指令则是取它的偏移地址来初始化变量;用 DD伪指令则是取它的段首地址和偏移地址来初始化变量。 (e)带DUP的表达式 格式为:n DUP (表达式),其中n为重复因子,只能取正整数,它表示定义了 n个相同的数据存储单元。
在8086汇编语言中,运算符分为:算术运算符、逻辑运算符、关系运算
符、数值返回运算符、属性运算符和字节分离运算符。
(一)、表达式
(1)数值表达式 数值表达式是由常量与算术运算符、逻辑运算符或关系运算符构成的有意 义的式子。数值表达式在汇编期间进行运算,运算结果为一数值常量,它 只有大小而没有属性。
数据定义伪指令的格式为: [变量名] DB(DW、DD、DQ、DT)
Байду номын сангаас
表达式1,表达式2,„
其中:变量名是可选项,它仅代表所定义数据存储区第一个单元的地址; DB、DW、DD、DQ和DT是伪指令符,具体一条数据定义伪指令取5种之一。 DB定义的是字节类型的变量,每个表达式被分配1个字节单元。 DW定义的是字类型的变量,每一个表达式被分配1个字单元(2个字节)。 DD定义的是双字类型的变量,每一个表达式被分配2个字单元(4个字节)。 DQ定义的是四字类型的变量,每一个表达式被分配4个字单元(8个字节)。 DT定义的是十字节类型的变量,每一个表达式被分配10个字节单元。
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 { ...段名 :{内容}...}文章出处:。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
MPASM 的伪指令我们在第一章中已经详细介绍了中档PIC 单片机的35 条指令,源程序的编写主要就是用这些基本的指令实现你的控制任务。
但为了增加源程序的可读性和可维护性,我们引入了伪指令的概念。
伪指令本身不会产生可执行的汇编指令,但它们可以帮组“管理”你编写的程序,其实用性和必要性绝不亚于35 条正真的汇编指令。
我们在此着重介绍最常用的几种伪指令。
z #i nclude 或include#i nclude 伪指令的作用是把另外一个文件的内容全部包含复制到本伪指令所在的位置。
被包含复制的文件可以是任何形式的文本文件,当然文件中的内容和语法结构必须是MPASM 能够识别的。
最经常被“include”的是针对PIC 单片机内部特殊功能寄存器定义的包含头文件,在MPLAB 安装后它们全部放在路径“C:\Program Files\MPLABIDE\MCHIP_Tools”下,每一个型号的PIC 单片机都有一个对应的预定义包含头文件,扩展名是“.inc”。
除了一些符号预定义文件,你也可以把现有的其它程序文件作为一个代码模块直接“包含”进来作为自己程序的一部分。
见例3-01。
#i nclude <p16f877a.inc> ;把预定义的PIC16F877A 寄存器符号包含到此处#i nclude ”math.asm”;把现有的程序文件包含进来作为自己代码的一部分例3-01请注意被包含文件的引用方式。
一种是<>尖括号引用,这种引用意味着让编译器去默认的路径下寻找该文件,MPASM 默认的寄存器预定义文件存放路径即为上面提及的MPLAB 安装后的目录;另一种是””双引号引用,这种引用方式的意思是指示编译器从引号中指定的全程文件路径下寻找该文件。
例3-01 中”math.asm”没有指定路径,即意味着在当前项目路径下寻找math.asm 文件。
如果编译器找不到被包含的文件,将会有错误信息告知。
请在你的源程序中尽量用MPLAB 标准头文件定义的寄存器符号。
一来这些被定义的寄存器符号和芯片数据手册上的描述一一对应,理解起来即直观又容易;二来如果用你自己定义符号就缺乏一个大家能一起交流的标准平台,其他人要解读你的代码时将费时费力。
故例3-01 中的首行#i nclude 包含引用伪指令可以说是PIC 单片机程序编写时的标准必备。
z listlist 伪指令可以设定程序编译时的一些信息,例如所选单片机的型号,编译时选择的缺省数制等。
例如:list p=16f877a, r=DEC ;单片机型号为PIC16F877A,无特别指明的数字为十进制数例3-02如果程序开发时使用项目管理的模式,则所有list 伪指令可以描述的参数项都可以在项目的设定选项中通过对话框的形式设定并保存。
在此只需对list 伪指令稍作了解即可。
z __config此伪指令的重要作用是把芯片的配置字设定在源程序中,请参阅2.5 节的详细说明。
建议大家尽量用此伪指令把芯片的配置字写在程序中。
z __idlocsPIC 单片机中有一处非常特殊的标记单元。
它独立于任何其它存储器,唯一的作用就是作为一个标记。
此标记值无法用软件读到,读取和写入的方法只有通过编程器实现。
此标记值没有读保护,你可以利用它存放程序的版本或日期等信息。
如果需要,则可以用伪指令__idloc 在程序中定义具体的值。
__idloc 0x1234 ;设定芯片的标记值为0x1234,注意前面有两个下划线符例3-03和__config 伪指令定义的配置字一样,用__idloc 定义的芯片标记值在最后也会存放在HEX 文件中,这就要求编程器能够解析它。
z errorlevelerrorlevel 的用途是控制编译信息的输出显示。
编译器在编译你的源程序时会提供很多信息,有些信息是你必须要处理的,例如错误信息(Error),只要有错误信息存在,你的程序将永远无法完成编译;有些可能只需要关注,例如警告信息(Warning);也有一些可能你根本就不感兴趣,它们只是一些提示信息(Message)而已。
注意出现警告和提示信息时将不会中止编译器的编译工作,你的程序将被编译并最终产生HEX 文件。
图3-14 中显示了一个程序编译后的各种信息实例,其中既有错误信息,也有警告和提示信息。
我们可以用errorlevel 伪指令来控制输出信息的级别,或刻意关闭/打开一些提示信息。
编译信息的输出显示级别有三种,分别是0、1 和2。
级别0 代表显示所有信息,包括各种错误、警告和提示信息,如图3-14 所示;级别1 代表显示错误和警告信息,忽略提示信息;级别3 代表只显示错误信息而忽略警告和提示信息。
在任何一个大的级别上还可以对某些信息单独设定显示或关闭。
每个信息都有一个识别标号,见图3-14 中信息项“[]”中的数字,打开或关闭某类信息只需在errorlevel 伪指令中引用信息识别标号,并在其前面用“+”或“-”号,即代表打开或关闭这一类信息,例如:errorlevel 0, -302, -305 ;显示所有信息,但不需要302 和305 这两类提示信息errorlevel 1, +305 ;显示错误和警告信息,但同时还要关注305 类的提示信息图3-14例3-04z #define / #undefine#define 的作用是定义常数符号,即用一个符号变量替换另一个符号串或变量。
被替换的可以是任意字母数字组成的符号但替换者本身不能是一个纯数字。
例如:#define DELAY_TIME 1000 ;定义常数符号,即用DELAY_TIME 符号代替1000#define KEY1 PORTB,7 ;用KEY1 符号代替端口PORTB 的第7 引脚例3-05用#define 伪指令定义符号后,可使程序中的变量或指令变得更具实际意义,也使程序变得更易维护。
指令“btfss PORTB,7”和“btfss KEY1”在事先用了例3-05 中的#define 后编译的结果是一样的,但明显地后者看起来更容易理解,一看就知道这是在测试编号为KEY1 的一个按键。
而且如果你的硬件设计改动了KEY1 所接的单片机引脚,只要改动这一处#define 重新定义引脚位置,程序的其它部分无需任何修改,再编译一次即可得到更新后的软件代码。
一个好的编程习惯是事先把一些代表实际意义的变量、单片机的输入输出引脚在硬件电路中的实际功能等用#define 伪指令定义成简单直观的符号名字,然后在程序中直接用其符号名字而不用简单机械的数字形式。
替换的工作由编译器在编译时自动完成。
它会先扫描你的源程序代码,把事先#define 的符号名改回成被替换的字符串,然后再继续编译生产机器码。
z equequ 顾名思义是“等于”的意思,其作用和#define 伪指令有点类似,也是用一个符号名字替换其它数字变量,但它只能替换立即数。
如果要替换一个符号名字,则此符号名必须事先用#define 或equ 伪指令已经定义替换了一个立即数。
例如:#define MyCount 0x70 ;定义MyCount 符号替换立即数0x70w_temp equ 0x20 ;符号名w_temp 等于0x20count1 equ MyCount ;符号名count1 等同于MyCount;如果MyCount 没有事先定义则会产生一个错误例3-06在绝对定位的编程模式中equ 被经常用于定义用户自己的变量,即用一个符号名代替一个固定的存储单元地址,上例3-06 中的w_temp 定义即属于此类。
用equ 方式定义的符号在汇编后可以生成相关的调试信息,可以通过各种变量观察的方式显示此符号所代表的内存地址处的数据内容,但用#define 方式定义的符号则不能产生调试信息。
要注意equ 伪指令本身并没有限定所定义的一定是一个变量地址,它只是一个简单的符号和数字替换而已,其意义必须和具体的指令结合才能确定,如下例3-07 中对符号w_temp 的理解。
w_temp equ 0x20 ;符号名w_temp 等于0x20movlw 0x55 ;W=0x55movwf w_temp ;把W 的值送给变量w_temp,(0x20 单元内容=0x55)movf w_temp, w ;把w_temp 单元内容送W,(W=0x55)movwf FSR ;把W 的内容送FSR,(FSR=0x55)movlw w_temp ;把w_temp 所代表的立即数即地址值送给W,(W=0x20)movwf FSR ;让FSR 指针指向w_temp,(FSR=0x20 而不是0x55)例3-07z cblock / endc用equ 伪指令可以给一个符号变量分配一个地址。
但在一个程序设计过程中往往需要定义很多变量,你当然可以给每一个变量逐个用equ 的方法分配一个地址空间。
但如果变量很多,这样做就显得非常麻烦,你必须自己安排每个变量的地址,小心不能出现地址重叠;若要在已定义分配好的变量间插入新的变量,那就必须重新逐个安排随后变量的地址等等。
cblock/endc 伪指令可以轻松解决有很多变量定义的场合出现的这些问题,我们把它叫作变量块连续定义。
具体用法如下:cblock 伪指令声明变量块的起始地址,endc 伪指令声明变量块定义结束,cblock/endc中间可以插入任意多的变量声明。
其地址编排由编译器自动计算:第一个变量地址分配从起始地址开始,然后按所声明变量保留的字节数自动分配后面变量的地址,变量所需保留的字节数用“:”加后面的数字表示,如果只有一个字节“:1”可以省略不写。
以例3-08 来说明:cblock 0x20 ;变量定义起始地址为0x20w_temp ;w_temp 地址为0x20,占一个字节status_temp ;status_temp 地址为0x21,占一个字节buffer:8 ;buffer 的起始地址为0x22,并保留8 个字节单元var1 ;var1 的地址为0x2a,占一个字节var2 ;var2 的地址为0x2b,占一个字节endc ;结束变量连续定义例3-08用cblock 方式定义的变量和用equ 方式定义的变量一样在汇编后可以生成相关的调试信息,可以通过各种变量观察的方式显示此符号所代表的内存地址和其中的数据内容,所以实际编程时一般无需关心计算每个变量的具体地址。
程序员要注意的用这种方式连续定义很多变量时不要让变量块跨越所处bank 的边界。
你可以在cblock 中随意插入新定义的变量,或通过改变起始地址的方式使变量块整个挪到其它内存地址处,地址的更新由编译器代劳。
z orgorg 用以定义程序代码的起始地址,通过此伪指令你可以把程序定位到任何可用的程序空间,它实现的是程序代码绝对定位,如例3-09:org 0x0000 ;定义复位入口地址,以下指令从地址0x0000 开始goto main ;org 0x0004 ;定义中断入口地址,以下指令从地址0x0004 开始movwf w_temp ;保存w;... ;其它中断服务代码org 0x0800 ;定义page1 的起始地址,以下指令代码放在page1Sub1 return例3-09只要你认为代码需要确定放在某一特定地址处,在程序的任何地方都可以用org 伪指令重新定义存放的起始地址,且地址顺序可以任意编排。