第四章汇编语言程序设计汇编语言程序设计概述汇编语言基本语法汇编语言程序设计BIOS及DOS功能调用汇编语言程序设计实 例在程序中重复执行相同功能的一段代码,可用循环程序实现。循环程序通常由五部分组成:初始化部分——为程序操作、地址指针、循环 计数、结束条件等设置初始值。循环工作部分——循环程序主体,完成基本操作。循环修改部分——修改循环工作部分的变量,为重复操作做准 备。循环控制部分——修改计数器或判断循环结束条件,决定是否终止循环。循环体循环结束部分——循环终止后,对循环结果的处理部 分。循环结构程序设计循环程序概述终止起始初始化循环工作循环修改循环控制完未完终止起始初始化 循环工作循环修改循环控制完未完先执行后判断先判断后执行循环程序基本结构循环结构程序设计未完终止起始 初始化循环工作循环修改循环控制完计数循环——重复次数已知,用计数值控制循环的开始与终止。条件控制循环——重复次数未知或 不确定,需找出循环控制的条件。解:已知循环次数,采用计数循环控制。程序段如下: MOV CX,100 ;确定循环计数 器值 MOV BX,1 ;确定循环初值 MOV AX,0 ;和的初值LOP: ADD AX,BX INC BX LOOPLOP ;循环控制【例】编写程序计算C=1+2+3+4+……+100循环控制方 式循环结构程序设计计数循环的常见方法:减1循环 MOV CX,NL: …… DEC CX JNZ L加1 循环 MOV CX,-NL: …… INC CX JNZ LLOOP短标号 MOV CX,NL: …… …… LOOP L 解:无法确定循环次数,采用条件循环控制。程序段如下: MOV SI,OFFSETO RGSTRIN ;读源串地址 MOV DI,OFFSETDESSTRIN ;读目的串地址LOP: MOV A L,[SI] MOV [DI],AL INC SI ;循环修改 INC DI CMP AL,‘$’ JNZ LOP ;循环控制【例】将一个字符串拷贝到另一个存储区中 ,直到拷贝到字符“$”结束。循环体中又有循环称多重循环。在多重循环程序设计时,应分别考虑每重循环的控制条件。通常内层循环要受 外层循环的控制。解:采用冒泡排序法,从第一个数开始依次对相邻的两个数进行比较,如果次序正确则不做任何操作,如果次序不正确 则将此两个数交换位置。【例】在首地址为Addr的存储单元中有N个数,编程序将此N个数按照从小到大的次序排列。多重循环 循环结构程序设计开始CX←外循环次数DI←最后一个数的地址BX←0取BX位置上的数到AL与后一数比较大于小于 交换两数位置BX←BX+1是否为最后的数?NYCX←CX-1结束CX==0?YNAADATA SEGM ENT Addr DBNDUP(?)DATA ENDSCODE SEGMENT ASSU MECS:CODE,DS:DATASTART: MOV AX,DATA MOV DS,AX MOV CX,N DEC CXLOOPl: MOV DI,CX ;设置外循环次数 MOV BX,0 ;设置内循环条件LOOP2: MOV AL,Addr[BX] CMP AL,Addr[BX+ 1] JL CONT XCHG AL,Addr[BX+1] ;让大的数向地址高处移动 MOV Addr[BX],ALCONT: INC BX CMP BX,DI ;内循环判断 JB LOOP2 LOOP LOOP1 ;外循环控制条件 MOV AH,4CH IN T 21HCODE ENDS END START MOV AX,3578H MOV CL,0L: O R AX,AX;判断AX是否为0 JZ EXIT ;AX=0结束 SHL AX,1 ;最高位进CF JNC L INC CL JMP LEXIT: INT 20H 【例】统计AX中1的个数。起始AX←357 8HCL←0AX<<1终止AX==0?YNCF==1?NYCL←CL+1【例】BUF中有N个有符号数,分 离其中的正负数,分别送入BUF1和BUF2中DATA SEGMENT BUF DB12H,34H,-56H ,-98H,096H,68H,56H,80H N=$-BUF BUF1 DBNDUP(0) BUF2 DB NDUP(?)DATA ENDSCODE SEGMENT ASSUMECS:CODE,DS:DATASTART : MOV DX,DATA MOV DS,AX LEA SI,BUF LEA DI,BUF1 LEA BX,BUF2 M OV CX,NAA: MOV AL,[SI] INC SI CMP AL,0 JGE BB MOV [BX],AL INC BX JMP CCBB: MOV [DI],AL INC DICC: LOOP AA;DECCX ;JNZ AA MOV AH,4CH INT 21HCODE ENDS END START(1)若DW定义BUF怎 样修改?(2)能改为条件控制循环吗?程序设计过程中常常把多次引用的相同程序段编成一个独立的程序段,当需要执行这个程序段 时,用调用指令(CALL)调用该程序段即可。具有这种独立功能的程序段称为过程或子程序。子程序设计适合编成子程序的程序 有两种:①程序需要反复使用,这类程序编写成子程序可避免重复编写程序,并可以节省存储空间。②程序具有通用性, 这类程序大家都要用到,如键盘管理程序、磁盘读写程序、标准函数程序等,编成子程序后便于功能共享。子程序适用范围子程序 必须有一个名称,方便其他程序调用;子程序出口是一条返回指令RET。子程序的结构子程序设计NAME PROC NEAR (FAR)过程名过程类型 RETNAME ENDP必须用RET结束 PUSH AX PUSH BX …… …… …… POP BX POP AX ……现场保护程序部分现场恢复 主程序调用子程序通过CALL指令来实现, 子程序执行结束后,通过RET指令返回主程序,转到主程序中CALL指令的下一条指令继续执行主程序。一个子程序可以由主程序在 不同时刻多次调用。如果在子程序中又调用了其它的子程序,称为子程序嵌套。特别当子程序又调用子程序本身时,这种调用称为递归调用。 子程序的调用和返回子程序设计子程序通常应以独立的文件形式编写,形成模块。子程序文件由子程序说明和子程序体构成。(1 )子程序说明①功能描述,如子程序名、功能,性能指标等;②所用寄存器和存储单元;③子 程序入口、出口参数;④子程序中调用的其它子程序;⑤调用实例(可无)。(2)子程序体 子程序本身常以“过程”形式存放在代码段中,以过程名开始,以RET指令结束。子程序文件子程序设计 (1)现场保护 如果子程序中要临时修改某些寄存器或存储单元时,为了不破坏原有的信息,要将寄存器或存储单元的原有内容压栈保护或存入子程序不用的 寄存器或存储单元中。 PUSH AX PUSH BX PUSH SI ………… ………… POP SI POP BX POP AX RET注意:现场保护的入栈和出栈顺序正好相反子程序设计应用注意事项子程序设计 (2)参数传递主程序在调用子程序时一般需要传递参数给子程序,这些参数是子程序运行时所需要的原始数据。常用的方法有: 寄存器——适用于参数少的情况,其特点是参数传递速度快。约定单元——适用于参数多的情况,要事先建立参数缓冲区。 堆栈——适用于参数较多、子程序嵌套或递归调用的情况。子程序设计应用注意事项子程序设计 …… MOV BX,OFFSETM1 MOV AX,[BX] ;AH,AL作子程序的入口参数 CALL ADDROC ;调用子程序 MOV [BX+2],AL ;AL作为子程序的返回参数 MOV BX,OFFSETM2 MOV A X,[BX] ;读第二组待处理数据 CALL ADDROC ;再次调用子程序处理第二个数据 ……ADDROC P ROC NEAR ;子程序定义 ADD AL,AH ;将AL,AH中的参数相加,结果存AL DAA RET ;子程序返回ADDROC ENDP【例4.13】利用寄存器传递参数。 …… MOV BX,OFFSET M1 ;待处理数据的地址用BX传递 CALL ADDROC2 ;调用子程序 MOV BX,OFFSETM2 ;将第二 组数据地址放到BX中 CALL ADDROC2 ……ADDROC2 PROC NEAR PUSH AX MOV AL,[BX] ;BX中存放待处理数据的地址 ADD AL,[BX+1] ;直接对该地址中的数据做运算 DA A MOV [BX+2],AL ;结果存回到内存中 POP AX RETADDPROC2 ENDP【例4. 14】利用存储器传递参数。 ……MOV AX,0MOV AH,BIN1 PUSH AX ;将待转换二进制数 压入堆栈LEA DI,ASCBUFPUSH DI ;将ASCII码存放地址压入堆栈MOV AX,8HPUSH AX ;将二进制数的位数压入堆栈CALL BINTOASC ;调用转换子程序MOV AH,BIN2 ;开始对第二 个数处理PUSH AXADD DI,10HPUSH DIMOV AX,10HPUSH AXCALL BIN TOASC……【例4.15】利用堆栈传递参数到子程序,由子程序对参数进行处理。将两个给定的二进制数BIN1、BIN2转换为对 应的二进制数的ASCⅡ码串。BINTOASC PROC NEAR ;转换子程序 PUSH DI ;保护现场 PUSH CX PUSH DX MOV BP,SP ;获取堆栈地址 MOV DX,[BP+12 ] ;取出堆栈中的数据 MOV DI,[BP+10] MOV CX,[BP+8] LOP: ROL DX,1 ;二进制数最高位放到DL中 MOV AL,DL AND AL,1 ADD AL,''0'' ;转换为ASCⅡ码 MOV [DI],AL ;存入相应内存 INC DI LOOP LOP POP DX POP CX POP DI RET 6BINTOASC ENDPMS-DOS操作系 统内置了几十个子程序(API),这些子程序能够完成大量底层功能,用户程序可以通过软中断调用方式使用这些子程序(称为DOS系统功能调 用),软中断号为21H。指令为:INT21HDOS系统功能调用的基本过程如下:(1)传送入口参数到指定寄 存器中;(2)调用子功能的功能编号放在AH寄存器中;(3)执行INT21H指令。调用结束后返回相应结果, 并由CF标志表示调用是否成功,当出现调用错误时CF=1,AX返回出错编号。BIOS及DOS功能调用DOS系统功能调用(1) MOV REG,XX ;传送入口参数到指定寄存器中 ;(部分无入口参数)(2)MOV AH,功能号 ;功能号 送入AH寄存器中(3)INT 21H ;DOS功能调用 (4)返回信息CF=1表示有错误发生,AX=返回错误代 码CF=0表示调用成功,AX=返回参数1、键盘单字符输入(1号) MOV AH,1 INT 21H 功能:等待从键盘 输入一个字符。 返回:(AL)=ASCII码,并回显在显示器上。 DEBUG演示 常用DOS功能调用介绍2、键盘输入字符串 (0AH号) MOV DX,OFFSETBUF ;DS:DX为键盘缓冲区 MOV AH,0AH INT 21H 功能:等待从键盘输入一串字符,回车结束。字符串存入键盘缓冲区。 键盘缓冲区定义(示例): BUF DB 81 ;缓冲区 的大小 DB ? ;实际输入的字符个数,不含0DH DB 80 DUP(?) ;字符串存放区3、输出单 字符(2号) MOV DL,‘A’ MOV AH,02 INT 21H 功能:将DL中字符从屏幕上输出。 返回:无。 DEBUG演示4、输出字符串(09号) MOV DX,OFFSET BUF MOV A H,09 INT 21H 功能:BUF中以“$”为结束标志的字符串显示在屏幕上。 DATA SEGMENT BUF DB “80X86CPU$” DATA ENDS DEBUG演示5、控制台输入/输出单字符(06) MOV AH,06 MOV DL,0FFH ;DL为0FFH时从键盘读一字符到AL INT 21H ;否则将DL中的字符送显示器 DEBUG演示6、无回显控制台输入单字符(08) MOV AH,08 INT 21H 功能:从键盘输入一个字符但不显示,常用于口令和控制键的输入。 DEBUG演示7、返回操作系统(4CH) MOV AH,4CH MOV AL,返回码 INT 21H 功能:将控制权交给操作系统。 DEBUG演示 |
|