MCS51汇编语言程序设计.docx

上传人:b****6 文档编号:12279317 上传时间:2023-06-05 格式:DOCX 页数:19 大小:104.68KB
下载 相关 举报
MCS51汇编语言程序设计.docx_第1页
第1页 / 共19页
MCS51汇编语言程序设计.docx_第2页
第2页 / 共19页
MCS51汇编语言程序设计.docx_第3页
第3页 / 共19页
MCS51汇编语言程序设计.docx_第4页
第4页 / 共19页
MCS51汇编语言程序设计.docx_第5页
第5页 / 共19页
MCS51汇编语言程序设计.docx_第6页
第6页 / 共19页
MCS51汇编语言程序设计.docx_第7页
第7页 / 共19页
MCS51汇编语言程序设计.docx_第8页
第8页 / 共19页
MCS51汇编语言程序设计.docx_第9页
第9页 / 共19页
MCS51汇编语言程序设计.docx_第10页
第10页 / 共19页
MCS51汇编语言程序设计.docx_第11页
第11页 / 共19页
MCS51汇编语言程序设计.docx_第12页
第12页 / 共19页
MCS51汇编语言程序设计.docx_第13页
第13页 / 共19页
MCS51汇编语言程序设计.docx_第14页
第14页 / 共19页
MCS51汇编语言程序设计.docx_第15页
第15页 / 共19页
MCS51汇编语言程序设计.docx_第16页
第16页 / 共19页
MCS51汇编语言程序设计.docx_第17页
第17页 / 共19页
MCS51汇编语言程序设计.docx_第18页
第18页 / 共19页
MCS51汇编语言程序设计.docx_第19页
第19页 / 共19页
亲,该文档总共19页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

MCS51汇编语言程序设计.docx

《MCS51汇编语言程序设计.docx》由会员分享,可在线阅读,更多相关《MCS51汇编语言程序设计.docx(19页珍藏版)》请在冰点文库上搜索。

MCS51汇编语言程序设计.docx

MCS51汇编语言程序设计

第四章MCS-51汇编语言程序设计

重点及难点:

单片机汇编语言程序设计的基本概念、伪指令、单片机汇编语言程序的三种基本结构形式、常用汇编语言程序设计。

教学基本要求:

1、掌握汇编语言程序设计的基本概念;

2、掌握伪指令的格式、功能和使用方法;

3、掌握顺序结构、分支结构和循环结构程序设计的步骤和方法;

4、掌握常用汇编语言程序设计步骤和方法。

教学内容

§4.1汇编语言程序设计概述

一、汇编语言的特点

(1)助记符指令和机器指令一一对应,所以用汇编语言编写的程序效率高,占用存储空间小,运行速度快,因此汇编语言能编写出最优化的程序。

(2)使用汇编语言编程比使用高级语言困难,因为汇编语言是面向计算机的,汇编语言的程序设计人员必须对计算机硬件有相当深入的了解。

(3)汇编语言能直接访问存储器及接口电路,也能处理中断,因此汇编语言程序能够直接管理和控制硬件设备。

(4)汇编语言缺乏通用性,程序不易移植,各种计算机都有自己的汇编语言,不同计算机的汇编语言之间不能通用;但是掌握了一种计算机系统的汇编语言后,学习其他的汇编语言就不太困难了。

二、汇编语言的语句格式

[<标号>]:

<操作码>[<操作数>];[<注释>]

三、汇编语言程序设计的步骤与特点

(1)建立数学模型

(2)确定算法

(3)制定程序流程图

(4)确定数据结构

(5)写出源程序

(6)上机调试程序

§4.2伪指令

伪指令是程序员发给汇编程序的命令,也称为汇编命令或汇编程序控制指令。

MCS-51常见汇编语言程序中常用的伪指令:

1.ORG(ORiGin)汇编起始地址命令

[<标号:

>]ORG<地址>

2.END(ENDofassembly)汇编终止命令

[<标号:

>]END[<表达式>]

3.EQU(EQUate)赋值命令

<字符名称>EQU<赋值项>

4.DB(DefineByte)定义字节命令

[<标号:

>]DB<8位数表>

5.DW(DefineWord)定义数据字命令

[<标号:

>]DW<16位数表>

6.DS(DefineStonage)定义存储区命令

[<标号:

>]DW<16位数表>

7.BIT位定义命令

<字符名称>BIT<位地址>

8.DATA数据地址赋值命令

<字符名称>DATA<表达式>

§4.3单片机汇编语言程序的基本结构形式

一、顺序程序

[例4-1]三字节无符号数相加,其中被加数在内部RAM的50H、51H和52H单元中;加数在内部RAM的53H、5414和55H单元中;要求把相加之和存放在50H、51H和52H单元中,进位存放在位寻址区的00H位中。

MOV

R0,

#52H

;被加数的低字节地址

MOV

R1,

#55H

;加数的低字节地址

MOV

A,

@R0

ADD

A,

@R1

;低字节相加

MOV

@R0,

A

;存低字节相加结果

DEC

R0

DEC

R1

MOV

A,

@R0

ADDC

A,

@R1

;中间字节带进位相加

MOV

@R0,

A

;存中间字节相加结果

DEC

R0

DEC

R1

MOV

A,

@R0

ADDC

A,

@R1

;高字节带进位相加

MOV

@R0,

A

;存高字节相加结果

CLR

A

ADDC

A,

#00H

;存放进位的单元地址

MOV

@R0,

A

;进位送00H位保存

二、分支程序

1.单分支程序

[例4-2]变量X存放在VAR单元内,函数值Y存放在FUNC单元中,试按下式的要求给Y赋值。

本题的程序流程见图4-1(a)。

参考程序:

ORG

1000H

VAR

DATA

30H

FUNC

DATA

31H

MOV

A,

VAR

;A←X

JZ

DONE

;若X=0,则转DONE

JNB

ACC.7,

POSI

;若X>0,则转POSI

MOV

A,

#0FFH

;若X<0,则Y=-1

SJMP

DONE

POSI:

MOV

A,

#01H

;若X>0,则Y=1

DONE:

MOVE

FUNC,

A

;存函数值

SJMP

$

END

图4-1例4-2的分支流程图

这个程序的特征是先比较判断,然后按比较结果赋值,这实际是三分支而归一的流程图,因此,至少要用两个转移指令。

初学者很容易犯的一个错误是:

漏掉了其中的SJMPDONE语句,因为流程图中没有明显的转移痕迹。

这个程序也可以按图4-1(b)的流程图来编写,其特征是先赋值,后比较判断,然后修改赋值并结束。

参考程序:

ORG

1000H

VAR

DATA

30H

FUNC

DATA

31H

MOV

A,

VAR

;A←X

JZ

DONE

;若X=0,则转DONE

MOV

R0,

#0FFH

;先设X<0,R0=FFH

JNB

ACC.7,

NEG

;若X<0,则转NEG

MOV

R0,

#01H

;若X>0,R0=1

NEG:

MOV

A,

#01H

;若X>0,则Y=1

DONE:

MOV

FUNC,

A

;存函数值

SJMP

$

END

2.多分支程序

图4-2多分支程序转移

三、循环程序

循环程序一般由4部分组成:

(1)置循环初值,即确立循环开始时的状态。

(2)循环体(工作部分),要求重复执行的部分。

(3)循环修改,循环程序必须在一定条件下结束,否则就要变成死循环。

(4)循环控制部分,根据循环结束条件,判断是否结束循环。

以上4个部分可以有两种组织方式。

[例4-3]从BLOCK单元开始存放一组无符号数,一般称为一个数据块。

数据块长度放在LEN单元,编写一个求和程序,将和存入SUM单元,假设和不超过8位二进制数。

在置初值时,将数据块长度置入一个工作寄存器,将数据块首地址送入另一个工作寄存器,一般称它为数据块地址指针。

每做一次加法之后,修改地址指针,以便取出下一个数来相加,并且使计数器减1。

到计数器减到0时,求和结束,把和存入SUM即可。

参考程序:

各单元的地址是任意的。

LEN

DATA

20H

SUM

DATA

21H

BLOCK

DATA

22H

CLR

A

;清累加器

MOV

R2,

LEN

;数据块长度送R2

MOV

R1,

#BLOCK

;数据块首址送Rl

LOOP:

ADD

A,

@R1

;循环做加法

INC

R1

;修改地址指针

DJNZ

R2,

LOOP

;修改计数器并判断

MOV

SUM,

A

;存和

以上程序在计数器初值不为零时是没有问题的,但若是数据块的长度有可能为零,则将

出现问题。

当R2初值为零,减1之后将为FFH,故要做256次加法之后才会停止,显然和题意不符。

若考虑到这种情况,则可按图4-3(b)的方式来编写程序。

在做加法之前,先判断一次R2的初值是否为零。

整个程序仍基本套用原来的形式:

CLR

A

;清累加器

MOV

R2,

LEN

;数据块长度送R2

MOV

R1,

#BLOCK

;数据块首址送Rl

INC

R2

SJMP

CHECK

LOOP:

ADD

A,

@R1

;循环做加法

INC

R1

;修改地址指针

CHECK:

DJNZ

R2,

LOOP

MOV

SUM,

A

;存和

§4.4MCS-51单片机汇编语言程序设计举例

一、算术运算程序

[例4-4]假定R2、R3和R4、R5分别存放两个16位的带符号二进制数,其中R2和R4的最高位为两数的符号位。

请编写带符号双字节二进制数的加减法运算程序,以BSUB为减法程序入口,以BADD为加法程序入口,以R6、R7保存运算结果。

参考程序:

BSUB:

MOV

A,

R4

;取减数高字节

CPL

ACC.7

;减数符号取反以进行加法

MOV

R4,

A

BADD:

MOV

A,

R

;取被加数

MOV

C,

ACC.7

MOV

F0,

C

;被加数符号保存在F0中

XRL

A,

R4

;两数高字节异或

MOV

C,

ACC.7

;两数同号CY=0,两数异号CY=1

MOV

A,

R2

CLR

ACC.7

;高字节符号位清“0”

MOV

R2,

A

;取其数值部分

MOV

A,

R4

CLR

ACC.7

;低字节符号位清“0”

MOV

R4,

A

;取其数值部分

JC

JIAN

;两数异号转JIAN

JIA:

MOV

A,

R3

;两数同号进行加法

ADD

A,

R5

;低字节相加

MOV

R7,

A

;保存和

MOV

A,

R2

ADDC

A,

R4

;高字节相加

MOV

R6,

A

;保存和

JB

ACC.7,

QAZ

;符号位为“1”转溢出处理

QWE:

MOV

C,

F0

;结果符号处理

MOV

ACC.7,

C

MOV

R6,

A

RET

JIAN:

MOV

A,

R3

;两数异号进行减法

CLR

C

SUBB

A,

R5

;低字节相减

MOV

R7,

A

;保存差

MOV

A,

R2

SUBB

A,

R4

;高字节相减

MOV

R6,

A

;保存差

JNB

ACC.7,

QWE

;判断差的符号,为“0”转QWE

BMP:

MOV

A,

R7

;为“1”进行低字节取补

CPL

A

ADD

A,

#1

MOV

R7,

A

MOV

A,

R6

;高字节取补

CPL

A

ADDC

A,

#0

MOV

R6,

A

CPL

F0

;保存在F0中的符号取反

SJMP

QWE

;转结果符号处理

QAZ:

;溢出处理

二、数制转换程序

[例4-5]在内部RAM的hex单元中存有2位十六进制数,试将其转换为ASCII码,并存放于asc和asc+1两个单元中。

主程序(MAIN):

MOV

SP,

#3FH

MAIN:

PUSH

hex

;十六进制数进栈

ACALL

HASC

;调用转换子程序

POP

asc

;第一位转换结果送asc单元

MOV

A,

hex

;再取原十六进制数

SWAP

A

;高低半字节交换

PUSH

ACC

;交换后的十六进制数进栈

ACALL

HASC

POP

asc+l

;第二位转换结果送asc+l单元

子程序(HASC):

HASC:

DEC

SP

;跨过断点保护内容

DEC

SP

POP

ACC

;弹出转换数据

ANL

A,

#0FH

;屏蔽高位

ADD

A,

#7

;修改变址寄存器内容

MOVC

A,

@A+PC

;查表

PUSH

ACC

;查表结果进栈

INC

SP

;修改堆栈指针回到断点保护内容

INC

SP

RET

SP

ASCTAB:

DB

“0,1,2,3,4,5,6,7”

;ASCII码表

DB

“8,9,A,B,C,D,E,F”

三、定时程序

有多个定时需要,我们可以先设计一个基本的延时程序,使其延迟时间为各定时时间的最大公约数,然后就以此基本程序作为子程序,通过调用的方法实现所需要的不同定时。

例如要求的定时时间分别为5μs、l0μs和20μs并设计一个1s延时子程序DELAY,则不同定时的调用情况表示如下:

MOV

R0,

#05H

;5s延时

LOOP1:

LCALL

DELAY

DJNZ

R0,

LOOP1

MOV

R0,

#0AH

;10s延时

LOOP2:

LCALL

DELAY

DJNZ

R0,

LOOP2

MOV

R0,

#14H

;20s延时

LOOP3:

LCALL

DELAY

DJNZ

R0,

LOOP3

四、查表程序

一个查表程序的例子。

假定有4

4键盘,键扫描后把被按键的键码放在累加器A中,键码与处理子程序入口地址的对应关系为:

键码

入口地址

0

RK0

1

RKl

2

RK2

 

并假定处理子程序在ROM64KB的范围内分布。

要求以查表方法,按键码转向对应的处理子程序。

参考程序如下:

MOV

DPTR,

#BS

;子程序入口地址表首址

RL

A

;键码值乘以2

MOV

R2,

A

;暂存A

MOVC

A,

@A+DPTR

;取得入口地址低位

PUSH

A

;进栈暂存

INC

A

MOVC

A,

@A+DPTR

;取得入口地址高位

MOV

DPH,

A

POP

DPL

CLR

A

JMP

@A+DPTR

;转向键处理子程序

BS:

DB

RK0L

;处理子程序入口地址表

DB

RK0H

DB

RK1L

DB

RK1H

DB

RK2L

DB

RK2H

五、数据极值查找程序

[例4-6]内部RAM20H单元开

始存放8个无符号8位二进制数,找

出其中的最大数。

极值查找操作的主

要内容是进行数值大小的比较。

假定

在比较过程中,以A存放大数,与之

逐个比较的另一个数放在2AH单元中。

比较结束后,把查找到的最大数送2BH

单元中。

程序流程如图所示。

图4-8极值查找程序流程

图4-8极值查找程序流程

参考程序如下:

MOV

R0,

#20H

;数据区首地址

MOV

R7,

#08H

;数据区长度

MOV

A,

@R0

;读第一个数

DEC

R7

LOOP:

INC

R0

MOV

2AH,

@R0

;读下一个数

CJNE

A,2AH,

CHK

;数值比较

CHK:

JNC

LOOP1

;A值大转移

MOV

A,

@R0

;大数送A

LOOP1:

DJNZ

R7,

LOOP

;继续

MOV

2BH,

A

;极值送2BH单元

HERE:

AJMP

HERE

;停止

六、数据排序程序

[例4-7]假定8个数连续存放在20H为首地址的内部RAM单元中,使用冒泡法进行升序排序编程。

设R7为比较次数计数器,初始值为07H。

TR0为冒泡过程中是否有数据互换的状态标志,TR0=0表明无互换发生,TR0=1表明有互换发生。

冒泡法排序程序流程

参考程序:

SORT:

MOV

R0,

#20H

;数据存储区首单元地址

MOV

R7,

#07H

;各次冒泡比较次数

CLR

TR0

;互换标志清“0”

LOOP:

MOV

A,

@R0

;取前数

MOV

2BH,

A

;存前数

INC

R0

MOV

2AH,

@R0

;取后数

CLR

C

SUBB

A,

@R0

;前数减后数

JC

NEXT

;前数小于后数,不互换

MOV

@R0,

2BH

DEC

R0

MOV

@R0,

2AH

;两个数交换位置

INC.

R0

;准备下一次比较

SETB

TR0

;置互换标志

NEXT:

DJNZ

R7,

LOOP

;返回,进行下一次比较

JB

TR0,

SORT

;返回,进行下一轮冒泡

HERE:

SJMP

$

;排序结束

本章小结:

本章首先介绍了单片机汇编语言程序设计的基本概念,单片机汇编语言伪指令;详细的讲述了三种汇编语言程序设计的基本结构,即:

顺序结构、分支结构和循环结构程序设计的步骤和方法;然后介绍了几种汇编语言程序设计实例。

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 医药卫生 > 基础医学

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2