第05章汇编语言程序设计_第1页
第05章汇编语言程序设计_第2页
第05章汇编语言程序设计_第3页
第05章汇编语言程序设计_第4页
第05章汇编语言程序设计_第5页
已阅读5页,还剩118页未读 继续免费阅读

下载本文档

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

文档简介

会计学1第05章汇编语言程序设计1.方式选择伪指令(续)以下三条伪指令是MASM6.12引入的:.686——用于汇编PentiumPro到Pentium4微处理器非特权(实模式)指令.686P——用于汇编PentiumPro到Pentium4微处理器保护方式在内的所有指令.MMX——用于汇编MMX指令.K3D——用于汇编AMD微处理器3DNOW!指令。是MASM6.13引入的.XMM——用于汇编SSE和SSE2指令。是MASM6.15引入的2.完整的段定义使用完整的段定义伪指令来定义一个段,可具体控制汇编程序MASM和连接程序LINK在内存中组织代码和数据的方式。

整个逻辑段必须用段定义语句括起来。(1)SEGMENT——ENDS伪指令<段名>SEGMENT[定位类型][组合方式][段长度][分类名]

{段体}<段名>ENDS每个逻辑段都以SEGMENT语句开头,以ENDS语句结束;

两语句前的段名作为逻辑段的标识符,它必须是唯一的,确定该段在存储器中的位置。

第1页/共123页(1)SEGMENT——ENDS伪指令(续)段开始和结束语句之间部分是段的内容——

对数据段、堆栈段和附加段而言,一般由存储单元定义、分配等伪指令所组成,对代码段,则主要是由可执行指令以及某些伪指令组成。方括号中是定位类型、组合方式、分类名和段长度等的说明,视情况可以省略。若对本逻辑段在内存中的定位加以限定、或需与其它段相连接,则须按规定选择这些项。定位类型(Align-type)规定该段的起始位置。有以下几种选择:

BYTE:段的起始地址可以从任何单元开始,段间不留空隙,存储器利用率最高;

WORD:段的起始地址为偶数,即从字的边界开始;适合字类型的数据段定位;

DWORD:段的起始地址是4的整数倍,适合双字类型的数据段定位;PARA:段的起始位置是16的整数倍,即从节(24=16为一节)的边界开始;

PAGE:段的起始地址必须是256的整数倍,即从页(28=256为一页)的边界开始;

INPAGE:该段长度不超过256个字节(一页之内),不允许跨页存放。定位类型缺省时为PARA方式。第2页/共123页(1)SEGMENT——ENDS伪指令(续)组合方式(Combinetype)又称连接方式,规定连接程序LINK处理本段与其它逻辑段时如何进行相互连接。可以有以下几种:

NONE:本段与其它段无组合关系,这是缺省方式。也可用等价的关键字

PRIVATE。PUBLIC:在满足定位的条件下,将本段与其它具有PUBLIC属性的同名段连接

成一个连续的大逻辑段,公用一个段基址;连接次序由连接命令指定。

COMMON:本段和其它具有COMMON属性的同名段重叠,对各段指定相同的

起始地址(即段基址),因而产生复盖。COMMON连接后段的长度是

各连接段中最大段的长度。

STACK:把不同模块中具有STACK属性的同名段连接成一个连续的堆栈段,连

接后的堆栈空间是被连接的各个堆栈空间之和。LINK自动将新段的段

基址送SS,将新段的长度送SP;定义堆栈段时没有将其说明为

STACK类型,就要在程序中用指令给SS和SP赋值;连接程序LINK在

连接时会给出一个警告信息。

MEMORY:早期版本的选项,LINK不再单独区分MEMORY类型,将其视为

PUBLIC类型,MASM允许它继续使用,主要是为了与支持Intel

MEMORY类型的连接程序兼容。

AT<表达式>:定位本段在指定节的整数边界上,节号由表达式给出。AT方式

不能用在代码段中。使用AT方式的逻辑段中,用DB、DW预置

数据将失败。第3页/共123页(1)SEGMENT——ENDS伪指令(续)段长度

对32位微处理器新增了USE属性说明,又称段字说明。

对16位CPU,默认的段长是16位,不使用USE选项。

对32位CPU,有两种方式(默认选项是USE32):USE16:表示逻辑段最大长度为64K,访问该逻辑段采用16位寻址方式。USE32:表示逻辑段最大长度为4G,访问该逻辑段采用32位寻址方式。分类名

用单引号括起来的长度不超过40个字符的字符串。连接程序把不同模块中分类名相同的段组织成一类,存放在连续的存储区域。习惯上数据段/代码段/堆栈段的分类名分别用’DATA’/’CODE’/’STACK’表示。第4页/共123页(2)段分配语句ASSUME段分配伪指令ASSUME用来通知汇编程序:CS、DS、SS、ES将被设置成那些段的段基址寄存器,这样在汇编时就能知道语句中引用的变量和标号是通过那些寄存器进行访问的。ASSUME<段寄存器名>:<逻辑段名>[,<逻辑段名>…];[<段寄存器名>:<逻辑段名>

[,<逻辑段名>…];…;[<段寄存器名>:NOTHING]]伪指令语句ASUMENOTHING将删除所有已设置的段寄存器与段名之间的关联。ASUME伪指令只是建立段名和段寄存器之间的关联,并未把各个段的段基址装入相应的段寄存器中。段基址的装入通常采用程序方法。①DS和ES装入:在程序中用指令经通用寄存器间接装入段基址。②SS装入:有两种方法——

◆一种是在SEGMENT语句的组合类型中选用STACK,在ASSUME语句中建

立堆栈段与SS的关联,则连接时LINK自动给SS和SP赋予正确的初值;

◆另一种SEGMENT语句中组合类型未选用STACK参数,或者程序中使用了

另一个堆栈段,可用传送指令间接地给SS和SP赋初值(组合类型未选用

STACK参数,连接时LINK会给出警告信息)。③

CS和IP装入:对CS和IP,通常是按照结束伪指令END[<起始地址>]

指定的地址来自动完成段基址和偏移地址装入的。第5页/共123页(3)组定义伪指令GROUP当用段定义语句SEGMENT—ENDS定义了若干个逻辑段而总容量不超过64K时,就可把这些段用GROUP语句定义为一个“组”,格式如下:<组名>GROUP<段名1>[,段名2,……]GROUP把程序模块中若干个不同名字的段组合成一个组,并赋予一个组名,组内各段都装在一个物理段中,使组内各段间的跳转都视作段内跳转。语句中的段名可以是表达式SEG<变量名>或SEG<标号>,表达式的值是定义该变量或标号的段号。语句中的段名可以是表达式SEG<变量名>或SEG<标号>,表达式的值是定义该变量或标号的段号。

组名是标识组的起始地址的标号,表示该组的段基址。组中各个段内的偏移地址都以这个基址为起点,而不以本段原来的段基址为起点。组名的使用方法与段名相同。第6页/共123页3.定位语句(1)ORG语句汇编源程序时,汇编程序将段名填入段表,并为该段配置一个位置计数器(初值为0),该计数器依次累计段内语句被汇编后所生成的目标代码的字节数,跟踪汇编过程。

伪指令ORG能改变这个位置计数器的值,从指定位置分配代码或数据。格式:

ORG<数值表达式>数值表达式中可用“$”表示位置计数器的当前值,表达式的值为正整数;ORG语句把表达式的值赋给位置计数器。

在代码段,ORG语句后的指令语句就从指定位置生成目标代码;

在数据段,ORG后的数据定义伪指令就从指定位置分配所定义的数据。(2)EVEN语句格式:

EVENEVEN语句使段内位置计数器当前值$与偶地址对齐。

遇到EVEN语句时,若地址计数器值$为奇数,在代码段汇编程序自动插入一条单字节空操作指令NOP,使$变为偶数;在数据段自动将$值加1,使下面定义的数据从偶地址单元开始存放。第7页/共123页4.模块开始与结束语句(1)模块开始语句模块开始语句Name表示源程序的开始并为模块取名字,格式如下:

NAME<模块名>汇编程序将以语句中的模块名作为模块的名字。

也可使用title语句,格式:

TITLE<标题>title伪指令指定了在每一页上打印的标题,最多为60个字符。如果程序中没有使用NAME伪指令,则汇编程序MASM将用title语句中标题的前6个字符作为模块名。如果程序中既无NAME语句,又无TITLE语句,则将用源文件名作为模块名。(2)模块结束语句ENDEND表示源程序到此结束,并可指出程序的启动地址。格式如下:

END[标号/过程名]该语句一般放在源程序最后一行,程序中有且只能有一个END语句。其中标号或过程名给出了程序开始执行的启动单元地址,只有主模块才可有此选项。◆当连接的多个模块中都没有给出启动地址,将从代码段的第一个字节

处开始执行,

◆当有多个模块都指定了启动地址,将从最后一条带标号的END语句指

定的启动地址单元开始执行。

这些都可能导致程序的错误执行,编程时应予避免。

第8页/共123页5.返回操作系统方式

(1)使用功能号为4CH的DOS功能调用调用方式:

MOVAH,4CH ;功能号4CH送AH寄存器

INT21H ;DOS系统功能调用这是最有效且兼容性最好的返回DOS方式。(2)将主程序定义为远过程在代码段中,将主程序定义为远过程,由RET语句返回。 <主过程名>

PROCFAR

…;{主程序}

RET <主过程名>

ENDP(3)利用20H号BIOS中断调用这种方式只能用于扩展名为.COM的可执行文件。调用方式为:

INT20H(4)利用0号DOS系统功能调用该方式与INT20H一样,只有在.COM类型的文件中才可使用。调用格式如下:

MOVAH,0 ;功能号送AHINT21H ;DOS系统功能调用第9页/共123页5.1.2段定义的简化

在MASM5.0及以上版本中,段的定义可以非常简单,方便了程序设计。使用简化段定义伪指令前,必须先说明用户程序使用的内存模式。1.内存模式定义伪指令MODEL内存模式指用户程序的代码和数据的存放格式,及他们占用内存的大小。

.MODEL<存储模式>[,语言类型][,操作系统类型][,堆栈类型]①

存储模式:共有七种——TINY——微型模式。

程序中的代码和数据放在同一个64KB段内,程序为*.COM型,该模式是MASM

6.0才引入的。SMALL——小型模式。

这是一般程序的默认模式。程序中的代码和数据各放入一个64KB的段内,数据段、

堆栈段和附加段一起共用一个段。对代码和数据的访问通过近程调用(NEAR)

来实现。MEDIUM——中型模式。

程序中代码长度大于64KB,可安排在不同的段内;数据存放在一个64KB的段内;

因此代码访问是远程(FAR)的,数据访问是近程的。COMPACT——压缩模式。

程序中所有代码安排在一个64KB的段内,数据区可大于64KB,安排在不同的段

中(但任一数据段存储空间不得超过64KB)。对代码访问是近程的,对数据访问

是远程的。第10页/共123页1.内存模式定义伪指令(续)LARGE——大型模式。

程序中的代码和数据都超过64KB,但静态(常数)数据限制在64KB之内;对代码和数据的访问默认都是远程的。HUGE——巨型模式。

程序中的代码和数据均大于64KB,静态数据也可以超过64KB。对代码、数据和数组的访问都是远程的。FLAT——平展模式。

DOS下不能使用此模式。该模式用于创建32位的Windows程序,只能运行在32位的80x86微处理器上。②语言类型子程序语言类型用来告诉汇编程序使用什么样的标识符命名风格、子程序调用和返回约定等。语言类型说明可使汇编程序和其他语言程序共享。有效的语言类型为C、SYSCALL(系统调用)、STDCALL(标准调用)、BASIC、FORTRAN、PASCAL等。③操作系统类型OS_DOS是当前唯一支持的选项也是该选项的缺省值。④堆栈类型堆栈类型有如下两个选项,不同选值主要影响伪指令.STARTUP所生成的指令序列。NEARSTACK——堆栈段和数据段是同一个段。这也是该选项的缺省值。FARSTACK——堆栈段和数据段是不同的段,且堆栈段不在段组DGROUP中。第11页/共123页2.简化的段定义

(1)简化段定义伪指令简化段定义伪指令在.MODEL<存储模式>语句之后,如下所列。

每个简化段伪指令都可用来表示一个段的开始,同时也说明前一个段结束。.STACK[长度] ;定义堆栈段,长度缺省值为1KB.CODE[名字] ;定义代码段.DATA ;定义数据段.DATA? ;定义数据段,初值不确定.FARDATA[名字] ;定义远调用数据段.FARDATA?[名字] ;定义远调用数据段,初值不确定.CONST ;定义只读常数数据段.STARTUP ;程序起始点,并初始化DS、SS.EXIT0 ;程序结束点,返回操作系统上述简化段定义伪指令中带方括号的项可省略。

伪指令.EXIT0相当于MOVAX,4C00H和INT21H两条指令。

第12页/共123页(2)缺省段名使用简化的段定义伪指令,每个段都有一个缺省的段名,如下表所示。第13页/共123页2.简化的段定义(续)(3)等价段名MASM5.0宏汇编语言中规定了几个代替真实段名的等价段名,允许用@代替简化段定义伪指令前的小数点。如@CODE代表.CODE定义的段名,@DATA代表.DATA、.DATA?、.CONST和.STACK共享的组名,@FARDATA代表.FARDATA定义的段名,等等。(4)定义段序伪指令MASM可以对汇编结果的目标文件中各段的位置进行排序。

定义段序的伪指令有三种。.SEG——按照段在程序中出现的顺序对之排序。

这是完整段定义格式中的默认顺序。.ALPHA——按照字母顺序对段排序。.DOSSEG——按照DOS定义的标准段序。

即按代码段、数据段、堆栈段的次序对段排序。这是用.MODEL伪指令

的简化段定义格式中默认的顺序。

第14页/共123页3.源程序编程格式

(1).EXE文件编程格式该格式下源程序允许使用多个逻辑段,适合编写大型程序,汇编-连接后生成扩展名为.EXE的可执行文件。

.EXE文件编程格式的源程序最少有一个代码段。

代码段的开始用一条ASUME语句设置段约定。在实模式下,每个逻辑段的目标模块最大64KB;

在保护模式下,80286不超过16MB,32位的80x86不超过4GB。.ASM源程序汇编、连接后生成可执行文件.EXE,.EXE文件有重定位信息。

DOS装入.EXE文件,再根据重定位信息完成对目标模块的重定位,然后在目标程序的上方(低地址处)自动生成256个字节的程序段前缀PSP(ProgramSegmentPrefix),DOS通过PSP管理用户程序(如程序结束时返回DOS的途径等)。DOS自动使DS=ES=PSP的段基址,FS=GS=0,CS:IP指向用户程序的启动地址,SS:SP指向用户堆栈的栈顶。

然后DOS把控制权交给用户程序。由于DOS给DS、ES、FS、GS所赋的初值不等于用户程序数据段、附加段的段基址,因此用户程序开始处必须对所用的段寄存器DS(及ES、FS、GS)等进行初始赋值。第15页/共123页3.源程序编程格式(续)(2).COM文件编程格式该格式只允许源程序设置一个代码段(堆栈在代码段内),代码段的目标模块要小于64KB,适合编写中小程序。

在.MODELTINY伪指令定义的内存模式下即可生成.COM结构的源程序。程序中使用的数据可集中设置在代码段的开始或末尾,程序的启动指令须设置在代码段内偏移量为100H的单元处。.COM文件没有重定位信息,比.EXE文件要小得多。

DOS装载.COM文件时也在用户程序上方生成256个字节单元的程序段前缀PSP,PSP开始处存放一条中断指令INT20H(2个字节)。

DOS自动赋值使CS=DS=ES=SS=PSP的段基址、FS=GS=0,使IP=100H、SP=FFFEH,然后把控制权交给用户程序,CPU从CS:100H处开始执行用户程序。DOS在装入.COM文件时自动在用户区高端(高地址处)设置堆栈,.COM文件编程不需要设置堆栈。常见可执行文件的执行级别从高到低依次是.COM、.EXE、.BAT。

可用EXE2BIN.EXE软件将汇编-连接生成的小于64K的.EXE文件转换成.COM文件:

EXE2BIN<文件名[.EXE]><文件名.COM>前一个文件名后缀.EXE可省略,但后一个文件名的后缀.COM必须写上,否则将生成.BIN文件(它不能装入执行)。用高版本汇编TASM.EXE汇编.ASM文件后,只需在连接(TLINK.EXE)时使用小写的“t”做连接参数就可直接生产.COM文件。

第16页/共123页5.2汇编语言语句

5.2.1汇编语言汇编语言是面向机器的程序设计语言,是为特定的计算机系列设计的,使用英文宿写的指令助记符、符号地址及标号等编写程序语句。与其它程序类似,汇编语言源程序由语句行构成。1.汇编程序汇编程序的种类很多,主要功能基本相同:把汇编语言源程序翻译成二进制代码,但汇编的处理器指令集和伪指令语句集有所不同。

◆Microsoft公司的MASM宏汇编程序应用最广,有多种版本,版本越高

功能越全;

◆基本汇编程序ASM只能汇编8086/8088指令源程序,ASM是MASM的

一个子集,它不支持有关结构、记录、宏、条件汇编等伪指令和伪操

作符。

第17页/共123页2.语句分类

构成汇编源程序的语句可分为两大类:指令性语句和指示性语句。指令性语句就是指令语句,是CPU要执行的语句部分。

指令语句由汇编程序汇编、翻译成目标代码,一条指令语句对应一条机器语言指令代码,规定机器的一种操作。指示性语句不是计算机系统指令集提供的,因此又称为伪指令。

每种汇编程序都有自己的伪指令集,伪指令主要作用是为汇编程序服务,告诉汇编程序如何翻译指令语句、以及如何分配内存、定义数据、进行各种有关的处理(替换、条件汇编、连接、列清单等等)。

伪指令汇编时由汇编程序执行,不产生机器代码。第18页/共123页3.语句结构

指令性语句:[标号:] <助记符>[操作数][;注释]

指示性语句:[名字] <定义符>[操作数][;注释]<……>尖括号内的为必选项,[……]方括号内的为可选项。(1)标号和名字指令性语句中的标号后一定要跟冒号,而指示性语句中的名字后不能有冒号,这是两种语句在格式上的主要区别之一。标号在代码段中设置,表示本语句的符号地址,可作为转移指令或Call指令的目标地址,因而标号只出现在作为目标而被访问的语句中。名字可以是变量名、段名、过程名、符号名等,语句中是否出现名字及出现什么名字取决于定义符的要求。标号或名字可由下列字符组成:

英文字母(汇编程序一般不区分大小写)、数字0~9以及_$.?@%等。

除数字外的字符都可以作为第一个字符出现,若使用“.”符号则必须出现在开头位置。

组成标号或名字的字符可以有多个,但只有前31个被汇编程序识别和承认。第19页/共123页(2)助记符和定义符指令语句中的助记符表示该指令的操作码类型,规定了语句的操作功能,如ADD、LOOP等。

伪指令中的定义符规定了该语句的伪操作功能,由汇编程序进行处理。除了注释语句外,助记符或定义符是汇编语句中必不可少的项目。(3)操作数操作数项可以是常数、寄存器、标号、变量或者表达式。

操作数项的多少由指令或伪指令规定,在一项以上时,各项之间用逗号分开。

对指令语句,操作数项通常给出操作数的地址,一般不超过2个;

对伪指令语句,该项则给出所需的参数,可以有多个。(4)注释注释以分号开始,用来对一段程序或某些指令在程序中的作用加以说明,增加程序的可读性。注释不被汇编程序汇编,也不被执行。一条语句一般只占一行,超过一行要用续行符“&”指明。两条语句不能写在同一行上。汇编源程序语句最多由四个部分组成;书写时各部分之间要留有一定数量的空格,以使各语句的相应部分全部左对齐,使整个程序规范整齐,清晰明了。第20页/共123页5.2.2数据定义语句

1.变量定义语句用变量表示存储器数据,是汇编语言中普遍采用的方法。

变量名是存放数据的存储单元符号地址,变量值是对应存储单元的内容。(1)语句格式格式一:[变量名]<定义符><数据项表>[;注释]格式二:[变量名]<定义符><常数表达式>DUP(<数据项表>)[;注释]变量名是可选项,表示符号地址,标记该语句数据项表中第一个数据的偏移地址,变量的值就是该偏移地址单元的存储内容。定义符是必选项,用来定义数据项的类型属性,常用的有以下几种:DB——定义字节,项表的每个数据项为字节,类型属性为1;DW——定义字,项表的每个数据项为字(2个字节长),类型属性为2;DD——定义双字,项表的每个数据项为双字,类型属性为4;DF——定义长字,项表的每个数据项为三字(48位二进位),类型属性为

6,仅用于386CPU上的指针变量;DQ——定义四字,项表的每个数据项为四字,类型属性为8;DT——定义十个字节,项表的每个数据项为十字节,类型属性为10。

第21页/共123页(2)变量定义语句例举

DBYTE DB10,-10,10HDWORD DW100,-100,100HDDW DD4*20,0FFFDH;变量汇编存储结果见下图左

MESSAGE0DB`HELLO'MESSAGE1DB`AB'MESSAGE2DW`AB‘;变量汇编存储结果见下图中

BUF1DB0,?,?,?,0;“?”操作数可预留空间,不存入数据BUF2DW?,36,?;变量汇编存储结果见下图右第22页/共123页用地址表达式定义变量地址表达式的运算结果是一个地址(无符号数),指向某个存储单元;该存储单元若用来存放数据,则为变量,若存放指令代码,则为标号。

可以用已有确定值的变量或标号来定义一个新的变量显然只能使用DW或DD来定义。

DW用来将已知变量或标号的偏移地址定义为新变量,

DD用来将已知变量或标号的偏移地址和段基址分别置入新变量的低位字和高位字中。设程序中已定义了变量V1和V2,代码段中已定义了标号FIRS和LLT,则可用它们来定义新变量如下:

NV1DW FIRS ;把标号FIRS的偏移地址赋给字变量NV1NV2DD LLT ;把标号LLT的偏移地址和段基址赋给双字变量NV2NV3DW V1 ;把变量V1的偏移地址赋给字变量NV3NV4DD V2 ;把变量V2的偏移地址和段基址赋给双字变量NV4格式二用复制操作符DUP(Duplicationoperator)来复制或重复定义变量;

其中<常数表达式>的值应是一个正整数,用来规定DUP后括号中数据项表的重复次数。

ARRAY1DB2DUP(0,10,10H,?);等价于ARRAY1DB0,10,10H,?,0,10,10H,?ARRAY2DW100DUP(?)DUP操作可以嵌套:TAB1DB2DUP(1,2,3DUP(10)) TAB2DW10DUP(5DUP(2DUP(1100H,2200H)))上面第一条语句定义了TAB1开始的10个字节单元,其内容为1,2,10,10,10,1,2,10,10,10;

第二条语句定义了TAB2开始的200个(10×5×2×2)字单元,其内容为1100H,2200H重复2次(4个字单元)、再重复5次(5×4=20个字单元)、再重复10次(20×10=200字单元),TAB2数组有200个字单元,占400个字节存储空间。(3)变量类型属性变量被定义后具有相应的值,还具有类型属性,变量表达式的类型属性和变量相同。汇编程序用类型属性来表明指令操作数的字节长度。指令在执行运算时,操作数作为参加运算的对象,其类型属性必须相同,否则出错。第23页/共123页2.标号

标号表示指令性语句的符号地址,作为转移类指令的目标操作数,一目了然地确定程序转移的目标地址。(1)标号属性段属性(SEG)

表示标号所在段的段基址。偏移属性(OFFSET)

表示标号在段内的偏移地址(从段基址到标号位置之间的字节数),是16位或32位无符号数。距离属性(TYPE)

也叫类型属性,指出标号被访问的段别:

近程NEAR——只允许在本段内被访问的标号,

指令性语句标号之后必须有一个冒号,这个标号的默认属性为NEAR。远程FAR——允许其它段跨段访问的标号。标号也可以作为过程定义语句的过程名,用作调用指令的目标地址。(2)更改属性的伪指令标号和变量,其属性可用PTR伪指令临时指定,用THIS和TABLE伪指令另行指定。第24页/共123页2.标号(续)PTR属性操作符格式:<类型>PTR<变量或标号[±常数表达式]>其中变量类型可以是BYTE、WORD、DWORD等,标号类型可以是NEAR或FAR。PTR临时指定某个变量、标号或地址表达式所指存储单元的类型或距离属性,使其具有语句左边的<类型>属性(与原定义的不同)。例: BUF3DB 1,2 BUF4DW3456H,7890H… MOVAX,BUF3+1 ;出错,操作数类型不匹配

MOVBL,BUF4 ;出错,操作数类型不匹配汇编程序在汇编这段程序时,发现两条MOV指令的类型属性不同:第一条MOV指令AX为字类型而BUF3+1为字节类型,第二条MOV指令BL为字节类型而BUF4为字类型,因而出错并提示:(这两条指令)操作数类型不匹配。用PTR运算符改变它们的属性,改正如下:

BUF3DB 1,2 BUF4DW 3456H,7890H … MOVAX,WORDPTRBUF3+1;5602H送AXMOVBL,BYTEPTRBUF4;56H送BL第25页/共123页2.标号(续)THIS属性运算符格式:

THIS<类型>THIS运算符常与伪指令EQU、=连用,为当前存储单元定义一个指定类型的变量或标号。THIS不分配新的存储单元。例: BUF EQUTHISWORD POT EQUTHISFAR第一(或第二)条语句表示从本语句开始,变量BUF(或标号POT)的类型属性就定义为字(或FAR),而不管BUF(或POT)原来的类型是什么,直到遇到新的类型定义语句为止。LABLE伪指令LABEL语句用来给变量或标号取一个别名,并可重新定义它的类型属性。这使得同一个变量或标号以不同的名字引用时具有不同类型的属性。格式:<名字>LABEL<类型>被LABEL定义的名字,其位置与紧跟在该语句下面的指令(变量定义伪指令或带标号的指令)具有相同的段基址和偏移地址。例:BARRAY LABELBYTEDARRAY DW100DUP(?) MOVBRRAY+2,0 MOVDARRAY+2,0BARRAY和它下面的DARRAY的地址是相同的,它们指向同一数组。BARRAY被定义成字节型,第一条MOV指令把该数组的第3个字节置0;DARRAY被定义成字类型,第二条MOV指令把该数组的第3个字(即第4和第5个字节)置0。第26页/共123页3.符号定义语句

为方便程序设计,对程序中多次出现的同一个常量、字符串或表达式,可以用符号定义伪指令赋予一个符号名;也可给某些符号取新的名字并赋予新的类型属性。符号定义语句不占用内存。(1)等值语句EQU格式:<符号名>EQU<表达式>表达式可以是数值、地址、新类型属性或其它符号名,

EQU将左边的符号名赋给表达式,使它们完全等价。在程序中可方便地用符号名代替表达式。例:

PORT1EQU20HPORT2EQUPROT1+1BUF_SIZEEQUPORT2*2COUNTEQUCX;COUNT代表CX寄存器

B8EQU[BP+8];B8代表地址引用[BP+8]CHAREQU‘C’CBDEQUDAA;CBD代表指令助记符DAA

…DECCOUNT;将CX寄存器内容减1第27页/共123页3.符号定义语句(续)(2)等号语句=等号语句功能与EQU语句相同,但是等号语句定义的符号名在程序中可重新定义,并且表达式只能是数值表达式。例:

DAT=100 ;DAT定义为100 COUNT=DAT+10 ;COUNT定义为110 LLP=3 ┆ COUNT=COUNT-20 ;重新定义COUNT为90 DAT=200 ;重新定义DAT为200LABLE可定义新的符号并赋予不同的属性;THIS、PTR可和EQU、=等伪指令连用,赋给新定义的符号以不同的属性。第28页/共123页4.常量

常量又叫常数,在汇编时有确定的值,一般在程序执行过程中不再改变。常量主要用于伪指令语句中给变量赋值,也用做指令中的立即数或存储器操作数的组成部分。常量可用数值形式直接写在指令语句中,也可预先为它定义一个名字保存在存储单元内。数值常量——常用作语句操作数项中的常数,可以是二、八、十六或十进制数,分别在数值末尾加“B”、“Q”(或“O”)、“H”和“D”标记。

数尾不加标记的,汇编程序默认作十进制数。伪指令RADEX可以把默认的基数改变为2~16范围内的任何基数:.RADIX<基数表达式>其中基数表达式的结果为2~16之间的十进制整数,用来表示基数值。下面两组指令是等价的:

MOVBX,0FFH .RADIX16MOVCX,178 MOVBX,0FF MOVCX,178D第29页/共123页4.常量(续)字符常数

是保存在单引号或双引号内的ASCII字符串。

定义多于2个字符的字符常数,必须用DB伪指令;

仅有1或2个字符,用伪指令DW、DD、DQ、DT都行。浮点常数

用十进制数科学计数法表示,如

SINEDD0.538E-1。十六进制实常数

与十六进制常数相似,但第一个字符必须是数字(0~9),数尾紧跟字母R,而且其位数必须是8、16或20。

HRNUMBDD0BAEF1234R5.表达式和运算符

表达式:用运算符连接变量、标号、常量等数据形式的式子。

表达式可作为语句中的数据项,由宏汇编程序进行计算,将所得结果作为指令的操作数,执行指令所规定的操作。

表达式的计算在汇编时完成,指令的运算在程序执行过程中完成。表达式的结果是一个数值则称为数值表达式,结果是一个存储单元的地址时则称为地址表达式。地址单元中存放的是数据则称为变量,地址单元中存放的是指令则称为标号。第30页/共123页MASM宏汇编程序中的表达式由操作符和操作对象组成,允许使用的操作符有六种类型,可进行算术运算、逻辑运算、关系运算、回送运算、修改类型属性运算与专用运算等。如下表所示。第31页/共123页MASM对方括号的地址表达式有如下的规定:①只有基址寄存器BX、基址指针BP、变址寄存器SI和DI可以出现在[]内。②BX或BP可单独出现在[]内,也可单独与SI或DI以及常数一起出现在[]内;但BX和BP不允许同时出现在[]内。③SI或DI可单独出现在[]内,也可单独与BX或BP以及常数一起出现在[]内;但SI和DI不允许同时出现在[]内。④一个[]内含基址和变址寄存器时,它们只能做加法运算;相加的基址和变址寄存器可以写在两个相邻的[]内。⑤当[]内包含基址指针BP时,约定的段基址由堆栈段寄存器SS提供,否则均隐含使用数据段寄存器DS。⑥相加的常数可以写在[]之外。⑦方括号内还可以是表达式,其值表示数组变量的下标。第32页/共123页5.2.3结构化数据定义

MASM宏汇编还支持有关结构、记录、联合等有结构的数据类型。1.结构定义语句结构是指一组相互关联变量的组合,例如学生成绩登记表中一个学生所登录的各项:学号、姓名、性别、课程名称、考试成绩等。

结构类型变量可把类似上述一个学生的各项看成一个整体,定义、赋值、修改、引用都大为方便。

(1)结构类型的定义格式:<结构类型名>STRUC

…{数据定义伪指令序列} <结构类型名>ENDS 例:为学生考试成绩登记表定义一个结构

STUDTABSTRUC NAME DB'WANGWEIHUA' ;姓名

SNO DD20020923H ;学号

SEX DB1 ;性别:0为女,1为男

COURSE DB'ASSEMBLER' ;课程名

SCORE DB90 ;成绩

STUDTABENDS第33页/共123页(2)结构变量的说明

格式:[结构变量名]<结构类型名><<[字段初值表]>>其中结构变量名由用户起,是可选项,没有它汇编程序照样分配空间。结构类型名是已定义的结构类型;<字段初值表>用来给结构变量的字段赋初值,它们的类型、顺序必须与结构类型名定义的一致,各初值之间以逗号隔开。

若某字段的初值采用结构类型定义时的初值,可空缺不写(但相应逗号不可省),若所有字段全部采用定义时的初值,可只写一个尖括号<>;

尖括号<>在任何时候都不可省。 例:利用已定义的STUDTAB结构类型说明考试成绩登记表中某学生的结构变量。

STUDENT1STUDTAB<>;各字段初值全部采用结构类型定义时的初值

STUDENT2STUDTAB<'ZHANGMING',20010907H,0,'PASCAL',85> ;各字段初值重新赋值

STUDENT3STUDTAB<'LIWEIDONG',20020918H,,'ENGLISH',> ;性别和成绩字段采用结构定义时的初值;

;下面说明一个50个学生的结构数组,各字段初值采用结构类定义时的初值。

CLASS2STUDTAB50DUP(<>)第34页/共123页(3)结构变量字段值的修改

定义结构类型时可为各字段设置初值,说明结构变量时可对字段初值进行修改,使用结构变量时仍可对它们各个字段进行修改。只有用DB、DW或DD加以说明的单项字段才能被修改字段值,

而用重复运算符DUP说明的多重字段不能被修改。

对字符串类型的字段,修改后串的长度不能超过定义结构类型时的长度。(4)结构的使用结构类型定义在先,一般定义在程序的开始部分,也可定义在数据段中;结构变量说明在后,通常在数据段中加以说明;

最后在代码段中对结构变量及其字段加以引用,包括对它们的值进行修改。对结构变量的引用,与引用其它变量一样,可以通过名字对结构变量进行存取。要引用结构变量中的字段,可使用点运算符,形式为:结构变量名.结构字段名例:取出结构变量的字段MOVAL,STUDENT2.SCORE;取出学生结构变量STUDENT2的成绩字段值送AL下面两条指令完成的操作与上面一条指令相同:

MOVBX,OFFSETSTUDENT2 MOVAL,[BX].SCORE第35页/共123页2.记录定义语句

记录用于处理按二进制数位计算的数据信息。使用记录,需要先定义记录类型,再说明记录变量,然后再使用记录。(1)定义记录类型格式:<记录名>RECORD<字段名>:<宽度>[=表达式][,<字段名>:<宽度>…]

记录名与字段名由用户起,程序中记录名不允许重名,同一记录内字段名不允许重名。宽度必须是常数,表示该字段所占二进位的位数;表达式为可选项,表示该字段的初值,未选时初值为0。一个记录中可有多个字段,它们之间用逗号隔开。16位微处理器方式,所有字段宽度之和不得超过16。宽度之和超过8时占用2个字节,汇编程序按字处理,否则按字节处理。若选用了386及以上方式,各字段宽度之和最多可达32;超过16位时,占用4个字节,按双字存放和处理。例:定义一个表示学生情况的记录,年龄占6位,性别占1位(0女,1男),健康状况占一位(0健康,1不健康)

STATUSRECORDAGE:6=19,SEX:1,HEALTH:1 与结构一样,记录类型定义时不分配存储空间。(2)记录变量说明格式:[记录变量名]<记录名><<[字段初值表]>>

记录变量名由用户定义,可以省略(照样分配内存),记录名是已定义的记录类型,字段初值表给各字段赋初值,各初值之间用逗号隔开,各项的顺序应与记录类型定义时的顺序一致;若某字段值采用记录类型定义时的初值,则可省略,仅写逗号即可;若全部字段都采用定义时的初值,则仅写尖括号。尖括号在任何时刻都不能省略。第36页/共123页2.记录定义语句(续)例:用记录类型STATUS定义记录变量

ZHANG1STATUS<17,1,0> 被分配一个字节的记录变量ZHANG1在内存中的分配形式为01011110,即该记录变量的值为5EH。

WANG3STATUS<,0,0> WANG3记录变量前6位为011001(记录类型定义的初值),后两位为00,该记录值为64H。STUDEN1STATUS<> 记录变量STUDENT1为一个字节,各字段值采用记录类型定义时的初值,为67H。CLASS1STATUS50DUP(<18,1,0>) CLASS1是个记录数组,共有50个元素,每个元素的三个字段初值分别为18、1、0,记录值为62H。(3)记录的使用可通过记录变量名对记录进行访问,记录变量名可以像其它变量名一样使用。 例: MOVAL,ZHANG1 ;AL←5EH(ZHANG1记录的值)记录变量可作为操作数(立即数)使用。 例:MOVAH,STATUS<18,1,0> ;AH←62H记录的字段名可在程序中直接使用,表示一个位移量,即该字段位移到记录的最低位所需的移位次数。 例:MOVCL,SEX ;CL←1(SEX移到记录最低位的次数)第37页/共123页2.记录定义语句(续)给记录变量(或记录数组元素)的某字段赋值时不应破坏其余字段上的值,先用AND指令对该字段清0,再用OR指令将相应值设置在该字段上。对记录数组元素的寻址与一般的字节、字或双字的数组一样,而对记录数组元素的某一字段访问与对记录变量的字段访问类似,只是将记录变量名换为记录数组元素的地址表达式。

例:把前面说明的记录数组CLASS1的第三个元素的AGE字段设为18。可先取得第三个元素的起始地址,取出该元素字节值,将AGE字段清0,然后将字段值18送一个寄存器,并移位到高6位,再用OR指令置成相应值。指令序列如下:

MOVSI,OFFSETCLASS1 ;记录数组的起始地址送SI ADDSI,2 ;生成第三个元素的起始地址

MOVAL,[SI] ;AL←第三个元素的字节值

ANDAL,03H ;将AGE字段清0

MOVAH,18 ;AH←18 MOVCL,AGE ;CL←移位次数2

SHLAH,CL ;AH左移2位,使18与AGE字段对齐

ORAL,AH ;将18置在AGE字段上

MOV[SI],AL ;将修改后的结果送回第三个单元

第38页/共123页3.联合定义语句

联合UNION也是一种结构性的数据类型,是MASM6.0新增的,实际上是对结构STRUC的一个补充。(1)联合类型定义格式:<联合名>UNION

┆{联合体,由数据定义语句构成} <联合名>ENDS

该语句定义了一个联合类型,与STRUC类似,联合体中的各字段由数据定义伪指令设置,但各字段的偏移地址与STRUC不一样:STRUC中的字段在结构中顺序分配,而UNION中的字段在联合中从起始地址处重叠分配,所以联合中各个字段的偏移地址均为0。因此定义联合时字段不赋初值。定义UNIMING的联合类型: UNIMING UNION XA DB? XB DB? XC DW? XD DD? UNIMING ENDS第39页/共123页(2)联合变量说明

格式: <变量名><联合名><<字段值表>> 字段值表须用尖括号<…>括起来,有关规定与结构变量相同。 定义一个联合变量,分配存储空间并给它的各个字段赋初值。 例:定义联合变量

BIANLUNIMING<12345678H>后,

它的各个字段值如下:BIANL.XA=78HBIANL.XB=78H

BIANL.XC=5678HBIANL.CD=12345678H对联合变量的字段访问可用:联合变量名.字段名。结构和联合的定义可互相嵌套,这类定义适用于面向对象程序设计的结构和I/O端口的描述。

第40页/共123页5.2.4其它汇编技术

1.重复汇编重复汇编伪指令又称重复块伪指令,用来缩写若干重复的语句,以便重复进行多次。重复块可看着是宏展开的一种特殊形式,在汇编时展开。重复块也可带有形式参数,在汇编过程中被实际参数代替;但重复块没有名字,不能进行调用,只在原处重复若干次。重复块伪指令共有三种:REPT、FOR(或IRP)和FORC(或IRPC),它们都用ENDM伪指令来结束,区别只是设置重复次数的方法不同;括弧中的伪指令名字是MASM5.X版本中使用的,在后续版本中仍可使用。(1)按参数值重复汇编 格式:

REPT<表达式>

…{重复的语句序列}

ENDM 其中表达式的值为REPT与ENDM之间的语句序列重复展开的次数。例:

TABLELABLEBYTE ;等价于

TABLELABLEBYTEX=0 ;DB1REPT5 ;DB2X=X+1 ;DB3DBX ;DB4ENDM ;DB5第41页/共123页1.重复汇编(续)(2)按参数个数重复汇编 格式:

FOR(或IRP)<形式参数>,<<实际参数表>>

…{重复的语句序列}

ENDM FOR(或IRP)与ENDM之间的语句对每个实际参数都执行一次,重复次数为实际参数的个数,实际参数必须用尖括弧括起来,在执行过程中用当前的实际参数去代替形式参数。 例

TABLELABELBYTE IRP X,<1,2,3,4,5>DB XENDM该段程序与上例是等价的。第42页/共123页1.重复汇编(续)(3)按参数字符个数重复汇编 格式:

FORC(或IRPC)<形式参数>,<字符串>或<<字符串>>

…{重复的语句序列}

ENDM 重复执行FORC(或IRPC)与ENDM之间的语句,每次都用当前字符中的字符去取代形式参数,重复的次数为字符串中字符的个数。如果字符串中包括空格、逗号或其它分隔符,则字符串必须用尖括号括起来。例:

TABLELABELBYTE IRPCX,12345 DBX ENDM该程序段与前2例是等价的。第43页/共123页2.条件汇编

条件汇编伪指令可根据条件对源程序块有选择地进行汇编,从而把某段指令序列包含在汇编语言源程序内,或者不对某段指令序列进行汇编。格式:

IF<条件> <语句序列1> [ELSE <语句序列2>]

ENDIF其中条件是伪指令助记符的一部分,

ELSE语句及其后的语句序列2是可选部分,

条件为真执行语句序列1,

为假执行语句序列2或者ENDIF之后的语句。

整个条件汇编以语句ENDIF结束。汇编条件有六组,见下表。

第44页/共123页第45页/共123页3.宏汇编

对程序中多次重复使用的指令序列,可给它取个名字,定义成一个宏,在源程序中书写宏名就代表这个指令序列。汇编时把宏名展开成该指令序列,从而减少了程序的编写量,使源程序更加简练、清晰。(1)宏定义格式:<宏名>MACRO[形式参数表]

…{宏体}

ENDM宏名必须唯一,宏调用时用来代替所定义的宏体(具体内容),宏体由汇编语言所允许的任何语句(指令或伪指令)组成,它决定了宏的功能。

形式参数根据宏体需要可以没有,或者有一个或多个;有多个形式参数时相互之间要用逗号或空格或制表符分隔开。

调用宏时要依次用对应的实参去取代。宏体中可以定义或调用另一个宏。定义一个宏,相当于增加了一条伪指令,汇编时告诉汇编程序用宏体来代替该名字。宏要先定义,后调用。宏定义一般放在源程序文本的开始处,而不放在某一个段内。第46页/共123页3.宏汇编(续)例:定义一个宏,参数为0时执行输入的DOS功能调用,否则执行输出的DOS功能调用。

INOUTMACROP IFP MOVAH,2 INT21H;输出DL中的字符

ELSE MOVAH,1INT21H;输入的字符送ALENDIF ENDM第47页/共123页3.宏汇编(续)(2)宏的调用与展开格式:<宏名>[实际参数表] 宏名必须是已定义的,实际参数表中参数的类型和顺序应与宏定义时的形式参数一一对应;实参个数多于形参时,多余的实参被忽略;实参个数少于形参的,多余的形参用空串取代。汇编源程序时,汇编程序要对源程序中所有的宏调用进行展开,即将宏名所定义的指令序列插入到宏调用处。宏与子程序(即过程)有所不同。宏调用是把宏体展开,程序中有几处宏调用就展开几次,源程序代码长,不节省存储空间,但展开后执行速度快,节省运行时间;子程序调用不展开子程序代码(子程序仍存储在原处),但改变程序流程,由主程序调用处转入子程序去执行,执行完毕再返回主程序调用处继续执行,子程序调用前后要保护和恢复现场,因此执行时间长,但节省存储空间。第48页/共123页3.宏汇编(续)(3)宏操作符

宏汇编程序MASM提供了相应的宏操作符,用于宏参数的传递连接,如下表所示。(4)宏的删除PURGE当宏在程序中调用完之后而再也用不到时,可用PURGE伪指令删除之,以释放它所占用的存储空间。格式:PURGE<宏名>[,宏名…]第49页/共123页3.宏汇编(续)(5)宏库为避免重复定义的麻烦,可将通用的宏定义集中放在一个单独的文件中,即放在后缀为.MAC的宏库文件中,宏库中可以有多个宏定义。可用任一个编辑程序像建立源程序那样来建立宏库。宏库中的宏必须是通用的例行程序或程序段,对宏中使用的寄存器及状态标志要入栈保存,宏定义中的标号要先用Local伪指令定义(限定只在宏内使用)。在程序中可用INCLUDE伪指令将宏库中的宏定义复制到该指令所在的位置:

INCLUDE[盘符:\路径\]<文件名>[.扩展名]

INCLUDE功能是通知汇编程序把指定的文件拷贝一份,插入到该语句下方,供汇编使用。如INCLUDEMLIB.MAC语句将宏库中MLIB.MAC的全部宏定义复制出来。

一般INCLUDE伪指令也放在源程序的开始部分。为避免汇编程序两次扫描都去重复读宏库文件,可用条件汇编IF1使宏库文件只在第一遍扫描时读入:

IF1 INCLUDEMLIB.MAC ENDIF

…第50页/共123页5.3汇编语言程序上机过程

汇编语言程序上机运行的过程有以下几个步骤:(1)

用编辑程序建立.ASM源文件;(2)

用宏汇编程序MASM等汇编源文件,生成.OBJ目标码文件;(3)

用连接程序LINK对目标码文件等模块进行连接,生成.EXE可执行文件;(4)

键入可执行文件名执行该文件,分析执行结果;(5)用DEBUG等工具调试.ASM源程序,再汇编、连接、运行,直到得出正确结果。 为此,除了DOS系统软件和编辑程序外,还需要备置如下程序:汇编程序

masm.exe或asm.exe或tasm.exe等连接程序

link.exe或tlink.exe等汇编调试程序

等交叉引用程序

cref.exe等

第51页/共123页5.3.1编辑源程序

可使用任何一种能建立ASCII文本文件的编辑程序来建立汇编源程序文件,扩展名为.ASM。在使用各种文字编辑程序时,被编辑的源文件(.ASM)中不应有排版格式控制符。5.3.2汇编源程序编辑生成的.ASM源程序文件,须经汇编程序进行汇编,生成二进制代码的目标文件。常见的汇编程序有行汇编和宏汇编两种类型。

◆行汇编——常用DEBUG.EXE的A命令,生成的目标代码可作为.COM

文件存盘,也可在DEBUG环境下直接运行。

行汇编简单直观,生成的目标程序所占用的内存空间最小;但汇编按

绝对地址进行,长度限制在64KB范围内,目标程序没有与其它程序模

块连接的信息,要由用户或安装程序实现各个目标程序在内存中的地

址分配,这样既可能使各程序之间产生太大的空隙(造成浪费)、也

可能造成各程序的内存存储冲突。

◆宏汇编MASM——对汇编语言源程序*.ASM进行汇编常用方法。第52页/共123页5.3.2汇编源程序(续)对早期版本的宏汇编程序,在DOS操作系统提示符下键入MASM后,MASM宏汇编程序被调入运行。屏幕上显示版本信息之后,对需要输入输出的4个文件提问如下:

sourcefilename[.ASM]:EXAMobjectfilename[EXAM.OBJ]:Sourcelisting[NUL.LST]:EXAMCross-reference[NUL.CRF]:EXAM第一个询问的是被汇编的源程序文件名,键入文件名(这里为EXAM,不必键入后缀),MASM即对其进行汇编。汇编过程会产生三个文件,第一个是扩展名为.OBJ的目标文件,这是汇编的主要目的,在提示询问后面直接按回车表示同意采用方括号内的缺省文件名,否则键入目标文件的新名字后再按回车。产生的第二个文件是扩展名为.LST的列表文件。列表文件可不要,若不要则在提示询问后面直接按回车键,否则键入列表文件名(后缀不必键入)后再按回车。

.LIST列表文件是个文本文件,有两部分:源程序列表和符号名表。

第一部分对源程序中的每条语句从左到右依次列出:段内偏移地址、机器代码、指令助记符;程序中若有语法错误,则列出错误信息。

第二部分列出程序中所定义的全部标识符信息,如段的名称、长度,变量和标号的名称、类型、偏移地址等。这一文件可打印出来供检查用。第53页/共123页5.3.2汇编源程序(续)汇编产生的第三个文件是扩展名为.CRF的交叉引用文件,也是可要可不要,回答的办法同第二个列表文件。交叉引用文件是个二进制文件,须经交叉引用程序CREF将其转换成交叉引用列表文件(后缀为.REF的ASCII文本文件)后方可显示输出,转换方法为:

C:>CREF<文件名> 转换后的交叉引用列表文件按字母顺序列出了源程序中使用的所有符号的列表。4个问题回答完毕,MASM就对源程序进行汇编。汇编中若发现源程序有语法错误则列出错误的语句和错误的代码,指出是什么性质的错误。最后列出警告错误(WarningErrors)和严重错误(SevereErrors)的总数。MASM软件有许多版本,现在常用的MASM6.X功能很强,包含有许多文件,最常用的是:汇编器ML.EXE、连接器

LINK.EXE、调试器CV.EXE等。汇编器ML.EXE(MasmandLink)能自动调用LINK,实现对源程序的汇编和连接。使用ML命令进行汇编连接的格式如下:ML[/<选项>…]<源文件列表>[/<连接选项>…]第54页/共123页5.3.2汇编源程序(续)<源文件列表>中的多个文件以空格分隔,文件名必须完整,扩展名.ASM不能省略;ML后的参数对大小写

温馨提示

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

评论

0/150

提交评论