汇编语言程序设计-第六章_子程序设计.ppt

上传人:yyf 文档编号:5029005 上传时间:2020-01-29 格式:PPT 页数:115 大小:518.50KB
返回 下载 相关 举报
汇编语言程序设计-第六章_子程序设计.ppt_第1页
第1页 / 共115页
汇编语言程序设计-第六章_子程序设计.ppt_第2页
第2页 / 共115页
汇编语言程序设计-第六章_子程序设计.ppt_第3页
第3页 / 共115页
汇编语言程序设计-第六章_子程序设计.ppt_第4页
第4页 / 共115页
汇编语言程序设计-第六章_子程序设计.ppt_第5页
第5页 / 共115页
点击查看更多>>
资源描述

《汇编语言程序设计-第六章_子程序设计.ppt》由会员分享,可在线阅读,更多相关《汇编语言程序设计-第六章_子程序设计.ppt(115页珍藏版)》请在三一文库上搜索。

1、第六章 子程序设计,河南师范大学计算机与信息技术学院,2,2020/1/29,本章内容提要,河南师范大学计算机与信息技术学院,3,2020/1/29,6.1 子程序设计,河南师范大学计算机与信息技术学院,4,2020/1/29,子程序,把功能相对独立的程序段单独编写和调试,作为一个相对独立的模块供程序使用,就形成子程序。,子程序可以实现源程序的模块化,可简化源程序结构,可以提高编程效率。,子程序设计要利用过程定义伪指。,参数传递是子程序设计的重点和难点,子程序可以嵌套; 一定条件下,还可以递归和重入,河南师范大学计算机与信息技术学院,5,2020/1/29,模块化程序设计,模块化程序设计方法是

2、按照各部分程序所实现的不同功能把程序划分成多个模块,各个模块在明确各自的功能和相互间的连接约定后,就可以分别编制和调试程序,最后再把它们连接起来,形成一个大程序。,这是一种很好的程序设计方法。,子程序结构就是模块化程序设计的基础。,河南师范大学计算机与信息技术学院,6,2020/1/29,6.1.1 过程定义伪操作,格式: 过程名 proc near|far . 过程名 endp,过程名(子程序名)为符合语法的标识符,是子程序入口的符号地址。,属性: NEAR属性(段内近调用)的过程只能被相同代码段的其他程序调用。 FAR属性(段间远调用)的过程可以被相同或不同代码段的程序调用。,河南师范大学

3、计算机与信息技术学院,7,2020/1/29,6.1.1 过程定义伪操作,80x86的汇编程序用PROC伪操作的类型属性来确定CALL和RET指令的属性。,对简化段定义格式,在TINY、SMALL、COMPACT、FLAT模式下,过程的缺省属性为near;在MEDIUM、LARGE和HUGE存储模式下,过程的缺省属性为far。,对完整段定义格式,过程的缺省属性为near。,用户可以在过程定义时用near或far改变缺省属性。,河南师范大学计算机与信息技术学院,8,2020/1/29,6.1.2 子程序的调用和返回,过程的正确执行是由子程序的正确调用和正确返回保证的。,80x86的CALL和RE

4、T指令完成的就是调用和返回的功能。,为了保证正确性:,要正确选择PROC的属性; 注意子程序运行期间的堆栈状态。,执行CALL指令时,要使返回地址入栈; 执行RET指令时,要使返回地址出栈。,河南师范大学计算机与信息技术学院,9,2020/1/29,6.1.3 保存与恢复寄存器,子程序中一般要使用寄存器,除了要带参数返回结果的寄存器(返回参数)外,希望过程的执行不改变其他寄存器的内容。,如果子程序中要使用寄存器,而又不希望改变其原有内容,常用的方法:在子程序开始部分,把将要修改内容的寄存器顺序压栈,在过程最后返回调用程序(又称主程序)之前,再将这些寄存器内容逆序弹出。,常见格式如下所示:,无参

5、数传递的子程序:回车换行,河南师范大学计算机与信息技术学院,10,2020/1/29,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,2020/1/29,6.1.4 子程序的参数传递,入口参数(输入参数):主程序提供给子程序。,出口参数(输出参数):子程序返回给主程序。,参数的形式: 数据本身(传值) 数据的地

6、址(传址),传递的方法: 寄存器 变量 地址表 堆栈,多个模块间参数传递问题,河南师范大学计算机与信息技术学院,12,2020/1/29,1. 通过寄存器传递参数,把参数存于约定的寄存器中,可以传值,也可以传地址。,子程序对带有出口参数的寄存器不能保护和恢复(主程序视具体情况进行保护)。,子程序对带有入口参数的寄存器可以保护,也可以不保护;但最好一致。,例6. 3 十进制到十六进制转换程序,河南师范大学计算机与信息技术学院,13,2020/1/29,2. 通过变量传递参数,如过程和调用程序在同一源文件(同一程序模块)中,则过程可直接访问模块中的变量。,主程序和子程序直接采用同一个变量名共享同一

7、个变量,实现参数的传递。,不同模块间共享时,需要声明。,例6.4a 数组累加和、用寄存器传递实现、 用堆栈传递实现,河南师范大学计算机与信息技术学院,14,2020/1/29,3. 通过地址表传递参数,在主存中建立一个地址表,把要传递给子程序的参数都存放在地址表中,然后把地址表的首地址通过寄存器传送到子程序中去。,子程序通过地址表取得所需参数,并把结果存入指定的存储单元中去。,例 6.4b 分别求两数组累加和,河南师范大学计算机与信息技术学院,15,2020/1/29,4. 通过堆栈传递参数,主程序将子程序的入口参数压入堆栈,子程序从堆栈中取出参数。,子程序将出口参数压入堆栈,主程序弹出堆栈取

8、得它们。,例6.4c 求数组累加和,注意:子程序结束时的RET指令,使用带参数返回,目的是在返回主程序后,堆栈能恢复原始状态不变。,河南师范大学计算机与信息技术学院,16,2020/1/29,5. 多个模块间的参数传送问题,将程序分段、采用子程序或宏结构都是进行模块化程序设计。,进行模块化设计时,很多情况下,各程序模块仍有各自的分段,只是通过模块之间的调用工作来进行。这就存在段组合以及参数调用问题。,本节主要介绍调用程序和子程序不在同一个程序模块时,参数传递的方法。,相关内容:,源程序文件的包含 目标模块连接 子程序库,河南师范大学计算机与信息技术学院,17,2020/1/29,(1)源程序文

9、件的包含,把源程序分放在几个文本文件中,在汇编时通过包含伪指令INCLUDE结合成一体 INCLUDE 文件名,可将常用的子程序形成.ASM汇编语言源文件,可将常用的宏定义存放在.MAC宏库文件中,可将常量定义、声明语句组织在.INC包含文件中,例:利用源程序包含方法实现将输入的数据按升序输出 宏库文件 lta.mac 主程序文件 lta.asm 子程序文件 suba.asm,源文件包含的操作步骤: 分别编辑生成各个文件 汇编、连接主程序文件,河南师范大学计算机与信息技术学院,18,2020/1/29,(2)目标代码文件的连接,把常用子程序写成独立的源程序文件,单独汇编,形成子程序的目标文件.

10、OBJ。,主程序也经过独立汇编之后形成目标文件。,连接程序将所有目标文件连接起来,最终产生可执行文件。,需要遵循的原则:, 声明共用的变量、过程等; 实现正确的段组合; 处理好参数传递问题。,例:利用目标文件连接方法实现将输入的数据按升序输出,模块连接的操作步骤: 分别编辑生成各个文件 分别汇编各个文件 连接各个目标文件,形 成可执行文件,河南师范大学计算机与信息技术学院,19,2020/1/29,声明共用的变量、过程,各个模块间共用的变量、过程等要说明 PUBLIC 标识符 ,标识符. ;定义标识符的模块使用 EXTRN 标识符:类型 ,标识符:类型. ;调用标识符的模块使用,标识符是变量名

11、、过程名等。,类型是byte / word / dword(变量)或near / far(过程)。,在一个源程序中,public/extrn语句可以有多条。,各模块间的public/extrn伪操作要互相配对,并且指明的类型互相一致。,河南师范大学计算机与信息技术学院,20,2020/1/29,实现正确的段组合,子程序文件必须定义在代码段中,也可以具有局部的数据变量。,采用简化段定义格式,只要采用相同的存储模式,容易实现正确的近或远调用。,完整段定义格式中,为了实现模块间的段内近调用(near类型),各自定义的段名、类别必须相同,组合类型都是public。实际的程序开发中,各个模块往往由不同的

12、程序员完成,不易实现段同名或类别相同,所以属性定义成远调用(far类型)。,定义数据段时,同样也要注意这个问题。当各个模块的数据段不同时,要正确设置数据段DS寄存器的段基地址。,河南师范大学计算机与信息技术学院,21,2020/1/29,处理好参数传递问题,少量参数可用寄存器或堆栈直接传送数据本身。,大量数据可以安排在缓冲区,用寄存器或堆栈传送数据的存储地址。,还可利用变量传递参数,但是要采用public/extrn声明为公共(全局)变量。,这些也是子程序间的参数传递方法。,外部符号定义 例6.5,各模块之间的参数传递方法 例6.4_n、例6.6、例6.7,河南师范大学计算机与信息技术学院,2

13、2,2020/1/29,(3)子程序库的调入,把常用子程序写成独立的源文件,单独汇编形成OBJ文件后,存入子程序库。,主程序也单独汇编形成OBJ文件。,主程序连接时,调入子程序库中的子程序模块,产生最终的可执行文件。,例 ltc, 主程序文件 ltc.asm 子程序文件 subc1.asm 子程序文件 subc2.asm 子程序文件 subc3.asm,库文件调入的操作步骤: 分别编辑生成各个文件 分别汇编各个文件 用库管理文件,将子程序模块添加 到库文件(.LIB)中 连接主程序,提供库文件,形成可 执行文件,河南师范大学计算机与信息技术学院,23,2020/1/29,6.1.5 增强功能的

14、过程定义伪操作,从MASM5.1开始为用户提供增强功能的过程定义伪操作。,格式: 过程名 PROC 属性USES寄存器表,参数 过程名 ENDP,另外,增强功能的过程定义伪操作还可以在过程中定义局部变量。,属性(attributes field)字段由以下几项组成: distance language type visibility prologue,河南师范大学计算机与信息技术学院,24,2020/1/29,属性字段的组成,distance:可以是NEAR或FAR。与前面说明相同。,languange type:说明当该过程作为某种高级语言程序的子过程时所用的高级语言,如PASCAL、BAS

15、IC、FORTRAN或C等。如在.model中已说明了所用语言,则此处可省略。,visibility:说明该过程的可见性。可用private或public。 Private说明该过程的可见性只能是当前的源文件; Public说明该过程允许其他模块调用该过程;为默认值。,Prologue:是宏名,允许用户用宏来控制过程的入、出口有关的代码。,注意:如果过程伪操作中使用了参数 字段,但在.model和language type中 都没有指定一种语言类型,则MASM 将指示出错。为此,即使过程并不需 要由高级语言调用,也应该指定一种 语言类型。,河南师范大学计算机与信息技术学院,25,2020/1/

16、29,USE字段和属性字段,USES字段允许用户指定所需保存和恢复的寄存器表,MASM将在过程入口自动生成PUSH指令来保存这些寄存器,并在过程出口的ret指令前自动生成POP指令来恢复这些寄存器。,参数字段的格式:,identifier: type , indentifier: type,允许用户指定该过程所用参数。 Identifier给出参数的符号名,type给出参数的类型。 参数之间用逗号隔开。 若参数太多,可使用逗号作为换行符,在下一行继续给出参数。,注意: MASM自动把这些参数转换为 BP+4、BP+6的形式。 参数排列顺序。,河南师范大学计算机与信息技术学院,26,2020/1

17、/29,参数排列顺序,参数排列的顺序与所指定的语言类型有关。,PASCAL、BASIC和FORTRAN语言是按参数在调用使出现的顺序入栈的;,C语言与上述三种语言的入栈次序相反,它的第一个参数是最后入栈的,所以其第一个参数正好在返回地址上。,如图6.3所示。,例6.4 用增强功能的过程定义伪操作的程序实现,河南师范大学计算机与信息技术学院,27,2020/1/29,局部变量,局部变量是指在过程内部使用的变量。,在过程被调用时在堆栈中建立的,在退出程序时被释放。,如图6.3中所示,在过程调用期间,BP指针的负偏移量区是局部变量区。,MASM规定,在过程内可用LOCAL为局部变量申请空间。,LOC

18、AL语句必须紧跟在过程定义伪操作后,并在任何80x86指令或可以产生任何代码的MASM语句之前出现。,它可以定义多个局部变量,如一行写不下,可用逗号作为换行符,并在下一行继续定义。,MASM将所定义的变量在堆栈中的BP负偏移区生成空间,并对每个局部变量生成如BP-2,BP-4,等代码。,河南师范大学计算机与信息技术学院,28,2020/1/29,LOCAL语句,其格式为:,LOCAL vardef , vardef,其中,变量定义可用的格式:,label label:type label count:type,type可以指定任意合法的类型说明。,未指定类型者,MASM将使用WORD。,第三种

19、格式,为用户申请数组提供了方便,如可指定M20:swor,用户可用019的下标来访问该数组。,例6.8 把以ASCII形式表示的十进制数转换为二进制数,河南师范大学计算机与信息技术学院,29,2020/1/29,6.2 子程序的嵌套,河南师范大学计算机与信息技术学院,30,2020/1/29,1. 子程序的嵌套,子程序内包含有子程序 的调用就是子程序嵌套 没有什么特殊要求。 来看个例子吧!,河南师范大学计算机与信息技术学院,31,2020/1/29,2. 子程序的递归,当子程序直接或间接地嵌套调用自身时称为递归调用,含有递归调用的子程序称为递归子程序。,递归子程序必须采用寄存器或堆栈传递参数,

20、递归深度受堆栈空间的限制。,例:求阶乘,河南师范大学计算机与信息技术学院,32,2020/1/29,3. 子程序的重入,子程序的重入是指子程序被中断后又被中断服务程序所调用,能够重入的子程序称为可重入子程序。在子程序中,注意利用寄存器和堆栈传递参数和存放临时数据,而不要使用固定的存储单元(变量),就能够实现重入。,子程序的重入不同于子程序的递归。重入是被动地进入,而递归是主动地进入;重入的调用间往往没有关系,而递归的调用间却是密切相关的。递归子程序也是可重入子程序。,河南师范大学计算机与信息技术学院,33,2020/1/29,6.3 子程序举例,例6.9 把十六进制数转换成十进制数的程序。P2

21、25,例6.10 一个简单的信息检索系统。P228,例6.11 人名排序程序。P231,例6.12 位串插入程序。P235,阅读程序、看程序框图、加深理解汇编指令、伪指令,河南师范大学计算机与信息技术学院,34,2020/1/29,练习与作业,练习: 6.3、6.4、6.5、6.7、6.9 提交作业: 6.8,河南师范大学计算机与信息技术学院,35,2020/1/29,例6.1 a,调用程序和子程序在同一代码段。 MAIN PROC FAR CALL SUB1 RET MAIN ENDP ; SUBR1 PROC NEAR RET SUBR1 ENDP,一般来说,主过程MAIN应定义为FAR属

22、性,这是由于把程序的主过程看作DOS调用的一个子过程。,河南师范大学计算机与信息技术学院,36,2020/1/29,例6.1 b,MAIN PROC FAR CALL SUBR1 RET SUBR1 PROC NEAR RET SUBR1 ENDP MAIN ENDP,过程定义可以嵌套,一个过程定义可以包含多个过程定义。,河南师范大学计算机与信息技术学院,37,2020/1/29,例6.2,用程序和子程序不在同一各代码段内 SEGX SEGMENT SUBT PROC FAR RET SUBT ENDP CALL SUBT SEGX ENDS ; SEGY SEGMENT CALL SUBT

23、SEGY ENDS,河南师范大学计算机与信息技术学院,38,2020/1/29,回车换行,;子程序功能:实现光标回车换行 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,2020/1/29,例6.3-1,要求从键盘取得一个十进制数,然后把该数以十六进制形

24、式在屏幕上显示出来。 子程序DECIBIN实现从键盘取得十进制数,并转换成二进制数的功能; 子程序BINIHEX实现把此二进制数转换成十六进制的形式,并在屏幕上显示出来的功能。 ;* .model small .stack .code .startup,图6.1,河南师范大学计算机与信息技术学院,40,2020/1/29,例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

25、21h sub al , 30h,图6.1,河南师范大学计算机与信息技术学院,41,2020/1/29,例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,2020/1/29,例6.3-4,;- binihex pro near mov ch , 4 rotate: mov cl , 4 rol b

26、x , cl mov al , bl and al , 0fh add al , 30h cmp al , 3ah jl printit add al , 7h printit:,图6.1,河南师范大学计算机与信息技术学院,43,2020/1/29,例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,2020/1/29,例6.3-6,mov dl , 0a

27、h mov ah , 2 int 21h ret crlf endp ;- end,图6.1,河南师范大学计算机与信息技术学院,45,2020/1/29,图6.1 十进制到十六进制转换的程序结构,河南师范大学计算机与信息技术学院,46,2020/1/29,例6.4a 用变量传递参数-1,用过程PROADD累加数组中的所有元素,并把和(不考虑溢出的可能性)送到指定的存储单元中去。 入口参数: count元素个数, ary数组名(含段地址:偏移地址) 出口参数: sum累加和 ;* .model small .data ary dw 100 dup(?) count dw 100 sum dw ?

28、,用寄存器传递参数实现,用堆栈传递参数实现,河南师范大学计算机与信息技术学院,47,2020/1/29,例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,2020/1/29,例6.4a 用变量传递参数-3,next: add ax , si add si , 2 loop nex

29、t mov sum , ax pop si pop cx pop ax ret proadd endp ;- end,用寄存器传递参数实现,用堆栈传递参数实现,河南师范大学计算机与信息技术学院,49,2020/1/29,例6.4a 用寄存器传递参数-1,用寄存器传递参数,过程PROADD_N实现累加。 入口参数:CX元素个数, DS:SI数组的段地址:偏移地址 出口参数:AX累加和 ;* .code .startup lea si , ary mov cx , count call proadd_n,用变量传递参数实现,用堆栈传递参数实现,河南师范大学计算机与信息技术学院,50,2020/1/

30、29,例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,2020/1/29,例6.4a 用堆栈传递参数-1,用堆栈传递参数,过程PROADD_N实现累加 入口参数:顺序压入偏移地址和元素个数 出口参数:AX累加和 ;* .code .startup mov ax , offset ary push

31、 ax mov ax , count push ax,用变量传递参数实现,对比例6.4c,注意:堆栈的情况 和语句add sp , 4,用寄存器传递参数实现,河南师范大学计算机与信息技术学院,52,2020/1/29,例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,用寄存器传递参数实现,河南师范大

32、学计算机与信息技术学院,53,2020/1/29,例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,2020/1/29,堆栈区及参数,河南师范大学计算机与信息技术学院,55,2020/1/29,例6.4b-1,;主程序两次调用PROADD,分别累加AR

33、Y和NUM数组的内容。 ;建立首地址为TABLE的地址表,分两次,分别将ARY的首地址、元素个数、SUM的偏移地址;NUM的首地址、元素个数、TOTAL的偏移地址存放在地址表中。每次调用PROADD前,将TABLE首地址送给BX,子程序通过BX取得地址表里的参数。 ;* .model tiny .code .startup,河南师范大学计算机与信息技术学院,56,2020/1/29,例6.4b-2,mov table , offset ary mov table+2 , offset count mov table+4 , offset sum mov bx , offset table ca

34、ll proadd mov table , offset num mov table+2 , offset N mov table+4 , offset total mov bx , offset table call proadd .exit 0 ;-,河南师范大学计算机与信息技术学院,57,2020/1/29,例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

35、 si , 2,河南师范大学计算机与信息技术学院,58,2020/1/29,例6.4b-4,loop next mov di , ax pop di pop si pop cx pop ax ret proadd endp ;-,河南师范大学计算机与信息技术学院,59,2020/1/29,例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,2020/1/29,例6.4c-1,.m

36、ode 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,2020/1/29,例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,对比例

37、6.4a,河南师范大学计算机与信息技术学院,62,2020/1/29,例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,2020/1/29,例6.4c-4,xor ax , ax next: add ax , si add si , 2 loop next mov di , ax pop d

38、i pop si pop cx pop ax pop bp ret 6 endp end,注意堆栈的情况 和返回语句RET 6,对比例6.4a,河南师范大学计算机与信息技术学院,64,2020/1/29,图6.2 堆栈最满时的状态,主程序实现平衡堆栈: add sp,n 子程序实现平衡堆栈: ret n,河南师范大学计算机与信息技术学院,65,2020/1/29,宏库文件lta.mac,dispchar macro char ;显示char字符 mov dl , char mov ah , 2 int 21h endm ;显示message字符串 dispmsg macro message m

39、ov dx , offset message mov ah , 9 int 21h endm,河南师范大学计算机与信息技术学院,66,2020/1/29,主程序文件lta.asm-1,include lt512a.mac .model small .stack .data .code .startup dispmsg msg1 ;提示输入数据 mov bx , offset buf call input ;数据输入,河南师范大学计算机与信息技术学院,67,2020/1/29,主程序文件lta.asm-1,cmp cx , 0 je start4 ;没有输入数据则退出 mov count , c

40、x . ;显示输入的数据 . ;数据排序 . ;显示经排序后的数据 start4: .exit 0 include sub512a.asm end,河南师范大学计算机与信息技术学院,68,2020/1/29,子程序源文件suba.asm,子程序源文件有3个子程序: ALdisp ;显示2位16进制数子程序(例5.7或例5.8) sorting ;排序子程序(例5.1) input ;键盘输入子程序 还包含一个宏: convert ;将DX两位ASCII码转换为两位16进制数,让我们重点分析键盘输入子程序 input。,河南师范大学计算机与信息技术学院,69,2020/1/29,Input.as

41、m-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,2020/1/29,Input.asm-2,input10: cmp al , 0dh je input30 ;是回车,结束整个数据的输入 cmp al , je input20 ;是空格和逗号,确认输入了一个数据 cmp al , ,

42、 je input20 cmp al , 08h je input17 ;是退格,丢弃本次输入的数据,出错,河南师范大学计算机与信息技术学院,71,2020/1/29,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,2020/1/29,Input.asm-4,input11: cmp al , F ;字符小于

43、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,2020/1/29,Input.asm-5,;dl=0,输入了一个数据的低位,则dlal jmp input02 ;转到字符输入 input13: cmp dh , 0 jne input17 ;dl0,dh0输入3位数据,出错 mov dh , dl ;dl0,dh0输入了一个数据

44、的高位 mov dl , al ;dhdl,dlal jmp input02 ;转到字符输入,河南师范大学计算机与信息技术学院,74,2020/1/29,Input.asm-6,input17: mov dl , 7 ;输入错误处理 mov ah , 2 int 21h mov dl , ? mov ah , 2 int 21h jmp input01 ;转到输入一个数据,河南师范大学计算机与信息技术学院,75,2020/1/29,Input.asm-7,;转换正确的输入数据 input20: convert jmp input01 ;转到输入一个数据 input30: convert pop

45、 dx pop ax ret ;返回,出口参数已设定 input endp,河南师范大学计算机与信息技术学院,76,2020/1/29,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,2020/1/29,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 d

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 研究报告 > 商业贸易


经营许可证编号:宁ICP备18001539号-1