1、DS ---预留存储区命令
格式: 〔标号:〕 DS   表达式值
其功能是从指定地址开始,定义一个存储区,以备源程序使用。存储区预留的存储单元数由表达式的值决定。

  ;从标号TEP地址处开始保留1个存储单元(字节)。 

2、BIT---定义位命令
格式:   字符名称   BIT   位地址
其功能用于给字符名称定义位地址。

SPK   BIT   P3.  ;经定义后,允许在指令中用SPK代替P3.7。 

3、USING指令
USING指令通知汇编器使用8051的哪一个工作寄存器组。
格式: USING 表达式 (值必须为0-3,默认值为0。)

USING   ;使用第0组工作寄存器。 

4、SEGMENT指令
SEGMENT 指令用来声明一个再定位段和一个可选的再定位类型。
格式: 再定位段名 SEGMENT 段类型〔再定位类型〕
其中,“再定位段名”用于指明所声明的段。“段类型”用于指定所声明的段将处的存储器地址空间。可用的段类型有 CODE、XDATA、DATA、IDATA和BIT。

STACK_SEG SEGMENT IDATA
DATA_SEG  SEGMENT DATA 

5、RSEG---再定位段选择指令
再定位段选择指令为RSEG,用于选择一个已在前面定义过的再定位段作为当前段
格式: RSEG 段名
段名必须是在前面已经声明过的再定位段。

DATA_SEG SEGMENT DATA   ;声明一个再定位DATA段
RSEG   DATA_SEG         ;选择前面声明的再定位DATA段作为当前段 

6、绝对段选择指令
CSEG---绝对代码段
DSEG---内部绝对数据段
XSEG---外部绝对数据段
ISEG---内部间接寻址数据段
BSEG---绝对位寻址数据段
格式:
CSEG [AT 绝对地址表达式]
DSEG [AT 绝对地址表达式]
XSEG [AT 绝对地址表达式]
ISEG [AT 绝对地址表达式]
BSEG [AT 绝对地址表达式]
括号内是可选项,用来指定当前绝对段的基地址

CSEG AT 0000H
AJMP MAIN 

7、ORG指令
ORG指令用来改变汇编器的计数器,从而设定一个新的程序起始地址。
格式: ORG 表达式
表达式必须是绝对或简单再定位表达式。

ORG 0000H
AJMP MAIN    ;设定 MAIN 程序的起始地址为 0x0000H。 

8、END指令
END指令用来控制汇编结束。在每个汇编程序的最后一行必须有一条END指令,并且END指令只能出现一次。

9、EQU指令
EQU 指令用于将一个数值或寄存器名赋给一个指定的符号名。
格式: 符号名   EQU   表达式
或     符号名   EQU   寄存器名
表达式必须是一个简单再定位表达式。
用 EQU 指令赋值以后的字符名,可以用作数据地址、代码地址、位地址或者直接当做一个立即数使用。

LIMIT   EQU
COUNT   EQU   R5 

10、DATA 指令
DATA 指令用于将一个内部 RAM 的地址赋给指定的符号名
格式: 符号名   DATA   表达式
数值表达式的值在 0-255 之间,表达式必须是一个简单再定位表达式。

PORT1   DATA   40H 

11、DB 指令
DB 指令以表达式的值的字节形式初始化代码空间。
格式: [标号:]   DB   表达式表
表达式中可包含符号、字符串、或表达式等项,各个项之间用逗号隔开,字符串应用引号括起来。括号内的标号是可选项,如果使用了标号,则标号的值将是表达式表中第一字节的地址。
DB 指令必须位于 CODE 段之内,否则将会发生错误。

TABLE:
DB 0C0H, 0F9H, 0A4H
TABLE1:
DB " 89C51 " 

51汇编程序基本框架
向大家介绍一种可以不用 EQU来定义变量的方法。
先说说用 EQU 定义变量的缺点:
1、人为为每一个变量指定地址,还必须注意防止地址冲突,工作量太大。
2、编译器只是把用 EQU 定义的标识符当作常数而已,在很多情况下当用户把该标识符用错时,编译器不会给出警告或报错。
  例如,假设想在 IDATA 区定义一个变量,如果用 EQU 方式作如下定义:

MYBYTE EQU 87H   ;(其实编译器只是将 MYBYTE 视为一个常量而已)如果想将该变量(位于 IDATA 区)赋值到累加器 A,正确的访问方式应该是
MOV R0,#MYBYTE
MOV A,@R0 

如果程序员将上面的语句错写为:

MOV A,MYBYTE  ;(原因可能是粗心,或者忘记了 MYBYTE 是大于 7FH 的) 

  编译器不会为此报错,结果执行的操作是将地址为 87H 的特殊功能寄存器的内容赋值到 A,而不是将 IDATA 区的 87H 赋值到 A,与用户的本意大相径庭。
  这只是一个例子,实际上还会有其它类似的问题。如果使用了下面描述的方式,则编译器会帮你指出此类错误。建议 EQU 只用于定义常数,不要做其它用途。
下面是一种比较好的变量定义方法,没有上面所说的缺点。
定义变量的方法:
1、定义字节变量用 DS 关键字,语法为:              变量名:    DS 分配的字节数
2、定义位变量用 DBIT 关键字,语法为:              位变量名: DBIT 分配的位数
3、定义特殊功能寄存器(SFR)用 DATA 关键字,语法为:        寄存器名:  DATA 寄存器地址
4、定义可位寻址的特殊功能寄存器中的位用 BIT 关键字,语法为:    位名:  BIT 位地址
5、常量定义用 EQU 关键字,语法为:                常量名:  EQU 常数

具体见如下示例:

;51汇编程序基本框架
$NOMOD51             ;不使用默认的 51 特殊功能寄存器定义$INCLUDE  (W79E825.INC)  ;用此语句可以包含头文件
;---------- 特殊功能寄存器定义 (仅作示范,不全)
    P0        DATA    080H
    SP        DATA    081H
    DPL       DATA    082H
    DPH       DATA    083H
    PCON      DATA    087H
    TCON     DATA    088H
    TMOD     DATA    089H
    TL0       DATA    08AH
    TL1       DATA    08BH
    TH0       DATA    08CH
    TH1       DATA    08DH
    P1     DATA    090H
    SCON      DATA    098H
    SBUF      DATA    099H
    P2        DATA    0A0H
    IE        DATA    0A8H
    PSW       DATA    0D0H

;---------- 可位寻址的特殊功能寄存器中的位定义(仅作示范,不全)
    BITIT0    BIT     TCON.        ;外部中断0触发方式
    BITIE0    BIT     TCON.        ;外部中断0标志
    BITIT1    BIT     TCON.        ;外部中断1触发方式
    BITIE1    BIT     TCON.        ;外部中断1标志
    BITTR0    BIT     TCON.        ;定时器0启动控制
    BITTF0    BIT     TCON.        ;定时器0溢出标志
    BITTR1    BIT     TCON.        ;定时器1启动控制
    BITTF1    BIT     TCON.        ;定时器1溢出标志
    BITRI     BIT     SCON.        ;接收中断标志
    BITTI     BIT     SCON.        ;发送中断标志
    BITRB8    BIT     SCON.
    BITTB8    BIT     SCON.
    BITREN    BIT     SCON.        ;接收使能
    BITSM2    BIT     SCON.        ;多机通信控制
    BITSM1    BIT     SCON.        ;串口模式位1
    BITSM0_FE BIT     SCON.        ;串口模式位0或FE

;---------- 常量定义
NSTACKSIZE    EQU                ;指定堆栈大小

;---------- 以下为变量定义
;如果MCU没有某些数据段,就删除或注释掉相应的段。
;变量定义有不可重定位和可重定位之分,这二种方式可混合使用。
;需要注意的是,某些编译器对可重定位方式支持的不是很好,
;而且可重定位方式对汇编不是很有用,所以建议不用可重定位方式。

;---- 下面为不可重定位的变量分配方式
; BSEG    关键词指定    BIT   区
; DSEG    关键词指定    DATA  区
; ISEG    关键词指定    IDATA 区
; XSEG    关键词指定    XDATA 区
; CSEG    关键词指定    CDATA 区
;注意:BIT 区的位地址 00H~7FH 范围与 DATA 区的20H~2FH范围是同一存储空间,
;所以在分配 DATA 区字节变量和 BIT 区位变量时要注意不要重叠。

BSEG    AT   00H        ;从 BIT 区的位地址 00H 开始分配位变量
    ;在 BIT 区定义一个位变量,位地址为 00H(即DATA区20H字节的第0位)
    ;在 BIT 区定义一个位变量,位地址为 01H(即DATA区20H字节的第1位)
    ;在 BIT 区定义一个位变量,位地址为 02H(即DATA区20H字节的第2位)

;在 DATA 区定义变量时要注意不要与 R0~R7 寄存器重叠。
DSEG    AT   08H        ;从 DATA 区的 08H 地址(为了避开 R0~R7)开始分配变量
    ;在 DATA 区定义一个 2 字节的变量,地址为 08H
    ;在 DATA 区定义一个 1 字节的变量,地址为 0AH
   ;注意不要与 BIT 区重叠,建议在地址 1FH 结束分配。
DSEG    AT   2EH        ;在 DATA 区的可位寻址区域定义可位寻址的字节变量
                        ;注意不要与前面在 BIT 区分配的 BIT 位重叠
    ;在 DATA 区定义一个 1 字节的变量,地址为 2EH(此变量可位寻址)
    ;在 DATA 区定义一个 1 字节的变量,地址为 2FH(此变量可位寻址)
DSEG    AT   30H        ;从 DATA 区的 30H 地址(已避开 BIT 区)开始分配变量
    ;在 DATA 区定义一个 1 字节的变量,地址为 30H
    ;在 DATA 区定义一个 3 字节的变量,地址为 31H
    ;在 DATA 区定义一个 1 字节的变量,地址为 34H
ISEG    AT   80H        ;从 IDATA 区的 80H 地址(为了避开 DATA 区)开始分配变量
    ;在 IDATA 区定义一个 1 字节的变量,地址为 80H
    ;在 IDATA 区定义一个 4 字节的变量,地址为 81H
ISEG    AT   -NSTACKSIZE    ;将堆栈放在 IDATA 区的末尾,首地址为 255-NSTACKSIZE
ISTACK:    DS    NSTACKSIZE    ;定义多字节变量,作为堆栈用(大小为 NSTACKSIZE),
                               ;见后面代码中的 “MOV   SP,#ISTACK”语句。
XSEG    AT   00H        ;从 XDATA 区的 00H 地址开始分配变量
    ;在 XDATA 区定义一个 1 字节的变量,地址为 00H
    ;在 XDATA 区定义一个 1 字节的变量,地址为 01H

;==============================================================================;
;CODE 段
    CSEG   AT          //程序起始地址
A_START:
    MOV    IE,#00H       ;关闭中断
    SJMP   A_MAIN
    CSEG   AT 0023H     //串口中断地址,其它中断地址的指定类似此方法。
    LJMP   A_UARTINT    //跳转到中断处理子函数
;==============================================================================;
A_MAIN:
    MOV  SP,#ISTACK    ;设置堆栈指针,
                        ;只能在调用任何函
                        ;数之前设定SP。
            ;将RS0,RS1及其它标志位清0。
                        ;注意:内存清零不要放在子函数中,
                        ;因为内存清零也会清零堆栈,
                        ;从而导致 RET 返回地址不正确!!!
    MOV  R0,#0FFH    ;内存00H~0FFH的内容清零。
    CLR  A
A_MAIN01:
    MOV  @R0,A
    DJNZ  R0,A_MAIN01

;用户初始化代码
...

A_LOOP: ;主循环
    ;用户代码
    LCALL _TEST
    SJMP   A_LOOP

;用户代码(子程序)
_TEST:
    NOP
    NOP
    RET

A_UARTINT: //串口中断处理子函数
    NOP
    NOP
    RETI
    END

;---------------------------------------------------------------------------

C51汇编伪指令的更多相关文章

  1. 《Intel汇编第5版》 条件汇编伪指令

    一.条件汇编伪指令和宏使用可以使汇编程序更加灵活 二.通过伪指令来检查函数的参数是否为空,如果为空则输出警告信息 INCLUDE Irvine32.inc includelib Irvine32.li ...

  2. C51汇编典型代码&一些org-mode技巧

    C51汇编典型代码&一些org-mode技巧 文档存放 具体内容可见存放的数据. 下面主要介绍关键代码. ASM 部分 1;; LCD数据发送========================= ...

  3. GNU汇编 伪指令

    伪指令 本身并没有所对应的机器码 它只是在编译的时候起作用,或者转换为其他的实际指令来运行 global ascii byte word data equ align @ 下面的例子是在数据段存放数据 ...

  4. keil or c51 汇编调用c语言函数 容易忽视的问题

    最近,在用keil 写一个小程序时,想实践一下从汇编调用 C语言函数,我们都知道C语言调用汇编函数讨论得较多,但反过来,从汇编中调用C语言的函数未见深入分析:在开始的时候,还是忽视了一个问题,就是对现 ...

  5. ARM GNU 常用汇编伪指令介绍

    abort .abort: 停止汇编 .align abs­expr1, abs­expr2: 以某种对齐方式,在未使用的存储区域填充值. 第一个值表示对齐方式,4, 8,16 或 32. 第 二个表 ...

  6. ARM汇编初探---汇编代码中都有哪几类指令---ARM伪指令介绍

    要学习一个东西首先要把概念搞清楚,以下仅仅是自己的一些关于汇编的理解. 可运行文件里的01码是机器码,机器码不等于汇编码,尽管机器码能够非常easy翻译成汇编码. 汇编码中包括非常多汇编指令.伪指令和 ...

  7. linux 汇编

    nasm的语法和大学教材上8086的汇编伪指令有些差别,指令都是一样的. 编辑器就是普通的编辑器,vim,emacs,gedit,kate源文件类型为ascii码的plain text 编译用gcc或 ...

  8. GNU-ARM汇编

    GNU ARM 汇编指令(2008-10-29 00:16:10) 标签:linux gnu arm 汇编指令 it 分类:技术文摘 第一部分 Linux下ARM汇编语法尽管在Linux下使用C或C+ ...

  9. 经常使用ARM汇编指令

    一面学习,一面总结,一面记录. 以下是整理在网上找到的一些资料,简单整理记录一下,方便以后查阅. ARM处理器的指令集能够分为跳转指令.数据处理指令.程序状态寄存器(PSR)处理指令.载入/存储指令. ...

随机推荐

  1. PSAM读卡芯片TDA8007BHL开发

    WWT:Work Waiting Time ATR:Answer To Reset,复位应答 etu =F/Df 1.     PSAM概述和应用 PSAM(PurchaseSecure Access ...

  2. js深入研究之牛逼的类封装设计

    <script type="text/javascript"> var Book = function(newIsbn, newTitle, newAuthor) { ...

  3. 2015第22周一Web性能测试工具及IE扩展区别

    在高性能web测试工具推荐http://www.jb51.net/article/23034.htm中发现了dynaTrace 感觉很不错,不但可以检测资源加载瀑布图,而且还能监控页面呈现时间,CPU ...

  4. c语言验证哥德巴赫猜想(从4开始 一个偶数由两个质数之和)

    #include <stdio.h> #include <stdlib.h> #include <math.h> int isit(int num) { int i ...

  5. Entify Framewrok - Join的使用方法

    问题:有2个表,使用id相连,如何用Join语法将其连接起来? 如下代码 List<tblAssociation> assoList = dataContext.tblAssociatio ...

  6. Java并发实现一(并发的实现之Thread和Runnable的区别)

    package com.subject01; public class ThreadOrRunnable { public static void main(String[] args) { Syst ...

  7. Android Studio编译好的apk放在哪里?

    Eclipse中编译好的apk文件时在bin文件中面的,可是在Android Studio有一个比較大的修改了,编译好的apk在android studio里面是直接看不到了,并且apk文件所在文件夹 ...

  8. js推断元素是否隐藏

    if( document.getElementById("div").css("display")==='none')   if( document.getEl ...

  9. 使用apktool解包和打包apk

    使用apktool解包和打包apk 下载apktool工具 解包 apktool d xxx.apk -f 植入代码 使用apktool解包要植入代码的apk(下面称为A), 使用apktool解包包 ...

  10. android调试系列--使用ida pro调试so

    1.工具介绍 IDA pro: 反汇编神器,可静态分析和动态调试. 模拟机或者真机:运行要调试的程序. 样本:阿里安全挑战赛第二题:http://pan.baidu.com/s/1eS9EXIM 2. ...