程序设计方课件_第1页
程序设计方课件_第2页
程序设计方课件_第3页
程序设计方课件_第4页
程序设计方课件_第5页
已阅读5页,还剩167页未读 继续免费阅读

下载本文档

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

文档简介

第五节基本结构程序设计方法一、顺序程序设计二、

分支程序设计三、循环程序设计四、子程序设计

1第五节基本结构程序设计方法一、顺序程序设计1概述汇编语言程序设计的一般步骤流程图2概述汇编语言程序设计的一般步骤2汇编语言程序设计的一般步骤汇编语言程序设计一般有以下几个步骤:1.分析问题,确定算法2.绘制流程图3.根据流程图编制程序4.调试程序3汇编语言程序设计的一般步骤汇编语言程序设计一般有以下几个步流程图1.流程图的概念 流程图是由特定的几何图形、指向线、文字说明来表示数据处理的步骤,形象描述逻辑控制结构以及数据流程的示意图。流程图具有简洁、明了、直观的特点。2.流程图符号表示(1)起止框:表示程序的开始和结束。起止框4流程图1.流程图的概念2.流程图符号表示起止框4(2)判断框

(3)处理框

(4)调用框

5(2)判断框(3)处理框(4)调用框5(5)指向线

(6)连接框

6(5)指向线(6)连接框6一、顺序程序设计顺序结构顺序结构的程序一般是简单程序,其特点是程序顺序执行,无分支,无循环与转移。例4.4内存中TABLE开始存放0~9的平方值,通过人机对话,对任意给定的数(0~9),查表得的平方值,将其放在AL中。datasegmenttabledb0,1,4,9,16,25,36,49,64,81dufdb’pleaseinputontnumber(0~9):’0dh,0ah,’$’dataendsstacksegmentparastack’stack’stapadb100dup(?)codesegmentassumecs:code,ds:data,ss:stack7一、顺序程序设计顺序结构7start:pushaxmovax,datamovds,axmovax,stackmovss,axmovsp,topmovbx,offsettablenext:movdx,offsetbuf;9号功能调用,显示字符串,提示输入一个数movah,9int21h8start:pushax8movah,1;1号功能调入,等待键入一个数且送ALint21hmovah,0;查表得键入数的平方值andal,0fh;屏蔽高4位addbx,axmoval,[bx]movah,4chint21hcodeendsendstart9movah,1

二、分支结构一个大的程序完全顺序结构实际上并不可能,经常会遇到有分支的情况,分支结构程序通常采用条件转移或转移表来实现。典型的分支结构如教材图4.3所示。下面举例说明分支结构:例4.5给符号函数建立标志。=1当>0符号函数y=0当=0=-1当<0要实现符号函数,只要把从内存中取出来,执行一次“与”或“或”操作,就可以把的数值特征反映在标志上,再根据标志来转移。程序框图如教材图4.4所示。10二、分支结构10源程序如下:datasegmentxdw15ydw?dataendsstacksegmentstack’stack’db100dup(?)stackendscodesegmentassumecs:code,ds:data,ss:stack11源程序如下:11 start:pushaxmovax,datamovds,axmovax,xandax,axjzxerojnszeromovbx,offffhjmpdone

12 start:pushax12

zero:movbx,0jmpdoneplus:movbx,1done:movy,bxmovah,4chint21hcodeendsendstart

13zero:movbx,013

三、循环结构循环结构是程序设计中最常用的结构。凡需要重复做的工作,在计算机中都可以用循环结构程序来实现。循环程序有两种结构形式,一种是“先执行,后判断”,另一种为“先判断,后执行”。这后一种结构实现上允许0次循环,因而对有些程序更有效,它适合于循环次数不固定的程序。14三、循环结构14循环程序的常见结构形式15循环程序的常见结构形式15无论哪种循环结构,都包括以下四个部分:(1)初始化:为循环作准备,设置循环计数值,设置变量初值。(2)循环体:循环部分的核心,包括循环的全部指令。(3)修改参数:修改操作数地址,为下次循环作准备。(4)循环控制:修改计数器值,判断循环控制条件,决定是否跳出循环。对“先执行,后判断”结构,进入循环后至少要执行一次循环体,再判判断循环是否结束。对“先判断,后执行”结构,进入循环后,先判断循环结构条件,再决定是否执行循环体,可能循环体一次也不执行,即循环次数为0。16无论哪种循环结构,都包括以下四个部分:16例4.6若将内存2000H:0100H开始的256个字节的数据块移动到内存2000H:0200Hmovax,2000h;初始化,为循环工作准备movds,axmovsi,0100h;设置源数据块地址指针movdi,0200h;设置目的地址指针movcx,100h;设置循环次数next:moval,[si];循环体mov[di],alincsi;修改参数incdiloopnext;循环控制movah,4chint21h17例4.6若将内存2000H:0100H开始的256个字节的数例4.7BX寄存器中有一个16位二进制数,编程统计该数中1的个数,将其结果放到CL寄存器中。xorcl,cl;初始化,为循环作准备lopl:andbx,bx;循环控制jzstopshlbx,1:循环体jnclop1inccljmplop1stop:movah,4ch;程序中止int21h18例4.7BX寄存器中有一个16位二进制数,编程统计该数中有些循环结构比较复杂,需要用多重循环完成。多重循环设计方法与单重循环设计方法相,但应注意:(1)各重循环的初始控制条件及程序实现。(2)内循环可以嵌套在外循环中,也可以多层嵌套,但各层循环这间不能交叉,可以从内循环跳到外循环,不可以从外循环中直接跳进内循环。(3)防止出没死循环,即不能让循环回到初始条件,引起死循环。例4.8设有N个符号数,要求将这N个数由小到大排列。采用冒泡排序法。从第一个数据开始相信的数进行比较,若次序不对,两数交换位置。第一遍就完成了排序,这样共有两重循环19有些循环结构比较复杂,需要用多重循环完成。多重循环设计方法与datasegmentbufdb15h,37h,86hdb0a7h,0c8h,90h,7eh,50hdb80h,23hcoutequ$-bufdataendsstacksegmentstack’stack’sapdb100dup(?)topequlengthsapstackendscodesegment

assumecs:code,ds:data,ss:stack20datasegment20

start:movax,datamovds,axmovax,stackmovss,axmovsp,topmovbx,offsetbufmovcx,cout-1

21start:movax,data21lpo1:movdx,cxlpo2:moval,[bx]cmpal,[bx+1]jlenextxchgal,[bx+1]mov[bx],almext:incbxlooplop2movcx,dxlooplop1movah,4chint21hcodeendsendstart22lpo1:movdx,cx22四、子程序结构若一段指令语句在一个程序中多次使用,或在多个程序中用到,则通常把这段指令语句当作一个独立的模块处理,这段模块称为子程序或“过程”。需要执行这个模块时,就进行过程调用,执行完毕后,再返回原来调用它的程序。采用子程序结构编程,使程序结构模块化,清晰明了,容易修改。在汇编语言中,每一个子程序都包括在过程定义语句PROC…ENDP中间。过程定义有属性NEAR或FAR,若调用子程序的程序在同一代码段中,则用NEAR属性,若不在同一段中,使用FAR属性。23四、子程序结构231.子程序清单通常编写子程序或过程时,写一个子程序说明或清单,能使模块结构一目了然,且使调用者知道如何使用该程序。子程序清单包括:(1)子程序的名称,功能说明;(2)子程序中用到的寄存器和存储单元;(3)子程序的入口参数,出口参数;(4)子程序中调用其他子程序的名称。241.子程序清单242.参数传递方法主程序与子程序相互之间可以传递参数。在许多情况下,希望子程序更具有通用性,更灵活,这时就希望子程序除了有使用说明外,还能够接受调用程序传来的入口参数,在子程序执行完毕后把出口参数传递给调用程序。参数的传递通有三种方法:(1)用寄存器传递:适合于参数较少的情况,传递速度较较快;(2)用存储器传递:适合参数较多的情况,需要先在存储器中建立一个参数表。(3)用堆栈传递:适合于参数较多且子程序有嵌套、递归调用的情况。252.参数传递方法25例4.11在数据段中定义了两个数组,编程实现数组分别求和。datasegmentart1db12,23,34,45,56,67,78,89,90,18contlequ$-ary1sum1dw?ary2db13h,24h,57h,68h,9ah,0bch,0cdh,0deh,80h,80hcont2equ$-ary2sum2dw?dataendscodesegmentassumecs:code,cs:data26例4.11在数据段中定义了两个数组,编程实现数组分别求和start:movax,datamovds,axleasiary1;入口参数,数据块1首址movcx,cont1;入口参数,数据块1长度callsum;调用求和子程序leasi,ary2;入口参数,数据块2首址movcx,cont2;入口参数,数据块2长度callsummovah,4chint21h27start:movax,data27

sumproc;子程序sumxorax,ax;ax清0,存放和next1:addal,[si];数组元素相加adcah,0;高位放在ah中incsiloopmext1mov[si],ax;数组和存入内存单元retsumendpcodeendsendstar28sumproc【例4.8】试编写一程序,要求比较两个字符串STR1和STR所含字符是否相同,若相同则显示‘MATCH!’,若不相同则显示‘NOMATCH!’。(程序略) 其流程图如图4.7所示。

29【例4.8】试编写一程序,要求比较两个字符串STR1和STR图4.7程序流程图30图4.7程序流程图30【例4.9】试编一个程序将字单元BUF中所含1的个数存入COUNT单元中。要测出BUF字单元所含1的个数,首先将BUF中的数送给寄存器AX,然后将AX寄存器逻辑左移一次,如果CF=1,则表明AX中的最高位为1,则计数器CL计数1次,如果CF=0,表明AX最高位为0,这样依次将最高位移入CF中去测试。移位之后,判断AX的值是否为0,如果为0则结束循环,不为0,则继续循环。其流程图如图4.8所示。2.条件控制31【例4.9】试编一个程序将字单元BUF中所含1的个数存入CO3232程序如下:STACK SEGMENTSTACK DB200DUP(0)STACK EDNSDATA SEGMENT BUF DW0011110010101011B COUNT DB?DATA ENDSCODE SEGMENTASSUMEDS:DATA,CS:CODE,SS:STACK33程序如下:33START: MOV AX,DATA MOV DS,AX MOV AX,BUF MOV CL,0 ;计数器为0LOPA: AND AX,AX;使CF位为0 JE EXIT ;(AX)=0,结束循环

SHL AX,1 ;AX左移一位 JNC LOPA

INC CL ;产生进位,(CL)+1→CL

JMP LOPAEXIT: MOV COUNT,CL

MOV AH,4CH INT 21HCODE ENDS END START34START: MOV AX,DATA344.4.3多重循环程序设计【例4.10】在以BUF为首址的字存储区中存放有N个有符号数,现需将它们按大到小的顺序排列在BUF存储区中,试编写其程序。 我们采用冒泡排序算法从第一个数开始依次对相邻两个数进行比较,如次序对,则不交换两数位置;如次序不对则使这两个数交换位置。可以看出,第一遍需比较(N-1)次,此时,最小的数已经放到了最后;第二遍比较只需考虑剩下的(N-1)个数,即只需比较(N-2)次;第三遍只需比较(N-3)次,……整个排序过程最多需(N-1)遍。如下面的4个数即是采用冒泡排序比较的例子。354.4.3多重循环程序设计【例4.10】在以BUF为首址数 10 8 16 90 32第一遍 10 16 90 32 8第二遍 16 90 32 10 8第三遍 90 32 16 10 8程序流程图如图4.9所示。36数 10 8 16 90 32363737程序如下:DATA SEGMENTBUF DW3,-4,6,7,9,2,0,-8,-9,-10,20N=($-BUF)/2DATA ENDSSTACK SEGNMENTSTACKDB200DUP(0)STACK ENDSCODE SEGMENTASSUMECS:CODE,DS:DATA,SS:STACK38程序如下:38START: MOV AX,DATA MOV DS,AX MOV CX,N DEC CX;设计数器CX内循环39START: MOV AX,DATA39LOOP1: MOV DX,CX;设计数器DX外循环 MOV BX,0LOOP2: MOV AX,BUF[BX]

CMP AX,BUF[BX+2]

JGE L;>=,不变,否则交换

XCHG AX,BUF[BX+2] MOV BUF[BX],AXL: ADD BX,2

DEC CX JNE LOOP2;相当于LOOPLOOP2 MOV CX,DX; LOOP LOOP140LOOP1: MOV DX,CX;设计数器DX外循环40 MOV AH,4CH INT 21HCODE ENDS END START程序运行后,BUF区中的内容如下:20,9,7,6,3,2,0,-4,-8,-9,-10若要对N个无符号数按由小到大的顺序排列,只需将指令“JGEL”改为“JLEL”即可。41 MOV AH,4CH414.5子程序设计4.5.1子程序的概念4.5.2子程序的定义4.5.3子程序设计方法4.5.4子程序应用举例4.5.5子程序的嵌套与递归调用424.5子程序设计4.5.1子程序的概念424.5.1子程序的概念

在程序设计中,我们会发现一些多次无规律重复的程序段或语句序列。解决此类问题一个行之有效的方法就是将它们设计成可供反复调用的独立的子程序结构,以便在需要时调用。在汇编语言中,子程序又称过程。 调用子程序的程序称为主调程序或主程序。

434.5.1子程序的概念 在程序设计中,我们会发现一些多次4.5.2子程序的定义子程序的定义是由过程定义伪指令PROC和ENDP来完成的。其格式如下:过程名PROC[NEAR/FAR]┆过程名ENDP其中PROC表示过程定义开始,ENDP表示过程定义结束。过程名是过程入口地址的符号表示。一般过程名同标号一样,具有三种属性,即段属性、偏移地址属性以及类型属性。444.5.2子程序的定义子程序的定义是由过程定义伪4.5.3子程序设计方法1.信息的保护与恢复2.主程序与子程序参数传递方式454.5.3子程序设计方法1.信息的保护与恢复451.信息的保护与恢复例如:若子程序PROG中改变了寄存器AX,BX,CX,DX的值,则可采用如下方法保护和恢复现场。PROG PROC PUSH AX PUSH BX PUSH CX ;保护现场 PUSH DX

461.信息的保护与恢复例如:若子程序PROG中改变了寄存器AX

POP DX POP CX POP BX ;恢复现场 POP AX RET ;返回断点处PROC ENDP47 ┆472.主程序与子程序参数传递方式(1)寄存器法(2)约定单元法(3)堆栈法482.主程序与子程序参数传递方式(1)寄存器法484.5.4子程序应用举例【例4.12】将一个给定的二进制数按位转换成相应的ASCII码字符串,送到指定的存储单元并显示。如二进制数10010011转换成字符串为‘10010011’。要求将转换过程写成子程序,且子程序应具有较好的通用性,而必须能实现对8倍和16倍二进制数的转换。494.5.4子程序应用举例【例4.12】将一个给定的二进制入口参数: DX存放待转换的二进制数 CX存放待转换数的位数(8位或16位) DI存放ASCII码首地址出口参数:转换后的字符串存放在以DI作指针的字节存贮区中程序如下:DATA SEGMENT NUM8 DB 93H NUM16 DW 0ABCDH ASCBUF DB 20 DUP(0)DATA ENDS50入口参数:50CODE SEGMENTASSUMEDS:DATA,CS:CODE,SS:STACKSTART: MOV AX,DATA MOV DS,AX

MOV DX,0 MOV DL,NUM8 ;转换二进制数送DX MOV CX,8 ;置位数8 LEA DI,ASCBUF;字符串首址→DI CALL BTASC ;调用子程序BTASC

MOV BYTEPTR[DI],0DH MOV BYTEPTR[DI+1],0AH51CODE SEGMENT51

MOV BYTEPTR[DI+2],

‘$’ LEA DX,ASCBUF MOV AH,9 INT 21H

MOV DX,NUM16 MOV CX,16 ;置位数16 LEA DI,ASCBUF CALL BTASC

MOV BYTEPTR[DI],0DH MOV BYTEPTR[DI+1],0AH MOV BYTEPTR[DI+2],

‘$’;显示转换后的字符串 LEA DX,ASCBUF MOV AH,9 INT 21H52MOV BYTEPTR[DI+2],‘$’BTASC PROC PUSH AX ;保存AX MOV AL,0 CMP CX,8;比较8位数 JNE L1 ;直接转换16位数 MOV DH,DL;8位数转换送DHL1: ROL DX,,1;DX最高位移入CF RCL AL,1;CF移入AL最低位 ADD AL,30H MOV [DI],AL INC DI LOOP L1 POP AX RETBTASC ENDP53BTASC PROC53CODE ENDS END START54CODE ENDS544.5.5子程序的嵌套与递归调用1.子程序的嵌套子程序不但可以被主程序调用,而且也可以被其他子程序调用。我们把一个子程序调用另一个子程序称为子程序的嵌套调用。2.子程序的递归调用子程序的递归调用是指一个子程序直接或间接地调用自己。递归子程序一般对应于数学上对函数的递归定义,它往往能设计出效率较高的程序,完成相当复杂的计算,因而是很有用的。554.5.5子程序的嵌套与递归调用1.子程序的嵌套55【例4.16】计算5!的程序示例,RESULT是保存阶乘的存储单元。程序如下:STACK SEGMENTSTACK DB200DUP(0)STACK ENDSDATA SEGMENTN DW5RESULT DW?DATA ENDSCODE SEGMENTASSUMECS:CODE,SS:STACK,DS:DATA56【例4.16】计算5!的程序示例,RESULT是保存阶乘的START: MOV AX,DATA MOV DS,AX

MOV AX,N

CALL FACT

MOV AX,RESULT

MOV AH,4CH INT 21H

57START: MOV AX,DATA57FACT PROC CMP AX,0 JNE L1 MOV RESULT,1 JMP EXITL1:

PUSH

AX DEC AX

CALL FACT

POP AX MOV RESULT,AXEXIT: RETFACT ENDPCODE ENDS END START58FACT PROC584.6模块化程序设计1.PUBLIC伪指令格式:PUBLIC符号[,符号]功能:说明其后的符号是全局符号。全局符号能被其他模块引用。2.EXTRN伪指令格式:EXTRN符号:类型[,符号:类型]功能:说明在本模块中需要引用的、由其他模块定义的符号,即外部符号。594.6模块化程序设计1.PUBLIC伪指令59【例4.17】用模块化程序设计方法建立两个模块MOD1ASM和MOD2ASM的数据通讯。NAME MOD1EXTRN DISP:FARPUBLIC STR1,N,BUFDATA1 SEGMENTSTR1 DB ‘HOWDOYOUDO?’N = $-STR1BUF DB‘THISISANEXAMPLEOFMODULESPROGRAM$′DATA ENDS60【例4.17】用模块化程序设计方法建立两个模块MOD1ASTACK SEGMENTSTACK DB200DUP(0)STACK ENDSCODE1 SEGMENTASSUMECS:CODE1,DS:DATA1,SS:STACKSTART: MOV AX,DATA MOV DS,AX

CALL DISP

MOV AH,4CH INT 21HCODE1 ENDSEND START61STACK SEGMENTSTACK61NAME MOD2EXTRN STR1:BYTE,STR2:BYTE,N:ABSPUBLIC DISPDATA2 SEGMENTSTR2 DB81DUP(0)DATA2 ENDSCODE2 SEGMENT ASSUMECS:CODE2,ES:DATA2DISP PROC FAR

MOV AX,DATA2 MOV ES,AX62NAME MOD262 LEA BX,STR1 MOV CX,N LEA SI,STR2NEXT: MOV AL,[BX] MOV ES:[SI],AL INC BX INC SI LOOPNEXT

LEA DX,BUF MOV AH,9 INT 21H

RET

DISP ENDPCODE2 ENDS END63 LEA BX,STR163典型问题的编程思路一、进制转换1.十进制转换成十六进制数4.16以两个字87654321为例: 0*10+8=AXAX*10+7=AXAH为全0 AL*10+6=AX AX*10+5=DX,AXDX为全0以字为单位按上述方法进行转换,再将高位字转换结果*10000+低位字。2.十六进转换成十进制制数 除10例4.3中给出。3.二进制转换成十六进制数

4.16给出。64典型问题的编程思路64二、键盘输入与屏幕显示1.显示字符串 在数据段设置字符串,以’$’结束。(4.2) MOVDX,字符串首址 MOVAH,9 INT21H2.人机对话(4.2) 第一步:用显示字符串功能显示计算机提问内容(9号功能调用)。 第二步:键盘输入接受用户选择(0A号功能调用)。 第三步:显示用户输入内容(9号功能调用)。65二、键盘输入与屏幕显示653.数值显示第一步:把字节数据分解为2个1位十六进制数。第二步:1位十六进制数转换为ASCII码后再以字符显示。注:0-9的ASCII码为30-39H,A-F的ASCII码为41-46H。转换方法(AL低4位存有1位十六进制数转换方法):方法一: DAA ADDAL,0F0H ADCAL,40H663.数值显示66方法二: ADDAL,90H DAA ADCAL,40H DAA方法三: CMPAL,10 JBS ADDAL,7 S:ADDAL,30H67方法二:674.日期显示4.3第一步:DOS系统功能调用,取日期功能2A第二步:将得到的日期进行转换第三步:将转换后的日期输出显示684.日期显示4.368三、多字节运算1.组合型BCD码求和程序4.18 从多字节低位开始计算,事先将串操作相关初始条件给出。do:lodsb adcal,[bx];如果是两个组合型BCD码求差计 算用sbb语句,daa改成das daa;如果是两个二进制数据求和该句省略 stosb decbx loopdo2.组合型BCD码求差程序3.二进制数据求和4.11或采用串操作方法如上

69三、多字节运算69四、数据排序与检索

排序从大到小,或从小到大;4.9 检索最大值,最小值;4.10

五、统计、求和、求平均值 统计某数中1的个数,正数、负数、零的个数;4.7, 求和如三; 求平均值;70四、数据排序与检索70例3,取当前日期,并显示第一步:取日期,并保存第二步:将日期转换为ASCII码第三步:显示字符串Bx内容最低位开始数据传送AL\AX除10,商AL/AX,余数DL/DX取余数DL/DX+30→ASCII码71例3,取当前日期,并显示Bx内容最低位开始数据传送AL\AX一、顺序结构例4.4三个步骤通过人机对话查表得某数的平方值显示字符串提示输入一个数:9号功能输入一个字符:1号功能得出ASCII值查表BX:表的首地址AL:指出待查的值AL与0F使之小于16XLAT得到的值送到AL72一、顺序结构例4.4三个步骤通过人机对话查表得某数的平二、分支结构条件转移或转移表例4.5见书中流程三、循环结构初始化循环次数固定:串操作 loop

循环次数不固定:跳转指令 DO-WHILE 循环体修改参数循环控制73二、分支结构条件转移或转移表73例4.7统计BX寄存器中二进制数的1的个数

两个RegCL:统计1的个数

BX:存待处理的二进制数①XORcl,cl②lop1:andbx,bx③jzstop Y④shlbx,1⑤jnclop1⑥inccl N⑦jmplop1stop:movah,4ch注意多层循环嵌套问题CL清零Bx的值取标志Bx=0?Bx左移1位Cf=1?Cl加1结束74例4.7统计BX寄存器中二进制数的1的个数

两例4.9排序:将N个数从小到大排序(从大到小?)

模拟过程:80311229第一轮:Flag=0内循环①②不对交换flag=1结果:31801229次数②③不对交换结果:31128029(n-1)③④不对交换 结果:31122980 (找出最大值)∵flag=1继续第二轮:Flag=031122980(n-2)①②不对flag=1,交换12312980②③不对 12293180 ③④对不交换(找到次大值)75例4.9排序:将N个数从小到大排序(从大到小?)

模拟过程第三轮:flag=0(n-3)12293180 ①②对 flag=0 ②③对 flag=0 ③④对 flag=0∵flag=0∴不用再循环了次数:内循环,找到本轮最大值(执行n-1次) 外循环,找到n-1次最大值(n-1次)76第三轮:flag=076另一种情况80312912第一轮结果31291280flag=1,继续第二轮结果29123180flag=1,继续第三轮结果29123180flag=1,继续?没必要继续,所以n-1即可*外循环所剩次数=内循环所剩次数77另一种情况8031291277外循环 NN数据块长度-1→CXDX-CX标志BH=0起始地址内循环分别找到最大值、次大值BH=1?DX→CXCX=0?结束78外循环数据块长度-1→CXDX-CX标志BH=0起始地址内循4.10向内存送256个数据找出数据块中最大的正数将正数的高位移至低4位将正数的低4位的高4位变成ASCII码显示4.11子程序(略)794.1079求数组的和①求第一组的和参数:多少个数,数据首址

求和:al=[si]+al(add)

新元素原和

ah=ah+0+cf 修改地址,到下一个地址 和→[si](出口参数用存储器)80求数组的和①求第一组的和参数:多少个数,数据首址804.12定义两个十进制数数组,编程实现数组求和.在屏幕上显示.要求:主程序与子程序不在同一代码段.第一步:第一组数求和,并显示1.求和入口参数:通过入栈方式[bp+10]→CX [bp+12]→BX调子程保护Reg值subp1将数据用[bx]保存,和→al(处理十、个位) 处理百位→调整→ 和→[bx]最后BX指向sum1地址2.和变成ASCII码取高字节(用dl作替换用) 高4位→ASCII码→[bx] 低4位→ASCII码→[bx+1]3.从sum1+2处开始显示字符串的内容例:结果为02370/2/3/7/0d/oa/$/814.12定义两个十进制数数组,编程实现数组求和.在屏幕上显4.16编程.键入十进制数转换为十六进制

①用两个或以上的过程编写

②键入文件后,光标停在第二行开始.键入十进制数,第三行显示①十进制转为二进制;回车,换行;②二进制→十六进制;显示;回车换行①十进制→二进制(dec2bin)例123=(1×10+2)×10+3=(((0×10+1)×10+2)×10+3 CX AX⒈输入”1”,用ah=1,得到真正1的二进制码(subal,30h)⒉将al扩展,→AX824.16编程.键入十进制数转换为十六进制

①用两个或以上的第二次输入2ax=0002,bx=1xchg,ax=1,bx=0002mulcx,后ax=1×10addbx,ax后bx=1×10+2xchgax,bx;ax=12,bx=1×10第三次输入3 ax=1×10,bx=1×10+283第二次输入283②调回车换行 movdl,0dh movah,2 ret21h movdl,0ah movah,2 ret21h ret84②调回车换行84③二进制转为十六进制数,并显示和放在bx中例123=64+32+16+(1011)B =01111011=7BH bx=000000000111,10110000rotate:movcl,4;rolbx,cl;rol;右移4位后,取低8位中低4位(与0FH) addal,30h(bl) cmpal,3ah jlprintit;小于9,是0-9数字 addal,07hprintit:movdl,al movah,2 int21h decch→ch存放4次循环 jnerotate85③二进制转为十六进制数,并显示85演讲完毕,谢谢观看!演讲完毕,谢谢观看!第五节基本结构程序设计方法一、顺序程序设计二、

分支程序设计三、循环程序设计四、子程序设计

87第五节基本结构程序设计方法一、顺序程序设计1概述汇编语言程序设计的一般步骤流程图88概述汇编语言程序设计的一般步骤2汇编语言程序设计的一般步骤汇编语言程序设计一般有以下几个步骤:1.分析问题,确定算法2.绘制流程图3.根据流程图编制程序4.调试程序89汇编语言程序设计的一般步骤汇编语言程序设计一般有以下几个步流程图1.流程图的概念 流程图是由特定的几何图形、指向线、文字说明来表示数据处理的步骤,形象描述逻辑控制结构以及数据流程的示意图。流程图具有简洁、明了、直观的特点。2.流程图符号表示(1)起止框:表示程序的开始和结束。起止框90流程图1.流程图的概念2.流程图符号表示起止框4(2)判断框

(3)处理框

(4)调用框

91(2)判断框(3)处理框(4)调用框5(5)指向线

(6)连接框

92(5)指向线(6)连接框6一、顺序程序设计顺序结构顺序结构的程序一般是简单程序,其特点是程序顺序执行,无分支,无循环与转移。例4.4内存中TABLE开始存放0~9的平方值,通过人机对话,对任意给定的数(0~9),查表得的平方值,将其放在AL中。datasegmenttabledb0,1,4,9,16,25,36,49,64,81dufdb’pleaseinputontnumber(0~9):’0dh,0ah,’$’dataendsstacksegmentparastack’stack’stapadb100dup(?)codesegmentassumecs:code,ds:data,ss:stack93一、顺序程序设计顺序结构7start:pushaxmovax,datamovds,axmovax,stackmovss,axmovsp,topmovbx,offsettablenext:movdx,offsetbuf;9号功能调用,显示字符串,提示输入一个数movah,9int21h94start:pushax8movah,1;1号功能调入,等待键入一个数且送ALint21hmovah,0;查表得键入数的平方值andal,0fh;屏蔽高4位addbx,axmoval,[bx]movah,4chint21hcodeendsendstart95movah,1

二、分支结构一个大的程序完全顺序结构实际上并不可能,经常会遇到有分支的情况,分支结构程序通常采用条件转移或转移表来实现。典型的分支结构如教材图4.3所示。下面举例说明分支结构:例4.5给符号函数建立标志。=1当>0符号函数y=0当=0=-1当<0要实现符号函数,只要把从内存中取出来,执行一次“与”或“或”操作,就可以把的数值特征反映在标志上,再根据标志来转移。程序框图如教材图4.4所示。96二、分支结构10源程序如下:datasegmentxdw15ydw?dataendsstacksegmentstack’stack’db100dup(?)stackendscodesegmentassumecs:code,ds:data,ss:stack97源程序如下:11 start:pushaxmovax,datamovds,axmovax,xandax,axjzxerojnszeromovbx,offffhjmpdone

98 start:pushax12

zero:movbx,0jmpdoneplus:movbx,1done:movy,bxmovah,4chint21hcodeendsendstart

99zero:movbx,013

三、循环结构循环结构是程序设计中最常用的结构。凡需要重复做的工作,在计算机中都可以用循环结构程序来实现。循环程序有两种结构形式,一种是“先执行,后判断”,另一种为“先判断,后执行”。这后一种结构实现上允许0次循环,因而对有些程序更有效,它适合于循环次数不固定的程序。100三、循环结构14循环程序的常见结构形式101循环程序的常见结构形式15无论哪种循环结构,都包括以下四个部分:(1)初始化:为循环作准备,设置循环计数值,设置变量初值。(2)循环体:循环部分的核心,包括循环的全部指令。(3)修改参数:修改操作数地址,为下次循环作准备。(4)循环控制:修改计数器值,判断循环控制条件,决定是否跳出循环。对“先执行,后判断”结构,进入循环后至少要执行一次循环体,再判判断循环是否结束。对“先判断,后执行”结构,进入循环后,先判断循环结构条件,再决定是否执行循环体,可能循环体一次也不执行,即循环次数为0。102无论哪种循环结构,都包括以下四个部分:16例4.6若将内存2000H:0100H开始的256个字节的数据块移动到内存2000H:0200Hmovax,2000h;初始化,为循环工作准备movds,axmovsi,0100h;设置源数据块地址指针movdi,0200h;设置目的地址指针movcx,100h;设置循环次数next:moval,[si];循环体mov[di],alincsi;修改参数incdiloopnext;循环控制movah,4chint21h103例4.6若将内存2000H:0100H开始的256个字节的数例4.7BX寄存器中有一个16位二进制数,编程统计该数中1的个数,将其结果放到CL寄存器中。xorcl,cl;初始化,为循环作准备lopl:andbx,bx;循环控制jzstopshlbx,1:循环体jnclop1inccljmplop1stop:movah,4ch;程序中止int21h104例4.7BX寄存器中有一个16位二进制数,编程统计该数中有些循环结构比较复杂,需要用多重循环完成。多重循环设计方法与单重循环设计方法相,但应注意:(1)各重循环的初始控制条件及程序实现。(2)内循环可以嵌套在外循环中,也可以多层嵌套,但各层循环这间不能交叉,可以从内循环跳到外循环,不可以从外循环中直接跳进内循环。(3)防止出没死循环,即不能让循环回到初始条件,引起死循环。例4.8设有N个符号数,要求将这N个数由小到大排列。采用冒泡排序法。从第一个数据开始相信的数进行比较,若次序不对,两数交换位置。第一遍就完成了排序,这样共有两重循环105有些循环结构比较复杂,需要用多重循环完成。多重循环设计方法与datasegmentbufdb15h,37h,86hdb0a7h,0c8h,90h,7eh,50hdb80h,23hcoutequ$-bufdataendsstacksegmentstack’stack’sapdb100dup(?)topequlengthsapstackendscodesegment

assumecs:code,ds:data,ss:stack106datasegment20

start:movax,datamovds,axmovax,stackmovss,axmovsp,topmovbx,offsetbufmovcx,cout-1

107start:movax,data21lpo1:movdx,cxlpo2:moval,[bx]cmpal,[bx+1]jlenextxchgal,[bx+1]mov[bx],almext:incbxlooplop2movcx,dxlooplop1movah,4chint21hcodeendsendstart108lpo1:movdx,cx22四、子程序结构若一段指令语句在一个程序中多次使用,或在多个程序中用到,则通常把这段指令语句当作一个独立的模块处理,这段模块称为子程序或“过程”。需要执行这个模块时,就进行过程调用,执行完毕后,再返回原来调用它的程序。采用子程序结构编程,使程序结构模块化,清晰明了,容易修改。在汇编语言中,每一个子程序都包括在过程定义语句PROC…ENDP中间。过程定义有属性NEAR或FAR,若调用子程序的程序在同一代码段中,则用NEAR属性,若不在同一段中,使用FAR属性。109四、子程序结构231.子程序清单通常编写子程序或过程时,写一个子程序说明或清单,能使模块结构一目了然,且使调用者知道如何使用该程序。子程序清单包括:(1)子程序的名称,功能说明;(2)子程序中用到的寄存器和存储单元;(3)子程序的入口参数,出口参数;(4)子程序中调用其他子程序的名称。1101.子程序清单242.参数传递方法主程序与子程序相互之间可以传递参数。在许多情况下,希望子程序更具有通用性,更灵活,这时就希望子程序除了有使用说明外,还能够接受调用程序传来的入口参数,在子程序执行完毕后把出口参数传递给调用程序。参数的传递通有三种方法:(1)用寄存器传递:适合于参数较少的情况,传递速度较较快;(2)用存储器传递:适合参数较多的情况,需要先在存储器中建立一个参数表。(3)用堆栈传递:适合于参数较多且子程序有嵌套、递归调用的情况。1112.参数传递方法25例4.11在数据段中定义了两个数组,编程实现数组分别求和。datasegmentart1db12,23,34,45,56,67,78,89,90,18contlequ$-ary1sum1dw?ary2db13h,24h,57h,68h,9ah,0bch,0cdh,0deh,80h,80hcont2equ$-ary2sum2dw?dataendscodesegmentassumecs:code,cs:data112例4.11在数据段中定义了两个数组,编程实现数组分别求和start:movax,datamovds,axleasiary1;入口参数,数据块1首址movcx,cont1;入口参数,数据块1长度callsum;调用求和子程序leasi,ary2;入口参数,数据块2首址movcx,cont2;入口参数,数据块2长度callsummovah,4chint21h113start:movax,data27

sumproc;子程序sumxorax,ax;ax清0,存放和next1:addal,[si];数组元素相加adcah,0;高位放在ah中incsiloopmext1mov[si],ax;数组和存入内存单元retsumendpcodeendsendstar114sumproc【例4.8】试编写一程序,要求比较两个字符串STR1和STR所含字符是否相同,若相同则显示‘MATCH!’,若不相同则显示‘NOMATCH!’。(程序略) 其流程图如图4.7所示。

115【例4.8】试编写一程序,要求比较两个字符串STR1和STR图4.7程序流程图116图4.7程序流程图30【例4.9】试编一个程序将字单元BUF中所含1的个数存入COUNT单元中。要测出BUF字单元所含1的个数,首先将BUF中的数送给寄存器AX,然后将AX寄存器逻辑左移一次,如果CF=1,则表明AX中的最高位为1,则计数器CL计数1次,如果CF=0,表明AX最高位为0,这样依次将最高位移入CF中去测试。移位之后,判断AX的值是否为0,如果为0则结束循环,不为0,则继续循环。其流程图如图4.8所示。2.条件控制117【例4.9】试编一个程序将字单元BUF中所含1的个数存入CO11832程序如下:STACK SEGMENTSTACK DB200DUP(0)STACK EDNSDATA SEGMENT BUF DW0011110010101011B COUNT DB?DATA ENDSCODE SEGMENTASSUMEDS:DATA,CS:CODE,SS:STACK119程序如下:33START: MOV AX,DATA MOV DS,AX MOV AX,BUF MOV CL,0 ;计数器为0LOPA: AND AX,AX;使CF位为0 JE EXIT ;(AX)=0,结束循环

SHL AX,1 ;AX左移一位 JNC LOPA

INC CL ;产生进位,(CL)+1→CL

JMP LOPAEXIT: MOV COUNT,CL

MOV AH,4CH INT 21HCODE ENDS END START120START: MOV AX,DATA344.4.3多重循环程序设计【例4.10】在以BUF为首址的字存储区中存放有N个有符号数,现需将它们按大到小的顺序排列在BUF存储区中,试编写其程序。 我们采用冒泡排序算法从第一个数开始依次对相邻两个数进行比较,如次序对,则不交换两数位置;如次序不对则使这两个数交换位置。可以看出,第一遍需比较(N-1)次,此时,最小的数已经放到了最后;第二遍比较只需考虑剩下的(N-1)个数,即只需比较(N-2)次;第三遍只需比较(N-3)次,……整个排序过程最多需(N-1)遍。如下面的4个数即是采用冒泡排序比较的例子。1214.4.3多重循环程序设计【例4.10】在以BUF为首址数 10 8 16 90 32第一遍 10 16 90 32 8第二遍 16 90 32 10 8第三遍 90 32 16 10 8程序流程图如图4.9所示。122数 10 8 16 90 323612337程序如下:DATA SEGMENTBUF DW3,-4,6,7,9,2,0,-8,-9,-10,20N=($-BUF)/2DATA ENDSSTACK SEGNMENTSTACKDB200DUP(0)STACK ENDSCODE SEGMENTASSUMECS:CODE,DS:DATA,SS:STACK124程序如下:38START: MOV AX,DATA MOV DS,AX MOV CX,N DEC CX;设计数器CX内循环125START: MOV AX,DATA39LOOP1: MOV DX,CX;设计数器DX外循环 MOV BX,0LOOP2: MOV AX,BUF[BX]

CMP AX,BUF[BX+2]

JGE L;>=,不变,否则交换

XCHG AX,BUF[BX+2] MOV BUF[BX],AXL: ADD BX,2

DEC CX JNE LOOP2;相当于LOOPLOOP2 MOV CX,DX; LOOP LOOP1126LOOP1: MOV DX,CX;设计数器DX外循环40 MOV AH,4CH INT 21HCODE ENDS END START程序运行后,BUF区中的内容如下:20,9,7,6,3,2,0,-4,-8,-9,-10若要对N个无符号数按由小到大的顺序排列,只需将指令“JGEL”改为“JLEL”即可。127 MOV AH,4CH414.5子程序设计4.5.1子程序的概念4.5.2子程序的定义4.5.3子程序设计方法4.5.4子程序应用举例4.5.5子程序的嵌套与递归调用1284.5子程序设计4.5.1子程序的概念424.5.1子程序的概念

在程序设计中,我们会发现一些多次无规律重复的程序段或语句序列。解决此类问题一个行之有效的方法就是将它们设计成可供反复调用的独立的子程序结构,以便在需要时调用。在汇编语言中,子程序又称过程。 调用子程序的程序称为主调程序或主程序。

1294.5.1子程序的概念 在程序设计中,我们会发现一些多次4.5.2子程序的定义子程序的定义是由过程定义伪指令PROC和ENDP来完成的。其格式如下:过程名PROC[NEAR/FAR]┆过程名ENDP其中PROC表示过程定义开始,ENDP表示过程定义结束。过程名是过程入口地址的符号表示。一般过程名同标号一样,具有三种属性,即段属性、偏移地址属性以及类型属性。1304.5.2子程序的定义子程序的定义是由过程定义伪4.5.3子程序设计方法

温馨提示

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

评论

0/150

提交评论