汇编语言子程序设计.ppt_第1页
汇编语言子程序设计.ppt_第2页
汇编语言子程序设计.ppt_第3页
汇编语言子程序设计.ppt_第4页
汇编语言子程序设计.ppt_第5页
已阅读5页,还剩34页未读 继续免费阅读

下载本文档

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

文档简介

本章主要教学内容,本章主要教学目的及要求,1.理解掌握子程序调用与返回指令; 2.掌握子程序设计的基本过程和设计方法; 3.能熟练设计子支程序。,1.子程序调用与返回指令。 2.子程序设计的基本过程和设计方法。,7.1 概述,7.1.1 子程序设计的概念,含义:被独立出来的程序段称为子程序或过程,主程序与子程序之间的关系,7.1.2 子程序的特性,(1)功能独立 (2)通用性 (3)可浮动性 (4)可递归和可重入性,7.1.3 子程序的优点,(1)简化了程序设计过程,使程序设计时间大量节省。 (2)缩短了程序的长度,节省了计算机汇编源程序的时间和程序的 存储空间。 (3)增加了程序的可读性,便于对程序的修改、调试。 (4)方便了程序的模块化、结构化和自顶向下的程序设计。,7.2 子程序调用和返回指令,7.2.1 子程序调用指令,类型,段内调用,主程序和子程序处在同一代码段,只改变IP值,段间调用,主程序和子程序处不在同一代码段,既改变IP值也改变CS值,段内直接调用,格式: CALL DST/NEAR PTR DST,功能:(1)SPSP-2 (SP)IP (2)IPIP+D16,段内间接调用,格式: CALL DST/WORD PTR DST,功能:(1)SPSP-2 (SP)IP (2)IP(EA),例:CALL MULL,段间直接调用,格式: CALL FAR PTR DST,功能:(1) SP SP-2(SP) CS SP SP-2(SP) IP (2) IP子程序偏移地址 CS子程序段地址,例:CALL BX CALL WORD PTR SI,段间直接调用,格式: CALL DWORD PTR DST,功能:(1) SP SP-2(SP) CS SP SP-2(SP) IP (2) IP(EA) CS(EA+2),例:CALL FAR PTR MULL,例:CALL DWORD PTR BX,从栈顶弹出一个字数据送入IP,7.2.2 返回指令,功能:从堆栈的栈顶弹出数据作为返回地址,含义:实现子程序执行完后要返回主程序的指令,分类:段内返回和段间返回,从栈顶弹出两个字数据分别送入IP和CS,类型,段内返回,RET,格式: RET,功能:IP(SP) SPSP+2,RET n,格式: RET n,功能:IP(SP) SP SP+2 SP SP+n,段间返回,RET,格式: RET,功能:IP (SP) SP SP+2 CS (SP) SP SP+2,RET n,格式: RET n,功能:IP (SP) SP SP+2 CS (SP) SP SP+2 SP SP+n,7.3 子程序的定义、调用和返回,7.3.1 子程序定义,1.子程序定义伪指令,格式: 子程序名 PROC NEAR/FAR RET 子程序名 ENDP,说明: (1)主程序和子程序在同一代码段中,定义为NEAR型。 (2)主程序和子程序不在同一代码段中,定义为FAR型。 (3)可将主程序定义为FAR型,看作是DOS调用的一个过程。,2.子程序调用方法说明,包括: (1)子程序名; (2)子程序功能; (3)占用寄存器; (4)入口参数; (5)输出参数; (6)子程序调用示例。,3.现场保护和现场恢复,现场保护:在子程序的功能实现前把将要用到的寄存器中的原有内 容保存起来,现场恢复:子程序的功能实现后,将数据取出再送回原来的寄存器中,例:子程序SUB1中用到了寄存器AX、BX、CX、DX,则可能的现场保护和现场恢复如下: SUB1 PROC PUSH AX ;现场保护 PUSH BX PUSH CX PUSH DX ;子程序功能段 POP DX ;现场恢复 POP CX POP BX POP AX RET SUB1 ENDP,注意:现场保护应与现场恢复的顺序正好相反。,4.子程序的设计方法,(1)利用过程定义伪指令声明; (2)利用RET指令返回主程序; (3)对堆栈的压入和弹出操作要成对使用; (4)现场保护和现场恢复; (5)应安排在代码段的主程序之外,也可以放在主程序开始之前; (6)允许嵌套和递归; (7)可以与主程序共用一个数据段,也可以使用不同的数据段; (8)编写可以很灵活,但一定要保证堆栈操作的正确性; (9)处理好子程序和主程序间的参数传递问题(见7.4节); (10)提供必要的子程序说明信息。,子程序定义应用举例,【例7-1】求两个数的最大公约数子程序,子程序调用方法说明: ;子程序名:MCDST ;功 能:求两个正整数的最大公约数; ;入口参数:AX和BX中存放两个正整数; ;出口参数:CX中存放求得的最大公约数; ;寄存器占用:使用AX、BX、CX、DX寄存器,CX中内容被改变, AX、BX、DX中的内容保持不变。,子程序清单: MCDST PROC NEAR/FAR PUSH AX ;保护现场 PUSH BX PUSH DX AGAIN:XOR DX,DX ;AX值扩展到DXAX中 DIV BX ;商存入AX,余数存入DX AND DX,DX JZ EXIT ;余数为0转EXIT,MOV AX,BX ;余数不为0更新被除数 MOV BX,DX ;更新除数 JMP AGAIN ;继续循环 EXIT:MOV CX,BX ;最大公约数存入CX POP DX ;恢复现场 POP BX POP AX RET ;返回主程序 MCDST ENDP,7.3.2子程序的调用与返回,调用子程序指令:CALL,返回主程序指令:RET,【例7-2】以下程序用于计算=m!/(n!*(m-n)!)的值(m、n为自然数,且mn)。(假设阶乘乘积大小不超过两个字节),DATA SEGMENT M EQU 8 N EQU 3 RES DW ? DATA ENDS CODE SEGMENT ASSUME CS:CODE,DS:DATA START:MOV AX,DATA MOV DS,AX MOV CX,N CALL SUB1 ;调子程序计算n! MOV BX,AX MOV CX,M CALL SUB1 ;调子程序计算m! DIV BX ;m!/n!送 AX MOV BX,AX,MOV CX,M SUB CX,N CALL SUB1 ;调用子程序,计算(m-n)! XCHG BX,AX DIV BX ;m!/n!/ (m-n)! 送AX MOV RES,AX MOV AH,4CH INT 21H SUB1 PROC ;计算阶乘的子程序 MOV AX,1 NEXT:MUL AX,CX LOOP NEXT RET SUB1 ENDP CODE ENDS END START,7.4 子程序的参数传递方法,入口参数:主程序调用子程序前,把要加工的数据传给子程序,这 些数据称为入口参数,出口参数:子程序执行完后,要把执行结果传回主程序,这些数据 称为出口参数,参数传递方式:寄存器传递、堆栈传递和存储单元传递,7.4.1 通过寄存器传递参数,含义:主程序把入口参数送入某些寄存器,然后调用子程序,子程序中 直接使用存放入口参数的寄存器进行处理。子程序处理完数据, 将执行结果作为出口参数存入寄存器中,回到主程序,主程序对 存放在寄存器中的出口参数进行相应处理,特点:方便、直观,适于参数较少的情况,注意:用于传递出口参数的寄存器不能进行现场保护和恢复,通过寄存器传递参数应用举例,【例7-3】以BCDBUF为首地址的内存中存放着若干单元的用BCD码表示的十进制数,每一个单元中存放两位BCD码,要求把它们分别转换为ASCII码,存放在ASCBUF为首地址的单元中,且高4位BCD码转换成得ASCII码放在地址较高的单元。并且要求边转换边显示这些ASCII码,DATA SEGMENT BCDBUF DB 12H,24H,96H,87H,71H,79H,56H,34H,63H,45H COUNT EQU $-BCDBUF ASCBUF DB 20 DUP(?) DATA ENDS STACK SEGMENT PARA STACK STACK STAPN DB 100 DUP (?) TOP EQU LENGTH STAPN STACK ENDS CODE SEGMENT ASSUME CS:CODE, DS:DATA,SS:STACK START:MOV AX,DATA MOV DS,AX MOV ES,AX MOV AX,STACK MOV SS,AX MOV AX,TOP MOV SP,AX MOV SI,OFFSET BCDBUF;BCD码的内存区首地址 MOV DI,OFFSET ASCBUF;ASCII码的内存区首地址 MOV CX,COUNT ;组合BCD码个数 CLD ;DF=0,按地址递增方式 LP:LODSB ;取一个组合BCD码 MOV BL,AL ;暂存 AND AL,0FH ;屏蔽高4位 OR AL,30H ;BCD码低位转换为ASCII码 MOV DL,AL ;存入DL,STOSB ;存入ASCII码存储区 CALL DISP ;调用显示子程序 MOV AL,BL ;取回BCD码 PUSH CX ;保存计数值 MOV CL,4 SHR AL,CL ;取BCD码高4位 OR AL,30H ;BCD码高位转为ASC码 MOV DL,AL ;存入DL STOSB ;存入ASCII码存储区 CALL DISP ;调用显示子程序 POP CX ;弹出计数值 LOOP LP ;计数不为0则继续 MOV AH,4CH;为0则返回DOS INT 21H ;子程序名:DISP ;功能:显示ASCII码字符 ;入口参数:ASCII码在DL中 DISP PROC ;子程序定义开始 MOV AH,2 ;显示ASCII码 INT 21H MOV DL, MOV AH,2 INT 21H RET ;返回主程序 DISP ENDP CODE ENDS END START,【例7-4】将给定的一组字数据X、Y代入Z=(X+Y)2-X)4公式中,计算相应的Z值,DATA SEGMENT X DW 5,3,8,9,2,5,3,4,7,1 Y DW 1,5,7,0,4,3,1,4,8,1 Z DW 10 DUP (?) DATA ENDS CODE SEGMENT ASSUME CS:CODE, DS:DATA START:MOV AX,DATA MOV DS,AX LEA SI,X LEA DI,Y LEA BX,Z MOV CX,Y-X SHR CX,1 REAPT:MOV AX,SI MOV DX,DI CALL SUBR MOV BX,AX ADD SI,2 ADD DI,2,ADD BX,2 LOOP REAPT EXIT:MOV AH,4CH INT 21H SUBR PROC NEAR PUSH BX PUSH CX MOV BX,AX ADD AX,DX ;AX=X+Y SAL AX,1 ;AX=(X+Y)2 SUB AX,BX ;AX=(X+Y)2-X MOV CL,2 SAL AX,CL ;AX=(X+Y)2-X)4 POP CX POP BX RET SUBR ENDP CODE ENDS END START,7.4.2 通过堆栈传递参数,含义:主程序把入口参数压栈保存,然后调用子程序,子程序从堆栈中 弹出入口参数进行处理。子程序处理完数据后将执行结果作为出 口参数压栈保存,回到主程序,主程序从堆栈中弹出出口参数进 行相应处理,通过堆栈传递参数应用举例,【例7-5】将例7-3改为用堆栈传递参数,DATA SEGMENT BCDBUF DB 12H,24H,96H,87H,71H,79H,56H,34H,63H,45H COUNT EQU $-BCDBUF ASCBUF DB 20 DUP(?) DATA ENDS STACK SEGMENT PARA STACK STACK STAPN DB 100 DUP (?) TOP EQU LENGTH STAPN STACK ENDS CODE SEGMENT ASSUME CS:CODE, DS:DATA START:MOV AX,DATA MOV DS,AX MOV ES,AX MOV SS,AX MOV AX,TOP MOV SP,AX MOV SI,OFFSET BCDBUF MOV DI,OFFSET ASCBUF MOV CX,COUNT CLD LP:LODSB MOV BL,AL AND AL,0FH OR AL,30H MOV AH,0 PUSH AX,STOSB CALL DISP MOV AL,BL MOV DX,CX MOV CL,4 SHR AL,CL OR AL,30H MOV CX,DX MOV AH,0 PUSH AX STOSB CALL DISP LOOP LP MOV AH,4CH INT 21H ;子程序名:DISP ;功能:显示ASCII码字符 ;入口参数:ASCII码在堆栈中 MOV AH,2 INT 21H MOV DL, MOV AH,2 INT 21H RET DISP ENDP CODE ENDS END START,【例7-6】利用堆栈传递参数,实现对2个已定义数组分别求和,DATA SEGMENT ARYA DB 06H,23H,0AH,2FH,1EH SUMA DW ? ARYB DB 0BH,21H,11H,3AH,4EH,10H SUMB DW ? DATA ENDS CODE SEGMENT ASSUME CS:CODE, DS:DATA START:MOV AX,DATA MOV DS,AX MOV AX,SUMA-ARYA PUSH AX MOV AX,OFFSET ARYA PUSH AX CALL SUM MOV AX,SUMB-ARYB PUSH AX MOV AX,OFFSET ARYB PUSH AX CALL SUM MOV AH,4CH INT 21H CODE ENDS PROCE SEGMENT ASSUME CS:PROCE,DS:DATA,SUM PROC FAR PUSH AX PUSH BX PUSH CX PUSH BP MOV BP,SP PUSHF MOV CX,BP+14 MOV BX,BP+12 MOV AX,0 LOP1:ADD AL,BX ADC AH,0 INC BX LOOP LOP1 MOV BX,AX POPF POP BP POP CX POP BX POP AX RET 4 SUM ENDP PROCE ENDS END START,7.4.3 通过存储单元传递参数,含义:主程序中把入口参数送入某些存储单元,然后调用子程序,子程 序中从存储单元取出入口参数进行处理。子程序处理完数据后, 将执行结果作为出口参数存入存储单元中,回到主程序,主程序 对存放在存储单元中的出口参数进行相应处理,通过存储单元传递参数应用举例,【例7-7】将例7-3改为用存储单元传递参数,DATA SEGMENT BCDBUF DB 12H,24H,96H,87H,71H,79H,56H,34H,63H,45H COUNT EQU $-BCDBUF ASCBUF DB 20 DUP(?) DATA ENDS STACK SEGMENT PARA STACK STACK STAPN DB 100 DUP (?) TOP EQU LENGTH STAPN STACK ENDS CODE SEGMENT ASSUME CS:CODE, DS:DATA START:MOV AX,DATA MOV DS,AX MOV ES,AX MOV AX,STACK MOV SS,AX MOV AX,TOP MOV SP,AX MOV SI,OFFSET BCDBUF MOV DI,OFFSET ASCBUF MOV CX,COUNT CLD LP:LODSB MOV BL,AL AND AL,0FH OR AL,30H STOSB CALL DISP,MOV AL,BL PUSH CX MOV CL,4 SHR AL,CL OR AL,30H STOSB CALL DISP POP CX LOOP LP MOV AH,4CH INT 21H ;子程序名:DISP ;功能:显示ASCII码字符 ;入口参数:ASCII码在堆栈中 DISP PROC ;子程序定义开始 PUSH DI DEC DI MOV DL,DI MOV AH,2 INT 21H POP DI MOV DL, MOV AH,2 INT 21H RET DISP ENDP CODE ENDS END START,【例7-8】,DATA SEGMENT XBUF DW x YBUF DW y FBUF DW ? BUF DW ?;入口参数单元 ROOT DW ?;出口参数单元 DATA ENDS CODE SEGMENT ASSUME CS:CODE, DS:DATA START:MOV AX,DATA MOV DS,AX MOV AX,XBUF MOV BUF,AX CALL SQROOT MOV CX,ROOT MOV AX,YBUF MOV BUF,AX CALL SQROOT MOV AX,ROOT ADD AX,CX,MOV FBUF,AX MOV AH,4CH INT 21H SQROOT PROC NEAR MOV DX,BUF XOR AX,AX AND DX,DX JZ SQR2 SQR1:MOV BX,AX SHL BX,1 INC BX SUB DX,BX JC SQR2 INC AX JMP SQR1 SQR2:MOV ROOT,AX RET SQROOT ENDP CODE ENDS END START,7.5 子程序的嵌套与递归,子程序的嵌套调用:子程序内包含有另外子程序的调用,子程序的递归调用:子程序直接或间接地调用其本身,7.5.1 子程序的嵌套调用,图7-4表示了两层嵌套的程序结构,子程序的嵌套应用举例,【例7-9】显示以“0”结尾字符串的嵌套子程序,DATA SEGMENT MSG DB WELL,I MADE IT!,0 DATA ENDS CODE SEGMENT ASSUME CS:CODE, DS:DATA START:MOV AX,DATA MOV DS,AX CLD MOV SI,OFFSET MSG CALL DPSTRI MOV AH,4CH INT 21H DPSTRI PROC PUSH AX DPS1:LODSB CMP AL,0,JZ DPS2 CALL DPCHAR JMP DPS1 DPS2:POP AX RET DPSTRI ENDP DPCHAR PROC PUSH AX MOV DL,AL MOV AH,2H INT 21H POP AX RET DPCHAR ENDP CODE ENDS END START,7.5.2 子程序的递归调用,子程序的递归应用举例,【例7-10】确定变量NUM的阶乘,把结果存入变量FNUM单元(变量NUM的值大于0小于9)。,DATA SEGMENT NUM DB 4 FNUM DW ? DATA ENDS CODE SEGMENT ASSUME CS:CODE,DS:DATA START:MOV AX,DATA MOV DS,AX PUSH CX MOV AH,0 MOV AL,NUM CALL FACT MOV FNUM,AX POP CX MOV AH,4CH,INT 21H FACT PROC NEAR PUSH AX SUB AX,1 JNZ F_CONT POP AX JMP RETURN F_CONT:CALL FACT POP CX MUL CL RETURN:RET FACT ENDP CODE ENDS END START,递归分析,7.6 子程序设计举例,7.6.1 输入输出子程序,1.有关I/O的DOS功能调用,含义:编了号的、可由汇编语言的源程序调用的I/O子程序,调用方法:把子程序的号(或称系统功能调用号)送至AH,把子程序规定的入口参数送至指定的寄存器,然后由中断指令INT 21H来实现调用,2.输入输出子程序设计,(1)输入子程序,子程序名:SUBIN 功 能:从标准输入设备(一般为键盘)输入一个字符 入口参数:无 出口参数:输入字符的ASCII码存入AL寄存器,程序清单: SUBIN PROC MOV AH,01H INT 21H RET SUBIN ENDP,(2)输出子程序,子程序名:SUBOUT 功 能:从标准输出设备(一般为屏幕)输出一个字符 入口参数:输出的字符的ASCII码送寄存器AL 出口参数:在屏幕上显示单个字符,程序清单: SUBOUT PROC PUSH DX MOV DL,AL MOV AH,2 INT 21H POP DX RET SUBOUT ENDP,输入输出子程序应用举例,【例7-11】在CRT上连续输出字符09,子程序名:CRT09 功 能:在CRT上连续输出字符09 入口参数:寄存器BL中不断累加得到的字符 出口参数:在CRT上连续输出字符09,CRT09 PROC NEAR/FAR BEGIN:PUSH DS MOV AX,0 PUSH AX MOV BL,OFFH PUSH BX MOV CX,10 GOON:MOV DL,20H CALL SUBOUT POP BX MOV AL,BL INC AL DAA AND AL,0FH MOV BL,AL PUSH BX OR AL,30H CALL SUBOUT LOOP GOON POP DS RET CRT09 ENDP,7.6.2 代码转换子程序,1.十六进制数的ASCII码转换成二进制数,转换规律:数字字符09进行转换时,对ASCII码的高4位清0就可以 了;而AF进行转换时,要减37H(af则减57H)。,【例7-12】将四位十六进制数(ASCII码)转换为十六位二进制数,子程序名:HEX16IN。 功 能:从输入设备输入四位16进制数,将其转换为16位2进 制数。 入口参数:从输入设备得到ASCII码表示的16进制数的各位,有 效数字为0-9和A-F。 出口参数:一个16位2进制数存放在DX寄存器中,JL HEX3 CMP AL,0FH JG HEX3 HEX2:CBW MOV CL,4 SAL DX,CL ADD DX,AX DEC BL JNZ HEX1 HEX3:POP AX POP CX RET HEX16IN ENDP,HEX16IN PROC NEAR/FAR PUSH CX PUSH AX PUSH BX MOV DX,0 MOV BL,4 HEX1:CALL SUBIN SUB AL,30H JL HEX3 CMP AL,9 JLE HEX2 SUB AL,7 CMP AL,0AH,2.二进制数转换成十进制数,转换规律:对要转换的16位二进制数进行一系列减法运算:能够减 10000的次数,就是十进制的万位,余下的数能够减1000 的次数,就是十进制的千位,依此类推。,【例7-13】将16位二进制数转换为十进制数的ASCII码形式,子程序名:DEC16OUT。 功 能:将DX寄存器中的16位2进制数转换为10进制数的ASCII 码并输出。 入口参数:16位2进制数存放在DX中。 出口参数:以10进制形式输出这个16位的2进制数。,DEC16OUT PROC NEAR/FAR PUSH SI PUSH DI PUSH CX PUSH AX MOV CX,5 LEA SI,DDEC LEA DI,TBUFF PUSH CX MOV AX,DX CONV:MOV BL,0 RRR:SUB AX,SI JC NEXT INC BL JMP RRR NEXT:ADD AX,SI,OR BL,30H MOV DI,BL ADD SI,2 INC DI LOOP CONV POP CX CRT1:DEC DI MOV AL,DI CALL SUBOUT LOOP CRT1 POP AX POP CX POP DI POP SI RET DEC16OUT ENDP,3.十进制数转换成二进制数,转换规律:BCD码表示的十进制数转换为二进制数,算法为: (010 + 千位数)10 + 百位数)10 + 十位数)10 + 个位数,【例7-14】将4位BCD码转换为二进制数,4位BCD码存放于字单元DBCD中,结果存于DBIN单元中。,子程序名:BCDEC。 功 能:将DX寄存器中的4位BCD码转换为二进制数。 入口参数:4位BCD码数存放在DX中。 出口参数:结果以二进制形式存放在DBIN单元,BCDEC PROC NEAR/FAR PUSH DI PUSH CX PUSH AX PUSH BX MOV CX,4 LEA DI, DBIN MOV BX,DX MOV AX,0 R1:PUSH CX MOV CL,4 ROL BX,CL POP CX,MUL 10 PUSH BX AND BX,000FH ADD AX,BX POP BX LOOP R1 MOV DBIN,AX POP BX POP AX POP CX POP DI RET BCDEC ENDP,7.6.3 多位数运算子程序,1.多位数加法子程序,【例7-16】多字节数相加,子程序名:MBINADD。 功 能:将两个多字节2进制数相加。 入口参数:SI、DI分别指向两个加数的首 地址,BX指向和的首地址,CX 中存放多字节的长度。 出口参数:BX指向和的首地址。,MBINADD PROC NEAR/FAR PUSH AX PUSH BX CLC MBINADD1:MOV AL,SI ADC AL,DI MOV BX,AL INC SI INC DI INC BX LOOP MBINADD1 POP BX POP AX RET MBINADD ENDP,说明:多字节数减法子程序与加法程 序类似,把ADC换成SBB即可,1.多位数乘法子程序,【例7-17】多字节数相乘,DATA SEGMENT BUFA DB 34H,5AH,6BH BUFB DB 10H,26H,49H CNT EQU $-BUFB BUFC DB 2*CNT DUP(?) DATA ENDS CODE SEGMENT ASSUME CS:CODE,DS:DATA START:MOV AX,DATA MOV DS,AX MOV SI,OFFSET BUFA MOV DI,OFFSET BUFB MOV BX,OFFSET BUFC CALL MBINMUL MOV SI,OFFSET BUFC CALL MBINDISP MOV AH,4CH INT 21H,;子程序名:MBINMUL。 ;功 能:两个多字节2进制数相乘。 ;入口参数:SI、DI分别指向两个乘数的首地址, BX指向乘积的首地址,乘数

温馨提示

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

评论

0/150

提交评论