微机原理与接口技术(4-2)

1 微机原理与接口技术 第四章汇编语言程序设计 2 4 4程序设计方法 4 4程序设计方法 概述 一个好的程序应该具备的特点 程序结构模块化 程序易读 易调试及维护 执行速度快 占用内存空间小 概述 3 4 4程序设计方法 概述 常用四种程序结构 顺序结构 分支结构 循环结构 子程序结构 设计汇编语言源程序的基本步骤 分析问题 抽象数学模型 确定实现算法 绘制程序流程图粗框图 细框图 图例如图4 1所示 分配存储空间 工作单元 分配数据段 堆栈段 程序段的位置 确定寄存器主要作用 编写程序 静态检查 上机调试 程序运行 结果分析 4 4 4程序设计方法 顺序结构 简单程序 程序顺序执行 无分支 循环 也无转移 图中没有判断框 例4 1内存中TABLE开始存放0 9的平方值 通过人机对话 当任给定一个数X 0 9 查表得X的平方值 放在AL中 一 顺序结构 DATASEGMENTTABLEDB0 1 4 9 16 25 36 49 64 81BUFDB Pleaseonenumber 0 9 DB0DH 0AH 0DH回车 0AH换行DATAENDSSTACKSEGMENTSTACK STACK DB100DUP TOPLABELWORDSTACKENDS 5 CODESEGMENTMAINPROCFARASSUMECS CODE DS DATA SS STACKSTART MOVAX DATA 段初始化MOVDS AXMOVAX STACKMOVSS AXMOVSP OFFSETTOPMOVBX OFFSETTABLENEXT MOVDX OFFSETBUF 9号功能调用 提示输入一个数MOVAH 9INT21HMOVAH 1 1号功能调用 键入数送ALINT21H 4 4程序设计方法 顺序结构 6 MOVAH 0 查表得输入数的平方值ANDAL 0FHADDBX AXMOVAL BX MOVAH 4CH 返回DOSINT21HRETMAINENDPCODEENDSENDSTART 4 4程序设计方法 顺序结构 7 4 4程序设计方法 分支结构 1 分支结构 二 分支结构 8 4 4程序设计方法 分支结构 例4 2存储器中有一串字符串首址为BUF 字符串长度N小于256 要求分别计算出其中数字 0 9 字母 A Z 和其它字符的个数 并分别将它们的个数存放到此字符串的下面三个单元中 DATASEGMENTBUFDB100DB01H 38H 47H 60H 76HNUMDB3DUP DATAENDSSTACKSEGMENTSTACK STACK DB100DUP TOPLABELWORDSTACKENDS 9 4 4程序设计方法 分支结构 CODESEGMENTMAINPROCFARASSUMECS CODE DS DATA SS STACKSTART MOVAX STACK 初始化SS和SPMOVSS AXMOVSP OFFSETTOPPUSHDS 程序段前缀SUBAX AXPUSHAXMOVAX DATA 初始化DSMOVDS AX 10 4 4程序设计方法 分支结构 MOVCH BUF 数组个数N CHMOVBX 1MOVDX 0 DH计数字的个数 DL计大写字母的个数LP MOVAH BUF BX CMPAH 30HJBNEXT 小于 0 转CMPAH 39HJAABC 大于 9 转INCDH 数字个数加1JMPNEXTABC CMPAH 41HJBNEXT 小于 A 转CMPAH 5AHJANEXT 大于 Z 转INCDL 字母的个数加1 11 4 4程序设计方法 分支结构 NEXT INCBX 数组地址加1DECCH 计数器减1JNZLPMOVNUM DH 数字的个数送入内存单元MOVNUM 1 DL 字母的个数送入内存单元MOVAH BUFSUBAH DH N DH DL 其它字符的个数SUBAH DLMOVNUM 2 AH 其它字符的个数送入内存单元RETMAINENDPCODEENDSENDSTART 12 4 4程序设计方法 分支结构 2 多分支依次测试多个条件是否满足 若满足转入相应分支入口 不满足继续向下测试 直到全部测试完 此方法编程简单直观 但速度慢 例4 3有8个加工子程序 入口地址分别为P1 P2 P8 编程实现检测键盘输入命令 使系统分别转向8个加工子程序 解 相应程序如下 13 4 4程序设计方法 分支结构 MOVAH 1INT21H 1号功能键调用 键盘接收CMPAL 1 键值为1 转1号加工子程序JEP1CMPAL 2 键值为2 转2号加工子程序JEP2 CMPAL 8 JEP8 键值非1 8 转向停止JMPSTP1 1号加工子程序 P8 ST HLT 14 4 4程序设计方法 分支结构 3 跳转表实现多分支好处 可以直接找到相应入口 实现 建立跳转表 包括每个分支的入口地址 跳转指令或关键字 根据表内地址分支表中存放 每个分支程序的入口地址 只要找到表地址 即可得到每个分支的入口地址 表地址 跳转表首地址 偏移地址 15 4 4程序设计方法 分支结构 跳转表在内存中的存放方法如图4 3所示 按表地址分支的流程图如图4 4所示 16 例4 4将上例用跳转表来实现ADATASEGMENTBASEDWP1 P2 P3 P4 定义跳转表DWP5 P6 P7 P8KEYDB ADATAENDSASTACKSEGMENTSTACK STACK DB100DUP TOPLABELWORDASTACKENDSACODESEGMEINTASSUMECS ACODE DS ADATA SS ASTACK 4 4程序设计方法 分支结构 17 MAINPROCFARSTART MOVAX ASTACK 初始化SSMOVSS AXMOVAX OFFSETTOP 初始化SPMOVSP AXPUSHDS 程序段前缀MOVAX 0PUSHAXMOVAX ADATA 初始化DSMOVDS AXLOP MOVAH 1 键值在AL中 为ASCII码INT21H 4 4程序设计方法 分支结构 18 CMPAL 1 按错键 重新读键JBLOPCMPAL 8 JALOPANDAL 0FHDECAL 地址表中P1对应的偏移地址为BASEMOVBX OFFSETBASE 取首地址MOVAH 0ADDAL ALADDBX AX 求表地址JMPWORDPTR BX 转入相应入口地址 RETMAINENDPACODEENDSENDSTART 4 4程序设计方法 分支结构 19 4 4程序设计方法 分支结构 根据表内指令分支表内存放 转移指令 查表后程序转到相应子程序 转移指令跳转表存放形式如图4 5 20 例4 5将例4 3程序用跳转表来安排指令实现分支 DATASEGMENTBASEDBE9 P1低 P1高 E9 DBE9 E9 P8低 P8高DATAENDS LOP MOVAH 1 读入键值INT21H AL中为ASCII码CMPAL 1 按错键 重新读键JBLOPCMPAL 8 JALOPANDAL 0FH 屏蔽高4位DECAL P1跳转表的偏移地址为BASE 4 4程序设计方法 分支结构 21 MOVAH 0MOVBL AL AL为键值ADDAL ALADDAL BL 偏移量 键值 3MOVBX OFFSETBASE 基地址ADDBX AX 表地址JMPBX 转入转移指令 4 4程序设计方法 概述 22 4 4程序设计方法 分支结构 根据关键字分支表中存放 关键字 及相应分支地址 图4 6给出了关键字跳转表的格式 图4 7给出了关键字分支流程图 23 BDATASEGMENTBASEDB31H 关键字DWP1 P1入口地址 DB38HDWP8BDATAENDS LOP MOVAH 1 读入键值INT21H 例4 6将例4 3用关键字跳转表方式实现分支 4 4程序设计方法 分支结构 24 CMPAL 1 按错键 重新读键JBLOPCMPAL 8 JALOPMOVBX OFFSETBASE 取表首址NEXT CMPAL BX 关键字转DOJEDOADDBX 3 修改地址JMPNEXTDO JMPWORTPTR BX 1 4 4程序设计方法 分支结构 25 4 4程序设计方法 分支结构 例4 7设有首地址为BUFFER的数组 已按升序排好 数组长度N 10 在数组中查找数M 80 若找到则从数组中删掉 若找不到将它插入正确的排序位置 DX中记录数组最后的长度 DATASEGMENTBUFFERDW5 10 32 47 53 77 89 106 115 124NDW10MEQU80DATAENDSASTACKSEGMENTSTACK STACK DB100DUP TOPLABELWORDASTACKENDS 26 4 4程序设计方法 分支结构 CODESEGMENTASSUMECS CODE DS DATA ES DATAMAINPROCFARSTART MOVAX ASTACK 初始化SSMOVSS AXMOVAX OFFSETTOP 初始化SPMOVSP AXPUSHDS 程序段前缀SUBAX AXPUSHAXMOVAX DATA 初始化DS ESMOVDS AXMOVES AX 27 MOVAX M 待查数 AXMOVCX N 计数 CXMOVDX NMOVDI OFFSETBUFFERCLDREPNESCASW 串扫描查找JEDEL 查到ZF 1MOVCX DXDECDX 未查到 此数插入正确位置MOVSI DX 关键字与最后一个数比较ADDSI DX N 1 2 SI 4 4程序设计方法 分支结构 28 L1 CMPAX BUFFER SI JLL2 关键字比较组中某个字小MOVBUFFER SI 2 AX 否则插在后面JMPL3L2 MOVBX BUFFER SI 数组下移一位MOVBUFFER SI 2 BXSUBSI 2LOOPL1MOVBUFFER SI 2 AX M为最小 插入最前面L3 ADDDX 2 修改长度 因DX减过1 JMPNEXT1 4 4程序设计方法 分支结构 29 DEL JCXZNEXT 找到 删此元素DEL1 MOVBX DI 其后元素依次前移MOV DI 2 BXADDDI 2LOOPDEL1NEXT DECDX 改变数组长度NEXT1 RETMAINENDPCODEENDSENDSTART 4 4程序设计方法 分支结构 30 4 4程序设计方法 循环程序结构 1 循环程序的两种结构形式 先执行后判断 进入循环后至少要执行一次循环体 再判断循环是否结束 适合于循环次数固定的程序 先判断后执行 进入循环后 先判断循环结束条件 再决定是否执行循环体 可能循环体一次也不执行 适合于循环次数不固定的程序 如图4 8所示 三 循环程序结构 31 4 4程序设计方法 循环程序结构 32 4 4程序设计方法 循环程序结构 两种循环结构都包括四部分 初始化设置循环计数值 设置变量初值 循环体循环部分的核心 循环的全部执行指令 修改参数修改操作数地址 为下次循环作准备 循环控制修改计数器值 判断循环控制条件 决定是否跳出循环 33 4 4程序设计方法 循环程序结构 例4 8将BX中的16进制数转换为ASCII码 存放到BUF开始的内存单元中去 并在屏幕显示出数值 本程序编写采用 先执行后判断 的结构 流程图如图4 9所示 34 MOVSI OFFSETBUF 设置内存地址MOVCH 4 计数初值 4NEXT MOVCL 4ROLBX CL 最高位移到右边MOVAL BL 一个数转换成ASCII码ANDAL 0FHADDAL 30H 或ORAL 30H CMPAL 3AH 字符为A F吗 JBSTOREADDAL 7STORE MOV SI AL 字符存入内存 4 4程序设计方法 循环程序结构 35 MOVAH 2 调用屏幕显示MOVDL ALINT21HINCSI 修改计数并判断DECCH