赵工的个人空间


专业技术部分转网页计算转业余爱好部分


 单片机与嵌入式

首页 > 专业技术 > 单片机与嵌入式 > 51单片机的汇编指令系统
51单片机的汇编指令系统

AT89C51汇编语言指令系统有42种助记符和111种指令,按指令长度可分单字节指令、双字节和三字节指令,按执行时间可分为单机器周期指令(64种)、双机器周期指令(45种)和四周期指令(只有乘、除法指令两种)。

汇编语言的指令格式一般为:

[标号:] 操作码 [操作数1][,操作数2][,操作数3][;注释]

标号:用符号表示该条指令的首地址,以字母开头,以冒号结束,根据需要设置。

操作码:是由助记符表示的字符串,以规定指令实现何种功能,是指令语句中必须的。

操作数:用字母、字符和数字等表示,可以是数据、地址、寄存器等。操作数个数因指令不同而不同,可多至3个,各操作数之间用”,”分隔。

注释:必须以”;”开始,是为便于阅读而对指令的附加说明,可用汉字。

注:每条指令必须有操作码,方括号内所包含的内容可选;标号不能用系统中已定义的字符;标号与操作码间要有”:”分隔;操作码和操作数之间一定要有空格;操作数之间必须用”,”分隔;每行只能有一条指令。

汇编语言指令系统中除表示操作码的42种助记符外还使用了一些符号,含义如下:

 Rn:当前选中的工作寄存器组中的8个寄存器R0~R7(n=0~7)。

 Ri:当然选中的工作寄存器组中的2个寄存器R0、R1(i=0、1)。

 direct:8位直接地址,可以是片内RAM的地址(00H~7FH)或特殊功能寄存器地址。

 #data8:包含在指令中的8位二进制数。

 #data16:包含在指令中的16位二进制数。

 Addr16:16位二进制地址,用于LCALL、LJMP等指令中,能到64kB地址的任何地方。

 Addr11:用于ACALL和AJMP指令中,在下条指令首地址所在页的2kB范围内。

 rel:是用补码表示的单字节带符号偏移字节数,取值范围为-128~+127。

 DPTR:数据指针,可用作16位二进制的地址寄存器。

 Bit:位,片内RAM及SFR中的可寻址位。

 A:累加器。

 B:特殊功能寄存器,常用于乘、除指令MUL和DIV中。

 C:进位标志或进位位,或位处理器中的累加器,也可用Cy表示。

 @:间址寄存器或基址寄存器的前缀,如@Ri、@DPTR。

 /:位操作的前缀,表示对该位操作数取反,如/bit。

 (X):X中的内容。

 ((X)):X中的内容为地址的空间中的内容。

 ←:用箭头右边的内容取代箭头左边的内容。

 $:指本条指令的首地址。

按指令功能可把111种指令分为5类:数据传送类(29种)、算术操作类(24种)、逻辑操作类(24种)、控制程序转移类(17种)、布尔变量操作类(即位操作类)(17种)。

1. 数据传送指令:

数据传送类指令有29种,可分为片内RAM数据传送指令(MOV类)、片外RAM数据传送指令(MOVX类)、程序存储器ROM数据传输指令(MOVC类)、堆栈操作指令、数据交换指令。数据传送指令操作数一般为两个,即“操作数1”和“操作数2”,这时“操作数2”可称为“源操作数”,“操作数1”可称为“目的操作数”。

1)片内RAM数据传送指令:

此类指令的特征是操作码为MOV。表中列出了片内RAM数据传送指令、功能、机器码和执行机器周期。

指令

功能操作

机器代码(16进制)

机器周期

MOV A,#data

(A)

 

 

 

←data

74 data

1

MOV Rn,#data

(Rn)

78~7F data

1

MOV @Ri,#data

((Ri))

76~77 data

1

MOV direct,#data

(direct)

75 direct data

2

MOV DPTR,#data16

(DPTR)

90 data15~8 data7~0

2

MOV A,direct

(A)

 

←(direct)

E5 direct

1

MOV Rn,direct

(Rn)

A8~AF direct

2

MOV @Ri,direct

((Ri))

A6~A7 direct

2

MOV direct1,direct2

(direct1)

←(direct2)

85 direct2 direct1

2

MOV @Ri,A

((Ri))

←(A)

F6~F7

1

MOV A,Rn

(A)

←(Rn)

E8~EF

1

MOV Rn,A

(Rn)

←(A)

F8~FF

1

MOV direct,A

(direct)

←(A)

F5 direct

1

MOV direct,Rn

(direct)

←(Rn)

88~8F direct

2

MOV A,@Ri

(A)

←((Ri))

E6~E7

1

MOV direct,@Ri

(direct)

←((Ri))

86~87 direct

2

2)片外RAM数据传送指令:

此类指令的特征是操作码为MOVX。表中列出了片外RAM数据传送指令、功能、机器码和执行机器周期。

指令

功能操作

机器代码(16进制)

机器周期

MOVX A,@Ri

(A)

←(Ri)

E2~E3

2

MOVX @Ri,A

((Ri))

←(A)

F2~F3

2

MOVX A,@DPTR

(A)

←((DPTR))

E0

2

MOVX @DPTR,A

((DPTR))

←(A)

F0

2

该类指令均涉及对片外RAM的64kB地址单元操作,而指令MOXV A,@Ri和MOVX @Ri,A中Ri只提供片外RAM地址的低8位地址,所以高8位应由P2提供。

3)ROM数据传送指令(查表指令):

这类指令共有2条,其特征操作码为MOVC,涉及ROM的寻址空间均为64kB。表中列出了ROM数据传送指令、功能、机器码和执行机器周期。

指令

功能操作

机器代码(16进制)

机器周期

MOVC A,@A+DPTR

(A)←((A)+(DPTR))

93

2

MOVX A,@A+PC

(PC)←(PC)+1   (A)←((A)+(PC))

83

2

A中的内容称为变址,DPTR、PC中内容称为基址。MOVC A,@A+DPTR指令首先执行A中的内容与DPTR中的内容进行16位无符号数的加法操作,获得基址与变址之和,将和作为地址,再将该地址中的内容传送到累加器A中。低8位相加产生进位时,直接加到高位,并不影响进位标志。

MOVC A,@A+PC指令首先将PC值修正到指向该指令的下一条指令地址,然后执行16位无符号数加法操作,获得基址与变址之和,将和作为地址,再将该地址中的内容传送到累加器A中。低8位相加产生进位时,直接加到高位,并不影响进位标志。

4)堆栈操作指令:

表中列出了堆栈操作指令、功能、机器码和执行机器周期。

指令

功能操作

机器代码(16进制)

机器周期

PUSH direct

(SP)←(SP)+1   ((SP))←(direct)

C0 direct

2

POP direct

(direct)←((SP))   (SP)←(SP)-1

D0 direct

2

第一条指令称为入栈指令,用于把direct地址中的内容传送到堆栈中去。这条指令执行时分为两步执行,第一步使SP中的值加1,使之指向新的栈顶单元;第二步是把direct中的数据压入由(SP)为地址的栈顶单元中,即((SP))←(direct)。

第二条指令称为弹出指令。这条指令也分两步执行,第一步把栈顶单元中的数据传送到direct单元中,即(direct)←((SP));第二步是使SP中的原栈顶地址减1,使之指向新的栈顶地址。

堆栈操作指令对堆栈指针SP而言是寄存器间接寻址指令,对direct而言是直接寻址,编写程序时应注意direct所表示的是直接地址。

例如:KEIL中认定A、R1位寄存器,而ACC、01H为直接地址,所以PUSH ACC、PUSH 01H、POP 01H、POP ACC为正确格式,而PUSH A、PUSH R1、POP R1和POP A错误。

5)数据交换指令:

表中列出了数据交换指令、功能、机器码和执行机器周期。

指令

功能操作

解释

机器代码(16进制)

机器周期

XCH A,Rn

(A)←(Rn)   

A中的内容和片内RAM单元中的内容相交换

 

C8~CF

1

XCH A,direct

(A)←(direct)   

C5 direct

1

XCH A,@Ri

(A)←((Ri))   

C6~C7

1

XCHD A,@Ri

(A)←((Ri))   

低4位相交换,高4位不变

D6~D7

1

SWAP A

(A3~0)←(A7~4)   

同一字节中高、低4位互换

D6~D7

1

2. 算术运算类指令:

算术运算类指令有24种,包括加、减、乘、除4种基本算术指令,能对8位无符号数进行直接的运算,借助溢出标志可对带符号数进行补码运算。有些算术运算类指令执行的结果将会影响程序状态字(PSW)中的标志位C、AC、OV,但是加1和减1指令并不影响这些标志位。表中列出了对进位标志位C、辅助进位标志位AC、溢出标志OV位有影响的所有指令。

指令

影响标志位

 

影响标志位

C

OV

AC

C

OV

AC

ADD  ADDC  SUBB

CPL  C

 

 

MUL  DIV

0

 

CJNE

 

 

DA

 

 

ANL C,bit

 

 

SETB  C

1

 

 

ORL C,bit

 

 

CLR  C

0

 

 

ANL C,bit-

 

 

MOV C,bit

 

 

ORL C,bit-

 

 

RRC  RLC

 

 

 

 

 

 

1)加法指令:

表中列出了加法指令、功能、机器码和执行机器周期。

指令

功能操作

机器代码(16进制)

机器周期

ADD A,Rn

(A)←(A)+(Rn)   

28~2F

1

ADD A,direct

(A)←(A)+(direct)   

25 direct

1

ADD A,@Ri

(A)←(A)+((Ri))   

26~27

1

ADD A,#data

(A)←(A)+data   

24 data

1

这些指令分别将工作寄存器中的数据、片内RAM单元中的数据、以Ri的内容为地址的单元中的数据或8位二进制立即数和累加器A中的数相加,并将相加所得的和存放在A中。若相加时第3位或第7位有进位时,则分别将AC、C标志位置1,否则为0。

2)带进位C的加法指令:

表中列出了带进位C的加法指令、功能、机器码和执行机器周期。

指令

功能操作

机器代码(16进制)

机器周期

ADDC A,Rn

(A)←(A)+(Rn)+C

38~3F

1

ADDC A,direct

(A)←(A)+(direct)+C   

35 direct

1

ADDC A,@Ri

(A)←(A)+((Ri))+C   

36~37

1

ADDC A,#data

(A)←(A)+data+C   

34 data

1

这些指令执行后,累加器A中内容为“和”。若相加时第3位或第7位有进位时,则分别将AC、C标志位置1,否则为0。

3)加1指令:

表中列出了加1指令、功能、机器码和执行机器周期。

指令

功能操作

机器代码(16进制)

机器周期

INC Rn

(Rn)←(Rn)+1

08~0F

1

INC direct

(direct)←(direct)+1 

05 direct

1

INC @Ri

((Ri))←((Ri))+1  

06~07

1

INC A

(A)←(A)+1 

04

1

INC DPTR

(DPTR)←(DPTR)+1  

A3

2

这些指令执行后,不影响PSW中的标志位C、AC、OV。

4)带进位C减法指令:

表中列出了带进位C的减法指令、功能、机器码和执行机器周期。

指令

功能操作

机器代码(16进制)

机器周期

SUBB A,Rn

(A)←(A)-(Rn)-C

98~9F

1

SUBB A,direct

(A)←(A)-(direct)-C   

95 direct

1

SUBB A,@Ri

(A)←(A)-((Ri))-C   

96~97

1

SUBB A,#data

(A)←(A)-data-C   

94 data

1

减法操作会对PSW中的标志位C、AC、OV产生影响。当减法有借位时,C=1,否则C=0;若低4位向高4位借位时,C=1,否则C=0;进行减法运算时,最高位与次高位不同时发生借位,则OV=1,否则OV=0。

虽然没有不带进位C的减法指令,但可在带进位C的减法指令前加清进位标志指令CLR C,将C清零,实际效果就是不带进位的减法运算。

5)减1指令:

表中列出了减1指令、功能、机器码和执行机器周期。

指令

功能操作

机器代码(16进制)

机器周期

DEC Rn

(Rn)←(Rn)-1

18~1F

1

DEC direct

(direct)←(direct)-1 

15 direct

1

DEC @Ri

((Ri))←((Ri))-1  

16~17

1

DEC A

(A)←(A)-1 

14

1

这些指令执行后,不影响PSW中的标志位C、AC、OV。

6)十进制调整指令:

表中列出了十进制调整指令、功能、机器码和执行机器周期。

指令

功能操作

机器代码(16进制)

机器周期

DA  A

若[(A3-0)>9]V[(AC)=1]则(A3~0)←(A3~0)+6

若[(A7-4)>9]V[(C)=1]则(A7~4)←(A7~4)+6

D4

1

DA A必须紧跟加法指令后,对加法运算所得的结果进行十进制调整。结果中,若低4位大于9,则低4位加6调整;若高4位大于9,则高4位加6调整。该指令对进位标志C产生影响。

前面紧跟的加法指令中,操作数为BCD码形式,结果就要用十进制调整指令。不能用DA指令对减法操作的结果进行调整。

7)乘除指令:

表中列出了乘除指令、功能、机器码和执行机器周期。

指令

功能操作

机器代码(16进制)

机器周期

MUL AB

(B7~0)(A7~0)←(A)x(B)

A4

4

DIV AB

(A)←(A)/(B)的商     (B)←(A)/(B)的余数

84

4

MUL指令实现了8位无符号数的乘法操作,被乘数与乘数分别放在累加器A和寄存器B中,执行后乘积为16位,低8位放在A中,高8位放在B中,并清进位标志C为0。若乘积大于FFH(255),溢出标志OV置1,否则置0.乘法指令需要4个机器周期,即48个振荡周期,对12MHz晶振系统,执行一次时间为4us。

DIV指令可实现8位无符号数除法,一般被除数放在A中,除数放在B中。指令执行后,商放在A中,余数放在B中,并清进位标志C为0。当除数为0时,OV标志置1,溢出。

3. 逻辑运算指令:

逻辑运算指令对两个8位二进制数进行与、或、非和异或等逻辑运算。逻辑运算是按位进行的。逻辑运算符分别为∧∨!⊕,逻辑运算法则如表:

参与运算的数据

∧与的结果

∨或的结果

⊕异或的结果

0

0

0

0

0

0

1

0

1

1

1

0

0

1

1

1

1

1

1

0

1)逻辑与指令:

表中列出了逻辑与指令、功能、机器码和执行机器周期。

指令

功能操作

机器代码(16进制)

机器周期

ANL A,Rn

(A)←(A)∧(Rn)   

58~5F

1

ANL A,direct

(A)←(A)∧(direct)   

55 direct

1

ANL A,@Ri

(A)←(A)∧((Ri))   

56~57

1

ANL A,#data

(A)←(A)∧data   

54 data

1

ANL direct,A

(direct)←(direct)∧(A)   

52 direct

1

ANL direct,#data

(direct)←(direct)∧data   

53 direct data

2

2)逻辑或指令:

表中列出了逻辑或指令、功能、机器码和执行机器周期。

指令

功能操作

机器代码(16进制)

机器周期

ORL A,Rn

(A)←(A)∨(Rn)   

48~4F

1

ORL A,direct

(A)←(A)∨(direct)   

45 direct

1

ORL A,@Ri

(A)←(A)∨((Ri))   

46~47

1

ORL A,#data

(A)←(A)∨data   

44 data

1

ORL direct,A

(direct)←(direct)∨(A)   

42 direct

1

ORL direct,#data

(direct)←(direct)∨data   

43 direct data

2

3)逻辑异或指令:

表中列出了逻辑异或指令、功能、机器码和执行机器周期。

指令

功能操作

机器代码(16进制)

机器周期

XRL A,Rn

(A)←(A)⊕(Rn)   

68~6F

1

XRL A,direct

(A)←(A)⊕(direct)   

65 direct

1

XRL A,@Ri

(A)←(A)⊕((Ri))   

66~67

1

XRL A,#data

(A)←(A)⊕data   

64 data

1

XRL direct,A

(direct)←(direct)⊕(A)   

62 direct

1

XRL direct,#data

(direct)←(direct)⊕data   

63 direct data

2

4)累加器清零、取反指令:

表中列出了累加器清零和取反指令、功能、机器码和执行机器周期。

指令

功能操作

机器代码(16进制)

机器周期

CLR A

(A)←0 

E4

1

CPL A

(A)←(!A)

F4

1

这两条指令皆为单字节单周期指令。

5)移位指令:

表中列出了移位指令、功能、机器码和执行机器周期。

指令

功能操作

机器代码(16进制)

机器周期

RL A

(An+1)←(An)  n=6~0  (A0)←(A7)

23

1

RL A

(An)←(An+1)  n=0~6  (A7)←(A0)

03

1

RLC A

(An+1)←(An)  n=6~0  (A0)←(C)  (C)←(A7)

23

1

RRC A

(An)←(An+1)  n=0~6  (A7)←(C)  (C)←(A07)

23

1

4条移位指令的功能操作示意图为:

4. 控制转移指令:

控制转移指令通过修改PC的内容来控制程序执行的流向,包括无条件转移指令、条件转移指令、比较转移指令、循环转移指令、子程序调用和返回指令、空操作指令等。

1)无条件转移指令:

表中列出了无条件转移指令、功能、机器码和执行机器周期。

指令

功能操作

机器代码(16进制)

机器周期

LJMP Addr16 长转移

(PC)←Addr15~0 

02 Addr15~8 Addr7~0

2

AJMP Addr11 绝对转移

(PC)←(PC)+2  

(PC10~0)←Addr10~0 

a10a9a800001Addr7~0

2

SJMP rel 相对短转移

(PC)←(PC)+2  (PC)←(PC)+rel 

80 相对地址

2

JMP @A+DPTR间接长转移

(PC)←(A)+(DPTR)

73

2

长转移指令:为三字节指令,其转移目标地址在ROM的64kB范围内。

绝对转移指令:二字节指令,第一字节的低5位是00001,是指令操作码,其高3位是低11位地址的前3位,第二字节是低11位地址的后8位。执行该指令时,先执行(PC)←(PC)+2,得到的是下一条指令地址。因为11位地址可寻址2kB范围,所以此指令是在下一条指令地址的2kB范围内寻址,不能超出。

相对短转移指令:rel是用补码表示的单字节带符号偏移字节数,取值范围为-128~+127。执行该指令时,先执行(PC)←(PC)+2,得到的是下一条指令地址。然后按照rel的值转移到-128~+127范围内的位置。(SJMP $实现“原地转圈”的运行状态,是动态停机)

间接长转移指令:转移地址由DPTR中的内容和A中的内容相加得到。

2)条件转移指令:

条件转移指令包含累加器A判零转移指令、比较条件转移指令和循环转移指令(减1条件)指令等。

a. 累加器A判零转移指令:

表中列出了累加器A判零转移指令、功能、机器码和执行机器周期。

指令

功能操作

机器代码(16进制)

机器周期

JZ rel

若(A)=0

(PC)←(PC)+2+相对地址 

60 相对地址

2

若(A)≠0

(PC)←(PC)+2

JNZ rel

若(A)≠0

(PC)←(PC)+2+相对地址 

70 相对地址

2

若(A)=0

(PC)←(PC)+2

rel的含义和转移地址范围均与相对短转移指令SJMP rel中的相同。

b. 比较条件转移指令:

表中列出了比较条件转移指令、功能、机器码和执行机器周期。

指令

功能操作

机器代码(16进制)

机器周期

CJNE A,#data, rel

若(A)≠data

(PC)←(PC)+3+相对地址 

B4 data 相对地址

2

若(A)=data

(PC)←(PC)+3

CJNE A,direct, rel

若(A)≠(direct)

(PC)←(PC)+3+相对地址 

B5 data 相对地址

2

若(A)=(direct)

(PC)←(PC)+3

CJNE Rn,#data, rel

若(Rn)≠data

(PC)←(PC)+3+相对地址 

B8~BF data 相对地址

2

若(Rn)=data

(PC)←(PC)+3

CJNE @Ri,#data, rel

若((Ri))≠data

(PC)←(PC)+3+相对地址 

B6~B7 data 相对地址

2

若((Ri))=data

(PC)←(PC)+3

比较条件转移指令均为3字节,都有3个操作数,影响C标志。若操作数1中的内容≧操作数2或其中的内容,则C=0,否则C=1。显然,可用此指令实现对两数大于、小于和等于的判断。rel的含义和转移地址范围均与相对短转移指令SJMP rel中的相同。

c. 循环转移指令:

表中列出了循环转移指令、功能、机器码和执行机器周期。

指令

功能操作

机器代码(16进制)

机器周期

 

DJNZ  R, rel

(Rn)←(Rn)-1, n=0~7

D8~DF  相对地址

2

若(Rn)≠0,  (PC)←(PC)+2+相对地址 

若(Rn)=0   (PC)←(PC)+2

 

DJNZ  direct, rel

(direct)←(direct)-1

D5 direct 相对地址

2

若(direct)≠0,  (PC)←(PC)+3+相对地址 

若(direct)=0   (PC)←(PC)+3

rel的含义和转移地址范围均与相对短转移指令SJMP rel中的相同。

3)子程序调用和返回指令:

表中列出了子程序调用和返回指令、功能、机器码和执行机器周期。

指令

功能操作

机器代码(16进制)

机器周期

 

ACALL Addr11

绝对调用

(PC)←(PC)+2

 

a10a9a810001

Addr7~0

 

2

(SP)←(SP)+1,    ((SP))←(PC7~0)

(SP)←(SP)+1,    ((SP))←(PC15~8)

(PC10~0)←Addr11 [2kB寻址范围]

 

LCALL Addr16

长调用

(PC)←(PC)+3

 

00010010

Addr15~8 Addr7~0

 

2

(SP)←(SP)+1,    ((SP))←(PC7~0)

(SP)←(SP)+1,    ((SP))←(PC15~8)

(PC15~0)←Addr16 [64kB寻址范围]

RET 子程序返回

(PC15~8)←((SP)),   (SP)←(SP)-1

(PC7~0)←((SP)),   (SP)←(SP)-1

22

2

RETI 中断返回

32

2

绝对调用子程序和返回指令:为2字节指令,与绝对转移指令AJMP Addr11类同,但有堆栈和返回操作。指令调用的子程序入口地址在该指令的下一条指令地址所在页内的2kB地址范围内;子程序最后一条指令是子程序返回指令RET,其作用是返回到原先调用子程序指令的下一条指令的首地址处。

长调用子程序和返回指令:为3字节指令,指令调用的子程序入口地址可以是ROM中的任一地址(64kB范围),子程序最后一条指令是子程序返回指令RET,其作用是返回到原先调用子程序指令的下一条指令的首地址处。

中断返回指令:该返回指令在中断中使用,是中断服务子程序的最后一条指令。

4)空操作指令:

NOP ;(PC)←(PC)+1 机器代码:00

这是一条单字节单机器周期控制指令,执行这条指令仅使(PC)加1,耗时1个机器周期,常用来延时。

5. 位操作指令:

位操作指令有位传送指令、位置位和位清零操作指令、位运算指令以及位控制转移指令。位操作指令的操作数不是字节,而只是字节中的某一位,每位取值只能是0或1。表中列出了位操作指令、功能、机器码和执行机器周期。

位指令类型

指令

机器代码

机器周期

功能

位传送

MOV C,bit

A2 bit

1

(Cy)←(bit)

MOV bit,C

92 bit

1

(bit)←(Cy)

 

位置位和

位清零

CLR C

C3

1

Cy←0

CLR bit

C2

1

bit←0

SETB C

D3

1

(Cy)←1

SETB bit

D2

1

(bit)←1

 

 

位运算

ANL C,bit

82 bit

2

(Cy)←(Cy)∧(bit)

ANL C,bit-

B0 bit

2

(Cy)←(Cy)∧(!bit)

ORL C,bit

72 bit

2

(Cy)←(Cy)∨(bit)

ORL C,bit-

A0 bit

2

(Cy)←(Cy)∨(!bit)

CPL C

B3

1

(Cy)←(!Cy)

CPL bit

B2

1

(bit)←(!bit)

 

位控制转移

JC rel

 

40 相对地址

2

若(Cy)=1,(PC)←(PC)+2+相对地址

若(Cy)=0,(PC)←(PC)+2

JNC rel

50 相对地址

2

若(Cy)=0,(PC)←(PC)+2+相对地址

若(Cy)=1,(PC)←(PC)+2

 

 

位地址内容为条件转移

JB bit,rel

 

20 bit相对地址

2

若(bit)=1,(PC)←(PC)+3+相对地址

若(bit)=0,(PC)←(PC)+3

JNB bit,rel

 

30 bit相对地址

2

若(bit)=0,(PC)←(PC)+3+相对地址

若(bit)=1,(PC)←(PC)+3

JBC bit,rel

 

10 bit相对地址

2

若(bit)=1,(PC)←(PC)+3+相对地址 且(bit)←0

若(bit)=1,(PC)←(PC)+3

 

Copyright@dwenzhao.cn All Rights Reserved   备案号:粤ICP备15026949号
联系邮箱:dwenzhao@163.com  QQ:1608288659