收藏 分享(赏)

汇编语言程序设计及上机指导+第6章+结构化程序设计.ppt

上传人:jinchen 文档编号:5712215 上传时间:2019-03-14 格式:PPT 页数:35 大小:519.50KB
下载 相关 举报
汇编语言程序设计及上机指导+第6章+结构化程序设计.ppt_第1页
第1页 / 共35页
汇编语言程序设计及上机指导+第6章+结构化程序设计.ppt_第2页
第2页 / 共35页
汇编语言程序设计及上机指导+第6章+结构化程序设计.ppt_第3页
第3页 / 共35页
汇编语言程序设计及上机指导+第6章+结构化程序设计.ppt_第4页
第4页 / 共35页
汇编语言程序设计及上机指导+第6章+结构化程序设计.ppt_第5页
第5页 / 共35页
点击查看更多>>
资源描述

1、第6章 结构化程序设计,【本章提要】本章针对Intel系列微处理器的指令系统,首先介绍利用宏汇编工具MASM6.X实现结构化程序设计的方法,然后介绍模块化程序设计和宏结构程序设计,最后叙述汇编语言源程序的汇编、链接和运行调试的过程。 【学习目标】熟练掌握顺序、分支、循环结构程序设计方法熟练掌握子程序及宏机构程序设计方法掌握利用宏汇编工具MASM6.X的专用伪指令实现程序结构控制熟练掌握汇编与调试工具的应用,2019/3/14,6.1 分支和循环结构程序设计,1. 分支程序设计 一、用转移指令实现 假如要把连续存放在内存变量名DAT中的三个数按递减次序排列。,2019/3/14,二、用MASM6

2、.X伪指令实现 MASM6.X引入了条件控制伪指令,格式: .IF 条件表达式 ;条件为真(非0),执行分支体分支体 .ELSEIF 条件表达式 分支体 ;前面IF条件为假,并且当前ELSEIF条件为真执行分支体 .ELSE ;前面IF条件为假执行分支体分支体 .ENDIF ;分支结束例如: .IF AX0MOV BX,1 ;如果AX0,则将1存入BX .ELSEIF AX= =0MOV BX,0 ;如果AX=0,则将0存入BX .ELSE MOV BX,-1 ;如果AX0,则将-1存入BX .ENDIF,2019/3/14,条件表达式中的操作符及功能,2019/3/14,&的优先级高于|和!

3、 位测试运算符的用法为:“数值表达式&数值”,相当于执行TEST指令和相应的条件转移指令。 以下为采用&运算符的分支结构程序片段,功能为:若AX内容为奇数,则把全1送BX;若AX内容为偶数,则把0送入BX。 .IF AX&1 ;相当于TEST AX,1指令,也设置标志位,若ZF=0则执行第一分支MOV BX,0FFFFH ;第一分支 .ELSEMOV BX,0 ;第二分支 .ENDIF,2019/3/14,【例】 用条件控制伪指令实现有实根判别的程序,.MODEL SMALL .386 .STACK .DATA A SBYTE ? B SBYTE ? C SBYTE ? SIGN BYTE ?

4、 .CODE .STARTUP MOV AL, B IMUL AL MOV BX,AX ;BX中为B的平方 MOV AL,A IMUL C MOV CX,4 IMUL CX ;AX中为4AC .IF SWORD PTR BX=AX ;比较B的平方和4AC的大小MOV SIGN,1 ;条件成立,SIGN得到1 .ELSEMOV SIGN,0 ;条件不成立,SIGN得到0 .ENDIF .EXIT 0 END,2019/3/14,6.1.2 循环程序设计,一、用循环指令实现循环结构 例:计算l20的整数之和,并 将结果存入字变量SUM中 .MODEL SMALL .STACK .DATASUM D

5、W ? .CODE .STARTUP XOR AX,AX ;被加数AX清零 MOV CX,20 AGAIN: ADD AX,CX ;从20,19,2,1倒序累加到AX LOOP AGAIN ;每循环一遍,CX自动减1 MOV SUM,AX ;将累加和送入SUM单元 .EXIT 0 END,2019/3/14,二、用MASM 6.x循环控制伪指令实现循环结构 (1).WHILE结构的循环控制伪指令的格式为:.WHILE 条件表达式 ;条件为真,执行循环体循环体.ENDW ;循环体结束 例: 求5的阶乘12345,并送入指定单元的程序片段可以编写为:MOV AX,1 ;积AX初值设为1MOV CX

6、,2 .WHILE CL =5 ;该循环总共执行4遍MUL CL ;从1,2,3,4,5累乘INC CL.ENDWMOV MEMWORD , AX ;将乘积送入指定单元 (2).REPEAT结构的循环控制伪指令的格式为:.REPEAT ;重复执行循环体循环体.UNTIL 条件表达式 ;直到条件为真结束循环 如果要实现1100之间偶数求和,循环体程序片段可以编写为;MOV AX,0MOV CX,100.REPEAT ;是先执行后判断的结构ADD AX,CXSUB CX,2.UNTIL CX = = 0 ;直到CX内容为0结束,AX内容为偶数之和,2019/3/14,(3).REPEAT结构还有一

7、种格式:.REPEAT ;重复执行循环体循环体.UNTILCXZ 条件表达式 ;cxcx-1,直到cx=0或条件;为真结束 不带表达式的.repeat/.untilcxz伪指令将汇编成一条loop指令,即重复执行直到cx减1后cx=0; 带有表达式的.repeat/.untilcxz伪指令的循环结束条件是cx减l后等于0或指定的条件为真。 .untilcxz伪指令的表达式只能是比较寄存器与寄存器、寄存器与常数,以及存储单元与常数相等()或不等(!)。(4).BREAK伪指令和.CONTINUE伪指令.BREAK的功能是无条件退出当前循环;.CONTINUE的功能是转向循环体的开始,直接进入下一

8、轮循环,2019/3/14,【例】设ARRAY 是100字节的字符数组,分别统计出其中大写、小写字符的个数,并保存到相应单元,同时将所有字母单元内容改为数值55H,对0到9的阿拉伯数字不统计,也不修改,遇到其他字符则推出循环。程序如下: .MODEL SMALL .STACK .DATA ARRAY DB A,A,4,B,G,R,3,5 ;总共不超过100个 UP_ALP DB 0 ;大写字母个数,初值为0 DOWN_ALP DB 0 ;小写字母个数,初值为0 .CODE .STARTUP MOV BX,0 .WHILE BX=41H & ARRAYBX=61H & ARRAYBX=30H &

9、 ARRAYBX=39H ;阿拉伯数字INC BX.CONTINUE.ELSE ;其他字符,结束循环.BREAK.ENDIFMOV ARRAYBX,55H ;大小写字母单元都该为55HINC BX .ENDW .EXIT 0 END,2019/3/14,6.1.3 用中断指令实现简单输入输出 (1)从键盘读入一个字符 功能号:1 入口参数:无 出口参数:AL输人字符的ASCII码 功能:等待从键盘读入一个字符,将字符的ASCII码送给AL,同时将该字符显示在屏幕上。 调用方法: MOV AH,l ;AH中存放的是功能号INT 21H 说明:在输入一个字符后,不需要键入回车。若只键入回车,则出口

10、参数AL得到的是回车符的ASCII码0DH。(2)显示一个字符 功能号:2 入口参数:DL要显示字符的ASCII码 出口参数:无 功能:在当前光标位置显示DL中的字符,然后光标右移。 调用方法示例: 下列指令序列用来显示字符A MOV DL,A MOV AH,2 INT 2lH,2019/3/14,功能号;9 入口参数;DS:DX欲显示的字符串在内存的首地址。字符串必须以$作为结束标志,$不属于被显示的字符串。 出口参数:无 功能:在当前光标位置,显示由DS:DX所指的、以$为结束标志的字符串,然后光标右移。 调用方法示例: STRING DB Hello world!, 下列指令序列用来显示

11、String中的字符串Hello world!。 MOV AX,SEG STRING MOV DS,AX LEA DX,STRING MOV AH,9 INT 21H,(3)显示一个字符串,2019/3/14,功能号:0AH 入口参数:DS:DX输人缓冲区的首地址 输入缓冲区格式:第0个字节给出输入缓冲区最多能容纳的字符个数(1255,包括回车符),由应用程序设置;第1个字节将存放实际输人的字符个数(不包括回车符),由系统在读入字符串后自动设置;从第2个字节开始存放实际输入的字符串,最后为回车符的ASCII码0DH。 出口参数;无 功能:从键盘读入一个字符串,存入由DS:DX所指的输入缓冲区。

12、 说明: 在输入字符串后,必须以回车结束。 当输人的字符数达到了输入缓冲区所能容纳的字符个数减l时,随后的输入将不被系统接收,且响铃警告。调用方法示例:BUF DB 80 ;定义输入缓冲区,最多容纳79个字符与1个回车符DB ? ;存放实际输入的字符个数,由系统自动设置DB 80 DUP (?) ;存放实际输入的字符串 下列指令序列将从键盘读人字符串,并存入输入缓冲区BUF中MOV AX,SEG BUFMOV DS,AXMOV DX,OFFSET BUFMOV AH,0AHINT 21H,(4)从键盘读入一个字符串,2019/3/14,一、过程设计 在MASM 6.X中,带有参数的过程定义伪指

13、令PROC格式如下: 过程名 PROC 调用距离语言类型作用范围(起始参数)USES寄存器列表,参数:类型 ,参数:类型LOCAL 参数表 ;汇编语言语句 过程名 ENDP 其中,过程所具有的各个选项参数如下: 过程名:表示该过程名称,应该是遵循相应语言类型的标识符。 调用距离:可以是NEAR或FAR,表示该过程是近或远调用。简化段格式中,默认值由MODEL语句选择的存储模式决定。 语言类型:可以是任何有效的语言类型,确定该过程采用的命名约定和调用约定; 语言类型还可以由.MODEL伪指令指定。 作用范围:可以是PUBLIC,PRIVATE,EXPORT,表示该过程是否对其他模块可见。默认是P

14、UBLIC,表示其他模块可见;PRIVATE表示对外不可见;EXPORT隐含有 PUBLIC和FAR,表示该过程应该放置在导出表中。 起始参数:采用这个格式的PROC伪指令,汇编系统将自动创建过程的起始代码和收尾代码,用于传递堆栈参数以及清除堆栈等。起始参数表 示传送给起始代码的参数;它必须使用尖括号“”括起来,多个参数用逗号分隔。,6.2 子程序设计,2019/3/14,寄存器列表:指通用寄存器名,用空格分隔多个寄存器。只要利用“USES寄存器列表”罗列该过程中需要保存与恢复的寄存器,汇编系统将自动在起始代码产生相应的入栈指令,并对应在收尾代码产生出栈指令。 参数:类型;表示该过程使用的形式

15、参数及其类型。在16位段中,默认的类型是字WORD,在32位段中默认的类型是双字DWORD。参数类型可以是任何MASM有效的类型或PTR(表示地址指针);在C,SYSCALL,STDCALL 语言类型中,参数类型还可以是VARARG,它表示长度可变的参数。 如果过程使用局部变量,紧接着过程定义伪指令PROC,可以采用一条或多条LOCAL伪指令说明。它的格式如下:LOCAL 变量名 个数:类型, 其中,可选的“个数”表示同样类型数据的个数,类似数组元素的个数。在l 6位段中,默认的类型是字WORD,在32位段中默认的类型是双字DWORD。使用LOCAL伪指令说明局部变量后,汇编系统将自动利用堆栈

16、存放该变量,其方法与高级语言的方法一样。,2019/3/14,PROTO是过程声明伪指令,用于事先声明过程的结构。它的格式如下:过程名 PROTO 调用距离 语言类型 ,参数:类型语句中的各个项必须与相应过程定义伪指令PROC的各个项一致。使用PROTO伪指令声明过程之后,汇编系统将进行类型检测,才可以使用INVOKE调用过程。与PROTO配合使用的过程调用伪指令是INVOKE,它的格式如下:INVOKE 过程名 ,参数它自动创建调用过程所需要的代码序列,调用前将参数压入堆栈,调用后平衡堆栈。其中“参数”表示通过堆栈将传递给过程的实在参数,可以是数值表达式、寄存器、ADDR标号。“ADDR标号

17、”传送的是标号的地址(如果是双字DWORD类型则是段地址和偏移地址,如果是字WORD类型则是偏移地址)。,2019/3/14,例: .MODEL SMALLARRAYSUM PROTO C,:WORD,:WORD ;声明过程.STACK 100.DATACOUNT EQU 5 ;数组的元素个数ARRAY DB 2H,60,10H,13H,5 ;数组RESULT DB ? ;和.CODE.STARTUPINVOKE ARRAYSUM,COUNT,OFFSET ARRAY ;调用过程MOV RESULT,AL ;保存和.EXIT 0;计算字节和的过程,入口参数:ARRAYCOUNT数组的元素个数,

18、; ARRAYADDR数组的偏移地址,出口参数:AL和ARRAYSUM PROC C USES BX CX,ARRAYCOUNT:WORD, ARRAYADDR:WORDMOV BX,ARRAYADDR ;数组的偏移地址送BXMOV CX,ARRAYCOUNT ;数组的元素个数送CXXOR AL,ALSUMD: ADD AL,BX ;求和:AL AL十DS:BXINC BXLOOP SUMDRETARRAYSUM ENDPEND,2019/3/14,可以把不同的过程或功能模块放在不同的源文件中,分别编辑、汇编和调试,最后把各模块连接成一个可执行文件。 (1)EXTRN伪指令 格式一:EXTRN

19、 过程名 属性:声明当前程序将要调用的存在于当前文件之外的过程名,调用属性可以是NEAR或FAR,默认的属性为NEAR,当模块规模比较大时可定义为FAR。 格式二:EXTRN 变量名 属性:声明当前程序将要用到的,但却是在其它文件中用PUBLIC语句定义的公共变量,属性可以是BYTE、WORD或DWORD等。 (2)PUBLIC伪指令 格式:PUBLIC 变量名表/过程名表:定义当前文件中的变量名或过程名是可以被其它模块中使用的公共变量或者过程。,二、多模块编程,2019/3/14,【例6.7】 MAIN.ASM,EXTRN SUBPROG1:FAR ;定义远调用的外部的过程名SUBPROG1

20、 EXTRN SUBPROG2:FAR ;定义远调用的外部的过程名SUBPROG2 PUBLIC VALUE1,VALUE2,SUM,PRODUCT ;声明4个全局变量.MODEL SMALL .STACK 64 .DATA VALUE1 DW 2050 VALUE2 DW 500 SUM DW 2 DUP (?) PRODUCT DW 2 DUP (?) .CODE .STARTUP CALL SUBPROG1 ;调用其他模块中的过程SUBPROG1 实现相加运算 CALL SUBPROG2 ;调用其他模块中的过程SUBPROG2 实现相乘运算 .EXIT 0END,2019/3/14,子模

21、块1: SUB1.ASM,EXTRN VALUE1:WORD ;声明3个被用到的变量及类型EXTRN VALUE2:WORD EXTRN SUM:WORDPUBLIC SUBPROG1 ;声明SUBPROG1是可被其他模块调用的过程.MODEL SMALL.CODE SUBPROG1 PROC FARSUB BX,BX ;实现BX及CF的清零MOV AX,VALUE1 MOV DX,VALUE2ADD AX,X ;把VALUE1和VALUE2相加ADC BX,00 ;把进位放在BX中MOV SUM,AX ;16位和存放在SUM中MOV SUM+2,BX ;进位存放在SUM的高字RET SUBP

22、ROG1 ENDPEND,2019/3/14,子模块2: SUB2.ASM,EXTRN VALUE1:WORD ;声明3个被用到的变量及类型EXTRN VALUE2:WORDEXTRN PRODUCT:WORDPUBLIC SUBPROG2 ;声明它是可被其他模块调用的过程.MODEL SMALL.CODE SUBPROG2 PROC FARMOV AX,VALUE1MOV CX,VALUE2MUL CX ;实现VALUE1 和VALUE2相乘MOV PRODUCT,AX ;积的低16位存入PRODUCTMOV PRODUCT+2,DX ;积的高16位存入PRODUCT的高字 SUBPROG2

23、 ENDPEND ;模块结束,2019/3/14,上述3个文件分别汇编生成各自的目标程序(.obj)文件之后,就可以把他们连接到一起形成一个可执行文件(.exe)了。 连接时,LINK程序根据自动各模块中用PUBLIC和EXTRN伪指令声明的变量及过程进行匹配。 连接可以用的DOS命令为:LINK MAIN.OBJ+SUB1.OBJ+SUB2.OBJ 注意:各个模块的文件名与模块内部的过程名是没有关联的,模块之间的相互调用和返回都是通过过程名来实现的,与模块的文件名无关。,2019/3/14,一、宏定义 宏定义由MACRO伪指令和ENDM伪指令定义,其语句格式如下:宏指令名 MACRO 宏体E

24、NDM 下例是定义有一个参数的宏DISPCHAR,在屏幕显示参数所对应的字符: DISPCHAR MACRO DISCHARMOV DL,DISCHARMOV AH,2HINT 21H ENDM 二、宏引用和宏扩展 如有DISPCHAR 42H宏引用,则汇编程序会自动将该宏扩展为如下语句 序列: MOV DL,42H ;显示BMOV AH,2HINT 21H 注意:宏定义本身不生成任何目标代码,宏引用语句也不生成目标代码,它仅表示宏引用出现的位置,宏扩展时才生成代码。,6.3 宏结构程序设计,2019/3/14,:宏注释符,用于表示在宏定义中的注释。采用这个符号的注释,在宏展开时不出现。 例:

25、对8086的4条移位指令:shlshrsalsar,现在我们用宏指令movereg替代。这时,需要用参数表示助记符:movereg MACRO X,Y,Z;PUSH CXMOV CL,YS&X& Z,CLPOP CXENDM,该宏调用在汇编后的宏展开为:PUSH CXMOV CL,3 ;用实参3代替形参YSHL AX,CL ;用实参HL代替形参Z 并;与前面的S连接,用实参AX代替形参XPOP CX,三、几个宏操作符的使用,2019/3/14,为了方便09H号DOS调用,字符串的定义可以采用如下宏:DISPSTRING MACRO STRDB 实参个数少于形参,则多余的形参为空值.,2019/

26、3/14,1)宏引用语句由宏汇编程序识别,并完成相应的处理;而调用过程的CALL语句是在执行程序时完成的。 2)源程序在汇编过程中,要将宏指令所代替的程序段汇编成相应的机器代码,并插入到源程序的目标代码中。由于每引用一次宏指令,就要插入一次,因此宏引用不能缩短目标代码的长度。但是,被调用的过程经汇编后的机器代码是与主程序分开并独立存在的,其目标代码在存储器中只需保留一份。因此,采用过程调用能有效地缩短目标代码长度,即节省内存空间。 3)过程调用时需要保护程序的断点和现场,待过程执行完毕后还要恢复现场和断点,这些操作需要耗费CPU的时间,而宏引用不需要进行这些操作。因此,过程调用节省存储空间,但

27、降低程序的执行速度;而宏指令及其引用不能节省存储空间,但能有较快的执行速度。,四、宏指令与过程的比较,2019/3/14,6.4 汇编程序和汇编处理过程,一、源程序的汇编 1行汇编: 按行对汇编语言源程序逐条汇编DEBUG.EXE中的A命令就属于这种汇编类型 例: C DEBUG-A0AF5:0100 MOV AH,0080 0AF5:0103 ADD AH,10 0AF5:0105 MOV 0081,AH 0AF5:0108 HLT 0AF5:0109 C,2019/3/14,2宏汇编,首先对扩展名为.ASM的汇编语言源程序进行汇编,产生扩展名为.OBJ的可重定位目标代码文件,然后用连接程序

28、LINK连接一个或多个.OBJ模块(包括库文件),生成一个扩展名为.EXE的可执行目标文件,2019/3/14,MASM6.X包含了许多文件,最常用的文件如下: ML.EXE 汇编器 LINK.EXE 连接器 CV.EXE 调试器Code View (1)汇编器ML.EXE (Masm and Link) ML 可以自动调用LINK,实现对程序的汇编和连接。设源文件为MYPRG.ASM,汇编的基本命令格式为:ML /c MYPRG.ASM 其中,源文件MYPRG的扩展名.ASM不能省略。若程序无语法错误,则汇编后将生成MYPRG.OBJ文件。此外若不带参数/c,直接使用命令:ML MYPRG.

29、ASM 则ML将自动调用连接器LINK进行连接,生成MYPRG.OBJ与MYPRG.EXE,这样就不需要单独使用LINK命令。,MASM6.X介绍,2019/3/14,ML允许的选项,ML允许的选项有很多,常用选项如下: /AT 生成COM文件 / c 只汇编,不连接 /Fe 可执行文件名 指定生成的可执行文件名 /Fl 列表文件名 产生列表文件(LST),缺省与源文件同名 /Fm 映象文件名 产生映象文件(MAP),缺省与源 文件同名 /Fo 目标文件名 指定生成的目标文件名 /I 包含路径名 指定include文件的路径名ML除了产生目标文件与可执行文件外,还可以根据需要生成些其他文件,如

30、列表文件(.Lst)与映象文件(.map)。例如命令:ML Fl /Fm myprg.asm除了能生成myprg.obj与myprg.exe之外,还生成列表文件myprg.lst与映象文件myprg.map。,2019/3/14,(2)列表文件:是一个文本文件,其内容包括两部分: 第一部分,从左到右依次列出数据或指令在段内的偏移地址、机器代码和源程序。若程序中有语法错误,则列出错误信息。 第二部分, 列出了程序中定义的所有标识符的信息,比如段的名称、大小与长度,变量与标号的名称、类型与偏移地址等。 (3)映象文件 是一个文本文件,主要列出每个段的内存分配情况。其中给出了每个段的起点、终点、长度

31、、段名、类别以及程序执行的起始地址等。,2019/3/14,2019/3/14,关于DEBUG参数的说明: 进制:在DEBUG中输入或显示的数据都是十六进制形式; 分隔:命令和参数、参数和参数之间要用空格、逗号或制表符等分隔; 地址:用“段值:偏移量”的形式来表示地址,也可用段寄存器来代表“段值”;例如:1000:0,ds:10,cs:30等; 范围:用来表示地址范围,从哪个地址开始,到哪个地址结束。有两种表示方式:地址 地址前者表示起始地址,要用“段值:偏移量”来表达, 后者表示终止地址,只用“偏移量”来表示;地址 长度前者表示起始地址,要用“段值:偏移量”来表达,后者表示该区域的大小,用字

32、母L开头的数值来表示 例如:100:50 80 ;段值为100,偏移量从50到80的内存区域,100:50 L80 ;段值为100,偏移量从50开始的80个字节区域。 端口地址:二位十六进制数值 字节值: 二位十六进制数值 字节值表:由若干个字节值组成,也可以是用引号括起来的字符串,2019/3/14,DEBUG应用示例:,【例】启动DEBUG,并装入test.exe文件(假设该文件已存在)。方法1: 方法2: debug test.exe debug-n test.exe-l 【例】比较以DS为段值,偏移量从10到50的内存区域与从地址100:20开始的内存区域。-C DS:10 50 10

33、0:20 或 -C DS:10 L41 100:20 【例】显示以DS为段值,偏移量从10到50内存区域的单元内容,然后用ABC来填充它。-D DS:10 60 或 -D DS:10 L51-F DS:10 00 ABC 【例】显示十六进制1234与5678之和、差。-H 1234 5678 【例】把数据段区域DS:0-50H内的内容传送给从附加段ES:20H开始的内存中。-M DS:0 50 ES:20 【例】在数据段区域DS:0-80内查找是否有字符串CIH。-S DS:0 80 CIH,2019/3/14,【例】将AX寄存器的值设置为1234H,并显示当前各寄存器的内容 -R AX ;该行为输入的命令 AX 0000 ;该行为系统显示的AX寄存器原来的值是0 :1234 ;冒号为系统的提示符,1234为当前输入的新值 -R ;输入R命令并回车,以下显示为当前各寄存器的内容 AX=1234 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=0AF5 ES=0AF5 SS=0AF5 CS=0AF5 IP=0100 NV UP EI PL NZ NA PO NC 可以在第二行右半部看到FLAG寄存器中的标志含义:,

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

当前位置:首页 > 生活休闲 > 社会民生

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报