1、第五章 程序设计基础,1,第五章 程序设计基本技术,一、汇编语言程序开发 二、系统功能子程序的调用 三、循环程序设计 四、分支程序设计 五、子程序设计,第五章 程序设计基础,2,一、汇编语言程序开发,分析问题,确定算法,编制程序流程图,编写程序,分配存储器单元,调测程序,程序设计步骤,第五章 程序设计基础,3,一、汇编语言程序开发,生成源程序文件,生成目标码程序,生成可执行文件,宏汇编程序 MASM,编辑程序,连接程序 LINK,程序名.asm,程序名.obj 程序名.LST,程序名.exe,语法有错,修改程序,有错,调测程序 DEBUG,结束,N,N,Y,Y,汇编语言程序开发步骤,MASM
2、程序名,LINK 程序名,DEBUG 程序名.exe,第五章 程序设计基础,4,一、汇编语言程序开发,例1(6-2)用查表的方法将一位十六进制数转换成ASCII码; DATA SEGMENT TABLE DB 30H,31H,32H,33H,34H,35H,36H,37HDB 38H,39H,41H,42H,43H,44H,45H,46H HEX DB 4 ;待转换的一位十六进制数 ASCI DB ? ;存放转换的ASCII码值 DATA ENDS STACK1 SEGMENT PARA STACKSTACK DW 20H DUP(0) STACK1 ENDS COSEG SEGMENTASS
3、UME CS:COSEG,DS:DATA,SS:STACK1,第五章 程序设计基础,5,一、汇编语言程序开发,START: MOV AX,DATAMOV DS,AXLEA BX,TABLE ;表的首地址XOR AH,AH MOV AL,HEXADD BX,AX ;确定查表位置MOV AL,BX ;查表MOV ASCI,AL ;存结果MOV AH,4CH ;返回dosINT 21H COSEG ENDS END START,第五章 程序设计基础,6,一、汇编语言程序开发,例2(6-22) 设某存储区有一数组ARRAY,现要求对数组中数据分别按正数(含0)和负数的绝对值累加,并统计正数和负数的个数
4、。累加和与统计个数分别存入SUM1、SUM2、CUNT1和CUNT2单元中。,分配寄存器:AX、BX为正数、负数和;DH、DL为正数、负数的个数;CL为计数器;CH存待判断的数。,寄存器清零,取数值个数CL,从内存中取数CH,数为负?,数取反,BX+CHBX,DL+1DL,AX+CHAX,DH+1DH,CL-1CL,CL为零?,存结果到指定内存,返回DOS,N,Y,Y,N,第五章 程序设计基础,7,一、汇编语言程序开发,TITLE EXAMPLE-6-22 DATA SEGMENT ARRAY DB 12,34,56,-12,-34,-9,0,3,0,-5,3,5DB 0AH,0FFH,4,0
5、,77H,88H,0F0H,0BBH COUNT EQU $-ARRAY SUM1 DW 0 ;存正数累加和 SUM2 DW 0 ;存负数累加和 CUNT1 DB 0 ;存正数数据个数 CUNT2 DB 0 ;存负数数据个数 DATA ENDS STACK1 SEGMENT PARA STACKSTA DW 20H DUP(0) STACK1 ENDS COSEG SEGMENTASSUME CS:COSEG,DS:DATA,SS:STACK1 START: MOV AX,DATAMOV DS,AXXOR AX,AXXOR BX,BX,第五章 程序设计基础,8,一、汇编语言程序开发,XOR C
6、X,CXXOR DX,DXLEA SI,ARRAYMOV CL,COUNT LOP: TEST BYTE PTR SI,80HJE PLUSMOV CH,SI ; 求负数绝对值NEG CHADD BL,CH ; 负数绝对值累加ADC BH,0INC DL ; 个数计数JMP NEXT PLUS: ADD AL,SI ; 正数累加ADC AH,0INC DH ; 个数计数 NEXT: INC SIDEC CLJNE LOP,第五章 程序设计基础,9,一、汇编语言程序开发,MOV SUM1,AX ; 存结果MOV SUM2,BXMOV CUNT1,DHMOV CUNT2,DLMOV AH,4CHI
7、NT 21HCOSEG ENDSEND START MASM、LINK、DEBUG操作。,第五章 程序设计基础,10,二、系统功能子程序的调用,通过软中断方式调用外部设备管理程序。 中断指令格式: INT n 执行操作:PUSH PSW, 0TF、IF, PUSH CS,PUSH IP,入口地址CS、IP; 调用格式: 送入口参量到指定寄存器 功能号AH INT n,第五章 程序设计基础,11,二、系统功能子程序的调用,DOS功能子程序的调用 调用格式:MOV CX/DXDL,参数MOV AH,功能号INT 21H,第五章 程序设计基础,12,三、循环程序设计,(一)、循环程序结构流程,初始化
8、部分,循环结束?,结束处理,DO WHILE(C),N,WHILE(C) ,工作部分,修改部分,Y,初始化部分,循环结束?,结束处理,N,工作部分,修改部分,Y,第五章 程序设计基础,13,三、循环程序设计,(二)、循环控制指令 1、LOOP指令 指令格式:LOOP TARGET 执行功能:CX-1CX;CX0 时,(继续循环,)转到TARGET所指的指令,CX=0时,顺序执行。 例6(6-8):编制裴波纳契数数列程序 0,1,1,2,3,5,8,MOV AX,0MOV BX,1 LOP: MOV DI,AX ADD AX,BXXCHG AX,BXADD DI,TYPE FIBONALOOP
9、LOP,CX数据个数 DI 数据首地址,CX=0?,AX AX+BX,N,(DI)AX,AX BX,Y,开始,结束,CXCX-1,DI DI+2,AX0,BX1,第五章 程序设计基础,14,三、循环程序设计,2、LOOPE/LOOPZ指令 指令格式:LOOPE/LOOPZ TARGET 功能:CX-1CX;若CX0且ZF=1时,转到TARGET所指的指令(继续循环),若CX=0或ZF=0时,顺序执行。 例7(6-9):编制寻找字符串 CHECK STRING中第一个非空格字符。若有,将字符的位置送指定存储单元中,否则将0FFH送指定单元中。 MOV BX,-1 NEXT: INC BXCMP
10、STRINGBX,20HLOOPE NEXTJNE OKMOV BL,0FFHJMP OK2 OK: INC BL OK2: MOV INDEX,BL,CX字串个数 BX -1(取数计数),数为空格?,(INDEX) BL,N,BXBX+1,取数与20H比较,Y,开始,结束,CXCX-1,BL BL+1,CX=0?,N,BL 0FFH,Y,第五章 程序设计基础,15,三、循环程序设计,3、 LOOPNE/LOOPNZ指令 指令格式:LOOPNE/LOOPNZ TARGET 执行功能:CX-1CX;若CX0 且ZF=0时,转到TARGET所指的指令(继续循环),若CX=0或ZF=1时,顺序执行。
11、 例8(6-10):设一字节数组ARRAY,对其中每一数用0FH除,用余数组成数组TUSHU。若余数为0或数组取完时,停止,并把余数个数存入LEN。 MOV DL,0FH NO_ZERO: MOV AL,ARRAYBXXOR AH,AHDIV DLMOV YUSHUBX,AHINC BXCMP AH,0LOOPNE NO_ZEROMOV LEN,BX,CX字串个数 BX 0(取数计数),余数为0?,(LEN) BX,N,YUSHU余数,取数与0FH相除,Y,开始,结束,CXCX-1,BX BX+1,CX=0?,N,Y,第五章 程序设计基础,16,三、循环程序设计,4、 JCXZ指令 指令格式:
12、JCXZ TARGET 执行功能:测试CX值,若CX=0,转到目标处(继续循环),否则,顺序执行。 (三)、循环控制方法(计数法、条件法) 例9(6-14):统计某数组中相邻两数据间符号变化次数。 XOR BL,BL EXCHANG: MOV AL, SIXOR AL,SI+1TEST AL,80HJE NEXTINC BL NEXT: INC SILOOP EXCHANGMOV NUM,BL,CX数据个数 SI 数组首址,AL.7=1?,NUM BL,N,AL(SI),BL0,计数,N,开始,结束,CXCX-1,ALAL+(SI+1),CX=0?,Y,BL BL+1,SI SI+1,Y,第五
13、章 程序设计基础,17,三、循环程序设计,(四)、多重循环程序设计的特点 1、设计方法和单重循环基本类似; 2、各重循环的控制条件及其程序实现相互之间不能混淆; 3、每次通过外层循环再次进入内层循环时,初始条件必须重新设置;,第五章 程序设计基础,18,三、循环程序设计,(四)、多重循环程序设计 例10(6-14):在存储区制作九九乘法表。1*1 1*2 1*3 1*4 1*5 MOV BH,0MOV CX,9 LOP1: PUSH CXINC BHMOV BL,0MOV CX,9 LOP2: INC BLMOV AL,BHMUL BLMOV DI,ALINC DILOOP LOP2POP C
14、XLOOP LOP1,DI存数据首址 CX 9 BH0,BL0(行,列),CX-1=0?,POP CX,N,BHBH+1,BL0,PUSH CX,开始,结束,CX 9,CX-1=0?,N,Y,AL BL*BH,(DI) AL,Y,DIDI+1,BLBL+1,第五章 程序设计基础,19,上机实验题目(二)多重循环设计,DAT开始的单元中存放N个字节有符号数,统计正数的个数存入T0单元中;负数的个数存入T1单元中;,第五章 程序设计基础,20,流程图,第五章 程序设计基础,21,四、分支程序设计,(一)、控制转移指令 1、无条件转移指令 基本格式:JMP TARGET 、段内直接短转移 指令格式:
15、JMP SHORT TARGET;TARGET为转移的目的地址(相对寻址)。 执行操作:IP+8位有符号数IP 源与目的地址之间要保持在-128+127范围内。 、段内直接近转移 指令格式:JMP NEAR PTR TARGET;TARGET为转移的目的地址(相对寻址) 。 执行操作:IP+16位符号数IP 源与目的地址之间要保持在-32768+32727范围内。,第五章 程序设计基础,22,四、分支程序设计,、段内间接转移 指令格式:JMP WORD PTR OPR;OPR为通用寄存器/存储器字单元,目标地址为其内的数据(间接寻址)。 执行操作:EAIP 例:JMP BX、JMP WORD
16、PTR BX 、段间转移 指令格式:JMP DWORD PTR OPR;OPR为存储器双字单元(间接寻址) 。 执行操作:(EA)IP,(EA+2)CS 例: JMP DWORD PTR BX 、JMP DWORD PTR 10HBXDI,第五章 程序设计基础,23,四、分支程序设计,2、条件转移指令 基本格式:JXX OPR 条件转移只能在段内转移,且转移范围为:-128127。 、单标志位条件转移指令(10条,简单条件转移) JZ(或JE) OPR;结果为0(或相等)(ZF=1)时转移; JNZ(或JNE) OPR;结果不为0(或不相等)(ZF=0)时转移; JS/JNS OPR;结果为负
17、/正(SF=1/0)时转移; JO/JNO OPR;结果溢出/无溢出(OF=1/0)时转移; JP(JPE)/JNP(JPO) OPR;奇偶位为偶/奇(PF=1/0)时转移; JC/JNC OPR;有/无借位(CF=1/0)时转移;,第五章 程序设计基础,24,四、分支程序设计,、无符号数条件转移指令(4条) JB/JNAE OPR;两个无符号数a、b比较时,若ab时转移,(ZF=0 AND CF=1); JBE/JNA OPR;两个无符号数a、b比较时,若ab时转移;( ZF=1 OR CF=1) JA/JNBE OPR;两个无符号数a、b比较时,若ab时转移;( ZF=0 AND CF=0
18、) JAE/JNB OPR;两个无符号数a、b比较时,若ab时转移(ZF=1 OR CF=0) ;,第五章 程序设计基础,25,四、分支程序设计,、有符号数条件转移指令(4条) JG/JNLE OPR;两个带符号数a、b比较时,若ab时转移;(SF=OF)AND ZF=0) JGE/JNL OPR;两个带符号数a、b比较时,若ab时转移;(SF=OF) OR ZF=1 ) JL/JNGE OPR;两个带符号数a、b比较时,若ab时转移;(SFOF)AND ZF=0) JLE/JNG OPR;两个带符号数a、b比较时,若ab时转移;(SFOF)OR ZF=1),第五章 程序设计基础,26,四、分
19、支程序设计,(二)、比较/测试分支程序设计 比较指令: 指令格式:CMP DEST,SRC; 执行操作:(DEST)-(SRC) 对标志的影响:OF、SF、ZF、AF、PF、CF 根据标志位判断源操作数和目的操作数的大小 测试指令: 指令格式:TEST DEST,SRC; 执行操作:(SRC)(DEST) 对标志位影响: SF、ZF、PF; 源操作数可为:通用寄存器、存储器或立即数。 目的操作数不能为立即数,源和目的操作数不能同时在存储器中。,第五章 程序设计基础,27,四、分支程序设计(),分支结构程序流程:,IF(C) ELSE ,程序段1,判定条件?,程序N,程序1,CASE (C1):
20、 CASE (C2):CASE (C3):,第五章 程序设计基础,28,四、分支程序设计,例 设数据段中NUM1,NUM2两字节单元有无符号整数,编程完成:1、若两个均是偶数,则两个数分别加1后送DA1、DA2字节单元中;2、若两个均是奇数,则两个数分别送DA1、DA2字节单元中;3、若一个是奇数,一个是偶数,则把奇数送DA1,偶数送DA2字节单元中;,第五章 程序设计基础,29,四、分支程序设计,第五章 程序设计基础,30,四、分支程序设计,DATA SEGMENT NUM1 DB 45H NUM2 DB 0AEH DA1 DB ? DA2 DB ? DATA ENDS STACK1 SEG
21、MENT PARA STACKSTA DW 20H DUP(0) STACK1 ENDS COSEG SEGMENTASSUME CS:COSEG,DS:DATA,SS:STACK1 BEGIN:MOV AX,DATAMOV DS,AX,第五章 程序设计基础,31,四、分支程序设计,MOV AL,NUM1MOV AH,NUM2TEST AL,01HJNE END0TEST AH,01H;偶数JNE L1 INC AL ;双偶数INC AHJMP END0 L1: XCHG AL,AH END0: MOV DA1,ALMOV DA2,AHMOV AH,4CHINT 21H COSEG ENDSE
22、ND BEGIN,开始,(NUIM1)AL,(NUM2)AH,(AL)0=0?,(AH)0=0?,(AL)(DA1) (AH)(DA2),结束,Y,Y,N,N,(AL+1)(AL) (AH+1)(AH),(AH) (AL),END0,L1,第五章 程序设计基础,32,上机实验题目(三)分支程序设计,TAB开始的单元中存放N个字节无符号数,请按照从大到小排序后,存入DAB单元中。(选作:从小到大排序),第五章 程序设计基础,33,流程图,第五章 程序设计基础,34,五、子程序设计,(一)、子程序结构流程,子程序调用下条指令,子程序返回,子程序段,子程序调用,调用程序,子程序,保存下条指令地址,恢
23、复下条指令地址,第五章 程序设计基础,35,五、子程序设计,(二)调用与返回指令 1、段内调用与返回指令 (1)、段内直接调用 指令格式:CALL OPR; OPR为子程序名; 执行操作:SP-2SP, IP(SP+1,SP), 16位符号数IP,(2)、段内间接调用 指令格式:CALL WORD OPR; OPR为寄存器或存储器地址;OPR可为除立即数以外的任何寻址方式; 执行操作:SP-2SP, IP(SP+1,SP), REG/EAIP,第五章 程序设计基础,36,五、子程序设计,(3)、段内返回指令 指令格式:RET 执行操作:(SP+1,SP) IP, SP+2SP,(4)、段内带立
24、即数返回 指令格式:RET EXP; 执行操作:(SP+1,SP) IP ,SP+2SP,SP+NSP,第五章 程序设计基础,37,五、子程序设计,2、段间调用与返回指令 (1)、段间直接调用 指令格式:CALL FAR PTR OPR; 或 CALL OPR OPR为子程序名 执行操作:SP-2SP, CS(SP+1,SP), SP-2SP,IP(SP+1,SP)子程序入口偏移地址IP子程序段地址CS,(2)、段间间接调用 指令格式:CALL DWORD OPR; OPR为存储器地址,可为除立即数以外的任何寻址方式。 执行操作:SP-2SP, CS(SP+1,SP), SP-2SP, IP(
25、SP+1,SP), (EA)IP, (EA+2)CS,调用程序与子程序不在一个逻辑段内,第五章 程序设计基础,38,五、子程序设计,(3)、段间返回指令 指令格式:RET; 执行操作: (SP+1,SP)IP,SP+2SP, (SP+1,SP) CS,SP+2SP,(4)、段间带立即数返回 指令格式:RET EXP; 执行操作: (SP+1,SP)IP,SP+2SP, (SP+1,SP) CS , SP+2SP,SP+NSP,第五章 程序设计基础,39,五、子程序设计,(三)、子程序定义指令 格式:过程名 PROC NEAR/FARRET过程名 ENDP 功能:子程序定义 定义的过程必须在一个
26、逻辑段内. 类型属性隐含为NEAR. 一个过程中至少有一个RET语句,可在任意位置,但必须是最后一条执行.,过程定义伪指令,传递参量方式:寄存器、存储器、堆栈,第五章 程序设计基础,40,五、子程序设计,例1:将字符串信息显示功能设计成子程序Print_message PROCPUSH AXMOV DX,OFFSET NUM MOV AH,9INT 21HPOP AXRETPrnt_message ENDPMOV DX,OFFSET NUMCALL Print_message,第五章 程序设计基础,41,五、子程序设计,6.1.4 子程序的参数传递: 参数传递:调用程序在调用子程序时,经常要传
27、递一些参数给子程序;子程序在运行结束后也常要回送一些信息给调用程序。 参数传递的方式:1、寄存器传递参数(参数多时不能使用)2、变量传递(过程和调用程序在同一原文件),第五章 程序设计基础,42,五、子程序设计,Decibin:接收键入的10进制值,转换为2进制,并存入BX中; Crlf:回车换行子程序; Binihex:二进制数据转换为4位16进制,并在crt上显示,1、通过寄存器传递参数 例6.3 要求从键盘输入十进制数(0ffffh) 然后以16进制形式在CRT上显示,第五章 程序设计基础,43,五、子程序设计, Main proc far Repeat: call decibincal
28、l clrfcall binihexcall clrfjmp repeatret Main endp decbin proc nearret Decibin endp,主程序,第五章 程序设计基础,44,五、子程序设计,decibin proc nearmov bx,0newchar: mov ah,1int 21h sub al,30hcmp al,0jl exitcmp al,09jg exitcbwxchg ax ,bxmov cx,10mul cxxchg ax,bx,bx,al?,cbw,ret,出口参量:bx,al接收键值,alal-30h,Al9?,bxax+bx*10,add
29、bx,ax jmp newchar Exit: ret decibin endp,第五章 程序设计基础,45,五、子程序设计,binihex proc nearmov cx,44hrotate: rol bx, clmov al,bland al,0fhadd al,30hcmp al,3ahjl printitadd al ,7printit: mov ah,02mov dl,al,入口参量:bx,int 21hdec ch jnz rotate ret decibin endpClrf proc nearmov dl,0dhmov ah,02hint 21hmov dl,0ahmov ah
30、,02hint 21hret Clrf endp,第五章 程序设计基础,46,五、子程序设计,proadd:将数组ary中的数据进行累加后放入sum中,2、通过变量传递参数 例6.4 要求使用过程proadd累加数组中的所有元素,并送到sum中,Sum定义,结束,开始,Call proadd,第五章 程序设计基础,47,五、子程序设计,proadd proc nearpush axpush cxpush simov ax,0lea si,arymov cx,count Next: add ax,siadd si,2loop nextmov sum,axpop sipop cxpop ax,出口参量:sum,ret proadd endp,第五章 程序设计基础,48,代码转换实验: 内容:用子程序设计的方法,分别把BUF字单元中的四位十六进制数转换为ASCLL代码存入MAS开始的单元中,并在crt上显示。,上机实验题目(四)子程序设计,第五章 程序设计基础,49,五、子程序设计,主程序,Decbin子程序,ax ax rol cl,ch4h,ax buf,si0,buf ax,取 al 低4bit,Al0a?,y,al al+7,al al+30,n,Massial,crt 显示,si si+1,Ch-1=0?,cl4h,y,n,现场保护,ret,恢复现场,