




已阅读5页,还剩48页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第5章汇编语言程序设计 主要内容 顺序 分支 循环结构程序设计子程序设计转移指令 循环指令和子程序伪指令 教学要求 掌握 1 分支程序的概念 结构和设计 2 循环程序的概念 结构和设计 3 子程序的概念 结构和设计了解 转移表法和地址表法多分支程序的设计原理 多重循环程序的结构形式 内层循环与外层循环遵守的层次结构规则 参数修改对各层的相互影响 汇编递归程序方法 编制一个汇编语言程序的步骤 1 分析题意 确定算法 2 根据算法 确定程序流程或画出程序框图 3 根据流程或框图编写程序 4 上机调试程序 5 1顺序程序设计 顺序结构是最简单的程序结构 程序的执行顺序就是指令的编写顺序 所以 安排指令的先后次序就显得至关重要 例 设置光标到屏幕左上角 SET CURPROCMOVAH 2 设置光标位置功能MOVBH 0 页号MOVDX 0 行DH 列DLINT10H BIOS输出字符中断RETSET CURENDP 这个程序段是顺序执行的 一条指令执行后顺序执行紧接其后的另一条指令 例 设在X单元中存放一个0 7之间的整数 用查表法求出其平方值 并将结果存入Y单元 分析 根据题意 首先将0 7所对应的平方值存入连续的8个单元中 构成一张平方值表 其首地址为SQTAB 由表的存放规律可知 表首址SQTAB与X单元中的数i之和 正是i2所在单元的地址 DATASEGMENT 数据段定义SQTABDB0 1 4 9 16 25 36 49 平方值表XDB5YDB DATAENDSSTACKSEGMENTPARASTACK STACK TAPNDB100DUP TOPEQULENGTHTAPNSTACKENDSCODESEGMENTASSUMECS CODE DS DATA SS STACK SQRTSUBPROCFARPUSHDSSUBAX AXPUSHAXMOVAX DATAMOVDS AXMOVAX STACKMOVSS AXMOVAL X 取数iMOVAH 0MOVBX OFFSETSQTAB BX 表首址ADDBX AXMOVAL BX 取i2并保存MOVY ALRETSQRTSUBENDPCODEENDSENDSQRTSUB 5 2分支程序设计 分支结构是一种非常重要的程序结构 也是实现程序功能选择所必要的程序结构 由于汇编语言需要用转移指令来实现分支结构 而转移指令肯定会破坏程序的结构 所以 编写清晰的分支结构是掌握该结构的重点 计算机可根据不同条件进行逻辑判断 从而选择不同的程序流向 程序的流向是由CS和IP值决定的 当程序的转移仅在同一段内进行时 只需修改偏移地址IP的值 如果程序的转移是在不同段之间进行的 则段基址CS和偏移地址IP的值均需要修改 5 2 1转移指令 转移指令是汇编程序员经常要用到的一组指令 在高级语言中 时常有 尽量不要使用转移指令语句 的劝告 但是 在汇编语言程序中 不但要使用转移指令 而且还要灵活运用 因为指令系统中有大量的转移指令 转移指令分为无条件转移指令和有条件转移指令 无条件转移指令JMP 无条件转移指令JMP指令是从程序当前执行的地方无条件地转移到另一个地方执行 无条件转移指令JMP JMP指令转移可以是短 short 转移 偏移量在 128B 127B 之内 近 near 转移 偏移量在 32KB 32KB 之内 远 far 转移 在不同的代码段之间转移 短转移和近转移都是段内转移 JMP指令只将目标指令位置处的偏移量赋值给指令指针寄存器IP 从而实现转移功能远转移属于段间转移 JMP指令不仅会把目标指令位置处的偏移量赋值给指令指针寄存器 同时还会把目标指令所处的代码段的段地址赋值给当前代码段寄存器CS 有条件转移指令 有条件转移指令是一组及其重要的转移指令 它根据标志寄存器中的一个 或多个 标志位来决定是否需要转移 这就为实现多功能程序提供了必要的手段 有条件转移指令的格式和类型 5 2 2分支程序的结构 分支程序结构有两种形式 双分支结构和多分支结构 分支程序设计要点 1 首先根据处理的问题用比较 测试 算术运算 逻辑运算等方式 使标志寄存器产生相应的标志位 例如 比较两个单元地址的高低 两个数的大小 测试某个数据是正还是负 测试数据的某位是 0 还是 1 等 将处理的结果反映在标志寄存器的CF ZF SF DF和OF位上 2 根据转移条件选择适当的转移指令 通常一条条件转移指令只能产生两路分支 因此要产生n路分支需n 1条条件转移指令 3 各分支之间不能产生干扰 如果产生干扰 可用无条件转移语句进行隔离 例 设有单字节无符号数X Y Z 若X Y 255 求X Z 否则求X Z 运算结果放在F1中 X Y Z F1均为字节变量名 分析 这是一个双分支结构 因为X Y均为无符号数 当X Y 255时会产生进位即CF 1 所以可以用进位标志来判断 MOVAL XMOVBL ALADDAL YJNCLET 若无进位则转LETADDBL ZDONE MOVF1 BLHLTLET SUBBL ZJMPDONE 例 已知符号函数 假设任意给定x值 存放在内存RS1单元中 求出函数y的值 存放在内存RS2单元中 DATASEGMENTRS1DBX 存放自变量XRS2DB 函数Y值的存储单元DATAENDSCODESEGMENTASSUMECS CODE DS DATASTART MOVAX DATAMOVDS AXMOVAL RS1 AL XCMPAL 0 将X与0比较JGEBIG 若X 0 BIGMOVRS2 0FFH 若X 0 RS2 1 补 0FFHJMPDONEBIG JEEQUL 若X 0 EQULMOVRS2 1 若X 0 RS2 1JMPDONEEQUL MOVRS2 0 若X 0 RS2 0DONE MOVAH 4CHINT21HCODEENDSENDSTART 5 3循环程序设计 在实际工作中 有时要求对某一问题进行多次重复处理 而仅仅只是初始条件不同 这种计算过程称为具有循环特征的 而循环程序设计是解决这类问题的一种行之有效的方法 循环程序是采用重复执行某一段程序来实现要求完成计算的编程方法 5 3 1循环指令 循环语句当然可以用条件转移指令来实现 除此之外 在80 x86系统中还有专门的循环控制指令来简化循环程序的设计 循环控制指令包括重复控制指令和串操作指令 重复循环控制指令 注意 在执行此类重复控制指令前必须把重复次数送入寄存器CX中 串操作指令 串操作指令能对存储区中一块 串 字节或字进行操作 其块的长度可达64KB 这些指令分别是 串复制指令MOVS 串取出指令LODS 串存储指令STOS 串比较指令CMPS和串搜索 扫描 指令SCAS 循环程序的结构 循环程序一般包括以下5个部分 1 初始化部分 为循环做准备工作 如设置地址指针 计数器及其他变量的初值等 2 循环工作部分 它是循环程序的主体 用来完成循环的基本操作 3 修改部分 为循环参数做必要的修改 如修改操作数地址 计数器 为下一次执行循环体做好准备 4 控制部分 根据循环条件来判断 控制循环的继续和终止 5 结束部分 主要是对循环的结果进行必要的处理 如将结果送入某一寄存器或内存区域 循环程序的结构 常见的循环程序结构有两种形式 先处理后判断 和 先判断后处理 例 计算 假设这10个已知数为字类型 已连续存放在内存中以AA为首址的存储区域中 其相加的和仍为字数据 存放在BB字单元 分析 求a1 a2 a10的和 要用10条加法指令来完成 这样程序太长 书写麻烦 由于数据是有规律存放的 并且每加一项所用的指令都一样 只是数据的地址不同 所以可用间接寻址的方法 将数据地址放在寄存器中 用寄存器加1指令修改地址来取得每个待加的数据 将相加的程序作为一个公共执行的程序段 重复执行10次来实现本题的累加过程 DATASEGMENT 定义数据AADW100H 200H 300H 400H 500H 600H 700H 800H 900H 1000HBBDB4DUP MES1DB AA 100H 200H 300H 400H 500H 600H 700H 800H 900H 1000H 0DH 0AH MES2DB BB 0DH 0AH DATAENDS CODESEGMENTASSUMECS CODE DS DATASTART MOVAX DATAMOVDS AXMOVDX OFFSETMES1MOVAH 09HINT21HMOVDX OFFSETMES2MOVAH 09HINT21HMOVAX 0 累加器AX清0MOVCX 10 设置计数器初始值MOVBX OFFSETAA BX 数据首地址MOVDI OFFSETBB DI 存放结果地址LOP ADDAX BX 累加一个数据INCBX 修改地址指针指向下一个数据INCBXLOOPLOP CX 1 0 继续循环累加MOVBX AXLEADI BBCALLDISPMOVAH 4CHINT21H DISPPROCNEAR 输出MOVCH 4CONV MOVCL 4ROLBX CLMOVAL BLANDAL 0FHCMPAL 09HJLEASCIADDAL 37HJMPDONEASCI ADDAL 30HDONE MOV DI ALINCDIDECCHJNZCONVMOVCX 4LEADI BBDIS MOVDL DI MOVAH 02HINT21HINCDILOOPDISRETDISPENDP HLTCODEENDSENDSTART 例 设有两个字数组XX和YY 各包含10个元素x0 x9及y0 y9 试编制程序计算 z0 x0 y0z5 x5 y5z1 x1 y1z6 x6 y6z2 x2 y2z7 x7 y7z3 x3 y3z8 x8 y8z4 x4 y4z9 x9 y9并将运算结果存入ZZ数组 分析 这是个循环次数已知的过程 每循环一次 由XX和YY数组各取一个数据进行相应的运算 并将运算结果存入ZZ数组 由于每次循环所做的运算不同 有加法也有减法 就必须建立一个标志位 若为 0 做加法 为 1 则做减法 这样一来 只要判断标志位就可确定本次循环该做什么操作了 另外 题目要求进行10次运算 应该建立10个标志位 并存放在一个存储单元中 称为逻辑尺 根据z0 z9的运算类型 设定逻辑尺如下 0000000011011100其中 最末位的状态对应z0的操作 应做加法 其余位依次类推 最高的6位无意义 5 4子程序设计 为了程序共享或模块化设计的需要 把功能相对独立的程序段单独编写和调试 作为一个相对独立的模块供程序使用 就形成子程序 子程序可以实现源程序的模块化 简化源程序结构 提高编程效率 5 4 1子程序概念 子程序又称过程 相当于高级语言中的过程和函数 在一个程序的不同部分 往往要用到 类似 的程序段 即这些程序段的功能和结构形式都相同 只是某些变量赋值不同 此时就可以把这些程序段写成子程序形式 以便需要时调用它 子程序伪指令 子程序的相关伪指令包括子程序的定义指令 调用指令和返回指令等 子程序定义指令 子程序就是过程 过程定义伪指令的格式如下 PROC 类型属性 RETENDP 过程和主程序在同一代码段时 过程定义和调用格式如下 CODESEGMENT SUBTPROCNEAR RETSUBTENDP CALLSUBT CODEENDS 当过程和主程序不在同一代码段时 过程定义和调用格式如下 CODE1SEGMENT SUBTPROCFAR RETSUBTENDP CALLSUBT CODE1ENDSCODE2SEGMENT CALLSUBT CODE2ENDS 子程序调用指令CALL CALL指令用在主程序中 实现子程序的调用 子程序和主程序可以在同一个代码段内 也可以在不同段内 类似无条件转移指令JMP 子程序调用指令CALL也可以分成段内调用 近调用 和段间调用 远调用 CALL目标地址也可以采用直接寻址或间接寻址方式 但是子程序执行结束后是要返回的 所以 CALL指令不仅要同JMP指令一样改变CS IP以实现转移 而且还要保留下一条要执行指令的地址 以便返回时重新获取它 保护CS IP值的方法是压入堆栈 获取CS IP值的方法就是弹出堆栈 CALL指令的4种格式 1 CALLLABEL 段内调用 直接寻址 SP SP 2 SS SP IP IP IP 16位位移量 2 CALLReg16 Mem16 段内调用 间接寻址 SP SP 2 SS SP IP IP Reg16 Mem16 3 CALLFARPTRLABEL 段间调用 直接寻址 SP SP 2 SS SP CS SP SP 2 SS SP IP IP LABEL偏移地址 CS LABEL段地址 4 CALLFARPTRMEM 段间调用 间接寻址 SP SP 2 SS SP CS SP SP 2 SS SP IP IP MEM CS MEM 2 子程序返回指令RET 子程序执行完后 应返回主程序中继续执行 这一功能由RET指令完成 要回到主程序 只需获得离开主程序时 由CALL指令保存于堆栈的指令地址即可 根据子程序与主程序是否同处于一个段内 返回指令分为段内返回和段间返回 RET指令的4种格式 1 RET 无参数段内返回 IP SS SP SP SP 2 2 RETImm16 有参数段内返回 IP SS SP SP SP 2 SP SP Imm16 3 RET 无参数段间返回 IP SS SP SP SP 2 CS SS SP SP SP 2 4 RETImm16 有参数段间返回 IP SS SP SP SP 2 CS SS SP SP SP 2 SP SP Imm16 子程序的调用 对于一个子程序 应该注意它的入口参数和出口参数 入口参数是由主程序传给子程序的参数 而出口参数是子程序运算完传给主程序的结果 另外 子程序所使用的寄存器和存储单元往往需要保护 以免影响返回后主程序的运行 保护寄存器 由于调用程序 即主程序 和子程序经常是分别编制的 所以它们所使用的寄存器往往会发生冲突 如果主程序在调用子程序之前的某个寄存器内容在从子程序返回后还有用 而子程序又恰好使用了同一个寄存器 这就破坏了该寄存器的原有内容 因而会造成程序运行错误 这是不允许的 为避免这种错误的发生 在一进入子程序后 就应该把子程序所需要使用的寄存器内容保存在堆栈中 而在退出子程序前把寄存器内容恢复原状 寄存器保护实例SUBTPROCNEARPUSHAXPUSHBXPUSHCXPUSHDXPOPDXPOPCXPOPBXPOPAXRETSUBTENDP 一般说来 子程序中用到的寄存器是应该保存的 但是 如果使用寄存器在主程序和子程序之间传送参数的话 则这种寄存器就不一定需要保存 特别是用来向主程序回送结果的寄存器 就更不应该因保存和恢复寄存器而破坏了应该向主程序传送的信息 子程序的参数传递 调用程序在调用子程序时 经常需要传送一些参数给子程序 子程序运行完后也经常要回送一些信息给调用程序 这种调用程序和子程序之间的信息传送称为参数传送 或称变量传送或过程通信 参数传递一般有3种方法 利用寄存器 这是一种最常见方法 把所需传递的参数直接放在主程序的寄存器中传递给子程序 这种方法的特点是编程方便 速度快 节省存储单元 但只适合参数较少的情况 因为寄存器是有限的 利用存储单元 这种参数传递方法是把所需传递的参数直接放在子程序调用指令代码之后 这种方法的特点是每个子程序都有独立的工作单元 工作时不易引起紊乱 但它占用了存储空间 这种方法不适合递归子程序 利用堆栈 这种方法将参数压入堆栈 在子程序运行时从堆栈中取参数 由于堆栈操作不占用寄存器 并且堆栈单元使用后可自动释放 反复使用 便于实现数据隔离和模块化设计 使用这种方法时 当子程序返回后 这些参数就不再有用了 应当丢弃 这时可以利用带立即数的返回指令修改指针 使其指向参数入栈以前的值 子程序的嵌套 子程序作为调用程序又调用其他子程序 称为子程序嵌套 一般来说 只要堆栈空间允许 嵌套的层数不限 但嵌套层数较多时应特别注意寄存器内容的保护和恢复 以免数据
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 任务造型专业知识培训课程课件
- 挤压修模工虚拟仿真系统操作考核试卷及答案
- 锅炉(承压)设备焊工持续学习与知识更新考核试卷及答案
- 兽药知识讲解培训心得体会课件
- 2025购车借款合同模板
- 静电记录头制作工岗位应急处置技术规程
- 2026届湖北省武汉市黄陂区部分学校数学九年级第一学期期末调研模拟试题含解析
- 2026届湖南常德芷兰实验学校数学七年级第一学期期末调研模拟试题含解析
- 2026届福建省晋江安海片区五校联考数学九上期末综合测试模拟试题含解析
- 2026届内蒙古鄂尔多斯市名校九年级数学第一学期期末调研试题含解析
- 水生产处理工三级安全教育(班组级)考核试卷及答案
- 2025至2030中国魔芋行业项目调研及市场前景预测评估报告
- 2024新译林版英语八年级上Unit 3 To be a good learner单词表(开学版)
- Python编程基础(第3版)(微课版)-教学大纲
- 2024北森图形推理题
- 第三节集装箱吊具一集装箱简易吊具二集装箱专用吊具课件
- 管理百年知到智慧树章节测试课后答案2024年秋南昌大学
- (餐饮娱乐业态助手模板合集)店铺选址评估审批表
- 腕踝针案例分析
- 天津市河东区2024-2025学年上学期第一次月考七年级数学试题(含答案解析)
- 第一次月考2024-2025学年度九年级英语
评论
0/150
提交评论