第4章 汇编语言程序设计

汇编语言语句格式

一、指令格式

[标号:]助记符 操作数1,操作数2 [;注释]
  • 标号:由1-8个字符组成,且第一个字符必须是字母。用于指示指令的地址。
  • 操作数:可使用二(B结尾)、十(D结尾或省略)、十六(H结尾)进制数和字符串(加" ")
  • 注释:为不可执行部分,对程序加以说明。

二、伪指令格式

伪指令是不可执行的指令,其功能是为汇编程序提供信息。常用伪指令有:

  1. 汇编起始地址命令:ORG
    格式: ORG 地址
    功能:规定程序的起始地址,省略时起始地址从0000H开始。

  2. 汇编终止命令:END
    格式: END 表达式
    功能:源程序汇编终止。在主程序模块中含有"表达式"给出程序的起始地址,在其它模块(子程序)中表达式可省略。

  3. 赋值命令:EQU
    格式:字符名称 EQU 表达式
    功能:将表达式的值赋给字符名称。表达式可以是常数、地址、标号和表达式。赋值之后的字符名称可以在程序中使用。

    例如:

    A1 EQU 20H
    B1 EQU A1
    C1 EQU 40H+10H
    .
    .
    .
    MOV A,# A1
    BAC: ADD A,C1
  4. 定义数据命令:DB、DW
    格式:[标号:] DB 字节数据项表
    功能:从指定地址(即标号)开始,在程序存储器中定义字节数据。

    格式: [标号:] DW 字数据项
    功能:从指定地址(即标号)开始,在程序存储器中定义16位字数据。高8位数据在低地址单元,低8位数据在高地址单元。

    例如:

    ORG 1000H
    TAB1: DB 1BH'A',-2128
    TAB2: DW 302AH34H

    存储格式如图:

    低 高
    TAB1 1BH
    41H
    FEH
    80H
    TAB2 30H
    2AH
    00H
    34H
  5. 定义存储区命令:DS
    格式: [标号:] DS 表达式
    功能:从指定地址(即标号)开始,保留指定数目(表达式的值)的字节单元作为存储区,供程序运行使用(用于程序存储器)。

    例如:

    ORG 2000H
    TAB: DS 05H
  6. 位定义命令:BIT
    格式:字符名称 BIT 位地址
    功能:将位地址赋给字符名称。位地址为绝对地址或符号地址。

    例如:

    HULED BIT P1.0

分支程序设计

分支程序是根据给出的条件满足与否执行不同的走向,基本结构分为单分支、双分支和多分支程序。

  1. 单分支结构
    给出的条件满足,则执行程序段 A,然后执行该指令下面的指令;若条件满不足,则不执行程序段 A,而是执行该指令下面的指令。

  2. 双分支结构
    给出的条件满足,则执行程序段 A,否则执行程序段 B。

  3. 多分支结构
    首先将分支按号进行排列,然后按序号的值来实现多分支选择。

循环程序设计

一、循环程序的基本结构

在基本设计中,控制一部分指令重复执行若干次,用简短的程序完成大量的处理任务,这种按某种控制规律重复执行的程序,称为循环程序。

  1. 先执行后判断结构
    特点是一进入循环先执行循环处理部分,然后根据循环控制条件判断是否结束循环,若不结束,则继续执行循环操作;若结束,退出循环。

  2. 先判断后执行结构
    特点是一进入循环先判断循环控制条件是否结束循环,若结束,退出循环,否则继续执行循环操作。

循环程序由以下四个基本组成部分:

  1. 置循环初值。设置循环开始的初始值,为循环做准备。如设计数器,工作单元初值。
  2. 循环处理。循环程序中重复执行的内容。
  3. 循环修改。修改循环参数,为执行下一次循环做准备。
  4. 循环控制。判断是否结束循环。

二、循环程序设计举例

通常采用"计数法"来控制循环,选择"先执行,后判断"循环结构。

例:多个单字节数求和
设:10 个字节的无符号数据依次存放在内部 RAM 40H开始的单元中,所求结果存放在 R3、R2中。本例循环次数已知,采用计数法控制循环。

源程序如下:

ORG 8000H
MOV R0#40H ;置数据指针
MOV R7#10 ;置计数器初值
MOV R3#0 ;结果单元清零
MOV R2#0 ;
LOOP1: MOV A,R2 ;取加数
ADD A,@R0 ;求和
MOV R2,A ;存结果低 8 位
JNC LOOP2 ;无进位,转LOOP2
INC R3 ;有进位,结果高 8 位加1
LOOP2: INC R0 ;修改指针
DJNZ R7,LOOP1 ;未完,继续
END

设计20ms延时程序
延时程序与MCS-51指令执行时间有很大的关系。在使用12MHz晶振时,一个机器周期为lμS,执行一个条"DJNZ"指令的时间为2μS,
20ms = 2μS×10000,
由于8位的计数值最大为256,这时可用双重循环方法
20ms = 2μS×100×100,

延时20ms程序如下的:

D20MS:MOV R4#100 ;20ms=2μS×100×100
; 外循环初值=100
DY1: MOV R3#100 ;内循环初值=100
DY2: DJNZ R3,DY2 ;100×2=200=0.2ms
DJNZ R4,DY1 ;0.2×100=20ms
RET

子程序设计

子程序的主要特点是:在执行过程中需要由其它程序来调用,执行完毕又需要把执行流程返回到调用该子程序的程序中。

在子程序调用过程中须解决以下两个方面的问题:

  • 程序之间的调用与返回;
  • 调用程序与被调用程序之间的参数传送。

程序设计举例

查表程序

在很多情况下,通过查表程序可以简化计算,简化程序的多分支结构,提高程序的运行效率。查表所使用的数据表格是按一定顺序排列的常数,存放在程序存储器中。

MCS-5l指令系统用于查表的指令有两条:

MOVC A,@A+DPTR
MOVC A,@A+PC

布尔处理程序

MCS-5l微处理器的一个最大特点就是它有很强的布尔处理能力,即对布尔变量(位变量)的处理能力,所以它最擅长开关量控制。

大部分硬件设计都是用组合逻辑实现复杂功能的。虽然所用硬件各式各样,但目的只有一个,那就是解若干布尔变量的逻辑函数所代表的问题。

例如,最常见的汽车头尾信号灯、电梯运行等都主要是用开关量控制的。

KEIL C51的应用

  • C语言是一种编译型程序设计语言,它兼顾了多种高级语言的特点,并具备汇编语言的功能。
  • 使用C语言进行程序设计已经成为软件开发的一个主流。
  • 用C语言开发系统可以大大缩短开发周期,明显增强程序的可读性,便于改进和扩充。
  • 而针对8051的C语言日趋成熟,成为了专业化的实用高级语言。

㈠ C-51的特点

C语言作为一种非常方便的语言而得到广泛的支持,国内最通用的是Keil C51.

C语言程序本身不依赖于机器硬件系统,基本上不作修改就可将程序从不同的单片机中移植过来。

C提供了很多数学函数并支持浮点运算,开发效率高,故可缩短开发时间,增加程序可读性和可维护性。

C-51与ASM-51相比,有如下优点:

  1. 对单片机的指令系统不要求了解,仅要求对8051 的存贮器结构有初步了解;
  2. 寄存器分配、不同存贮器的寻址及数据类型等细节可由编译器管理;
  3. 程序有规范的结构,可分成不同的函数,这种方式可使程序结构化;
  4. 具有将可变的选择与特殊操作组合在一起的能力,改善了程序的可读性;
  5. 提供的库包含许多标准子程序,具有较强的数据处理能力;
  6. 由于具有方便的模块化编程技术,使已编好程序可容易地移植;

C51存储类型

存储类型 寻址空间 数据长度 值域范围
data 片内直接寻址 RAM 8 0~127
idata 片内间接寻址 RAM 8 0~255
pdata 分页寻址片外 RAM 8 0~255
xdata 片外数据存储 (64K) 16 0~65535
code 片内统一编址ROM (64K) 16 0~65535
bdata 片内可位寻址的RAM (16byet) 1 0~127

C51的数据声明的一般格式如下:

[类型说明符][修饰符] 标识符[=初值]……

例如:unsigned char code Flag = 0x0f;就是声明一个无符号的char型变量Flag,并给他赋初值为0x0f;并且声明他所在的存储空间在片内统一编址的ROM中。

声明中,如果没有修饰符,则数据默认的存储空间为data型,也就是在片内RAM中。

㈡ C-51的程序结构

与一般C语言的结构相同,以main()函数为程序人口,程序体中包含若干语句还可以包含若干函数。

C-51函数的一般格式:

类型 函数名(参数表)
{
数据说明部分
语句执行部分
}

㈢ C-51的数据类型

基本数据类型:

类型 符号 关键字 所占位数 数的表示范围
整型 (signed) int 16 -32768~32767
(signed) short 16 -32768~32767
(signed) long 32 -2147483648~2147483647
unsigned int 16 0~65535
unsigned short int 16 0~65535
unsigned long int 32 0~4294967295
实型 float 32
double 64 1.7e-308~1.7e308
字符型 char 8 -128~127
unsigned char 8 0~255

扩充定义:

  • sfr: 特殊功能寄存器声明
  • sfr16: sfr的16位数据声明
  • sbit: 特殊功能位声明
  • bit: 位变量声明

例:

sfr SCON = 0X98;
sfr16 T2 = 0xCC;
sbit OV = PSW^2;

㈣ C-51数据的存储类型

名称 存储空间位置 长度 数据范围
data 直接寻址片内RAM 8位 0~255
bdata 可位寻址片内RAM 1位 0/1
idata 间接寻址片内RAM 8位 0~255
pdata 片外页RAM 8位 0~255
xdata 片外RAM 16位 0~65535
code 程序ROM 16位 0~65535

例:

数据类型 存储类型 变量
char data bit data unsigned
var1; flags; char xdata
vextor[10];

㈤ C-51的包含的头文件

通常有: reg51.h、math.h、ctype.h、stdio.h、stdlib.h、absacc.h

常用有:

  • reg51.h (定义特殊功能寄存器和位寄存器)
  • math.h (定义常用数学运算)

㈥ C-51的运算符

与C语言基本相同:

  • +-*/ (加、减、乘、除)
  • >>=<<= (大于、大于等于、小于、小于等于)
  • ==!= (测试等于、测试不等于)
  • &&||! (逻辑与、逻辑或、逻辑非)

㈦ C-51的基本语句

与标准C语言基本相同:

  • if 选择语言
  • switch/case 多分支选择语言
  • while 循环语言
  • do-while 循环语言
  • for 循环语言

㈧ 中断服务程序

函数名()interrupt n
{ }

㈨ I/O口定义

#include <absacc.h>
#define prot xbyte[0x1000]

或用指针定义

例:清零程序 (将2000H—20FFH的内容清零)

★ 汇编语言程序

ORG 0000H
SE01: MOV R0,#00H
MOV DPTR,#2000H ;(0000H)送DPTR
LOO1: CLR A
MOVX @DPTR,A ;0送(DPTR)
INC DPTR ;DPTR+1
INC R0 ;字节数加1
CJNE R0,#00H,LOO1 ;不到FF个字节再清
LOOP: SJMP LOOP

★ C-51程序

#include <reg51.h>
main( )
{
int i;
unsigned char xdata *p=0x2000;
/* 指针指向2000H单元 */
for(i=0;i<256;i++)
{*p=0; p++;} /*清零2000H-20FFH单元*/
}