第 3章 指令系统及汇编
第 3章 指令系统及汇编
3.1 MCS— 51单片机汇编语言与指令格式
3.2 寻址方式
3.3 MCS— 51单片机指令系统
3.4 汇编语言及汇编语言程序设计
3.5 基本程序设计方法
3.6 程序设计举例
第 3章 指令系统及汇编
3.1 MCS— 51单片机汇编语言与指令格式
3.1.1 单片机的汇编语言
由于构成计算机的电子器件特性所决定,计算机只
能识别二进制代码 。 这种以二进制代码来描述指令功
能的语言,称之为机器语言,用机器语言组成的程序,称
为目标程序 。 计算机就是按照机器语言的指令来完成
各种功能操作的,它具有程序简捷, 占用存储空间小,
执行速度快, 控制功能强等特点 。
第 3章 指令系统及汇编
3.1.2 指令格式
MCS—51单片机汇编语言指令的标准格式如下,
[ 标号, ] 操作码 [ 目的操作数 ] [,源操作数 ]
[ ; 注释 ]
例如, LOOP,ADD# A,# 10H ; (A)←(A)+ 10H
(1) 方括号 [ ] 表示该项是可选项,可有可无 。
(2) 标号是用户设定的符号,它实际代表该指令所在
的地址 。 标号必须以字母开头,其后跟 1~ 8个字母或数
字,并以,,”结尾 。
第 3章 指令系统及汇编
(3) 操作码是用英文缩写的指令功能助记符 。 它
确定了本条指令完成什么样的操作功能 。 如, ADD表
示加法操作 。 任何一条指令都必须有该助记符项,不得
省略 。
(4) 目的操作数提供操作的对象,并指出一个目标
地址,表示操作结果存放单元的地址,它与操作码之间
必须以一个或几个空格分隔 。 如上例中 A表示操作对
象是累加器 A的内容,并指出操作结果又回送 A存放 。
第 3章 指令系统及汇编
(5) 源操作数指出的是一个源地址 ( 或立即数 ),
表示操作的对象或操作数来自何处 。 它与目的操作数
之间要用,,”号隔开 。
(6) 注释部分是在编写程序时,为了增加程序的可
读性,由用户拟写对该条指令或该段程序功能的说明 。
它以分号, ;”开头,可以用中文, 英文或某些符号来表
示,显然它不存入计算机,只出现在源程序中 。
第 3章 指令系统及汇编
3.1.3 指令中常用符号
在分类介绍各类指令之前,先对描述指令的一些符
号意义进行一些简单约定,
(1) Ri和 Rn,R表示当前工作寄存器区中的工作寄存
器,i表示 0或 1,即 R0和 R1。 n表示 0~ 7,即 R0~ R7,当前
工作寄存器的选定是由 PSW的 RS1和 RS0位决定的 。
(2) # data,#表示立即数,data为 8位常数 。 # data
是指包含在指令中的 8位立即数 。
第 3章 指令系统及汇编
(3) # data16,包含在指令中的 16位立即数 。
(4) rel,相对地址,以补码形式表示的地址偏移量,范
围为 -128~ +127,主要用于无条件相对短转移指令 SJMP
和所有的条件转移指令中 。
(5) addr16,16位目的地址 。 目的地址可在全部程序
存储器的 64 KB空间范围内,主要用于无条件长转移指令
LJMP和子程序长调用指令 LCALL中 。
(6) addr11,11位目的地址 。 目的地址应与下条指令
处于相同的 2 KB程序存储器地址空间范围内,主要用于绝
对转移指令 AJMP和子程序绝对调用指令 ACALL指令中 。
第 3章 指令系统及汇编
(7) direct,表示直接寻址的地址,即 8位内部数据存
储器 RAM的单元地址 ( 0~ 127/255),或特殊功能寄存
器 SFR的地址 。 对于 SFR可直接用其名称来代替其直
接地址 。
(8) bit,内部数据存储器 RAM和特殊功能寄存器
SFR中的可直接寻址位地址 。
(9) @,间接寻址寄存器或基地址寄存器的前缀,如
@Ri,@DPTR,表示寄存器间接寻址 。
第 3章 指令系统及汇编
(10) (X),表示 X中的内容 。
(11) ((X)),表示由 X寻址的单元中的内容,即 (X)作
地址,该地址的内容用 ((X))表示 。
(12) / 和 → 符号, /表示对该位操作数取反,但不影
响该位的原值 。 → 表示指令操作流程,将箭头一方的内
容,送入箭头另一方的单元中去 。
第 3章 指令系统及汇编
3.2 寻址方式
3.2.1寄存器寻址
选定某寄存器,自该寄存器中读取或存放操作数,
以完成指令规定的操作,称为寄存器寻址 。
例如, MOV A,R0 ; (A)←(R 0)
该指令的功能是把工作寄存器 R0中的内容传送到
累加器 A中,如, R0内容为 FFH,则执该指令后 A的内容
也为 FFH。 在该条指令中,源操作数和目的操作数是由
寻址 R0和 A寄存器得到的,故属于寄存器寻址 。 该指令
为单字节指令,机器代码为 E8H。
第 3章 指令系统及汇编
3.2.2 立即寻址
操作数直接出现在指令中,它紧跟在操作码的后面,
作为指令的一部分与操作码一起存放在程序存储器内,
可以立即得到并执行,不需要另去寄存器或存储器等处
寻找和取数,故称为立即寻址 。 该操作数称为立即数,
并在其前冠以, #, 号作前缀,以表示并非地址 。 立即
数可以是 8位或 16位,用十六进制数表示 。
第 3章 指令系统及汇编
例如, MOV A,# 0FH ; (A)← 0FH
该指令的功能是将立即数 0FH传送到累加器 A中,
对应的机器码为 74H。 它隐含了寄存器寻址累加器 A方
式,长一个字节,占用一个存储单元 ; 立即数 0FH紧跟在
操作码之后,成为指令代码的一部分,长也是一个字节,
占用紧跟在后面的另一个存储单元 。 故该指令为双字
节指令,其机器码为 74H 0FH。
第 3章 指令系统及汇编
3.2.3寄存器间接寻址
由指令指出某一个寄存器的内容作为操作数地址的
寻址方法,称为寄存器间接寻址方法,简称寄存器间址 。
这里要强调的是, 寄存器的内容不是操作数本身,而是操
作数地址 。
寄存器间接寻址使用所选定寄存器区中的 R0和 R1作
为地址指针 ( 对堆栈操作时,使用堆栈指针 SP),来寻址
片内数据存储器 RAM( 00~ FFH) 的 256个单元,但它不
能访问特殊功能寄存器 SFR。 寄存器间接寻址也适用于
访问外部数据存储器,此时,用 R0,R1或 DPTR作为地址
指针 。 寄存器间接寻址用符号, @”指明 。
第 3章 指令系统及汇编
图 3―1 寄存器间接寻址示意图
第 3章 指令系统及汇编
3.2.4 直接寻址
指令中直接给出操作数所在的存储器地址,以供寻
址取数或存数的寻址方式称为直接寻址 。
例如, MOV A,40H ; (A)←( 40H)
该指令的功能是把内部数据存储器 RAM 40H单元
内的内容送到累加器 A。 指令直接给出了源操作数的
地址 40H。 该指令的机器码为 E5H 40H。
第 3章 指令系统及汇编
3.2.5 变址寻址
基址寄存器加变址寄存器间接寻址,简称变址寻址 。
它以数据指针 DPTR或程序计数器 PC作为基址寄存器,
累加器 A作为变址寄存器,两者的内容相加形成 16位程
序存储器地址,该地址就是操作数所在地址 。
例如, MOVC A,@A+DPTR ; (A)←((A)+(DPTR))
该指令寻址及操作功能如图 3― 2所示,该指令为单
字节指令,机器代码为 93H。 这种寻址方式常用于访问
程序存储器中的常数表 。
第 3章 指令系统及汇编
图 3―2 变址寻址示意图
第 3章 指令系统及汇编
3.2.6 相对寻址
相对寻址是以当前程序计数器 PC值加上指令规定的
偏移量 rel,而构成实际操作数地址的寻址方法 。 它用于
访问程序存储器,常出现在相对转移指令中 。
在使用相对寻址时要注意以下两点,
第一,当前 PC值是指相对转移指令所在地址 ( 一般
称为源地址 ) 加上转移指令字节数 。 即, 当前 PC值 = 源
地址 + 转移指令字节数 。
例如, JZ rel 是一条累加器 A为零就转移的双字节指
令 。 若该指令地址 ( 源地址 ) 为 2050H,则执行该指令
时的当前 PC值即为 2052H。
第 3章 指令系统及汇编
第二,偏移量 rel是有符号的单字节数,以补码表示,
其相对值的范围是 -128~ +127( 即 00H~ FFH),负数
表示从当前地址向上转移,正数表示从当前地址向下转
移 。 所以,相对转移指令满足条件后,转移的地址 ( 一
般称为目的地址 ) 应为, 目的地址 = 当前 PC值 + rel =
源地址 + 转移指令字节数 + rel例如,指令 JZ 08H和 JZ
0F4H 表示累加器 A为零条件满足后,从源地址 ( 2050H)
分别向下, 向上转移 10个单元 。 其相对寻址示意如图
3― 3 (a),(b) 所示 。 这两条指令均为双字节指令,
机器代码分别为, 60H 08H和 60H F4H。
第 3章 指令系统及汇编
图 3―3 相对寻址示意图
(a)指令 JZ 08H寻址示意图; (b)指令 JZ F4H寻址示意图
第 3章 指令系统及汇编
3.2.7 位寻址
MCS—51系列单片机具有位寻址的功能,即指令中
直接给出位地址,可以对内部数据存储器 RAM中的 128
位和特殊寄存器 SFR中的 93位进行寻址,并且位操作指
令可对地址空间的每一位进行传送及逻辑操作 。
例如, SETB PSW.3 ; (PSW.3)←1
该指令的功能是给程序状态字 PSW中的 RS0置 1。
该指令为双字节指令,机器代码为 D2H D3H,指令的第
二字节直接给出位地址 D3H( PSW.3的位地址 ) 。
第 3章 指令系统及汇编
综上所述,在 MCS—51系列单片机的存储空间中,指
令究竟对哪个存储器空间进行操作是由指令操作码和
寻址方式确定的 。 7种寻址方式如表 3― 1所示 。
第 3章 指令系统及汇编
表 3―1 7 种寻址方式及使用空间
第 3章 指令系统及汇编
3.3 MCS— 51单片机指令系统
MCS—51单片机指令系统分为, 数据传送类指令,
算术运算类指令, 逻辑运算及移位类指令, 控制转移
类指令和位操作 ( 布尔操作 ) 指令 5大类,共计 111条指
令 。 现按其分类分别介绍各条指令的格式, 功能, 对
状态标志的影响以及应用 。
第 3章 指令系统及汇编
3.3.1 数据传送类指令
数据传送类指令共 29条,它是指令系统中最活跃,
使用最多的一类指令 。 一般的操作是把源操作数传送
到目的操作数,即指令执行后目的操作数改为源操作数,
而源操作数保持不变 。 若要求在进行数据传送时,不丢
失目的操作数,则可以用交换型传送指令 。
第 3章 指令系统及汇编
数据传送类指令不影响进位标志 CY,半进位标志
AC和溢出标志 OV,但当传送或交换数据后影响累加器
A的值时,奇偶标志 P的值则按 A的值重新设定 。
按数据传送类指令的操作方式,又可把传送类指令
分为 3种类型, 数据传送, 数据交换和堆栈操作,并使
用 8种助记符, MOV,MOVX,MOVC,XCH、
XCHD,SWAP,PUSH及 POP。 表 3― 2给出了各种数
据传送指令的操作码助记符和对应的操作数 。
第 3章 指令系统及汇编
表 3―2 数据传送类指令助记符与操作
第 3章 指令系统及汇编
1,内部数据存储器间数据传送指令
内部数据存储器 RAM区是数据传送最活跃的区域,
可用的指令数也最多,共有 16条指令,指令操作码助记
符为 MOV。 内部 RAM之间源操作数传递关系如图
3― 4所示 。 为了便于理解指令功能,我们按源操作数的
寻址方式逐一介绍各条指令 。
(1) 立即寻址。 在该寻址方式下,内部 RAM区数据
传送指令有如下 5条指令。
第 3章 指令系统及汇编
图 3―4 内部 RAM间数据传递关系
第 3章 指令系统及汇编
操作码助记符 目的操作数 源操作数 功能注释 机器代码 (H)
MOV A,# data ; (A) ← # data,74 data
MOV direct,# data ; (direct) ← # data,75 direct data
MOV @Ri,# data ; ((Ri)) ← # data,76~ 77 data
MOV Rn,# data ; (Rn) ← # data,78~ 7F data
MOV DPTR,# data16 ; (DPTR) ← # data16,90 data15~
8data7~ 0
第 3章 指令系统及汇编
这组指令表明,8位立即数可以直接传送到内部数
据区 RAM的各个位置,并且可把 16位立即数直接装入
数据指针 DPTR。 把立即数送入累加器 A的传送指令在
3.2.2节中已作了介绍,其它指令的功能及应用举例如下,
① MOV direct,# data ; (direct) ← # data #,75
direct data
该指令的功能是把立即数传送到内部数据存储器
RAM的 00H~ 7FH,以及特殊功能寄存器 SFR的各单元
中去,它为三字节指令 。 例如把立即数 40H传送到 RAM
的 30H单元和 P1口 ( 口地址为 90H),可采用如下指令:
第 3章 指令系统及汇编
MOV 30H,# 40H ; (30H) ← # 40H,75 30 40
MOV P1,# 40H ; (90H) ← # 40H,75 90 40
② MOV @Ri,# data ; ((Ri)) ← # data,76~ 77
data
该指令的功能是把立即数传送到由 R0和 R1寄存器
的内容指出的片 内数据存储 器 RAM 的单元 中去
( MCS— 51系列为 00H~ 7FH,MCS— 52系列为 00H~
FFH) 。
MOV R0,# 30H ; (R0) ← # 30H,78 30
MOV @R0,# 40H ; ((R0)) ← # 40H,76 40
第 3章 指令系统及汇编
③ MOV Rn,# data ; (Rn) ← # data,78~ 7F data
该指令的功能是把立即数传送到内部寄存器 R0~
R7中去,该指令为双字节指令,机器代码为,
0 1 1 1 1 r r r data
第 3章 指令系统及汇编
④ MOV DPTR,# data16 ; (DPTR) ← # data16,
90 data 15~ 8 data 7~ 0
该指令的功能是把 16位立即数装入数据指针
DPTR中去 。 它是 MCS—51系列单片机指令系统中唯一
的一条 16位数据传送指令 。 该指令为三字节指令,第一
字节为 90H,第二字节为高 8位立即数,第三字节为低 8位
立即数 。
例如, MOV DPTR,# 1234H指令执行后,DPTR寄
存器的高 8位寄存器 DPH的内容为 12H,低 8位寄存器
DPL内容为 34H。 该指令的机器代码为 90H 12H 34H。
第 3章 指令系统及汇编
(2) 寄存器寻址 。 在该寻址方式下,内部 RAM区数据
传送指令有以下 5条,
MOV direct,A # ; (direct) ← (A),F5 direct
MOV @Ri,A ; ((Ri)) ← (A),F6~ F7
MOV Rn,A ; (Rn) ← (A),F8~ FF
MOV A,Rn ; (A) ← (Rn),E8~ EF
MOV direct,Rn ; (direct) ← (Rn),88~ 8F direct
第 3章 指令系统及汇编
这组指令的功能是把累加器 A的内容传送到内部数
据区 RAM的各个单元,或者把指定工作寄存器 R0~ R7
中的内容传送到累加器 A或 direct所指定的片内 RAM的
00H~ 7FH单元或特殊功能寄存器 SFR中去 。 但不能用
这类指令在内部工作寄存器之间直接传送 。 例如, 不
存在 MOVR1,R2这样的指令 。
第 3章 指令系统及汇编
(3) 直接寻址 。 在该寻址方式下,内部 RAM区数据
传送指令有如下 4条指令,
MOV A,direct ; (A) ← (direct),E5 direct
MOV Rn,direct ; (Rn) ← (direct),A8~ AF direct
MOV @Ri,direct ; ((Ri)) ← (direct),A6~ A7 direct
MOV direct2,direct1; (direct2)← (direct1),85 direct1 direct2
第 3章 指令系统及汇编
这组指令将直接地址所规定的内部 RAM单元 ( 片
内 RAM的 00H~ 7FH,SFR的 80H~ FFH单元 ) 内容传送
到累加器 A,寄存器 Rn,并能实现内部数据寄存器 RAM
之间, 特殊功能寄存器 SFR之间或 SFR与内部 RAM之
间的直接数据传递 。 直接传递不需要通过累加器 A或
者工作寄存器来间接传送,从而提高了数据传送的效率 。
第 3章 指令系统及汇编
例如, MOV P2,P1 ; (P2) ← (P1),85 90 A0
该指令的功能是不通过其它寄存器,直接把 P1口
( 口地址 90H) 的内容传送到 P2口 ( 口地址 A0H) 输出,
提高了效率 。 该指令为三字节指令,机器代码为 85H
90H A0H。
第 3章 指令系统及汇编
(4) 寄存器间接寻址 。 在该寻址方式下,内部 RAM
区数据传送指令有以下两条,
MOV A,@Ri ; (A) ← ((Ri)),E6~ E7
MOV direct,@Ri ; (direct) ← ((Ri)),86~ 87 direct
这组指令把以 Ri的内容作为地址进行寻址所得到
单元的内容,传送到累加器 A或 direct 指定的片内
RAM区单元 。
第 3章 指令系统及汇编
例如, 设内部 RAM (30H)=40H,(40H)=10H,
(10H)=00H,端口 (P1)=CAH,分析以下程序执行后各单
元及寄存器, P2口的内容 。
MOV R0,# 30H ; (R0) ← 30H,78 30
MOV A,@R0 ; (A) ← ((R0)),E6
MOV R1,A ; (R1) ← (A),F9
MOV B,@R1 ; (B) ← ((R1)),87 F0
MOV @R1,P1 ; ((R1))← (P1),A7 90
MOV P2,P1 ; (P2) ← (P1),85 90 A0
MOV 10H,# 20H ; (10H) ← 20H,75 10 20
第 3章 指令系统及汇编
2,外部数据存储器数据传送指令
MCS—51单片机 CPU对片外扩展的数据存储器
RAM或 I/O口进行数据传送,必须采用寄存器间接寻址
的方法,通过累加器 A来完成 。 一般数据的传送是通过
P0口和 P2口完成的,即片外 RAM地址总线低 8位由 P0口
送出,高 8位由 P2口送出,数据总线 ( 8位 ) 也由 P0口传
送 ( 双向 ),但与低 8位地址总线是分时传送的 。 这类
数据传送指令共有以下 4条单字节指令,指令操作码助
记符标志为 MOVX。
第 3章 指令系统及汇编
MOVX A,@DPTR ; (A) ← ((DPTR)),E0
MOVX A,@Ri ; (A) ← ((Ri)),E2~ E3
MOVX @DPTR,A ; ((DPTR)) ← (A),F0
MOVX @Ri,A ; ((Ri)) ← (A),F2~ F3
第 3章 指令系统及汇编
例如, 设外部 RAM (0203H)=FFH,分析以下指令执
行后的结果 。
MOV DPTR,# 0203H ; (DPTR) ← 0203H,90 02 03
MOVXA,@DPTR ; (A) ← ((DPTR)),E0
MOV 30H,A ; (30H) ← (A),F5 30
MOV A,# 0FH ; (A) ← 0FH,74 0F
MOVX@DPTR,A ; ((DPTR)) ← (A),F0
执行结果为, (DPTR)=0203H,(30H)=FFH,
(0203H)=(A)=0FH。
第 3章 指令系统及汇编
3,程序存储器向累加器 A传送数据指令
程序存储器向累加器 A传送数据指令,又称查表指
令 。 它采用变址寻址方式,把程序存储器 ( ROM或
EPROM) 中存放的表格数据读出,传送到累加器 A。
它共有如下两条单字节指令,指令操作码助记符为
MOVC。
MOVC A,@A+DPTR; (A) ← ((A)+(DPTR)),93
MOVC A,@A+PC; (PC) ← (PC)+1,(A) ← ((A)+(PC)),83
第 3章 指令系统及汇编
例 1,在外部 ROM/EPROM中,从 2000H单元开始依
次存放 0~ 9的平方值, 0,1,4,9,…,81,要求依
据累加器 A中的值 ( 0~ 9) 来查找所对应的平方值,分
析下述程序的结果 。
MOV DPTR,# 2000H ; (DPTR) ← 2000H,90 20 00
MOV A,# 09H ; (A) ← 09H,74 09
MOVC A,@A+DPTR ; (A) ← ((A)+(DPTR)),93
执行结果, (DPTR)=2000H,(A)=51H( 81的十六进制数)。
第 3章 指令系统及汇编
例 2,仍以例 1外部 ROM/EPROM 2000H单元开始
存放 0~ 9的平方值,以 PC作为基址寄存器进行查表 。
解, 设 MOVC指令所在地址 (PC)=1FF0H,则
偏移量 = 2000H- (1FF0H+1) = 0FH
相应的程序如下,
MOV A,# 09H ; (A) ← 09H,74 09
ADD A,# 0FH ; 地址调整,24 0F
MOVC A,@A+PC ; (A) ← ((A)+(PC)+1),83
执行结果为, (PC)=1FF1H,(A)=51H。
第 3章 指令系统及汇编
4,数据交换指令
数据传送类指令一般都用来将操作数自源地址传
送到目的地址,指令执行后,源地址的操作数不变,目的
地址的操作数则修改为源地址的操作数 。 而数据交换
指令其数据作双向传送,涉及传送的双方互为源地址,
目的地址,指令执行后各方的操作数都修改为另一方的
操作数 。 因此,两操作数均未冲掉, 丢失 。 数据交换
类指令共有如下 5条指令,
第 3章 指令系统及汇编
XCH A,direct ; (A) (direct),C5 direct
XCH A,@Ri ; (A) ((Ri)),C6~ C7
XCH A,Rn ; (A) (Rn),C8~ CF
XCHD A,@Ri ; (A3~ 0) ((Ri)3~ 0),D6~ D7
SWAP A ; (A7~ 4) (A3~ 0),C4
第 3章 指令系统及汇编
例 3,设 (R0)=30H,(30H)=4AH,(A)=28H,则,
执行 XCH A,@R0 ; 结果为, (A)=4AH,(30H)=28H
执行 XCHD A,@R0 ; 结果为, (A)=2AH,(30H)=48H
执行 SWAP A ; 结果为, (A)=82H
第 3章 指令系统及汇编
5,堆栈操作类指令
堆栈操作有进栈和出栈操作,即压入和弹出数据,
常用于保存或恢复现场 。 该类指令共有如下两条指令,
(SP)←(SP)+ 1
((SP))←(direct)
(direct)←((SP))
(SP)←(SP) -1
C0 direct PUSH direct
POP direct D0 direct
第 3章 指令系统及汇编
例 4,若在外部 ROM/EPROM中 2000H单元开始依次
存放 0~ 9的平方值,数据指针 (DPTR)=3A00H,用查表指
令取出 2003H单元的数据后,要求保持 DPTR中的内容
不变 。 完成以上功能的程序如下,
第 3章 指令系统及汇编
MOV A,# 03H ; (A) ← 03H,74 03
PUSH DPH ; 保护 DPTR高 8位入栈,C0 83
PUSH DPL ; 保护 DPTR低 8位入栈,C0 82
MOV DPTR,# 2000H ; (DPTR) ← 2000H,90 20 00
MOVC A,@A+DPTR ; (A) ← (2000H+03H),93
POP DPL ; 弹出 DPTR低 8位,D0 82
POP DPH ; 弹出 DPTR高 8位,( 先进后出 ),83
第 3章 指令系统及汇编
3.3.2 算术运算类指令
算术运算类指令共有 24条,可分为加法, 带进位加
法, 带借位减法, 加 1减 1,乘除及十进制调整指令共 6
组 。 它主要完成加, 减, 乘, 除四则运算,以及增量,
减量和二 —十进制调整操作,对 8位无符号数可进行直接
运算 ; 借助溢出标志,可对带符号数进行 2的补码运算 ;
借助进位标志,可进行多字节加减运算,也可以对压缩
BCD码 ( 即单字节中存放两位 BCD码 ) 进行运算 。
第 3章 指令系统及汇编
1,加法指令
加法指令共有如下 4条指令,操作数助记符为 ADD。
ADD A,# data ; (A) ← (A)+# data,24 data
ADD A,direct ; (A) ← (A)+(direct),25 direct
ADD A,@Ri ; (A) ← (A)+((Ri)),26~ 27
ADD A,Rn ; (A) ← (A)+(Rn),28~ 2F
第 3章 指令系统及汇编
这 4条指令使得累加器 A可以和内部 RAM的任何一
个单元的内容进行相加,也可以和一个 8位立即数相加,
相加结果存放在 A中 。 无论是哪一条加法指令,参加运
算的都是两个 8位二进制数 。 对用户来说,这些 8位数可
当作无符号数 ( 0~ 255),也可以当作带符号数 ( -
128~ +127),即补码数 。 例如, 对于二进制数
11010011,用户可认为它是无符号数,即为十进制数 211,
也可以认为它是带符号数,即为十进制负数 -45。 但计
算机在作加法运算时,总按以下规定进行,
第 3章 指令系统及汇编
(1) 在求和时,总是把操作数直接相加,而无须任何
变换 。 例如,若 A=11010011B,R1=11101000B,执行指
令 ADD A,R1时,其算式表达为,
11010011
+ 11101000
1 10111011
相加后 (A)=10111011B。 若认为是无符号相加,则
A的值代表十进制数 187; 若认为是带符号补码数相加,
则 A的值为十进制负数 -69。
第 3章 指令系统及汇编
(2) 在确定相加后进位标志 CY的值时,总是把两个
操作数作为无符号数直接相加而得出进位 CY值 。 如上
例中,相加后 CY=1。 若为无符号数相加 CY代表十进制
数 256,但若是两个带符号数相加,CY没有意义 。
(3) 在确定相加后溢出标志 OV的值时,计算机总是
把操作数当作带符号数来对待 。 在作加法运算时,一个
正数和一个负数相加是不可能产生溢出的,只有两个同
符号数相加才有可能产生溢出,表示运算结果出错 。
第 3章 指令系统及汇编
(4) 加法指令还会影响半进位标志和奇偶标志 P。
在上述例子中,由于 D3相加对 D4没有进位,所以 AC=0,
而由于运算结果 A中 1的数目为偶数,故 P=0。
例如, 设 (A)=49H,(R0)=6BH,
执行指令, ADD A,R0 ; (A) ← (A)+(R0),28
结果为, (A)=B4H,OV=1,CY=0,AC=1,P=0。
第 3章 指令系统及汇编
2,带进位加法指令
带进位加法指令有如下 4条指令,其助记符为 ADDC。
ADDC A,# data ; (A) ← (A)+(CY)+# data,34 data
ADDC A,direct ; (A) ← (A)+(CY)+(direct),35 direct
ADDC A,@Ri ; (A) ← (A)+(CY)+((Ri)),36~ 37
ADDC A,Rn ; (A) ← (A)+(CY)+(Rn),38~ 3F
第 3章 指令系统及汇编
例如, 设 (A)=C3H,数据指针低位 (DPL)=ABH,
CY=1
执行指令, ADDC A,DPL ; (A) ← (A)+(CY)+(DPL),
35 82
结果为, (A)=6FH,CY=1,OV=1,AC=0,P=0。
第 3章 指令系统及汇编
例 1,双字节无符号数加法 (R0 R1)+(R2 R3) →
(R4 R5)R0,R2,R4存放 16位数的高字节,R1,R3、
R5存放低字节 。 由于不存在 16位数加法指令,所以只
能先加低 8位,后加高 8位,而在加高 8位时要连低 8位相
加时产生的进位一起相加 。 假设其和不超过 16位,其
编程如下,
第 3章 指令系统及汇编
MOV A,R1 ; 取被加数低字节,E9
ADD A,R3 ; 低字节相加,2B
MOV R5,A ; 保存和低字节,FD
MOV A,R0 ; 取高字节被加数,E8
ADDC A,R2 ; 两高字节之和加低位进位,3A
MOV R4,A ; 保存和高字节,FC
第 3章 指令系统及汇编
3,带借位减法
带借位减法指令有如下 4条指令,其助记符为 SUBB。
SUBB A,# data ; (A) ← (A)- (CY)-# data,94 data
SUBB A,direct ; (A) ← (A)- (CY)- (direct),95 direct
SUBB A,@Ri ; (A) ← (A)- (CY)- ((Ri)),96~ 97
SUBB A,Rn ; (A) ← (A)- (CY)- (Rn),98~ 9F
第 3章 指令系统及汇编
由于减法指令只有带借位减法指令,因此,若要进
行不带借位位的减法操作,需先清借位位,即置 CY=0。
清 CY有专门的指令,它属于位操作类指令 ( 详见 3.3.5
节 ),指令为,
CLR C ; (CY) ← 0,C3
例如, 设 (A)=52H,(R0)=B4H
执行指令,
CLR C ; (CY)← 0,C3
SUBB A,R0 ; (A) ← (A)- (CY)- (R0),98
结果为, (A)=9EH,CY=1,AC=1,OV=1,P=1。
第 3章 指令系统及汇编
例 2,双字节无符号数相减 (R0 R1)- (R2 R3) → (R4
R5)。 R0,R2,R4存放 16位数的高字节,R1,R3,R5
存放低字节, 先减低 8位,后减高 8位和低位减借位 。 由
于低位开始减时没有借位,所以要先清零 。 其编程如下,
MOV A,R1 ; 取被减数低字节,E9
CLR C ; 清借位位,C3
SUBB A,R3 ; 低字节相减,9B
MOV R5,A ; 保存差低字节,FD
MOV A,R0 ; 取被减数高字节,E8
SUBB A,R2 ; 两高字节差减低位借位,9A
MOV R4,A ; 保存差高字节,FC
第 3章 指令系统及汇编
4,加 1,减 1指令
加 1指令共有如下 5条指令,助记符为 INC。
INC A ; (A) ← (A)+1,04
INC direct ; (direct) ← (direct)+1,05 direct
INC @Ri ; ((Ri)) ← ((Ri))+1,06~ 07
INC Rn ; (Rn) ← (Rn)+1,08~ 0F
INC DPTR ; (DPTR) ← (DPTR)+1,A3
第 3章 指令系统及汇编
减 1指令有如下 4条指令,助记符为 DEC。
DEC A ; (A) ← (A)- 1,14
DEC direct ; (direct) ← (direct)- 1,15 direct
DEC @Ri ; ((Ri)) ← ((Ri))- 1,16~ 17
DEC Rn ; (Rn) ← (Rn)- 1,18~ 1F
第 3章 指令系统及汇编
例如, 设 (R0)=7EH,(7EH)=FFH,(7FH)=38H,
(DPTR)=10FEH,分析逐条执行下列指令后各单元的内容。
INC @R0 ; 使 7EH单元内容由 FFH变为 00H
INC R0 ; 使 R0的内容由 7EH变为 7FH
INC @R0 ; 使 7FH单元内容由 38H变为 39H
INC DPTR ; 使 DPL为 FFH,DPH不变
INC DPTR ; 使 DPL为 00H,DPH为 11H
INC DPTR ; 使 DPL为 01H,DPH不变
第 3章 指令系统及汇编
5,乘, 除法指令
乘, 除法指令为单字节 4周期指令,在指令执行周
期中是最长的两条指令 。
(1) 乘法指令
MUL AB
(B)←((A) × (B))15~ 8,(A)←((A) × (B))7~ 0
(CY)←0
A4
第 3章 指令系统及汇编
乘法指令的功能是把累加器 A和寄存器 B中的两个
8位无符号数相乘,将乘积 16位数中的低 8位存放在 A中,
高 8位存放在 B中 。 若乘积大于 FFH( 255),则溢出标
志 OV置 1,否则 OV清 0。 乘法指令执行后进位标志 CY
总是清零,即 CY=0。 另外,乘法指令本身只能进行两个
8位数的乘法运算,要进行多字节乘法还需编写相应的
程序 。
例如, 若 (A)=4EH( 78),(B)=5DH( 93)
执行指令, MUL AB
结果为, 积为 (BA)=1C56H(7254) > FFH(255),
(A)=56H,(B)=1CH,OV=1,CY=0,P=0。
第 3章 指令系统及汇编
例 3,利用单字节乘法指令进行双字节数乘以单字
节数运算 。 若被乘数为 16位无符号数,地址为 M1和
M1+1( 低位先, 高位后 ),乘数为 8位无符号数,地址
为 M2,积存入 R2,R3和 R4三个寄存器中 。
(M1+1) (M1)
× (M2)
R3 R4
+ B A
R2 R3 R4
第 3章 指令系统及汇编
参考程序如下,
MOV R0,# M1 ; 被乘数地址存于 R0
MOV A,@R0 ; 取 16位数低 8位
MOV B,M2 ; 取乘数
MUL AB ; (M1)× (M2)
MOV R4,A ; 存积低 8位
MOV R3,B ; 暂存 (M1)× (M2)高 8位
INC R0 ; 指向 16位数高 8位
MOVA,@R0 ; 取被乘数高 8位
第 3章 指令系统及汇编
MOV B,M2 ; 取乘数
MUL AB ; (M1+1)× (M2)
ADD A,R3 ; (A)+(R3)得 (积 )15~ 8
MOV R3,A ; (积 )15~8存 R3
MOV A,B ; 积最高 8位送 A
ADDCA,# 00H ; 积最高 8位 +CY得 (积 )23~ 16
MOV R2,A ; (积 )23~ 16存入 R2
若上述程序执行前, (M1+1)=ABH,(M1)=CDH,
(M2)=64H,则执行后, (R2)=43H,(R3)=1CH,(R4)=14H。
第 3章 指令系统及汇编
(2) 除法指令
(A)←(A) ÷ (B)之商,(B)←(A) ÷ (B)
(CY)←0,(OV)←0
除法指令的功能是把累加器 A中的 8位无符号整数
除以寄存器 B中的 8位无符号整数,所得商存于累加器 A
中,余数存于寄存器 B中,进位标志 CY和溢出标志 OV均
被清零 。 若除数 B中的内容为 0时,除法运算没有意义,
结果为不定值,此时溢出标志 OV被置为 1,即 OV=1,而
CY仍为 0。
DIV A B ;,84
第 3章 指令系统及汇编
例 4,利用除法指令把累加器 A中的 8位二进制数转
换为 3位 BCD数,并以压缩形式存放在地址 M1,M2单元
中 。
解, 累加器 A中的 8 位二进制数,先对其除以 100
( 64H),商数即为十进制的百位数 ; 余数部分再除以 10
(0AH),所得商数和余数分别为十进制十位数和个位数,
即得到 3位 BCD数 。 百位数放在 M1中,十位, 个位数
压缩 BCD数放在 M2中,十位与个位数的压缩 BCD数的
存放是通过 SWAP和 ADD指令实现的 。 参考程序如下,
第 3章 指令系统及汇编
MOV B,# 64H ; 除数 100 送 B
DIV AB ; 得百位数
MOV M1,A ; 百位数存于 M1中
MOV A,# 0AH ; 取除数 10
XCH A,B ; 上述余数与除数交换
DIV AB ; 得十位数和个位数
SWAP A ; 十位数存于 A的高 4位
ADD A,B ; 组成压缩 BCD数
MOV M2,A ; 十, 个位压缩 BCD数存 M2
若上述程序执行前, (A)=A8H (168),则执行后,
(M1)=(01)BCD,(M2)=(68)BCD。
第 3章 指令系统及汇编
6,十进制调整指令
若 (A)3~ 0 >9或 (AC)=1,则 (A)3~ 0 ←(A) 3~ 0 +06H
DA A
若 (A)7~ 4 >9或 (CY)=1,则 (A)7~ 4 ←(A) 7~ 4 +06H
,D4
十进制调整指令是一条对二 —十进制的加法进行
调整的指令 。 两个压缩 BCD码按二进制相加,必须经
过本条指令调整后才能得到正确的压缩 BCD码和数,
实现十进制的加法运算 。 由于指令要利用 AC,CY
等标志才能起到正确的调整作用,因此它必须跟在加
法 ADD,ADDC指令后面方可使用 。
第 3章 指令系统及汇编
例 5,对 BCD码加法 65+58 BDH,进行十进制调整 。
解,参考程序如下:
MOV A,# 65H ; (A) ← 65
ADD A,# 58H ; (A) ← (A)+58
DA A ; 十进制调整
执行结果, (A)=(23)BCD,(CY)=1,即, 65+58=123。
01100101 65
+ 01011000 58
10111101 BD
+ 01100110 加 66H调整
1 00100011
第 3章 指令系统及汇编
例 6,双字节压缩 BCD码加法 。
解, 设 R5(高 ),R4(低 )为被加数 ; R3(高 ),R2(低 )为
加数,相加和的结果存入, R6(万 ),R5(千, 百 )、
R4(十, 个 )。 参考程序如下,
MOV A,R4 ; 被加数十位, 个位送入 A
ADD A,R2 ; 十位, 个位相加
DA A ; 和的十位, 个位调整
MOV R4,A ; 和的十位, 个位存入 R4
MOV A,R5 ; 被加数千位, 百位送入 A
ADDCA,R3 ; 千位, 百位的和加低位进位
第 3章 指令系统及汇编
DA A ; 和的千位, 百位调整
MOV R5,A ; 和的千位, 百位存入 R5
MOV A,# 00H ; A清零
ADDCA,# 00H ; 求和的万位值
MOV R6,A ; 和的万位存入 R6
若程序执行前, (R5)=(98)BCD,(R4)=(76) BCD,
(R3)=(54)BCD,(R2)=(32)BCD,
则执行后, (R6)=(01) BCD,(R5)=(53) BCD,
(R4)=(08) BCD 。
第 3章 指令系统及汇编
例 7,利用十进制加法调整指令 DA作十进制减法
调整 。
解, 由于 DA指令不能直接对减法进行十进制调整,
为了进行十进制减法运算,只能用加减数的补数来进
行 。 两位十进制数是对 100取补的,如 60-30=30,也可
:
60+(100-30)= 1 30
丢掉进位(模) 100后,就得到正确的结果。
第 3章 指令系统及汇编
在实际运算时,由于 CPU为 8位,不可能用 9位二进
制 数 表 示 十 进 制 数 100,但可用 8 位 二 进 制 数
10011010(9AH)代替,因为这个二进制数经过十进制调
整后就是 100000000。 这样十进制无符号数的减法运算
可按以下步骤进行,
(1) 求减数的补数 ( 9AH-减数 ) ;
(2) 被减数与减数的补数相加 ;
(3) 经 DA指令调整后就得到所求的十进制减法运算
结果。
第 3章 指令系统及汇编
这里用, 补数, 而不是, 补码, 是为了和带符号
位的补码加以区别 。 由于现在操作数都是正数,没有必
要再加符号位,故称, 补数, 更为合适一些 。
设 M1,M2,M3 分别为被减数, 减数和差的符
号地址,相应的十进制减法运算程序如下,
第 3章 指令系统及汇编
CLR C ; CY清 0
MOV A,# 9AH ; (A) ← # 9AH
SUBBA,M2 ; 求减数的补数
ADD A,M1 ; 加补数完成减法
DAA ; 十进制调整
MOV M3,A ; 差存入 M3单元
若程序执行前, (M1)=(91)BCD,(M2)=(36)BCD,则
程序执行后, (M3)=(55)BCD。
第 3章 指令系统及汇编
3.3.3 逻辑运算及移位类指令
逻辑运算及移位指令共有 24条,其中逻辑指令有
,与,,, 或,,, 异或,, 累加器 A清零和求反 20
条,移位指令 4条 。
1,逻辑, 与, 运算指令
逻辑, 与, 运算指令共有如下 6条,其助记符为
ANL。
ANL direct,A; (direct) ← (direct)∧ (A),52 direct
ANL direct,# data ; (direct) ← (direct)∧ # data,53 direct
data
第 3章 指令系统及汇编
ANL A,# data; (A) ← (A)∧ # data,54 data
ANL A,direct ; (A) ← (A)∧ (direct),55 direct
ANL A,@Ri ; (A) ← (A)∧ ((Ri)),56~57
ANL A,Rn ; (A) ← (A)∧ (Rn),58~5F
逻辑, 与, 运算指令是将两个指定的操作数按位进行逻
辑, 与, 的操作 。
例如, (A)=FAH=11111010B,(R1)=7FH=01111111B
执行指令, ANL A,R1 ; (A) ← 11111010∧ 01111111
结果为, (A)=01111010B=7AH。
逻辑, 与, ANL指令常用于屏蔽 ( 置 0) 字节中某
些位 。 若清除某位,则用, 0”和该位相与 ; 若保留某位,
则用, 1”和该位相与 。
第 3章 指令系统及汇编
2,逻辑, 或, 运算指令
逻辑, 或, 运算指令共有如下 6条指令,其助记符为 ORL。
ORL direct,A ; (direct) ← (direct)∨ (A),42 direct
ORL direct,# data; (direct) ← (direct)∨ # data,43 direct
data
ORL A,# data ; (A) ← (A)∨ # data,44 data
ORL A,direct ; (A) ← (A)∨ (direct),45 direct
ORL A,@Ri ; (A) ← (A)∨ ((Ri )),46~ 47
ORL A,Rn ; (A) ← (A)∨ (Rn),48~ 4F
第 3章 指令系统及汇编
逻辑, 或, 指令将两个指定的操作数按位进行逻
辑, 或, 操作 。 它常用来使字节中某些位置, 1”,欲
保留 ( 不变 ) 的位用, 0”与该位相或,而欲置位的位则
用, 1”与该位相或 。
例如, 若 (A)=C0H,(R0)=3FH,(3F)=0FH
执行指令, ORL A,@R0 ; (A) ← (A)∨ ((R0))
结果为, (A)=CFH。
第 3章 指令系统及汇编
又如, 根据累加器 A中 4~ 0位的状态,用逻辑与,
或指令控制 P1口 4~ 0位的状态,P1口的高 3位保持不变 。
ANL A,# 00011111B ; 屏蔽 A的高 3位
ANL P1,# 11100000B ; 保留 P1的高 3位
ORL P1,A ; 使 P14~ 0 按 A4~ 0 置位
若上述程序执行前, (A)=B5H=10110101B,
(P1)=6AH=01101010B,则
执行程序后, (A)=15H=00010101B,
(P1)=75H=01110101B。
第 3章 指令系统及汇编
3,逻辑, 异或, 运算指令
,异或, 运算是当两个操作数不一致时结果为 1,两
个操作数一致时结果为 0,这种运算也是按位进行,共有
如下 6条指令,其助记符为 XRL。
XRL direct,A ; (direct) ← (direct) (A),62 direct
XRL direct,# data ; (direct) ← (direct) # data,63 data
XRL A,# data ; (A) ← (A) # data,64 data
XRL A,direct ; (A) ← (A) (direct),65 direct
XRL A,@Ri ; (A) ← (A) ((Ri )),66 ← 67
XRL A,Rn ; (A) ← (A) (Rn),68 ← 6F
第 3章 指令系统及汇编
逻辑, 异或, 指令常用来对字节中某些位进行取
反操作,欲某位取反则该位与, 1”相异或 ;欲某位保留
则该位与, 0”相异或 。 还可利用异或指令对某单元自
身异或,以实现清零操作 。
例如, 若 ( A) =B5H=10110101B,执行下列指令,
XRL A,# 0F0H ; A的高 4位取反,低 4位保留
MOV 30H,A ; (30H) ← (A) = 45H
XRL A,30H ; 自身异或使 A清零
执行后结果, (A)=00H。
第 3章 指令系统及汇编
以上逻辑, 与,,, 或,,, 异或, 各 6条指令
有如下共同的特点,
(1) 逻辑, 与, ANL,,或, ORL,,异或, XRL
运算指令除逻辑操作功能不同外,三者的寻址方式相同,
指令字节数相同,机器周期数相同 。
(2) ANL,ORL,XRL的前两条指令的目的操作
数均为直接地址方式,可很方便地对内部 RAM的 00H~
FFH任一单元或特殊功能寄存器的指定位进行清零,
置位, 取反, 保持等逻辑操作 。
第 3章 指令系统及汇编
(3) ANL,ORL,XRL的后 4条指令,其逻辑运算
的目的操作数均在累加器 A中,且逻辑运算结果保存在
A中 。
4,累加器 A清零与取反指令
CLR A ; (A) ← 00H,E4
CPL A ; (A) ←(A ),F4
第 1条是对累加器 A清零指令,第 2条是把累加器 A
的内容取反后再送入 A中保存的对 A求反指令,它们均
为单字节指令 。 若用其它方法达到清零或取反的目的,
则至少需用双字节指令 。
第 3章 指令系统及汇编
例如, 上例中用异或指令使累加器清零,需要两条
双字节指令, MOV30H,A和 XRL A,30H共占用四字节
存储空间 ; 若用 MOV A,# 00H实现累加器清零,也需一
条双字节指令,而用 CLRA一条单字节指令就可完成 A
清零的操作,大大节约了程序的存储空间和程序的执行
时间 。
第 3章 指令系统及汇编
例 1,双字节数求补码 。
解, 对于一个 16 位数,R3 存高 8 位,R2 存低 8 位,
求补结果仍存 R3,R2。 求补的参考程序如下,
MOV A,R2 ; 低 8 位数送 A
CPL A ; 低 8 位数取反
ADD A,# 01H ; 加 1 得低 8 位数补码
MOV R2,A ; 存补码低 8 位
MOV A,R3 ; 高 8 位数送 A
CPL A ; 高 8 位取反
ADDCA,# 00H ; 加低 8 位进位
MOV R3,A ; 存补码高 8 位
第 3章 指令系统及汇编
5,移位指令
移位指令有如下循环左移, 带进位位循环左移, 循
环右移和带进位位循环右移 4 条指令,移位只能对累加器
A进行 。
循环左移 RL A ; (A n+1) ← (An),(A0) ← (A7),23
带进位位循环左移 RLC A ; (A n+1 ) ← (An ),(CY) ← (A7 ),
(A0 ) ← (CY),33
循环右移 RRA ; (An) ← (A n+1 ),(A7 ) ← (A0),03
带进位位循环右移 RRC A ; (An) ← (A n+1 ),(CY) ← (A0),
(A7) ← (CY),13
以上移位指令操作,可用图 3 ― 5 表示。
第 3章 指令系统及汇编
图 3 ― 5 移位指令操作示意图
第 3章 指令系统及汇编
另外,值得一提的是在前述数据传送类指令中有一
条累加器 A的内容半字节交换指令,
SWAP A ; (A)7~ 4 (A)3~ 0,C4
它实际上相当于执行循环左移指令 4 次 。 该指令
在 BCD码的变换中是很有用的,如 3.3.2 节的例 4。
第 3章 指令系统及汇编
例如, 设 (A)=43H,(CY)=0,则
执行指令, RL A ;
RLC A ;
RR A ;
RRC A ;
结果为, (A)=86H,(CY)=0
(A)=0CH,(CY)=1
(A)=06H,(CY)=1
(A)=83H,(CY)=0
第 3章 指令系统及汇编
例 2,16 位数的算术左移 。 16 位数在内存中低 8
位存放在 M1单元,高 8 M1+1 单元 。
解, 所谓算术左移就是将操作数左移一位,并使最
低位补充 0,相当于完成 16 位数的乘 2 操作,故称算术
左移 。 参考程序如下:
CLR C ; 进位 CY清零
MOV R1,# M1 ; 操作数地址 M1送 R1
MOV A,@R1 ; 16 位数低 8 位送 A
RLC A ; 低 8 位左移,最低位补 0
第 3章 指令系统及汇编
MOV @R1,A ; 低 8 位左移后,回送 M1存放
INC R1 ; 指向 16 位高 8 位地址 M1+1
MOV A,@R1 ; 高 8 位送 A
RLC A ; 高 8 位带低 8 位进位左移
MOV @R1,A ; 高 8 位左移后回送 M1+1 存放
第 3章 指令系统及汇编
3.3.4 控制转移类指令
控制转移类指令共计 17 条,可分为无条件转移指令,
条件转移指令, 子程序调用及返回指令 。 有了丰富的
控制转移类指令,就能很方便地实现程序的向前, 向后
跳转,并根据条件分支运行, 循环运行, 调用子程序等 。
1,无条件转移指令
无条件转移指令有如下 4 条指令,它们提供了不同
的转移范围和寻址方式,
LJMPaddr16; (PC) ← addr16,02 addr 15~ 8 addr 7~ 0
AJMPaddr11; (PC) ← (PC)+2,addr10~ 8 00001 addr
7~ 0 (PC)10~ 0 ← addr11
第 3章 指令系统及汇编
SJMP rel ; (PC) ← (PC)+2+rel,80rel
JMP @A+DPTR ; (PC) ← (A)+DPTR,73
(1) LJMP 称为长转移指令,三字节指令,提供 16 位
目标地址 addr16。
例如, 在程序存储器 0000H单元存放一条指令,
LJMP3000H; (PC) ← 3000H,02 30 00
则上电复位后程序将跳到 3000H 单元去执行用户程序 。
第 3章 指令系统及汇编
(2) AJMP称为绝对转移指令,双字节指令 。 它的机
器代码是由 11 位直接地址 addr11和指令特有操作码
00001,按下列分布组成的,
该指令执行后,程序转移的目的地址是由 AJMP指
令所在位置的地址 PC值加上该指令字节数 2,构成当前
PC值 。 取当前 PC值的高 5 位与指令中提供的 11 位直
接地址形成转移的目的地址,即,
a10 a9 a8 0 0 0 0 1 a7 a6 a5 a4 a3 a2 a1 a0
PC15 PC14 PC13 PC12 PC11 a10 a9 a8 a7 a6 a5 a4 a3 a2 a1 a0
PC
转移目的地址,
第 3章 指令系统及汇编
由于 11 位 地 址 的 范 围 是 00000000000 ~
11111111111,即 2 KB范围,而目标地址的高 5 位是由
PC当前值固定的,所以程序可转移的位置只能是和 PC
当前值在同一 2 KB的范围之内 。 本指令转移可以向前
也可以向后,指令执行后不影响状态标志位 。
例如, 若 AJMP指令地址 (PC)=2300H。
执行指令, AJMP0FFH; (PC) ← (PC)+2=2302H,01 FF
(PC)10~ 0← 00011111111
第 3章 指令系统及汇编
结果为, 转移目的地址 (PC)=20FFH,程序向前转
向 20FFH单元开始执行 。
又如, 若 AJMP指令地址 (PC)=2FFFH。
执行指令,
AJMP0FFH; (PC) ← (PC)+2=3001H,01 FF
(PC)10~ 0 ← 00011111111
结果为, 转移目的地址 (PC)=30FFH,程序向后转
向 30FFH单元开始执行。
第 3章 指令系统及汇编
(3) SJMP称为短转移指令,双字节指令,指令的操作
数是相对地址 rel。 由于 rel是带符号的偏移量,所以程
序可以无条件向前或向后转移,转移的范围是在 SJMP
指令所在地址 PC值 ( 源地址 ) 加该指令字节数 2的基础
上,以 -128~ +127 为偏移量 ( 256 个单元 ) 的范围内实
现相对短转移,即,
目的地址 =源地址 +2+rel
第 3章 指令系统及汇编
用汇编语言编程时,指令中的相对地址 rel往往用欲
转移至的地址的标号 ( 符号地址 ) 表示,能自动算出相
对地址值 ; 但人工将程序翻译成机器代码时,需自己计
算相对地址 rel。 rel的计算公式如下,
向前转移, rel=FE- ( 源地址与目的地址差的绝对值 )
向后转移, rel=(源地址与目的地址差的绝对值 ) - 2
若 rel值大于 80H,程序向前转移 ; 若 rel值小于 80H,则
程序向后转移 。
例如, 设 ( PC) =2100H,若转向 215CH去执行程序,则,
rel=(215CH- 2100H)- 2H=5AH
第 3章 指令系统及汇编
(4) JMP称为间接长转移指令 。 它是以数据指针
DPTR的内容为基址,以累加器 A的内容为相对偏移量,
在 64 KB范围内可无条件转移的单字节指令 。 该指令
的特点是转移地址可以在程序运行中加以改变 。
例如, 根据累加器 A的数值,转不同处理程序的入口 。
MOV DPTR,# TABLE ; 表首址送 DPTR
JMP @A+DPTR ; 依据 A值转移
TABLE,AJMPTAB1; 当 (A)=0时转 TAB1执行
AJMPTAB2; 当 (A)=2时转 TAB2执行
AJMPTAB3; 当 (A)=4时转 TAB3执行
第 3章 指令系统及汇编
2,条件转移指令 ( 判跳指令 )
条件转移指令是当某种条件满足时,程序转移执行 ;
条件不满足时,程序仍按原来顺序继续执行 。 条件转移
的条件可以是上一条指令或者更前一条指令的执行结
果 ( 常体现在标志位上 ),也可以是条件转移指令本身
包含的某种运算结果 。
1) 累加器判零转移指令
这类指令有 2 条:
JZ rel;若 (A)=0,则 (PC) ← (PC)+2+rel 60 rel
若 (A)≠0,则 (PC) ← (PC)+2
第 3章 指令系统及汇编
JNZ rel ; 若 (A)≠0,则 (PC) ← (PC)+2+rel,70 rel
若 (A)=0,则 (PC) ← (PC)+2
例 1,将外部数据 RAM的一个数据块传送到内部数
据 RAM,两者的首址分别为 DATA1 和 DATA2,遇到传
送的数据为零时停止 。
解, 外部 RAM向内部 RAM的数据传送一定要以累加
器 A作为过渡,利用判零条件转移正好可以判别是否要
继续传送或者终止 。 完成数据传送的参考程序如下,
第 3章 指令系统及汇编
MOV R0,# DATA1 ; 外部数据块首址送 R0
MOV R1,# DATA2 ; 内部数据块首址送 R1
LOOP:MOVX A,@R0 ; 取外部 RAM数据入 A
HERE:JZ HERE ; 数据为零则终止传送
MOV @R1,A ; 数据传送至内部 RAM单元
INCR0 ; 修改地址指针,指向下一数据地址
INCR1
SJMP LOOP ; 循环取数
第 3章 指令系统及汇编
2) 比较转移指令
比较转移指令共有 4 条,其一般格式为,
CJNE目的操作数,源操作数,rel
这组指令是先对两个规定的操作数进行比较,根据
比较的结果来决定是否转移到目的地址 。
4 条比较转移指令如下,
CJNE A,# data,rel ; B4 data rel
CJNE A,direct,rel ; B5direct rel
CJNE @Ri,# data,rel ; B6~ B7data rel
CJNER n,# data,rel ; B8~ Bfdata rel
第 3章 指令系统及汇编
这 4 条指令的含义分别为,
第 1 条指令, 累加器内容与立即数比较,不等则转
移 ;
第 2 条指令, 累加器内容与内部 RAM( 包括特殊功
能寄存器 ) 内容比较,不等则转移 ;
第 3 条指令, 内部 RAM内容与立即数比较,不等则
转移 ;
第 4 条指令, 工作寄存器内容与立即数比较,不等
则转移 。
第 3章 指令系统及汇编
以上 4 条指令的差别仅在于操作数的寻址方式不
同,均完成以下操作,
若目的操作数 =源操作数,则 (PC) ← (PC)+3 ;
若目的操作数 >源操作数,则 (PC) ← (PC)+3+rel,CY=0;
若目的操作数 <源操作数,则 (PC) ← (PC)+3+rel,CY=1;
指令的操作过程如图 3 ― 6 所示。
第 3章 指令系统及汇编
偏移量 rel 的计算公式为,
向前转移, rel = FD- ( 源地址与目的地址差的绝对
值 )
向后转移, rel =( 源地址与目的地址差的绝对值 ) -3
例如, 当 P1 口输入为 3AH时,程序继续进行,否则等
待,直至 P1口出现 3AH。 参考程序如下,
MOV A,# 3AH ; 立即数 3A送 A; 74 3A
WAIT,CJNE A,P1,WAIT ; (P1)≠3AH,则等待,B5 90 FD
第 3章 指令系统及汇编
图 3 ― 6 比较转移指令操作示意图
第 3章 指令系统及汇编
3) 减 1 条件转移指令 ( 循环转移指令 ) 减 1 条件
转移指令有如下两条,
DJNZ direct,rel; (direct)← (direct)- 1,D5 direct rel
若 (direct)=0,则 (PC) ← (PC)+3
否则,(PC) ← (PC)+3+rel
DJNZ Rn,rel ; (Rn) ← (Rn)- 1,D8~ DF rel
若 (Rn)=0,则 (PC) ← (PC)+2
否则,(PC) ← (PC)+2+rel
第 3章 指令系统及汇编
这组指令是把减 1功能和条件转移结合在一起的一
组指令 。 程序每执行一次该指令,就把第一操作数减 1,
并且结果保存在第一操作数中,然后判断操作数是否为
零 。 若不为零,则转移到规定的地址单元,否则顺序执
行 。 转移的目标地址是在以 PC当前值为中心的-
128~ +127 的范围内 。 如果第一操作数原为 00H,则
执行该组指令后,结果为 FFH,但不影响任何状态标志 。
第 3章 指令系统及汇编
例 2,软件延时程序,
MOV R1,# 0AH; 给 R1赋循环初值
DELAY,DJNZ R1,DELAY; (R1) ← (R1)- 1,若
(R1)≠0则循环
由于 DJNZ R1,DELAY 为双字节双周期指令,当
单片机主频为 12 MHz时,执行一次该指令需 24 个振荡
周期约 2 μs。 因此,R1 中置入循环次数为 10 时,执行
该循环指令可产生 20 μs 的延时时间 。
第 3章 指令系统及汇编
例 3,将内部 RAM中从 DATA单元开始的 10 个无符
号数相加,相加结果送 SUM 单元保存 。
解, 设相加结果不超过 8位二进制数,则相应的程序
如下,
MOV R0,# 0AH ; 给 R0 置计数器初值
MOV R1,# DATA ; 数据块首址送 R1
CLR A ; A清零
第 3章 指令系统及汇编
LOOP,ADD A,@R1 ; 加一个数
INC R1 ; 修改地址,指向下一个数
DJNZ R0,LOOP ; R0 减 1,不为零循环
MOV SUM,A ; 存 10 个数相加和
第 3章 指令系统及汇编
3,子程序调用及返回指令
在主程序中,有时需要反复执行某段程序,通常把
这段程序设计成子程序,用一条子程序调用指令,将程
序转向子程序的入口地址 。
(1) 子程序调用指令 。
子程序调用有长调用指令 LCALL和绝对调用指令
ACALL两条,它们分别表示如下,
LCALL addr16 ; (PC) ← (PC)+3,12 addr 15~ 8 addr 7~ 0
(SP) ← (SP)+1,((SP)) ← (PC 7~ 0)
(SP) ← (SP)+1,((SP)) ← (PC 15~ 8)
(PC) ← addr 15~ 0
第 3章 指令系统及汇编
ACALLaddr11 ; (PC) ← (PC)+2,addr 10~ 8 10001 addr 7~ 0
(SP) ← (SP)+1,((SP)) ← (PC 7~ 0)
(SP) ← (SP)+1,((SP)) ← (PC 15~ 8)
(PC) 10~ 0 ← addr11
LCALL 和 ACALL 指令类似于转移指令 LJMP 和
AJMP,不同之处在于它们在转移前要把执行完该指令的
PC内容自动压入堆栈后,才将 addr16( 或 addr11) 送往 PC,
即把子程序的入口地址装入 PC。
第 3章 指令系统及汇编
LCALL与 LJMP一样提供 16 位地址,可调用 64 KB
范围内所指定的子程序 。 由于该指令为三字节指令,所
以执行该指令时首先把 (PC)+3→(PC),以获得下一条指
令地址,并把此时 PC内容压入堆栈 ( 先压入低字节,后
压入高字节 ) 作为返回地址,堆栈指针 SP加 2指向栈顶,
然后把目的地址 addr16 装入 PC。 执行该指令不影响标
志位 。
第 3章 指令系统及汇编
ACALL与 AJMP一样提供 11 位目的地址 。 由于该
指令为两字节指令,所以执行该指令时 (PC)+2→(PC) 以
获得下一条指令的地址,并把该地址压入堆栈作为返回
地址 。 该指令可寻址 2 KB,只能在与 PC同一 2 KB 的
范围内调用子程序 。 执行该指令不影响标志位 。
例如, 设, (SP)=30H,标号为 SUB1 的子程序首址在
2500H,(PC)=3000H。
执行指令, 3000H,LCALL SUB1; 12 25 003003H …
结果为, (SP)=32H,(31H)=03H,(32H)=30H,(PC)=2500H。
第 3章 指令系统及汇编
(2) 返回指令 。
返回指令共有两条, 一条是对应两条调用指令的子
程序返回指令 RET; 另一条是对应从中断服务程序的返
回指令 RETI。
RET; ( PC15~ 8) ← ((SP)),(SP) ← (SP)- 1,22
( PC7~ 0) ← ((SP)),(SP) ← (SP)- 1
RETI; ( PC15~ 8) ← ((SP)),(SP) ← (SP)- 1,32
( PC7~ 0) ← ((SP)),(SP) ← (SP)- 1
第 3章 指令系统及汇编
4,空操作指令
NOP ; (PC) ← (PC)+1,00
空操作指令是一条单字节单周期指令 。 它控制
CPU不做任何操作,仅仅是消耗这条指令执行所需要的
一个机器周期的时间,不影响任何标志,故称为空操作
指令 。 但由于执行一次该指令需要一个机器周期,所以
常在程序中加上几条 NOP指令用于设计延时程序,拼凑
精确延时时间或产生程序等待等 。
第 3章 指令系统及汇编
3.3.5位操作类指令
位操作又称为布尔变量操作,它是以位 (bit)作为单
位来进行运算和操作的 。 MCS- 51系列单片机内设置
了一个位处理器 ( 布尔处理机 ),它有自己的累加器
( 借用进位标志 CY),自己的存储器 ( 即位寻址区中
的各位 ),也有完成位操作的运算器等 。
第 3章 指令系统及汇编
这一组指令的操作对象是内部 RAM中的位寻址区,
即 20H~ 2FH中连续的 128 位 ( 位地址 00H~ 7FH),以
及特殊功能寄存器 SFR中可进行位寻址的各位 。 在指
令中,位地址的表示方法主要有以下 4 种 ( 均以程序状
态字寄存器 PSW的第五位 F0 标志为例说明 ),
(1) 直接位地址表示方式, 如 D5H;
(2) 点操作符表示 ( 说明是什么寄存器的什么位 )
方式, 如 PSW.5,说明是 PSW的第五位 ;
(3) 位名称表示方法, 如 F0 ;
(4) 用户定义名表示方式, 如用户定义用 FLG这一名
称 ( 位符号地址 ) 来代替 F0,
第 3章 指令系统及汇编
1,位传送指令
位传送指令有如下互逆的两条双字节单周期指令,
可实现进位位 CY与某直接寻址位 bit间内容的传送 。
MOV C,bit ; (CY) ← ( bit),A2 bit
MOV bit,C ; (bit) ← (CY),92 bit
上述指令中, bit为直接寻址位,C为进位标志 CY的
简写 。 第 1条指令是把 bit中的一位二进制数送位累加
器 CY中,不影响其余标志 。 第 2条指令是将 C中的内容
传送给指定位 。
第 3章 指令系统及汇编
由于两个寻址位之间没有直接的传送指令,常用上述
两条指令并通过 C作为中间媒介来进行寻址位间的传送 。
例如, 将内部 RAM中 20H 单元的第 7位 ( 位地址为
07H) 的内容,送入 P1口的 P1.0中的程序如下,
MOV C,07H ; (CY) ← (07H)
MOV P1.0,C ; (P1.0) ← (CY)
当 (20H)=A3H,(P1)=11111110B时,执行上述指令后修
改了 P1 口第 0 位, 即 (CY)=1,(P1)=11111111B。
第 3章 指令系统及汇编
2,位置位指令
对进位标志 CY以及位地址所规定的各位都可以进
行置位或清零操作,共有如下 4条指令,
CLR bit ; (bit) ← 0,C2 bit
CLR C; (CY) ← 0,C3
SETB bit ; (bit) ← 1,D2 bit
SETB C ; (CY) ← 1,D3
第 3章 指令系统及汇编
前两条指令为位清零指令,后两条指令为位置 1 指
令 。 当第 1,3 条指令的直接寻址位为某端口的某位
时,指令执行时具有读 —修改 —写功能 。
例如, 将 P1 口的 P1.7 置位,并清进位位的程序如下,
SETB P1.7 ; (P1.7) ← 1
CLR C ; (CY) ← 0
当 (P1)=00001111B时,执行完上述指令后,
(P1)=10001111B,(CY)=0。
第 3章 指令系统及汇编
3,位逻辑指令
位逻辑指令包含, 与, ANL,,或, ORL、
,非, CPL位逻辑运算操作,共有如下 6 条指令,
ANL C,bit ; (CY) ← (CY)∧ ( ),82bit
ANL C,/ bit ; (CY) ← (CY)∧ ( ),B0bit
ORL C,bit ; (CY) ← (CY)∨ ( ),72bit
ORL C,/ bit ; (CY) ← (CY)∨ ( ),A0bit
CPL bit ; (bit) ← ( ),B2bit
CPL C ; (CY) ← (C),B3
bit
bit
bit
bit
bit
第 3章 指令系统及汇编
例 1,完成 (←Z ) =(X) (Y)异或运算,其中, X,Y、
Z表示位地址 。
解, 异或运算可表示为, ( Z) =(X)( )+( )(Y),参
考子程序如下,
PR1,MOV C,X ; (CY) ← (X)
ANL C,/Y ; (CY) ← (X)( )
MOV Z,C ; 暂存 Z中
MOV C,Y ; (CY) ← (Y)
ANL C,/X ; (CY)←( ) (Y)
ORL C,Z ; (CY) ← (X)( )+( )(Y)
MOV Z,C ; 保存异或结果
RET
?
Y X
Y
X
Y X
第 3章 指令系统及汇编
例 2,利用位逻辑指令,模拟图 3 ― 7 所示硬件逻辑
电路功能 。 参考子程序如下,
PR2,MOV C,P1.1 ; (CY) ← (P1.1)
ORL C,P1.2 ; (CY) ← (P1.1)∨ (P1.2) = A
ANL C,P1.0 ; (CY) ← (P1.0)∧ A
CPL C ; (CY) ←
MOV F0,C ; F0内暂存 B
MOV C,P1.3 ; (CY) ← (P1.3)
ANL C,/P1.4 ; (CY) ← (P1.3)∧
ORL C,F0 ; (CY) ← B∨ D
MOV P1.5,C ; 运算结果送入 P1.5
RET
( 1,0 )P A B??
( 1.4)PD?
第 3章 指令系统及汇编
4,位条件转移指令
位条件转移指令是以进位标志 CY或者位地址 bit的
内容作为是否转移的条件,共有 5 条指令 。
(1) 以 CY内容为条件的双字节双周期转换指令。
JC rel ; 若 (CY)=1,则 (PC) ← (PC)+2+rel转移,40 rel
否则,(PC) ← (PC)+2 顺序执行
JNC rel ; 若 (CY)=0,则 (PC) ← (PC)+2+rel转移,50 rel
否则,(PC) ← (PC)+2 顺序执行
第 3章 指令系统及汇编
这两条指令常和比较条件转移指令 CJNE一起使用,
先由 CJNE指令判别两个操作数是否相等,若相等就顺
序执行 ; 若不相等则依据两个操作数的大小置位或清零
CY(参见图 3 - 6),再由 JC 或 JNC指令根据 CY的值决定
如何进一步分支,从而形成三分支的控制模式,如图 3 -
8 所示 。
第 3章 指令系统及汇编
图 3 ― 7 例 2 硬件逻辑电路
第 3章 指令系统及汇编
图 3 ― 8CJNE 与 JC( 或 JNC) 一起构成三分支模式
第 3章 指令系统及汇编
例 3,比较内部 RAM I,J单元中 A,B两数的大小 。
若 A=B,则使内部 RAM的位 K置 1; 若 A≠B,则大数存 M
单元,小数存 N单元 。 设 A,B数均为带符号数,以补码
数存入 I,J中,该带符号数比较子程序的比较过程示意
图如图 3 ― 9 所示 。 参考子程序如下:
第 3章 指令系统及汇编
图 3 ― 9 带符号数比较过程示意图
第 3章 指令系统及汇编
MOV A,I ; A数送累加器 A
ANL A,# 80H ; 判 A数的正负
JNZ NEG ; A<0 则转至 NEG
MOV A,J ; B数送累加器 A
ANL A,# 80H ; 判 B数的正负
JNZ BIG1 ; A≥0,B< 0,转 BIG1
SJMP COMP ; A≥0,B≥0,转 COMP
NEG,MOV A,J ; B数送累加器 A
ANL A,# 80H ; 判 B数的正负
JZ SMALL ; A< 0,B≥0,转 SMALL
COMP:MOV A,I ; A数送累加器 A
第 3章 指令系统及汇编
CJNE A,J,BIG ; A≠B则转 BIG
SETB K ; A=B,位 K置 1
RET
BIG,JC SMALL ; A<B转 SMALL
BIG1,MOV M,I ; 大数 A存入 M单元
MOV N,J ; 小数 B存入 N单元
RET
SMALL,MOV M,J ; 大数 B存入 M单元
MOV N,I ; 小数 A存入 N单元
RET
第 3章 指令系统及汇编
(2) 以位地址内容为条件的三字节双周期转移指令 。
JB bit,rel;若 (bit)=1,则 (PC) ← (PC)+3+rel转移,20 bit rel
否则,(PC) = (PC)+3 顺序执行
JNBbit,rel;若 (bit)=0,则 (PC) ← (PC)+3+rel转移,30 bit rel
否则,(PC) ← (PC)+3 顺序执行
JBC bit,rel ;若 (bit)=1,则 (PC) ← (PC)+3+rel,(bit)← 0,10
bit rel
否则,(PC) ← (PC)+3 顺序执行
第 3章 指令系统及汇编
上述指令测试直接寻址位,若位变量为 1( 第 1,3
条指令 ) 或位变量为 0( 第 2 条指令 ),则程序转向目
的地址去执行,否则顺序执行下条指令 。 该类指令测试
位变量时,不影响任何标志 。 前两条指令执行后也不影
响原位变量值,而第 3 条指令虽和第 1 条指令的转移功
能相同,但无论测试位变量原为何值,检测后即对该位
变量清零 。 该指令直接寻址位若为某端口的某位时,具
有读 — 修改 — 写功能 。
第 3章 指令系统及汇编
以上介绍了 MCS- 51 系列单片机的指令系统 。 有
关 111 条指令助记符, 操作数, 机器代码以及字节数
和指令周期一览表详见附录 B。 附录 B中表 B ― 1 是按
字母顺序排列的指令, 表 B ― 2 是按功能排列指令表 。
有关影响标志位的指令一览表见表 3 ― 3。
第 3章 指令系统及汇编
表 3 ― 3 影响标志的指令
第 3章 指令系统及汇编
3.4 汇编语言及汇编语言程序设计
3.4.1 机器语言, 汇编语言和高级语言
用户要使计算机能完成各式各样的任务,就要设计
各种相应的应用程序,而设计程序就要用到程序设计语
言 。 程序设计语言有 3种, 机器语言, 汇编语言和高级
语言 。
第 3章 指令系统及汇编
1,机器语言
计算机能直接识别和执行的二进制代码形式的指令
称为机器指令,而该类指令的集合称为计算机的机器语
言,或称指令系统 。 机器语言是面向计算机系统的 。
由于各种计算机内部结构,线路的不同,每种计算机系
统都有它自己的机器语言,即使执行同一操作,其指令
也不相同 。
第 3章 指令系统及汇编
2,汇编语言
计算机所能执行的每条指令都对应一组二进制代
码 。 为了容易理解和记忆计算机的指令,人们用一些英
语的单词和字符以及数字作为助记符来描述每一条指
令的功能 。 用助记符描述的指令系统,称为机器的汇编
语言系统,简称汇编语言 。 汇编语言也是面向机器的,
每种计算机系统也都有它自己的汇编语言,用汇编语言
编写的程序,称为汇编语言源程序或汇编源程序 。
第 3章 指令系统及汇编
MCS—51 系列单片机是用 51 系列单片机的指令系
统来编程的,其汇编语言的语句格式,也就是单片机的
指令格式,即,
[ 标号, ] 操作码 [ 操作数 ] [ ; 注释 ]
汇编语言是面向机器的程序设计语言,与具体的计
算机硬件有着密切的关系,然而汇编语言也有它的缺点,
在用它编写程序时,必须熟悉机器的指令系统, 寻址方
式, 寄存器设置和使用方法,而编出的程序也只适用于
某一系列的计算机 。 因此,可移植性差,不能直接移植
到不同类型的计算机系统上去 。
第 3章 指令系统及汇编
3,高级语言
高级语言 ( 如, PASCAL,C,FORTRAN、
BASIC等 ) 克服了汇编语言的缺点,是一种面向问题或
过程的语言 。 它是一种接近于自然语言和数学算法的
语言,与机器的硬件无关,用户编程时不必仔细了解所
用计算机的具体性能和指令系统 。 高级语言不但直观,
易学, 易懂,而且通用性强,可以在不同的计算机上运
行,因此可移植性好 。
第 3章 指令系统及汇编
3.4.2 汇编程序与伪指令
1,汇编程序
MCS—51 指令所编写的汇编语言源程序,还必须经
过从汇编源程序到机器语言目标程序的, 翻译,,才能
在 51 系列单片机运行,这种翻译的过程称为汇编 。 完
成汇编工作有两种途径, 一种是人工汇编 ; 一种是机器
汇编 。 对于量小, 简单的程序,程序员经过查指令系
统表,将汇编源程序逐条翻译成机器代码,完成手工汇
编,再从单片机开发装置的键盘上输入目标程序进行调
试, 运行 ; 而对于量大, 较复杂的程序,翻译过程可采
用计算机系统软件 — 汇编程序完成,即机器汇编 。
第 3章 指令系统及汇编
汇编程序是将汇编源程序转变为相应目标程序的
翻译程序 。 由于指令助记符与机器语言指令是一一对
应的等价关系,所以汇编程序能很容易将汇编源程序迅
速, 准确, 有效地翻译成目标程序 。
第 3章 指令系统及汇编
2,伪指令
在汇编源程序的过程中,还有一些指令不要求计算
机进行任何操作,也没有对应的机器码,不产生目标程
序,不影响程序的执行,仅仅是能够帮助汇编进行的一
些指令,称之为伪指令 。 它主要用来指定程序或数据的
起始位置,给出一些连续存放数据的确定地址,或为中
间运算结果保留一部分存储空间以及表示源程序结束
等等 。 不同版本的汇编语言,伪指令的符号和含义可能
有所不同,但是基本用法是相似的 。 下面介绍几种常用
的基本伪指令 。
第 3章 指令系统及汇编
(1) 设置目标程序起始地址伪指令 ORG。
格式, [ 标号, ] ORG 16位地址
该伪指令的功能是规定其后面目标程序的起始地
址 。 它放在一段源程序 ( 主程序, 子程序 ) 或数据块
的前面,说明紧跟在其后的程序段或数据块的起始地址
就是指令中的 16 位地址 ( 4 位十六进制数 ) 。
例如, ORG 2000H
START,MOVA,# 7FH

第 3章 指令系统及汇编
(2) 结束汇编伪指令 END。
格式, [ 标号, ] END
END是汇编语言源程序的结束标志,表示汇编结束 。
在 END以后所写的指令,汇编程序都不予以处理 。 一
个源程序只能有一个 END命令 。 在同时包含有主程序
和子程序的源程序中,也只能有一个 END命令,并放到
所有指令的最后,否则,就有一部分指令不能被汇编 。
第 3章 指令系统及汇编
(3) 定义字节伪指令 DB。
格式, [ 标号, ] DB 项或项表
其中项或项表指一个字节,或用逗号分开的字符串,
或以引号括起来的字符串 ( 一个字符用 ASCII码表示,
就相当于一个字节 ) 。 该伪指令的功能是把项或项表
的数值 ( 字符则用 ASCII码 ) 存入从标号开始的连续存
储单元中 。
第 3章 指令系统及汇编
例如, ORG 2000H
TAB1,DB 30H,8AH,7FH,73
DB ′5′,′A′,′BCD′
由于 ORG 2000H,所以 TAB1的地址为 2000H,因此
以上伪指令经汇编以后,将对 2000H开始的若干内存单
元赋值,
(2000H) = 30H
(2001H)=8AH
(2002H)=7FH
第 3章 指令系统及汇编
(2003H) = 49H ; 十进制数 73 以十六进制数存放
(2004H) = 35H ; 数字 5 的 ASCII码
(2005H) = 41H ; 字母 A的 ASCII码
(2006H) = 42H ; ′BCD′中 B的 ASCII码
(2007H) = 43H ; ′BCD′中 C的 ASCII码
(2008H) = 44H ; ′BCD′中 D的 ASCII码
又如,

1FFDH LJMP 1234H
DB 30H,8AH,7FH,73,′5′,′A′,′BCD′
第 3章 指令系统及汇编
(4) 定义字伪指令 DW。
格式, [ 标号, ] DW 项或项表
DW伪指令与 DB的功能类似,所不同的是 DB用于
定义一个字节 ( 8 位二进制数 ),而 DW则用于定义一个
字 ( 即两个字节,16 位二进制数 ) 。 在执行汇编程序时,
机器会自动按高 8 位先存入,低 8 位后存入的格式排列,
这和 MCS—51 指令中 16 位数据存放的方式一致 。
例如, ORG 1500H
TAB2,DW 1234H,80H
汇编以后, (1500H)=12H,(1501H)=34H,(1502H)=00H,
(1503H)=80H。
第 3章 指令系统及汇编
(5) 预留存储空间伪指令 DS。
格式, [ 标号, ] DS 表达式
该伪指令的功能是从标号指定的单元开始,保留若
干字节的内存空间以备源程序使用 。 存储空间内预留
的存储单元数由表达式的值决定 。
例如, ORG 1000H
DS 20H
DB 30H,8FH
第 3章 指令系统及汇编
汇编后, 从 1000H开始,预留 32(20H)个字节的内存
单元,然后从 1020H开始,按照下一条 DB指令赋值,即
(1020H)=30H,(1021H)=8FH。 保留的存储空间将由程
序的其它部分决定它们的用处 。
第 3章 指令系统及汇编
(6) 等值伪指令 EQU。
格式, 标号,EQU 项
该伪指令的功能是将指令中项的值赋予本语句的
标号 。 项可以是常数, 地址标号或表达式 。
例如,TAB,EQU 1000H
TAB1,EQU TAB
前一条伪指令表示 TAB地址的值为 1000H,后一条
表示符号地址 TAB1与 TAB等值 ( 可以互换 ),需要注
意的是,在同一程序中,用 EQU伪指令对某标号赋值后,
该标号的值在整个程序中不能再改变 。
第 3章 指令系统及汇编
(7) 位地址赋值伪指令 BIT。
格式, 标号 BIT位地址
该伪指令的功能是将位地址赋予特定位的标号,经
赋值后就可用指令中 BIT左面的标号来代替 BIT右边所
指出的位 。
例如, FLG,BIT F0
AI,BIT P1.0
经以上伪指令定义后,在编程中就可以把 FLG和 AI
作为位地址来使用。
第 3章 指令系统及汇编
3.5 基本程序设计方法
3.5.1 程序的基本结构
用汇编语言进行程序设计的过程和用高级语言进
行程序设计相类似 。 对于比较复杂的问题,首先要掌握
解决它的方法和步骤 ——算法,有了合适的算法常常可以
起到事半功倍的效果 ; 其次,就是用操作框, 带箭头流
程线, 框内外必要的文字说明所组成的流程图来描述
算法 ; 最后是根据流程图用程序设计语言来编制程序 。
第 3章 指令系统及汇编
程序的基本算法结构有 3 种, 顺序结构, 分支
( 选择 ) 结构和循环结构 。
顺序结构如图 3 ― 10 所示,虚框内 A框和 B框分别
代表不同的操作,而且是 A,B顺序执行 。
分支结构如图 3 ― 11 所示,它又称为选择结构 。
该结构中包含一个判断框,根据给定条件 P是否成立而
选择执行 A框操作或 B框操作 。 条件 P可以是累加器是
否为零, 两数是否相等,以及测试状态标志或位状态
等等 。
第 3章 指令系统及汇编
循环结构如图 3 ― 12 所示,它在一定的条件下,反
复执行某一部分的操作 。 循环结构又分为当型 ( While)
循环结构和直到型 ( Until) 循环结构两种方式,见图 3
― 12 的 (a),(b)。 当型循环是先判断条件,条件成立
则执行循环体 A; 而直到型循环则是先执行循环体 A一
次,再判断条件,条件不成立再执行循环体 A。 循环结
构的两种形式可以互相转换 。
第 3章 指令系统及汇编
图 3 ― 10 顺序结构
第 3章 指令系统及汇编
图 3 ― 11 分支结构
第 3章 指令系统及汇编
由以上 3 种基本结构顺序组成的算法结构,可以解
决任何复杂的问题 。 由基本结构所构成的算法属于结
构化的算法 。 虽然在 3 种基本结构的操作框 A或 B中,
可能是一些简单操作,也可能还嵌套着另一个基本结构,
但是不存在无规律的转移,只在该基本结构内才存在分
支和向前或向后的跳转 。
第 3章 指令系统及汇编
图 3 ― 12循环结构
(a) 当型循环 ; (b) 直到型循环
第 3章 指令系统及汇编
3.5.2 顺序结构程序设计
顺序结构是最简单的一种基本结构 。 如果某一个
需要解决的问题可以分解成若干个简单的操作步骤,并
且可以由这些操作按一定的顺序构成一种解决问题的
算法,则可用简单的顺序结构来进行程序设计 。
例 1,单字节压缩 BCD码转换成二进制码子程序 。
解, 设两个 BCD码 d1d0 表示的两位十进制数压缩存
于 R2,其中 R2 高 4 位存十位,低 4 位存个位,要把其转
换成纯二进制码的算法为, (d1d0)BCD=d1× 10+d0。 实
现该算法所编制的参考子程序如下,
第 3章 指令系统及汇编
入口, 待转换的 BCD码存于 R2。
出口, 转换结果 ( 8 位无符号二进制整数 ) 仍存 R2。
BCD2B,ORG 2000H
MOV A,R2 ; (A) ← (d1d0)BCD
ANL A,# 0F0H ; 取高位 BCD码 d1
SWAP A ; (A)=0d1H
MOV B,# 0AH ; (B) ← 10
MUL AB ; d1× 10
MOV R3,A ; R3暂存乘积结果
MOV A,R2 ; (A) ← (d1d0)BCD
ANL A,# 0FH ; 取低位 BCD码 d0
ADD A,R3 ; d1× 10+d0
MOV R2,A ; 保存转换结果
RET ; 子程序返回
第 3章 指令系统及汇编
例 2,双字节压缩 BCD码转换成二进制码子程序 。
解, 该转换的算法为,
(d3d2d1d0)BCD=(d3× 10+d2)× 100+(d1× 10+d0)
实现该算法的参考子程序如下,
入口, R5(千位, 百位 ),R4(十位, 个位 )为 BCD码 。
出口, R5R4(16 位无符号二进制整数 )。
BCD4B,ORG 2100H
MOV A,R5 ; (A) ← d3d2 (千位, 百位 )
MOV R2,A ; (R2) ← d3d2
ACALL BCD2B ; 调例 1子程序实现 d3× 10+d2→A
第 3章 指令系统及汇编
MOV B,# 64H ; (B) ← 100
MUL AB ; (d3× 10+d2)× 100
MOV R6,A ; R6 暂存乘积低 8 位
XCH A,B ; 乘积高 8 位送 A
MOV R5,A ; R5暂存乘积高 8位
MOV A,R4 ; (A) ← d1d0 (十位, 个位 )
MOV R2,A ; (R2) ← d1d0
ACALL BCD2B ; 调例 1 子程序实现 d1× 10+d0→A
第 3章 指令系统及汇编
ADD A,R6 ; (A) ← (R6)+(A)
MOV R4,A ; R4存转换后 16 位数低 8 位
MOV A,R5 ; (A) ← (R5)
ADDC A,# 00H ; (A) ← (R5)+低 8 位和的进位 C
MOV R5,A ; R5存转换后 16 位数高 8 位
RET ; 子程序返回
第 3章 指令系统及汇编
3.5.3 分支 ( 选择 ) 结构程序设计
顺序结构程序设计是最基本的程序设计技术 。 在
实际的程序设计中,有很多情况往往还需要程序按照给
定的条件进行分支 。 这时就必须对某一个变量所处的
状态进行判断,根据判断结果来决定程序的流向 。 这就
是分支 ( 选择 ) 结构程序设计 。
在编写分支程序时,关键是如何判断分支的条件 。
在 MCS—51 单片机指令系统中,有 JZ( JNZ), CJNE、
JC( JNC) 及 JB( JNB) 等丰富的控制转移指令,它们
是分支结构程序设计的基础,可以完成各种各样的条件
判断, 分支 。
第 3章 指令系统及汇编
例 3,设变量 X存放在 VAR单元中,函数 Y存放在
FUNC单元 。 编写按照下式要求给 Y赋值的程序 。
1 X>0
Y= 0 X=0
-1 X<0
第 3章 指令系统及汇编
解, 由于 X为有符号数,因此可以根据它的符号位来
决定其正负 。 判别符号位是 0 还是 1,可利用 JB或 JNB
指令 ; 而判别 X是否为 0,则可直接用累加器判零指令 JZ。
完成本例题任务的程序流程框图是由顺序结构 +分支结
构组成的,并且在分支结构中又嵌套了另一个分支结构,
从而形成了三分支而归一的流程,如图 3 ― 13 所示 。
第 3章 指令系统及汇编
图 3 ― 13 例 3 程序框图
第 3章 指令系统及汇编
程序清单,
BR1,ORG 2000H
MOV A,VAR ; 取出 X送 A
JZ COMP ; 若 X=0 则转移到 COMP
JNB ACC.7,POSI ; 若 X>0则转移到 POSI
MOV A,# 0FFH ; 若 X<0 则 A=-1
SJMP COMP ; 转分支结构出口
POSI,MOV A,# 01H ; X>0 时 A=1
COMP,MOV FUNC,A ; 存函数 Y值
HERE,AJMPHERE ; 结束程序
第 3章 指令系统及汇编
例 4,3 个无符号单字节整数分别存于 R1,R2、
R3 中,找出其中最大数放于 R0 中 。
解, 首先将 R0 清零,然后进行 (R1)与 (R0)减法,若
(R1)- (R0)>0,则 (R1)>(R0),把 (R1) 送 (R0); 否则 (R0)保
持不变 。 再将 (R0)分别与 (R2)和 (R3)比较,比较处理的
方法与上面相同,这样比较 3 次后,R0 中即为 3 数中的
最大数 。 程序清单如下,
BR2,ORG 2500H
MOV R0,# 00H ; R0 清零
MOV A,R1 ; 第一个数 (R1)送 A
ACALL COMP ; 比较 (R1)与 (R0)大小
第 3章 指令系统及汇编
MOV A,R2 ; 第二个数 (R2)送 A
ACALL COMP ; 比较 (R2)与 (R0)大小
MOV A,R3 ; 第三个数 (R3)送 A
ACALL COMP ; 比较 (R3)与 (R0)大小
HERE,AJMP HERE
COMP,MOV R4,A ; R4 暂存 A的内容
CLR C ; 清进位位 C
SUBB A,R0 ; (A)- (R0)
JC M1 ; (A)<(R0)转至 M1
MOV A,R4 ; 恢复 A值
MOV R0,A ; (A)>(R0)时大数存 R0
M1,RET
第 3章 指令系统及汇编
3.5.4 循环结构程序设计
在解决实际问题时,往往会遇到同样的一组操作需
要重复多次的情况,这时应采用循环结构,以简化程序,
缩短程序的长度及节省存储空间 。 例如,要做 1 到 100
的加法,没有必要写 100 条加法指令,而只需写一条加
法指令,使其执行 100 次,每次执行时操作数亦作相应
的变化,同样能完成原来规定的操作 。
第 3章 指令系统及汇编
循环程序一般由 3 部分组成,
(1) 置循环初值, 即设置循环开始时的状态。
(2) 循环体, 即要求重复执行的部分。
(3) 循环控制部分, 它包括循环参数修改和依据循
环结束条件判断循环是否结束两部分 。
第 3章 指令系统及汇编
例 5,从 BLOCK单元开始有一个无符号数数据块,
其长度存于 LEN单元,试求出数据块中最大的数并存入
MAX单元 。
解, 该问题解决方法与例 4 相同,所不同的是无符
号数个数增加,即搜索寻找最大值的范围扩大了 。 因此,
本例题采用直到型单重循环的程序结构方式比较合理 。
程序框图如图 3 ― 14 所示 。
第 3章 指令系统及汇编
图 3 ― 14 例 5 程序框图
第 3章 指令系统及汇编
程序清单,
LOOP,ORG 2000H
MOV R0,# BLOCK ; 数据块首址送 R0
MOV R1,LEN ; 数据块长度送 R1
MOV MAX,# 00H ; 存最大数单元清零
LOOP1,MOV A,MAX ; (A) ← (MAX)
CLR C ; 清 C
SUBB A,@R0 ; (MAX)- ((R0))
JNC NEXT ; 若 (MAX)>((R0)),则转移
MOV MAX,@R0 ; 若 (MAX)<((R0)),则 (MAX) ← ((R0))
NEXT,INC R0 ; 修改地址指针
DJNZ R1,LOOP1 ; 若 (R1)≠0则循环搜索
RET
第 3章 指令系统及汇编
图 3 ― 15 例 6 程序框图
第 3章 指令系统及汇编
例 6,设计 100 ms延时程序 。
解, 计算机执行一条指令需要一定的时间,由一些
指令组成一段程序,并反复循环执行,利用计算机执行
程序所用的时间来实现延时,这种程序称为延时程序 。
如当系统使用 12 MHz晶振时,一个机器周期为 1 μs,执
行一条双字节双周期 DJNZ指令的时间为 2 μs,因此,执
行该指令 50 000 次,就可以达到延时 100 ms的目的 。
对于 50 000 次循环可采用外循环, 内循环嵌套的多重
循环结构 。 本例题的程序流程如图 3― 15所示 。
第 3章 指令系统及汇编
程序清单,
START,ORG 1000H
MOV R6,# 0C8H ; 外循环 200 次
LOOP1,MOV R7,# 0F8H ; 内循环 248 次
NOP ; 时间补偿
LOOP2,DJNZR7,LOOP2 ; 延时 2 μs× 248=496 μs
DJNZ R6,LOOP; 延时 500 μs× 200=100 ms
RET
第 3章 指令系统及汇编
以上程序执行 MOV Rn,# data 指令的时间为 1 μs,
DJNZ指令 2 μs,NOP指令 1 μs,所以,内循环延迟时间,
1 μs+1 μs+2 μs× 248=498 μs,外循环延迟时间, 1 μs+(内
环延时 +2 μs)× 200=100.001 ms。
第 3章 指令系统及汇编
3.5.5 子程序结构程序设计
在一个程序中,将反复出现的程序段编制成一个个
独立的程序段,存放在内存中,这些完成某一特定任务
可被重复调用的独立程序段被称为子程序 。 在前面所
举的例子中,已有一些程序段是以带有 RET指令的子程
序形式出现的 。 在汇编语言编程时,恰当地使用子程序,
可使整个程序的结构清楚,阅读和理解方便,而且还可
以减少源程序和目标程序的长度,不必多次重复书写和
翻译同样的指令 。 在汇编语言源程序中使用子程序,需
要强调注意两个问题,即子程序中参数传递和现场保护
的问题 。
第 3章 指令系统及汇编
一般在汇编语言中采用的参数传递方法有以下 3 种 。
(1) 用累加器或工作寄存器来传递参数。
(2) 用指针寄存器传递参数。
(3) 用堆栈来传递参数。
第 3章 指令系统及汇编
例 7,将 HEX单元存放的两个十六进制数分别转换
成 ASCII码,并存入 ASC和 ASC+1 单元 。
解, 由于伪指令 DB在汇编后,使字节以 ASCII码形
式存放,所以采用查表子程序的方式来实现十六进制数
到 ASCII码的转换 。 转换子程序为 HASC,调用时传递
参数采用堆栈来完成 。
程序清单如下:
ORG 2000H
PUSH HEX ; 第一个十六进制数入栈
ACALL HASC ; 调查表转换子程序
第 3章 指令系统及汇编
POP ASC ; 低 4 位转换值保存
MOV A,HEX ; 十六进制数送 A
SWAP A ; 高 4 位低 4 位交换
PUSH A ; 第二个十六进制数入栈
ACALL HASC ; 调查表转换子程序
POP ASC+1 ; 高 4 位转换值保存
HERE,AJMP HERE ; 结束源程序
HASC,DEC SP ;
DEC SP ; 修改 SP到参数位置
POP A ; 弹出十六进制数到 A
ANL A,# 0FH ; 取 A低 4 位
第 3章 指令系统及汇编
ADD A,# 07H ; 为查表进行地址调整
MOV CA,@A+PC ; 查表转换
PUSH A ; 转换结果入栈
INC SP ;
INC SP ; 恢复返回地址
RET
ASCTAB,DB ′0,1,2,3,4,5,6,7′
DB ′8,9,A,B,C,D,E,F ′
END
第 3章 指令系统及汇编
由于堆栈操作是, 先入后出,,因此,先压入堆栈的
参数应后弹出,才能保证恢复原来的状态 。 例如,
SUBROU,PUSH A
PUSH PSW
PUSH DPL
PUSH DPH

POP DPH
POP DPL
POP PSW
POP A
RET
第 3章 指令系统及汇编
3.6 程序设计举例
3.6.1 代码转换程序设计
前面各章节的举例中已介绍了 BCD码与二进制数
间的相互转换 ( 见 3.5 节例 1,例 2,3.3.2 节例 4),以
及十六进制数用查表法转换为 ASCII码的程序设计方法
( 见 3.5 节例 7 ) 。
第 3章 指令系统及汇编
例 1, 十六进制数到 ASCII码的转换子程序设计 。
解, 该转换的算法为, 凡大于等于 10 的十六进制数
加 37 H,凡小于 10 的十六进制数加 30 H,便可得到相
应的 ASCII码 。
入口, R2( 高 4位为 0000,低 4 位为 0000~ 1111 的
一个十六进制数 0~ F) 。
出口, R2( 相应的 ASCII码 ) 。
程序清单如下,
HASC1,MOV A,R2 ; 十六进制数送 A
ADD A,# 0F6H ; (A)+(-10)补
第 3章 指令系统及汇编
MOV A,R2 ; 恢复十六进制数
JNC AD30H ; 若 (A)<10 则转 AD30H
ADD A,# 07H ; (A) ≥ 10 则先加 07H
AD30H,ADD A,# 30H ; (A)+30H
MOV R2,A ; ASCII码存 R2
RET
第 3章 指令系统及汇编
例 2,ASCII码到十六进制数的转换子程序设计 。
解, 该转换的算法为, 若为 0~ 9 的 ASCII码,则减去
30H; 若为 A~ F的 ASCII码,则减去 37H,便可得到相应
的十六进制数 0~ F。
入口, R2( 0~ 9 或 A~ F的 ASCII码 ) 。
出口, R2( 高 4 位为 0000,低 4 位为 0000~ 1111) 。
程序清单如下,
ASCH1,MOV A,R2 ; ASCII码值送 A
ADD A,# 0D0H ; (A)+(-30H)补
MOV R2,A ; R2暂存减结果
ADD A,# 0F6H ; A+(-10)补
第 3章 指令系统及汇编
JNC RET1 ; 若 (A)<10 转 RET1
MOV A,R2 ; 若 (A)≥10 则 (R2)送 A
ADD A,# 0F9H ; (A)+(-07H)补
MOV R2,A ; 十六进制数存 R2
RET1,RET
第 3章 指令系统及汇编
3.6.2 运算子程序设计
在 3.3.2 节例 1,例 2 中已经介绍了双字节无符号
数的加法, 减法程序,在 3.3.2 节例 3中介绍了双字节数
乘单字节数,以及在 3.3.2 节例 5, 例 6,例 7 中介绍
了 BCD码加法和利用 DA调整指令进行十进制减法程序
等 。 下面再分别介绍双字节乘法, 除法子程序 。
例 3,双字节无符号数乘法子程序设计 。
解, 算法, 两个双字节无符号数被分别放在 R7,R6
和 R5,R4中 。 由于 MCS—51指令中只有 8 位数的乘法
指令 MUL,用它来实现双字节数相乘时,可把被乘数分
解为,
第 3章 指令系统及汇编
(R7)(R6)=(R7)·28+(R6),(R5)(R4)=(R5)·28+(R4)
则这两个数的乘积可表示为,
(R7)(R6)(R5)(R4)=[ (R7)· 28 +(R6)] ·[ (R5)· 28 8+(R4)]
=(R7)·(R5)·216+(R7)·(R4)· 28+ (R6)·(R5)· 28 +(R6)·(R4)
=(R04)(R03)(R02)(R01)
第 3章 指令系统及汇编
显然,我们将 (R6)·(R4) 放入 (R02)(R01) 中,将
(R7)·(R4) 和 (R6)·(R5) 累加到 (R03) (R02) 中 ; 再将
(R7)·(R5)累加到 (R04)(R03)中即可得到乘积结果 。
入口, (R7 R6)=被乘数 ; (R5 R4)=乘数 ; (R0)=乘积的
低位字节地址指针 。
出口, (R0)=乘积的高位字节地址指针,指向 32 位
积的高 8 位 。
工作寄存器, R3,R2 存放部分积 ; R1存放进位位。
第 3章 指令系统及汇编
程序清单如下,
MUL1:MOV A,R6
MOV B,R4
MUL AB ; (R6)·(R4)
MOV @R0,A ; R01 存乘积低 8 位
MOV R3,B ; R3暂存 (R6)·(R4)的高 8 位
MOV A,R7
MOV B,R4
MUL AB ; (R7)·(R4)
ADD A,R3 ; (R7)·(R4)低 8 位加 (R3)
第 3章 指令系统及汇编
MOV R3,A ; R3暂存 2 8 部分项低 8 位
MOV A,B ; (R7)·(R4)高 8 位送 A
ADD CA,# 00H ; (R7)·(R4)高 8 位加进位 CY
MOV R2,A ; R2暂存 2 8 部分项高 8 位
MOV A,R6
MOV B,R5
MUL AB ; (R6)·(R5)
ADD A,R3 ; (R6)·(R5)低 8 位加 (R3)
INC R0 ; 调整 R0 地址为 R02 单元
MOV @R0,A ; R02 存放乘积 15~ 8 位结果
第 3章 指令系统及汇编
MOV R1,# 00H ; 清暂存单元
MOV A,R2
ADD CA,B ; (R6)·(R5)高 8 位加 (R2)与 CY
MOV R2,A ; R2暂存 28部分项高 8 位
JNC NEXT ; 28 项向 216 项无进位则转移
INC R1 ; 有进位则 R1 置 1 标记
NEXT,MOV A,R7
MOV B,R5
MUL AB ; (R7)·(R5)
ADD A,R2 ; (R7)·(R5)低 8 位加 (R2)
INC R0 ; 调整 R0 地址为 R03
第 3章 指令系统及汇编
MOV @R0,A ; R03 存放乘积 23~ 16 位结果
MOV A,B
ADD CA,R1 ; (R7)·(R5) 高 8 位加 2 8 项进位
INC R0 ; 调整 R0 地址为 R04
MOV @R0,A ; R04 存放乘积 31~ 24 位结果
RET
第 3章 指令系统及汇编
例 4,双字节带符号数乘法子程序设计 。
解, 算法, 由于带符号数乘法和无符号数乘法的基
本算法是一样的,因此可以根据入口条件调用例 3
MUL1子程序进行计算 。 不同之处有以下 3 点, (1) 需
根据被乘数和乘数的符号计算乘积的符号 ; (2) 当被乘
数和乘数为负数时,应对它们取补,形成 2 的补码,然后
才能调用 MUL1进行运算 ; (3) 当积为负数时,计算的结
果尚需取补后才是正确的积 ( 绝对值 ),积为 31 位 。
第 3章 指令系统及汇编
乘积符号的算法在本程序中分两步完成, 首先用
ANL指令判断两数是否均为负,若与操作的结果为 1,
则两数均为负,乘积应为正,对与的结果取反即为积的
符号,存入 SIG;若不属于此情况,则用 ORL指令算出积
的符号存入 SIG。 程序中 SIG,SIG1, SIG2均为内部
RAM中的可寻址位 。
入口, (R7 R6)=带符号位被乘数 ; (R5 R4)=带符号位
乘数 ; (R0)=乘积的低位字节地址指针 。
第 3章 指令系统及汇编
出口, (R0)=乘积的高位地址指针 。
程序清单如下,
MUL2,MOV A,R7 ; 被乘数高 8 位送 A
RLC A ; (R7)的符号位送 CY
MOV SIG1,C ; SIG1 存被乘数符号
MOV A,R5 ; 乘数高 8 位送 A
RLC A ; (R5)的符号位送 CY
MOV SIG2,C ; SIG2 存放乘数符号
ANL C,SIG1 ; 计算积的符号
第 3章 指令系统及汇编
JC POSI ; 若两数均负积为正则转 POSI
MOV C,SIG1 ; 计算两数非全负时积的符号
ORL C,SIG2
SJMP SIGN
POSI,CPL C
SIGN,MOV SIG,C ; 存积的符号
MOV A,R7
JB A.7,CPL1 ; 被乘数为负转求补
STEP1,MOV A,R5
JB A.7,CPL2 ; 乘数为负转求补
第 3章 指令系统及汇编
STEP2,ACALL MUL1 ; 调 (R7 R6)·(R5 R4)子程序
JB SIG,CPL3 ; 积符号为负转求补
RET
CPL1,MOV A,R6 ; 被乘数求补
CPL A
ADD A,# 01H
MOV R6,A
MOV A,R7
CPLA
ADDC A,# 00H
MOV R7,A
SJMP STEP1
第 3章 指令系统及汇编
CPL2,MOV A,R4 ; 乘数求补
CPL A
ADD A,# 01H
MOV R4,A
MOV A,R5
CPLA
ADD CA,# 00H
MOV R5,A
SJMP STEP2
CPL3,DEC R0 ; 乘积结果求补
DEC R0
DEC R0 ; 使 R0指向乘积低字节地址
第 3章 指令系统及汇编
MOV R2,# 03H ; 待取补数字节数 -1 送 R2
ACALL CPL4 ; 调用多字节数求补子程序
RET
CPL4,MOVA,@R0 ; 多字节数求补
CPL A
ADD A,# 01H
MOV @R0,A
STEP3,INC R0
MOV A,@R0
CPL A
ADD CA,# 00H
第 3章 指令系统及汇编
MOV @R0,A
DJNZ R2,STEP3 ; 字节未转换完转移
RET
CPL4为多字节数求补子程序,入口为 (R0)=待取补
数低字节地址指针 ; (R2)=待取补数字节数 -1。 出口为
(R0)=求补后的高位字节地址指针 。
第 3章 指令系统及汇编
例 5,双字节无符号数除法子程序设计 。
解, MCS—51 除法指令只能进行 8位无符号数相除
运算,而对于多字节除法,还需用一般的除法算法进行 。
常用的除法算法采用, 移位相减法,,即, 先设余数为 0,
并将被除数和余数分别左移一位,使被除数的最高位移
入余数的最低位,再求 ( 余数 —除数 ) 之差,若差为正,
则令差代替余数,商为 1; 若差为负,则不作任何操作 。
然后重复以上移位相减的过程,使每位被除数都参与了
运算为止 。
第 3章 指令系统及汇编
图 3 ― 16例 5 程序框图
(a) 除法程序框图 ; (b) 四舍五入处理框图
第 3章 指令系统及汇编
入口, (R7 R6)=被除数,(R5 R4)=除数 。
出口, (R7 R6)=商数,(OVER)=溢出标志 ( FFH为
溢出 ) 。
工作寄存器,(R3 R2)=部分余数,(R1)=计数器,
(R0)=差值暂存。
程序清单如下,
DIV,MOV A,R5 ; 除数高 8 位送 A
JNZ BEGIN ; 除数非零则转 BEGIN
MOV A,R4 ; 除数低 8 位送 A
第 3章 指令系统及汇编
JZ OVER ; 除数为零置溢出标志
BEGIN,MOV A,R7 ; 被除数高 8 位送 A
JNZ BEGIN1 ; 被除数非零则转 BEGIN1
MOV A,R6 ; 被除数低 8 位送 A
JNZ BEGIN1 ; 被除数非零则转 BEGIN1
RE T ; 被除数为零则返回
BEGIN1,CLR A ; 清余数单元
MOV R2,A
MOV R3,A
第 3章 指令系统及汇编
MOV R1,# 10H ; 双字节除法计数器置 16
DIV1,CLR C ; 开始 R3 R2 R7 R6 左移
MOV A,R6 ; 被除数低 8 位送 A
RLC A ; R6循环左移一位
MOV R6,A ; 左移结果回送
MOV A,R7 ; 被除数高 8 位送 A
RLC A ; R7 循环左移一位
MOV R7,A ; 左移结果回送
MOV A,R2 ; 余数左移一位
RLC A
MOV R2,A
MOV A,R3
第 3章 指令系统及汇编
RLC A
MOV R3,A
DIV2,MOV A,R2 ; 开始部分余数减除数
SUBB A,R4 ; 低 8 位先减
MOV R0,A ; 暂存差值
MOV A,R3
SUBB A,R5 ; 高 8 位相减
JCN EXT ; 若部分余数 <除数则转 NEXT
INC R6 ; 若部分余数 ≥除数则商为 1
MOV R3,A ; 新余数存 R3 R2
MOV A,R0
MOV R2,A
第 3章 指令系统及汇编
NEXT,DJN ZR1,DIV1 ; 16 位未除完则返回
MOV A,R3 ; 开始四舍五入处理
JB A.7,ADD1 ; 若余数最高位为 1 则进 1
CLR C ; 开始余数乘 2 处理
MOV A,R2
RLC A ; 余数低 8 位乘 2
MOV R2,A
MOV A,R3
RLC A ; 余数高 8 位乘 2
SU BBA,R5 ; 余数 × 2-除数
JC NOOVER ; 若余数 × 2<除数则转
JN ZADD1 ; 若够减则转进 1
第 3章 指令系统及汇编
MOV A,R2 ; 高 8 位相等时比较低 8 位
SUBB A,R4
JC NOOVER ; 余数 × 2<除数则转
ADD1,MOV A,R6 ; 开始商进 1处理
ADD A,# 01H
MOV R6,A
MOV A,R7
ADDC A,# 00H
MOV R7,A
NOOVER,MOV OVER,# 00H ; 清溢出标志
RET
OVER,MOV OVER,# 0FFH ; 置溢出标志
RET
第 3章 指令系统及汇编
双字节带符号数除法的算法与无符号数除法的算
法基本相同,所不同的是在计算除法之前先进行商的符
号确定 。 商的符号确定方法与例 4带符号数乘法中乘积
符号的确定方法相同 。 所以双字节带符号除法程序首
先要进行商的符号确定,再调用无符号数除法子程序
DIV即可,这里不再重复 。
第 3章 指令系统及汇编
3.6.3 查表程序设计
查表,就是根据变量 x,在表格中查找 y,使 y = f (x)。
单片机应用系统中,查表程序 是一种常用程序,它被广
泛应用于 LED显示器控制,打印机打印以及数据补偿,
计算, 转换等功能程序中 ( 如 3.3.1 节例 1,2,4;
3.5.4 节例 7 ) 。
第 3章 指令系统及汇编
例 6,设有一巡检报警装置,需要对 16 路值进行
比较,当每一路输入值超过该路的报警值时,实现报警 。
要求编制一个查表子程序,依据路数 xi,查表得 yi的报
警值 。
解, xi为路数,查表时按照 0,1,2,…,15 取值,故为
单字节规则量 。 表格依 xi顺序列表,仅存二字节报警
值 yi,其表格构造见表 3― 4。
第 3章 指令系统及汇编
表 3 ― 4 路数 xi与报警值 yi对应关系
第 3章 指令系统及汇编
程序入口, (R2)=路数 xi。
程序出口, (R4 R3)=对应 xi的报警值 yi。
查表子程序如下,
STA1,MOV A,R2 ; 路数 xi送 A
RL A ; x-i× 2
MOV R4,A ; 暂存
ADD A,# TABL(rel) ; 加上表首偏移量
MOV CA,@A+PC ; 查 y-i第一字节
XCH A,R4 ; 第一字节送 R4
ADD A,# TABL(rel)+1 ; 形成第二字节表址
第 3章 指令系统及汇编
MOV CA,@A+PC ; 取 yi第二字节
MOV R3,A ; 第二字节送 R3
RET
TAB2,DW 050FH,0E89H,A695H,1EAAH; 报警值表
DW 0D9BH,7F93H,0373H,26D7H
DW 2710H,9E3FH,1A66H,22E3H
DW 1174H,16EFH,33E4H,6CA0H
第 3章 指令系统及汇编
上述查表程序中使用 RL A使 (A)乘 2,这是由于 DW
定义的是双字节空间,为了保证指向正确的查表地址,
所以要进行乘 2 处理 。 另外,程序中使用 MOVCA,
@A+PC指令,使表格偏移不得超过 255个字节 。 当表格
偏移大于 255个字节时,应使用 MOVCA,@A+DPTR 查
表指令 。
第 3章 指令系统及汇编
表 3 ― 5 x 与表地址对应关系
第 3章 指令系统及汇编
编制一个查表程序,将查得的函数值 yi存入 R4、
R3 中 。
解, 入口, (R3R2)=由其它程序得到的 xi规则量,即,
xi = 0000H,0001H,0002H,…。
出口, (R5 R4)=依据 xi查得的函数值 yi。
查表程序如下:
STA,MOV DPTR,# TABL ; 置表首地址
MOV A,R2 ; 求 yi在表中序号
CLRC
RLCA
MOV R2,A
MOV A,R3
第 3章 指令系统及汇编
RLC A
MOV R3,A
MOV A,R2 ; 求 yi在表中地址
ADD A,DPL
MOV DPL,A
MOV A,R3
ADD CA,DPH
MOV DPH,A
CLR A
MOV CA,@A+DPTR ; 查表得 yi高位
MOV R5,A
INC DPTR ; 表格地址加 1
第 3章 指令系统及汇编
CLR A
MOV CA,@A+DPTR ; 查表得 yi低位
MOV R4,A
RET
TAB1,DW… ; 函数值 yi表
第 3章 指令系统及汇编
例 8,输入一个 ASCII命令符,要求按照输入的命令
字符转去执行相应的处理程序 。 设命令为单字节字符
′A′,′D′,′E′,′L′,′M′,′X′,′Z′七种,相应的处理
程序入口标号分别为双字节 XA,XD,XE,XL、
XM,XX,XZ。
解, 对于上述情况,由于 xi与 yi 均为非规则量,因此
在表格中必须存放相应的 xi,yi值,xi为输入命令符,yi
为相应处理程序入口地址,其表格构造见表 3 ― 6。
第 3章 指令系统及汇编
表 3 ― 6 存储内容与表地址关系
第 3章 指令系统及汇编
这类表格 xi,yi可以是单字节, 双字节或多字节,
它以两种方式给出表格的容量 。 一种是用表格结束标
志 0 来表示,另一种则是给出表格中的项数 。 本程序采
用结束标志 0 表示 。 该查表子程序的算法为, 当输入
一个 ASCII命令符时,该子程序顺序查找,若为所定义的
7 种命令符,则转相应的处理程序 ; 若查不到则返回 。
第 3章 指令系统及汇编
入口, (A)=由其它程序将命令字符送入 A中 。
出口, 查到命令字符则转处理程序,反之,若为结束
标志则返回 。
程序清单如下,
STA3,MOV DPTR,# TABL ; 置表首地址
MOV B,A ; 输入命令符暂存
LOOP,CLR A
MOV CA,@A+DPTR ; 取存储命令符 xi
JZ LEND ; 查到结束标志返回
INC DPTR ; 表格地址指向 yi高位
第 3章 指令系统及汇编
CJNE A,B,LNF ; 输入与存储命令符不等转移
CLR A
MOV CA,@A+DPTR ; 命令符相等时取转移地址
MOV B,A ; yi高位暂存于 B
INC DPTR ;
MOV CA,@A+DPTR ; yi低位送 A
MOV DPL,A ; 转移地址送 DPTR
MOV DPH,B
CLR A
JMP @A+DPTR ; 转相应处理程序入口
第 3章 指令系统及汇编
LNF,INC DPTR ; 准备查下一项
INC DPTR
SJMP LOOP ; 转 LOOP查下一项
LEND,RET ; 没查到返回
TABL,DB′A′ ; ASCII码 A
DW′XA′ ; 相应处理入口地址
第 3章 指令系统及汇编
DB ′D′
DW ′XD′
DB ′E′
DW ′XE′
DB ′L′
DW ′XL′
DB ′M′
DW ′XM′
DB ′X′
DW ′XX′
DB ′Z′
DW ′XZ′
DB0 ; 表格结束标志
第 3章 指令系统及汇编
3.6.4 散转 ( 多分支 ) 程序设计
散转程序是一种并行分支程序 。 它是根据某种输
入或运算结果,分别转向各个处理程序 。 在 MCS—51 单
片机中,散转指令为 JMP@A+DPTR,它按照程序运行时
决定的地址执行间接转移指令 。
1,使用地址偏移量表的散转程序
如果所有的 N个分支处理程序的总长度小于 256 个
字节时,可以使用地址偏移量来实现 N分支散转 。 它的
优点是程序简单,转移表短 。
第 3章 指令系统及汇编
例 9,按 R2 的内容转向 4 个分支处理程序 。 4 个分
支处理程序总长度小于 256个字节 。
解, 入口, (R2)=入口条件 ( 0,1,2,3) 。
出口, 各分支处理程序入口 。
程序清单如下:
N-JMP,MOV A,R2
MOV DPTR,# TABL ; 分支表首地址送 DPTR
MOV CA,@A+DPTR ; 查表取转移目标地址偏移量
JMP @A+DPTR ; 转移到相应处理程序
TABL,DBP RG0(rel) ; 存放转移目标地址偏移量
第 3章 指令系统及汇编
DB PRG1(rel)
DB PRG2(rel)
DB PRG3(rel)
PR G0,…… ; 分支处理程序 0
… …
PR G3,…… ; 分支处理程序 3
… …
第 3章 指令系统及汇编
2,使用转移指令表的散转程序
使用地址偏移量表的散转程序分支 N不能太多,而
且由于 DB伪指令只能定义 8 位字节,分支入口地址的
分布也要受到较大的限制 。 若在 TABL表中存放的不
是入口地址偏移量,而存放的是一系列转移指令 AJMP,
则可实现 128 分支程序,各分支入口地址可在 2 KB范围
内分布 。
第 3章 指令系统及汇编
例 10,设计可多达 128 路分支出口的转移程序 。
解, 入口, (R2)=转移目标地址的序号 00H~ 7FH。
出口, 转移到相应分支程序入口 。
程序清单如下:
JMP-128,MOV DPTR,# TABL ; 转移指令表首址送
DPTR
MOV A,R2
RL A ; (A) ← (R2)× 2
JMP @A+DPTR
TABL,AJMP PRG00
AJMP PRG01;
AJMP PRG7F
128 个分支程序首址
第 3章 指令系统及汇编
PRG00:……
… … …
PRG7F,……
以上程序中由于 AJMP是双字节指令,因此采用 RL
指令使 (R2)乘以 2,可保证移向正确的位置 。 值得注意
的是, 每个分支的入口地址 ( PRG00~ PRG7F) 必须与
其相应的 AJMP指令在同一个 2 K存储区内 。 也就是说,
分支入口地址的安排仍有一定的限制 。 如改用长转移
LJMP指令,则分支入口可在 64 KB范围内任意安排,但
程序要作相应的修改 ( 请参阅其它参考书 ) 。
第 3章 指令系统及汇编
3,使用位检测指令的散转程序
例 11,根据 P1口上的位状态 (, 1”有效 ) 散转到不
同的处理程序 。
解, 若 P1 口 D0~ D7 位为 1,则转相应处理子程序 。
如 P1 中第 0 位为 1,则转 PRG0。
程序清单如下:
BIT-JMP,JB 90H,LP0 ; P1 口 D0 为 1,则转 LP0 子程序
JB 91H,LP1
JB 92H,LP2
JB 93H,LP3
JB 94H,LP4
第 3章 指令系统及汇编
JB 95H,LP5
JB 96H,LP6
JB 97H,LP7
RET
LP0,ACALL PRG0 ; 调相应子程序
RET
LP1,ACALLPRG1
RET
… … …
LP7,ACALL PRG7
RET