第四章-Pentium指令系统_第1页
第四章-Pentium指令系统_第2页
第四章-Pentium指令系统_第3页
第四章-Pentium指令系统_第4页
第四章-Pentium指令系统_第5页
已阅读5页,还剩145页未读 继续免费阅读

下载本文档

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

文档简介

第四章Pentium指令系统

与汇编语言编程第四章Pentium指令系统与汇编语言编程4.1概述4.2通用整数指令及应用4.3汇编语言程序概述

4.4常用伪指令语句

4.5汇编语言编程入门

4-24.1概述

Pentium的指令系统是在80X86系列指令系统的基础上逐步发展而形成的,在代码级具有向上兼容性。它增加了指令的种类,增强了一些指令的功能,提供了32位寻址方式和32位操作方式,并且包含全部浮点运算指令。Pentium指令的操作数可以是0~3个,根据寻址方式不同,可直接包含在指令中,也可存于寄存器或存储器中。每条指令的长度因指令而异,平均指令长度为3.2字节。指令的操作数宽度可以是8位、16位、32位,寻址宽度可以是16位或32位。Pentium指令系统的突出特点是:功能强、灵活性高,给编译程序和汇编语言程序的设计人提供了很宽的选择余地。4-3Pentium指令格式字段1字段2字段3modr/m字段4s-i-b字段5displ字段6data1字节1字节寄存器/存储器寻址方式说明符字段

主寻址字节,规定操作数的寻址方式,包括操作数的存放位置和存储器中操作数EA的计算方法等比例-变址-基址字节,为第二寻址字节位移量字段,属存储器地址的一部分。位移量足够小时,通常采用带符号的8位整数,CPU自动将它扩展到16位或32位立即数字段8位立即数与16/32位操作数一起使用时,CPU自动将其扩展至符号相同的16/32位数。同理也可将16位立即数扩展至32位1~4字节1~2字节前缀Prefix操作码OPcode0,1,2,4字节0,1,2,4字节规定指令的操作性质,包括操作数类型、操作数传送方向、寄存器编码或符号扩展等用于修改指令操作的某些属性,有5类前缀:●段超越前缀●操作数宽度前缀●地址宽度前缀●重复前缀●总线锁定前缀4.1概述4-4本节重点介绍最基本的整数指令。

Pentium指令分类整数指令--最常用部分浮点数指令操作系统型指令Pentium指令系统分为:4.1概述4-5Pentium的整数指令按功能分为:4.串操作类指令5.控制转移类指令9.高级语言指令1.数据传送类指令2.算术运算类指令3.逻辑运算与移位指令6.处理器控制类指令7.标志操作指令8.按条件设置字节指令4.2通用整数指令及应用4-64.2通用整数指令及应用4-71.数据传送类指令数据传送是计算机中最基本、最常用、最重要的一类操作。如:●各种初始化操作●取操作数●保存结果在实际程序中,它的使用频率最高。这类指令寻址方式最丰富,除POPF外,均不影响标志寄存器的标志位。数据传送指令主要包括:

通用数据传送指令。如数值传送指令(MOV)、装入有效地址指令(LEA)、段装入指令、交换类指令(XCHG和BSWAP)、查表转换指令(XLAT)等。

堆栈指令。如PUSH类/POP类指令等。

数据类型变换指令。如数据宽度变换指令,带符号数符号位扩展/无符号数位扩展指令等。

I/O指令。如IN类/OUT类指令等。

标志寄存器传送指令4.2通用整数指令及应用4-8指令操作:(源操作数)→目的操作数

⑴传送指令指令格式:MOV目的操作数,源操作数

寻址规定: REG/MEM/SREG,REGREG/MEM,SREG REG/SREG,MEMREG/MEM,IMMIMM8/16/32位立即数REG8/16/32位通用寄存器MEM8/16/32位存储器SREG段寄存器4.2通用整数指令及应用4-9立即数通用寄存器(EAX、EBX、ECX、EDX、EBP、ESP、ESI、EDI)CS存储器段寄存器(SS、DS、ES、FS、GS)MOV指令允许的传送关系4.2通用整数指令及应用4-104.2通用整数指令及应用4-11使用说明:源操作数和目的操作数的类型必须一致。目的操作数不能为立即数。CS和(E)IP均不能用作指令的目的寄存器。段寄存器间不能直接传送,也不能直接将立即数送给段寄存器。源操作数为立即数,而目的操作数类型不确定时,要给目的操作数加类型说明。源操作数和目的操作数不能同为存储器操作数。4-12⑴MOVDX,BL⑵MOVDS,0100H错。源、目的操作数不能同为存储器寻址。⑶MOV[1200H],[SI]错。源和目的操作数类型不一致。错。立即数不能直接赋给段寄存器⑷MOVAX,[BX][BP]在16位基址加变址的寻址方式中,用作基址和变址的寄存器不能同为基址或变址寄存器

例4.1识别下列指令的正确性,对错误的指令,说明错误的原因。MOVAX,[SI]MOV[1200H],AX4.2通用整数指令及应用4-13

例4.1识别下列指令的正确性,对错误的指令,说明错误的原因。4.2通用整数指令及应用⑸MOV1020H,DS错。目的操作数不能为立即数。⑹MOVCS,AX错。目的操作数类型不确定错。不能用传送指令改变代码段寄存器。(7)MOV[BX][DI],34HMOVWORDPTR

[BX][DI],34H4-14⑵交换指令操作:(目的操作数)(源操作数)格式:XCHG目的操作数,源操作数

REG/MEM, REG REG,MEM说明:

⑴基本用法同MOV指令;⑵当源或目的操作数为MEM操作数时,会自动激活LOCK信号,该特性常用于多机、多任务或多用户系统中的临界段(共享资源)访问。4.2通用整数指令及应用4-15(3)扩展传送指令操作:MOVSX是将源操作数中的8位或16位操作数带符号等值扩展为16位或32位操作数,存于目的操作数中。格式:

MOVSX/MOVZX

目的操作数,源操作数

4.2通用整数指令及应用4-16说明:

XLAT是一条隐含寻址的指令。隐

含两个操作数:DS:(E)BX存放表基址,AL

存放查表参数。使用前要给隐含操作数赋

初值。⑷查表指令

格式:

XLAT

操作:

((EBX)+(AL))→AL((BX)+(AL))→AL4.2通用整数指令及应用4-17

例4.2内存中自TABLE开始的16个单元连续存放着自然数0到15的平方值(构成一个平方表),任给一整数M在XX单元中(该数为0≤M≤15),查表求M的平方值,并将结果存入YY单元中。解: LEABX,TABLE MOVAL,XX

XLAT

MOVYY,ALTABLE0+11+24+39+15225XX54.2通用整数指令及应用4-18⑸压栈/弹栈指令格式:PUSH 源操作数

REG16/MEM16/IMM16 REG32/MEM32/IMM32操作:((E)SP)-2/4→(E)SP (源操作数)→(SS:(E)SP)●压栈指令4.2通用整数指令及应用4-19格式:POP目的操作数

MEM16/MEM32/REG16/REG32操作:([SS:(E)SP])→目的操作数 ((E)SP)+2/4→(E)SP●弹栈指令4.2通用整数指令及应用4-20堆栈指令的操作数只能为字或双字。PUSH和POP要成对出现,以保持堆栈平衡堆栈指令也隐含了一个目的/源操作数—堆栈。压栈顺序是先压高字节后压低字节,弹栈则是先弹低字节后弹高字节。●使用说明:4.2通用整数指令及应用

例4.3用堆栈指令实现将EAX的高16位送BX,低16位送CX。PUSHEAX;将EAX压栈,先压高16位,后压低16位POPCX;弹出EAX的低16位送CXPOPBX;弹出EAX的高16位送BX解:4.2通用整数指令及应用4-214-22设(EAX)=12345678H,(SP)=0100H,执行上列指令时,堆栈变化下图所示。…sp(0100H)(a)执行之前78H56H34H12H…0100Hsp(00FCH)(b)执行PUSHEAX4.2通用整数指令及应用4-2334H12H…0100Hsp(00FEH)(c)执行POPCX(CX)=5678H…sp(0100H)(d)执行POPBX(BX)=1234H

4.2通用整数指令及应用设(EAX)=12345678H,(SP)=0100H,执行上列指令时,堆栈变化下图所示。4-24⑸地址传送指令格式:

LEA目的操作数,源操作数功能:将源操作数的有效地址送指定的寄存器。说明:LEA指令的目的操作数只能是16位或32位通用寄存器,而源操作数只能是存储器操作数 ●装入有效地址指令LEA4.2通用整数指令及应用4-25例4.4在数据段中,有一如图所示存储形式的字数据区,若将BUF为偏移地址的存储区的内容分别送到AX、BX和CX,则下程序段执行后各寄存器的内容是多少?LEASI,BUFMOVAX,BUFMOVBX,[SI]MOVCX,[SI+4]LEADI,[SI+6]M120010H780011H990012H610013H880014H190015H290016H390017H690018HBUF…4.2通用整数指令及应用4-26程序段执行后各寄存器的内容是:(SI)=0011H(AX)=9978H(BX)=9978H(CX)=2919H(DI)=0017H注意:通过上面的例子体会LEA指令和MOV指令功能的区别LEASI,BUF;

将存储单元BUF的0011H有效地址送SI

MOVAX,BUF;取存储单元BUF的内容送AX4.2通用整数指令及应用4-27格式:LDSLESLFS目的操作数,源操作数LGSLSS功能:将源操作数的有效地址送指定的寄存器。说明:LEA指令的目的操作数只能是16位或32位通用寄存器,而源操作数只能是存储器操作数

装入全地址指针指令4.2通用整数指令及应用

例4.580486工作在实地址方式时,(DS)=091DH,(BX)=0024H,有关存储器的内容如图所示。求指令LESDI,32H[BX]执行后的结果。DIES00F6H1E40H09226H段基址…操作码操作码32H00H存储器…指令代码段偏移量数据段位移量F6H00H40H1EH…0032HBX0024H+DS*16091D0H09226HLESDI,32H[BX]4.2通用整数指令及应用4-28►说明:I/O端口有两种寻址方式

直接寻址,寻址范围为0~255;

间接寻址,寻址范围为0~216-1。●输入指令►格式:IN累加器,端口AL/AX/EAX,IMM8AL/AX/EAX,DX►操作:AL/AX/EAX←(I/O端口)直接寻址:指令给出的立即数是I/O端口地址间接寻址:DX寄存器给出的是I/O端口地址4.2通用整数指令及应用4-29⑹输入/输出指令4-30●输出指令格式:OUT端口, 累加器

IMM8,AL/AX/EAXDX,AL/AX/EAX操作:(AL/AX/EAX)→I/O端口4.2通用整数指令及应用4-31例4.6INAL,20H;从20H号端口输入8位字节数据送到AL中INEAX,DX;从DX所指16位端口输入32位双字数据送到EAX中OUT80H,AL;把AL中的8位字节数据发送到80H号端口OUT0FFH,EAX;把EAX中的32位双字数据发送到0FFH号端口OUTDX,AX;把AX中的16位字数据发送到DX所指端口4.2通用整数指令及应用

这类指令支持加、减、乘、除四种基本算术运算,其操作对象可以是字节、字、双字的无符号和有符号的二进制整数;也可以是无符号的压缩/非压缩BCD码数;还支持符号扩展指令和十进制调整指令。

它的操作结果一般会影响标志寄存器中的状态标志位,如ZF、CF、SF、OF、AF、PF等。2.算术运算类指令

数据传送类

算术运算类逻辑运算与移位类串操作类控制转移类处理器控制4.2通用整数指令及应用4-32算术运算指令有:双操作数指令,如加、减、比较等。单操作数指令,如增/减、整数变反、乘除法指令等。无操作数指令,如十进制运算调整和符号位扩展等。三操作数指令,如有符号整数乘法指令IMUL等。4.2通用整数指令及应用4-334-34(1)加法/减法类指令

操作:

ADD:(目的)+(源)→目的

SUB:(目的)-(源)→目的

ADC:(目的)+(源)+CF→目的

SBB:(目的)-(源)-CF→目的目的操作数,源操作数REG,REG/MEM/IMMMEM,REG/IMM

格式:

ADDSUB

ADCSBB加/减法指令4.2通用整数指令及应用4-35使用说明:源操作数和目的操作数可以是字节、字和双字数据,但两者的类型必须一致。源操作数可以为通用寄存器、存储器或立即数,目的操作数可以为通用寄存器和存储器。但两者不能同为存储器操作数。溢出标志OF是针对有符号数运算设置的,若是无符号数运算,结果是否“溢出”,则要看运算是否产生进位/借位来判断,有进位/借位产生,则结果溢出。。4.2通用整数指令及应用4-36

加1/减1指令(INC/DEC)格式:INC/DEC目的操作数

REG/MEM操作:(目的操作数)+/-1→目的操作数应用:

CPU根据操作结果设置状态标志OF、SF、ZF、AF和PF,但不影响进位/借位标志CF。4.2通用整数指令及应用4-37使用说明:操作数可以是8位、16位或32位的通用寄存器和存储器。INC/DEC指令常用于调整地址指针和用作加法/减法计数器。INC/DEC指令与“ADD/SUB目的操作数,1”的功能基本相同,两者区别在于ADD/SUB指令根据结果改变进位/借位标志CF,但INC/DEC指令不影响进位/借位标志CF。4.2通用整数指令及应用4-38例4.7求AX中存放的有符号数的绝对值。

4.2通用整数指令及应用程序如下: TESTAX,8000H;测试符号位 JZNEXT;SF=0,转NEXT,正数不求补NEGAX;求补,AX值为原值的绝对值NEXT:HLT4-39整数变反指令(求补)格式:NEG目的操作数

REG/MEM操作:0-(目的操作数)→目的操作数应用:

常用于求负数的绝对值。

例4.8

两个32位双字数据X、Y定义如下,DW是汇编语言伪指令,为每个数据项分配两个字节存储单元(称为字),请编写计算X=X-Y的程序段(低位在前)。4.2通用整数指令及应用XDW9999H,9678H;X=96789999HYDW1111H,1F11H;Y=1F111111H4-40比较指令格式:CMP目的操作数,源操作数

REG,REG/MEM/IMM MEM,REG/IMMCMP与SUB指令都执行减法操作,但前者不因操作结果改变目标操作数值,而后者改变。操作:(目的操作数)-(源操作数),根据操作结果修改状态标志,但不改变目标操作数值。4.2通用整数指令及应用乘法指令分为有符号数和无符号数乘法指令(IMUL/MUL)。

无符号数乘法指令只有单操作数格式一种;

有符号数乘法指令则有单操作数、双操作数和三操作数三种格式。4-41(2)乘法指令4.2通用整数指令及应用4-42◆单操作数乘法指令格式:MUL/IMUL源操作数

REG/MEM操作:MUL和IMUL分别为有符号数和无符号数乘法指令,两种指令除操作数类型不同外,操作完全相同:字:(AX)×(源操作数)→DX:AX双字:(EAX)×(源操作数)→EDX:EAX字节:(AL)×(源操作数)→AX源操作数4.2通用整数指令及应用4-43单操作数乘法指令的被乘数是隐含的(在AL/AX/EAX中),而结果长度一定是被乘数/乘数的二倍(在AX/DX:AX/EDX:EAX中)。源操作数不能为立即数。源操作数为存储器操作数,且类型不能确定时,要显式说明操作数类型。乘法指令使用说明:4.2通用整数指令及应用4-44要根据是有符号数还是无符号数,分别选用IMUL或MUL指令指令执行影响CF和OF标志,若指令执行后,结果的高一半是有效数值位,则CF=OF=1,否则CF=OF=0。乘法指令使用说明:4.2通用整数指令及应用4-45(3)除法指令格式:DIV∕IDIV源操作数 REG/MEM操作:按源操作数类型:字节:(AX)/(源),商存于AL中,余数存于AH字:(DX:AX)/(源),商存于AX中,余数存于DX双字: (EDX:EAX)/(源),商在EAX中,余数在EDX4.2通用整数指令及应用例4.9编程实现无符号字节数NUMX除以无符号字节数NUMY,要求商存入REZULT,将余数存入地址ADDI。程序如下:MOVAL,NUMX;将地址NUMX内的字节数据,取出传送给;AL寄存器MOVAH,0;扩展无符号的被除数为字数据DIVNUMY;用寄存器AX中的数据除以NUMYMOVREZULT,AL;将商存入REZULTMOVADDI,AH;将余数存入ADDI4.2通用整数指令及应用4-464-47说明:除法指令的被除数是隐含的,且长度一定是除数的二倍(在AX/DX:AX/EDX:EAX中)。所以,使用除法指令常要扩展被除数长度。扩展时无符号数一般用:MOVZXAX,ALMOVDX,0MOVEDX,0有符号数一般用:CBW/CWD/CDQ4.2通用整数指令及应用(3)数据宽度变换指令格式:CBW/CWD/CWDE/CDQ功能:用于将源操作数的宽度加倍,又称为符号位扩展指令CBW;AL带符号扩展→AXCWD;AX带符号扩展→DX:AXCWDE;AX带符号扩展→EAXCDQ;EAX带符号扩展→EDX:EAX4.2通用整数指令及应用4-49使用说明:CBW指令将AL中的8位有符号数带符号扩展为16位放入AX中。AH中各位取与AL中数的符号位相同的值,即对负数进行1扩展,正数进行0扩展。CWD指令将AX中的16位有符号数带符号扩展为32位,扩展后的高16位存放在DX中,各位值与AX中符号位相同,AX值不变。CWDE指令将AX中的16位有符号数带符号扩展为32位存放在EAX中,高16位与原符号位值相同。4.2通用整数指令及应用4-50使用说明:CDQ指令将EAX中的32位有符号数带符号扩展为64位数,扩展后的高32位存放在EDX中,且都与原符号位值相同。数据宽度变换指令对标志位无影响。该类指令常在有符号数除法运算中,用于扩展被除数的位数。4.2通用整数指令及应用4-51例4.10将例4.9中的被除数和除数都看作是有符号字节数,则要完成相同的功能,该如何修改程序。4.2通用整数指令及应用改动有两点,一个是使用有符号数的除法指令,另一个是被除数长度扩展应用CBW。程序如下:MOVAL,NUMX;将地址NUMX内的字节数据,取出传;送给AL寄存器CBW;扩展有符号的被除数为字数据IDIVNUMY;用寄存器AX中的数据除以NUMYMOVREZULT,AL;将商存入REZULTMOVADDI,AH;将余数存入ADDI4-52

MOVAX,a①;a×b在CX:BX中②③MOVAX,c④;c在DX:AX中⑤;a×b+c在DX:AX中⑥⑦;(a×b+c)/a,商存入S⑧IMULbMOVCX,DXMOVBX,AXCWDADDAX,BXADCDX,CXIDIVaMOVS,AX

例4.11

下列程序段完成S=(a×b+c)/a的运算,其中变量a、b、c和S均为带符号的字数据,结果的商存入S,余数则不计,填空完成下列程序。4.2通用整数指令及应用4-53(4)BCD调整指令

格式:AAA∕AAS∕AAM∕AAD∕DAA∕DAS功能:AAA/AAS:

未组合BCD加法/减法调整指令,隐含操作数为AL。AAM:

未组合BCD乘法调整指令,隐含操作数AX、AH、AL。将AX中乘积调整为两个未组合BCD数存于AH和AL。DAA/DAS:

组合BCD加法/减法调整指令,隐含操作数为AL。AAD:调整除法运算前AX中的被除数内容。操作:(AH)×10+(AL)→AX4.2通用整数指令及应用◆BCD调整指令说明:DAA/DAS、AAA/AAS隐含的操作寄存器是AL,所以BCD码加法/减法只能用累加器AL为目的操作数的加法/减法指令,且加法/减法指令后要跟调整指令。多字节、字和双字BCD加法/减法只能用带进位/借位的字节加法/减法指令实现。ASCII码数的运算与非压缩BCD码数的运算基本相同,但要保持结果仍为ASCII码,则需转换。4.2通用整数指令及应用4-54◆BCD调整指令说明:AAM隐含的操作寄存器是AX,要跟在MUL指令之后AAD指令的功能不是将除法后的结果调整为BCD码,而是在除法前将AX保存的两位非压缩BCD数调整为二进制数。该指令要放在DIV指令之前。4.2通用整数指令及应用4-554-56例4.12解:MOVAL,BYTEPTRXADDAL,BYTEPTRY;低位相加

DAA;BCD码调整MOVBYTEPTRX,AL;保存低位结果MOVAL,BYTEPTRX[1];取字变量的高字节ADCAL,BYTEPTRY[1];高位相加

DAAMOVBYTEPTRX[1],AL两个4位压缩BCD码定义如下:

XDW9F11H

YDW19F9H

请编写计算X+Y的程序段。4.2通用整数指令及应用功能:分别按位进行逻辑“与”、“或”、“异或”、“测试”和“非”。◆格式:AND

OR

XOR

TEST 目标操作数,源操作数

REG,REG/MEM/IMMMEM,REG/IMM

NOT目标操作数

REG/MEM4-573.逻辑运算与移位指令⑴逻辑运算指令4.2通用整数指令及应用4-58使用说明:②编程时要根据操作合理选用指令,一般:

●对某些二进制位‘清零’用逻辑‘与’指令AND;●对某些二进制位‘置位’用逻辑‘或’指令OR;●对某些二进制位‘求反’用逻辑‘异或’指令

XOR,全部位‘求反’用逻辑‘非’指令NOT。①逻辑运算指令除NOT指令外,都影响标志寄存器的状态标志位,且逻辑运算后进位标志CF一定为0,所以逻辑运算指令常用于清0和清进位。4.2通用整数指令及应用③AND指令与TEST指令的相同之处是都执行按位“与”操作,两者执行后对标志寄存器中状态标志位的影响相同,不同之处是前者改变目标操作数的值,而后者并不改变目标操作数的值。所以TEST指令与CMP指令的用法类似,用于产生按位测试的条件码。4-594.2通用整数指令及应用使用说明:4-60例4.13IBMPC打印机状态口为210H,D7位为打印机“忙”状态标志,D0=0表示打印机忙,CPU要等待,否则允许打印输出。编写判断打印机状态的程序段程序段如下:MOVDX,210H;取打印机状态口BUSY:INAL,DX;读打印机状态TESTAL,01H;测试忙状态D0,产生状态标志JZBUSY;D0=0,表示打印机忙,等待;打印4.2通用整数指令及应用4-61⑵移位指令

移位指令包括:算术移位指令(SAL/SAR)逻辑移位指令(SHL/SHR)循环移位指令(ROR/ROL/RCR/RCL)双精度移位指令(SHLD/SHRD)4.2通用整数指令及应用4-62使用说明:移位指令的源操作数采用立即数寻址时,8086指令只能为1,80486则为8位,实际使用低5位。移位指令常用于二进制数的倍乘和倍除,即算术/逻辑移n位,相当于把二进制数乘以或除以2n。4.2通用整数指令及应用4-63要注意算术右移(SAR)与逻辑右移(SHR)的区别:

前者在符号位和数值位依次右移的同时,用符号

位充填符号位,而后者用0充填符号位。所以,有符号和无符号数倍乘用SHL/SAL均可,但倍除时,有符号数用SAR和无符号数用SHR。移位指令也常用于循环控制,如逻辑尺控制循环。4.2通用整数指令及应用使用说明:

例4.14试编写用移位和加法指令完成如下计算的程序段:(EAX)×9/4解:

(EAX)×9/4=[(EAX)×8+(EAX)]/4MOVEBX,EAX;保存EAXSAL/SHLEAX,3;(EAX)×8→EAXADD EAX,EBX;(EAX)×8+(EAX)→EAXSAR/SHR

EAX,2;(EAX)×9/4→EAX4.2通用整数指令及应用4-644.串操作指令串传送指令MOVSB/MOVSW/MOVSD串装入指令LODSB/LODSW/LODSD串存储指令STOSB/STOSW/STOSD串比较指令CMPSB/CMPSW/CMPSD串扫描指令SCASB/SCASW/SCASD串输入指令INSB/INSW/INSD串输出指令OUTSB/OUTSW/OUTSD串操作指令是指用于对存储器中字节串、字串和双字串进行操作的指令,包括:

数据传送类算术运算类逻辑运算与移位类串操作类控制转移类处理器控制4.2通用整数指令及应用4-654-66串操作约定:●用DS:(E)SI寻址源串,允许段超越;●用ES:(E)DI寻址目的串,但ES段不能超越;●由DF标志位决定(E)SI,(E)DI指针增减:

DF=0,递增;DF=1,递减;●由串长度决定指针增/减量大小;●带重复前缀时,用(E)CX作重复计数器。4.2通用整数指令及应用⑴串传送指令

格式:

MOVSB/MOVSW/MOVSDMOVS 目的串,源串

MEM,MEM操作:将DS:[(E)SI]所指的源串中的一个字节、字或双字传送到ES:[(E)DI]指的目的串中,然后,按DF指示和操作数长度修改(E)SI,(E)DI指针,即:[ES:(E)DI]←([DS:(E)SI])(E)SI←((E)SI)±1/2/4;修改源指针(E)DI←((E)DI)±1/2/4;修改目的指针4.2通用整数指令及应用4-67说明:应用:用于数据块传送该指令允许加重复前缀REP。即:

REPMOVSB/MOVSW/MOVSD此时,由(E)CX控制串传送指令MOVS的执行次数。相当于指令序列:AGAIN:MOVSB/MOVSW/MOVSDLOOPAGAIN4.2通用整数指令及应用4-684-69例4.15欲将数据段中自FIRST开始的100个双字数据搬移到附加段中以SECOND开始的数据区中,用基本串传送指令实现,程序如下:LEAESI,FIRSTLEAEDI,SECONDMOVECX,100CLDDONE:MOVSD;或MOVSSECOND,FIRSTLOOPDONE4.2通用整数指令及应用4-70可用带重复前缀的串传送指令实现,程序如下: LEAESI,FIRST LEAEDI,SECOND MOVECX,100 CLD REPMOVSD4.2通用整数指令及应用格式:

LODSB/LODSW/LODSDLODS 源串

MEM说明:

允许加重复前缀REP。操作:

([DS:(E)SI])→AL/AX/EAX

按DF指示和操作数长度修改(E)SI指针应用:用于取数据块中元素值(2)串装入指令4.2通用整数指令及应用4-714-72(3)串存储器指令

格式:

STOSB/STOSW/STOSD STOS 目的串

MEM

说明:允许加重复前缀REP。操作:

AL/AX/EAX→([ES:(E)DI])

按DF指示和操作数长度修改(E)DI指针应用:用于数据块初始化。LODS和STOS结合常用于数据块传送。4.2通用整数指令及应用4-73(4)串扫描指令

格式:

SCASB/SCASW/SCASD SCAS 目的串

MEM 操作:(AL/AX/EAX)-([ES:(E)DI]),影响标志,但

不改变目的串内容。按DF指示和操作数长度修改(E)DI指针。4.2通用整数指令及应用说明:允许加重复前缀REPE或REPNE。扫描次数由(E)CX指定。重复条件:

REPE:IF((E)CX)≠0ANDZF=1THEN重复串扫描

REPNE:IF((E)CX)≠0ANDZF=0THEN重复串扫描应用:用于在串数据中查找关键字。4.2通用整数指令及应用4-744-75(5)串比较指令格式:

CMPSB/CMPSW/CMPSDCMPS 源串,目的串

MEM ,MEM说明:允许加重复前缀REPE或REPNE。操作:([DS:(E)SI])-([ES:(E)DI]),影响标

志,但不改变源串和目的串内容。按DF指示和

操作数长度修改(E)DI、(E)SI指针应用:常用于比较两个串数据是否匹配。4.2通用整数指令及应用包括以下5种指令:无条件转移指令(JMP)过程调用/返回指令(CALL/RET)条件转移指令(JCC)

循环控制指令(LOOP)中断指令(INT)无条件向目标地址转移,可分为段内、段间转移,段内、段间转移又可分别分为直接和间接转移。实现子程序调用或返回,也可归入无条件转移指令中。根据指令执行后标志寄存器的状态进行转移,通常和CMP或TEST指令组合使用。控制循环程序的循环,实质上也是条件转移指令,在CX(ECX)中预置循环次数。产生一个由8位立即数指定中断号的软中断和处理溢出中断。这类指令的共同特点是可改变程序的正常执行顺序,使之转移。而改变程序的执行顺序,本质上就是要改变CS:(E)IP的内容这类指令对标志位无影响。5.控制转移指令

数据传送类算术运算类逻辑运算与移位类串操作类控制转移类处理器控制4.2通用整数指令及应用4-764-77直接转移间接转移控制转移指令使用说明:(1)按目标地址的寻址方式,转移可分为:4.2通用整数指令及应用直接转移

此时,指令中直接给出转移的目标地址。又分为:

◆直接短(SHORT)转移

◆段内(NEAR)直接转移

◆段间(FAR)直接转移

段内直接短转移和段内直接转移又称为相对转移。即转移的目标地址为当时的(E)IP地址加上一8位位移量(短转移)、16位位移量(16位寻址)或32位位移量(32位寻址),即: ((E)IP)+DISP→(E)IP4.2通用整数指令及应用4-784-79■间接转移●寄存器间接转移。仅有段内转移。●存储器间接转移。分段内和段间转移。

此时,指令中给出的寄存器或存储单元中间接存放着转移的目标地址。又分为:4.2通用整数指令及应用(2)8086/8088的条件转移指令都为短转移,80386/80486则推广到段内转移。

(3)CALL指令与JMP指令的不同之处:CALL指令执行时,增加了保存断点地址进栈的操作。(4)循环指令只能是短转移。

4.2通用整数指令及应用4-804-81

例4.17

指令JMPNEARPTRPROG在程序代码段中的偏移地址为2013H(这是该指令第一字节的偏移地址),组成该指令的三字节机器码为E9H、12H、34H(其中E9H为操作码)。该指令执行后,程序将转去何处?4.2通用整数指令及应用

解:该指令执行过程如下:5428H3412H位移量程序转移到当前代码段中偏移地址为5428H的单元执行E9H12H34H存储器指令代码段2013HIP5428H+IP2016H2016H4.2通用整数指令及应用4-824.3汇编语言程序概述4.3.2伪指令语句源程序结构4.3.3汇编语言语句格式4.3.1汇编语言程序的特点4-834.3汇编语言程序概述4.3.1汇编语言程序的特点汇编语言是一种介于机器语言和高级语言之间的、采用助记符表示的程序设计语言,它既不像机器语言那样直接使用计算机所能理解和识别的二进制代码,也不像高级语言那样直接面对用户。实质上仍然是一种面向机器的语言。汇编语言用助记符来表示指令的功能,用标号或符号代表地址、常量或变量。用汇编语言编写的程序要比与其等效的高级语言生成的目标代码精简得多,占内存少,执行速度快。但用汇编语言编写和调试程序的周期较长,程序设计的技巧性强,对程序员的要求高,既要熟悉计算机的指令系统也要熟悉计算机的硬件结构。4-84用汇编语言编写的源程序称为汇编语言源程序,在提交计算机执行之前也需要翻译成机器指令(目标程序),这个过程叫汇编。完成汇编的程序则称为汇编程序(Assembler)。汇编程序无法区分源程序中的符号是数据还是地址,也无法识别数据的类型,还搞不清源程序的分段情况等。汇编语言为了解决这些问题,专门设置了伪指令和算符。汇编时,伪指令和算符只为汇编程序将符号指令翻译成机器指令提供辅助说明信息,它们并不生成对应的机器指令代码,汇编工作结束后他们就不存在了。4.3汇编语言程序概述4-854.3.2汇编语言源程序结构80X86/Pentium系列MPU汇编语言都是以逻辑段为基础,按段的概念来组织代码和数据的。因此,源程序结构与逻辑段的定义方法密切相关,而宏汇编语言MASM5.0以上的版本中,逻辑段既可用完整段定义,又可用简化段定义。4.3汇编语言程序概述4-861.标准的单模块源程序框架[.586] DATASEGMENT[USE16/USE32] ;定义数据段

;数据定义伪指令序列 DATAENDS

STACKSEGMENT[USE16/USE32]STACK ;定义堆栈段

;数据定义伪指令序列 STACKENDS

CODESEGMENT[USE16/USE32] ;定义代码段 ASSUMECS:CODE,SS:STACK,DS:DATA,ES:DATA

START:MOVAX,DATA ;取数据段基址 MOVDS,AX ;建立DS的可寻址性 MOVES,AX ;建立ES段的可寻址性

;核心程序段 MOVAH,4CH ;返回DOS操作系统 INT21H CODEENDS

ENDSTART⑴一个源程序由若干逻辑段组成。一般一个源程序具有数据段、附加数据段、堆栈段和代码段;但只有代码段是必不可少的。

⑵采用完整段定义时,对程序中定义的逻辑段,要说明逻辑段与段寄存器的寻址关系。ASSUMECS:CODE,SS:STACK,DS:DATA,ES:DATA⑶对数据段(有时还有堆栈段),程序中要包含初始化段寄存器的语句。MOVAX,DATAMOVDS,AXMOVES,AX程序中要包含返回DOS的语句。MOVAH,4CHINT21H⑸源程序(模块)以END伪指令结束

ENDSTART4.3汇编语言程序概述4-874.3.3汇编语言语句格式1.语句种类●指令语句是可执行语句,由硬件(CPU)完成其功能,汇编时产生目标代码。●伪指令语句

不可执行语句,其功能由相应软件完成,不产生目标代码。●宏指令语句

用户定义的新指令,汇编时产生相应的目标代码。

4.3汇编语言程序概述4-88指令语句:[标号:]助记符[操作数][;注释]伪指令语句:[名字]定义符[操作数][;注释]●标号和名字——分别是给指令单元和伪指令起的符号名称,统称为标识符。(注意组成的语法规则)●助记符和定义符——分别用于规定指令语句的操作性质和伪指令语句的伪操作功能,统称操作符。2.语句格式4.3汇编语言程序概述4-89●操作数

操作数允许有多个,这时各操作数之间要用逗号“,”隔开。伪指令语句中操作数的格式和含义则随伪操作命令不同而不同,有时是常量或数值表达式,有时是一般意义的符号

(如变量名、标号名、常数符号等),有时是具有特殊意义的符号(如指令助记符、寄存器名等)。

指令语句中的操作数提供该指令的操作对象,并说明要处理的数据存放在什么位置以及如何访问它,它可以是常量操作数、寄存器操作数、存储器操作数和表达式。4.3汇编语言程序概述4-904.4.1方式选择伪指令4.4.2逻辑段定义伪指令4.4.3数据定义伪指令4.4.4模块定义伪指令4.4.5过程与宏定义伪指令4.4常用伪指令语句4.4常用伪指令语句4-914.4.1方式选择伪指令方式选择伪指令用于通知汇编程序,当前的源程序指令是哪一种CPU指令,经过汇编链接之后生成的目标程序在哪一种CPU机型上运行。不属于选定CPU的指令均为非法指令。所以,方式选择伪指令本质上也就是指令集选择伪指令。通常,方式选择伪指令放在程序的头部,作为源程序的第一条语句。缺省时默认8086指令集。4.4常用伪指令语句4-924.4.2逻辑段定义伪指令1.完整段定义伪指令80X86/Pentium系列微处理器汇编语言有两种逻辑段定义方法:完整段和简化段定义采用完整段定义伪指令可具体控制汇编程序(MASM)和链接程序(LINK)在内存中组织代码和数据的方式。主要包括段定义语句和段寄存器说明语句。

4.4常用伪指令语句4-934.4常用伪指令语句3.3.2逻辑段定义伪指令格式:段名SEGMENT[定位类型][,组合类型][,字长选择][,‘类别’]段体 ;由指令、伪指令和宏指令语句组成段名ENDS

⑴段定义语句

说明:

(1)SEGMENT/ENDS是一对段定义语句,一个逻辑段从SEGMENT语句开始,到ENDS语句结束。(2)段名是用户定义的段的标识符,用于指明段的基址。(3)4个可选参数用于为源程序的汇编、连接提供必要的信息,特别是模块化程序,各个模块如何定位,彼此之间如何连接,将较多地涉及到定位类型和组合类型的选择。指定段起点的边界类型:BYTE(字节)WORD(字)DWORD(双字)PARA(节)PAGE(页)

定位类型告诉链接程序本段与其它模块中同名段的组合连接关系:PUBLIC连接到同一个物理段中STACK连接到同一个物理堆栈段中,并给SS:ESP赋值COMMON产生一个覆盖段。MEMORYAT表达式

组合类型定义段中使用的偏移地址和寄存器的字长USE16──表示该段字长为16位USE32──表示该段字长为32位字长选择4-94⑵段寄存器说明语句

格式:ASSUME段寄存器:段名[,段寄存器:段名,…]功能:说明源程序中定义的段由那个段寄存器去寻址。说明:

⑴CS只能用于包含有程序的段,反之含有程序的段也只能以CS作为段寄存器。SS也一样,只能与堆栈段对应。⑵CS所对应的段名必须在该语句之前有定义。⑶该语句是说明性语句。4.4常用伪指令语句4-95简化段有利于实现汇编语言程序模块与Microsoft高级语言程序模块的连接,它可以由操作系统自动安排段序,自动保证名字定义的一致性。但是命令文件(.COM)的编程不能使用简化段定义。⑴段次序语句(DOSSEG)⑵内存模式语句(.MODEL)⑶段语句

简化段定义有三种语句:2.简化段定义伪指令

4.4常用伪指令语句4-964-974.4常用伪指令语句

使用简化段定义的独立汇编语言源程序框架:

DOSSEG .MODELSMALL .STACK[长度] .DATA

…;数据语句 .CODE启动标号:MOVAX,@DATA;或MOVAX,DGROUP MOVDS,AX

…;可执行语句 MOVAH,4CH;返回DOS INT21H END启动标号段语句.CODE.DATA.STACKDOSSEG段次序语句:规定各逻辑段在内存的顺序按DOS段次序约定排列。

.MODELSMALL内存模式语句:用于指定数据和代码允许使用的长度。4.4.3数据定义伪指令格式:赋值语句:符号名EQU表达式功能:都是用符号名代替表达式的值。但赋值语句定义的符号名不能重新定义,而等号语句允许。1.符号定义伪指令等号语句:符号名=表达式

4.4常用伪指令语句4-98

赋值语句与等号语句举例。赋值语句: XEQU50 YEQUX+10 COUNTEQU$-ARRY 等号语句: CON=5 BASE=200H

BASE=BASE+10H ;重新定义BASE4.4常用伪指令语句4-992.数据定义伪指令伪指令格式:DBDWDDDFDQDT数据项[,数据项,…,数据项][变量名]功能:是为数据项或项表分配存储空间,给它们赋初值,并用一个符号名(称为变量)与之相联系。8位(字节)16位(字)32位(双字)48位(长字)64位(四字)80位(十字节)

4.4常用伪指令语句4-100使用说明:⑴给变量赋初值可以是赋确定的值,也可以是赋不确定的值(用“?”表示),还可以是用DUP运算符建立的多次拷贝。

4.4常用伪指令语句4-101

⑵使用SEG、OFFSET、TYPE、LENGTH和SIZE运算符求变量的各种属性时,特别要注意:对LENGTH运算符,如果变量是用重复数据操作符DUP说明的,则返回外层DUP给定的值;如果没有DUP说明,则返回值总是1。对SIZE运算符有:SIZE=TYPE×LENGTH⑶操作符“$”是取地址计数器的当前值,常用于表达式定义数组长度。使用说明:4.4常用伪指令语句4-102

⑷使用DB、DW、DD定义串数据(用‘’定义的字符串)时,允许定义的串长度不同,字符的存放顺序也不相同:DB是从左至右顺序为每个字符分配一个字节单元;DW是从左至右顺序为每2个字符分配一个字单元,且前面的字符在高字节,串长度不能超过2;DD是从左至右顺序为每4个字符分配一个双字单元,也是按前面的字符在高字节顺序存放,串长度不能超过4。4.4.5过程与宏定义伪指令过程定义伪指令宏定义伪指令宏和过程的比较4.4常用伪指令语句4-103格式:过程名PROC[属性]

;过程体 [RET]

RET

过程名ENDP

说明:②过程允许嵌套调用,还可以递归调用。③过程与逻辑段也可以相互嵌套,但决不允许过程与段交叉覆盖。过程又称为子程序。它是一段必须通过CALL指令调用才能执行的程序段,执行完后通过一条RET指令返回原调用处。过程需先定义才能调用。

①过程体中必须至少包含一条RET指令,这是过程的出口。但也允许过程有多条RET指令,即过程有多个出口。1.过程定义伪指令4.4常用伪指令语句4-104宏定义格式:宏名MACRO[形式参数表]

;宏体 ENDM

说明:宏定义的宏名必须唯一,称为宏指令。宏指令一经定义就可以在源程序的任何地方调用。相当于由用户给汇编程序提供了一个新的操作码。

宏调用格式:宏名[实际参数表]宏的概念与过程很相似,也是用一个宏名字来代替源程序中经常要用到的一个程序模块。2.宏定义伪指令

4.4常用伪指令语句4-105使用宏定义和宏调用时要注意两个问题:对带参数的宏指令,宏调用时实际参数与形式参数的类型要一致,以免产生无效调用。宏调用是用宏体中定义的指令序列替换宏指令,所以宏体内的标号要用LOCAL伪指令说明为局部标号,以免多次调用宏时,发生标号重复定义错误。LOCAL伪指令格式:

LOCAL标号1[,标号2,…]4.4常用伪指令语句4-106解:宏定义如下:

MOVEMACROSARY,DARY

LOCALLP MOVSI,0 MOVCX,100LP:MOVAL,SARY[SI] MOVDARY[SI],AL INCSI LOOPLP ENDM例4.18

定义宏MOVE,其功能是将一个有100个字节元素的数组搬移到另一个数据区。进行宏调用:MOVEFIRST,SECOND宏展开如下: MOVSI,0MOVCX,100??0000:MOVAL,FIRST[SI] MOVSECOND[SI],AL INCSI LOOP??00004.4常用伪指令语句4-1073.宏和过程的比较

宏和过程都可简化源程序的书写,因而也减少了程序出错的可能性。但两者使用上也有区别:(1)宏操作可以直接传递和接收参数,而过程不能直接带参数。当过程之间需要传递参数时,必须通过堆栈、寄存器或存储器来进行,编程比宏要复杂。所以,宏汇编适合于代码较短,传送参数较多的子功能段使用,子程序适合于代码较长,调用比较频繁的子功能段使用。(3)引入宏操作并不会在执行目标代码时增加额外的时间开销,但过程调用由于要保护和恢复现场及断点,因此会延长目标程序的执行时间。(2)子程序不管被调用多少次它都只被汇编一次,即有唯一的一段目标代码;而宏指令则调用多少次就汇编多少次,每次调用都要在程序中展开并保留宏体中的每一行。4.4常用伪指令语句4-1084.5汇编语言编程入门4.5.1汇编语言程序的开发过程4.5.2基本结构程序设计4.5.3子程序设计与调用4.5.4DOS/BIOS功能调用4-1094.5.1汇编语言程序的开发过程

与其它程序设计语言一样,汇编语言程序的开发过程可归结为:就需求分析、模块划分和算法确定等工作而言,各种程序设计语言是类似的,均可按软件工程的方法进行,但编程和调试则因程序设计语言而异。

需求分析根据需求和规模等因素划分模块确定各功能模块的求解算法、并定义所需的数据结构进行编程和调试4.5汇编语言编程入门4-110对汇编语言而言,根据数据结构和算法进行编码到形成可用程序的过程如下:

需求分析、数据结构和算法汇编语言源程序文件*.ASM目标代码程序文件*.OBJ可执行程序文件*.EXE可用程序连接编辑汇编调试4.5汇编语言编程入门4-1114.5.2基本结构程序设计程序的基本结构形式有三种:●顺序结构●分支结构●循环结构理论上,三种基本结构是完备的,即任何功能的程序都可由顺序、分支和循环三种结构实现。4.5汇编语言编程入门4-1121.顺序程序设计●在实际应用中,纯粹用顺序结构编写的完整程序很少见,但是在程序段中它却是大量的存在。所以掌握它是编写复杂应用程序的基础。——顺序程序又称直线程序。●其特点是顺序执行的,无分支,无循环,也无转移,只作直线运行。4.5汇编语言编程入门4-1132.分支程序设计在许多实际问题中,往往需要根据不同的情况和给定的条件做出不同的处理。要设计这样的程序,必须事先把各种可能出现的情况及处理方法都编写在程序中,以后计算机运行程序时,可自动根据运行的结果做出判断,有条件地选择执行不同的程序段,按这种要求编写的程序称为分支程序。4.5汇编语言编程入门4-114分支1条件结束开始YN分支2(b)完全分支结构分支程序条件结束开始YN(a)不完全分支结构分支1结束开始条件ii=1i=n分支2分支n…i=2(c)多分支结构分支程序的结构有三种形式:

IF条件THEN分支程序IF条件THEN分支1ELSE分支24.5汇编语言编程入门4-115⑴利用比较与条件转移指令实现分支

程序如下:

DATA SEGMENT

VAR1DB10HVAR2DB09HABUFDB?BBUFDB?DATA ENDS4.5汇编语言编程入门4-116例19已知两个整数字节变量VAR1和VAR2,试编写完成下列操作的程序:(1)若两个数中只有一个是奇数,则将奇数存入ABUF单元,偶数存入BBUF单元。(2)若两个数均为奇数,则两数分别加1,并存回原变量处。(3)若两个数均为偶数,则两变量不变。

CODE SEGMENT ASSUMECS:CODE,DS:DATASTART:MOV AX,DATA MOV DS,AX MOVAL,ABUFMOVBL,BBUFXORAL,BLTESTAL,01H;测试是否为同类JZSAME;是同类,转CLASSTESEBL,01H;不是同类,测试B是否为偶数JZEXIT;B是偶数,满足要求(1),转EXITXCHGBL,ABUF;B不是偶数,按要求(1),交换两数MOVBBUF,BLJMPEXIT;转EXITSAME:TESTBL,01H;同类时,测试B是否为偶数JZEXIT;B是偶数,满足要求(3),转EXITINCABUF;B不是偶数,按要求(2),两数加1 CODE ENDS END START4.5汇编语言编程入门4-117⑵利用跳转表实现分支

——适于多分支结构。有三种跳转表:

BASE

关键字0ADR0

M

(c)根据关键字分支关键字nADRn关键字1ADR1+3+3nBASEJMP

JMPM

(b)根据表内指令分支JMP+3n+3BASEADR0

M

(b)根据表内地址分支ADRnADR1+2n+24.5汇编语言编程入门4-118使用跳转表实现分支时,要特别注意表内地址分支和表内指令分支两种结构跳转表的定义方法和正确的寻址方式。表内地址分支在数据段定义跳转表,用存储器间接寻址;表内指令分支在代码段定义跳转表,用寄存器间接寻址。4.5汇编语言编程入门4-119解:这是一个多分支结构程序,适合于用跳转表实现。假设用表内地址分支实现,此时,跳转表在数据段定义,转移要用存储器间接寻址的跳转指令。程序如下:

例4.20设某控制程序可完成8种产品的加工,每种加工程序对应一个数字(1~8)。现要求根据输入的值去加工相应产品。假设8种加工程序段与主程序在同一代码段中。4.5汇编语言编程入门4-120例4.20表内地址分支程序

.486DATASEGMENT‘DATA’DISPDB‘Errorrepeatinput’DB0AH,0DH,‘$’

BASEDDSBR1,SBR2,SBR3,SBR4DDSBR5,SBR6,SBR7,SBR8DATAENDSCODESEGMENT‘CODE’ASSUMECS:CODE,DS:DATASTART:MOVAX,DATAMOVDS,AXINPUT:MOVAH,1;输入数字序号INT21HCMPAL,‘1’JBERRCMPAL,‘8’JAERRSUBAL,‘1’

ANDEAX,0000000FH

JMPBASE[EAX*4]SBR1:…

SBR2:…

SBR8:…

ERR:CMPAL,‘E’JZEXITMOVDX,OFFSETDISPMOVAH,09HINT21HJMPINPUTEXIT:MOVAH,4CHINT21HCODEENDSENDSTART此题也可用表内指令分支实现。这时,跳转表要在代码段定义,转移则要用寄存器间接寻址的跳转指令。程序如下:4.5汇编语言编程入门4-121

.486DATASEGMENTUSE16‘DATA’DISPDB‘Errorrepeatinput’DB0AH,0DH,‘$’DATAENDSCODESEGMENTUSE16‘CODE’ASSUMECS:CODE,DS:DATASTART:MOVAX,DATAMOVDS,AXINPUT:MOVAH,1;

温馨提示

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

评论

0/150

提交评论