arm嵌入式原理技術及應用ch4_第1頁
arm嵌入式原理技術及應用ch4_第2頁
arm嵌入式原理技術及應用ch4_第3頁
arm嵌入式原理技術及應用ch4_第4頁
arm嵌入式原理技術及應用ch4_第5頁
已閱讀5頁,還剩69頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

2024/11/6第四章ARM匯編程序設計2024/11/6

◆了解與熟悉ADS下的偽操作和宏指令以及它的應用

◆了解與熟悉GNU下的偽操作和宏指令以及它的應用

◆熟悉ARMATPCS

◆能夠利用匯編語言進行簡單的程序設計2024/11/61.偽指令、偽操作和宏指令概念

偽指令——是匯編語言程序里的特殊指令助記符,在匯編時被合適的機器指令替代。偽操作——為匯編程序所用,在源程序進行匯編時由匯編程序處理,只在匯編過程起作用,不參與程序運行。4.1.匯編偽指令和宏指令2024/11/6

宏指令——通過偽操作定義的一段獨立的代碼。在調用它時將宏體插入到源程序中。也就是常說的宏。

說明:所有的偽指令、偽操作和宏指令,均與具體的開發(fā)工具中的編譯器有關,當前主要采用ARM公司的“ADS/SDTIDE”開發(fā)工具,所以后面的討論,均是基于ARM公司的開發(fā)工具。2024/11/62.ARM匯編偽指令ARM偽指令不屬于ARM指令集中的指令,是為了編程方便而定義的。偽指令可以像其它ARM指令一樣使用,但在編譯時這些指令將被等效的ARM指令代替。ARM偽指令有四條,分別是:ADR:小范圍的地址讀取偽指令。ADRL:中等范圍的地址讀取偽指令。LDR:大范圍的地址讀取偽指令。NOP:空操作偽指令。2024/11/6(1)ADR——小范圍的地址讀取

ADR偽指令功能:將基于PC相對偏移的地址值或基于寄存器相對偏移的地址值讀取到寄存器中。

ADR偽指令功能的實現(xiàn)方法:在匯編編譯器編譯源程序時,ADR偽指令被編譯器替換成一條合適的指令。通常,編譯器用一條ADD指令或SUB指令來實現(xiàn)此ADR偽指令的功能,若不能用一條指令實現(xiàn),則產生錯誤,編譯失敗。

語法格式:

ADR{cond}register,expr其中:register:加載的目標寄存器。expr:地址表達式。取值范圍是參考P2122024/11/6例1:

……(0x20)ADRR1,Delay……Delay(0x64)MOVR0,R14……

使用ADR將程序標號Delay所表示的地址存入R1。編譯后的反匯編代碼:

……ADDR1,PC,#0x3C……MOVR0,R14PC+0x3C=0x20+0x08+0x3C=0x642024/11/6例2:查表

ADRR0,D_TAB;加載轉換表地址

LDRBR1,[R0,R2];使用R2作為參數(shù),進行查表

……D_TABDCB0xC0,0xF9,0xA4,0xB0,0x99,0x922024/11/6(2)ADRL——中等范圍的地址讀取

ADRL偽指令功能:將基于PC相對偏移的地址值或基于寄存器相對偏移的地址值讀取到寄存器中,比ADR偽指令可以讀取更大范圍的地址。

ADRL偽指令功能實現(xiàn)方法:在匯編編譯器編譯源程序時,ADRL被編譯器替換成兩條合適的指令。若不能用兩條指令實現(xiàn),則產生錯誤,編譯失敗。

語法格式:

ADRL{cond}register,expr

其中:register:加載的目標寄存器。expr:地址表達式。取值范圍參考P2122024/11/6例3:

……(0x20)ADRLR1,Delay

……Delay(0x64)MOVR0,R14

……

使用ADRL將程序標號Delay所表示的地址存入R1。編譯后的反匯編代碼:

……ADDR1,PC,#0x3CADDR1,R1,#0……MOVR0,R14ADRL偽指令被匯編成兩條指令,盡管第2條指令并沒有意義。2024/11/6(3)LDR——大范圍的地址讀取

LDR偽指令功能:用于加載32位立即數(shù)或一個地址值到指定的寄存器。

LDR偽指令功能實現(xiàn)方法:在匯編編譯源程序時,LDR偽指令被編譯器替換成一條合適的指令。

若加載的常數(shù)未超過MOV或MVN的范圍,則使用MOV或MVN指令代替該LDR偽指令;

否則匯編器將常量放入文字池,并使用一條程序相對偏移的LDR指令從文字池讀出常量。

2024/11/6

語法格式:

LDR{cond}register,=expr

其中:Register:加載的目標寄存器。expr:32位常量或地址表達式。2024/11/6例4:

……(0x060)LDRR1,=Delay……Delay(0x102)MOVR0,R14……

使用LDR將程序標號Delay所表示的地址存入R1。編譯后的反匯編代碼:

……LDRR1,stack……DelayMOVR0,R14……LTORGstackDCD0x102LDR偽指令被匯編成一條LDR指令,并在文字池中定義一個常量,該常量為標號Delay的地址。2024/11/6

注意:從指令位置到文字池的偏移量必須小于4KB。與ARM指令的LDR的區(qū)別:偽指令LDR的參數(shù)有“=”號。2024/11/6(4)NOP——空操作偽指令

NOP偽指令功能實現(xiàn)方法:在匯編時將被替代成ARM中的空操作,比如可能是“MOVR0,R0”指令等。

用途:NOP可用于延時操作。

語法格式:NOP

例:延時子程序

DelayNOP;空操作

NOPNOPSUBSR1,R1,#1;循環(huán)次數(shù)減1BNEDelayMOVPC,LR2024/11/63.ARM匯編偽操作 ADS編譯環(huán)境下的偽操作可分為以下幾類:◆符號定義(SymbolDefinition)偽操作◆數(shù)據定義(DataDefinition)偽操作◆匯編控制(AssemblyControl)偽操作◆其它(Miscellaneous)偽操作2024/11/6(1)符號定義偽操作GBLA,GBLL,GBLS:聲明全局變量。LCLA,LCLL,LCLS:聲明局部變量。SETA,SETL,SETS:給變量賦值。RLIST:為通用寄存器列表定義名稱。

2024/11/6(2)數(shù)據定義偽操作LTORG:聲明一個數(shù)據緩沖池的開始SPACE:分配一塊字節(jié)內存單元,并用0初始化DCB:分配一段字節(jié)內存單元,并初始化DCD、DCDU:分配一段字內存單元,并初始化MAP:定義一個結構化的內存表的首地址FIELD:定義結構化內存表中的一個數(shù)據域

2024/11/6◆MAP、FIELD、SPACEMAP0x100,R0;定義結構化內存表首地址的值為0x100+R0AFIELD16 ;定義A的長度為16字節(jié),位置為0x110+R0LTORG;定義數(shù)據緩沖池&0x8000DataSPACE4200;從當前位置開始分配4200字節(jié)的內存單元,并初始化為0。

2024/11/6

◆LTORG

用于聲明一個數(shù)據緩沖池(文字池)的開始。

語法格式:

LTORG例:startBLfunc ;……funcLDRR1,=0x8000;子程序……MOVPC,LR;子程序返回

LTORG;定義數(shù)據緩沖池&0x8000DataSPACE4200;從當前位置開始分配4200字節(jié)的內存單元,并初始化為0。END默認數(shù)據緩沖池為空2024/11/6注意:LTORG偽操作通常放在無條件跳轉指令之后,或者子程序返回指令之后,這樣處理器不會錯誤地將數(shù)據緩沖池中的數(shù)據當作指令來執(zhí)行。 通常ARM匯編編譯器把數(shù)據緩沖池放在代碼段的最后面,即下一個代碼段開始之前,或者END偽操作之前。2024/11/6

DCB——也可以用符號”=”表示 用于定義并且初始化一個或者多個字節(jié)的內存區(qū)域。

語法格式:

{label}DCBexpr{,expr}……或{label}=expr{,expr}其中expr表示: -128到255之間的一個數(shù)值常量或者表達式。一個字符串。

注意:當DCB后面緊跟一個指令時,可能需要使用ALIGN確保指令是字對齊的。2024/11/6

例:shortDCB1 ;為short分配了一個字節(jié),并初始化為1。 stringDCB“string”,0 ;構造一個以0結尾的字符串

2024/11/6

◆DCD、DCDU分配一段字內存單元

(1)DCD——分配一段字對齊的內存單元 用于分配一段字對齊的內存單元,并初始化。DCD也可以用符號”&”表示 語法格式:

{label}DCDexpr{,expr}……或{label}&expr{,expr}……

其中:expr:數(shù)字表達式或程序中的標號。

注意:DCD偽操作可能在分配的第一個內存單元前插入填補字節(jié)以保證分配的內存是字對齊的。2024/11/6 例: data1DCD2,4,6;為data1分配三個字,內容初始化為2,4,6data2DCDlabel+4;初始化data2為label+4對應的地址

(2)DCDU——分配一段字非嚴格對齊的內存單元 DCDU與DCD的不同之處在于DCDU分配的內存單元并不嚴格字對齊。2024/11/6(3)匯編控制偽操作IF,ELSE及ENDIF:有條件選擇匯編WHILE及WEND:有條件循環(huán)(重復)匯編MACRO,MEND及MEXIT:宏定義匯編2024/11/6(4)其它偽操作◆AREA:定義一個代碼段或數(shù)據段◆CODE16、CODE32:告訴編譯器后面的指令序列位數(shù)◆ENTRY:指定程序的入口點 ◆ALIGN:將當前的位置以某種形式對齊

◆END:源程序結尾

◆EQU:為數(shù)字常量、基于寄存器的值和程序中的標號定義一個字符名稱。2024/11/6◆EXPORT、GLOBAL:聲明源文件中的符號可以被其他源文件引用◆IMPORT、EXTERN:聲明某符號是在其他源文件中定義的◆GET、INCLUDE:將一個源文件包含到當前源文件中,并將被包含的文件在其當前位置進行匯編處理?!鬒NCBIN:將一個文件包含到當前源文件中,而被包含的文件不進行匯編處理2024/11/61)AREA

用于定義一個代碼段或是數(shù)據段。

語法格式:

AREAsectionname{,attr}{,attr}…

其中:sectionname:為所定義的段的名稱。attr:該段的屬性。具有的屬性為:CODE:定義代碼段。DATA:定義數(shù)據段。READONLY:指定本段為只讀,代碼段的默認屬性。READWRITE:指定本段為可讀可寫,數(shù)據段的默認屬性。2024/11/6ALIGN:指定段的對齊方式為2expression。expression的取值為0~31。COMMON:指定一個通用段。該段不包含任何用戶代碼和數(shù)據。NOINIT:指定此數(shù)據段僅僅保留了內存單元,而沒有將各初始值寫入內存單元,或者將各個內存單元值初始化為0。

注意:一個大的程序可包含多個代碼段和數(shù)據段。一個匯編程序至少包含一個代碼段。2024/11/6

2)CODE16和CODE32 CODE16告訴匯編編譯器后面的指令序列為16位的Thumb指令。

CODE32告訴匯編編譯器后面的指令序列為32位的ARM指令。

語法格式:

CODE16CODE32

注意:CODE16和CODE32只是告訴編譯器后面指令的類型,該偽操作本身不進行程序狀態(tài)的切換。2024/11/6

例:AREAChangeState,CODE,READONLYENTRY

CODE32;下面為32位ARM指令

LDRR0,=start+1BXR0……

CODE16;下面為16位Thumb指令startMOVR1,#10…….END;切換到Thumb狀態(tài),并跳轉到start處執(zhí)行2024/11/6

3)ENTRY

指定程序的入口點。

語法格式:

ENTRY

注意: 一個程序(可包含多個源文件)中至少要有一個ENTRY(可以有多個ENTRY),但一個源文件中最多只能有一個ENTRY(可以沒有ENTRY)2024/11/6

4)ALIGN

ALIGN偽操作通過填充0將當前的位置以某種形式對齊。

語法格式:

ALIGN{expr{,offset}}其中:expr:一個數(shù)字,表示對齊的單位。這個數(shù)字是2的整數(shù)次冪,范圍在20~231之間。 如果沒有指定expr,則當前位置對齊到下一個字邊界處。Offset:偏移量,可以為常數(shù)或數(shù)值表達式。不指定offset表示將當前位置對齊到以expr為單位的起始位置。2024/11/6例1:shortDCB1 ;本操作使字對齊被破壞ALIGN ;重新使其為字對齊MOVR0,1例2:ALIGN8 ;當前位置以2個字的方式對齊2024/11/65)END

END偽操作告訴編譯器已經到了源程序結尾。

語法格式:

END

注意: 每一個匯編源程序都必須包含END偽操作,以表明本源程序的結束。2024/11/6

6)EQU EQU偽操作為數(shù)字常量、基于寄存器的值和程序中的標號定義一個字符名稱。

語法格式:

nameEQUexpr{,type}其中:name:為expr定義的字符名稱。expr:基于寄存器的地址值、程序中的標號、32位的地址常量或者32位的常量。表達式,為常量。type:當expr為32位常量時,可以使用type指示expr的數(shù)據的類型。取值為:CODE32CODE16DATA2024/11/6

例:

abcdEQU2 ;定義abcd符號的值為2abcdEQUlabel+16;定義abcd符號的值為(label+16)abcdEQU0x1c,CODE32 ;定義abcd符號的值為絕對地址

;值0x1c,而且此處為ARM指令2024/11/67)EXPORT及GLOBAL

聲明一個源文件中的符號,使此符號可以被其他源文件引用。

語法格式:

EXPORT/GLOBALsymbol{[weak]}其中:symbol:聲明的符號的名稱。(區(qū)分大小寫)[weak]:聲明其他同名符號優(yōu)先于本符號被引用。例:AREAexample,CODE,READONLY

EXPORTDoAddDoAddADDR0,R0,R12024/11/68)IMPORT及EXTERN

聲明一個符號是在其他源文件中定義的。

語法格式:

IMPORTsymbol{[weak]} EXTERNsymbol{[weak]}其中:symbol:聲明的符號的名稱。2024/11/6[weak]:當沒有指定此項時,如果symbol在所有的源文件中都沒有被定義,則連接器會報告錯誤。當指定此項時,如果symbol在所有的源文件中都沒有被定義,則連接器不會報告錯誤,而是進行下面的操作。如果該符號被B或者BL指令引用,則該符號被設置成下一條指令的地址,該B或BL指令相當于一條NOP指令。其他情況下此符號被設置成0。2024/11/6 9)GET及INCLUDE

將一個源文件包含到當前源文件中,并將被包含的文件在其當前位置進行匯編處理。

指令格式:

GETfilename INCLUDEfilename其中:filename:包含的源文件名,可以使用路徑信息(可包含空格)。 例:GETd:\arm\file.s2024/11/610)INCBIN

將一個文件包含到當前源文件中,而被包含的文件不進行匯編處理

指令格式:

INCBINfilename其中:filename:被包含的文件名稱,可使用路徑信息(不能有空格)。

適用情況:通常使用此偽操作將一個可執(zhí)行文件或者任意數(shù)據包含到當前文件中。 例:INCBINd:\arm\file.txt2024/11/6

例:編寫一具有完整匯編格式的程序,實現(xiàn)冒泡法排序功能。設無符號字數(shù)據存放在從0x400004開始的區(qū)域,字數(shù)據的數(shù)目字存放在0x400000中。AREASORT,CODE,READONLY ENTRYSTART MOV R1,#0x400000LP SUBS R1,R1,#1 BEQ EXIT MOV R7,R1 LDR R0,=0x400004LP1 LDR R2,[R0],#4 LDR R3,[R0] CMP R2,R3 STRLOR3,[R0,#-4] STRLOR2,[R0] SUBSR7,R7,#1 BNE LP1 B LPEXIT END2024/11/64.GNU下的偽操作和宏指令

GNU編譯環(huán)境下的偽操作可分為以下幾類:1)常量編譯控制偽操作2)匯編程序代碼控制偽操作3)宏及條件編譯控制偽操作4)其他偽操作2024/11/61)常量編譯控制偽操作2024/11/62)匯編程序代碼控制偽操作2024/11/63)宏及條件編譯控制偽操作2024/11/64)其他偽操作2024/11/65.ADS與GNU編譯環(huán)境下的比較

2024/11/62024/11/64.2ARMATPCS1.基本ATPCS

ATPCS就是ARM程序和Thumb程序中子程序調用的基本規(guī)則。ATPCS規(guī)定了一些子程序間調用的基本規(guī)則。◆子程序調用過程中寄存器的使用規(guī)則◆數(shù)據棧的使用規(guī)則◆參數(shù)的傳遞規(guī)則。2024/11/6

相對于其他類型的ATPCS,滿足基本ATPCS的程序的執(zhí)行速度更快,所占用的內存更少。

它不能提供以下的支持:

1)ARM程序和Thumb程序相互調用;

2)數(shù)據以及代碼的位置無關的支持;

3)子程序的可重入性;

4)數(shù)據棧檢查的支持。2024/11/61)寄存器的使用規(guī)則

寄存器的使用必須滿足下面的規(guī)則:◆子程序間通過寄存器R0一R3來傳遞參數(shù)◆在子程序中,使用寄存器R4~R11來保存局部變量.◆寄存器R12用作子程序間scratch寄存器(用于保存SP,在函數(shù)返回時使用該寄存器出棧),記作ip。在子程序間的連接代碼段中常有這種使用規(guī)則。2024/11/6◆寄存器R13用作數(shù)據棧指針,記作sp?!艏拇嫫鱎14稱為連接寄存器,記作lr?!艏拇嫫鱎15是程序計數(shù)器,記作pc。它不能用作其他用途。2024/11/6

ATPCS中各寄存器的使用規(guī)則及其名稱2024/11/62)數(shù)據棧使用規(guī)則棧指針通常可以指向不同的位置。當棧指針指向棧頂元素(即最后一個入棧的數(shù)據元素)時,稱為FULL棧;當棧指針指向與棧頂元素(即最后一個入棧的數(shù)據元素)相鄰的一個可用數(shù)據單元時,稱為EMPTY棧。數(shù)據棧的增長方向也可以不同。當數(shù)據棧向內存地址減小的方向增長時,稱為DESCENDING棧,當數(shù)據棧向內存地址增加的方向增長時,稱為ASCENDING棧。2024/11/6

綜合這兩種特點可以有以下4種數(shù)據棧。FDFullDescendingEDEmptyDescendingFAFullAscendingEAEmptyAscendingATPCS規(guī)定數(shù)據棧為FD類型,并且對數(shù)據棧的操作是8字節(jié)對齊的。2024/11/63)數(shù)傳遞規(guī)則

(1)參數(shù)個數(shù)可變的子程序參數(shù)傳遞規(guī)則:對于參數(shù)個數(shù)可變的子程序,當參數(shù)不超過4個時,可以使用寄存器R0~R3來傳遞參數(shù);當參數(shù)超過4個時,還可以使用數(shù)據棧來傳遞參數(shù)。在參數(shù)傳遞時,將所有參數(shù)看作是存放在連續(xù)的內存字單元中的宇數(shù)據。然后,依次將各字數(shù)據傳送到寄存器R0、Rl、R2、R3中,如果參數(shù)多于4個,將剩余的字數(shù)據傳送到數(shù)據棧中,入棧的順序與參數(shù)順序相反,即最后一個字數(shù)據先入棧。2024/11/6(2)參數(shù)個數(shù)固定的子程序參數(shù)傳遞規(guī)則對于參數(shù)個數(shù)固定的子程序,參數(shù)傳遞與參數(shù)個數(shù)可變的子程序參數(shù)傳遞規(guī)則不同。如果系統(tǒng)包含浮點運算的硬件部件,浮點參數(shù)將按照下面的規(guī)則傳遞:

█各個浮點參數(shù)按順序處理。

█為每個浮點參數(shù)分配FP寄存器。

█分配的方法是,滿足該浮點參數(shù)需要的且編號最小的一組連續(xù)的FP寄存器。第一個整數(shù)參數(shù),通過寄存器R0~R3來傳遞。其他參數(shù)通過數(shù)據棧傳遞。2024/11/6(3)子程序結果返回規(guī)則結果為一個32位的整數(shù)時,可以通過寄存器R0返回。結果為一個64位整數(shù)時,可以通過寄存器R0和R1返回,依次類推。結果為一個浮點數(shù)時,可以通過浮點運算部件的寄存器f0、d0或者s0來返回。結果為復合型的浮點數(shù)(如復數(shù))時,可以通過寄存鉛f0~fn或者d0~dn來返回。對于位數(shù)更多的結果,需要通過內存來傳遞。2024/11/62.ARM和Thumb程序混合使用在編譯和匯編時,使用/interwork告訴編譯器生成的目標代碼遵守支持ARM程序和Thumb程序混合使用的ATPCS。它用在以下場合:1)程序中存在ARM程序調用Thumb程序的情況。2)程序中存在Thumb程序調用ARM程序的情況。3)需要連接器來進行ARM狀態(tài)和Thumb狀態(tài)切換的情況。2024/11/6例如:進行狀態(tài)切換的匯編程序ARMADRr0,ThumbProg+1BXr0;跳到ThumbProg,程序切換到Thumb狀志THUMB ;THUMB指示編譯器后面的為Thumb指令ThumbProg:...ADRr0,ARMProgBX r0;跳轉到ARMProg,程序切換到ARM狀態(tài)ARM ;ARM指示編譯器后面的為ARM指令ARMProg:MOVr4,#42024/11/64.3ARM程序設計1.ARM匯編語言程序設計

ARM匯編語言以段(section)為單位組織源文件。段是相對獨立的、具有特定名稱的、不可分割的指令或數(shù)據序列。段又可以分為代碼段和數(shù)據段,代碼段存放執(zhí)行代碼,數(shù)據段存放代碼運行時需要用到的數(shù)據。一個ARM源程序至少需要一個代碼段,大的程序可以包含多個代碼段和數(shù)據段。2024/11/61)ARM匯編中的文件格式ARM源程序文件(可簡稱為源文件)可以由任意一種文本編輯器來編寫程序代碼,它一般為文本格式。在ARM程序設計中,常用的源文件可簡單分為以下幾種.

2024/11/62)ARM匯編語言語句格式ARM匯編語言語句格式如下所示:{symbol}{instruction|directive|pseudo-instruction}{;comment}其中:

instruction為指令。

directive為偽操作。

pseudo-instrkeuction為偽指令。

symbol為符號。

comment為語句的注釋。

2024/11/6ARM匯編語言中,符號可代表地址、變量和數(shù)字常量。數(shù)字常量一般有3種表達方式:

十進制數(shù),如79、4等。

十六進制數(shù),以0x和&開頭,如0x345、0xFB。

n進制數(shù),用n_XXX表示,如2_01100101、8_5642。標號:表示程序中的指令或數(shù)據地址的符號,代表地址。局部標號:主要用于局部范圍代碼。2024/11/63)ARM匯編語言程序格式

ADS環(huán)境下ARM匯編語言源程序的基本結構:AREAEXAMPLE,CODE,READONLYENTRYstartMOVr0,#10MOVr1,#3

ADDr0,r0,r1END上述程序的程序體部分實現(xiàn)了一個簡單的加法運算。

2024/11/6GNU環(huán)境下ARM匯編語言源程序的基本結構:.equ x,45 /*定義變量x,并賦值為45*/.equ y,64 /*定義變量y,并賦值為64*/.equ stack_top,0x1000 /*定義棧頂0x1000*/.global_start.text_start: /*程序代碼開始標志*/MOVsp,#stack_topMOVr0,#x /*x的值放入R0*/MOVr1,#y /*y的值放入R0*/

ADDr2,r1,r0/*求二者之和并放入R1中*/

STR r2,[sp]/*將二者之和保存到堆棧中*/stop:

B stop/*程序結束,進入死循環(huán)*/.end

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論