PIC16系列_单片机常用伪指令(汇编)
- 格式:doc
- 大小:83.50 KB
- 文档页数:17
伪指令依照其用途可分为五类:定义类、存储类、存储定义类、条件类及汇编方式类。
它们的具体分类及用途详见伪指令的类别一览类别a定义类用于对以下内容进行定义的伪指令:1.程序;2.程序中所用数据的性质、范围或结构;3.宏或结构4.程序5.其它1CODE、DATA、TEXT2IRAM、ISRAM、ORAM、OSRAM、RAM、SRAM3MACRO、MACEXIT、ENDM4PROC、ENDP、STRUCT、ENDS;5.DEFINE、VAR、PUBLIC、EXTERNAL、EQU、VDEFb存储类以指定的数据类型存储数据或设定程序地址等DW、DD、FLOAT、DOUBLE、ENDc存储定义类定义若干指定数据类型的数据存储单元DUPd条件类对汇编指令进行条件汇编IF、ELSE、ENDIF;IFMA、IFDEF、IFNDEFe汇编方式类包含汇编文件或创建用户定义段INCLUDE;SECTION详解:定义类伪指令DEFINE【类别】定义类【功能描述】定义常量符号【语法格式】.DEFINE variable[value][,…]【应用解释】给常量符号所赋之值既可是一已定义过的常量符号,亦可是一表达式。
切忌符号超前引用,即如果赋值引用的符号不是在引用前定义的,则会出现“非法超前引用”的错误。
【举例】.DEFINE BODY1;.DEFINE IO_PORT0x7016;.IFDEF BODY;R1=0xFFFF;[IO_PORT]=R1;.ENDIFPUBLIC【类别】定义类【功能描述】声明将被引用在其它文件中的全局标号【语法格式】.PUBLIC label[,label][,…]【应用解释】本伪指令用来在文件中声明将被引用在外部文件中的全局标号。
故在外部文件中用伪指令EXTERNAL所声明的标号必须是用PUBLIC伪指令声明过的。
类似地,当要声明多个全局标号时,要用逗号(,)将每一标号分开。
【举例】.PUBLIC sym1//声明要引用在其它文件中的全局标号.PUBLIC sym1,sym2//声明多个全局标号需用逗号将每一标号分开,空格会被忽略。
MOV指令为双操作数指令,两个操作数中必须有一个是寄存器.MOV DST , SRC // Byte / Word执行操作: dst = src1.目的数可以是通用寄存器, 存储单元和段寄存器(但不允许用CS段寄存器).2.立即数不能直接送段寄存器3.不允许在两个存储单元直接传送数据4.不允许在两个段寄存器间直接传送信息PUSH入栈指令及POP出栈指令: 堆栈操作是以"后进先出"的方式进行数据操作.PUSH SRC //Word入栈的操作数除不允许用立即数外,可以为通用寄存器,段寄存器(全部)和存储器.入栈时高位字节先入栈,低位字节后入栈.POP DST //Word出栈操作数除不允许用立即数和CS段寄存器外, 可以为通用寄存器,段寄存器和存储器.执行POP SS指令后,堆栈区在存储区的位置要改变.执行POP SP 指令后,栈顶的位置要改变.XCHG(eXCHanG)交换指令: 将两操作数值交换.XCHG OPR1, OPR2 //Byte/Word执行操作: Tmp=OPR1 OPR1=OPR2 OPR2=Tmp1.必须有一个操作数是在寄存器中2.不能与段寄存器交换数据3.存储器与存储器之间不能交换数据.XLAT(TRANSLATE)换码指令: 把一种代码转换为另一种代码.XLAT (OPR 可选) //Byte执行操作: AL=(BX+AL)指令执行时只使用预先已存入BX中的表格首地址,执行后,AL中内容则是所要转换的代码.LEA(Load Effective Address) 有效地址传送寄存器指令LEA REG , SRC //指令把源操作数SRC的有效地址送到指定的寄存器中.执行操作: REG = EAsrc注: SRC只能是各种寻址方式的存储器操作数,REG只能是16位寄存器MOV BX , OFFSET OPER_ONE 等价于 LEA BX , OPER_ONEMOV SP , [BX] //将BX间接寻址的相继的二个存储单元的内容送入SP中LEA SP , [BX] //将BX的内容作为存储器有效地址送入SP中LDS(Load DS with pointer)指针送寄存器和DS指令LDS REG , SRC //常指定SI寄存器。
常用的7条:ORG—定位伪指令END—结束汇编伪指令EQU—赋值伪指令DB—定义字节指令DW—定义数据字指令DS—定义存储区指令;从标号开始预留若干单元,单元个数有表达式值决定BIT—位定义指令51汇编伪指令2008-12-20 10:58伪指令是对汇编起某种控制作用的特殊命令,其格式与通常的操作指令一样,并可加在汇编程序的任何地方,但它们并不产生机器指令。
许多伪指令要求带参数,这在定义伪指令时由“表达式”域指出,任何数值与表达式匀可以作为参数。
不同汇编程序允许的伪指令并不相同,以下所述的伪指令仅适用于MASM51系统,但一些基本的伪指令在大部份汇编程序中都能使用,当使用其它的汇编程序版本时,只要注意一下它们之间的区别就可以了。
MASM51中可用的伪指令有:ORG 设置程序起始地址END 标志源代码结束EQU 定义常数SET 定义整型数DATA 给字节类型符号定值BYTE 给字节类型符号定值WROD 给字类型符号定值BIT 给位地址取名ALTNAME 用自定义名取代保留字DB 给一块连续的存储区装载字节型数据DW 给一块连续的存储区装载字型数据DS 预留一个连续的存储区或装入指定字节。
INCLUDE 将一个源文件插入程序中TITLE 列表文件中加入标题行NOLIST 汇编时不产生列表文件NOCODE 条件汇编时,条件为假的不产生清单一、ORG伪指令ORG用于为在它之后的程序设置地址值,它有一个参数,其格式为:ORG 表达式表达式可以是一个具体的数值,也可以包含变量名,如果包含变量名,则必须保证,当第一次遇到这条伪指令时,其中的变量必须已有定义(已有具体的数值),否则,无定义的值将由0替换,这将会造成错误。
在列表文件中,由ORG定义的指令地址会被打印出来。
ORG指令有什么用途呢?指令被翻译成机器码后,将被存入系统的ROM中,一般情况下,机器码总是一个接一个地放在存储器中,但有一些代码,其位置有特殊要求,典型的是五个中断入口,它们必须被放在0003H,000BH,0013H,001BH和0023H的位置,否则就会出错,如果我们编程时不作特殊处理,让机器代码一个接一个地生成,不能保证这些代码正好处于这些规定的位置,执行就会出错,这时就要用到ORG伪指令了。
PIC 单片机端口电平变化中断使用必须注意的问题PICC18使用说明PIC 单片机常用伪指令PIC单片机2009-02-19 11:16:40 阅读8 评论0 字号:大中小订阅3.2.3 MPASM 的伪指令我们在第一章中已经详细介绍了中档PIC 单片机的35 条指令,源程序的编写主要就是用这些基本的指令实现你的控制任务。
但为了增加源程序的可读性和可维护性,我们引入了伪指令的概念。
伪指令本身不会产生可执行的汇编指令,但它们可以帮组“管理”你编写的程序,其实用性和必要性绝不亚于35 条正真的汇编指令。
我们在此着重介绍最常用的几种伪指令。
#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 安装后的目录;另一种是””双引号引用,这种引用方式的意思是指示编译器从引号中指定的全程文件路径下寻找该文件。
PIC16程序设计及应用PIC16程序设计及应用引言PIC16是一种微控制器,它在嵌入式系统中有着广泛的应用。
本文将介绍PIC16程序设计的基本知识和应用场景,帮助读者了解和掌握PIC16的编程技巧和应用方法。
本文将以Markdown文本格式输出,方便读者阅读和理解。
什么是PIC16PIC16是微芯科技(Microchip Technology)推出的一种8位微控制器。
它具有低功耗、高性能和丰富的外设特性,适用于各种嵌入式应用中。
PIC16微控制器可以通过编程实现各种功能,如数据采集、通信、控制等。
因此,学习PIC16程序设计具有重要的意义。
PIC16程序设计基础1. 开发环境搭建在开始PIC16程序设计之前,我们需要搭建PIC16的开发环境。
首先,我们需要安装MPLAB X IDE(Integrated Development Environment),这是用于PIC16开发的集成开发环境。
其次,我们需要选择合适的编译器和调试工具。
最常用的编译器是XC8,它支持C语言编程。
调试工具可以使用MPLAB ICD等。
安装好开发环境后,我们可以开始编写程序了。
2. 程序结构每个PIC16程序都需要遵循一定的程序结构。
一个典型的PIC16程序包含以下几个部分:- 引用库文件:包含一些常用的库文件,以便在编程中使用预定义的函数和变量。
- 定义引脚:定义用于输入输出的引脚。
- 初始化:进行一些初始化工作,如配置引脚功能、初始化外设等。
- 主函数:程序的入口,包含了程序的主要逻辑。
- 中断处理函数(可选):处理来自外部的中断信号。
3. 常用函数和指令PIC16的编程主要使用C语言进行。
在编程过程中,我们会使用到一些常用的函数和指令,如GPIO控制、定时器操作、串口通信等。
这些函数和指令可以通过引用库文件进行调用。
以下是一些常用的函数和指令示例:```cinclude <pic16.h>void mn(){TRISB0 = 0; // 将B0引脚设置为输出PORTB0 = 1; // 将B0引脚输出高电平}```4. 调试和仿真在PIC16程序开发过程中,调试和仿真是非常重要的环节。
单片机编程之汇编语言基础-PIC单片机汇编指令1、程序的基本格式先介绍二条伪指令:EQU 标号赋值伪指令ORG 地址定义伪指令PIC16C5X在RESET后指令计算器PC被置为全1,所以PIC16C5X几种型号芯片的复位地址为:PIC16C54/55:1FFHPIC16C56:3FFHPIC16C57/58:7FFH一般来说,PIC的源程序并没有要求统一的格式,大家可以根据自己的风格来编写。
但这里我们推荐一种清晰明了的格式供参考。
TITLE This is ;程序标题;--------------------------------------;名称定义和变量定义;--------------------------------------F0 EQU 0RTCC EQU 1PC EQU 2STATUS EQU 3FSR EQU 4RA EQU 5RB EQU 6RC EQU 7┋PIC16C54 EQU 1FFH ;芯片复位地址PIC16C56 EQU 3FFHPIC16C57 EQU 7FFH;-----------------------------------------ORG PIC16C54 GOTO MAIN ;在复位地址处转入主程序ORG 0 ;在0000H开始存放程序;-----------------------------------------;子程序区;-----------------------------------------DELAY MOVLW 255┋RETLW 0;------------------------------------------;主程序区;------------------------------------------MAINMOVLW B00000000TRIS RB ;RB已由伪指令定义为6,即B口┋LOOPBSF RB,7 CALL DELAYBCF RB,7 CALL DELAY┋GOTO LOOP;-------------------------------------------END ;程序结束注:MAIN标号一定要处在0页面内。
PIC16CXX指令系统
PIC16CXX每条指令长14位,指令由操作码和操作数组成。
PIC16CXX共有35条指令,由操作对象可分为:
1. 面向字节操作类
2. 面向位操作类
3. 常数操作和控制类操作。
全部指令如图所示。
注:(1)PIC16CXX有35条基本指令及二条附加指令,即TRIS和OPTION。
在PIC16CXX中TRIS和OPTION 寄存器是直接可寻址的,所以不必用这二条指令,保留它们只是为了和PIC16C5X向上兼容,即便于PIC16C5X 代码向PIC16CXX的移植,见下节指令详介。
(2)对I/O寄存器操作的指令,如"MOVF 6,1",使用的F6(RB口)的值是RB口脚上的状态值,而非输出锁存器的值。
(3)"f"代表寄存器,"d"代表目的寄存器,当d=0,操作结果放入W寄存器,d=1,则结果放入f寄存器。
"b"代表位(0~7),K代表一个8位或11位的常数。
PIC16系列单片机汇编指令集-包括部分伪指令-很有帮助(整理的)2011.txt遇事潇洒一点,看世糊涂一点。
相亲是经销,恋爱叫直销,抛绣球招亲则为围标。
没有准备请不要开始,没有能力请不要承诺。
爱情这东西,没得到可能是缺憾,不表白就会有遗憾,可是如果自不量力,就只能抱憾了。
当D不写时默认是放到F中吗?好像是.更新:1,PIC16没有同或指令;面向字节ADDWF F,D ;寄存器加法指令,F+W→D 影响C,DC,Z 进位C为1表示有进位INCF F,D ;寄存器加1指令F+1→DSUBWF F,D ;减法指令F-W→D 影响C,DC,Z 进位C为0表示有借位.则F<W 那么W等于多少呢?DECF F,D ;寄存器减1指令F-1→D 影响ZANDWF F,D ;F里的内容和W里的内容相与结果存入F(d=1)或(d=0),F∧W→d,影响Z 不带进位的加法,在PIC18系列中才有带进位加法指令.IORWF F,D ;F内容和W内容相或,F∨W→d,影响ZXORWF F,D ;F内容与W内容异或F⊕W→D, 位异或,影响Z位即是只要相异就为真0⊕1=1和1异或则取反0⊕0=0和0异或则保持不变1⊕1=01⊕0=1面向常数ADDLW K ;常数加法指令,8位立即数和W内容相加,结果存入W K+W→W,影响C,DC,ZSUBLW K ;8位立即数减掉W内容,存入W, K-W→W,影响C,DC,ZANDLW K ;常数逻辑与K∧W→W 影响ZIORLW K ;常数逻辑或K∨W→W 影响ZXORLW K ;常数逻辑异或K⊕W→W 影响ZCLRW ;寄存器W被清零CLRWDT ;看门狗定时器清零(若已赋值,同时清零预分频器)CLRF F ;寄存器F清零指令BCF F,b ;把寄存器F的第b位清零 Bit Clear FMOVLW K ;传送立即数(或常数,标号)至工作寄存器W MOVE Literal to WTRIS F ;把W的内容送I/O口控制寄存器F Load TRIS Register ;好像没有这个指令;MOVWF ;是MOVE W的内容TO F,(W内容保持不变),如MOVWF 6 (F6表示RB口) 不影响状态位.MOVF F,D ;D=0,F内容送W. D=1,F内容送寄存器影响ZNOP ;空操作,PC加1,占用一个机器周期GOTO K ;无条件跳转指令,将指令转移到指定地址,“K"常与程序中的标号联系起来。
/**用TMR0延时中断,产生脉冲**//**设定时器TMR0延时10MS,8位pic单片机晶振4MHZ,则指令周期Tcy=1us,计算如下:1.设预分频比为K,则256*K*Tcy=10_000us,得K=39.06,要取大于此值的最小分频比,即K=642.计算延时常数X,(256-X)*64*Tcy=10_000us,得X=99.75,四舍五入取整,得X=100. */#include<pic.h>__CONFIG(0x3f71);#define LED RB0#define T0_10MS 100 //定义TMR0延时10MS的时间常数char A;void interrupt ISR(void);void main(void){RISB0=0; //设定RB0位输出,其余B口未设置,采用上电默认值,为输入OPTION=0b10000101;//RBPU=1:B口上拉使能,INTEDG=0:下降沿触发,T0CS=0:对内部指令周期计数,T0SE=0:RA4/T0CKI的上升沿计数,PSA=0:预分频分配位给TMRO,PS2PS1PS0=101:TMR0比率为1:64INTCON=0b10100000;//GIE=1:允许全局中断使能,PEIE=0:禁止外设中断使能,T0IE/TMR0IE=1:允许TMR0溢出中断使能,INTE=0:禁止INT引脚中断使能//RBIE=0:禁止RB口高4位电平变化使能,T0IF/TMR0IF=0:TMR0溢出中断标志位--未溢出//INTF=0:未发生INT中断,RBIF=0:RB7:RB4引脚的逻辑状态未发生变化TMR0=T0_10MS; //TMR0赋初值LED=1;A=1;while(1); //原地等待}void interrupt ISR(void){if(T0IF==1){T0IF=0;TMR0=T0_10MS;//TMR0赋初值,必须if(A==1){A=0;LED=0;}else{A=1;LED=1;}}}proteus如下:(已修改)第一步:初步画好仿真图,设置好PIC参数(晶振,配置位)并运行,如下:第二步:设置ANALOGUE ANALYSIS(我们主要看RB0的模拟电压情况),设置方法如下:1.右击---Edit Graph---起始时间50m,终止时间150m---OK2.右击---Add Traces---Name为RB0,Probe P1为RB0---OK3.右击---Edit Graph---Set Y-scales---若此时显示为灰色不可输入状态,那就点确定,会弹出一个窗口“Resimulate?”,点击确定,方波图就出来了,不过默认是0~5V,你现在就可以重新修改Y-scales,如下图:先打勾“Lock values”,在设置Min -1,Max 6----Ok----又会弹出“resimulate?”,确定即可。
PIC 单片机端口电平变化中断使用必须注意的问题PICC18使用说明PIC 单片机常用伪指令PIC单片机2009-02-19 11:16:40 阅读8 评论0 字号:大中小订阅3.2.3 MPASM 的伪指令我们在第一章中已经详细介绍了中档PIC 单片机的35 条指令,源程序的编写主要就是用这些基本的指令实现你的控制任务。
但为了增加源程序的可读性和可维护性,我们引入了伪指令的概念。
伪指令本身不会产生可执行的汇编指令,但它们可以帮组“管理”你编写的程序,其实用性和必要性绝不亚于35 条正真的汇编指令。
我们在此着重介绍最常用的几种伪指令。
#include 或include#include 伪指令的作用是把另外一个文件的内容全部包含复制到本伪指令所在的位置。
被包含复制的文件可以是任何形式的文本文件,当然文件中的内容和语法结构必须是MPASM 能够识别的。
最经常被“include”的是针对PIC 单片机内部特殊功能寄存器定义的包含头文件,在MPLAB 安装后它们全部放在路径“ C:\Program Files\MPLABIDE\MCHIP_Tools”下,每一个型号的PIC 单片机都有一个对应的预定义包含头文件,扩展名是“.inc”。
除了一些符号预定义文件,你也可以把现有的其它程序文件作为一个代码模块直接“包含”进来作为自己程序的一部分。
见例3-01。
#include <p16f877a.inc> ;把预定义的PIC16F877A 寄存器符号包含到此处#include ”math.asm” ;把现有的程序文件包含进来作为自己代码的一部分例3-01请注意被包含文件的引用方式。
一种是<>尖括号引用,这种引用意味着让编译器去默认的路径下寻找该文件,MPASM 默认的寄存器预定义文件存放路径即为上面提及的MPLAB 安装后的目录;另一种是””双引号引用,这种引用方式的意思是指示编译器从引号中指定的全程文件路径下寻找该文件。
例3-01 中”math.asm”没有指定路径,即意味着在当前项目路径下寻找math.asm 文件。
如果编译器找不到被包含的文件,将会有错误信息告知。
请在你的源程序中尽量用MPLAB 标准头文件定义的寄存器符号。
一来这些被定义的寄存器符号和芯片数据手册上的描述一一对应,理解起来即直观又容易;二来如果用你自己定义符号就缺乏一个大家能一起交流的标准平台,其他人要解读你的代码时将费时费力。
故例3-01 中的首行#include 包含引用伪指令可以说是PIC 单片机程序编写时的标准必备。
listlist 伪指令可以设定程序编译时的一些信息,例如所选单片机的型号,编译时选择的缺省数制等。
例如:list p=16f877a, r=DEC ;单片机型号为PIC16F877A,无特别指明的数字为十进制数例3-02如果程序开发时使用项目管理的模式,则所有list 伪指令可以描述的参数项都可以在项目的设定选项中通过对话框的形式设定并保存。
在此只需对list 伪指令稍作了解即可。
__config此伪指令的重要作用是把芯片的配置字设定在源程序中,请参阅2.5 节的详细说明。
建议大家尽量用此伪指令把芯片的配置字写在程序中。
__idlocsPIC 单片机中有一处非常特殊的标记单元。
它独立于任何其它存储器,唯一的作用就是作为一个标记。
此标记值无法用软件读到,读取和写入的方法只有通过编程器实现。
此标记值没有读保护,你可以利用它存放程序的版本或日期等信息。
如果需要,则可以用伪指令__idloc 在程序中定义具体的值。
__idloc 0x1234 ;设定芯片的标记值为0x1234,注意前面有两个下划线符例3-03和__config 伪指令定义的配置字一样,用__idloc 定义的芯片标记值在最后也会存放在HEX 文件中,这就要求编程器能够解析它。
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-04#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 的符号名改回成被替换的字符串,然后再继续编译生产机器码。
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-07cblock / 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 中随意插入新定义的变量,或通过改变起始地址的方式使变量块整个挪到其它内存地址处,地址的更新由编译器代劳。