第 4章 汇编语言程序设计
4.1 汇编语言基本概念
4.2 汇编语言程序设计
4.1 汇编语言基本概念
4.1.1 程序设计语言
4.1.2 汇编语言的语句结构
4.1.3 伪指令
返回本章首页
4.1.1 程序设计语言
按照语言的结构及其功能可以分为三种:
1,机器语言,机器语言是用二进制代码 0和 1表
示指令和数据的最原始的程序设计语言 。
2,汇编语言,在汇编语言中, 指令用助记符表
示, 地址, 操作数可用标号, 符号地址及字
符等形式来描述 。
3,高级语言,高级语言是接近于人的自然语言,
面向过程而独立于机器的通用语言 。
返回本节
4.1.2 汇编语言的语句结构
1,汇编语言的指令类型
MCS-51单片机汇编语言, 包含两类不同性质
的指令 。
( 1) 基本指令:即指令系统中的指令 。 它们都
是机器能够执行的指令, 每一条指令都有对
应的机器码 。
( 2) 伪指令:汇编时用于控制汇编的指令 。 它
们都是机器不执行的指令, 无机器码 。
下一页
2,汇编语言的语句格式
汇编语言源程序是由汇编语句 ( 即指令 ) 组成
的 。 汇编语言一般由四部分组成 。
其典型的汇编语句格式如下:
标号,操作码 操作数 ;注释
START,MOV A,30H ; A←
( 30H)
返回本节
4.1.3 伪指令
1,ORG:汇编起始地址
用来说明以下程序段在存储器中存放的起
始地址 。
例如程序,ORG 1000H
START,MOVA,#20H
MOVB,#30H

2,EQU:赋值
给变量标号赋予一个确定的数值 。
下一页
3,DB:定义数据字节
把数据以字节数的形式存放在存储器单元中。
4,DW:定义数据字
按字的形式把数据存放在存储单元中 。
5,DS:定义存储区
从指定的地址单元开始,保留一定数量存储单元。
6,BIT:位定义
确定字符名为确定的位地址值。
7,END:汇编结束
返回本节
4.2 汇编语言程序设计
4.2.1 汇编语言程序设计步骤
4.2.2 顺序程序
4.2.3 分支程序
4.2.4 循环程序
4.2.5 子程序
4.2.6 位操作程序
返回本章首页
4.2.1 汇编语言程序设计步骤
1,分析问题
2,确定算法
3,设计程序流程图
4,分配内存单元
5,编写汇编语言源程序
6,调试程序
返回本节
4.2.2 顺序程序
顺序程序是一种最简单,最基本的程序。
特点:程序按编写的顺序依次往下执行每一条
指令,直到最后一条。
【 例 4.1】 将 30H单元内的两位 BCD码拆开并
转换成 ASCII码,存入 RAM两个单元中。程
序流程 如图 4.1所示 。 参考程序 如下:
ORG 0100H
MOV A,30H ;取值
ANL A,#0FH ;取低 4位
下一页
ADD A,#30H ;转换成 ASCII码
MOV32H,A ;保存结果
MOVA,30H ;取值
SWAP A ;高 4位与低 4位互换
ANL A,#0FH ;取低 4位 ( 原来的高 4位 )
ADD A,#30H ;转换成 ASCII码
MOV 31H,A ;保存结果
SJMP $
END
下一页
结束
取数据低 4位
转换成 ASCII码
存 ASCII码
取数据高 4位
转换成 ASCII码
存 ASCII码
开始
图4.1







返回
【 例 4.2】 设 X,Y两个小于 10的整数分别存于
片内 30H,31H单元, 试求两数的平方和并将
结果存于 32H单元 。
解:两数均小于 10,故两数的平方和小于 100,
可利用乘法指令求平方 。 程序流程 如图 4-2所
示 。 参考程序 如下:
ORG 0100H
MOV A,30H ;取 30H单元数据
MOV B,A ;将 X送入 B寄存器
下一页
MUL AB ;求 X2,结果在累加器中
MOV R1,A ;将结果暂存于 R1寄存器中
MOV A,31H ;取 31H单元数据
MOV B,A ;将 Y送入 B寄存器
MUL AB ;求 Y2,结果在累加器中
ADD A,R1 ;求 X2+ Y2
MOV 32H,A ;保存数据
SJMP $ ;暂停
END
返回本节
结束
取数据 X
求 X2
暂存 X2
取数据 Y
求 Y2
求 X2+Y2
开始
保存平方和
图4-
2
例4.2





返回
4.2.3 分支程序
1,分支程序的基本形式
分支程序有三种基本形式,如图 4-3所示 。
分支程序的设计要点如下:
( 1)先建立可供条件转移指令测试的条件。
( 2)选用合适的条件转移指令。
( 3)在转移的目的地址处设定标号。
下一页
条件满足?
A
Y
N
( a)
条件满足?
A B
N
Y
( b)
( c)
A0 A1 An
K=0 K=1 … K=n
K=?
……
图 4-3 分支程序结构流程图
返回
2,双向分支程序设计举例
【 例 4.3】 设 X存在 30H单元中, 根据下式
X+2 X>0
Y = 100 X=0
∣ X∣ X<0
求出 Y值, 将 Y值存入 31H单元 。
解:根据数据的符号位判别该数的正负, 若最高位为 0,
再判别该数是否为 0。 程序流程 如图 4-4所示 。
参考程序 如下:
ORG 0100H
下一页
MOV A,30H ;取数
JB ACC.7,NEG;负数, 转 NEG
JZ ZER0 ;为零, 转 ZER0
ADD A,#02H ;为正数, 求 X+2
AJMP SAVE ;转到 SAVE,保存数据
ZER0,MOV A,# 64H ;数据为零, Y=100
AJMP SAVE ;转到 SAVE,保存数据
NEG,DEC A ;
CPL A ;求 ∣ X∣
SAVE,MOV 31H,A ;保存数据
SJMP $ ;暂停
下一页
A为负数?
取数,A← ( 30H)
开始
结束
A=0?Y
N
N A← |X|A←64H
A← X+2
存数,( 31H) ← A( 30H)
图4-
4
例4.3





返回
3,多向分支程序设计举例
【 例 4.4】 根据 R0的值转向 7个分支程序 。
R0<10,转向 SUB0;
R0<20,转向 SUB1;
R0<60,转向 SUB5;
R0>=60,转向 SUB6;
解:利用 JMP @A+DPTR 指令直接给 PC赋值,
使程序实现转移 。 程序流程 如图 4-5所示 。
?
下一页
参考程序如下:
ORG 0100H
MOV DPTR,#TAB;转移指令表首地址
MOV A,R0 ;取数
CLR C
RLC A ; A← 2*A
JMP @A+DPTR; PC ← A+DPTR
TAB,AJMP SUB0 ;转移指令表
AJMP SUB1 AJMP SUB2
AJMP SUB5 AJMP SUB6
返回本节
K=?
转 SUB0 转 SUB1 转 SUB6
K=0 K=1 …… K=6
开始
图 4-5 多向分支程序流程图
返回
4.2.4 循环程序
1,循环程序的结构 ( 如图 4-6所示 )
☆ 循环程序一般包括如下四个部分:
( 1) 初始化 ( 2) 循环体
( 3) 循环控制 ( 4) 结束
☆ 循环程序按结构形式, 有单重循环与多重循环 。
☆ 在多重循环中, 只允许外重循环嵌套内重循环 。
☆ 不允许循环相互交叉, 也不允许从循环程序的外部跳
入循环程序的内部 ( 如图 4-7所示 ) 。
下一页
( a) 循环结构 1 ( b) 循环结构 2
循环结束?
循环体
Y
N
初始化
修改循环参数
结束部分
开始
结束
循环结束?
循环体
Y
初始化
修改循环参数
结束部分
开始
N
结束
图 4-6 循环结构程序流程图
返回
外循环
中循环
内循环
外循环
内循环
外循环
内循环
内循环
( a)嵌套正确 ( b)嵌套正确 ( c)交叉不正确
图 4-7 多重循环示意图
返回
2,循环程序设计举例
【 例 4.5】 有一数据块从片内 RAM的 30H单元开始存入,
设数据块长度为 10个单元 。 根据下式:
X+2 X>0
Y= 100 X=0
∣ X∣ X<0
求出 Y值, 并将 Y值放回原处 。
解:设置一个计数器控制循环次数, 每处理完一个数据,
计数器减 1。 程序流程 如图 4-8所示 。
下一页
参考源程序如下:
ORG 0100H
MOV R0,#10
MOV R1,#30H
START,MOV A,@R1 ;取数
JB ACC.7,NEG ;若为负数, 转 NEG
JZ ZER0 ;若为零, 转 ZER0
ADD A,#02H ;若为正数, 求 X+2
AJMP SAVE ;转到 SAVE,保存数据
ZER0,MOV A,# 64H ;数据为零, Y=100
下一页
AJMP SAVE ;转到 SAVE,保存数据
NEG,DEC A
CPL A ;求 ∣ X∣
SAVE,MOV @R1,A ;保存数据
INC R1 ;地址指针指向下一个地址
DJNZ R0,START ;数据未处理完, 继续处理
SJMP $ ;暂停
返回本节
A=0?Y
Y
N
N
Y
N
A为负数?
取数,A← (( R1))
开始
结束
A← ∣ X∣A←64H
A←X+2
存数,(( R1)) ← A( 30H)
设置地址指针 R1、计数器 R0初值
R1←R1+1 ; R0←R0 -1
R0=0?
图4-
8
例4.5






返回
4.2.5 子程序
1,子程序概念
所谓调用子程序,暂时中断主程序的执行,
而转到子程序的入口地址去执行子程序。 如图
4-10所示 。调用子程序应注意:
( 1) 子程序占用的存储单元和寄存器 。
( 2) 参数的传递 。
( 3) 子程序经过调用后得到的数据来完成程序
之间的参数传递 。
( 4) 嵌套调用与递归调用 。 如图 4-11所示 。
下一页
RET
LCALL SUB
图 4-10 子程序的调用与返回
返回
LCALL A
RETRET
LCALL B
图 4-11 子程序的嵌套调用与返回
返回
2,子程序设计举例
【 例 4.8】 将 4.4节中的例 4.5改为子程序结构 。
解:数据块中的十个数都需要进行符号判断并
作相应处理, 可把一部分工作交给子程序完
成, 主程序只负责读取数据, 调用判断处理
子程序, 保存数据, 循环控制工作 。 源程序
如下:
ORG 0100H
MOV R0,#10
MOV R1,#30H
下一页
START,MOV A,@R1 ;取数
ACALL DISPOSE ;调用判断, 处理子程序
SAVE,MOV @R1,A ;保存数据
INC R1 ;修改地址指针, 指向下一个地址
DJNZ R0,START ;数据未处理完, 继续处理
SJMP $ ;暂停
ORG 0200H
DISPOSE,JB ACC.7,NEG ;若为负数, 转 NEG
下一页
JZ ZER0 ;若为零, 转 ZER0
ADD A,#02H ;若为正数, 求 X+2
AJMP BACK ;转到 SAVE,保存数据
ZER0,MOV A,#64H ;数据为零, Y=100
AJMP BACK ;转到 SAVE,保存数据
NEG,DEC A
CPL A ;求 ∣ X∣
BACK,RET
返回本节
4.2.6 位操作程序
【 例 4.9】 编写一程序, 实现 图 4-12中的逻辑运
算电路 。 其中 P3.1,P1.1,P1.0分别是单片机端
口线上的信息, RS0,RS1是 PSW寄存器中的
两个标志位, 30H,31H是两个位地址, 运算
结果由 P1.0输出 。
程序如下:
ORG 0000H
MOV C,P3.1
下一页
ANL C,P1.1
CPL C
MOV 20H,C ;暂存数据
MOV C,30H
ORL C,/31H
ANL C,RS1
ANL C,20H
ANL C,RS0
MOV P1.0,C ;输出结果
SJMP $
返回本节
P3.1
P1.1
30H
31H
RS1
RS0
&
≥ 1 &
& P
1.0
图 4-12 硬件逻辑硬件电路图
返回