第四章 汇编语言程序设计
DESCRIPTION
简单程序. 查表程序. 子程序. 分支程序. 循环程序. 第四章 汇编语言程序设计. 程序设计实例引入. 实例 假设一个班有50个人, 共有3门选修课: 计算机算法 服装 CAD 设计 德语 请找出: 同时选了三门课的同学;. 计算机算法. 服装 CAD 设计. 德语. 5. 2. 4. 12. 25. 12. 23. 39. 25. 25. 29. 29. 39. 39. 问题的解决. 第一步 如何在计算机中表示选修某门课的所有同学 ?. 选修这门人数. 学生的学号. 这个过程实际上是设计数据结构的问题. - PowerPoint PPT PresentationTRANSCRIPT
第四章 汇编语言程序设计
循环程序
简单程序
查表程序子程序
分支程序
程序设计实例引入 实例假设一个班有 50 个人,共有 3 门选修课: 计算机算法 服装 CAD 设计 德语请找出: 同时选了三门课的同学;
问题的解决 第一步 如何在计算机中表示选修某门课的所有同
学 ?
5122325
22539
2939
412252939
计算机算法 服装 CAD 设计 德语选修这门人数
学生的学号
这个过程实际上是设计数据结构的问题这个过程实际上是设计数据结构的问题
问题的解决 第二步 设计思路:找出同时选了三门课的同学
这个过程实际上是设计算法的过程,既构建模型。这个过程实际上是设计算法的过程,既构建模型。
计算机算法 CAD 设计
德语
重复该过程
第三步:设计流程
找出第一个学生
他选了德语吗?
他选了 CAD 吗?
记录要找的人
还有学生吗?
下一个学生
N
NY
N
Y
Y
结束
他选计算机吗?
N
Y
几点启示整体构思;构建整体流程框图;结构合理,流程清晰,简单明了;局部模块化;
为什么要用流程图?为什么要用流程图? 符合人进行逻辑思考的习惯 计算机从根本上来说,没有任何逻辑性,所以,你必须告诉它,先做什么,后做什么,遇到什么情况又该做什么,等等
流程图设计本身是一个逐步求精的过程,最终将任务划分为若干能由机器指令实现的小模块
4.1 程序设计过程 题意分析 画出流程图 分配内存及端口 编制源程序 仿真、调试程序 固化程序
2 、编程技巧
1. 程序功能模块化
2. 尽量采用循环结构和子程序
3. 少用无条件转移指令
4. 多采用累加器来传递参数
5. 注意现场保护,即压入堆栈
4.2 顺序程序设计例:求多项式 a2-b解:设 a 存放在 R2中, b 存放在 R3中,结果存放在 R6和 R7
中。bay 2程序如下:
MOV A , R2 MOV B , A MUL AB CLR C SUBB A , R3 ;带进位减 MOV R7 , A :保存低 8 位 MOV A , B SUBB A , #00H ;高八位减进位 MOV R6 , A END
4.3 分支程序设计 根据不同的条件转向不同的处理程序 控制转移指令 AJMP 、 LJMP 、 SJMP 、 JMP
JZ 、 JNZ 、 CJNE 、 DJNZ 位转移指令 JC 、 JNC 、 JB 、 JNB 、 JBC
举例;累加器 A 内有一个 16进制 ASCII字符,要求转换成一个 16进制数存放于 A 。ASCII字符转换成 16进制数规则 :数字 0~9 :只需减 30H字母 A~F :减 30H,再减 7
START
0C
(A)-30H A
(A) < 10 ?
(A)-7 A
END
ASCH: CLR C SUBB A, #30 CJNE A, #10, $+3 JC AH10
SUBB A, #07AH10: RET
散转程序—多分支程序
散转程序是指通过修改某个参数后,程序可以有三个以上的流向,多用于键盘程序。
常用的指令是 JMP @A+DPTR
DPTR ++ A PC
A 中内容为8 位无符号数
16 位地址数
程序清单如下:JUMP1 : MOV DPTR ,# JPTAB1 ;跳转表首送数据指针 MOV A , R7
ADD A , R7 ; R72A ( 修正变址值 )
JNC NOAD ;判有否进位 INC DPH ;有进位则加到高字节地址 NOAD : JMP @ A+DPTR ;转向形成的散转地址人口JPTAB1 : AJMP OPR0 ;直接转移地址表 AJMP OPR1
.
AJMP OPRn
例: 根据 R7 的内容,转向各自对应的操作程序 ( R7= 0 ,转入 OPR0 ; R7= 1 ,转入 OPR1…R7= n ,转入 OPRn )
K= ?
分支程序 0 分支程序 1 分支程序 n
4.4 循环程序设计
循环程序的结构
1.置循环初值
2.循环体
3.修改控制变量
4.循环终止控制
循环程序举例
例:设在外部 RAM中有一个 ASCII字符串,它的首地址是在 DPTR中,字符串以‘ 0’结束。现要求用89c51串行口把该字符串发送出去。在串行口已经初始化的条件下,该流程图可用以下框图表示:
TI:串口发送中断请求标志。每发送完串行数据,硬件自动将TI置1。 CPU响应中断后,须由软件清 0
流程图
结束
((DPTR)) - >A
开始
(A)=0?
发送器空?
0 - >TI(A) - >SBUF
(DPTR)+1 - >DPTR
程序: SOUT : MOVX A , @DPTR
JNZ SOT1
RET
SOT1 : JNB TI , SOT1
CLR TI
MOV SBUF , A
INC DPTR
SJMP SOUT
TI :串口发送中断请求标志。每发送完串行数
据,硬件自动将TI置1。 CPU 响应中
断后,须由软件清 0
例: 200 名学生参加考试,成绩放在 8031的外部 RAM 的一个连续存储单元, 95~100分颁发 A 级证书, 90~94 分颁发 B 级证书,编一程序,统计获 A 、 B 级证书的人数。将结果存入内部 RAM 的两个单元。
ORG 0030H EG XDATA 1000H GA DATA 20H GB DATA 21H
MOV GA , #00 MOV GB , #00 MOV DPTR , #EG MOV R2 , #200LOOP : MOVX A , @DPTR
CJNE A,#95, LOOP1
LOOP1: JNC NEXT1 CJNE A,#90,LOOP2LOOP2: JC NEXT INC GB SJMP NEXTNEXT1: INC GANEXT: INC DPTR DJNZ R2,LOOP SJMP $ END
4.5 查表程序 表格是事先存放在 ROM 中的,一般为一串有序
的常数,例如平方表、字型码表等。 表格可通过伪指令 DB 来确定。 通过查表指令 MOVC A , @A+DPTR
MOVC A , @A+PC 来实现。
•用 DB 、 DW 建立表格•首地址送 DPTR
•关键字送 A
•查表: MOVC A,@A+DPTR
用查表法计算平方 (一 )
ORG 0000H MOV DPTR, #TABLE ;表首地址送 DPTR MOV A, #05 ; 被查数字 05A MOVC A, @A+DPTR ;查表求平方 SJMP $ TABLE: DB 0,1,4,9,16,25,36,49,64,81 END
用查表法计算平方用查表法计算平方 (( 二二 ))
ORG 0000H0000H MOV A, #05 ;05 A0002H ADD A, #02 ;修正累加器 A0004H MOVC A, @A+PC ;查表求平方0005H SJMP $ 0007H : DB 0,1,4,9,16,25,36,49,64,81 END
使用 MOVC A,@A+PC 须注意 :
1. 使用传送指令将关键字送入 ACC
2. ADD A, #DATA 指令对 A 进行修改 : PC+DATA=表格首地址
3. MOVC A,@A+PC 完成查表 .
DATA= 表格首地址 - 指令地址 -1
例 :
MOV A, X ADD A,#01H MOVC A,@A+PC RET DB 00,01,04,09,10H,19H,24H,31H,30H…
DATA= 表格首地址 - 指令地址 -1即: MOVC 与DB 之间的字节数
4.7 子程序设计 好处:1. 避免重复编程
2. 简化程序的逻辑结构
3. 缩短程序长度,节省存储单元
4. 便于调试、增强可移植性
1 、子程序编写注意的问题 子程序调用 : ACALL、 LCALL 子程序返回 : RET 子程序第一条必须有标号 . 注意现场的保护和恢复 子程序嵌套注意的问题 : 嵌套深度与堆栈区大小的问题 .
正确传递参数 : 入口参数和出口参数 .
64k 范围内
2k 范围内
2 、 参数传递方法 用累加器或工作寄存器来传递参数
用指针寄存器来传递参数
用堆栈来传递参数
程序段参数传递(适于传递大量常数参数)
( 1 )累加器或工作寄存器传递参数 A 、 R0~R7 优点:最简单,运算速度快。 缺点:累加器和工作寄存器数量有限,不能传递太多参数。
( 2 )指针寄存器传递参数片内 RAM : @R0 、 @R1片外 RAM : @DPTR
例:将( R0 )和( R1 )指出的内部 RAM 中两个3B 无符号整数相加,结果送( R0 )指出的内部RAM 中,入口时, ( R0 )( R1 )分别指向加数和被加数的低字节,出口时,( R0 )指向结果的高位字节。利用 MCS - 51 的带进位加法指令,编写程序:
程序:NADD : MOV R7 ,# 3 CLR CNADD1 : MOV A , @R0 ADDC A , @R1 MOV @R0 , A INC R0 INC R1 DJNE R7 , NADD1
JNC ADDB MOV @R0,#01H ADDB : DEC R0 RET
( 3 )堆栈传递参数
PUSH
POP
优点:简单,能传递大量参数,由于参数在堆栈中,故大大简化了中断响应时的现场保护。
( 4 )程序段参数传递 采用程序段参数传递的方法,编写字符串发送的子程序: SOUT : POP DPH POP DPL SOT1: CLR A MOVC A, @A+DPTR INC DPTR JZ SEND JNB TI , $ CLR TI MOV SBUF , A SJMP SOT1 SEND : JMP @A+DPTR
以发送‘ MCS-51 CONTROLLER ’为例,说明该子程序的调用方法:
ACALL SOUT DB ‘MCS-51 CONTROLLER ’ DB 0AH,0DH,0
换行键回车键
• 以上子程序特点:• 不以一般返回指令 RET结尾,而是采用散转指令返
回到参数表后第一条指令• 可适用 ACALL或 LCALL,因为这两种调用指令把
下一条指令或数据字节地址压入堆栈• 需传递的参数可按最方便的次序排列• 子程序只使用 A 和 DPTR
习题 1 :
片内 RAM 中 30H 和 31H 中存有两个无符号数,将两个数的最小者存放入 40H 中。
解: 1 )需要用到的指令: CJNE 、 JC
2) 画流程图 3 )编程 ORG 1000H
MOV A , 30H
CJNE A , 31H , BIG
SJMP STORE
BIG: JC STORE
MOV A , 31H
STORE : MOV 40H , A
END
开始
(30H) - >A
(30H)=(31H)?
(30H)>(31H)?
(31H)40H
(30H)40H
结束
存任意数
习题 2
设变量 X 存放在 VAR 单元内,函数 Y 存放在FUNC 单元内,按下式赋值:
1 X>0
Y = 0 X=0
-1 X<1
解: 1 )假设 VAR 在片内 RAM 的 30H 单元, FUNC 在片内 RAM 的 31H 单元;
2 )画流程图 开始
(VAR)A
A=0?
-1(31H) 1(31H)
0(31H)
结束
A>0?
3 )编程 ORG 2000H
30H DATA VAR
31H DATA FUNC
START : MOV A , 30H
JZ COMP
JNB ACC.7 , POSI
MOV 31H ,# 0FFH
POSI : MOV 31H ,# 01H
COMP : MOV 31H ,# 00H
END
习题 3 :设计延时 50ms 的程序,设晶振为
12MHz 。
解: 1 机器周期= 1us ( T=1/f×12 ) 延时用 DJNZ-----2 个机器周期 50ms = 2us×125×200
编程: DEL : MOV R7 ,# 200 DEL1 : MOV R6 ,# 125 DEL2 : DJNZ R6 , DEL2 DJNE R7 , DEL1 RET实际上,该程序执行时间 >50ms ,因为没有考虑
到除 DJNZ 指令之外的其它指令的执行时间。
例 设一巡回报警系统 , 对 16 路输入进行控制 , 现根据测量路数 , 找出每路的最大允许值。(若大于允许值就报警)。
(查找双字节表格)TB3: MOV A,R2
ADD A,R2
MOV R3,A
ADD A, #6
MOVC A,@A+PC
XCH A,R3
ADD A, #3
MOVC A,@A+PC
MOV R4,A
RET
TAB3: DW 1520,3721,4256 ; 表格最大长度 256
DW …