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

下载本文档

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

文档简介

1、教学目标 熟悉单片机编程的步骤、方法和技巧 掌握单片机汇编程序的常用结构及设计方法 掌握典型汇编语言应用程序,第4章 汇编语言程序设计,第4章 汇编语言程序设计,4.1 汇编语言程序设计基础,计算机能完成各式各样的任务, 是因为各种的应用程序, 而设计程序就要用到程序设计语言。程序设计语言有3种: 机器语言、 汇编语言和高级语言。,1. 机器语言 计算机能直接识别和执行的二进制代码形式的指令称为机器指令,而该类指令的集合称为计算机的机器语言,或称指令系统。机器语言是面向计算机系统的。由于各种计算机内部结构,线路的不同,每种计算机系统都有它自己的机器语言, 即使执行同一操作, 其指令也不相同。,

2、一、 机器语言、 汇编语言,2. 汇编语言 计算机所能执行的每条指令都对应一组二进制代码。 为了容易理解和记忆计算机的指令,人们用助记符来描述每一条指令的功能。用助记符描述的指令系统,称为机器的汇编语言系统,简称汇编语言。汇编语言也是面向机器的,每种计算机系统也都有它自己的汇编语言,用汇编语言编写的程序,称为汇编语言源程序或汇编源程序。,汇编语言是面向机器的程序设计语言,与具体的计算机硬件有着密切的关系,然而汇编语言也有它的缺点,在用它编写程序时,必须熟悉机器的指令系统、寻址方式、寄存器设置和使用方法,而编出的程序也只适用于某一系列的计算机。因此, 可移植性差,不能直接移植到不同类型的计算机系

3、统上去。,3. 高级语言 高级语言(如C语言)克服了汇编语言的缺点, 是一种面向问题或过程的语言。它是一种接近于自然语言和数学算法的语言,与机器的硬件无关。高级语言不但直观、易学、易懂,而且通用性强, 可以在不同的计算机上运行,因此可移植性好。,MCS-51系列单片机,其汇编语言的语句格式, 也就是单片机的指令格式, 即: 标号: 操作码 操作数;注释,二、汇编语言的格式,1.操作码 指示计算机进行何种操作。 指令助记符,如MOV,ADD,NOP等 伪指令助记符,如END,DB,ORG等,2.标号 标号放于句首,指明语句所在单元的首位置。由18个字母数字构成,第一个必须是字母,允许使用一个下横

4、线符号。系统中保留字符或字符组不能用作标号,如各种特殊功能寄存器名、各个位地址记忆符、各种伪指令等都不能用作标号。 合法的标号:A1,LOOP等。 不能用作标号:4G,F-G,DB,EQU(后两种为保留字)。 标号不是每一行都必须要有,而只是在需要时才使用。,3.操作数 指令中的操作数或操作数地址。,立即数,如:MOV A,30H等;,寄存器名,如:MOV A,SP等。,标号地址,如:SUM EQU 30H MOV A,SUM等,带加减的表达式,如:MOV A,SUM+9,专门符号“$”,它表示转移指令所在的首地址,例如: LJMP$ 这条指令实际上是一条自身跳转的死循环。,三、 伪指令,汇编

5、语言语句一般分为指令性语句和指示性语句。 指令性语句是采用助记符构成的汇编语言语句,在汇编时能产生与之对应的机器码,供CPU识别,从而执行相应的功能。 指示性语句又称伪指令语句。伪指令不是真正的指令,虽然与指令的形式类似,但在汇编时不产生供CPU执行的任何机器代码。 伪指令起到指示说明的作用,在机器汇编时供汇编程序识别和执行的命令,用于在汇编过程中对数据的存储环境或汇编实施一定的控制。,1.ORG 起始汇编伪指令,标号: ORG 16位的地址或标号,汇编过程中,机器检测到该语句时,便确认了汇编的起始地址,然后把ORG伪指令下一条指令的首字节机器码存入16位的地址或标号所指示的存储单元内,其他的

6、后续指令字节或数据连续依次存入后面的存储单元中。,例: ORG 1000H START:MOV A,#45H;,结果:(1000H)=74H,(1001H)=45H,2.END 汇编结束伪指令,END,汇编程序检测到该语句时,认为汇编语言源程序已经结束,END后面的指令语句将不被汇编成机器码。一个程序中包括主程序和若干个子程序,只能有一个END语句,它在所有程序单位的最末尾。,3.EQU 赋值伪指令(等值),字符名 EQU 数据或汇编符,其功能是将一个数或者特定的汇编符号赋予规定的符号名称。,例如: INPEQU33H ADDA,#INP 这里将INP等值为33H.,“字符名”必须先赋值后使用

7、,因此EQU伪指令通常放在源程序的开头。,例: ORG 1000H KK EQU R0 H1 EQU 20H DISP EQU 0300H MOV R1,H1; MOV A,KK; ACALL DISP END,例: ORG 0000H CC DATA 20H DISP XDATA 0B00H MOV A,CC; LCALL DISP END,4.DATA 数据地址赋值伪指令,字符名 DATA 表达式,它用来给左边的“字符名”赋值。表达式可以是数据、地址,也可以是包含被定义的“字符名”在内的表达式,但不能是汇编符号,如R0-R7等。,(1)EQU伪指令定义的符号必须先定义后使用, 而DATA伪

8、指令的符号可以先使用后定义; (2)用EQU伪指令可以把一个汇编符号赋给一个字符名称,而DATA伪指令则不能。 (3)DATA伪指令可将一个表达式的值,赋给一个字符名称。所定义的字符名称也可以出现在表达式中,而用EQU定义的字符则不能这样使用。 (4)DATA伪指令常在程序中用来定义数据地址。,5.BIT 位地址赋值伪指令,字符名 BIT 位地址,例:X1 BIT 30H RECORD BIT P2.2,其功能是将位地址赋予所规定的字符名称。,把两位位地址分别赋给两个变量X1和RECORD,在编程中它们可当作位地址来使用。但不是所有的MCS-51汇编程序都有这条伪指令。当不具备BIT命令时,可

9、以使用EQU命令来定义位地址变量。,6.DB 定义字节伪指令,标号:DB 项或项表,从规定的地址单元开始,定义若干个8位内存单元的内容。在程序存储器的某一部分存入一组规定好的8位二进制数,或者是将一个数据表格存入程序存储器。这个伪指令在汇编后,将影响程序存储器的内容。,例如: TAB1:DB3FH,55,8,C TAB2:DB10100B,若TAB1的对应地址为2000H,则以上伪指令经汇编以后,将对2000H开始的若干内存单元赋值: (2000H)=3FH(2001H)=37H(2002H)=38H(2003H)=43H (2004H)=14H,7.DW 定义字伪指令,标号:DW 项或项表,

10、DW与DB的功能类似,区别在于DB定义的是字节,DW定义的是字。DW经常被用来定义16位的地址,16位地址的存放顺序是高8位在前,低8位在后。,例如: ORG1000H DW 3964H,6H,20,汇编以后结果为: (1000H)=39H (1001H)=64H (1002H)=00H (1003H)=6H (1004H)=00H (1005H)=14H,8. DS预留存储空间伪指令,标号: DS 表达式,该伪指令的功能是从标号指定的单元开始, 保留若干字节的内存空间以备源程序使用。存储空间内预留的存储单元数由表达式的值决定。,例如: ORG 1000H DS 10 DB 30H, 8FH,

11、从1000H开始,预留10个字节的内存单元,然后从1010H开始,按照下一条DB指令赋值,即(100AH)=30H, (100BH)=8FH。保留的存储空间将由程序的其它部分决定它们的用处。,MCS-51指令的汇编语言源程序, 必须经过从汇编源程序到机器语言目标程序的“翻译”, 才能在51系列单片机运行,这种翻译的过程称为汇编。 完成汇编工作有两种途径:一种是人工汇编;一种是机器汇编。,汇编程序是将汇编源程序转变为相应目标程序的翻译程序。由于指令助记符与机器语言指令是一一对应的等价关系, 所以汇编程序能很容易将汇编源程序迅速、准确、有效地翻译成目标程序。,4.2 MCS-51单片机汇编语言设计

12、,程序的基本算法结构有3种:顺序结构、分支(选择)结构和循环结构。,顺序结构:,分支结构:它又称为选择结构。该结构中包含一个判断框,根据给定条件P是否成立而选择执行A框操作或B框操作。条件P可以是累加器是否为零、两数是否相等,以及测试状态标志或位状态等等。,循环结构:它在一定的条件下, 反复执行某一部分的操作。循环结构又分为当型(While)循环结构和直到型(Until)循环结构两种方式。 当型循环是先判断条件,条件成立则执行循环体A;而直到型循环则是先执行循环体A一次,再判断条件,条件不成立再执行循环体A。循环结构的两种形式可以互相转换。,(a) 当型循环 (b) 直到型循环,一 简单程序设

13、计,例:将30H内的两位压缩BCD码拆开,并转换成相应的ASCII码,存入两个RAM单元31H和32H中(低位存31H),开始,保存30H内容,取低位,将低位变ASCII,取高位,将高位变ASCII,结束,ORG 1000H,MOV R0,#30H; MOV SP,#50H; MOV A,R0; PUSH ACC;,ANL A,#0FH; ORL A,#30H; INC R0; MOV R0,A;,POP ACC; ANL A,#0F0H; SWAP A; ORL A,#30H; INC R0; MOV R0,A;,END,例:将40H单元中8位无符号二进制数,转换成3位BCD码,并存在BAI

14、(百),SHI(十),GE(个)三个单元中。,ORG 2000H,BAI DATA 30H SHI DATA 31H GE DATA 32H MOV A, 40H MOV B, #100,DIV AB ;A/100,商存A,余数存B MOV BAI,A;存百位数,MOV A, B MOV B, #10,END,DIV AB ;A/10,商存A,余数存B MOV SHI, A;存十位数,MOV GE, B SJMP $,例:三字节无符号数相加,其中一个加数在内部RAM的50H、51H和52H单元中(高位存于52H),另一个加数在内部RAM的53H、54H和55H中(高位存于55H),把相加之和存

15、放在50H、51H和52H中,进位存放在位寻址区的00位中。,ORG 2000H,MOV R0,#50H; MOV R1,#53H; MOV A,R0; ADD A,R1; MOV R0,A;,INC R0; INC R1;,MOV A,R0; ADDC A,R1; MOV R0,A;,INC R0; INC R1;,MOV A,R0; ADDC A,R1; MOV R0,A;,MOV 00H,C;,END,二 分支程序设计,根据不同的条件,执行不同的程序段。直接用来判断分支条件的指令有JZ、JNZ、CJNE、JC、JNC、JB、JNB等。,例:在内部RAM50H单元中有一数,若其最高位为1,

16、则将此数各位变反,反之不变。,ORG 1000H,MOV A,50H;,JNB ACC.7,HERE;,CPL A; MOV 50H,A;,HERE:SJMP HERE;,END,ORG 1000H,MOV A,50H;,ANL A,#80H; CJNE A,#80H,HERE;,MOV A,50H;,CPL A;,MOV 50H,A;,HERE:SJMP HERE;,END,例:设变量X存放于R2,函数值Y存放于R3,按下式的要求给Y赋值。,ORG 0500H,MOV A,R2; CJNE A,#00H,L1;,MOV R3,#00H; SJMP L3;,L1:JNB ACC.7,L2,MO

17、V R3,#0FFH; SJMP L3;,L2:MOV R3,#01H;,L3:SJMP L3;,END,例:设变量X存放于R2,函数值Y存放于R3,按下式的要求给Y赋值。,ORG 0500H,MOV A,R2; JZ L2;,MOV R3,#01H;,JB ACC.7,L1,SJMP L3;,L1:MOV R3,#0FFH;,SJMP L3;,L2:MOV R3,#00H,L3:SJMP L3;,END,三、循环程序设计,循环程序一般由四部分组成:,1 循环初始化 循环初始化程序段位于循环程序的开头,用于完成循环前的准备工作。例如:给循环体中计数器和各工作寄存器设置初值。,2 循环处理 这部

18、分程序位于循环体内,是循环程序重复执行的部分。,3 循环控制 循环控制在循环体内,由修改循环控制变量和条件转移语句等组成,用于控制循环执行次数。,4 循环结束 用于存放执行循环程序所得结果以及恢复各单元结果,循环程序通常有两种编制方法: 一种是先循环处理后循环控制的直到型循环; 一种是先循环控制后循环处理的当型循环。,例:已知内RAM32H单元开始有一无符号数据块,块长在30H单元中,求数据块中各数累加和并存入31H单元中(设所加之和不超过8位数)。,ORG 0200H,MOV R2,30H; MOV R1,#32H; CLR A;,LOOP:ADD A,R1; INC R1; DJNZ R2

19、,LOOP;,MOV 31H,A;,END,ORG 0200H,MOV R2,30H; MOV R1,#32H; CLR A; INC R2;,CHECK:DJNZ R2,LOOP,SJMP CHECK;,LOOP:ADD A,R1; INC R1;,END,SJMP ,MOV 31H,A; SJMP ,例:内存中以STRING开始的区域有若干个字符和数字,一般称为一个字符串,最末一个字符为“$”,试统计这些字符数字的数目,结果存入NUM单元。,符号“$”的ASCII码是24H。,ORG 0300H NUM DATA20H STRING DATA21H CLR A;A清零 MOV R0,#ST

20、RING ;首地址送R0 LOP: CJNE R0,#24H,LOP2;与$不等转移 SJMP LOP3 ;找到$,结束循环 LOP2: INC A ;计数器加1 INC R0 ;修改地址指针 SJMP LOP ;循环 LOP3: INC A ;再计这个$字符 MOV NUM,A ;存结果 END,例:设在内部RAM的BLOCK单元开始处有长度为LEN个的无符号数据块, 试编一个求和程序, 并将和存入内部RAM的SUM单元(设和不超过8位)。,ORG 03OOH BLOCK EQU 20H LEN EQU 30H SUM EQU 40H,START: CLR A ; 清累加器A MOV R2,

21、 LEN ; 数据块长度送R2 MOV R1, BLOCK; 数据块首址送R1,LOOP: ADD A, R1 ; 循环加法 INC R1; 修改地址指针 DJNZ R2, LOOP ; 修改计数器并判断 MOV SUM, A; 存和 END,例:已知内部RAM31H为起始地址的数据块内数据是无符号数,块长在30H内,编程求数据块中最大值并存入29H单元中。,ORG 0300H,MOV R0,#31H; MOV 29H,#00H;,LOOP:MOV A,R0; CJNE A,29H,L1;,L1:JC NEXT; MOV 29H,A;,NEXT:INC R0; DJNZ 30H,LOOP;,E

22、ND,CJNE只用于无符号整数的比较。,SJMP ,例:把内部RAM中起始地址为BLK1的数据块传送到外部RAM中以BLK2为起始地址的区域,直到遇到“#”字符的ASCII码为止。数据块长度放在R1中。,ORG 2000H,BLK1 EQU 30H BLK2 EQU 1000H MOV R0,#BLK1; MOV DPTR,#BLK2;,XH:CLR C; MOV A,R0;,CJNE A,#23H,L1;,SJMP JS;,L1:MOVX DPTR,A; INC R0; INC DPTR; DJNZ R1,XH;,JS:SJMP JS;,END,SJMP ; END,例:已知以30H和50H

23、为首地址的存储区中分别有5个字节无符号被减数和减数(低位在前,高位在后),编写一多字节减法程序,把差放入以30H为起始地址的存储单元。,ORG 4000H,MOV R0,#30H; MOV R1,#50H; MOV R2,#05H; CLR C;,LOOP:MOV A,R0; SUBB A,R1; MOV R0,A; INC R0; INC R1; DJNZ R2,LOOP;,例:在外部RAM中,BLOCK开始的单元中有一无符号数据块, 其个数为LEN个字节。试将这些无符号数按递减次序重新排列,并存入原存储区。,ORG 1000H START: MOV DPTR, BLOCK; 置地址指针 M

24、OV P2, DPH ; P2作地址指针高字节 MOV R7, LEN ; 置外循环计数初值 DEC R7 ; 比较与交换 n-1次,LOOP0: CLR F0 ; 交换标志清 0 MOV R0, DPL; MOV R1, DPL ; 置相邻两数地址指针低字节 INC R1 MOV R6, R7 ; 置内循环计数器初值 LOOP1: MOVX A, R0 ; 取数 MOV B, A ; 暂存 MOVX A, R1 ; 取下一个数 CJNE A, B, NEXT; 相邻两数比较, 不等转 SJMP NOCHA ; 相等不交换,NEXT: JC NOCHA; Cy =1, 则前者大于后者, 不必交

25、换 SETB F0 ; 否则, 置交换标志 MOVX R0, A ; XCH A, B ; 两数交换, 大者在前, 小者在后 MOVX R1, A ; NOCHA: INC R0 INC R1; 修改指针 DJNZ R6, LOOP1 ; 内循环未完, 则继续 JNB F0, EXIT ; 若从未交换, 则结束 DJNZ R7, LOOP0; 外循环未完, 则继续 EXIT: RET,例:单片机使用12MHZ晶振时,一个机器周期为1us,执行一条DJNZ指令的时间为2us,求下面的程序延时多长时间?,DEL: MOV R7,#C8H; DEL1:MOV R6,#7DH;,DEL2:DJNZ R

26、6,DEL2; DJNZ R7,DEL1;,结果:C8H=200,7DH=125, T=2001252=50000us=50ms,四 查表程序设计,两条查表指令:,MOVC A,A+DPTR;,MOVC A,A+PC;,例:已知R0中有一个十六进制数(0-F中的一个),编程把它转换成相应的ASCII码并送入R0。,ORG 0100H,MOV DPTR,#TAB; MOV A,R0;,MOVC A,A+DPTR;,MOV R0,A;,SJMP ,TAB:DB 0, 1,2,3,4,DB 5, 6,7,8,9,DB A, B,C,D,E,F,END,例:已知R0中有一个十六进制数(0-F中的一个)

27、,编程把它转换成相应的ASCII码并送入R0。,ORG 0100H,MOV A,R0; ADD A,#03H;,MOVC A,A+PC;,MOV R0,A;,SJMP ,TAB:DB 0, 1,2,3,4,DB 5, 6,7,8,9,DB A, B,C,D,E,F,END,使用DPTR作为基地址查表比较简单: (1)将所查表格的首地址存入DPTR数据指针寄存器; (2)将所查表格的项数(即在表中的位置是第几项)送累加器A; (3)执行查表指令MOVC A,A+DPTR进行读数,查表结果送回累加器A。,使用PC作为基地址查表,也可分为三步: (1)将所查表格的项数送累加器A,在MOVC A,A+

28、PC指令前先写上ADD A,#data指令,data的值待定; (2)计算从MOVC A,A+PC指令执行后的地址到所查表的首地址之间的距离(以字节数表示),用这个计算结果取代加法指令中的data,作为A的调整量; (3)执行查表指令MOVC A,A+PC进行查表,查表结果送回累加器A。,五 散转程序设计,散转程序为分支程序的一种,是根据某种输入或运算的结果,分别转向各个处理程序。使用MCS-51指令 JMP A+DPTR 可以很容易地实现散转功能。,1、使用转移指令表(在2KB范围内),如果程序入口和散转表均在2KB范围内,可以使用散转指令实现转移。,例:根据R2的内容,转向各个处理程序 (

29、R2)=0,转向PRG0;(R2)=1,转向PRG1, (R2)=N,转向PRGN,MOV DPTR,#TAB; MOV A,R2; ADD A,R2; JNC NADD; INC DPH;,NADD:JMP A+DPTR;,TAB:AJMP PRG0 AJMP PRG1 AJMP PRGN,2 使用转向地址表的散转程序(64KB范围内),当转向范围较大时,可以直接使用转向地址表的方法,它的各项表目为各个转向程序的入口。,例:根据R2的内容转向各个处理程序,MOV DPTR,#TAB1; MOV A,R2; ADD A,R2; JNC NADD; INC DPH;,NADD:MOV R3,A;

30、 MOVC A,A+DPTR; XCH A,R3; INC A; MOVC A,A+DPTR;,MOV DPL,A; MOV DPH,R3; CLR A; JMP A+DPTR;,TAB1:DW PRG0 DW PRG1 DW PRGN,PRG0: PRGN:,六 子程序设计,子程序是指完成某一确定任务并能被其他程序反复调用的程序段。子程序在结构上应具有通用性和独立性,ORG 4000H MOV SP,#50H; MOV A,R2; ACALL HASC; MOV 30H,A; MOV A,R2; SWAP A; ACALL HASC; MOV 31H,A; SJMP ;,HASC:MOV D

31、PTR,#TAB; ANL A,#0FH; MOVC A,A+DPTR; RET,TAB:DB 01234567 DB 89ABCDEF,例:在R2中有两位16进制数,试将它们分别转换成ASCII,并存入30H和31H单元中。,END,ORG 3000H Y1 DATA 30H; MOV SP,#50H; MOV DPTR,#TAB; PUSH 02H; ACALL HASC; POP Y1; MOV A,R2; SWAP A; PUSH ACC; ACALL HASC; POP Y1+1; SJMP ;,HASC:DEC SP; DEC SP; POP ACC; ANL A,#0FH; MO

32、VC A,A+DPTR; PUSH ACC; INC SP; INC SP; RET,TAB:DB 01234567 DB 89ABCDEF,例:在R2中有两位16进制数,试将它们分别转换成ASCII,并存入Y1和Y1+1单元中。,END,例:编制C=A2+B2 程序,设A和B均小于10的整数,ABC放在内部RAM的XA、XB、XC三个单元中。,ORG 2000H XA DATA 40H XB DATA 41H XC DATA 42H MOV A,XA; ACALL SQR;,SQR;MOV B,A; MUL AB; RET,MOV XC,A; MOV A,XB; ACALL SQR;,ADD

33、 A,XC; MOV XC,A; SJMP ;,END,4-4 从20H单元开始存放一组带符号数,其个数已存在1FH单元。要求统计出大于0、小于0和等于0的个数并存于ONE、TWO、THREE三个单元。,ORG 1000H ONE EQU 30H TWO EQU 31H THREE EQU 32H,MOV 30H,#00H; MOV 31H,#00H; MOV 32H,#00H;,MOV R0,#20H;,L:MOV A,R0;,CJNE A,#00H,L1;,INC THREE; SJMP CH;,L1:JB ACC.7 L2;,INC ONE; SJMP CH;,L2:INC TWO;,C

34、H:INC R0; DJNZ 1FH,L;,SJMP $; END,4-7 外部RAM从2000H-2100H有一数据块,请编出将它们传送到外部RAM3000H-3100H区域的程序。,ORG 4000H MOV DPTR,#2000H; MOV P2,#30H; MOV R0,#00H; MOV R2,#00H;,DJNZ R2,XH;,XH:MOVX A,DPTR;,MOVX R0,A;,INC DPTR; INC R0;,MOVX A,DPTR;,MOVX R0,A;,MOV P2,#31H;,SJMP ;,END,4-8 在内存RAM中,有一个以BLOCK为始址的数据块,块长在LEN单元,它们若是十六进制数中的A-F变为ASCII码,若不是变为00H,用查表指令实现。,SJMP LOP4; LOP3:MOV A,#00H; LOP4:MOV R0,A; INC R0; DJNZ R1,LOP SJMP $;,LOP: MOV A,R0; CLR C; CJNE A,#OAH,LOP1; LOP1:JC LOP3; CJNE A,#10H,LOP2; LOP2:JNC LOP3; CLR C; SUBB A,#0AH; MOVC A,A+DPTR;,TAB:DB A,B,C,D,E,F,END,ORG 0100H,MOV DPTR,#TAB;

温馨提示

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

最新文档

评论

0/150

提交评论