汇编语言程序设计技巧详解(附例题)
目录
1、顺序结构
2、分支结构
(1)先建立可供条件转移指令测试的条件。
(2)选用合适的条件转移指令。
(3)在转移的目的地址处设定标号。
多重分支程序
a.多次使用条件转移指令,形成两个以上判断框。
b.按分支号转移
(1)用地址表法。设分支号已存入A。
(2)转移表法。用分支转移指令 JMP @A+DPTR
3、循环结构
(1)循环初始化
(2)循环体
(3)循环控制
多重循环循环体中套循环结构
4、子程序
(1)子程序入口用标号作为子程序名。
(2)调用子程序之前设置好堆栈。
(3)用返回指令RET结束子程序,并保证堆栈栈顶为调用程序的返回地址。
(4)子程序嵌套须考虑堆栈容量。
(5)提供足够的调用信息:
1.寄存器传送参数
2.存储器传送参数
3.堆栈传送参数
模块化设计
汇编语言程序设计技巧
四种基本结构:顺序结构、分支结构、循环结构和子程序。
1、顺序结构
【例】将R0单元内的两位BCD码拆开并转换成ASCII码,存入RAM两个单元中R2 (存高位)和R1 (存低位)中 。
参考程序:
ORG 2000H
MOV A,R0 ;取值
ANL A,#0FH ;取低4位
ADD A,#30H ;转换成ASCII码
MOV R1,A ;保存结果
MOV A,R0 ;取值
SWAP A ;高4位与低4位互换
ANL A,#0FH ;取原来的高4位
ADD A,#30H ;转换成ASCII码
MOV R2,A ;保存结果
SJMP $
END
2、分支结构
(1)先建立可供条件转移指令测试的条件。
(2)选用合适的条件转移指令。
(3)在转移的目的地址处设定标号。
【例】求R2中补码绝对值,正数不变,负数变补。
MOV A,R2
JNB ACC.7,NEXT;为正数?
CPL A ;负数变补
INC A
MOV R2,A
NEXT:SJMP NEXT ;结束
多重分支程序
a.多次使用条件转移指令,形成两个以上判断框。
【例】 求符号函数Y=SGN(X)
+1 当 X>0
SGN(X)= 0 当 X=0
-1 当 X<0
SYMB: MOV A,40H ;取X
JZ STOR ;X=0,Y=X
JB ACC7,MINUS;X<0
MOV A,# 1 ;X>0,Y=+1
SJMP STOR
MINUS:MOV A,#0FFH;X<0,Y= -1
STOR: MOV 41H,A ;保存Y
RET
b.按分支号转移
如:分支号=0,程序转移到ADDR0处;当分支号=1,程序转移到ADDR1处;… 。
(1)用地址表法。设分支号已存入A。
MTJS:MOV DPTR,#TAB ;取表首地址
CLR C
RLC A ;分支号×2
MOV R2,A
INC A
MOVC A,@A+DPTR;取分支地址低位
PUSH ACC ;入栈保存
MOV A,R2
MOVC A,@A+DPTR;取分支地址高位
PUSH ACC ;入栈保存
RET ;分支地址→PC,转移
TAB: DW ADDR0 ;分支地址表
DW ADDR1
…
ADDR0: … ;程序段0 …
(2)转移表法。用分支转移指令 JMP @A+DPTR
【例】根据R0的值转向7个分支程序。R0<10,转向SUB0; R0<20,转向SUB1;… …R0<60,转向SUB5; R0>=60,转向SUB6;
分析:这里应该利用JMP @A+DPTR
指令直接给PC赋值,使程序实现转移
参考程序如下:
ORG 2000H
MOV DPTR,#TAB;取转移指令表首地址
MOV A,R0 ;取数
MOV B,#10
……
DIV AB ;A/10,商在A中
CLR C
RLC A ;A←2A
JMP @A+DPTR ;PC ← A+DPTR
TAB: AJMP SUB0 ;转移指令表
AJMP SUB1
AJMP SUB2
……
AJMP SUB6
3、循环结构
循环程序结构是汇编语言程序中常见的一种程序结构。所谓循环,就是让计算机反复执行某一段程序。使用循环程序可以省略很多类似的代码,提高程序的代码密度。
循环程序主要包含以下三个方面:
(1)循环初始化
设置循环的初始状态,如工作单元的清零,循环次数的设置等。在设置初始条件时要小心,否则很容易让程序多执行(或少执行)一次。
(2)循环体
即循环程序的主体,是要求计算机重复执行的部分。这部分程序应该特别注意精简,因为要重复多次,所以这部分的精简程度决定了整个循环程序的执行效率。
(3)循环控制
包括对循环计数器的修改和循环结束条件的判断等内容。
【例】把内部RAM中从ST1地址开始存放的数据传送到以ST2开始的存储区中,数据块长度未知,但已知数据块的最后一个字节内容为00H,而其它字节均不为0。并设源地址与目的地址空间不重叠。
分析:显然,我们可以利用判断每次传送的内容是否为 0 这一条件来控制循环。利用判A转移控制的循环流程图如下图所示。
参考程序如下:
START:MOV R0,#ST1
MOV R1,#ST2
LOOP: MOV A, @R0
JZ ENT
MOV @R1,A
INC R0
INC R1
SJMP LOOP
ENT: RET
例:求n个单字节数据的累加,设数据串已在43H起始单元,数据串长度在42H单元,累加和不超过2个字节。
SUM: MOV R0,#42H;设指针
MOV A,@R0
MOV R2,A ;循环计数器←n
CLR A ;结果单元清0
MOV R3,A
ADD1:INC R0 ;修改指针
ADD A,@R0 ;累加
JNC NEXT ;处理进位
INC R3 ;有进位,高字节加1
NEXT: DJNZ R2,ADD1 ;循环控制:数据是否加完?
MOV 40H,A ;循环结束,保存结果
MOV 41H,R3
RET
多重循环循环体中套循环结构
例将内存一串单字节无符号数升序排序。
步骤:
每次取相邻单元的两个数比较,决定是否需要交换数据位置。
第一次循环,比较N-1次,取到数据表中最大值。
第二次循环,比较N-2次,取到次大值。
…
第N-1次循环:比较一次,排序结束。
程序:
SORT: MOV A,#N-1 ;N个数据排序
MOV R4,A ;外循环次数
LOOP1: MOV A,R4
MOV R3,A ;内循环次数
MOV R0,#TAB ;设数据指针
LOOP2: MOV A,@R0 ;取二数
MOV B,A
INC R0
MOV A,@R0
CJNE A,B,L1 ;比较
L1: JNC UNEX ;A≥B,不交换
DEC R0 ;否则交换数据
XCH A ,@R0
INC R0
MOV @R0,A
UNEX: DJNZ R3,LOOP2 ;内循环结束?
DJNZ R4,LOOP1 ;外循环结束?
RET
4、子程序
能完成某项特定功能的独立程序段,可被反复调用。
子程序设计
(1)子程序入口用标号作为子程序名。
(2)调用子程序之前设置好堆栈。
(3)用返回指令RET结束子程序,并保证堆栈栈顶为调用程序的返回地址。
(4)子程序嵌套须考虑堆栈容量。
(5)提供足够的调用信息:
如:子程序名、子程序功能、入口参数和出口参数、子程序占用的硬件资源、子程序中调用的其他子程序名。
选用不同的参数传递方式。
1.寄存器传送参数
2.存储器传送参数
3.堆栈传送参数
【例】将R4R5R6中三个字节数据对半分解,变成6个字节, 存入显示缓冲区(DISMEM0~DISMEM5)。
1)子程序UFOR1的功能:将A累加器中单字节数据,对半分解成两个字节,存入R0所指向的相邻两个单元
UFOR1:MOV @R0,#0
XCHD A,@R0 ;保存低半字节
INC R0 ;修改指针
MOV @R0,#0
SWAP A
XCHD A,@R0 ;保存高半字节
RET
2)调用子程序UFOR1之前,将待分解的内容送A,存放地址送R0。
【例】利用MCS-51仿真实验板,外部扩展四个双色发光二极管HL1、HL2、HL3和HL4分别模拟北(HL1)、西(HL2)、东(HL3)、南(HL4)四个方向交通灯,连接电路如下图所示:
分析:双色发光二极管有一个阴极,两个阳极G和R,当G极为高电平时,发光二极管呈现绿色,当R极为高电平时,发光二极管呈现红色,当G和R极都为高电平时,发光二极管呈现黄色,根据题意要求和图3.19的电路连接情况可以知道P1口的控制状态如下表所示:
参考程序如下:
ORG 1000H
START:MOV R0,#0
MOV R1,#0 ;南北绿灯亮5秒钟,东西红灯亮
MOV P1,#10010110B ;南北绿灯亮红灯灭,东西红灯亮绿灯灭,为状态1
SNDL5: MOV R1, #10
ACALL DL500ms ;调用延时500ms程序10次,实现延时5秒
DJNZ R1, SNDL5 ;南北绿灯闪烁3次,每次1秒(亮0.5秒,灭0.5秒)
SS1: MOV P1,#10011111B;南北绿灯和红灯都灭,东西红灯亮绿灯灭,为状态2
ACALL DL500ms ;延时500ms
MOV P1,# 10010110B ;南北绿灯亮红灯灭,东西红灯亮绿灯灭,为状态1
ACALL DL500ms ;延时500ms
INC R0
CJNE R0,#03H,SS1 ;闪烁3次,南北黄灯亮2秒
MOV P1,#00000110B ;南北黄灯亮,东西红灯亮绿灯灭,为状态3
SNDL2: MOV R1, #4
ACALL DL500ms ;调用延时500ms程序4次,实现延时2秒
DJNZ R1, SNDL2 ;东西绿灯亮5秒钟,南北红灯亮
MOV P1,#01101001B ;东西绿灯亮红灯灭,南北红灯亮绿灯灭,为状态4
EWDL5: MOV R1, #10
ACALL DL500ms ;调用延时500ms程序10次,实现延时5秒
DJNZ R1, EWDL5 ;东西绿灯闪烁3次,每次1秒(亮0.5秒,灭0.5秒)
SS2: MOV P1,#01101111B ;东西绿灯和红灯都灭,南北红灯亮绿灯灭,为状态5
ACALL DL500ms ;延时500ms
MOV P1,# 01101001B ;东西绿灯亮红灯灭,南北红灯亮绿灯灭,为状态4
ACALL DL500ms ;延时500ms
INC R0
CJNE R0,#03H,SS2 ;闪烁3次,东西黄灯亮2秒
MOV P1,#00001001B ;东西黄灯亮,南北红灯亮绿灯灭,为状态6
SNDL2: MOV R1, #4
ACALL DL500ms ;调用延时500ms子程序4次,实现延时2秒
DJNZ R1, SNDL2
SJMP START ; 500ms 秒延时子程序
DL1500mS: MOV R7,#5 ;500ms 秒延时子程序,假定为6MHz晶振
DL2: MOV R6,#200
DL1: MOV R5,#250
DJNZ R5,$
DJNZ R6,DL1
DJNZ R7,DL2
RET
END
模块化设计
模块化设计是指把一个具体的功能分解成多个小的模块,各个模块之间相互独立,而又可以相互传递参数。分解成的小模块程序功能单一,易于调试和修改,而在模块内部要注意多使用子程序调用,一个子程序可以被多次调用,节省空间而且便于阅读。在程序中应该尽量使用循环结构,这样可以节省内存,提高执行效率,不过要注意循环的初始值和循环的结束条件。
注意:由于中断是随机产生的,因此在处理中断程序时,一定要注意保存程序现场(保护标志寄存器和中断处理程序用到的寄存器),以便执行完毕后恢复。在进行子程序调用时,经常使用累加器A(参数多时还可以使用寄存器或存储器)进行参数传递。
汇编语言程序设计技巧详解(附例题)相关推荐
- 数学规划详解(附例题及部分Python实现)
数学规划详解(附例题及Python实现) 例题来自于清风老师的数学建模课,个人认为讲的非常好,欢迎大家购买 一.概述 1.1 定义 数学规划是运筹学的一个分支,在约束条件下,按照目标函数来寻求计划管理 ...
- 二分图匹配 Hopcroft-Carp (HK) 算法详解 附例题
了解这个算法之前 首先了解一个概念 :增广路 增广路 :简单的说 ,是二分图匹配中的一条边,他总是从 左边集合的一个点出发通过一条没有被匹配的边连接到右边集合,再从该点通过一条 匹配过的边连接到右边集 ...
- .user.ini上传详解附CTF例题
.user.ini上传详解附CTF例题 题目 解法 https://buuoj.cn/challenges#[SUCTF%202019]CheckIn [SUCTF 2019]CheckIn 题目 解 ...
- mysql入门优化_MySQL数据库:MySQL十大优化技巧详解
本文主要向大家介绍了MySQL数据库的MySQL十大优化技巧详解,通过具体的内容向大家展现,希望对大家学习MySQL数据库有所帮助. WEB开发者不光要解决程序的效率问题,对数据库的快速访问和相应也是 ...
- 蓝牙:CRC原理详解(附crc16校验代码)
CRC原理详解(附crc16校验代码) 参考链接: https://www.cnblogs.com/esestt/archive/2007/08/09/848856.html Cyclic Redun ...
- 塞尔达盾反机器人_《塞尔达传说:荒野之息》新手盾反技巧详解攻略
<塞尔达传说:荒野之息>新手盾反技巧详解攻略 作者:屁股平沙落雁式 来源:塞尔达传说吧 发布时间:2017年05月09日 <塞尔达传说荒野之息>中的盾反是一个很重要的技巧,熟练 ...
- Sniff网络基础原理和软件实现技巧详解
Sniff网络基础原理和软件实现技巧详解 前言 SNIFF真是一个古老的话题,关于在网络上采用SNIFF来获取敏感信息已经不是什么新鲜事,也不乏很多成功的案例,那么,SNIFF究竟是什么呢? SNIF ...
- Android吃鸡 3dtouch,绝地求生刺激战场3Dtouch怎么用 刺激战场3Dtouch吃鸡技巧详解
腾讯光子&PUBG联合出品,正版<绝地求生>手游!百人空投,荒岛求生!虚幻4引擎研发,次世代完美画质,重现端游视听感受:8000Mx8000M正版... 类型:飞行射击 大小:11 ...
- 挑战程序设计竞赛——详解DFS及BFS
挑战程序设计竞赛--详解DFS及BFS 一.学会要用到的stl函数,Stack.Quene.Pair 1.Stack(DFS隐式的用到,并与Queue对比记忆) 头文件==#include== sta ...
- 潮人篮球不显示服务器,潮人篮球补篮技巧详解
<潮人篮球>PF和C都有补篮这一技能,在技能的说明中是连按两下篮板触发,然而玩家们发现屏幕都要搓烂了也没能按出来几次.补篮按不出来怎么办?下面就为大家带来由"无良哥哥" ...
最新文章
- python使用openCV图像加载(转化为灰度图像)、使用filter2D函数对图像进行锐化(Sharpen Images)
- 从VC 6.0移植代码到VS C++ 2005得出的一些经验
- 高成本低收益的市场现状下 安防企业该怎么办?
- PS:将webp后缀图片最简单最快速的方法另存为png后缀的图片
- php网站制作商品结算怎么做,一种以让产品、信息快速同步多网站销售并结算的技术的制作方法...
- 《C++ Primer》14.2.1节练习
- 本地方法(JNI)——使用调用API
- PYTHON知识梳理
- vscode创建代码截图_如何在VSCode中创建代码配置文件
- 机器学习(八)支持向量机svm终结篇
- 请还未提交实名的博客专家在8月4日前尽快提交您的实名信息
- 酒桌扑克娱乐喝酒小游戏微信小程序源码下载多娱乐功能支持流量主
- 实验十七 通信录csv文件管理
- Windows 8轻松用系列
- 写贺卡给毕业师姐怎么写计算机系的,写给师姐的毕业祝福语赠言 送给师姐的毕业祝福语大全...
- Curator基本操作(Zookeeper节点增删改查)
- oracle怎么对账,Oracle EBS 如何月结、对账[Z]
- c++类和对象(类的概念)
- HAL库实践记录之串口接收不定长数据
- 小数除以整数在c语言,小数除以整数的说课稿
热门文章
- elasticsearch修改配置文件后启动报错:Caused by: expected 'document start‘', but found BlockMappingStart
- python launcher卸载后蓝屏_使用dump文件分析系统蓝屏原因
- 网易 android 加密,解析网易云音乐的加密方式
- 复合线转权属线lisp_三权发证中使用MAPGIS CASS如何应用复合线 简单、快速生成集体土地所有权权属线 -...
- 100天搞定机器学习|Day35 深度学习之神经网络的结构
- fm信号表达式_chirp信号表达式
- snap7读写西门子plc1200步骤(python) PLC通讯
- 对极域64位禁止终止进程、键盘锁定的分析
- 顺序栈基本操作代码实现
- protues仿真器51单片机定时器内部定时方式