汇编语言程序设计-第六章_子程序设计.ppt_第1页
汇编语言程序设计-第六章_子程序设计.ppt_第2页
汇编语言程序设计-第六章_子程序设计.ppt_第3页
汇编语言程序设计-第六章_子程序设计.ppt_第4页
汇编语言程序设计-第六章_子程序设计.ppt_第5页
免费预览已结束,剩余110页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第六章 子程序设计,河南师范大学计算机与信息技术学院,2,2019/2/6,本章内容提要,河南师范大学计算机与信息技术学院,3,2019/2/6,6.1 子程序设计,河南师范大学计算机与信息技术学院,4,2019/2/6,子程序,把功能相对独立的程序段单独编写和调试,作为一个相对独立的模块供程序使用,就形成子程序。,子程序可以实现源程序的模块化,可简化源程序结构,可以提高编程效率。,子程序设计要利用过程定义伪指。,参数传递是子程序设计的重点和难点,子程序可以嵌套; 一定条件下,还可以递归和重入,河南师范大学计算机与信息技术学院,5,2019/2/6,模块化程序设计,模块化程序设计方法是按照各部分程序所实现的不同功能把程序划分成多个模块,各个模块在明确各自的功能和相互间的连接约定后,就可以分别编制和调试程序,最后再把它们连接起来,形成一个大程序。,这是一种很好的程序设计方法。,子程序结构就是模块化程序设计的基础。,河南师范大学计算机与信息技术学院,6,2019/2/6,6.1.1 过程定义伪操作,格式: 过程名 proc near|far . 过程名 endp,过程名(子程序名)为符合语法的标识符,是子程序入口的符号地址。,属性: near属性(段内近调用)的过程只能被相同代码段的其他程序调用。 far属性(段间远调用)的过程可以被相同或不同代码段的程序调用。,河南师范大学计算机与信息技术学院,7,2019/2/6,6.1.1 过程定义伪操作,80x86的汇编程序用proc伪操作的类型属性来确定call和ret指令的属性。,对简化段定义格式,在tiny、small、compact、flat模式下,过程的缺省属性为near;在medium、large和huge存储模式下,过程的缺省属性为far。,对完整段定义格式,过程的缺省属性为near。,用户可以在过程定义时用near或far改变缺省属性。,河南师范大学计算机与信息技术学院,8,2019/2/6,6.1.2 子程序的调用和返回,过程的正确执行是由子程序的正确调用和正确返回保证的。,80x86的call和ret指令完成的就是调用和返回的功能。,为了保证正确性:,要正确选择proc的属性; 注意子程序运行期间的堆栈状态。,执行call指令时,要使返回地址入栈; 执行ret指令时,要使返回地址出栈。,河南师范大学计算机与信息技术学院,9,2019/2/6,6.1.3 保存与恢复寄存器,子程序中一般要使用寄存器,除了要带参数返回结果的寄存器(返回参数)外,希望过程的执行不改变其他寄存器的内容。,如果子程序中要使用寄存器,而又不希望改变其原有内容,常用的方法:在子程序开始部分,把将要修改内容的寄存器顺序压栈,在过程最后返回调用程序(又称主程序)之前,再将这些寄存器内容逆序弹出。,常见格式如下所示:,无参数传递的子程序:回车换行,河南师范大学计算机与信息技术学院,10,2019/2/6,6.1.3 保存与恢复寄存器,subt proc nera push ax ;保护寄存器:顺序压入堆栈 push bx ;ax/bx/cx仅是示例 push cx ;过程体 pop cx ;恢复寄存器:逆序弹出堆栈 pop bx pop ax ret ;过程返回 subt endp ;过程结束,河南师范大学计算机与信息技术学院,11,2019/2/6,6.1.4 子程序的参数传递,入口参数(输入参数):主程序提供给子程序。,出口参数(输出参数):子程序返回给主程序。,参数的形式: 数据本身(传值) 数据的地址(传址),传递的方法: 寄存器 变量 地址表 堆栈,多个模块间参数传递问题,河南师范大学计算机与信息技术学院,12,2019/2/6,1. 通过寄存器传递参数,把参数存于约定的寄存器中,可以传值,也可以传地址。,子程序对带有出口参数的寄存器不能保护和恢复(主程序视具体情况进行保护)。,子程序对带有入口参数的寄存器可以保护,也可以不保护;但最好一致。,例6. 3 十进制到十六进制转换程序,河南师范大学计算机与信息技术学院,13,2019/2/6,2. 通过变量传递参数,如过程和调用程序在同一源文件(同一程序模块)中,则过程可直接访问模块中的变量。,主程序和子程序直接采用同一个变量名共享同一个变量,实现参数的传递。,不同模块间共享时,需要声明。,例6.4a 数组累加和、用寄存器传递实现、 用堆栈传递实现,河南师范大学计算机与信息技术学院,14,2019/2/6,3. 通过地址表传递参数,在主存中建立一个地址表,把要传递给子程序的参数都存放在地址表中,然后把地址表的首地址通过寄存器传送到子程序中去。,子程序通过地址表取得所需参数,并把结果存入指定的存储单元中去。,例 6.4b 分别求两数组累加和,河南师范大学计算机与信息技术学院,15,2019/2/6,4. 通过堆栈传递参数,主程序将子程序的入口参数压入堆栈,子程序从堆栈中取出参数。,子程序将出口参数压入堆栈,主程序弹出堆栈取得它们。,例6.4c 求数组累加和,注意:子程序结束时的ret指令,使用带参数返回,目的是在返回主程序后,堆栈能恢复原始状态不变。,河南师范大学计算机与信息技术学院,16,2019/2/6,5. 多个模块间的参数传送问题,将程序分段、采用子程序或宏结构都是进行模块化程序设计。,进行模块化设计时,很多情况下,各程序模块仍有各自的分段,只是通过模块之间的调用工作来进行。这就存在段组合以及参数调用问题。,本节主要介绍调用程序和子程序不在同一个程序模块时,参数传递的方法。,相关内容:,源程序文件的包含 目标模块连接 子程序库,河南师范大学计算机与信息技术学院,17,2019/2/6,(1)源程序文件的包含,把源程序分放在几个文本文件中,在汇编时通过包含伪指令include结合成一体 include 文件名,可将常用的子程序形成.asm汇编语言源文件,可将常用的宏定义存放在.mac宏库文件中,可将常量定义、声明语句组织在.inc包含文件中,例:利用源程序包含方法实现将输入的数据按升序输出 宏库文件 lta.mac 主程序文件 lta.asm 子程序文件 suba.asm,源文件包含的操作步骤: 分别编辑生成各个文件 汇编、连接主程序文件,河南师范大学计算机与信息技术学院,18,2019/2/6,(2)目标代码文件的连接,把常用子程序写成独立的源程序文件,单独汇编,形成子程序的目标文件.obj。,主程序也经过独立汇编之后形成目标文件。,连接程序将所有目标文件连接起来,最终产生可执行文件。,需要遵循的原则:, 声明共用的变量、过程等; 实现正确的段组合; 处理好参数传递问题。,例:利用目标文件连接方法实现将输入的数据按升序输出,模块连接的操作步骤: 分别编辑生成各个文件 分别汇编各个文件 连接各个目标文件,形 成可执行文件,河南师范大学计算机与信息技术学院,19,2019/2/6,声明共用的变量、过程,各个模块间共用的变量、过程等要说明 public 标识符 ,标识符. ;定义标识符的模块使用 extrn 标识符:类型 ,标识符:类型. ;调用标识符的模块使用,标识符是变量名、过程名等。,类型是byte / word / dword(变量)或near / far(过程)。,在一个源程序中,public/extrn语句可以有多条。,各模块间的public/extrn伪操作要互相配对,并且指明的类型互相一致。,河南师范大学计算机与信息技术学院,20,2019/2/6,实现正确的段组合,子程序文件必须定义在代码段中,也可以具有局部的数据变量。,采用简化段定义格式,只要采用相同的存储模式,容易实现正确的近或远调用。,完整段定义格式中,为了实现模块间的段内近调用(near类型),各自定义的段名、类别必须相同,组合类型都是public。实际的程序开发中,各个模块往往由不同的程序员完成,不易实现段同名或类别相同,所以属性定义成远调用(far类型)。,定义数据段时,同样也要注意这个问题。当各个模块的数据段不同时,要正确设置数据段ds寄存器的段基地址。,河南师范大学计算机与信息技术学院,21,2019/2/6,处理好参数传递问题,少量参数可用寄存器或堆栈直接传送数据本身。,大量数据可以安排在缓冲区,用寄存器或堆栈传送数据的存储地址。,还可利用变量传递参数,但是要采用public/extrn声明为公共(全局)变量。,这些也是子程序间的参数传递方法。,外部符号定义 例6.5,各模块之间的参数传递方法 例6.4_n、例6.6、例6.7,河南师范大学计算机与信息技术学院,22,2019/2/6,(3)子程序库的调入,把常用子程序写成独立的源文件,单独汇编形成obj文件后,存入子程序库。,主程序也单独汇编形成obj文件。,主程序连接时,调入子程序库中的子程序模块,产生最终的可执行文件。,例 ltc, 主程序文件 ltc.asm 子程序文件 subc1.asm 子程序文件 subc2.asm 子程序文件 subc3.asm,库文件调入的操作步骤: 分别编辑生成各个文件 分别汇编各个文件 用库管理文件,将子程序模块添加 到库文件(.lib)中 连接主程序,提供库文件,形成可 执行文件,河南师范大学计算机与信息技术学院,23,2019/2/6,6.1.5 增强功能的过程定义伪操作,从masm5.1开始为用户提供增强功能的过程定义伪操作。,格式: 过程名 proc 属性uses寄存器表,参数 过程名 endp,另外,增强功能的过程定义伪操作还可以在过程中定义局部变量。,属性(attributes field)字段由以下几项组成: distance language type visibility prologue,河南师范大学计算机与信息技术学院,24,2019/2/6,属性字段的组成,distance:可以是near或far。与前面说明相同。,languange type:说明当该过程作为某种高级语言程序的子过程时所用的高级语言,如pascal、basic、fortran或c等。如在.model中已说明了所用语言,则此处可省略。,visibility:说明该过程的可见性。可用private或public。 private说明该过程的可见性只能是当前的源文件; public说明该过程允许其他模块调用该过程;为默认值。,prologue:是宏名,允许用户用宏来控制过程的入、出口有关的代码。,注意:如果过程伪操作中使用了参数 字段,但在.model和language type中 都没有指定一种语言类型,则masm 将指示出错。为此,即使过程并不需 要由高级语言调用,也应该指定一种 语言类型。,河南师范大学计算机与信息技术学院,25,2019/2/6,use字段和属性字段,uses字段允许用户指定所需保存和恢复的寄存器表,masm将在过程入口自动生成push指令来保存这些寄存器,并在过程出口的ret指令前自动生成pop指令来恢复这些寄存器。,参数字段的格式:,identifier: type , indentifier: type,允许用户指定该过程所用参数。 identifier给出参数的符号名,type给出参数的类型。 参数之间用逗号隔开。 若参数太多,可使用逗号作为换行符,在下一行继续给出参数。,注意: masm自动把这些参数转换为 bp+4、bp+6的形式。 参数排列顺序。,河南师范大学计算机与信息技术学院,26,2019/2/6,参数排列顺序,参数排列的顺序与所指定的语言类型有关。,pascal、basic和fortran语言是按参数在调用使出现的顺序入栈的;,c语言与上述三种语言的入栈次序相反,它的第一个参数是最后入栈的,所以其第一个参数正好在返回地址上。,如图6.3所示。,例6.4 用增强功能的过程定义伪操作的程序实现,河南师范大学计算机与信息技术学院,27,2019/2/6,局部变量,局部变量是指在过程内部使用的变量。,在过程被调用时在堆栈中建立的,在退出程序时被释放。,如图6.3中所示,在过程调用期间,bp指针的负偏移量区是局部变量区。,masm规定,在过程内可用local为局部变量申请空间。,local语句必须紧跟在过程定义伪操作后,并在任何80x86指令或可以产生任何代码的masm语句之前出现。,它可以定义多个局部变量,如一行写不下,可用逗号作为换行符,并在下一行继续定义。,masm将所定义的变量在堆栈中的bp负偏移区生成空间,并对每个局部变量生成如bp-2,bp-4,等代码。,河南师范大学计算机与信息技术学院,28,2019/2/6,local语句,其格式为:,local vardef , vardef,其中,变量定义可用的格式:,label label:type label count:type,type可以指定任意合法的类型说明。,未指定类型者,masm将使用word。,第三种格式,为用户申请数组提供了方便,如可指定m20:swor,用户可用019的下标来访问该数组。,例6.8 把以ascii形式表示的十进制数转换为二进制数,河南师范大学计算机与信息技术学院,29,2019/2/6,6.2 子程序的嵌套,河南师范大学计算机与信息技术学院,30,2019/2/6,1. 子程序的嵌套,子程序内包含有子程序 的调用就是子程序嵌套 没有什么特殊要求。 来看个例子吧!,河南师范大学计算机与信息技术学院,31,2019/2/6,2. 子程序的递归,当子程序直接或间接地嵌套调用自身时称为递归调用,含有递归调用的子程序称为递归子程序。,递归子程序必须采用寄存器或堆栈传递参数,递归深度受堆栈空间的限制。,例:求阶乘,河南师范大学计算机与信息技术学院,32,2019/2/6,3. 子程序的重入,子程序的重入是指子程序被中断后又被中断服务程序所调用,能够重入的子程序称为可重入子程序。在子程序中,注意利用寄存器和堆栈传递参数和存放临时数据,而不要使用固定的存储单元(变量),就能够实现重入。,子程序的重入不同于子程序的递归。重入是被动地进入,而递归是主动地进入;重入的调用间往往没有关系,而递归的调用间却是密切相关的。递归子程序也是可重入子程序。,河南师范大学计算机与信息技术学院,33,2019/2/6,6.3 子程序举例,例6.9 把十六进制数转换成十进制数的程序。p225,例6.10 一个简单的信息检索系统。p228,例6.11 人名排序程序。p231,例6.12 位串插入程序。p235,阅读程序、看程序框图、加深理解汇编指令、伪指令,河南师范大学计算机与信息技术学院,34,2019/2/6,练习与作业,练习: 6.3、6.4、6.5、6.7、6.9 提交作业: 6.8,河南师范大学计算机与信息技术学院,35,2019/2/6,例6.1 a,调用程序和子程序在同一代码段。 main proc far call sub1 ret main endp ; subr1 proc near ret subr1 endp,一般来说,主过程main应定义为far属性,这是由于把程序的主过程看作dos调用的一个子过程。,河南师范大学计算机与信息技术学院,36,2019/2/6,例6.1 b,main proc far call subr1 ret subr1 proc near ret subr1 endp main endp,过程定义可以嵌套,一个过程定义可以包含多个过程定义。,河南师范大学计算机与信息技术学院,37,2019/2/6,例6.2,用程序和子程序不在同一各代码段内 segx segment subt proc far ret subt endp call subt segx ends ; segy segment call subt segy ends,河南师范大学计算机与信息技术学院,38,2019/2/6,回车换行,;子程序功能:实现光标回车换行 dpcrlf proc ;过程开始 push ax ;保护寄存器ax和dx push dx mov dl , 0dh ;显示回车 mov ah , 2 int 21h mov dl , 0ah ;显示换行 mov ah , 2 int 21h pop dx ;恢复寄存器dx和ax pop ax ret ;子程序返回 dpcrlf endp ;过程结束,河南师范大学计算机与信息技术学院,39,2019/2/6,例6.3-1,要求从键盘取得一个十进制数,然后把该数以十六进制形式在屏幕上显示出来。 子程序decibin实现从键盘取得十进制数,并转换成二进制数的功能; 子程序binihex实现把此二进制数转换成十六进制的形式,并在屏幕上显示出来的功能。 ;* .model small .stack .code .startup,图6.1,河南师范大学计算机与信息技术学院,40,2019/2/6,例6.3-2,reapeat: call decibin call crlf call binihex call crlf jmp reapeat .exit 0 ;- decibin proc near mov bx , 0 newchar: mov ah , 1 int 21h sub al , 30h,图6.1,河南师范大学计算机与信息技术学院,41,2019/2/6,例6.3-3,jl done cmp al , 9d jg exit cbw xchg ax , bx mov cx ,10d mul cx xchg ax , bx add bx , ax jmp newchar done: ret decibin endp,各个子程序之间通过bx寄存器来传送信息,图6.1,河南师范大学计算机与信息技术学院,42,2019/2/6,例6.3-4,;- binihex pro near mov ch , 4 rotate: mov cl , 4 rol bx , cl mov al , bl and al , 0fh add al , 30h cmp al , 3ah jl printit add al , 7h printit:,图6.1,河南师范大学计算机与信息技术学院,43,2019/2/6,例6.3-5,mov dl , al mov ah , 2 int 21h dec ch jnz rotate ret binihex endp ;-crlf proc near mov dl , 0dh mov ah , 2 int 21h,图6.1,河南师范大学计算机与信息技术学院,44,2019/2/6,例6.3-6,mov dl , 0ah mov ah , 2 int 21h ret crlf endp ;- end,图6.1,河南师范大学计算机与信息技术学院,45,2019/2/6,图6.1 十进制到十六进制转换的程序结构,河南师范大学计算机与信息技术学院,46,2019/2/6,例6.4a 用变量传递参数-1,用过程proadd累加数组中的所有元素,并把和(不考虑溢出的可能性)送到指定的存储单元中去。 入口参数: count元素个数, ary数组名(含段地址:偏移地址) 出口参数: sum累加和 ;* .model small .data ary dw 100 dup(?) count dw 100 sum dw ?,用寄存器传递参数实现,用堆栈传递参数实现,河南师范大学计算机与信息技术学院,47,2019/2/6,例6.4a 用变量传递参数-2,.code .startup call near ptr proadd .exit 0 ;- proadd proc near push ax push cx push si lea si , ary mov cx , count xor ax , ax,用寄存器传递参数实现,用堆栈传递参数实现,河南师范大学计算机与信息技术学院,48,2019/2/6,例6.4a 用变量传递参数-3,next: add ax , si add si , 2 loop next mov sum , ax pop si pop cx pop ax ret proadd endp ;- end,用寄存器传递参数实现,用堆栈传递参数实现,河南师范大学计算机与信息技术学院,49,2019/2/6,例6.4a 用寄存器传递参数-1,用寄存器传递参数,过程proadd_n实现累加。 入口参数:cx元素个数, ds:si数组的段地址:偏移地址 出口参数:ax累加和 ;* .code .startup lea si , ary mov cx , count call proadd_n,用变量传递参数实现,用堆栈传递参数实现,河南师范大学计算机与信息技术学院,50,2019/2/6,例6.4a 用寄存器传递参数-2,mov sum , ax .exit 0 ;- proadd_n proc near xor ax , ax next: add ax , si add si , 2 loop next ret proadd_n endp ;- end,用变量传递参数实现,用堆栈传递参数实现,河南师范大学计算机与信息技术学院,51,2019/2/6,例6.4a 用堆栈传递参数-1,用堆栈传递参数,过程proadd_n实现累加 入口参数:顺序压入偏移地址和元素个数 出口参数:ax累加和 ;* .code .startup mov ax , offset ary push ax mov ax , count push ax,用变量传递参数实现,对比例6.4c,注意:堆栈的情况 和语句add sp , 4,用寄存器传递参数实现,河南师范大学计算机与信息技术学院,52,2019/2/6,例6.4a 用堆栈传递参数-2,call proadd_n add sp , 4 mov sum , ax .exit 0 ;- proadd_n proc near push bp mov bp , sp push si push cx mov si , bp+6,用变量传递参数实现,对比例6.4c,注意:堆栈的情况 和语句add sp , 4,用寄存器传递参数实现,河南师范大学计算机与信息技术学院,53,2019/2/6,例6.4a 用堆栈传递参数-3,mov cx , bp+4 xor ax , ax next: add ax , si add si , 2 loop next pop cx pop si pop bp ret proadd_n endp ;- end,用变量传递参数实现,对比例6.4c,注意:堆栈的情况 和语句add sp , 4,用寄存器传递参数实现,河南师范大学计算机与信息技术学院,54,2019/2/6,堆栈区及参数,河南师范大学计算机与信息技术学院,55,2019/2/6,例6.4b-1,;主程序两次调用proadd,分别累加ary和num数组的内容。 ;建立首地址为table的地址表,分两次,分别将ary的首地址、元素个数、sum的偏移地址;num的首地址、元素个数、total的偏移地址存放在地址表中。每次调用proadd前,将table首地址送给bx,子程序通过bx取得地址表里的参数。 ;* .model tiny .code .startup,河南师范大学计算机与信息技术学院,56,2019/2/6,例6.4b-2,mov table , offset ary mov table+2 , offset count mov table+4 , offset sum mov bx , offset table call proadd mov table , offset num mov table+2 , offset n mov table+4 , offset total mov bx , offset table call proadd .exit 0 ;-,河南师范大学计算机与信息技术学院,57,2019/2/6,例6.4b-3,proadd proc near push ax push cx push si push di mov si , bx mov di , bx+2 mov cx , di mov di , bx+4 xor ax , ax next: add ax , si add si , 2,河南师范大学计算机与信息技术学院,58,2019/2/6,例6.4b-4,loop next mov di , ax pop di pop si pop cx pop ax ret proadd endp ;-,河南师范大学计算机与信息技术学院,59,2019/2/6,例6.4b-5,ary dw 100 dup(?) count dw 100 sum dw ? ; num dw 100 dup(?) n dw 100 total dw ? ; table dw 3 dup(?) ;- end,河南师范大学计算机与信息技术学院,60,2019/2/6,例6.4c-1,.mode small .stack dw 100 dup(?) tos lable word .data ary dw 100 dup(?) count dw 100 sum dw ? .code .startup,对比例6.4a,注意堆栈的情况 和返回语句ret 6,河南师范大学计算机与信息技术学院,61,2019/2/6,例6.4c-2,mov bx , offset ary push bx mov bx , offset count push bx mov bx , offset sum push bx call proadd .exit 0,注意堆栈的情况 和返回语句ret 6,对比例6.4a,河南师范大学计算机与信息技术学院,62,2019/2/6,例6.4c-3,poradd proc far push bp mov bp , sp push ax push cx push si push di mov si , bp+0ah mov di , bp+8 mov cx , di mov di , bp+6,注意堆栈的情况 和返回语句ret 6,对比例6.4a,河南师范大学计算机与信息技术学院,63,2019/2/6,例6.4c-4,xor ax , ax next: add ax , si add si , 2 loop next mov di , ax pop di pop si pop cx pop ax pop bp ret 6 endp end,注意堆栈的情况 和返回语句ret 6,对比例6.4a,河南师范大学计算机与信息技术学院,64,2019/2/6,图6.2 堆栈最满时的状态,主程序实现平衡堆栈: add sp,n 子程序实现平衡堆栈: ret n,河南师范大学计算机与信息技术学院,65,2019/2/6,宏库文件lta.mac,dispchar macro char ;显示char字符 mov dl , char mov ah , 2 int 21h endm ;显示message字符串 dispmsg macro message mov dx , offset message mov ah , 9 int 21h endm,河南师范大学计算机与信息技术学院,66,2019/2/6,主程序文件lta.asm-1,include lt512a.mac .model small .stack .data .code .startup dispmsg msg1 ;提示输入数据 mov bx , offset buf call input ;数据输入,河南师范大学计算机与信息技术学院,67,2019/2/6,主程序文件lta.asm-1,cmp cx , 0 je start4 ;没有输入数据则退出 mov count , cx . ;显示输入的数据 . ;数据排序 . ;显示经排序后的数据 start4: .exit 0 include sub512a.asm end,河南师范大学计算机与信息技术学院,68,2019/2/6,子程序源文件suba.asm,子程序源文件有3个子程序: aldisp ;显示2位16进制数子程序(例5.7或例5.8) sorting ;排序子程序(例5.1) input ;键盘输入子程序 还包含一个宏: convert ;将dx两位ascii码转换为两位16进制数,让我们重点分析键盘输入子程序 input。,河南师范大学计算机与信息技术学院,69,2019/2/6,input.asm-1,;键盘输入子程序 ;入口参数:ds:bx=存放数据的缓冲区 ;出口参数:cx=数据个数 input proc push ax push dx xor cx , cx ;数据个数清0 input01: xor dx , dx ;输入字符清0 input02: mov ah , 1 ;键盘输入一个字符 int 21h,河南师范大学计算机与信息技术学院,70,2019/2/6,input.asm-2,input10: cmp al , 0dh je input30 ;是回车,结束整个数据的输入 cmp al , je input20 ;是空格和逗号,确认输入了一个数据 cmp al , , je input20 cmp al , 08h je input17 ;是退格,丢弃本次输入的数据,出错,河南师范大学计算机与信息技术学院,71,2019/2/6,input.asm-3,cmp al , 0 ;有效数字判断 ;小于0,不是有效数字,出错 jb input17 cmp al , f ja input17 ;大于f,不是有效数字 cmp al , a jb input11 ;af转换成大写af sub al , 20h jmp input12,河南师范大学计算机与信息技术学院,72,2019/2/6,input.asm-4,input11: cmp al , f ;字符小于a、大于f,出错 ja input17 cmp al , a jae input12 ;是af,有效字符 cmp al , 9 ja input17 ;是09,有效字符 input12: cmp dl , 0 ;有效字符的处理 jne input13 mov dl , al,河南师范大学计算机与信息技术学院,73,2019/2/6,input.asm-5,;dl=0,输入了一个数据的低位,则dlal jmp input02 ;转到字符输入 input13: cmp dh , 0 jne input17 ;dl0,dh0输入3位数据,出错 mov dh , dl ;dl0,dh0输入了一个数据的高位 mov dl , al ;dhdl,dlal jmp input02 ;转到字符输入,河南师范大学计算机与信息技术学院,74,2019/2/6,input.asm-6,input17: mov dl , 7 ;输入错误处理 mov ah , 2 int 21h mov dl , ? mov ah , 2 int 21h jmp input01 ;转到输入一个数据,河南师范大学计算机与信息技术学院,75,2019/2/6,input.asm-7,;转换正确的输入数据 input20: convert jmp input01 ;转到输入一个数据 input30: convert pop dx pop ax ret ;返回,出口参数已设定 input endp,河南师范大学计算机与信息技术学院,76,2019/2/6,convert.asm-1,;将dx两位ascii码转换为两位16进制数 convert macro local input21 , input22 local input24 , input25 cmp dl , 0 ;dl=0,没有要转换的数据,退出 je input25 cmp dl , 9 jbe input21 sub dl , 7 ;字符af,则减7,河南师范大学计算机与信息技术学院,77,2019/2/6,convert.asm-2,input21: and dl , 0fh ;转换低位 cmp dh , 0 ;dh=0,没有高位数据 je input24 cmp dh , 9 jbe input22 sub dh , 7 input22: shl dh , 1 shl dh , 1 shl dh , 1 shl dh , 1 ;转换高位 or dl , dh ;合并高、低位,河南师范大学计算机与信息技术学院,78,2019/2/6,convert.asm-3,input24: mov bx , dl ;存入缓冲区 inc bx inc cx ;数据加1 input25: endm,河南师范大学计算机与信息技术学院,79,2019/2/6,例6.5-1,;* .model small .data var1 db ? var2 dw ? var3 dw ? .code extrn var2:word , lab2:far public var1 , lab1 .startup,河南师范大学计算机与信息技术学院,80,2019/2/6,例6.5-2, lab1: .exit 0 end ;* .model small .data var2 dw 0 var3 db 5 dup(?) .code extrn var1:byte , var4:word public var2,河南师范大学计算机与信息技术学院,81,2019/2/6,例6.5-3,.startup .exit 0 end ;* .model small .code extrn lab1:far public lab2 , lab3 .startup ,河南师范大学计算机与信息技术学院,82,2019/2/6,例6.5-4,lab2: lab3: .exit 0 end,连接程序可分配段地址、确定 外部符号及浮动地址值,连接 完成后建立装入模块,再由装入 程序把该模块装入内存等待执行。,河南师范大学计算机与信息技术学院,83,2019/2/6,例6.4_n-1,主程序和子程序不在同一模块时 ;* .model small .data ary dw 100 dup(?) count dw 100 sum dw ? .code extrn proadd:far .startup call far ptr proadd .exit 0 end,河南师范大学计算机与信息技术学院,84,2019/2/6,例6.4_n-2,;* .model small .data ary dw 100 dup(?) count dw 100 sum dw ? .code public proadd .startup ;-,河南师范大学计算机与信息技术学院,85,2019/2/6,例6.4_n-3,proadd proc far push ax push cx push si lea si , ary mov cx , count xor ax , ax next: add ax , si add si , 2 loop next mov sum , ax,河南师范大学计算机与信息技术学院,86,2019/2/6,例6.4_n-4,pop si pop cx pop ax ret proadd endp ;- end,河南师范大学计算机与信息技术学院,87,2019/2/6,例6.6-1,;模块1本身的局部变量都在ds段中,而外部变量则在es段中,在程序中动态地改变es寄存器的内容,以达到正确访问各外部变量的目的。 ;如果源模块1本身使用es段,或者外部变量较多,为避免动态改变段地址易产生的错误,也可以用例6.7所使用的办法。 ;* .model small .data var dw 5 ,河南师范大学计算机与信息技术学院,88,2019/2/6,例6.6-2,.code extrn var1:word , output:far extrn var2:word public done .startup mov ax , seg var2 mov es , ax sub es:var2 , 50 jmp output ,河南师范大学计算机与信息技术学院,89,2019/2/6,例6.6-3,done: .exit 0 end ;* .model small .data var1 dw 10 .code public var1 .startup .exit 0 end ;*,河南师范大学计算机与信息技术学院,90,2019/2/6,例6.6-4,.model small .data var2 dw 3 .code public var2 , output extrn done:far .startup output: jmp done .exit 0 end,河南师范大学计算机与信息技术学院,91,2019/2/6,例6.7-1,;* .model small .data .code extrn var1:word , var2:word .startup mov ax , ds mov es , ax mov bx , es:var1 add es:var2 , bx ,河南师范大学计算机与信息技术学院,92,2019/2/6,例6.7-2,.exit 0 end ;* .model small .data var1 dw ? var2 dw ? .code public var1 , var2 .startup .exit 0 end,河南师范大学计算机与信息技术学院,93,2019/2/6,例ltc.asm,. ;宏定义 .code extrn aldisp:near,sorting:near,input:near ;声明其他模块中的子程序 .startup . .exit 0 end,河南师范大学计算机与信息技术学院,94,2019/2/6,例subc1.asm,.model small .code public aldisp aldisp proc . aldisp endp end,河南师范大学计算机与信息技术学院,95,2019/2

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论