已阅读5页,还剩113页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
汇编语言程序设计Ch 5汇编语言程序设计5 1汇编源程序的编程格式5 2DOS系统I O功能调用5 3BIOS键盘输入功能调用5 5分支程序5 6循环程序5 7子程序及其调用5 8宏指令与条件汇编5 9代码转换5 10数值计算和数据处理5 12模块化程序设计 486DATASEGMENTUSE16MESGDB A 0DH 0AH DATAENDSCODESEGMENTUSE16ASSUMECS CODE DS DATABEG MOVAX DATAMOVDS AXDS初值 以上设置 MOVAH 4CHINT21H 返回DOSCODEENDSENDBEG 汇编结束语句 例 将N1和N2两个单字节数以28为模求和 SUM单元 5 1汇编源程序的编程格式 1 EXE文件编程格式允许源程序使用多个逻辑段 适合编写大型程序 最终能生成 EXE文件 486DATASEGMENTUSE16N1DBxxN2DBxxSUMDB DATAENDSSTACK SEGMENTSTACK STACK USE16DB128DUP STACK ENDS BEG MOVAX DATAMOVDS AXMOVAX STACK MOVSS AXMOVSP 128MOVAL N1ADDAL N2MOVSUM ALMOVAH 4CHINT21HCODEENDSENDBEG CODESEGMENTUSE16ASSUMECS CODE DS DATA SS STACK 说明 EXE文件中堆栈段的设置a本例以 STACK 为段名的逻辑段 选用了 STACK 链接参数 DOS自动认为 STACK 段为堆栈段 所以 DOS将自动给SS SP赋初值 因此 源程序给SS SP赋初值的三条语句是多余的 b链接程序要求 EXE文件中的源程序必须有堆栈段 否则链接时将给出警告信息 Warningnostacksegment但这不代表源程序有错 仅仅是警告而已 c如果源程序中不设置堆栈段 在链接时 会给出错误信息 DOS将自动给程序分配最少128字节的堆栈区 故源程序中 如果没有大量数据压栈的话 可以不设置堆栈段 从而简化程序 486DATASEGMENTUSE16N1DBxxN2DBxxSUMDB DATAENDSSTACK SEGMENTSTACK STACK USE16DB128DUP STACK ENDSCODESEGMENTUSE16ASSUMECS CODE DS DATA SS STACK BEG MOVAX DATAMOVDS AXMOVAX STACK MOVSS AXMOVSP 128MOVAL N1ADDAL N2MOVSUM ALMOVAH 4CHINT21HCODEENDSENDBEG 2 COM文件的编程格式 1 汇编语言规定 COM文件的源程序只能有一个段 代码段 不允许有堆栈段 在代码段偏移地址 100H处 必须是程序的启动指令 程序中使用的数据可以放在代码段的开始或结尾 486 486CODESEGMENTUSE16CODESEGMENTUSE16ASSUMECS CODEASSUMECS CODEORG100HORG100HBEG JMPSTARTBEG MOVAL N1N1DBXXADDAL N2N2DBXXMOVSUM ALSUMDB MOVAH 4CHSTART MOVAL N1INT21HADDAL N2N1DBXXMOVSUM ALN2DBXXMOVAH 4CHSUMDB INT21HCODEENDSCODEENDSENDBEGENDBEG 2 上例写成COM格式源程序 3 COM文件的生成设上例的文件名为N1ADDN2 ASM 编辑生成N1ADDN2 ASM 调用TASM EXE生成N1ADDN2 OBJTASMN1ADDN2 调用TLINK EXE生成N1ADDN2 COMTLINKN1ADDN2 t注意 链接参数为小写字母t DOS系统I O功能的调用 DOS操作系统由四个部分组成 其中 IBMDOS COM 是磁盘文件管理程序IBMBIO COM 是基本I O设备处理程序这两个模块中都有若干子程序 供应用程序调用 可调用的子程序集中存放在 21H型中断服务程序 中 用户程序调用这些子程序就称为 DOS系统功能调用 BIOS DOS调用模式 MOVAH 功能号设置入口参数INTn分析出口参数 BIOS DOS功能调用 1 调用模式MOVAH 功能号设置入口参数INT21H分析出口参数 2DOS系统I O功能调用 在DOS功能子程序调用中 我们把通过INT21H来实现的子程序调用成为DOS系统功能调用 功能号01 等待键入一个字符 有回显 响应Ctrl C 入口参数 无 出口参数 AL 按键的ASC 码 若AL 0 表明按键是功能键 光标键 需再次调用此功能 才能返回按键的扩展码 功能号07 等待键入一个字符 无回显 不响应Ctrl C 入口参数 无 出口参数 AL 按键的ASC 码 若AL 需再次调用该功能才能在AL中得到按键的扩展码 功能号08 等待键入一个字符 无回显 响应Ctrl C 入口参数 无 出口参数 AL 按键的ASC 码 若AL 0 需再次调用该功能才能在AL中得到按键的扩展码 2键盘功能的调用 功能号0AH 等待键入一串字符 送用户程序数据缓冲区入口参数 出口参数如图所示 使用0AH号功能的几点说明 要求键入的字符串以 回车 作为结束标志 换句话说 按下回车键后 此功能调用结束 光标返回当前行始格 回车 符留在缓冲区当中 缓冲区要设置在用户程序数据段 调用前 缓冲区首址偏移量应赋给DX寄存器 缓冲区首单元应预置 允许接受的字符个数 包括回车符在内 最多255个 DOS的操作 接受的键入的字符串从BUF 2单元开始依次存放 因此 设置的缓冲区容量要不小于键入串的长度 2 用户键入回车后 把实际键入的字符个数 不包括回车符 写入BUF 1单元 缓冲区不接受超长字符 并发出声响以示警告 0AH在接收字符的过程中 有回显 响应Ctrl C 按下退格键可删除屏幕及缓冲区中的当前字符 下面的程序段给出了0AH功能调用的示范 它允许用户键入15个字符 包括回车键 假设 数据段BUFDB15DB DB15DUP 代码段 MOVAH 0AHMOVDX OFFSETBUFINT21H 功能号0CH 清除键盘缓冲区 然后调用由AL指定的功能 入口参数 AL允许是 01H键入一个字符 有回显 响应Ctrl C 06H字符I O 07H键入一个字符 无回显 不响应Ctrl C 08H键入一个字符 无回显 响应Ctrl C 0AH键入一串字符 写入用户数据区 其他入口参数应根据相关的功能 另行设置 功能号02H 显示一个字符 响应Ctrl C入口参数 DL 待显字符的ASC 码 出口参数 无 本功能在屏幕的当前位置显示一个字符 光标右移一格 如果是在一行末尾显示字符 则光标返回下一行的开始格 如果是在屏幕的右下角显示字符 光标返回时屏幕要上滚一行 3 显示功能的调用 注意 该项功能破坏AL寄存器的内容 功能号09H 显示字符串 响应Ctrl C 入口参数 DS DX 字符串首地址 字符串必须以 为结束标志 ASC 码24H 出口参数 无 该项功能从屏幕当前位置开始 显示字符串 遇到结束标志 时停止 字符并不显示 注意 该项功能破坏AL寄存器的内容 功能号4CH 该功能是指 终止当前程序的运行 并把控制权交给调用它的程序 由被终止程序打开的全部文件都被关闭 该项功能还把程序占用的内存空间交还给DOS另行分配 该项功能允许被终止的程序传送一个 返回码 给调用它的程序 假若被终止的程序是由DOS命令调入的 那么返回码可以被DOS批处理命令中的 IFERRORLEVEL 子命令识别 入口参数 AL 返回码 或者不设置 出口参数 无 说明 当用户程序执行1 2 8 9 0AH 0BH OCH功能调用时 如果键入Ctrl C或者Ctrl Break DOS将自动调用INT23H中断处理程序 从而强行使用户程序中断 我们称为响应Ctrl C 4 其它功能的调用 例 人机会话程序 问题 如何设置程序运行所需的数据 有以下几种方法 数据设置在程序的数据段 程序运行时通过人机会话临时键入 程序装入时通过命令行参数给出本例学习前两种方法 并以此学习DOS功能调用 Limai Y N Whatisyourname 1 会话内容及设计思路 Linai 前者是程序给出的询问信息 后者是用户键入的回答 N 程序复制的姓名和回答提示 Limai 再次问答 Linai Y N Whatisyourname Y 2 框图 N DATASEGMENTUSE16MESG1DB0DH 0AHDB Whatisyourname MESG2DB Y N BUFDB30DB DB30DUP DATAENDSCODESEGMENTUSE16ASSUMECS CODE DA DATABEG MOVAX DATAMOVDS AXAGAIN MOVAH 9MOVDX OFFSETMESG1INT21H 询问姓名MOVAH 0AHMOVDX OFFSETBUFINT21H 接收键入字符串MOVBL BUF 1MOVBH 0 486 实际键入的字符个数 BXMOVSI OFFSETBUF 2MOVBYTEPTR BX SI 用 作为串结束符MOVAH 2MOVDL 0AHINT21H 光标下移一行MOVAH 9MOVDX OFFSETBUF 2INT21H 复制键入的字符串MOVAH 9MOVDX OFFSETMESG2INT21H 给出认可信息MOVAH 1INT21H 等待键入CMPAL Y 比较JNEAGAINMOVAH 4CHINT21H 返回DOSCODEENDSENDBEG 3BIOS键盘输入功能调用 自学 主板EPROM中固化有基本I O系统程序 BIOS 它是最接近硬件的驱动程序 BIOS中的许多子程序可被用户程序调用 调用这些子程序称为BIOS功能调用 结构化程序设计顺序结构分枝结构循环机构子程序 顺序结构 486DATASEGMENTUSE16SIGNDB A DATAENDSCODESEGMENTUSE16ASSUMECS CODEBEG MOVAX DATAMOVDS AXMOVAH 2MOVDL SIGNINT21HMOVAH 4CHINT21HCODEENDSENDBEG 1分枝结构 5 5分支程序 例1 二进制数显示将BX寄存器中的内容以二进制数格式 屏显 DOS功能调用 BIOS功能调用 本例令BX 5678H 2 示例 N 数 BX 16次 CX C 0 1 DL 调显示程序 CX 1 CX 0 0 DLBX左移一位 Y N Y 返DOS 解 486CODESEGMENTUSE16ASSUMECS CODEBEG MOVBX 5678HMOVCX 16LAST MOVDL 0 ROLBX 1JNCNEXTMOVDL 1 NEXT MOVAH 2INT21HLOOPLASTMOVAH 4CHINT21HCODEENDSENDBEG 例2 复合分支举例 书例自学 某科室9人 统计月收入在800元 900元间的人数 并用十进制数显示 解 月收入是无符号数 本例对一批数处理使用间接寻址 月收入在800元 900元间的解释 800 月收入 900 486DATASEGMENTUSE16NUMDWXX XXDATAENDSCODESEGMENTUSE16ASSUMECS CODE DS DATABEG MOVAX DATAMOVDS AXMOVBX OFFSETNUMMOVCX 9MOVDL 0LAST CMPWORDPTR BX 800JBNEXT 900转INCDLNEXT INCBXINCBXLOOPLAST ADDDL 30HMOVAH 2INT21HMOVAH 4CHINT21HCODEENDSENDBEG 例3 多分支段内转移要求 键入0 转P0程序段键入1 转P1程序段 键入9 转P9程序段 思路 用比较指令配合直接转移指令实现CMP键入字符 0 JEP0CMP键入字符 1 JEP1 用转移地址表配合间接转移指令实现 486DATASEGMENTUSE16TABDWP0 P1 P9 汇编后自动装入相应的偏移地址MESGDB0DH 0AH strike0 9 DATAENDSCODESEGMENTUSE16ASSUMECS CODE DS DATABEG MOVAX DATAMOVDS AXAGA MOVAH 9MOVDX OFFSETMESGINT21HMOVAH 1INT21HCMPAL 0 JCAGACMPAL 9 JAAGASUBAL 30HMOVZXBX ALADDBX BX 2 BX BXMOVSI OFFSETTAB JMP BX SI DS BX SI IPP0 P1 P9 CODEENDSENDBEG 1 循环程序的结构 5 6循环程序 多体循环 2 结束循环的方法 编程技巧 用寄存器做循环计数器 用主存单元做循环计数器 用循环结束标志结束循环 ASC 码是由7位二进制数表示的 所以可以把ASC 码看成无符号数 例 设从BUF单元开始 存有若干个ASC 码 找出其中表示ASC 码的最大数值送屏幕显示 解法1 486DATASEGMENTUSE16BUFDB QWERTYUIOP123 COUNTEQU BUF 统计串长度MAXDB MAX 0DH 0AH DATAENDSCODESEGMENTUSE16ASSUMECS CODE DS DATABEG MOVAX DATAMOVDS AXMOVAL 0LEABX BUFMOVCX COUNTLAST CMP BX AL 比较JBENEXTMOVAL BX 大数 ALNEXT INCBXLOOPLAST 循环计数MOVMAX 4 AL MOVAH 9MOVDX OFFSETMAXINT21H 显示结果MOVAH 4CHINT21H 返回DOSCODEENDSENDBEG 解法2 486DATASEGMENTUSE16BUFDB QWERTYUIOP123 FLAGDB 1 设置串结束标志MAXDB MAX 0DH 0AH DATAENDSCODESEGMENTUSE16ASSUMECS CODE DS DATABEG MOVAX DATAMOVDS AXMOVAL 0LEABX BUFLAST CMPBYTEPTR BX 1JEDISP 是 转CMP BX ALJNANEXTMOVAL BX NEXT INCBXJMPLASTDISP MOVMAX 4 AL MOVAH 9MOVDX OFFSETMAXINT21H 显示结果MOVAH 4CHINT21H 返回DOSCODEENDSENDBEG 5 7子程序及其调用 子程序是相对独立的程序 当程序中要多次完成某一操作时 为了简化整体程序 增强程序可读性 常常把 完成某一操作 设计成一个子程序 供调用 向子程序传递参数的方法 通过寄存器传递参数 利用堆栈区传递参数 利用主存单元传递参数 子程序用PROC ENDP定界 子程序分为 段内子程序 段间子程序 无参数子程序 有参数子程序 例 无参数子程序 CODESEGMENT CALLCRLF CALLCRLF CRLFPROCMOVAH 2MOVDL 0DHINT21HMOVAH 2MOVDL 0AHINT21HRETCRLFENDPCODEENDS 例 用寄存器传递参数 数据段 MESG1DB PleaseEnter0 9 MESG2DB Strikeanykey 0DH 0AH 例 设N1 1122H N2 3344H N3 5566H用子程序调用的方法实现3个数的累加和 解法1 编程技巧 把数据单元的偏移地址传送给计算累加和的子程序 CODESEGMENTUSE16ASSUMECS CODEASSUMEDS DATA SS STACK BEG MOVAX DATAMOVDS AXMOVSI OFFSETNUM 参数指针 SICALLCOMPUTEXYZ CALLDISPEXIT MOVAH 4CHINT21H COMPUTEPROCMOVBX 0ADDBX SI 0 BX N1 BXADDBX SI 2 BX N2 BXADDBX SI 4 BX N3 BXRET 返断点XYZCOMPUTEENDP DISPPROC 显示BX内容MOVCX 16LAST MOVDL 0 RCLBX 1JNCNEXTMOVDL 1 NEXT MOVAH 2INT21HLOOPLASTRET 返断点EXITDISPENDPCODEENDSENDBEG 解法2 编程技巧 调用前先把数据压栈 计算累加和的子程序从堆栈中取数 完成累加和 486DATASEGMENTUSE16NUMDW1122H N1DW3344H N2DW5566H N3DATAENDSSTACK SEGMENTSTACK STACK USE16DB100DUP STACK ENDSCODESEGMENTUSE16ASSUMECS CODE DS DATA SS STACK 程序清单 BEG MOVAX DATAMOVDS AXMOVSI OFFSETNUM N1 N2 N3压栈PUSHWORDPTR SI 0 PUSHWORDPTR SI 2 PUSHWORDPTR SI 4 CALLCOMPUTEXYZ CALLDISPEXIT MOVAH 4CHINT21H COMPUTEPROCMOVBP SPMOVBX 0ADDBX BP 2 ADDBX BP 4 ADDBX BP 6 RET6 返断点XYZ 清栈COMPUTEENDP DISPPROC 显示BX内容MOVCX 16LAST MOVDL 0 RCLBX 1ADCDL 0MOVAH 2INT21HLOOPLASTRET 返断点EXITDISPENDPCODEENDSENDBEG 解法3 编程技巧 数据放在代码段 利用主存单元传递数据 COMPUTEPROCMOVBP SP 栈针 BP 断口地址NUM SIMOVSI BP 0 MOVBX 0 BX N1 BXADDBX CS SI 0 BX N2 BXADDBX CS SI 2 BX N3 BXADDBX CS SI 4 弹出原来的断口地址POPAXMOVAX OFFSETXYZPUSHAXRET 返回断点XYZCOMPUTEENDP 显示BX内容DISPPROCMOVCX 16LAST MOVAL 0 RCLBX 1ADCAL 0MOVAH 0EHINT10HLOOPLAST 返回断点EXITRETDISPENDPCODEENDSENDBEG Thesimpler thebetter Thesimpler thebetter Thesimpler thebetter 5 8宏指令与条件汇编 子程序调用可以简化程序 但是如果子程序的参数太多 调用时太麻烦 汇编语言提供了另一种简化的途径 宏指令 宏指令是汇编语言提供的伪指令 是用户自行设计的程序 宏指令有 无参数宏指令 有参数宏指令 宏指令应该先定义后调用 宏指令的定义 可以不在任何逻辑段之中 习惯上放在源程序首部 1 宏定义语句的格式宏指令名字MACRO宏体ENDM 1 无参数宏指令的定义与调用 2 宏指令调用宏指令先行定义之后 在代码段的任何位置 书写 宏指令名字 即完成了调用 3 宏指令的 汇编 汇编时 汇编程序自动用宏体取代宏调用 例 486CRLFMACRO 实现回车换行MOVAH 0EHMOVAL 0DHINT10HMOVAL 0AHINT10HENDMCODESEGMENTUSE16ASSUMECS CODEBEG MOVAH 2MOVDL A INT21HCRLF 汇编时 自动用宏体替换宏指令拷贝一份到这儿 2 有参数的宏指令及其调用格式 宏指令名字MACRO哑元1 哑元2 哑元n 宏体ENDM 调用格式 宏指令名字实元1 实元2 实元n 注意 实元表是一串用逗号 或空格 间隔的立即数 寄存器操作数或者是没有PTR说明符的存储器操作数 汇编时 汇编程序自动地把实元一一对应的赋给哑元 例 定位显示彩色字符串要求置显示器为彩色文本方式 并在 0行5列显示黑底绿色HELLO12行36列显示黑底红色WELCOME 24行66列显示黑底黄色BYE BYE 解 486DISPMACROY X VAR LENGTH COLORMOVAH 13HMOVAL 1MOVBH 0 选择0页显示屏MOVBL COLOR 属性字 颜色值 BLMOVCX LENGTH 串长度 CXMOVDH Y 行号 DHMOVDL X 列号 DLMOVBP OFFSETVAR 串有效地址 BPINT10HENDM EDATASEGMENTUSE16SS1DB HELLO SS2DB WELCOME SS3DB BYE BYE EDATAENDSCODESEGMENTUSE16ASSUMECS CODE ES EDATAMOVAX EDATAMOVES AXMOVAX 3INT10HDISP0 5 SS1 5 2 0行5列显示绿色HELLODISP12 36 SS2 8 4 12行36列显示红色WELCOMEDISP24 66 SS3 7 0EH 24行66列显示黄色BYE BYESCAN MOVAH 1INT16HJZSCAN 等待用户键入 无键入转 MOVAX 2INT10H 恢复80 25黑白文本方式MOVAH 4CHINT21HCODEENDSENDBEG 分析 BIOSINT10H的13H子功能 要求待显字符串在附加段 串首址 ES BP 对哑参数的赋值是在调用指令中完成的 子程序调用能减小目标程序的体积 而宏指令调用则不能减小目标程序的体积 宏指令可以嵌套 3 LOCAL伪指令如果宏体中有分支 转移 则必然有标号 2次以上调用这样的宏体 就会出现标号重复定义的错误 为此汇编语言又提供了一条LOCAL伪指令 应用 用LOCAL定义的标号称为 局部标号 它是宏体中所有标号的集合 局部标号可以和代码段中其他标号重名 宏指令仅被调用1次时 不必使用LOCAL伪指令 例 分组显示8 16 32位二进制数 解 486CRLFMACRO 光标返回下一行始格MOVAH 0EHMOVAL 0DHINT10HMOVAL 0AHINT10HENDM 格式 LOCAL标号1 标号2 标号n 分组显示VAR中的NN位二进制数DISPMACROVAR NNLOCALL1 L2MOVCH NN 4L1 MOVCL 4L2 MOVAL 0 ROLVAR 1ADCAL 0MOVAH 0EHINT10HDECCLJNZL2MOVAL INT10HDECCHJNZL1CRLFENDM CODESEGMENTUSE16ASSUMECS CODENUMDB88HBEG MOVEBX 12345678HDISPBH 8 显示BH中的8位数DISPBX 16 显示BX中的16位数DISPEBX 32 显示EBX中的32位数DISPNUM 8 显示NUM单元中的8位数MOVAH 4CHINT21HCODEENDSENDBEG 4 条件汇编语句 条件汇编是汇编语言提供的伪指令 伪语句 高版本的汇编语言提供了许多格式的条件语句 此处仅介绍最常用 最基本的格式 格式1 IF条件语句集合ELSE语句集合2ENDIF 格式2 IF条件语句集合ENDIF 说明 IF ENDIF是一对定界语句 条件 为逻辑表达式或关系表达式 格式1功能 如果条件成立 汇编语句集合1 如果不成立 汇编语句集合2 格式2功能 如果条件成立 汇编语句集合 否则不汇编 5 9代码转换 常见的代码转换有 二进制数 显示 二进制数 十进制数 显示 二进制数 十六进制数 显示 BCD码数 二进制数 1 二进制数显示 解 486CODESEGMENTUSE16ASSUMECS CODEBEG MOVBX 5678HMOVCX 16LAST MOVDL 0 ROLBX 1JNCNEXTMOVDL 1 NEXT MOVAH 2INT21HLOOPLASTMOVAH 4CHINT21HCODEENDSENDBEG DISPPROCMOVCX 16LAST MOVDL 0 RCLBX 1JNCNEXTMOVDL 1 NEXT MOVAH 2INT21HLOOPLASTRETDISPENDPCODEENDS DISPPROCLAST MOVDL 0 RCLEBX 1JNCNEXTMOVDL 1 NEXT MOVAH 2INT21HLOOPLASTRETDISPENDPCODEENDS 通用的二进制数显示子程序 MOVBX 12HRALEBX 24MOVCX 8CALLDISP MOVBX 1234HRALEBX 16MOVCX 16CALLDISP MOVEBX 12345678HMOVCX 32CALLDISP 例 把键盘输入的一位数 0 9 转换成等值二进数显示 显示的格式要求如下 A PleaseEnter PleaseEnter 9 00001001B 思路 键盘缓冲区中是键入字符的ASC 码 0 9的ASC 码为30H 39H 二进制数每一位代码的判断 本程序采用两种格式设计源程序 一种是EXE文件编程格式 另一种是COM文件编程格式 程序框图 AL 30H BL 屏幕 8 CX 0 屏幕 1 屏幕 CX 1 CX B 屏幕 返回DOS N N 给出操作提示键盘输入 AL AL 0 9 CF CX 0 BL左移一位 Y 显示错误信息 Y 0 1 486DATASEGMENTUSE16MESG1DB PleaseEnter 0DH 0AH MESG2DB Error DATAENDSCODESEGMENTUSE16ASSUMECS CODE DS DATABEG MOVAX DATAMOVDS AXMOVAH 9MOVDX OFFSETMESG1INT21H 显示操作提示MOVAH 1INT21H 等待键入CMPAL 39HJAERROR 9 转CMPAL 30HJBERROR 0 转SUBAL 30HMOVBL AL BL 0 9的二进制数 EXE格式程序清单 MOVAH 2MOVDL INT21HCALLDISPMOVAH 2MOVDL B INT21HJMPEXITERROR MOVAH 9MOVDX OFFSETMESG2INT21H 显示错误信息EXIT MOVAH 4CHINT21H DISPPROC 显示BL中的二进制数MOVCX 8LAST MOVDL 0 RCLBL 1JNCNEXTMOVDL 1 NEXT MOVAH 2INT21HLOOPLASTRETDISPENDPCODEENDSENDBEG COM格式程序清单 486CODESEGMENTUSE16ASSUMECS CODEORG100HSTART JMPBEGMESG1DB PleaseEnter 0DH 0AH MESG2DB Error BEG MOVAH 9MOVDX OFFSETMESG1INT21H 显示操作提示MOVAH 1INT21H 等待键入CMPAL 3AHJNCERROR 9 转CMPAL 30HJCERROR 0 转SUBAL 30H MOVBL AL BL 0 9的二进制数MOVAH 2MOVDL INT21HCALLDISPMOVAH 2MOVDL B INT21HJMPEXITERROR MOVAH 9MOVDX OFFSETMESG2INT21H 显示错误信息EXIT MOVAH 4CHINT21H DISPPROC 显示BL中的二进制数MOVCX 8LAST MOVDL 0 RCLBL 1JNCNEXTMOVDL 1 NEXT MOVAH 2INT21HLOOPLASTRETDISPENDPCODEENDSENDSTART 2 二进制数 十六进制数显示 思路 编程方法 二进数 ACSII码N2 16ASCPROCMOVSI OFFSETBUF 输出缓冲区地址 SIMOVCOUNT 2LAST ROLEDX 4ANDDL 0FHCMPDL 10JCNEXTADDDL 7NEXT ADDDL 30HMOV SI DLINCSI 地址加1DECCOUNT 计数JNZLASTRETN2 16ASCENDPCODEENDSENDBEG MOVDL 9AHSALEDX 24CALLN2 16ASC 二进数 ACSII码N2 16ASCPROCMOVSI OFFSETBUF 输出缓冲区地址 SIMOVCOUNT 4LAST ROLEDX 4ANDDL 0FHCMPDL 10JCNEXTADDDL 7NEXT ADDDL 30HMOV SI DLINCSI 地址加1DECCOUNT 计数JNZLASTRETN2 16ASCENDPCODEENDSENDBEG MOVDX 89ABHSALEDX 16CALLN2 16ASC 例 设从BNUM单元开始 有4个16位的二进制数 要求把它们转换成16进制数 并送屏幕显示 程序清单 486DATASEGMENTUSE16BNUMDW0001001000110100B 1234HDW0101011001111000B 5678HDW0001101000101011B 1A2BHDW0011110001001101B 3C4DHBUFDB4DUP H 输出缓冲区COUNTDB4DATAENDSCODESEGMENTUSE16ASSUMECS CODE DS DATA BEG MOVAX DATAMOVDS AXMOVCX 4MOVBX OFFSETBNUMAGA MOVDX BX SALEDX 16CALLN2 16ASCMOVAH 9MOVDX OFFSETBUFINT21H 显示一个16进数ADDBX 2 地址加2LOOPAGAMOVAH 4CHINT21H 二进数 十六进数ACSII码N2 16ASCPROCMOVSI OFFSETBUF 输出缓冲区地址 SIMOVCOUNT 4LAST ROLEDX 4ANDDL 0FHCMPDL 10JCNEXTADDDL 7NEXT ADDDL 30HMOV SI DLINCSI 地址加1DECCOUNT 计数JNZLASTRETN2 16ASCENDPCODEENDSENDBEG 3 二进制数 十进制数 方法 比较法 恢复余数法 除法 8位二进制数最大为11111111 等值的十进制数为255 因此 比较法的关键是 判断某二进制数 假设为BEN单元的内容 包含几个100 几个10 几个1 1 8位二进制数 十进制数比较法 DL 1 DL BEN 10 BEN BEN 100 N Y BEN 10 N Y DL 1 DL BEN 100 BEN DL 30H 屏幕0 DL DL 30H 屏幕 BEN 30H 屏幕返回DOS 程序清单 486CMPDISPMACRONNLOCALLAST NEXT DL清0MOVDL 0LAST CMPBEN NN 比较JBNEXTINCDL DL加1SUBBEN NNJMPLASTNEXT ADDDL 30HMOVAH 2INT21H 显示ENDM CODESEGMENTUSE16ASSUMECS CODEBENDB10101110B 174BEG CMPDISP100CMPDISP10CMPDISP1MOVAH 4CHINT21HCODEENDSENDBEG 2 恢复余数法 请自学 3 除权值求商 的算法分析 把11110101B 十进制数245 算法 依次用权值100 10 1去除上次的余数 直到余数为0时停止 每次除法所得的商数顺序排列 即为十进制数 例 将NUM单元中的16位二进制数 转换成十进制数显示 思路 16位二进制数 最大为1 1 其等值的十进制数为65535 故应判断NUM单元的数包含几个10000 几个1000 几个100 几个10 几个1 设计一个XX YY并显示商值的宏指令供调用 XX为32位 YY为16为二进制数 程序清单 486DIVIDEMACROXX YYMOVAX XXMOVDX 0MOVCX YY CX为除数DIVCX AX 商 且 1010B DX 余数MOVAH 0EHADDAL 30HINT10HENDMCODESEGMENTUSE16ASSUMECS CODENUMDW65530 汇编后为二进制数BEG DIVIDENUM 10000DIVIDEDX 1000 DX AX为被除数 本题在代码段中设置数据 这是COM格式 EXE格式 如果改为 BEG MOVBX OFFSETNUMDIVIDE BX 10000 是错误的 为什么 DIVIDEDX 100DIVIDEDX 10DIVIDEDX 1MOVAH 4CHINT21HCODEENDSENDBEG 显示一位商值 不能颠倒 分析 应写成 DIVIDECS BX 10000 4 除十取余 的算法分析把11110101 十进制数245 算法 N被 10 10除 商再被 10 10除 直到商数为0时止 每次所得的余数按倒序方式排列显示 编程技巧 每次除法的余数 栈 除法结束后 再从堆栈中依次弹出余数 30H 屏 8位 32位二进制数转换成十进制数 通用的除法求余框图 书p119程序 自学 设N为待转换的8位 32位二进制数 EAX 商 EDX 余数 且余数肯定 1010B统计除法的次数 4 BCD码 二进制数例 4位BCD码数 二进制数显示 算法 设4位BCD码数列为 N3N2N1N0 等值二进制数 N3 1000 N2 100 N1 10 N0 0 10 N3 10 N2 10 N1 10 N0 编程考虑 4位BCD码最大为9999H 等值的二进制数最大为16位 超过8位 而且D15位肯定为0 分离出BCD千位N3 百位N2 十位N1 个位N0 设计一个AX 10 BX AX的子程序供调用 首次调用时 令AX 0 BX N3 共调用4次 则AX中即为等值的二进制数 本例数据放在代码段 本例 因为AX的D15 0 是正的有符号数 所以可用IMUL指令 1 程序模块化的作用在设计大型程序时 为了加快设计速度 把一个大程序分解成若干个有独立功能的子模块分别设计 最后链接成一个大的可执行文件 2 模块的层次结构 符号名是标号 变量名 过程名的 统称 在模块化设计中 往往会有模块之间的调用和转移 因此在一个模块中也会出现另一个模块中的标号 过程名等 又由于在进行模块化程序设计时 容易出现符号名相重的问题 所以在链接时就出现了错误 3 符号名的引用 模块间的参数传送 如何解决上述的问题呢 汇编语言提供了3条支持模块化程序的伪指令 1 PUBLIC伪指令 公用符号名说明语句 格式 PUBLIC符号名 符号名 如 PUBLICNEXT MESG 应用 PUBLIC伪指令应出现在定义了这些符号名的模块上方 功能 通知链接程序 用PUBLIC说明的这些符号是公用的 它们要被其他模块引用 注意 段定义语句中的PUBLIC段参数和PUBLIC伪指令是两回事 PUBLIC段参数 通知链接程序 把不同模块中都有PUBLIC属性的同名段 按照指定的链接顺序 组成一个大的逻辑段 功能 通知汇编程序 用EXTRN说明的这些符号是外部符号名 这些符号及其属性已经在其他模块定义过了 本模块引用 如果不用EXTRN伪指令说明 汇编时给出错误信息 symbolnotdefined符号没定义 应用 EXTRN伪指令 放在引用这些符号名的模块的上方 2 EXTRN伪指令 外部符号名说明语句 格式 EXTRN符号名 属性 符号名 属性 如 EXTRNNEXT FAR MESG BYTE 3 INCLUDE伪指令格式 INCLUDE盘符 路径 文件名 扩展名 应用 宏指令共享和子程序共享时使用 功能 将指定路径上的文件 拷贝一份到本语句的下方 供汇编程序汇编源程序时使用 5 12 2模块化程序的设计考虑1 合理划分模块 尽量减少模块间的调用2 模块之间性质相同的逻辑段 要不要组合 要组合 需采取2项措施待组合的逻辑段 选用相同的段名 选用PUBLIC参数 缺一不可 如 各模块之间的代码段 要不要组合成一个统一的代码段 各模块之间的数据段 要不要组合成一个统一的数据段 这一问题要优先考虑 无外乎两种选择 不组合待组合的逻辑段 选用不同的段名 或者不选用PUBLIC段参数 或者链接参数缺省即可 3 模块之间的转移与调用如果不同模块之间的代码段最后要组合成一个统一的代码段 那么模块之间的转移和调用就是段内转移和段内调用 近过程调用 如果不同模块之间的代码段 链接后仍然是各自独立的代码段 那么模块之间的转移 调用均为段间转移和段间调用 远过程调用 4 不论采用组合形式 还是非组合形式 模块之间只要出现符号名引用 都必须用PUBLIC EXTRN语句对符号名进行说明 键入 1 屏幕中央显示 WelcomeToBeijing 底部显示 Pleasestrikeanykey 击任意键之后 再显示菜单 5 12 3模块化程序设计举例设计一个简易的旅游菜单程序 主菜单界面如下 键入 2 屏幕中央显示 WelcomeToNanjing 底部显示 Pleasestrikeanykey 击任意键之后 再显示菜单 5 12 3模块化程序设计举例设计一个简易的旅游菜单程序 主菜单界面如下 键入 3 返回DOS 5 12 3模块化程序设计举例设计一个简易的旅游菜单程序 主菜单界面如下 1 编程 见书p159 分3个模块 主模块显示主菜单 完成菜单项选择 子模块1 显示 WelcomeToBeijing 子模块2 显示 WelcomeToNanjing 3个模块都有各自的数据段 代码段 链接后 各模块的数据段不组合 各自独立各模块的代码段不组合 各自独立 2程序的框架结构 EXTRNBEG1 FAREXTRNBEG2 FARPUBLICBEG EXTRNBEG FARPUBLICBEG1 EXTRNBEG FARPUBLICBEG2 DATA0SEGMENT DATA0ENDSCODE0SEGMENT BEG MOVAX DATA0MOVDS AX显示菜单 键入1转BEG1 键入2转BEG2 CODE0ENDSENDBEG DATA1SEGMENT DATA1ENDSCODE1SEGMENT BEG1 MOVAX DATA1MOVDS AX显示欢迎词 JMPBEGCODE1ENDSEND DATA2SEGMENT DATA2ENDSCODE2SEGMENT BEG2 MOVAX DATA2MOVDS AX显示欢迎词 JMPBEGCODE2ENDSEND 注意 解法1的特点是 主模块 子模块1 子模块2的汇编结束语句不同 模块之间 数据段段名不同 没有PUBLIC段参数 所以各模块数据段是独立的 模块之间 代码段段名不同 没有PUBLIC段参数 所以各模块代码段是独立的 因此模块间的转移是段间转移 各模块上方用PUBLIC EXTRN说明了符号名的引用情况 解法1主模块 486PUBLICBEGEXTRNBEG1 FAR BEG2 FARDISPMACROYYXX VARMOVAH 2MOVBH 0MOVDX YYXXINT10HMOVAH 9MOVDX OFFSETVARINT21HENDMDATA0SEGMENTUSE16NEQU28DUP L1DBN MENU 0DH 0AHDBN 0DH 0AHDBN 1 BeiJing 0DH 0AHDBN 2 NanJing 0DH 0AHDBN 3 RetrunDOS 0DH 0AHDBN 0DH 0AHL7DBN Chioce 1 2 3 DATA0ENDS CODE0SEGMENT CODE USE16ASSUMECS CODE0 DS DATA0BEG MOVAX DATA0MOVDS AXMOVAX 2INT10HDISP0500H L1AGA DISP0B00H L7MOVAH 1INT21HCMPAL 3 JEEXITCMPAL 1 JEBEG1CMPAL 2 JEBEG2JMPAGAEXIT MOVAH 4CHINT21HCODE0ENDSENDBEG 解法1子模块1 486PUBLICBEG1EXTRNBEG FARDISPMACROYYXX VAR同解法1主模块ENDMDATA1SEGMENTUSE16MESG1DB WelcomeToBeiJing ENDMESGDB Pleasestrikeanykey DATA1ENDS CODE1SEGMENT CODE USE16ASSUMECS CODE1 DS
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年秋河大版(三起)(新教材)小学信息科技第三册期末综合测试卷及答案
- 信息安全长图课件
- 汛期安全培训课件
- 国家基本公共卫生服务项目规范培训考试(第一季度)
- 医护普法考试多选答案
- 2025年装配钳工(高级)职业技能鉴定模拟试题
- 三级安全教育钢筋工试题
- 医院信息科考试试题大全(附答案)
- 2025年设备监理师职业资格考试案例分析重点解析卷
- 大学化妆品创业计划书
- 美导下店标准化流程
- 生产保密配方管理办法
- 草莓授粉培训课件图片
- 建筑企业安全生产目标责任书范本
- 阴式手术的围手术期护理
- 书法机构印章管理制度
- 铁路调车员岗前培训
- 物业管理居间合同协议书
- 中医基础阴阳学说课件
- 冷链设施设备验证与校准培训课件
- 小学素养大赛考试参考题库300题(含各题型)
评论
0/150
提交评论