文档库 最新最全的文档下载
当前位置:文档库 › keil+A51

keil+A51

keil+A51
keil+A51

宏汇编器及相关应用程序

宏汇编器,连接/定位器,

库管理器,用于8051、扩展型

8051和251微控制器的库管理器

用户手册

2001年2月

编译说明

这是罗亩在学习A51的过程中,为了使用方便而翻译整理的,由于没有多少时间检查较对,而且其中好多译法也没有深入研究,所以错误的地方可能比较多,还请各位同好斧正。

非常感谢21IC为我提供了一个可以记录我的学习、工作历程的空间,欢迎大家加入21IC,欢迎大家访问我的笔记:

https://www.wendangku.net/doc/4c13532625.html,

本手册的原文版权归Keil公司所有,中文版权归罗亩所有,请各位同好只用来学习参考,不要用作其它用途。

罗亩

2006年8月

本手册讲述如何使用 A51、AX51 和 A251 宏汇编器(罗亩按:此处将Assembler译作汇编器,以便与汇编程序(Assembly Program)区分),以及相关的应用程序,这些程序的作用是把汇编源代码翻译为可执行程序,以在8051或其变型,如Philips 80C51MX和Intel / Atmel WM 251器件上运行。本手册假定你熟悉Windows操作系统,并且知道如何将可执行程序装入微处理器中。

“第1章. 简介”,大体浏览一下不同的汇编器版本,讲解一些基本的汇编语言编程知识。

“第2章、架构”,大致讲解一下8051,扩展型8051,Philips 80C51MX和Intel / Atmel WM 251器件。

“第3章、编写汇编程序”,讲解汇编语句和算术、逻辑表达式的规则。

“第4章、汇编程序的伪指令”,讲解如何定义段和符号,以及所有伪指令的使用方法。

“第5章、汇编程序的宏”,讲解标准宏的功能,以及应用标准宏的一些知识。

“第6章、宏处理语言”,定义和讲解英特尔宏处理语言的应用。

“第7章、调用和控制”,讲解如何调用汇编器,如何控制汇编器的运行。

“第8章、错误信息”,列出了所有的汇编器错误信息,并说明导致出错的原因,以及怎样避免。

“第9章、连接/定位器”,包括所有连接/定位器伪指令的参考部分,还有例子和详细的说明。

“第10章、库管理器”,讲解如何制作和管理自己的库文件。

“第11章、目标文件-16制文件(Object-Hex)转换器”,说明如何生成英特尔16进制文件。

附录中包含程序举例,不同版本汇编器之间的区别,以及其他一些大家感兴趣的项目。

行文惯例(略)

第1章简介

本手册讲述的是用于传统的8051、扩展型8051和251微处理器家族的宏汇编器和相关软件,以及使用汇编语言为这些微处理器开发软件的过程。

传统的8051、扩展型8051和251的架构将在“第2章架构概览”中作一下简短的讲解。其中,对传统的8051处理器、扩展型8051不同版本的处理器和251处理器之间的区别作了讲解。对于微处理器架构最完整的信息,请参照你所用的微处理器的硬件参考手册。

为了实现对不同的8051和251变型产品的最优化支持,Keil提供了以下开发工具:

开发工具支持的微处理器,说明

A51宏汇编器

BL51连接/定位器LIB51库管理器用于传统型8051的开发工具包含对32×64KB代码堆的支持

AX51宏汇编器

LX51扩展型连接/定位器LIBX51库管理器用于传统型和扩展型8051(菲利浦80C51MX,达拉斯390,等等)的开发工具

最多支持16MB代码和XDATA存储空间。

A251宏汇编器

L251连接/定位器

LIB251库管理器

用于Intel / Atmel 251的开发工具。

AX51和A251汇编器是A51汇编器的扩展集。该用户向导覆盖了所有的开发工具版本。每当有一个特点或选项是某种工具专有的时,都已经清楚地标注出来。

下表列出了所有工具的版本和微处理器架构:

项目所指

Ax51宏汇编器A51,AX51和A251宏汇编器

Cx51编译器C51,CX51,C251 ANSI C编译器

Lx51连接/定位器BL51,LX51和L251连接/定位器

LIBx51库管理器LIB51,LIBX51和LIB251库管理器

OHx51目标-16进制转换器OH51,OHX51和OH251目标-16进制转换器

x51架构或x51器件所有的传统8051,扩展8051和251器件类型

如何开发一个程序

该部分大致讲解一下Ax51宏汇编器,Lx51连接/定位器及其应用。

什么是汇编器?

汇编器是一种软件工具,作用是简化编写计算机程序的任务。它可以将符号代码翻译为可执行的目标代码。该目标代码可以被编写进微处理器中,并被执行。汇编语言程序可直接被翻译为CPU指令,控制处理器完成运算。所以,要想有效地编写汇编程序,你应该既熟悉微处理器的架构,又熟悉汇编语言。

汇编语言的操作代码(助记符)很容易记忆(如MOV代表转移指令,ADD代表加法指令,等等)。对于指令操作数中的地址和数值,我们也可以把它们符号化。当我们为它们命名时,应尽量使它们的名称像指令助记符一样具有意义。例如,如果我们的程序必须处理一个日期数据,我们可以把它命名为DATE。如果我们的程序包含一组指令,它们完成一个定时循环(一组指令被重复执行,直到过去指定长度的时间为止),那么我们可以把这一程序组命名为TIMER_LOOP。

一个汇编程序由三部分组成:

?机器指令

?汇编器伪指令

?汇编器控制指令

一条机器指令就是一条机器代码,它可以被机器执行。关于机器指令的详细论述,请参考8051或其派生微处理器的硬件手册。附录A对机器指令作了一下概述。

汇编器伪指令是用来定义程序结构和符号的,并生成不可执行的代码(数据、信息,等)。参见“第4章汇编器伪指令”对所有汇编器伪指令的详细讨论。

汇编器控制指令设定汇编模式,并控制汇编流向。“第7章调用和控制指令”对所有的汇编器伪指令作了详细论述。

模块化编程

许多程序太长或太复杂,很难写在单一单元中。如果把代码分为较小的功能单元,将大大简化编程过程。模块化程序一般比单块程序容易编写、调试和修改。

模块化编程方法类似于包含大量电路的硬件设计。器件或程序在逻辑上被分为多个“黑箱子”,这些黑箱子都有指定的输入和输出。只要把各个单元之间的接口定义好,各个单元的详细设计就可以独立进行了。

模块化编程的优点如下:

更有效的程序开发:使用模块化方法可以更快地开发程序,因为较小的子程序比大程序更容易理解、设计和测试。定义好模块的输入和输出之后,程序员可以给模块提供需要的输入,通过检测输出来判断模块的正确性。然后由连接器把分立的模块连接、定位,生成一个单一的绝对地址的可执行的程序模块。最后,测试整个模块。

子程序可以重复利用:为一个程序编写的代码经常可以用于其它的程序中。在模块化编程中,可以把这些部分保存起来,以备将来使用。因为代码可以被重定位,所以保存的模块可以连接到满足其输入和输出要求的任意程序中。而在单块程序编程中,这样的部分深埋在整个程序中,不易被其它的程序使用。

便于调试和修改:模块化程序一般比单块程序易于调试。因为精心定义了程序的模块接口,很容易把问题定位到特定的模块。一旦找到了有问题的模块,改正问题就相当容易了。模块化编程可以简化程序修改的工作。我们可以很有信心地把新的或调试过的模块连接到一个已有的程序,而不用更改程序的其余部分。

下图是为x51开发程序的总体步骤。

模块化程序开发过程

这一部分简要讨论一下可重定位的Ax51汇编器,Lx51连接/定位器,以及OHx51编码转换器。

段、模块和程序

在初始设计阶段,首先定义程序要完成的任务,然后分为各个子程序。下面简要介绍一下使用Ax51汇编器和Lx51连接/定位器的子程序的种类。

一个段是一个程序块或数据块。一个段既可以是可重定位的,也可以是绝对的。一个可重定位的段有一个名字,类型,和其它的特性。名称相同、来自不同模块的段被认为是同一个段的一部分,它们叫做部分段。几个名称相同的部分段由Lx51连接/定位器结合为一个段。一个绝对段不能与其它段相结合。

一个模块包含一个或多个段或部分段。模块是一个源代码单元,可以被单独编译。它包含模块中使用的所有符号的定义。一个模块可以是单个由标准文本编辑器制作的ASCII文本文件。但是,你可以用include汇编伪指令把几个文本文件合并在一起。Ax51编译器把一个源文件编译为一个目标文件(object file)。每个目标文件就是一个模块。

当程序的所有模块都汇编完毕后,就由Lx51处理目标模块文件。Lx51连接/定位器给所有的可重定位的段分配绝对地址,把名称和类型相同的部分段合并起来。Lx51也分解模块间的所有引用。Lx51输出整个程序的一个绝对目标模块文件,和一个地图文件(map file),列出连接/定位过程的结果。

翻译和连接过程

一般地,我们会在μVersion2集成开发环境(IDE)中使用Ax51汇编器和其它工具。参见μVersion2用户手册:8051入门,以获取使用μVersion2集成开发环境的更多信息。

当然,我们也可以在命令行(罗亩按:在Windows中仿DOS的窗口,如果您没有学过DOS,可以略过这一部分)中调用Ax51汇编器。在Windows命令行中输入你想使用的汇编器版本的名称,例如A51。在这一命令行中,我们必须输入要被翻译的汇编源文件的名称,以及其它一些需要用来控制源文件翻译过程的控制指令。例如:

A51 DEMO.A51

回车后,汇编器输出如下:

A51 MACRO ASSEMBLER V6.00

ASSEMBLY COMPLETE. 0 WARNING(S), 0 ERROR(S)

所有的程序模块汇编完毕后,将由Lx51把目标模块连接起来,所有的变量和地址都被解析并定位到一个可执行程序中。下例所示为使用连接器的一条简单命令:

BL51 DEMO.OBJ, PRINT.OBJ

连接器生成一个绝对地址的目标文件和一个地图文件,地图文件中包含详细的静态信息和屏幕信息。连接器的输出如下:

BL51 LINKER/LOCATER V4.00

LINK/LOCATE RUN COMPLETE. 0 WARNING(S), 0 ERROR(S)

然后我们可以把可执行程序转换为Intel HEX文件,以编入PROM。这要用到OHx51十六进制转换程序,调用命令如下:

OH51 DEMO

转换程序的输出如下:

OBJECT TO HEX FILE CONVERTER OH51 V2.40

GENERATING INTEL HEX FILE: DEMO.HEX

OBJECT TO HEX CONVERSION COMPLETED.

由汇编器生成的一个列表文件例子。

A51 MACRO ASSEMBLER ASSEMBLER DEMO PROGRAM 07/07/2000 18:32:30 PAGE 1

MACRO ASSEMBLER A51 V6.01

OBJECT MODULE PLACED IN demo.OBJ

ASSEMBLER INVOKED BY: C:\KEIL\C51\BIN\A51.EXE DEMO.A51 DEBUG

LOC OBJ LINE SOURCE

1 $title (ASSEMBLER DEMO PROGRAM)

2 ; 一个简单的示例汇编模块

3

4 ; 符号定义

000D 5 CR EQU 13 ; Carriage?Return 进位?返回

000A 6 LF EQU 10 ; Line?Feed

7

8 ; 定义段

9 ?PR?DEMO SEGMENT CODE ; 程序部分

10 ?CO?DEMO SEGMENT CODE ; 常数部分

11

12 ; Extern Definition 外部定义

13 EXTRN CODE (PRINTS, DEMO)

14

15 ; 程序部分开始

_ _ _ _ 16 CSEG AT 0 ; Reset Vector 复位失量0000 020000 F 17 JMP Start

18

_ _ _ _ 19 RSEG ?PR?DEMO ; 程序部分

0000 900000 F 20 START: MOV DPTR, #Txt ; 示例文本

0003 120000 F 21 CALL PRINTS ; 打印字符串

22

0006 020000 F 23 JMP DEMO ; 示例程序

24

25 ; 文本常量

_ _ _ _ 26 RSEG ?CO?DEMO ; 常量部分

27 Txt: DB ‘Hello World’, CR, LF, 0

0000 48656C6C

0004 6F20576F

0008 726C640D

000C 0A00

28

29 END ; 模块结束SYMBOL TABLE LISTING

_ _ _ _ _ _ _ _ _ _ _ _ _ _ _

N A M E T Y P E V A L U E ATTRIBUTES

?CO?DEMO . . . . . C SEG 000EH REL=UNIT

?PR?DEMO . . . . . C SEG 0009H REL=UNIT

CR . . . . . . . . N NUMB 000DH A

DEMO . . . . . . . C ADDR _ _ _ _ _ EXT

LF . . . . . . . . N NUMB 000AH A

PRINTS . . . . . . C ADDR _ _ _ _ _ EXT

START. . . . . . . C ADDR 0000H R SEG=?PR?DEMO TXT. . . . . . . . C ADDR 0000H R SEG=?CO?DEMO

REGISTER BANK(S) USED: 0

ASSEMBLY COMPLETE. 0 WARNING(S), 0 ERROR(S)

文件的扩展名

一般地,文件扩展名是用来标志文件内容的。下表列出8051工具链中用到的文件扩展名。

扩展名内容描述

.A51

.ASM

.SRC

源代码文件:包含ASCII文本,是Ax51编译器的输入文件。

.C

.C51

C源代码文件:包含ASCII文本,是Cx51 ANSI C编译器的输入文件。

.INC .H 包含文件:包含ASCII文本,将由include伪指令合并入一个源代码文件中。它们也是Ax51或Cx51的输入文件。

.OBJ 可重定位目标文件:是Ax51或Cx51的输出文件,包含程序代码和控制信息。

几个可重定位的目标文件是Lx51连接/定位器的典型输入文件。

.LST 列表目标文件:由Ax51或Cx51生成,是用来记录编译过程的。一个典型的列表文件包含ASCII程序文本和有关源模块的诊断信息。

. (无后缀).ABS 绝对目标文件:是Lx51的输出文件。典型地,它是一个完整的程序,可以在x51 CPU上执行。

.M51 .MAP 连接器地图文件:是由Lx51生成的列表文件。一个地图文件包含内存使用的信息和其它静态信息。

.HEX .H86 Hex文件:是OHx51目标文件-16进制转换器的输出文件,文件格式为Intel HEX。HEX是PROM编程器或其它应用程序的输入文件。

程序模板文件

下面的模板文件包含了编写汇编程序模块的指导原则和提示。该模板文件位于文件夹\C51\ASM或\C251\ASM中。罗亩对其中的英文说明作了一下汉化。

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

; Source code template for A251/A51 assembler modules.

; A251/A51汇编模块的源代码模板。

; Copyright (c) 1995-2000 KEIL Software, Inc.

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

$NOMOD51 ; disable predefined 8051 registers

; 禁能预定义的 8051 寄存器

#include // include CPU definition file (for example, 8052)

// 包含 CPU 定义文件(例如,8052)

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

; Change names in lowercase to suit your needs.

; 把名称改为小写来适合你的要求。

;

; This assembly template gives you an idea of how to use the A251/A51

; Assembler. You are not required to build each module this way-this is only

; an example.

; 该汇编模板给你一个如何使用 A251/A51汇编器的概念。你不需要按这种方式建立

; 每个模块——这只是一个例子。

;

; All entries except the END statement at the End Of File are optional.

; 除了文件末尾的 END 语句外,所有语句都是可选的。

;

; If you use this template, make sure you remove any unused segment declarations,

; as well as unused variable space and assembly instructions.

; 如果您使用该模板,一定要把不用的段声明、以及不用的变量空间和汇编指令

; 全部去掉。

;

; This file cannot provide for every possible use of the A251/A51 Assembler.

; 该文件并未包含 A251/A51 汇编器的所有应用。

; Refer to the A51/A251 User's Guide for more information.

; 参见 A51/A251 用户手册以获取更多信息。

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

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

; Module name (optional)

; 模块名称(可选)

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

NAME module_name

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

; Here, you may import symbols from other modules.

; 你可以从其它模块把符号导入到此处。

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

EXTRN CODE (code_symbol) ; May be a subroutine entry declared in

; CODE segments or with CODE directive.

; 可以是在 CODE 段中或用伪指令CODE

; 声明的子程序入口

EXTRN DATA (data_symbol) ; May be any symbol declared in DATA segments

; segments or with DATA directive.

; 可以是在 DATA 段中或用伪指令 DATA

; 声明的的任意符号。

EXTRN BIT (bit_symbol) ; May be any symbol declared in BIT segments

; or with BIT directive.

; 可以是在 BIT 段中或用伪指令 BIT

; 声明的任意符号。

EXTRN XDATA (xdata_symbol) ; May be any symbol declared in XDATA segments

; or with XDATA directive.

; 可以是在 XDATA 段中或用伪指令 XDATA

; 定义的任意符号。

EXTRN NUMBER (typeless_symbol); May be any symbol declared with EQU or SET

; directive

; 可以是用伪指令 EQU 或 SET 声明的任意符号

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

; You may include more than one symbol in an EXTRN statement.

; 在一条 EXTRN 语句中,你可以包含多个符号。

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

EXTRN CODE (sub_routine1, sub_routine2), DATA (variable_1)

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

; Force a page break in the listing file.

; 在列表文件中强制换页。

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

$EJECT

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

; Here, you may export symbols to other modules.

; 此处,你可以把符号输出到其它模块。

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

PUBLIC data_variable

PUBLIC code_entry

PUBLIC typeless_number

PUBLIC xdata_variable

PUBLIC bit_variable

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

; You may include more than one symbol in a PUBLIC statement.

在一条 PUBLIC 语句中,你可以包含多个符号。

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

PUBLIC data_variable1, code_table, typeless_num1, xdata_variable1

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

; Put the STACK segment in the main module.

; 把堆栈 (STACK) 段置于主模块中。

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

?STACK SEGMENT IDATA ; ?STACK goes into IDATA RAM.

; 把 ?STACK 定义在IDATA RAM 中。

RSEG ?STACK ; switch to ?STACK segment.

; 切换到 ?STACK 段。

DS 5 ; reserve your stack space

; 5 bytes in this example.

; 在本例中保留 5 个字节的堆栈空间$EJECT

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

; Put segment and variable declarations here.

; 把段和变量声明放在此处。

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

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

; DATA SEGMENT--Reserves space in DATA RAM--Delete this segment if not used.

; DATA SEGMENT—在 DATA RAM中预留空间—如果不用的话就删掉。

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

data_seg_name SEGMENT DATA ; segment for DATA RAM.

; 声明一个 DATA RAM 段

RSEG data_seg_name ; switch to this data segment

; 切换到该数据段

data_variable: DS 1 ; reserve 1 Bytes for data_variable

; 为data_variable 预留1个字节

data_variable1: DS 2 ; reserve 2 Bytes for data_variable1

; 为data_variable1 预留2个字节

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

; XDATA SEGMENT--Reserves space in XDATA RAM--Delete this segment if not used. ; XDATA SEGMENT--在XDATA RAM 中预留空间—如果不用的话就删掉。

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

xdata_seg_name SEGMENT XDATA ; segment for XDATA RAM

; 声明一个 XDATA RAM 段

RSEG xdata_seg_name ; switch to this xdata segment

; 切换到该数据段

xdata_variable: DS 1 ; reserve 1 Bytes for xdata_variable

; 为xdata_variable 预留1个字节xdata_array: DS 500 ; reserve 500 Bytes for xdata_array

; 为xdata_array 预留500个字节

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

; INPAGE XDATA SEGMENT--Reserves space in XDATA RAM page (page size: 256 Bytes)

; INPAGE XDATA SEGMENT—在 XDATA RAM 页中预留空间(页大小: 256 Bytes)

; INPAGE segments are useful for @R0 addressing methodes.

; 对于 @R0 寻址模式 INPAGE 非常有用。

; Delete this segment if not used.

; 如果不用的话就删掉该段。

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

page_xdata_seg SEGMENT XDATA INPAGE ; INPAGE segment for XDATA RAM

; 声明一个 XDATA RAM 的INPAGE段 RSEG xdata_seg_name ; switch to this xdata segment

; 切换到该xdata 段

xdata_variable1:DS 1 ; reserve 1 Byte for xdata_variable1

; 为变量 xdata_variable1 预留1个字节

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

; ABSOLUTE XDATA SEGMENT--Reserves space in XDATA RAM at absolute addresses.

; ABSOLUTE XDATA SEGMENT—在XDATA RAM 中预留绝对地址的空间。

; ABSOLUTE segments are useful for memory mapped I/O.

; 绝对段对于内存映射 I/O 非常有用。

; Delete this segment if not used.

; 如果不用的话就删掉该段。

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

XSEG AT 8000H ; switch absolute XDATA segment @ 8000H

; 切换到绝对地址 XDATA 段到8000H XIO: DS 1 ; reserve 1 Byte for XIO port

; 为XIO 口预留一个字节。XCONFIG: DS 1 ; reserve 1 Byte for XCONFIG port

; 为XCONFIG 口预留一个字节。

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

; BIT SEGMENT--Reserves space in BIT RAM--Delete segment if not used.

; BIT SEGMENT—在BIT RAM 中预留空间—如果不用的话就删掉。

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

bit_seg_name SEGMENT BIT ; segment for BIT RAM.

; 声明一个位于 BIT RAM 中的段

RSEG bit_seg_name ; switch to this bit segment

; 切换到该 bit 段。

bit_variable: DBIT 1 ; reserve 1 Bit for bit_variable

bit_variable1: DBIT 4 ; reserve 4 Bits for bit_variable1

; 为bit_variable1 预留4位

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

; Add constant (typeless) numbers here.

; 把常量(无符号)数值加在此处。

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

typeless_number EQU 0DH ; assign 0D hex

; 赋给 16 进制数 0D typeless_num1 EQU typeless_number-8 ; evaluate typeless_num1

; 计算typeless_num1 $EJECT

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

; Provide an LJMP to start at the reset address (address 0) in the main module.

; 提供一个 LJMP 到主模块中位于复位地址(地址0)处的 start 。

; You may use this style for interrupt service routines.

; 你可以把这种方法用于中断服务程序。

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

CSEG AT 0 ; absolute Segment at Address 0

; 位于地址 0 的绝对段。

LJMP start ; reset location (jump to start)

; 复位地址(跳转到 start)

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

; CODE SEGMENT--Reserves space in CODE ROM for assembler instructions.

; CODE SEGMENT—为汇编器指令在 CODE ROM 中预留空间。

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

code_seg_name SEGMENT CODE

RSEG code_seg_name ; switch to this code segment

; 切换到该代码段

USING 0 ; state register_bank used

; for the following program code.

; 用来跟踪程序代码的状态寄存器堆。

start: MOV SP,#?STACK-1 ; assign stack at beginning

; 在程序开始前分配堆栈

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

; Insert your assembly program here. Note, the code below is non-functional.

; 把你的汇编程序插在此处。注意,下面的代码没有任何实际功能。

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

ORL IE,#82H ; enable interrupt system (timer 0)

; 使能中断系统(定时器0)

SETB TR0 ; enable timer 0

; 使能定时器0

repeat_label: MOV A,data_symbol

ADD A,#typeless_symbol

CALL code_symbol

MOV DPTR,#xdata_symbol

MOVX A,@DPTR

MOV R1,A

PUSH AR1

CALL sub_routine1

POP AR1

ADD A,R1

JMP repeat_label

code_entry: CALL code_symbol

RET

code_table: DW repeat_label

DW code_entry

DB typeless_number

DB 0

$EJECT

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

; To include an interrupt service routins, provide an LJMP to the ISR at the

; interrupt vector address.

; 要包含一个中断服务程序,在中断向量地址处加一条跳转到中断服务程序 (ISR) 的语句。;------------------------------------------------------------------------------

CSEG AT 0BH ; 0BH is address for Timer 0 interrupt

LJMP timer0int ; 0BH 是定时器0的中断入口地址。

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

; Give each interrupt function its own code segment.

; 给出每个中断函数自己的代码段。

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

int0_code_seg SEGMENT CODE ; segment for interrupt function

; 中断函数段

RSEG int0_code_seg ; switch to this code segment

; 切换到该代码段

USING 1 ; register bank for interrupt routine

; 为中断程序设置寄存器堆

timer0int: PUSH PSW

MOV PSW,#08H ; register bank 1

; 寄存器堆1

PUSH ACC

MOV R1,data_variable

MOV DPTR,#xdata_variable

MOVX A,@DPTR

ADD A,R1

MOV data_variable1,A

CLR A

ADD A,#0

MOV data_variable1+1,A

POP ACC

POP PSW

RETI

相关文档