C51 汇编伪指令
51单片机(宏汇编)指令集5

常量及其表示
数据形式 格 式 取值范围 备注
2进制 ********B
0,1
0进制 ******
0, 1,2...9
ห้องสมุดไป่ตู้
****H 0,1...E,F
0CDE3H
符应是0--9
ASCII '**' ASCII 'AD' 使用
示例
10110011B 32768 16进制 最前面一个字
HIGH 高字节分离 ADD A,#HIGH 05E2H
LOW 低字节分离 ADD A,#LOW 77F0H
ASM51汇编器通用伪指令
汇编起始命令
ORG 16位地址 (常数或表达式 )
定义程序/数据的起始地址
ORG $+5
ORG 0008H
汇编结束命令
END
汇编到此结束,其后面的内
运算 操 作 含 义
以ADD为例
+
加操作 ADD A,#RR1+36
-
减操作 ADD A,#RR1-2EH
*
乘操作 ADD A,#RR1*0E3H
/
除操作 ADD A,#RR1/23
MOD 模除 ADD A,#RR1 MOD 12
数值运算
操 作 含 义
以ADD为例
SHR
右移 ADD A,#RR1 SHR 3
格式: 字符名称 BIT 位地址 例如: fire bit p1.0
或者: fire equ p1.0
ASM51汇编伪指令EQU/BIT
TEMP EQU 30H ;定义变量TEMP地址为30H T_MOD EQU 40H ;定义定时器模式控制字常
MCS-51单片机-伪指令

伪指令并不是真正的指令,也不产生相应的机器 码,它们只是在计算机将汇编语言转换为机器码时, 指导汇编过程,告诉汇编程序如何汇编。下面介绍一 些MCS-51汇编程序常用的伪指令。 (1)汇编起始伪指令ORG 格式:[标号:] ORG 16位地址 功能:规定程序块或数据块存放的起始地址。如: ORG 8000H START: MOV A ,#30H …… 该指令规定第一条指令从地址8000H单元开始存 放,即标号START的值为8000H。
(5)定义字命令 DW 格式:[标号:] DW 16位二进制数表 例如, ORG 1000H TAB: DW 1234H , 0ABH , 10 汇编后: (1000H)=12H (1001H ) = 34H (1002H ) = 00H ( 1003H ) = ABH (1004H ) =00H (1005H) =0AH DB、DW伪指令都只对程序存储器起作用,不能 用来对数据存储器的内容进行赋值或进行其它初始化 的工作。
(2)汇编结束伪指令END 格式:[标号:] END [表达式] 功能:结束汇编。 例如: ORG 2000H START: MOV A ,# 00H …… END START 表示标号START开始的程序段结束。 (3)等值指令EQU MOV A,TEST
(4)定义字节指令DB 格式:[标号:] DB 8位二进制数表 DB命令是从指定的地址单元开始,定义若干个8 位内存单元的内容。例如, ORG 1000H TAB; DB 23H,73, “6”, “B” TABl: DB 110B 以上伪指令经汇编以后,将对从1000H开始的若 干内存单元赋值: (1000H)=23H (1001H)=49H (1002H)=36H (1003H)=42H (1004H)=06H 其中36H和42H分别是字符6和B的ASCII码,其 余的十进制数(73)和二进制数(110B)也都换算为 十六进制数了。
伪指令和汇编语言

从指定单元开始,定义若干个字(双字节数)。
例如:
ORG 8000H
HETAB:
DW 7234H,8AH,10
汇编后则:
(8000H)=72H (8001H)=34H (8002H)=00H (8003H)=8AH (8004H)=00H (8005H)=0AH
03 常用旳伪指令
DS:定义空间命令
“DS <体现式>定义空间命令 格式: 标号: DS 数据或字符体现式 从指定单元开始,由数据或体现式 拟定保存若干个字节内存空间备用。 例如: ORG 8000H DS 08H DB 30H,8AH 即8000H~8007H单元保存备用 (8008H)=30H (8009H)=8AH
DATA和EQU旳区别在于DATA定义旳字符名称
作为标号登记在符号表中,故可先使用后定义;
而用EQU定义旳字符名称必须先定义后使用,其
原因是EQU不定义在符号表中。
03 常用旳伪指令
BIT:位地址符号命令
“
BIT<体现式>位地址符号命令
格式:
字符名称:
BIT 位地址
该命令把地址赋予标号段要求旳字符名称。
地址,位地址或立即数。
例如:
ORG 8000H
AA: EQU R6
;AA与R6等值
MOV A,AA
;A(R6)
…
03 常用旳伪指令
DATA:数据地址赋值命令
“ DATA<体现式>数据地址赋值命令 格式:
字符名称:
DATA 数据或体现式
此命令把数据地址或代码地址赋予标号段要求旳字符名称。
例如:INDEXJ DATA 8389H
定义了INDEXJ这个字符名称旳地址为8389H,主要用于
5-MCS-51单片机讲义(宏汇编伪指令)

第五章 MCS-51宏汇编伪指令伪指令是对汇编起某种控制作用的特殊命令,但自身并不产生机器码,不属于指令系统,而仅仅为汇编服务的一些指令,因此称为伪指令。
其格式与通常的操作指令一样,并可加在汇编程序的任何地方,但它们并不产生机器指令。
许多伪指令要求带参数,这在定义伪指令时由“表达式”域指出,任何数值与表达式均可以作为参数。
不同汇编程序允许的伪指令并不相同,以下所述的伪指令适用于Intel公司的MASM51系统,但一些基本的伪指令在大部份汇编程序中都能使用,当使用其它的汇编程序版本时,只要注意一下它们之间的区别就可以了。
MASM51中常用的伪指令共分为五大类:1. 程序计数与结束伪指令:ORG、END;2. 符号定义伪指令:EQU、SET、DATA、BYTE、WORD、BIT、ALTNAME、DB、DW、DS;3. 附加文件伪指令:INCLUDE;4. 程序清单格式化伪指令:TITLE、PAGE;5. 一般控制伪指令:LIST、NOLIST、NOCODE。
下面简要介绍一下各条伪指令的功能:5.1 ORG功能:程序计数伪指令,用于设置由表达式决定的初始地址,ORG也称为起始伪指令。
表达式缺省为0。
格式:ORG 16位地址例如:ORG 0100HSTART:MOV A,#05HADD A,#08HMOV 20H,AORG 0100H表示该伪指令下面第一条指令的起始地址是0100H,即“MOV A,#05H”指令的首字节地址为0100H,或标号START代表的地址为0100H。
5.2 END功能:是汇编语言源程序的结束标志。
在END以后所写的指令,汇编程序不再处理。
一个源程序只有一个END指令,放在所有指令的最后。
源程序中若没有END语句,汇编将报出错。
5.3 EQU功能:将一个数值或寄存器名赋给一个指定的符号名。
格式:符号名 EQU 表达式或符号名EQU 寄存器名符号名=表达式例如:DELY EQU 3344HDELY1 EQU 30HPP EQU R0ORG 0000HJMP MAINORG 0050HMAIN:MOV DPTR,#DELY ;(DPTR)=3344HMOV A,#DELY ;(A)=44HMOV A,#DELY1 (A)=30HMOV PP,#10 ;(PP)=10MOV A,PP ;(A)=10NOPEND5.4 SET功能:SET指令的功能与EQU指令类似,不同的是,用SET指令定义过的符号名可被重新定义。
汇编+C51程序解释

第一个闪烁的灯:(P2口接LED,P2输出低时LED点亮)/**************************************************** /ORG 0000H ;ORG伪指令,定义程序起始地址AJMP START ;跳转到真正的程序起始地址ORG 0040H ;定义START地址START: SETB P2.0 ;设置P2口第一位为高,则LED灭(本开发板LED接低电平亮) LCALL DELAY;调用延时程序CLR P2.0 ;清除P20端口,则LED亮LCALL DELAY ;调用延时程序AJMP START ;返回开始处继续执行之前的步骤DELAY: MOV R7,#250 ;延时的外循环数放在R7D1: MOV R6,#250 ;内循环数放在R6内D2: DJNZ R6,D2 ;R6内数据自减,直至为0则继续执行下一行代码DJNZ R7,D1 ;R7内数据自减,直至为0则继续执行下一行代码RET ;返回指令END ;伪代码,告诉编译器程序到此结束/**********************************************************/#include <reg51.h> //包含51系列单片机标准头文件sbit P20=P2^0; //定义P20为一个bit寄存器(sbit定义一个位寄存器的关键字)void delay(int k); //声明delay函数,有形参int kvoid main() //主函数开始{while (1) //死循环,即程序一直运行这里面的命令{P20=1; //P20为高,LED灭=SETB P20delay(300); //延时P20=0; //P20为低,LED亮=CLR P20delay(300); //延时}}void delay(int k) //延时函数{unsigned char i; //定义i为无符号字符型,最大255for( ;k>0;k--) //外循环{for(i=250;i>0;i--); //内循环}}第一个简单的LED流水灯:(P2口接LED,P2输出低时LED点亮)************************************************************************** ORG 0000H ;ORG伪指令,定义程序起始地址AJMP START ;跳转到真正的程序起始地址ORG 0040H ;定义START地址START: MOV A,#0FEH ;将寄存器A赋值FEH,即1111 1110MOV P2,A ;将A赋值给P2端口,即P2=1111 1110,最低位LED亮LCALL DELAY ;延时LOOP: RL A ;将A循环左移,即A=1111 1101MOV P2,A ;再将A赋值给P2,则当前P2=1111 1101,第二个LED亮LCALL DELAY ;延时CJNE A,#7FH,LOOP ;A=7FH=0111 1111,则结束循环,否则跳转到LOOP处执行AJMP START ;如果A=7FH了,则跳转到START处重新开始执行DELAY: MOV R7,#250 ;延时的外循环数放在R7D1: MOV R6,#250 ;内循环数放在R6内D2: DJNZ R6,D2 ;R6内数据自减,直至为0则继续执行下一行代码DJNZ R7,D1 ;R7内数据自减,直至为0则继续执行下一行代码RET ;返回指令END ;伪代码,告诉编译器程序到此结束************************************************************************** #include <reg51.h> //包含头文件#define LED P2 //宏定义LED,即编译时程序出现LED处均用P2来代替void delay(int k); //声明delay函数,有形参int kchar code tab[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//定义tab为代码型数组void main(void) //主函数开始{ int a; //定义a为变量LED=0xfe; delay(300);//P2=0xfe=1111 1110,最低位LED亮while(1) //循环体{for(a=1;a<8;a++) //8次循环体{LED=tab[a]; delay(300);//将数组内数据赋值给P2=tab[1]=0xfd=1111 1101}//for结束for(a=6;a>=0;a--) //7次循环体,为什么a=6???{LED=tab[a]; delay(300);//同上一个循环} //for结束} //while结束} //main结束void delay(int k) //延时函数{unsigned char i; //定义i为无符号字符型,最大255for( ;k>0;k--) //外循环{for(i=250;i>0;i--); //内循环}}一个按键控制流水灯(P1口接8接独立按键,按键按下拉低;P2口接LED,P2输出低LED点亮)************************************************************************** ORG 0000HAJMP STARTORG 0030HSTART: MOV P1,#0FFH; ;将P1写入1JB P1.0,$ ;等待P10=0,即P10被按下接地,我们的P1接了上拉电阻LCALL DELAY ;如果被按下了,延时125*200us,去除抖动JB P1.0,START ;再次判断是否被按下,是则顺序执行,否则跳转到STARTMOV A,#0FEH ;将寄存器A赋值FEH,即1111 1110MOV P2,A ;将A赋值给P2端口,即P2=1111 1110,最低位LED亮LCALL DELAY ;延时LOOP: RL A ;将A循环左移,即A=1111 1101MOV P2,A ;再将A赋值给P2,则当前P2=1111 1101,第二个LED亮LCALL DELAY ;延时CJNE A,#7FH, LOOP;当A=7FH是,LED已经循环完成1次AJMP START ;跳转到起始位置,接着等待按键DELAY: MOV R7,#250D1: MOV R6,#250D2: DJNZ R6,D2DJNZ R7,D1RETEND**************************************************************************#include <reg51.h>char code tab[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};sbit P10=P1^0; sbit P11=P1^1;void delay(int k);void main(){ char a; P2=0xfe;while(1) //等待P10被按下,则执行流水等程序,详见上节{ P1=0xff;delay(2000); //延时20ms左右去除抖动if(P10==0) //按下P10执行流水灯{ for(a=0;a<8;a++){ P2=tab[a];delay(60000);}}if(P11==0) //按下P11执行反向流水灯{ for(a=7;a>=0;a--){ P2=tab[a];delay(60000);}} }}void delay(int k) //最简单的C延时程序{ while(k--); } //直至K减为0则跳出利用中断方式实现一个灯的闪烁(P2口接LED阴极,LED阳极经过400欧电阻接VCC)************************************************************************** ORG 0000hAJMP STARTORG 000BH ;T0中断入口地址AJMP TIME0 ;跳转到真正的中断程序处START: CLR P2.0 ;取反p20,点亮最低位LEDMOV 30H,#0 ;30H地址置数,用于计算中断次数MOV TMOD,#00000001B ;设置定时器0,使用方式1,定时20msMOV TH0,#0B1H ;计数器初始值高8位MOV TL0,#0E0H ;计数器初始值低8位SETB EA ;开总中断允许位SETB ET0 ;开启T0定时器SETB TR0 ;开启T0定时器中断允许位AJMP $ ;死循环,等待中断产生TIME0: PUSH ACC ;进入中断首先将ACC\PSW压栈PUSH PSW ;然后重装计数器初始值MOV TH0,#0B1H ;计数器初始值高8位MOV TL0,#0E0H ;计数器初始值低8位INC 30H ;将30H内数据加1MOV A,30H ;然后判断是否计数到25次(即0.5秒)?CJNE A,#25,TIME01 ;未到25次,则跳转到TIME01处执行出栈操作CPL P2.0 ;到了25次,则取反P20端口MOV 30H,#0 ;同时将30H单元内数据清零TIME01: POP PSW ;出栈POP ACC ;出栈RETI ;中断返回用RETIEND ;伪指令,结束程序********************************************************************#include<reg51.h>sbit P20=P2^0;volatile int i; //声明一个变量为可能意外变化的量(相对于const而言)用语中断程序void main(){ P20=0; //先将P20位的LED点亮TMOD=0x01; //设置定时器T0工作在模式1TH0=0xb1; TL0=0xe0; //装T0的计数初值,12MHz,20ms计时EA=1; //开启总中断允许位ET0=1; //开启T0定时器TR0=1; //开启T0定时器中断允许位while(1); //循环等待中断发生}void time0(void) interrupt 1 //中断程序写法{ TH0=0xb1; TL0=0xe0; //重装T0的计数初值i++; if(i==25) //计数到25次(即0.5秒)??{i=0; //i清零P20=~P20;//取反LED端口,}}一个数码管循环显示0—F(P2口接数码管段码,P00接数码管阴极)**************************************************************************ORG 0000HAJMP STARTORG 0030HSTART: MOV 30H,#00H ;要显示的内容,写入30H单元内MAIN: MOV R5,#50 ;设置显示次数,越大时间越长main1: MOV A,30H ;将显示的数据送入A寄存器MOV DPTR,#TAB ;将TAB的地址送入DPTR寻址MOVC A,@A+DPTR ;将TAB+A处地址内的数据读出来送入A寄存器SETB P0.0 ;关闭数码管公共端,关闭显示,是为了去除显示重影MOV P2,A ;将这个数据写入P2段码端口CLR P0.0 ;打开显示LCALL DELAY ;调用延时程序DJNZ R5,main1 ;一共显示R5次INC 30H ;将30H内数据加1MOV A,30H ;将30H内数据送入寄存器A,继续上面的步骤CJNE A,#10H,MAIN ;判断是否到达16,是则运行下一行程序,否则跳转到MAIN AJMP START ;TAB为数码管显示段码值TAB: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH,77H,7CH,39H,5EH,79H,71HDELAY: MOV R7,#50D1: MOV R6,#250D2: DJNZ R6,D2DJNZ R7,D1RETEND**************************************************************************#include <reg51.h>#define SEG P2sbit P00=P0^0; //Tab为数码管显示值,存入一个数组内unsigned char code Tab[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71};void delay(int k); //延时函数,每次都会用到void main(){ int i;while(1){ for(i=0;i<16;i++) //循环16次,显示0-9,A,B,C,D,E,F一共16个数{P00=1; //将LED公共端置高,关闭显示,目的是为了去除显示重影SEG=Tab[i]; //将段码送到P2口,输出到LED段码端P00=0; //打开显示delay(50000);delay(50000); //延时,使人能看清楚}}}void delay(int k) //最简单的C延时程序{ while(k--); } //直至K减为0则跳出两个数码管循环显示00—99(P2口接数码管段码,P00接数码管各位阴极,P01接十位)************************************************************************** ORG 0000HLJMP STARTORG 0040HSTART: MOV 30H,#00H ;30H单元内放低位数据MOV 31H,#00H ;31H单元内放高位数据MOV P2,#00H ;将P2初始化为0CLR P0.1 ;设置低位显示0CLR P0.0 ;设置高位显示0LCALL DELY1 ;调用延时程序MAIN: MOV R5,#50 ;设置重复显示次数,越大显示时间越长LCALL DISP ;调用显示程序INC 30H ;将30内数据加1,即个位加1MOV A,30H ;将30H单元内数据送给A寄存器CJNE A,#0AH,MAIN ;判断30H内数据是否计到了10?未达到则跳转到MAINMOV 30H,#00H ;30H内数计到了10,则清零INC 31H ;并将31H内数据加1MOV A,31HCJNE A,#0AH,MAIN ;同理判断31H内数据是否到了10MOV 31H,#00H ;到了10则清零LJMP MAIN ;并跳转到MAIN处循环上面的过程DISP: SETB P0.1 ;首先关闭十位显示SETB P0.0 ;再关闭个位显示MOV A,30H ;MOV DPTR,#TAB ;将显示代码TAB地址送入DPTRMOVC A,@A+DPTR ;查询30H内数据的显示代码送入AMOV P2,A ;将查询到的代码送入P2显示CLR P0.1 ;打开个位显示刚才的数据LCALL DELY1 ;调用小的演示程序(10ms以内),形成视觉效果SETB P0.1 ;关闭个位显示MOV A,31H ;现在要显示31H内数据了MOV DPTR,#TAB ;将显示代码TAB地址送入DPTRMOVC A,@A+DPTR ;查询31H内数据的显示代码送入AMOV P2,A ;将查询到的代码送入P2显示CLR P0.0 ;打开十位显示刚才的数据LCALL DELY1 ;调用小的演示程序(10ms以内),形成视觉效果SETB P0.0 ;关闭显示DJNZ R5,DISP ;R5自减,不为0则跳转到DISPRET ;子程序返回TAB: DB 3FH,06H,5BH,4FHDB 66H,6DH,7DH,07HDB 7FH,6FH,77H,7CHDB 39H,5EH,79H,71HDELY1: MOV R7,#10D10: MOV R6,#250D20: DJNZ R6,D20DJNZ R7,D10RETEND************************************************************************** #include<reg51.h>sbit P0_0=P0^0; //个位数字sbit P0_1=P0^1; //十位数字void delay(int k); //Tab为数码管显示值,存入一个数组内unsigned char code Tab[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71};unsigned char i,shi,ge,num,count; //num为被显示的数字void main(){P2=Tab[0];P0_0=0;P0_1=0;//显示00num=0; //被显示的数置0count=20;while(1){for(i=1;i<count;i++) //显示个位、十位count次后显示的数加1{shi=num/10; //取出十位数ge=num%10; //取出个位数P0_0=1;P0_1=1; //关闭显示P2=Tab[shi]; //P2口送出十位数据显示代码P0_0=0; //打开十位显示delay(10); //延时P0_0=1; //关闭显示P2=Tab[ge]; //P2口送出个位数据显示代码P0_1=0; //打开个位显示delay(10); //延时}if(++num==100) //num自加1,然后判断是否等于100,等于则置0 num=0;}}void delay(int k) //最简单的C延时程序{unsigned char i;while(k--) //直至K减为0则跳出{for(i=250;i>0;i--);}}按键控制加、减显示00-99(P10为加,P11为减,P2接A- -H,P0接DS1- -DS8)********************************************************************************** #include<reg51.h>sbit P0_0=P0^0; //个位数字sbit P0_1=P0^1; //十位数字void delay(int k); //Tab为数码管显示值,存入一个数组内void key_ccan(void); //声明按键扫描函数unsigned char code Tab[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71};unsigned char i,shi,ge,num,count=10; //num为被显示的数字void main(){P2=Tab[0];P0_0=0;P0_1=0;//显示00num=0; //被显示的数置0while(1){key_ccan(); //调用按键扫描程序for(i=0;i<count;i++) //显示个位、十位count次后显示的数加1{shi=num/10; //取出十位数ge=num%10; //取出个位数P0_0=1;P0_1=1; //关闭显示P2=Tab[shi]; //P2口送出十位数据显示代码P0_0=0; //打开十位显示delay(10); //延时P0_0=1; //关闭显示P2=Tab[ge]; //P2口送出个位数据显示代码P0_1=0; //打开个位显示delay(10); //延时P0_1=1; //关闭个位显示}}}void key_ccan(void){unsigned char ii;P1=0xff;ii=P1;if(ii!=0xff){P1=0xff;delay(50);ii=P1;if(ii!=0xff){switch(ii){case 0xfe: num++;if(num==100) num=0;break;case 0xfd: if(num==0) num=99;else num--;break;default: break;}}}}void delay(int k) //最简单的C延时程序{ unsigned char i;while(k--) //直至K减为0则跳出{for(i=100;i>0;i--);}}定时器计数00-59(P0接ds1-ds8,P2接A-H)*******************************************************************************************#include<reg51.h>sbit P0_0=P0^0; //个位数字sbit P0_1=P0^1; //十位数字void delay(int k); //Tab为数码管显示值,存入一个数组内unsigned char ge,shi,num,count;unsigned char code Tab[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71};void main(){TMOD=0x1; //T0,工作方式1TH0=0xb1; //20ms定时TL0=0xe0;TR0=1; //开启T0定时器ET0=1; //允许T0定时器中断EA=1; //开启总中断允许P2=Tab[0];P0_0=0;P0_1=0;//显示00num=0; //被显示的数置0while(1) //一直调用显示,等待T0中断修改显示数据{shi=num/10; //取出十位数ge=num%10; //取出个位数P0_0=1;P0_1=1; //关闭显示P2=Tab[shi]; //P2口送出十位数据显示代码P0_0=0; //打开十位显示delay(1000); //延时P0_0=1; //关闭显示P2=Tab[ge]; //P2口送出个位数据显示代码P0_1=0; //打开个位显示delay(1000); //延时P0_1=1; //关闭个位显示}}void time0(void) interrupt 1{TH0=0xb1;TL0=0xe0;count++; //计数值+1if(count==50) //加到50次即1秒{ count=0;num++; //显示数据+1if(num==60){ num=0; }}}void delay(int k){while(k--);}定时器计数秒表000.0-999.9(P0接ds1-ds8,P2接A-H)*******************************************************************************************#include<reg51.h>sbit P0_0=P0^0; //百位数字sbit P0_1=P0^1; //十位数字sbit P0_2=P0^2; //个位数sbit P0_3=P0^3; //小数位void delay(int k); //Tab为数码管显示值,存入一个数组内unsigned char ge,shi,bai,xiao,count;unsigned int num;unsigned char code Tab[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71};void main(){TMOD=0x1; //T0,工作方式1TH0= 0xd8; //10ms定时TL0=0xf0;TR0=1; //开启T0定时器ET0=1; //允许T0定时器中断EA=1; //开启总中断允许P2=Tab[0];P0_0=0;P0_1=0;//显示00num=0; //被显示的数置0while(1) //一直调用显示,等待T0中断修改显示数据{bai=num/1000; //取出十位数shi=num%1000/100; //取出个位数ge=num%100/10;//第一位小数xiao=num%10; //第二位小数P0_0=0xff; //关闭显示P2=Tab[bai]; //P2口送出十位数据显示代码P0_0=0; //打开十位显示delay(200); //延时P0_0=1; //关闭显示P2=Tab[shi]; //P2口送出个位数据显示代码,各位要加小数点,即最高位为1则显示小数点P0_1=0; //打开个位显示delay(200); //延时P0_1=1; //关闭个位显示P2=Tab[ge]+0x80; //P2口送出第一个小数据显示代码P0_2=0; //打开十位显示delay(200); //延时P0_2=1; //关闭显示P2=Tab[xiao]; //P2口送出第二个笑数据显示代码P0_3=0; //打开个位显示delay(200); //延时P0_3=1; //关闭个位显示}}void time0(void) interrupt 1{TH0= 0xd8; //10ms定时TL0=0xf0;count++; //显示数据+1if(count==10) //显示数据计数到9999次即99.99秒{ count=0;if(num++==10000) num=0;}}void delay(int k){while(k--);}11。
51汇编伪指令详解

51汇编伪指令伪指令是对汇编起某种控制作用的特殊命令,其格式与通常的操作指令一样,并可加在汇编程序的任何地方,但它们并不产生机器指令。
许多伪指令要求带参数,这在定义伪指令时由“表达式”域指出,任何数值与表达式匀可以作为参数。
不同汇编程序允许的伪指令并不相同,以下所述的伪指令仅适用于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伪指令了。
51汇编伪指令详解word资料17页

51汇编伪指令伪指令是对汇编起某种控制作用的特殊命令,其格式与通常的操作指令一样,并可加在汇编程序的任何地方,但它们并不产生机器指令。
许多伪指令要求带参数,这在定义伪指令时由“表达式”域指出,任何数值与表达式匀可以作为参数。
不同汇编程序允许的伪指令并不相同,以下所述的伪指令仅适用于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伪指令了。
C51汇编指令

MCS51部分汇编指令8种常用伪指令1.ORG 16位地址;此指令用在原程序或数据块的开始,指明此语句后面目标程序或数据块存放的起始地址。
2.[标号:] DB 字节数据项表;将项表中的字节数据存放到从标号开始的连续字节单元中。
例如:SEG: DB 88H,100,“7”,“C”3.[标号:]DW 双字节数据项表;定义16位地址表,16地址按低位地址存低位字节,高位地址存高位字节。
例如:TAB: DW 1234H,7BH4.名字 EQU 表达式或名字=表达式;用与给一个表达式赋值或给字符串起名字。
之后名字可用做程序地址,数据地址或立即数地址使用。
名字必须是一字母开头的字母数字串。
例如:COUNT=10 或 SPACE EQU 10H 5.名字 DATA 直接字节地址;给8位内部RAMm单元起个名字,名字必须是一字母开头的字母数字串。
同一单元可起多个名字。
例如:ERROR DATA 80H 6.名字 XDATA 直接字节地址;给8位外部RAM起个名字,名字规定同DATA伪指令。
例如:IO_PORT XDATA 0CF04H7.名字 BIT 位指令;给一可位寻址的位单元起个名字,规定同DATA伪指令。
例如:SWT BIT 30H8.[标号:]END;指出源程序到此结束,汇编对其后的程序语句不予理睬.源程序只在主程序最后使用一个END定义指令符号符号说明Rn 目前所选定的寄存器组中的R0-R7寄存器Ri 当前选中的寄存器区中可作为地址寄存器的两个寄存器R0和R1(i=0,1)Direct8位直接寻址地址,可以是内存RAM地址(00H--7FH)或SFR(80H--FFH)@Ri 通过R0或R1做间接寻址内部RAM的地址(00H--FFH)的前缀#data 8位立即数#data1616位立即数,只有DPTR中才用到Addr 16 只用在LCALL(长指令调用,三字节)和LJMP(无条件长转移指令)指令中的16位目的地地址,可寻址64K存储器中的任何地址Addr 11 使用在ACALL(绝对调用指令,双字节)和AJMP(无条件绝对转移指令)指令中的11位目的地地址,可寻址下一个指令算起2K内的任何地址,即目的地址必须放在与下条指令第一个字节同一个2kB程序存储器空间DPTR 数据指针rel 有符号的8位偏移地址(Offset Address),其范围是从下一个指令算起的-128到+128字节中。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
51单片机汇编伪指令命令按字母排序:1、ALTNAME功能: 这一伪指令用来自定义名字,以替换源程序中原来的保留字,替换的保留字均可等效地用于子程序中。
格式: ALTNAME 保留字自定义名注意: 自定义名与保留字之间首字符必须相同。
1、BIT功能:指令用于将一个位地址赋给指定的符号名。
指令格式:符号名 BIT 位地址经BIT 指令定义过的位符号名不能更改。
例如:X_ON BIT 60H ;定义一个绝对位地址X_OFF BIT 24h.2 ;定义一个绝对位地址BIT---定义位命令格式:字符名称BIT 位地址其功能用于给字符名称定义位地址。
SPK BIT P3.7 经定义后,允许在指令中用SPK代替P3.7。
2、BSEG功能:绝对选择指令指令BSEG选择绝对位寻址数据段指令格式如下:BSEG [AT 绝对地址表达式]3、CODE功能:用于将程序存储器ROM 地址赋给指定的符号名。
指令格式:符号名 CODE 表达式例如:RESET CODE 00H4、CSEG功能:绝对选择指令CSEG选择绝对代码段;指令格式如下:CSEG [AT 绝对地址表达式]5、DATA(BYTE)功能:指令用于将一个内部RAM 的地址赋给指定的符号名指令格式:符号名 DATA 表达式数值表达式的值应在0~255 之间,表达式必须是一个简单再定位表达式。
例如:REGBUF DATA(BYTE) 40H PORT0 DATA(BYTE) 80HDATA与BYTE的区别: DATA与BYTE是相类似的伪指令。
当程序运行到DATA伪指令定义的符号名时,该符号名将被显示;而由BYTE定义的符号名不被显示。
6、DB功能:DB伪指令用于定义一个连续的存储区,给该存储区的存储单元赋值。
该伪指令的参数即为存储单元的值,在表达式中对变元个数没有限制,只要此条伪指令能容纳在源程序的一行内,其格式为:标号:DB 表达式只要表达式不是字符串,每一表达式值都被赋给一个字节。
计算表达式值时按16位处理,但其结果只取低8位,若多个表达式出现在一个DB伪指令中,它们必须以逗号分开。
表达式中有字符串时,以单引号“'”作分隔符,每个字符占一个字节,字符串不加改变地被存在各字节中,并不将小写字母转换成大写字母。
例如:DB 00H 01H 03H 46H DB 'This is a demo!'7、DBIT功能:在内部数据区的BIT 段以位为单位保留存储空间。
指令格式:[标号:] DBIT 数值表达式其操作类似于DB。
8、DS功能:DS为定义存储内容的伪指令,用它定义一个存储区,并用指定的参数填满该存储区。
DS伪指令包含两个变元,第一个变元定义了存储区的长度的字节数,在汇编时,汇编程序将跳过这些单元把其它指令汇编在这些字节之后,因此在使用DS伪指令时第一个变元不可活力第二个变元表示在这些单元中真入什么值,第二个变元可以活力活力时这些字节将不处理。
下例中0173处有一条DS 9,则空出9个字节,下一第指令被汇编到017C处;在017C处空出1BH 个单元,在这些字节中被27H所填充。
DS指令的格式如下:标号:DS 表达式1,表达式2表达式1定义了存储区的长度(以字节为单位)。
这个变元不能省略。
表达式2是可选择的,它的值低8位用以填入所定义的存储区。
若省略则这部分存储单元不处理。
例:0000 04 INC A0001 DS 9000A 04 INC A000B DS 1BH,27H0026 04 INC ADS ---预留存储区命令格式:〔标号:〕DS 表达式值其功能是从指定地址开始,定义一个存储区,以备源程序使用。
存储区预留的存储单元数由表达式的值决定。
TMP: DS 1 从标号TEP地址处开始保留1个存储单元(字节)。
9、DSEG功能:绝对选择指令DSEG内部绝对数据段指令格式如下:DSEG [AT 绝对地址表达式]10、DW功能:DW为以字节为单元(十六位二进制)来给一个的存储区赋值,其格式为:标号:DW 表达式例如:0000 3035 D46B DW 12341,54379,10110100101110B11、END功能:END语句标志源代码的结束,汇编程序遇到END语句即停止运行。
若没有END语句,汇编将报错。
END 语句有一个参数,可以是数值0,也可以是表达式,其格式是:标号: END 表达式它的值就是程序的地址并且作为一个特殊的记录写入HEX文件。
若这个表达式省略,HEX文件中其值就是0。
12、EQU(=)存器名赋给一个指定符号名。
指令格式:符号名 EQU(=)表达式符号名 EQU(=)寄存器名经过EQU 指令赋值的符号可在程序的其它地方使用,以代替其赋值。
例如:MAX EQU 2000则在程序的其它地方出现MAX,就用2000 代替。
表达式必须是一个简单再定位表达式。
用EQU 指令赋值以后的字符名,可以用作数据地址、代码地址、位地址或者直接当做一个立即数使用。
13、EXTRNEXTRN 是与PUBLIC 配套使用的,要调用其它模块的函数,就必须先在模块前声明。
指令格式:EXTRN 段类型(符号,符号······)例如:EXTRN CODE (TONGXING,ZHUANHUAN)调用外部TONGXING和ZHUANHUAN 程序。
14、IDATAIDATA 指令用于将一个间接寻址的内部RAM 地址赋给指定的符号名。
指令格式:符号名 IDATA 表达式例如:FULLER IDATA 60H15、IF条件伪操作格式:IF 表达式[ 程序块1 ][ ELSE ][ 程序块2 ]ENDIF当IF指令中的表达式为真时,被汇编的代码段是程序块1;当IF指令中的表达式为假时,被汇编的代码段是程序块2。
在一个条件结构中,仅有一个代码段被汇编,其它的则被忽略。
16、INCLUDE功能: 利用此伪指令可将一个源文件插入到当前源文件中一起汇编,最终成为一个完整的源程序。
格式: INCLUDE [ 驱动器名: ] [ 路径名 ] 文件名注意:1、文件名中若没有扩展名,则系统默认是。
ASM(该文件必须是能打开的)。
2、被插入的源程序中不能包含END伪指令,否则汇编会停止运行。
被链接文件的每一行,在程序清单中以“I“开头。
3、链接伪指令可有8级嵌套,若要求嵌套的多,则要修改 DOS 中的CONFIG。
SYS文件的FILES参数。
17、ISEG功能:绝对选择指令ISEG内部间接寻址绝对数据段idata指令格式如下:ISEG [AT 绝对地址表达式]18、MACRO宏指令格式[ 宏指令名 ] MACRO [形式参数,。
]代码段ENDM宏调用格式[ 宏指令名 ] [实在参数,。
]19、LIST它们的格式为:$LIST功能:LIST伪指令使汇编时主生程序清单,但即使不用该指令,汇编也会自动产生清单。
但如果使用了NOLIST伪指令后需要继续主生清单则必须使用LIST伪指令。
20、NAME功能:用来给当前模块命名。
指令格式:NAME 模块名例如:NAME TIMER定义一个模块名为TIMER 的模块。
21、NOCODE其格式为$NOCODE NOCODE伪指令使得在汇编时,条件汇编程序结构中那些真值为假的条件不产生清单。
有关条件汇编结构在下面介绍。
如果没有这条伪指令,汇编将主生所有条件下的清单,不论其真值是否为真。
但是假的条件,不产生目标码。
而NOCODE伪指令使汇编清单中只列出那些由汇编程序用到的部分,因此,当使用NOCODE伪指令时,程序清单与源程序并非逐行对应。
22、NOLIST它们的格式为:$NOLIST功能:NOLIST伪指令使汇编时不产生清单,所有包含此伪指令及在这条伪指令之后的语句都不进入列表文件。
当不需要任何列表文件,并且不需要显示程序清单时,可以在启动汇编时不加.L附加项,且在源代码的第一行加上NOLIST指令。
使用NOLIST伪指令与附加项/L不同之处是NOLIST伪指令可加在源程序中,与LIST伪指令配合使用,使源程序中某些部分不产生清单。
而不加附加项/L则不产生任何程序清单。
不过,不管有无$NOLIST伪指令,程序在汇编时检查到的错误都将在屏幕上显示出错的源代码行及错误信息23、PAGE功能:PAGE伪指令用于形成新的一中定义一面的行数。
其格式为:$PAGE表达式若表达式缺省则开始新的一页,若有表达式,则每页行数重新定义。
汇编开始时页长为66行。
一页中除出页外,剩余55行用于打印源程序,这一格式适用于标准打印纸。
如果变元值小于66,页内可打印的源代码行将相应减少。
页长最小值为12。
若小于12时,每页内除页上只打印一行源程序。
页长变元是16位字节,因而每页最长可定义到65535行,这时分页打印变为连续打印,在屏幕显示程序清单或在卷筒纸上打印程序清单时,常常使用连续打印,如果在启动汇编时用/N选项,页长就是65535。
24、PUBLIC功能:声明可被其它模块使用的公共函数名。
指令格式:PUBLIC 符号 [,符号,符号[,······]] PUBLIC 后可跟多个函数名,用逗号格开。
每个函数名都必须是在模块内定义过的。
例如:PUBLIC INTER,_OUTER其中_OUTER 可供C 调用。
25、RSEG功能:再定位段选择指令为RSEG,用于选择一个已在前面定义过的再定义段作为当前段,指令格式:RSEG 段名段名必须是在前面声明过的再定位段。
例如:DATAS SEGMENT DATA :声明一个再定位DATA 段CODES SEGMENT CODE ;声明一个再定位CODE 段BSEG AT 60HRSEG CODES ;选择前面声明的再定位CODE 段作为当前段。
绝对段选择指令CSEG---绝对代码段DSEG---内部绝对数据段XSEG---外部绝对数据段ISEG ---内部间接寻址数据段BSEG---绝对位寻址数据段格式:CSEG [AT 绝对地址表达式] DSEG [AT 绝对地址表达式] XSEG [AT 绝对地址表达式] ISEG [AT 绝对地址表达式] BSEG [AT 绝对地址表达式]括号内是可选项,用来指定当前绝对段的基地址。
CSEG AT 0000H AJMP MAIN26、SEGMENT功能:SEGMENT 指令用来声明一个再定位段和一个可选的再定位类型。
指令格式:再定位段型 SEGMENT 段类型(再定位类型)段类型用于指定所声明的段将处的储存器地址空间,可用的段类型有CODE/XDATA/DATA/IDATA 和BIT。
例如: FLAG SEGMENT BIT PONITER SEGMENT IDATA27、SET功能:SET 指令类似于EQU 指令,不同的是SET 指令定义过的符号可重定义。