




已阅读5页,还剩186页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1 第七章汇编语言程序设计 2 7 1汇编语言程序设计的一般步骤 汇编语言程序设计一般有以下几个步骤 p1461 分析问题 确定算法2 绘制流程图3 根据流程图编制程序4 调试程序 3 7 1 1流程图1 流程图的概念流程图是由特定的几何图形 指向线 文字说明来表示数据处理的步骤 形象描述逻辑控制结构以及数据流程的示意图 流程图具有简洁 明了 直观的特点 4 2 判断框 3 处理框 4 调用框 5 5 指向线 6 连接框 6 7 1 2程序结构 基本程序结构 顺序结构循环结构分支结构子程序结构复合结构 多种程序结构的组合 7 7 2程序设计 7 2 1顺序程序设计 例 试编写一程序计算以下表达式的值 v 540 x式中x v均为有符号字数据 设 的值存放在字变量 V中 结果存放在双字变量 之中 程序的流程图如图所示 8 9 源程序如下 DATASEGMENTXDW200YDW100ZDW3000VDW10000WDW2DUP DATAENDSSTACKSEGMENTSTACKDB200DUP 0 STACKENDSCODESEGMENTASSUMEDS DATA CS CODE SS STACK 10 START MOVAX DATAMOVDS AX DATA AXMOVAX XIMULY X Y DX AXMOVCX AXMOVBX DX DX AX BX CX MOVAX ZCWD Z 符号扩展ADDCX AXADCBX DX BX CX DX AX BX CX SUBCX 540SBBBX 0 BX CX 540 BX CX MOVAX V 11 CWD V 符号扩展SUBAX CXSBBDX BX DX AX BX CX DX AX IDIVX DX AX XMOVW AX 商 WMOVW 2 DX 余数DX W 2MOVAH 4CHINT21HCODEENDS 退出DOS状态ENDSTART 12 7 2 2分支程序设计 条件转移指令 JNZ JC等 和无条件转移指令JMP用于实现程序的分支结构 JMP不测试条件 Jcc可根据条件是否成立决定转移到指定位置或不转移而顺序执行后续指令 由于条件转移指令不支持条件表达式 而是以当前标志位的状态为条件 故条件转移指令之前一定要安排设置标志位的指令 如加减法 比较 测试等指令 基本分支类型分为单分支和双分支 13 1 单分支类型 对同一个问题 根据选择的条件不同 单分支结构的流程图有两种画法 对应的程序也有两种编法 如计算AX中的有符号数的绝对值 14 cmpax 0jgenonegnegaxNoneg movresult ax cmpax 0jngeyesnegjmpdoneyesneg negaxDone movresult ax 15 2 双分支程序 两个分支都有语句体 如何选择条件不重要 流程图中分支体的位置就是程序的实际顺序 故分支语句体 最后一定要有一条 指令 跳过语句体 转移到 后续操作 16 双分支举例 显示BX的最高位 shlbx 1jcone 转分支体movdl 0 分支体1jmpnext 转后续操作One movdl 1 分支体2next movah 2 后续操作int21h分支程序的其他问题 有些双分支问题可以先假设一种情况 把双分支改成单分支问题 如上例 先假设BX最高位为0 在分支外准备显示0 如最高位为0 即可直接跳到后续操作 如最高位为1才需要执行分支体 17 3 多分支程序 分支的嵌套形成多分支 嵌套形式多种多样 例1 求符号函数1当X 0Y 0当X 0 1当X 0 18 例4 19 p149 数据块传送程序DATASEMENTSTRGDB1000DUP STG1EQUSTRG 7STG2EQUSTRG 25STRSEEQU50DATAENDSSTACKSEGMENTPARASTACK STACK STRNDB100DUP STACKENDSCOSEGSEGMENTASSUMECS COSEG DS DATA ES DATA SS STACKBBEGIN MOVAX DATAMOVDS AX 19 MOVES AXMOVCX STRSEMOVSI OFFSETSTG1MOVDI OFFSETSTG2CLDPUSHSIADDSI STRSE 1CMPSI DIPOPSIJBOKSTDADDDI STRSE 1ADDSI STRSE 1OK REPMOVSBMOVAH 4CHINT21HCOSEGENDSENDBEGIN 20 循环程序设计 21 7 2 3循环程序设计 重复执行的程序段 p1541 循环程序的组成初始化部分 设置循环条件 次数 初值等 循环体部分 重复执行的代码 含循环条件的修改等 循环控制部分 判断循环条件 决定是否继续 2 两种循环结构1 先循环 后判断 结构相当于高级语言的 直到型 循环2 先判断 后循环 结构相当于高级语言的 当型循环 可实现0次循环 22 23 3 循环程序设计编写循环程序的关键在于循环的控制 循环次数已知 可用LOOP指令 CX计数 如教材p154 循环次数和ZF标志 可用LOOPZ LOOPNZ指令 例如7 6循环次数未知 通常要采用各类条件转移指令实现循环控制 如字符串以0结尾 字符串以 结尾 例如7 7 24 循环程序例题分析 例7 5 计算100个数字之和 仅用循环次数控制 且循环次数已知 比较简单 例7 6 确定一个字变量中为1的最低位数 从最低位向高位依次测试 最多测试16次 测试到某位为1 即可结束程序 测试结果用ZF标志反映 因此可用LOOPE或LOOPZ控制循环 结果非0 退出 例7 7 将一个字符串中的所有大写字母改为小写字母 字符串以0结尾 循环次数未知 应使用条件判断控制循环 循环结构应使用 先判断 后执行 的结构 通常 采用条件判断控制循环时 往往采用 先判断 后执行 的循环结构 25 DATASEGMENT P155求负数个数 D1DB 1 3 7 9COUNTEQU D1RSDW DATAENDSCODESEGMENTASSUMECS CODE DS DATA SS STACKBEGIN MOVAX DATAMOVDX AXLEABX OFFSETD1MOVCX COUNTMOVDX 1 26 LOP1 MOVAL BX CMPAL 0JGEJUSINCDXJUS INCBXDECCXJNZLOP1MOVRS DXMOVAH 4CHINT21HCODEENDSEND 27 例7 6 确定一个字变量中为1的最低位数 movax wordX 测试目标送AXmovcx 16 循环计数器置初值movdl 1 计位器置初值again incdltestax 1rorax 1 循环指令不影响ZFloopeagain CX 0且ZF 1 测试位为0 继续循环je jznotfound 退出循环 但0标志成立 没有1movbyteY dljmpdonenotfound movbyteY 1 ZF 1 16个位均为0done movah 4chint21hend 28 例7 7 将一个字符串中的所有大写字母改为小写字母 字符串以0结尾 DatasegmentStringdb xxxxxxxxxxxxxxxxxx 0Dataendscodesegmentassumecs code da datamovbx offsetstringagain moval bx 取一个字符oral al 是否为结尾符0jzdone 是 退出循环 29 cmpal A 是否为大写A Zjbnextcmpal Z janextoral 20h 是 转换为小写字母 使D5 1 mov bx al 仍保存在原位置next incbxjmpagain 继续循环done movah 4chint21hend 30 4 多重循环 循环程序的嵌套构成多重 多层 循环 最常见的多重循环为两重循环 两重循环结构 31 算术运算程序设计举例 32 例7 8编制一程序 实现非组合型BCD码减法运算 并显示运算结果 ex6 1 1 asm stack1segmentparastackdb5dup stack stack1endsdatasegmentnum1db2 1 5 十进制被减数s1 215num2db2 8 6 十进制减数s2 286Result0db theresultis 提示字符串resultdb4dup 运算结果加进位的ASCII码dataendsprogramsegmentmainprocfarassumecs program ds data ss stack1start movax datamovds ax 33 leasi num1 2 置被减数低位指针leadi num2 2 置减数低位指针movah 预置结果为 xorbx bx 置指针初值movcx 3 置循环次数lop1 moval num1 bx 比较被减数S1和减数S2cmpal num2 bx 从高到低依次比较jenext1 相等比较下一位jncnext2 若S1 S2 转移movah 若S1 S2 修改结果为 xchgsi di 指针交换jmpnext2next1 incbx 指针指向下一位looplop1 34 next2 movresult ah 存结果符号leabx result 3 置结果存放指针movcx 3 置循环次数clclop2 moval si 由低位开始 依次相减sbbal di 同位相减aas 十进制调整lahf 保存标志位在AH中oral 30h 同位相减的差转换为ASCII码mov bx al 存结果sahf 恢复标志位decsi 修改被减数指针decdi 修改减数指针decbx 修改结果指针looplop2 循环控制 35 leadx result0 显示结果movah 09hint21hmovah 4chint21hmainendpprogramendsendstart 36 例7 9试编制一个计算XY的程序 Titlemathematicalpower ex6 2 1 datasegmentvarxdw5 变量Xvarydw6 变量Ypowerdw 存结果dataendsprogramsegmentmainprocfarassumecs program ds data ss stack1start movax datamovds ax 37 movax varx 取自乘数movcx vary 取自乘次数deccxjeexit 自乘次数 1 转移movdx 0lop mulvarx 自乘looplopexit movpower ax 存结果movpower 2 dx 存结果高位movah 4chint21hmainendpprogramendsendstart 38 例7 10试用乘法指令实现32位二进制数的乘法Titlemathematicalpower ex6 2 2 stack1segmentparastackdb5dup stack stack1endsdatasegmentnum1dw1220h 48a2h 0h 1ha bnum2dw2398h 0ae41h c dprodudw4dup 0 存放乘积 produ high produ 6 lowdb end dataends 39 programsegmentmainprocfarassumecs program ds data ss stack1start movax datamovds axxordx dxmovax num2 2 取Dmulnum1 2 完成B Dmovprodu 6 ax 存最低位movprodu 4 dx 存乘积高位movax num2 2 取Dmulnum1 完成A Daddprodu 4 ax 加乘积低位adcprodu 2 dx 加乘积高位 40 adcprodu 0 加进位movax num2 取Cmulnum1 2 完成B Caddprodu 4 ax 加乘积低位adcprodu 2 dx 加乘积高位adcprodu 0 加进位movax num2 取Cmulnum1 完成A Caddprodu 2 ax 加乘积低位adcprodu dx 加乘积高位movah 4chint21hmainendpprogramendsendstart 41 例7 11试编制一程序 找出从2开始的前N个质数 并依次存放在NUM开始的字单元中 Titleex7 11 ex6 2 3 stack1segmentparastackdb5dup stack stack1endsdatasegmentcountdb20h 指定质数个数numdw40hdup 0 存放质数dataendsprogramsegmentmainprocfarassumecs program ds data ss stack1start movax datamovds ax 42 leadi num 存放质数指针初始值movcl count 取质数个数xordh dh 初始化xorch chmovwordptr di 2 存储第一个质数adddi 2 修改地址指针movwordptr di 3 存储第二个质数subcx 2 从第三个开始查找新质数movdl 5 待查找新质数起点movbl 3 除数起点movbh 3 置最大除数lop xorah ahmoval dl 取一个试探新数在AX中divbl 除一个奇数cmpah 0 能整除吗 jenext1 能整除 不是质数 转走 43 addbl 2 不能整除 找新除数cmpbl bh 新除数大于等于最大除数 jaenext2 是质数 转走jmplop 不是质数 继续查证next1 adddl 2 不是质数 确定下一个待查找数movbh dl 确定新的最大除数 存在BH中shrbh 1 取其一半做最大除数movbl 3 重新置除数起点jmplopnext2 adddi 2 修改地址指针mov di dx 存放新质数adddl 2 下一个待查找数movbh dl 确定新的最大除数shrbh 1 取其一半做最大除数movbl 3 重新置除数起点looplop 质数个数计数未满 继续 44 movah 4chint21hmainendpprogramendsendstart 45 代码转换程序设计 46 例7 12将ASCII码表示的两位十进制数转换成一字节二进制数 DatasegmentAsdecdb37h 35hBindb Dataendscodesegmentassumecs code ds dataStart movax datamovds axmovsi offsetasdecmoval si subal 30h 47 salal 1 采用移位指令乘10 优点 movbl almovcl 2salal claddbl alincsimoval si subal 30haddal blmovbin almovah 4chint21hCodeendsendstart 48 例7 13将ASCII码表示的两位十六进制数转换成一字节二进制数 Datasegmentashexdb41h 36hbindb DataendsCodesegmentassumecs code ds datastart movax datamovdx axmovsi offsetashex 49 moval si subal 30hcmpal 0ahJbnext1Subal 7Next1 movcl 4salal clmovbl alincsimoval si subal 30hcmpal 0ah 50 jbnext2subal 7Next2 oral blmovbin almovah 4chint21hCodeendsendstart 将ASCII码表示的数转换为十六进制数值时需考虑两种情况1 30 39h2 41H 46h 51 例7 14将一字节二进制数转换成ASCII码表示的十进制数 DATASEGMENTBINDB01001111BASDECDB2DUP DATAENDSCODESEGMENTASSUMECS CODE DS DATASTART MOVAX DATAMOVDS AXMOVDI OFFSETASDECXORAX AXMOVAL BINAGAIN SUBAL 10JBNEXTINCAHJMPAGAIN 52 NEXT ADDAL 10ADDAH 30HMOV DI AHINCDIADDAL 30HMOV DI ALMOVAH 4CHINT21HCODEENDSENDSTART 53 例7 15将ASCII码表示的5位十进制数 小于65535 转换成两字节二进制数 Datasegmentasdecdb33h 39h 35h 33h 34hcountequ asdecbindw dataendsCodesegmentassumecs code ds dataStart movax datamovds ax 54 movsi offsetasdecmovcx countxorax axAgain addax axmovbx axaddax axaddax axaddax bxmovbh 0movbl si 55 Subbl 30haddax bxIncsiLoopagainMovbin axMovah 4chInt21hCodeendsendstart 56 7 2串的处理 串操作指令 数据传送类指令每次只能传送一个数据 若要传送大批数据就需要重复编程 这样就浪费了大量的时间和空间 为此8086提供了一组处理主存中连续存放数据串的指令 下例就是有重复前缀repz串操作指令 57 串操作流程图 58 串操作指令举例 例7 16在STRBUF字符串中 寻找STRING中指定的字符串个数 stack1segmentparastackdb5dup stack stack1endsdatasegmentstrbufdb asasaasassassaasasas 被搜索字符串cuntequ strbuf 被搜索字符串字符个数stringdb as 要搜索字符串numdb 搜索到的个数dataendsprogramsegmentmainprocfarassumecs program ds data ss stack1start 59 movax datamovds ax 设置数据段moves ax 设置扩展段与数据段在同一段leasi strbuf 取源串首址leadi string 取目的串首址movcx cunt 1 置源串字符个数movbl 0 置计数器初值cld 置方向为增量方式lop cmpsw 字串比较 比较后SI DI自动加2 jnenext 不相等 查下一个incbl 相等 计数器加一next decsi 修改源串指针 后移一位leadi string 目的串首址恢复deccx 待查字符个数减一jglop 未结束 查下一个 60 movnum bl 存统计数movah 4chint21hmainendpprogramendsendstart 61 例试编制一程序 比较BUF与STRING两个字符串 把完全相同的字符个数送RESU单元中 ex7 2 2 stack1segmentparastack 自看 db5dup stack stack1endsdatasegmentbufdb abcdefghijklmnop 被比较字符串cuntequ buf 被比较字符串字符个数stringdb abcdefghijklmnop 要比较的字符串resudb 找到的相同字符个数dataendsprogramsegmentmainprocfarassumecs program ds data ss stack1start 62 movax datamovds ax 设置数据段moves ax 设置扩展段与数据段在同一段movsi offsetbuf 取源串首址movdi offsetstring 取目的串首址movcx cunt 置源串字符个数movbx cx 暂存源串字符个数cld 置方向为增量方式repzcmpsb 重复字节串比较 直到CX 0或者ZF不等于1jzend0 ZF 1 表示两字符串完全相同 转移subsi offsetbuf ZF 0 表示中途跳出 计算相同字符个数movbx si 送BX 并修正decbxend0 movresu bl 存相同字符个数 63 movah 4chint21hmainendpprogramendsendstart 64 例7 17试编制一程序 在TXTBUF字符串中查找STRING指定的字符 若查到 则把该字符所在位置 1 N 送INDEX单元中 若未查到 便把0FFH送INDEX单元中 ex7 2 3 stack1segmentparastackdb5dup stack stack1endsdatasegmenttxtbufdb abcdefghijklmnop 要查找的目的串cuntequ txtbuf 目的串字符个数stringdb g 要查找的字符indexdb 所在位置dataendsprogramsegmentmainprocfarassumecs program ds data ss stack1start 65 movax datamovds ax 设置数据段moves ax 设置扩展段与数据段在同一段movdi offsettxtbuf 取目的串首址movcx cunt 置目的串字符个数movbx 0ffh 预置未查到标识moval string 取要查找的字符cld 置方向为增量方式repnzscasb 重复字节串扫描 直到CX 0或者ZF 1 找到 jneend0 ZF 0 表示全部查完都没有找到 转移subdi offsettxtbuf ZF 1 表示中途跳出 已找到 所在位置movbx di 送BXend0 movindex bl 存标识movah 4chint21hmainendpprogramendsendstart 66 例从键盘上输入两个长度不同的字符串 设各自长度 25个字符 要求在屏幕上以右边对齐的方式显示出来 ex7 2 4 自看 stack1segmentparastackdb5dup stack stack1endsdatasegmentnumequ25prompt1db0ah 0dh string 输入字符串的提示信息Prompt2db0ah 0dh right adjustingofstring 右对齐字符串的提示信息db0ah 0dh String1dbnum 0 numdup 0ah 0dh 输入的第一个字符串String2dbnum 0 numdup 0ah 0dh 输入的第二个字符串dataendsprogramsegmentmainprocfarassumecs program ds data ss stack1 67 start movax datamovds ax 设置数据段moves ax 设置扩展段与数据段在同一段movcx 2 设循环2次leabx string1 置第一个字符串存放位置lop leadx prompt1 显示输入字符串的提示movah 09hint21hmovdx bx 输入一个字符串movah 0ahint21hleabx string2 置第二个字符串存放位置looplop 未完 继续输入下一个字符串右对齐处理leabx string1 2 置第一个字符串存放首址callmove 右对齐处理leabx string2 2 置第二个字符串存放首址callmove 右对齐处理 68 输出右对齐字符串leadx prompt2 显示右对齐字符串的提示信息movah 09hint21hleadx string1 2 置第一个字符串存放首址movah 09h 显示第一个字符串int21hleadx string2 2 置第二个字符串存放首址movah 09h 显示第二个字符串int21hmovah 4chint21hmainendp 69 moveproc 字符串右对齐处理子程序xorch ch 清零movcl 1 bx 取字符串字节数movsi cx 计算传送源串末地址addsi bx decsi 修正 SI指向源串末地址movdi bx 计算传送目的串末地址adddi num 1 std 设置DF为减量方式repmovsb 字符串传送 使其右对齐movcx num 计算剩余字节数subcl 1 bx moval AL预置空格repstosb 存串 剩余字节填空格retmoveendpprogramendsendstart 70 表的处理 在计算机处理的数据中 有许多数据具有相同的属性 例如 一个班学生的学号 姓名 性别 某门课成绩等 将这些数据按照一定的格式或规律组织起来 形成一张表格 我们就可以根据其格式寻找到其中任何一个数据 进行处理 例如 将12个月份的英文单词各取三个字符作为缩写表示 并依次排列成为一个月份缩写表 我们就可以根据月份来查出其缩写 一 表的构造 71 例7 18用查表法显示英文月份缩写 ex7 3a stack1segmentparastackdb5dup stack stack1endsdatasegmentmontabdb jan feb mar apr may jun 英文月份缩写表db jul aug sep oct nov dec monthdb9 月份dataendsprogramsegmentmainprocfarassumecs program ds data ss stack1 72 start movax datamovds ax 设置数据段moval month 取出月份的数字decal 月份减1movbl al 乘3 得表内偏移量salal 1addal blleabx montab 取月份表首址addbl al 形成该月英文缩写首址adcbh 0 73 movcx 3 置显示字符个数lop movdl bx 取显示字符movah 2 显示int21hincbx 修改地址指针looplop 未结束 显示下一个movah 4chint21hmainendpprogramendsendstart如果需要显示英文月份的全名 月份表中月份字符个数就要设为最大的一个 september9个 其余不足9个字符的月份 后面填空格 74 例7 3b假设一个班学生人数不超过9人 学生成绩表包含姓名和英语 数据结构 程序设计三门课成绩 为简化起见 这个表可以规定 9个学生姓名用A00 A09表示 姓名后依次存放字符型的三门课成绩 而且表是按学号为序排列好的 要求从键盘输入一个学号 然后从表中查找该学生的成绩并显示出来 自看 stack1segmentparastackdb5dup stack stack1endsdatasegmenttabldb a01 88 79 91 a02 78 83 77 学生成绩表db a03 77 81 80 a04 91 92 93 db a05 69 82 90 a06 76 75 79 db a07 90 90 91 a08 66 69 82 db a09 88 79 91 Listdb nameenglishdata struprogramming 表头信息inputdb inputnumber 0 exit 输入学号提示信息dataends 75 programsegmentmainprocfarassumecs program ds data ss stack1start movax datamovds ax 设置数据段lop callcrlf 显示回车换行leadx input 显示提示信息movah 09int21hmovah 1 从键盘输入要查询的学号int21handal 0fh 屏蔽学号高四位cmpal 0 学号是否为0jeend0 学号为0退出decal 学号修正为序号 76 callmult9 学号乘9 得表内偏移量 一个学生的信息9字节 leabx tabl 取成绩表首地址addbl al 加上表内偏移量adcbh 0 callcrlf 显示回车换行leadx list 显示表头信息movah 09hint21hcalldisp 显示该生成绩jmplop 循环查找end0 movah 4chint21hmainendp 77 crlfproc 回车换行子程序movdl 0ah 显示换行movah 6int21hmovdl 0dh 显示回车movah 6int21hretcrlfendpmult9proc 乘9子程序movbl al 暂存ALsalal 1 AL 2salal 1 AL 4salal 1 AL 8addal bl 加暂存值 得9倍值retmult9endp 78 显示查找结果子程序dispproccallcrlf 显示回车换行movcx 3 取显示字符个数3calldisdl 显示学生姓名movdh 3 要显示三门成绩 DH做循环控制变量lop0 movcx 8 取显示空格个数8calldispac 显示空格movcx 2 取显示字符个数2calldisdl 显示一门成绩decdh 循环控制变量减1jnzlop0 未结束 转去显示下一门成绩retdispendp 79 dispacproc 显示空格子程序 空格个数在CXlop1 movdl 取一个空格movah 6 单字符显示int21hlooplop1 未结束 转去显示下一空格retdispacendpdisdlproc 显示字符子程序 字符个数在CX中lop2 movdl bx 取一个字符movah 6 单字符显示int21hincbx 修改地址指针looplop2 未结束 转去显示下一字符retdisdlendpprogramendsendstart 80 二 表的插入 在一个数据表中 要插入一个数据 一般是将插入位置以后的数据依次往后移动 腾出所需的位置 再插入数据 MABCDEFGHIJ 81 例已有一字符串STRING 按指定位置插入一个字符 自看 stack1segmentparastackdb5dup stack stack1endsdatasegmentstringdb0dh 0ah abcdefghij 5dup 0 已有字符串stringcountequ string 字符串长度prompt1db0dh 0ah location 输入位置提示信息prompt2db0dh 0ah insertchara 输入字符提示信息dataends 82 programsegmentmainprocfarassumecs program ds data ss stack1start movax datamovds ax 设置数据段leadx string 显示原串stringmovah 09int21hleadx prompt1 显示输入位置提示信息movah 09int21hmovah 1 输入插入位置int21h AL中为位置数的ASCII码 83 andal 0fh 屏蔽位置高四位incal 加1得后移要停止的位置movbx count 5 取串长move movah string bx 后移字符movstring bx 1 ahcmpal bl 是否插入位置jeinsert 是 转插入decbx 不是 指针前移一位jmpmove 继续后移insert leadx prompt2 显示输入字符提示信息movah 09int21hmovah 1 从键盘输入字符int21h 84 movstring bx al 插入leadx string 显示插入后的串movah 09int21hmovah 4chint21hmainendpprogramendsendstart 85 例7 19对已有一字符串STRING 按指定位置删除一个字符 删除操作 只需要找到要删除的位置 将后续的数据依次往前搬动 覆盖掉要删除的数据 stack1segmentparastackdb5dup stack stack1endsdatasegmentstringdb0dh 0ah abcdefghij 5dup 0 已有字符串stringcountequ string 字符串长度prompt1db0dh 0ah location 删除位置提示信息dataends 86 programsegmentmainprocfarassumecs program ds data ss stack1start movax datamovds ax 设置数据段leadx string 显示原串stringmovah 09int21hleadx prompt1 显示删除位置提示信息movah 09int21hmovah 1 输入删除位置int21h AL中为位置数的ASCII码 87 andal 0fh 屏蔽位置高四位xorah ah AH清0 与AL组合leabx string 取原串首址movdi bx 转存在DIaddbx ax 计算删除数据的地址adddi count 1 计算串尾地址move movah bx 1 前移字符mov bx ahincbx 修改地址指针cmpbx di 是否到字符串末尾jnemove 不是 转继续前移movbyteptr bx 00h 最后字符填0 88 leadx string 显示删除后的串movah 09int21hmovah 4chint21hmainendpprogramendsendstart 89 排序 一个数据表 其中的数据如果按照某种顺序 递增或递减 排列 我们称其为有序表 否则是无序表 对无序表的处理和操作费时又复杂 效率很低 而有序表则效率高得多 所以 一般数据表都需要按照一定的顺序重新排列 这种处理叫做分类或排序 排序方法有多种 其中冒泡排序是最基本 也最常见的一种 90 冒泡法排序 不是最优的算法 但它易于理解和实现 冒泡法从第一个元素开始 依次对相邻的两个元素进行比较 如次序对 则不交换两数位置 如次序不对则将这两个数位置交换 这样使前一个元素不大于后一个元素 将所有元素比较完之后 最大的元素排到了最后 然后 除掉最后一个元素之外的元素依上述方法再进行比较 得到次大的元素排在后面 如此重复 直至完成就实现元素从小到大的排序 这是一个双重循环程序结构 可以看出 第一遍需比较 N 1 次 此时 最大的数已经放到了最后 第二遍比较只需考虑剩下的 N 1 个数 即只需比较 N 2 次 第三遍只需比较 N 3 次 整个排序过程最多需 N 1 遍 91 内循环次数是按每循环一次减1的规律变化的 是确定值 可用loop指令实现 而外循环次数则不一定要进行N 1次 因为每进行一次内循环 凡是不符合顺序的数据都交换位置 有可能在外循环尚未全部完成前就排好了顺序 这样外循环就可以提前结束 所以 我们可以在每次内循环之前设置一个交换标志位为0 在内循环中 有交换就将标志位置位0FFH 每次内循环结束后 检查交换标志 一旦交换标志为0 则表示已经排好序 可以提前退出外循环 这种办法可以使排序效率提高很多 特别是数据表很大的情况 92 例 数据表108169032第一遍101690328第二遍169032108第三遍903216108 93 例冒泡排序 stack1segmentparastackdb5dup stack stack1endsdatasegmentdadb80 3 20 116 9 120 6 62 32 42 数据表countequ da 数据表长度dataendsprogramsegmentmainprocfarassumecs program ds data ss stack1start movax datamovds ax 设置数据段 94 movdx count 1 大循环次数初值sort1 movbl 0 设交换标志初值movcx dx 内循环比较次数初值movsi 0 数据首址sort2 moval da si 取一相邻数据项cmpal da si 1 比较 是否要交换数据项 jgenoxchg 大于等于 不交换 可改试jge jl 有符号jae jb无符号xchgal da si 1 小于 交换movda si al movbl 0ffh 置已交换标志noxchg incsi 修改地址指针loopsort2 内循环控制 95 decdx 大循环次数减1cmpbl 0 本次循环是否有交换 jnesort1 有交换 继续排序movah 4ch 无交换 排序结束int21hmainendpprogramendsendstart 96 查找 要在一个数据表中查找某一个数据项 最简单的方法是顺序查找 如果数据项不在表中 或者是最后一个 查找就必须从头查到尾 这种查找的平均次数是N 2 效率很低 二分查找是在有序表的基础上 将表划分成一系列依次对半减少的空间 逐步缩小范围 首先查找表的中间数据项 如果是要找的数据项 则查找成功 如果不是 则根据中间数据项比要查找的数据项大还是小 确定下一步是在上半部份还是下半部分查找 然后又取这一半的中间数据项比较 若相同 则查找成功 若不相同 则根据它们比较的大小 再次判断要查找的数据项在哪一小半 如此反复 直到查找成功或者剩下的一小半不复存在为止 这种算法称对分查找法 对于有N个数据项的有序表 它的最多查找次数是log2N次 是用得最多 效率很高的一种算法 97 例在一个由大到小排好序的数据表中 采用对分查找法查找数据 若查找成功 将其在表中的位置送LOCA单元 若查找失败 把全1送LOCA单元 stack1segmentparastackdb5dup stack stack1endsdatasegmenttabledbcunt 1 7fh 7ah 79h 73h 70h 6eh 6bh 6ahdb5dh 5ch 5ah 59h 55h 54h 50h 4dh 4ch 4ahdb49h 48h 44h 41h 40h 3eh 3dh 3ah 39h 36hdb35h 32h 30h 2ch 25h 23h 1fh 19h 15h 00h 有序表cuntequ table 有序表长度da0db32h 要查找的数据locadw 存查找结果dataends 98 programsegmentmainprocfarassumecs program ds data ss stack1start movax datamovds ax 设置数据段movbx 1 计算查找表的长度使其等于2nmovax cunt 1 取查找表长度leng cmpbx ax 比较jaesearch 大于等于则开始搜索salbx 1 不大于 乘2jmpleng 重新比较 BX存对分点位置 DX存剩余表长 AL存待查找的数search movcx cunt 1 最后一个数据项位置shrbx 1 除2 得第一个对分点movdx bx 剩余表长moval da0 取待查找的数在AL中 99 BX存对分点位置 DX存剩余表长 AL存待查找的数comp cmpal table bx 比较jeend0 已查到 转移到结束pushf 未查到 保护标志位cmpdx 0 表已查完 jenofund 是 转移到结束popf 恢复标志位 继续查找jgup 大于 往数据表高端查找shrdx 1 小于 向下查 剩余表长除2对分addbx dx 对分位置加剩余表长jmpnext up shrdx 1 向上查 剩余表长除2对分subbx dx 对分位置减剩余表长next cmpbx cx 对分点落在表外 jbcomp 不是 转移到继续查找jmpup 是 向上找对分点nofund movbx 0ffffh 未查到 BX置常数popf end0 movloca bx 存结果 100 movah 4chint21hmainendpprogramendsendstart 101 补充例题 把BX中的二进制数以十六进制的形式显示在屏幕上 自看 BX 102 movch 4rotate movcl 4rolbx clmoval blandal 0fhaddal 30h 0 9 ASCII30H 39Hcmpal 3ahjlprintitaddal 7h A F ASCII41H 46Hprintit movdl almovah 2int21hdecchjnzrotate 103 例2 将正数n插入一个已整序的字数组的正确位置 算法 将数组中数逐个与N比较 Si为指针若N Ki 则Ki下移一个单元若N Ki 则插在Ki的下一个单元 并结束临界条件 若N Kn 则插入Kn的下一个单元若N K1 则K1 Kn后移一个单元 N插在第一个单元循环控制 计数控制元素个数 字末地址 字首地址 2 1字数 字节末地址 字节首地址 1字节数地址边界控制结束地址为ARRAY HEAD特征值控制 表示结束条件的值 104 例2 将正数n插入一个已整序的字数组的正确位置 xdw array headdw3 5 15 23 37 49 52 65 78 99array enddw105ndw32movax nmovarray head 2 0ffffhmovsi 0compare cmparray end si axjleinsertmovbx array end si movarray end si 2 bxsubsi 2jmpshortcompareinsert movarray end si 2 ax 105 例3 自看 将首地址为A的字数组从小到大排序 气泡算法 多重循环 Adw32 85 16 15 8 106 movcx 10deccxloop1 movdi cxmovbx 0loop2 movax A bx cmpax A bx 2 jlecontinuexchgax A bx 2 movA bx axcontinue addbx 2looploop2movcx dilooploop1 107 过程 子程序 定义伪操作procedure namePROCNEAR FAR procedure nameENDP 1 NEAR属性 调用程序和子程序在同一代码段中 段内调用 2 FAR属性 调用程序和子程序不在同一代码段中 段间调用 7 7子程序的设计方法 108 保存与恢复寄存器subtprocfarpushax 保存pushbxpushcxpushdx 子程序体 popdx 恢复popcxpopbxpopaxretsubtendp 109 子程序调用 中断调用 隐含使用堆栈保存返回地址callnearptrsubp 1 保存返回地址 2 转子程序 IP subp的偏移地址callfarptrsubp 1 保存返回地址 2 转子程序 CS subp的段地址 IP subp的偏移地址 子程序的
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年第八届“人才·南平校园行”活动暨光泽县紧缺急需医疗人才引进考前自测高频考点模拟试题及答案详解(典优)
- 2025湖北咸宁市通城县城市发展建设投资(集团)有限公司招聘模拟试卷完整参考答案详解
- 2025湖北襄阳市枣阳市招聘事业单位人员206人模拟试卷附答案详解(模拟题)
- 2025广东广州市百万英才汇南粤广州中医药大学第三附属医院招聘14人考前自测高频考点模拟试题及答案详解(各地真题)
- 2025北京市海淀区中关村第二小学科学城北区分校招聘考前自测高频考点模拟试题及参考答案详解1套
- 2025江西交科交通工程有限公司招聘1人考前自测高频考点模拟试题及参考答案详解一套
- 2025广西贵港桂平市江口中心卫生院招聘3人模拟试卷及答案详解(新)
- Glutaryl-CoA-Glutarylcoenzyme-A-生命科学试剂-MCE
- 安全培训效果评价报告课件
- 广州资料员培训课件
- 美术微课课题立项申报书
- GB/T 46084-2025燃煤锅炉火焰温度图像检测技术规范
- DB37-T 4457-2021企业开办工作指引
- 中科大中级有机化学实验讲义
- 《高效纠错本》课件
- 干部任免审批表(空白)【电子版】
- 中西医结合 围绝经期综合征课件
- 达梦数据库DM8系统管理员手册
- TSG11-2020 锅炉安全技术规程
- 《足球运动发展史》PPT课件
- 个人简历模板(可填写)
评论
0/150
提交评论