第三章 汇编语言程序设计第一节 汇编语言程序的格式第二节 伪指令第三节 汇编语言程序的编写步骤及基本结构第四节 程序设计举例本章要点
本章介绍 汇编语言程序的书写格式、
编写步骤以及程序的基本结构。通过一些具体范例,了解与掌握编程方法并从中掌握程序设计的基本技巧。
第一节 汇编语言程序的格式汇编语言编写的程序由语句组成,每一语句占一行填写一条指令。每行分 4段,分别为标号、操作码、操作数和注释。
ORG 2000H
ADDR,MOV A,00H ;累加器清零
MOV 41H,A ;41H,42H清零
MOV 42H,A
MOV R2,0AH ;设定累加次数
MOV R1,30H ;设定数据首地址
LOOP,MOV A,@R1 ;取数
ADD A,41H ;累加到 41H
JNC NEXT ;是否有进位
INC 42H ;有进位 42H加 1
NEXT,MOV 41H,A ;将和存入 41H
INC R1
DJNZ R2,LOOP
LJMP $
END
标号:代表该行指令所在的地址,结尾应加一冒号操作码:助记符或伪指令的符号。 操作数:操作所需要的数据或数据的存储位置来源注释:对语句的说明,也可不加注释返回本章首页第二节 伪指令伪指令不执行任何操作,汇编时也不生成目标程序。它仅仅提供对汇编的要求。汇编成机器语言后,伪指令就不存在了。以下为常用的伪指令:
1.ORG(Origin):,指明汇编起始点地址。
2.END,指明源程序至此结束 。
3.EQU(Epual),赋值伪指令,可对地址标号进行赋值 。
4.DB(Define Byte),定义从指定标号地址开始所存放的字节数据,多字节时各字节间用逗号隔开 。
5.DW(Define Word),定义从指定的标号地址开始,所存放的字数据 。 跟 DB一样,输入几个字时各字间要用逗号隔开 。
6.DS(Define Storage),定义存储区,表示从标号所指的存储单元开始,保留的内存单元数量,以供程序使用 。
返回本章首页第三节 汇编语言程序的编写步骤及基本结构一、顺序结构:
顺序结构是指程序按指令顺序逐条执行的一种结构。
也是程序结构中最简单的一种结构。
二、分支结构:
指程序中具有转移指令,可根据转移条件决定是转移还是继续执行下一条指令。
几种分支结构程序的框图三,循环结构循环结构由四个环节组成 。
1.初始化部分,对循环体中参加操作的有关参数,地址等赋以初始值,并指定循环结束条件 。
2.循环体部分,指每次循环都需要重复执行的程序段 。
3.修改初始值,每次循环结束都要对初始值进行修改,特别是判断结束条件的参数,每经一次循环后都要作相应的修改,以便决定是否结束循环 。
4.结束判断部分,检查结束条件是否满足,
若条件满足停止循环,否则返回继续执行循环体 。
循环结构框图图中 每执行一次循环体后,都要检查结束条件是否满足,若条件满足停止循环,否则返回继续执行循环体。
右边两图区别是先检查循环是否结束后修改初值,还是先修改初值后检查循环是否结束。
顺序结构的程序举例例 3-1 将地址为 2000H,2001H,2002H的片外数据存储单元的内容,
分别传送到 2002H,2003H,2004H存储单元中去。
ORG 0000H
LJMP 1000H
ORG 1000H
MOV DPTR,#2002H
MOVX A,@DPTR
MOV DPTR,#2004H
MOVX @DPTR,A
MOV DPTR,#2001H
MOVX A,@DPTR
MOV DPTR,#2003H
MOVX @DPTR,A
MOV DPTR,#2000H
MOVX A,@DPTR
MOV DPTR,#2002H
MOVX @DPTR,A
SJMP $
分支结构的程序举例例 3-2 有甲乙两数存于 41H和 42H存储单元,运算符号的
ASCII码存于 40H单元,编写一根据 40H的符号,对甲乙两数进行相应运算的程序;井将运算结果存于 43H单元。
ORG 0000H
LJMP 0100H
ORG 0100
MOV A,40H
CJNE A,#2BH,MINUS
PLUS,MOV A,41H
ADD A,42H
MOV 43H,A
SJMP CLOSE
MINUS:CJNE A,#2DH,ERR
CLR C
MOV A,41H
SUBB A,42H
MOV 43H,A
SJMP CLOSE
ERR,MOV 43H,#0FFH
CLOSE:SJMP $
循环结构的程序举例例 3-3 有一组数据,存放在 30H为首地址的内存单元,数据长度为 32
个 。 试将每一个数分别取出加 1,再存人以 40H为首地址的内存单元 。
ORG 0000H
0000 020100 LJMP 0100H
0100 ORG 0100H
0100 784F MOV R0,#4FH
0102 795F MOV R1,#5FH
0104 7F20 MOV R7,#20H
0106 E6 LOOP,MOV A,@R0
0107 04 INC A
0108 F7 MOV @R1,A
0109 18 DEC R0
010A 19 DEC R1
010B DFF9 DJNZ R7,LOOP
010D 80FE SJMP $
END
循环结构程序举例例 3-4 编制一延时子程序,使执行这一段程序延时 2s。
0100 7D64 MOV R5,#64H
0102 7E64 LOOP1,MOV R6,#64H
0104,7F62 LOOP2,MOV R7,#62H
0106 DFFE LOOP3,DJNZ R7,LOOP3
0108 DEFA DJNZ R6,LOOP2
010A DDF6 DJNZ R5,LOOPl
010C 22 RET
以上程序执行的时间近似为 2秒,如要准确计算还需考虑执行对 R5,R6,R7的赋值指令所需的时间,RET返回指令的时间等等。
返回本章首页第四节 程序设计举例一、多字节加法程序例 3-5 两个 10字节数,分别从存储单元 0801H,和
0901H开始存放,先存低字节后存高字节,求其和并存于乙数原来所在的单元。
多字节加法的程序
0100 ORG 0100H
0100 900801 MOV DPTR,#0801H ;甲数据地址
0103 75A009 MOV P2,#09H ;乙数据地址高字节
0106 7901 MOV R1,#01H ;乙数据地址低字节
0108 7F0A MOV R7,#0AH ;数据字节数
010A C3 CLR C
010B E0 LOOP,MOVX A,@DPTR ;取甲数
010C FC MOV R4,A ;暂存 R4
010D E3 MOVX A,@R1 ;取乙数
010E 3C ADDC A,R4 ;两数相加并加上一次进位位
010F F3 MOVX @R1,A ;和存于原乙数的地址
0110 09 INC R1 ;修改地址指针
0111 A3 INC DPTR
0112 DFF7 DJNZ R7,LOOP ;继续相加
0114 E4 CLR A
0115 3400 ADDC A,#00H
0117 F3 MOVX @R1,A ;存最高字节进位位
0118 80FE SJMP $ ;结束二,数制变换例 3-6 将 30H中的十六进制数转换为 BCD码,并存于
40H,41H。
主程序:入口条件为待转换的十六进制数存 R1
0100 ORG 0100H
0100 A930 MOV R1,30H
0102 122000 LCALL SUB
0105 8A40 MOV 40H,R2
0107 8B41 MOV 41H,R3
0109 80FE SJMP $
END
子程序:出口条件为转换所得 BCD码存 R2,R3
2000 ORG 2000H
2000 E9 SUB ;MOV A,R1 ;取十六进制数
2001 75F064 MOV B,#64H
2004 84 DIV AB ;除以 100
2005 FA MOV R2,A ;商为百位数存 R2
2006 740A MOV A,#0AH
2008 C5F0 XCH A,B ;除 100余数作为下一次的被除数
200A 84 DIV AB ;余数再除以 10
200B C4 SWAP A
200C 45F0 ORL A,B ;十位个位合并
200E FB MOV R3,A ;十位个位合并存 R3
200F 22 RET
三,求最大值或最小值
1.无符号数求最大值与最小值例 3-7 在以 2042H为首地址的存储单元中,连续存放一组单字节无符号数,
数据个数存于 2041H单元,
从中找出最大数并存于
2040H。
无符号数求最大值或最小值的程序
0100 ORG 0100H
0100 902041 MOV DPTR,#2041H
0103 E0 MOVX A,@DPTR
0104 FF MOV R7,A
0105 753000 MOV 30H,#00H
0107 A3 LOOP:INC DPTR
0108 E0 MOVX A,@DPIR
0109 B53002 CJNE A,30H,HERE
010C 8004 SJMP TOSMA
010E 4002 HERE:JC TOSMA
0110 F530 MOV 30H,A ;大于 30H取代原有值
0112 DFF3 TOSMA:DJNZ R7,LOOP ;小于 30H,继续比较
0114 902040 MOV DPTR,#2040H
0117 E530 MOV A,30H
0119 F0 MOVX @DPTR,A
011A 80FE SJMP $
END
2.带符号数求最大值或最小值例 3-8 — 组单字节带符号数据存放在以 2042H为首地址的连续单元中,
数据长度存放在
2041H单元,找出的最大值存于
2040H单元。
带符号数求最大值与最小值的程序
0100 ORG 0100H
0100 90204l MOV DPTR,#2041H
0103 EO MOVX A,@DPTR
0104 FF MOV R7,A
0105 7900 MOV R1,#80H ;开始 R1存最小值
-128
0107 A3 LOOP,INC DPTR
0108 E0 MOVX A,@DPIR
0109 FA MOV R2,A
010A C3 CLR C
010B 99 SUBB A,R1
010C 20E705 JB ACC.7,MINUS
010F 20D209 PLUS:JB OV,SMA
0112 8005 SJMP BIG
带符号数求最大值与最小值的程序 (续 )
0114 20D202 MINUS:JB OV,BIG
0117 8002 SJMP SMA
0119 EA BIG:MOV A,R2
011A F9 MOV R1,A
011B DFEA SMA:DJNZ R7,LOOP
011D 902040 MOV DPTR,#2040H
0120 E9 MOV A,R1
0121 F0 MOVX @DPTR,A
0122 80FE SJMP $
END
比较条件 两数相减后标志状态
X为正数,Y为正数 X>Y X-Y为正 OV=0
X<Y X-Y为负 OV=0
X为负数,Y为负数 X>Y X-Y为正 OV=0
X<Y X-Y为负 OV=0
X为正数,Y为负数 X>Y X-Y为正 OV=0
X>Y X-Y为负 OV=1
X<Y X为正数且 Y为负数,X不可能小于 Y
X为负数,Y为正数 X>Y X为负数且 Y为正数,X不可能大于 Y
X<Y X-Y为正 OV=1
X<Y X-Y为负 OV=0
带符号数的比较四,搜索例 3-9 有一批数据存放在以 2043H为首地址的连续单元中,数据长度置于 2042H存储单元,
编制检索程序,使之能从该批数据中寻找是否有等于字母 T的 ASCII码的数据 。 字母 T的 ASCII
码存放在 2041H单元 。
ORG 0100H
O100 902041 MOV DPTR,#2041H
0103 E0 MOVX A,@DPTR ;取关键字
0104 F5F0 MOV B,A
0106 A3 INC DPTR
0167 E0 MOVX A,@DPTR
0108 FF MOV R7,A
0109 A3 LOOP,INC DPTR
010A E0 MOVX A,@DPTR
010B 35F005 CJNE A,B,LOOPl
010E 753000 MOV 30H,#00H ;找到字母 T
0111 80FE SJMP $
0113 DFF4 LOOP1,DJNZ R7,LOOP
0115 7530FF MOV 30H,#0FFH ;找不到字母 T
0118 80FE SJMP $
END
检索程序举例五,排序例 3-10 一组无符号的二进制数,
存于以 30H为首地址的连续单元中,
数据长度存于 21H
单元,试设计一程序,使该组数据按从大到小的顺序排列。
ORG 0100H
0100 E521 MOV A,21H
0102 l4 DEC A
0103 FF MOV R7,A ;定外循环次数
0104 FE MOV R6,A ;定内循环次数
0105 8F22 MOV 23H,R6
0107 752230 MOV 22H,#30H ;首地址存 22H
010A A822 NEXT,MOV R0,22H
010C E6 MOV A,@R0
010D F9 MOV R1,A ;设首地址内容存 R1
010E 08 LOOP,INC R0
010F C3 CLR C
0110 96 SUBB A,@R0
0111 5003 JNC TOSMA
0113 E6 MOV A,@R0
0114 C9 XCH A,R1
0115 F6 MOV @R0,A ;若大于 R1,双方易位排序程序举例
0116 E9 TOSMA,MOV A,R1
0117 DEF5 DJNZ R6,LOOP
0119 A822 MOV R0,22H
01lB E9 MOV A,R1
0llC F6 MOV @R0,A ;存本轮最大值
011D 0522 INC 22H ;首地址加 1
011F 1523 DEC 23H ;比较次数减 1
0121 AE23 MOV R6,23H
0123 DFE5 DJNZ R7,NEXT
0125 80FE SJMP $
续上
0300 ORG 0300H
EXB EQU 00H
0300 AE21 MOV R6,21H ;取数据长度
0302 1E LOOP0:DEC R6
0303 EE MOV A,R6
0304 FF MOV R7,A ;定循环次数
0305 C200 CLR EXB
0307 7830 MOV R0,#30H
0309 E6 LOOP1:MOV A,@R0 ;取数
030A F5F0 MOV B,A
03OC 08 INC R0
030D C3 CLR C
030E 96 SUBB A,@R0 ;比较排序程序举例 (下沉法 )
030F 4008 JC LOOP2 ;不交换
0311 D200 SETB EXB ;交换
0313 E5F0 MOV A,B
0315 C6 XCH A,@R0
0316 18 DEC R0
0317 F6 MOV @R0,A
0318 08 INC R0
0319 DFEE LOOP2,DJNZ R7,LOOP1 ;结束判断
031B 2000E4 JB EXB,LOOP0 ;是否无交换了
031E 80FE FINISH,SJMP $
下沉法 续六、查表当某一变量 x与函数 y的关系无规律可循时,可以将变量 x作为序号,函数 y值作为元素,列出一份序号与元素的关系表。然后利用查表法从序号求得元素 。
1.序号小于 256的查表程序例 3-11 设在寄存器 R1存了两个 BCD码,
将它们转换为共阴数码管的七段码,存入 21H和 22H。
序号小于 256查表程序
TRAN,MOV DPTR,#TABLE ;取表头地址
MOV A,R1
ANL A,#0FH ;取 BCD码低 4位
MOVC A,@A+DPTR ;换成七段码
MOV 21H,A
MOV A,R1
SWAP A ;转换高 4位位置
ANL A,#0FH ;取 BCD码高 4位
MOVC A,@A+DPTR ;换成七段码
MOV 22H,A
RET
TABLE,DB 06H,5BH,4FH,66H,6DH,7DH,7H,7FH,6FH
2.序号大于 256的查表程序当元素总数大于 256,要用 DPTR直接加 16位序号,
才能得到元素地址值 。
例 3-13 设有 1000个元素的函数表,元素序号高 8位存于
20H,低 8位存于 21H,要求将求出的元素值存于 30H。
TRAN,MOV DPTR,#TABLE ;取表头地址
MOV A,21H ;求元素位置低 8位
ADD A,DPL
MOV DPL,A
MOV A,20H ;求元素位置高 8位
ADDC A,DPH
MOV DPH,A
CLR A
MOVC A,@A+DPTR ;取出元素
MOV 30H,A
RET
TABLE,DB……………………,
3.元素值占两个字节以上的查表程序当元素占两个以上字节,应考虑每个序号的偏移量 。
例 3-14 设序号存 20H,且小于 128,元素占 2个字节,表头为
2001H,即元素 0地址为 2001H,2002H,元素 1地址为 2003H、
2004H,… 余类推 。 试根据序号求出元素值,并存于 30H,31H。
TRAN,MOV DPTR,#TABLE
MOV A,20H
RL A ;序号乘 2得序号与表头距离
MOV R2,A ;暂存于 R2
MOVC A,@A+DPTR
MOV 30H,A
MOV A,R2
INC A
MOVC A,@A+DPTR
MOV 31H,A
RET
TABLE,DB ……………………
4.变量 x的数值不是等差序列 的查表程序解决这类问题可以采用搜索的办法,即制作一张序号与元素即 x-y依序排列表,表中在每个序号 x的后面紧接着元素 y。 表的结构如下:
TAB,x1
y1
x2
y2
.
.
xn
yn
给出序号 x的数值后,用搜索法查出它所在的地址,
将查出的地址加 1,就是元素所在的地址,然后从中取出 y值 。
七,散转程序散转程序实际是一种并行分支程序,可根据某个输入值或运算结果,转到不同的分支处理。
例 3-15 设程序中有四个功能子程序入口,分别为 1000H、
1200H,1400H,1600H。 要求根据运行后 21H的数值 0,1、
2,3转相应 子程序。
ANYCHEN,MOV DPTR,#TABLE ;取 入口地址表头
MOV A,21H ;取 输入值
RL A
ADD A,21H ;输入值乘 3
JMPA,@A+DPTR
TABLE:LJMP 1000H
LJMP 1200H
LJMP 1400H
LJMP 1600H
返回本章首页