汇编语言 8086/8088指令系统

汇编语言 8086/8088指令系统

1.指令基本组成

1.1 指令的一般格式

一条指令一般由两部分组成。第一部分是操作码(指令码),一般用英文缩写表示,用来指出指令要做什么操作,所以是指令中必须给出的内容。第二部分便是操作数,它可以根据不同的情况显式给出或者隐式存在。第二部分中,前一个为目标操作数,后者为源操作数。

在微处理器指令系统中,一条指令的操作数可以没有或有一个,但最多只能有两个,所以在格式上便有一下三种形式:

  1. 零操作数指令。形式上只有操作码,操作数是隐含存在的。这类指令的操作对象通常为处理器本身。
  2. 单操作数指令。指令只给出一个操作数,另一个隐含存在。
  3. 双操作数指令。比较常见的。

1.2 指令中的操作数类型

  1. 立即数操作数
    立即数是有固定数值的操作数,就是我们说的常数,他不会因为指令的变化而变化。在指令中,立即数只能做源操作数

  2. 寄存器操作数
    8086CPU中的8个通用寄存器和4个段寄存器可以作为指令中的寄存器操作数。通用寄存器通常用来存放参加运算的数据或者数据所在存储器单元的偏移地址段寄存器用来存放当前操作数的段基地址

  3. 存储器操作数
    存储器操作数我理解为直接将偏移地址作为操作数。之后讲到的寻址方式大多是存储器操作数的。

2.寻址方式

2.1立即寻址

源操作数直接写在指令里面,成为指令的一部分,这种操作数称为立即数,类似于常数,同时这种寻址方式叫做立即寻址。

立即数可以是8位、16位、32位,如果立即数是16位或者32位则按照高位存在高地址单元,低位存在低地址单元。

举例:
MOV B1, 12H   MOV W1, 3456H   ADD D1, 32123456H

以上均是立即寻址,同时也展现了8位立即数、16位立即数和32位立即数。其中B1是字节,W1是字,D1是双字单元。

同时,在汇编语言中规定:目的操作数不能为立即数。(许多指令需要将结果存入目的操作数中)

立即寻址一般用于对通用寄存器或内存单元的赋值。

2.2 直接寻址

首先,直接寻址是存储器作为源操作数,其中存放的地址直接由指令给出,用 [ ] 框起来。允许段重设。
举例:
MOV AX , [3102H]
表示将偏移地址为3102H和3103H两单元的内容送入到AX(AH和AL)中,段基地址默认在DS中。
MOV BL , ES:[1200H]
该句使用了段重设,将ES中偏移地址为1200H单元的内容送到BL中。

2.3 寄存器寻址

寄存器寻址比较常见,他的操作数可以是数据寄存器、地址指针、变址寄存器或段寄存器。

MOV SI , AX

该语句表示将AX中的内容送到SI 中,同时AX不变。

2.4 寄存器间接寻址

寄存器间接寻址是使用寄存器的内容表示操作数的偏移地址
和直接寻址比较相似,但是该寻址方式的操作数只能是SI、DI、BX、BP,即间址寄存器(地址指针)。
一般默认情况,选择SI、DI、BX时,操作数在数据段,段基地址由DS决定,而选择BP,操作数在堆栈段,段基地址则在SS中,四个选择均允许段重设。

MOV AX , [SI] 或 MOV AX , ES : [SI]

2.5 寄存器相对寻址

在寄存器相对寻址中,操作数由间址寄存器的内容加上指令中给出的一个8位或16位的位移量组成。操作数所在端由所使用的间址寄存器决定。

举例:
MOV AX , DATA [ BX ]
设 DS = 6000H , BX = 1000H , DATA = 0008H
物理地址 = 60000H + 1000H + 0008H = 61008H

以下写法完全等价:
MOV AL , DATA [ SI ]
MOV AL , [ SI ] DATA
MOV AL , DATA+ [ SI ]
MOV AL , [ SI ]+ DATA
MOV AL , [ DATA + SI ]
MOV AL , [ SI + DATA ]

2.6 基址-变址寻址

将一个基址寄存器(BX或BP)和一个变址寄存器(SI或DI)的内容相加而形成的操作数的的偏移地址,叫做基址-变址寻址。默认情况下,BX 对应 DS,BP 对应 SS,允许段重设

MOV AX , [ BX ][ SI ]
设DS = 8000H , BX = 2000H , SI = 1000H
物理地址 = 80000H + 2000H + 1000H = 83000H

指令执行后,AL = [ 83000H ] , AH = [ 83001H ]

不允许同时出现两个基址寄存器或者两个变址寄存器,如MOV AX,[BX][BP] 或者 MOV AX,[SI][DI]

2.7 基址-变址-相对寻址

基址-变址-相对寻址其实就是基址-变址寻址的扩充,他是在其基础上,同时还给出一个8位或者16位的位移量,将三者相加就得到操作数的偏移地址

MOV AX , 5[ DI ][ BX ]

偏移地址为 DI + BX + 5

2.8 隐含寻址

该寻址方式的操作数或者操作码将会被隐藏,比如 MUL 指令

MUL BL

该指令表示把 AL 和 BL 相乘,结果放到AX中。

3. 8086指令系统

3.1 数据传送指令

数据传送指令主要分为四类:通用数据传送指令、目标地址传送指令、标志传送指令、输入输出指令

3.1.1 通用数据传送指令

通用数据传送指令主要包括MOV(一般传送指令)、PUSH,POP(堆栈操作指令)、XCHG(交换指令)、XLAT(查表转换指令)和字位扩展指令。

1)一般传送指令 MOV

MOV dest , src

(1)指令特点

  1. 指令中的操作数可以是8位的,也可以是16位的。
  2. 可以任意使用上面说的寻址方式。

(2)指令实现的操作

  1. 寄存器与寄存器,或者寄存器与段寄存器之间的传送
    MOV BX , SI ;变址寄存器 -> 基址寄存器
    MOV DS , AX ;累加器 -> 段寄存器
    MOV AL , CL ;通用寄存器 -> AL

  2. 寄存器与存储器之间的传送
    MOV [ BX ] , AX
    MOV CL , [ BP ][DI ]
    MOV AX , [ 6000H ]

  3. 立即数到寄存器的传送
    MOV AL , 5

  4. 立即数到存储器的传送
    MOV BYTE PTR [ BP + SI ] , 5 ;将5送到堆栈段中偏移地址为BP + SI 的单元中
    MOV WORD PTR [ BX ] , 1005H ;将1005H送到数据段中偏移地址为BX和BX+1的单元中

  5. 存储器和段寄存器之间的传送
    MOV DS , [ 1000H ]
    MOV [ BX ] , ES

(3)指令对操作数的要求

  1. 两个操作数字长必须相等
  2. 两个操作数不等同时为存储器操作数
  3. 不能用立即数直接给段寄存器赋值
  4. 两个操作数不能同时为段寄存器
  5. 一般情况下,IP和CS不直接通过MOV修改
  6. 通常情况下,FLAGS不能做为操作数

2)堆栈操作指令 PUSH和POP

(1)堆栈的段地址存在SS中,可以将堆栈看成一个小存储器,但是不能任意存取,要遵循一下原则:

  1. 堆栈的存取每次必须是一个字(16位),即堆栈操作指令的操作数必须是16位,而且只能是寄存器或者存储器操作数,不能是立即数。
  2. 向堆栈中存放数据时,总是从高地址向低地址方向增长,取数据相反。
  3. 堆栈段在内存中的位置由SS决定,堆栈指针SP总是指向栈顶,每次压入数据时,SP先-2,每弹出一个字,SP+2
  4. 对堆栈的操作遵循“后进先出”。

堆栈示意图

(2)堆栈操作指令。PUSH(压栈)、POP(出栈)

两条指令中的操作数必须为16位的字操作数,他们可以是:

  • 16位的通用寄存器或段寄存器(CS除外,POP CS是非法的)
  • 存储器单元(地址连续的连个存储单元)

例:
PUSH AX
PUSH WORD PTR [ DATA + SI ]
POP DS
POP WORD PTR [ BX ]

(3)堆栈指令的执行过程

  1. PUSH执行过程:

SP-2 -> SP
src高8位 -> [ SP + 1 ]
src地8位 -> [ SP ]

  1. POP指令相反

src地8位 -> [ SP ]
src高8位 -> [ SP + 1 ]
SP+2 -> SP

执行示意图

必要时也可以通过修改SP的值来恢复堆栈原有状态。
有时可以利用堆栈“后进先出”的特点来实现两操作数内容互换

3)交换指令 XCHG

XCHG OPRD1 , OPRD2
;OPRD1 <-> OPRD2

该指令能实现源地址与目标地址中的内容互换,但有如下要求:

  • 源操作数和目标操作数可以为寄存器或存储器,但不能同时为存储器
  • 段寄存器不能参与互换
  • 两个操作数字长必须相等,可以是字互换,也可以是字节互换

4)查表转换指令 XLAT

XLAT是一条查表指令,可以根据表中元素的序号查出表中相应元素的内容。该指令要求将表的首地址(偏移地址)送寄存器BX,要查找的元素序号送AL(表第一个元素序号为0),执行完之后,指定元素内容将被存入AL

举例:
LEA BX , TABLE
MOV AL , 5
XLAT

由于查找元素的序号放在AL中,所以表格最大长度不能超过256个字节。

3.1.2 输入/输出指令

输入指令IN用于从I/O端口读数据到AL(或AX)中,而输出指令OUT用于把累加器AL(或AX)的内容写到I/O端口,由于只有AL(或AX)才能与I/O端口进行数据传送,所以这两条指令也叫累加器专用传送指令。

在8088I/O指令中可以用两种形式来表示端口地址,或称为两种寻址方式:

  1. 直接寻址:指令中I/O端口地址为8位,此时允许寻址256个端口,端口地址为0-FFH
  2. 寄存器间接寻址:端口地址为16位,由DX寄存器指定
3.1.3 取偏移地址指令

LEA reg16 , mem

LEA指令负责将源操作数的偏移地址送到目标操作数中,源操作数必须是存储器操作数目标操作数必须是16位通用寄存器 。在这里最好选4个间址寄存器。

设BX = 1000H , DS = 6000H , [ 61050H ] = 33H , [ 61051 ] = 44H。
LEA BX , [ BX + 50H ]
MOV BX , [ BX + 50H ]
第一条指令执行后,BX = 1050H,第二条指令执行后,BX = 4433H

LEA应用举例

3.1.4 其他传送指令

其他传送指令

3.2 算术运算指令

3.2.1 加法运算指令

加运算指令有3条:ADD(普通加法指令)、ADC(带进位的加法指令)和INC(加1指令)。其中基本规则与MOV类似,但是段寄存器不能作为加法指令的操作数

1)普通加法指令 ADD

ADD OPRD1 , OPRD2
; ORD1 <- OPRD1 + OPRD2

在这里,两个操作数均可以是8位或16位的寄存器或存储器源操作数可以是立即数但是不能两个操作数都是存储器或者有段寄存器的存在

ADD指令对6个状态标志位都会有影响。

2)带进位位的加法指令 ADC

ADC OPRD1 , OPRD2
; OPRD1 <- OPRD1 + OPRD2 + CF

ADC与ADD在各个方面基本相同,只是CF也要参与运算。

ADC主要用于超过16位的数字加法,可以将超过16位的数字分成若干个16位数字分别相加,地位可以用ADD,但是高位相加要考虑地位的进位,所以使用ADC。

举例:
求0107A379H HE 10067E4FH的和
MOV AX , 0A379H
ADD AX , 7E4FH
MOV BX , 0107H
ADC BX , 1006H
最后相加结果为:110E21C8H

3)加1指令 INC

INC OPRD
; OPRD <- OPRD + 1

INC主要用于将操作数加1,类似于i++,OPRD不能是立即数和段寄存器。另外,INC不影响CF,对其他5个状态标志均有影响。

3.2.2 减法指令

8086/8088系统中共有条减法指令:SUB(普通减法指令)、SBB(考虑借位的减法指令)、DEC(减1指令)、NEG(求补指令)和CMP(比较指令)。

1)不考虑借位的普通减法指令 SUB

SUB OPRD1 , OPRD2
; OPRD1 <- OPRD1 - OPRD2

该指令对操作数的要求以及对状态标志位的影响与ADD完全相同。

2)考虑借位的减法指令 SBB

SBB OPRD1 , OPRD2
; OPRD1 <- OPRD1 - OPRD2 - CF

该指令对操作数的要求以及对状态标志位的影响与ADC完全相同。

3)减1指令 DEC

该指令对操作数的要求以及对状态标志位的影响与INC完全相同。

4)求补指令 NEG

NEG是用0减去操作数,结果返回操作数所在的地址。

NEG OPRD
; OPRD <- 0 - OPRD

OPRD可以是寄存器或者存储器操作数。该指令可以对负数求绝对值或者说对负数求其补码,并且对6个标志位均有影响。使用需注意之下几点:

  • 执行NEG指令后CF都会变为1.
  • 当给定操作数为8000H或者80H时,执行NEG结果不变,但OF置为1,其他情况下OF为0

5)比较指令 CMP

CMP对于操作数要求和标志位的变化和SUB完全相同,只是结果不送入目标操作数。以下是该指令比较规则:
(1)相等关系。如果ZF=1,则相等
(2)大小关系。
1. 无符号数。CF=0,无借位,OPRD1 > OPRD2
2. 有符号数。
符号相同:没有溢出,OF=0,SF=0(符号位为0,正数),则OPRD1 > OPRD2
符号不同:
1. OF=0(无溢出),SF=0,则OPRD1 > OPRD2
2. OF=1(有溢出),SF=1,则OPRD1 > OPRD2

3.2.3 减法指令

减法指令会隐含目标操作数(AX或DX),源操作数由指令给出。对于8位数乘法,结果为16位,放在AX中;对于16位乘法,结果高16位放在DX,低16位放在AX中。
对于有符号和无符号的乘法,有如下3个区别:

  1. 操作数的性质不同,前者是无符号数,后者要求两乘数都为符号数
  2. 对于无符号数,如果高位不等于0(字节相乘时高位为AH,字相乘时为DX),CF=OF=1,否则CF=OF=0。对于有符号数,若高半部分是地板部分的符号位扩展,则CF=OF=0.
  3. 无符号数乘法指令源操作数应满足无符号数表示范围,有符号则满足有符号数表示范围
  4. 无符号乘法指令MUL,有符号数乘法指令IMUL

MUL BX
; AX <- AX * BX
MUL BYTE PTR [ SI ]
; AX <- AL * [ SI ]
MUL DL
; AX <- AL * DL

某些情况下,可以用左移指令代替乘法指令,速度会快很多

3.2.4 除法指令

除法指令要求被除数字长是除数的两倍。若除数是8位,则被除数为16位,放在AX中;若除数是16位,则被除数是32位,高16位放在DX,低16位放在AX。

DIV OPRD
字节除法:AL <- AX/OPRD , AH <- AX%OPRD
字除法:AX <- DX : AX/OPRD , DX <- DX : AX%OPRD

如果结果查过了寄存器可保存的值,则会产生一个类型0的中断。除法指令对标志位均没影响。

3.2.5 其他算术指令

其他算术指令

3.3 逻辑算数和移位指令

3.3.1 逻辑算术指令

逻辑运算指令共有5条:AND(与)、OR(或)、NOT(非)、XOR(异或)和TEXT(测试)。NOT对操作数要求与INC一样,对标志位没有影响,其余指令对操作数要求与MOV一样,并且执行会使CF=OF=0,AF不定,对SF、PF、ZF有影响。

1)逻辑“与”指令 AND

AND指令在程序中主要应用在三个方面:

(1)实现两个操作数按位相与:
AND AX , [ BX ]
; AX和 [ BX ]中所指字单元按位相与,结果送AX

(2)使操作数中某些位不变,其他位清零:
AND AL , 0FH
; 将AL高4位清零,低4位不变,0F二进制是00001111
目标数哪些位要清零,就把源操作数相应位设为0,其他位为1

(3)使操作数不变,但影响其他6个标志位,并使CF=OF=0:
AND AX , AX
; AX和自身相与,不改变AX内容

2)逻辑“或”指令 OR

OR也用于以下3个方面:

(1)实现操作数按位相或

(2)使操作数中某些位不变,其他位 置1:
AND AL , 20H
; 将ALD5置1,其他位不变,20H二进制是000100000
目标数哪些位要置1,就把源操作数相应位设为1,其他位为0

(3)使操作数不变,但影响其他6个标志位,并使CF=OF=0:
OR AX , AX
; AX和自身相与,不改变AX内容

3)逻辑“非”指令 NOT

NOT指令用于将操作数取反,再返回该操作数。OPRD可以是8位或者16位寄存器或者存储器,不能是立即数,NOT指令对标志位没有影响。

NOT WORD PTR [ SI ]
; 将[ SI ]中所指连个单元的内容取反,再送回两单元

4)逻辑“异或”指令 XOR

异或:两数相同为0,相异为1

异或自身结果为0,可以利用这一点使寄存器清零。

XOR AX , AX
; 是AX清零

5)测试指令 TEXT

TEXT指令与AND类似,唯一的区别是不将结果返回目标数,因此可利用AND的特性来判断操作数某些位是0还是1。

TEXT AL , 02H
; 02H二进制是0010,因此其他位清零的情况下,如果操作数D1位为0,那结果将为0,从ZF可以判断出,若D1=0,则ZF=1,否则ZF=0

3.3.2 移位指令

移位指令包括非循环移位指令和循环移位指令。当移动一位时,由指令给出;如果移动2位或多位时,移动的位数要放在CL中。

1)非循环移位指令

非循环移位指令有四条:SAL(算数左移)、SAR(算数右移)、SHL(逻辑左移)和SHR(逻辑右移)
四条指令格式相同,均可对8位或16位寄存器和存储器进行操作。算数移位针对有符号数,逻辑移位针对无符号数

(1)算数左移和逻辑左移指令 SAL/SHL

SAL和SHL运算方法一样,都是将最左边的最高位放入CF中,最右边的最低位补0如果移动一次后最高位和CF不一样,则OF=1,否则OF=0。两者区别在于:若OF=1,对于SHL不表示溢出,对SAL则表示移位后超出符号数表示范围

例题:
把以DATA为首地址的两个连续单元中的16位无符号数乘以10。、
因为10x = 8x + 2x = 2*2*2x + 2x,实现如下:
LEA SI , DATA
MOV AX , [ SI ]
SHL AX , 1
MOV BX , AX
MOV CL , 2
SHL AX , CL
ADD AX , BX
HLT

(2)逻辑右移 SHR

逻辑右移SHR与逻辑左移相似,每右移1位,右边最低位送入CF中,同时最高位补0,。如果移动一次后,最高位与次高位不一样,则OF=1,否则OF=0。若移位次数不为1,则OF不定。

逻辑右移一位相当于除2。

(3)算数右移 SAR

SAR 右移一位,将最低位送入CF,最高位不变

MOV AL , 82H
SAR AL , 1

AL=C1H , CF=0

SAR对ZF、SF、PF、CF有影响,对OF、AF无影响。而且SAR右移一位相当于有符号数除以2。

2)循环移位指令

循环移位指令共有四条:ROL(不带CF的循环左移)、ROR(不带CF的循环右移)、RCL(带CF的循环左移)和RCR(带CF的循环右移)

循环移位示意图

(1)不带CF的循环左移 ROL

ROL将操作数左移1或CL位,最高位送入CF,同时再补到最低位,形成循环,CF不加入循环。
ROL影响CF和OF,如果最高位和CF不等,则OF=1,否则OF=0,若移位次数不为1,则OF不定。

(2)不带CF的循环右移 ROR

基本和ROL一样,标识符状态也一样。

(3)带CF的循环左移 RCL

(4)带CF的循环右移 RCR

总结:循环移位后,各位数信息并没有变化,如果需要还可以反向移动变回去。利用循环移位可以测试操作数某一位状态。

举例:
测试BL寄存器第4位状态
MOV CL , 4
ROL BL , CL
JNC ZERO
ROR BL , CL

ZERO : ROR BL , CL

用TEXT命令也可完成该操作
TEXT BL , 1H
JNZ ZERO

ZERO : …

3.4 串操作指令

3.4.1 串操作指令的共同特点
  1. 源操作数指针为DS : SI,允许段重设。

  2. 目标操作数指针为ES : DI,不允许段重设

  3. 串长度放在CX中。

  4. 串操作会自动修改地址指针,修改方向与DF有关。若DF=0,SI和DI按地址增量方向修改,DF=1则相反。

  5. 可以在串操作指令前使用重复前缀。若是使用了重复前缀,每一次串操作之后CX会自动减1。

所以,使用串操作指令时,要预先设定:源串指针(DS、SI),目标串指针(ES、DI),重复次数(CX),操作方向(DF)

3.4.2 重复操作前缀
  1. REP:无条件重复,重复指定操作直到CX=0

  2. REPE:相等/结果为0,ZF=1,CX不等于0时重复

  3. REPNE:不相等/结果不为0,ZF=0,CX不等于0时重复

3.4.3 串操作指令

(1)串传送指令 MOVS

MOVSB负责字节传送,MOVSW负责字传送,这两个指令源串默认DS:SI,目标串默认ES:DI,源串可以段重设。

MOVS OPRD1 , OPRD2

该指令用于段重设情况。MOVS指令常和REP一起用,同时不改变标志位。

例:
将2000H:1200H地址开始的100个字节传送到6000H:0000H开始的内存单元中去。
MOV AX , 2000H
MOV DS , AX
MOV AX , 6000H
MOV ES , AX
MOV SI , 1200H
MOV DI , 0H
MOV CX , 100
CLD
REP MOVSB
HLT

(2)串比较指令 CMPS

CMPS与MOVS用法基本一样,但是CMPS一般与REPE和REPNE一起使用,结果ZF=1时,两字符串有重复。

例:
比较两字符串,找出第一个不同的字符地址,地址送BX,字符送AL。两字符串长度均为200字节,M1为源串首地址,M2为目标串首地址。

LEA M1 , DI
LEA M2 , SI
MOV CL , 200
CLD
REPE CMPSB
JZ STOP
DEC SI
MOV BX , SI
MOV AL , [ SI ]
STOP : HLT

(3)串扫描指令 SCAS

SCAS通常用来查找字符串中特定的字符,关键字放AL(AX),字符串放ES:DI

例:
在ES段中从2000H单元开始存放了10个字符,寻找其中是否有误字符“A”。若有则记下搜索次数(放DATA1),并记下A的地址(放DATA2)。

MOV DI ,2000H
MOV BX , DI
MOV CL , 10
MOV AL , ‘A’
CLD
REPE SCASB
JZ FOUND
MOV DATA1 , 0
FOUND : DEC , DI
MOV DATA2 , DI
INC DI
SUB DI , BX
MOV DATA1 , DI

(4)串装入指令 LODS

目测不考

(5)串存储指令 STOS

将AL(AX)中的值存入目标串(ES:DI)中,不改变标志位

例:
把6000H:1200H单元开始的100个字存储单元内容清零
MOV AX , 6000H
MOV ES , AX
MOV DI , 1200H
MOV CX , 100
MOV AX , 0
CLD
REP STOSW
HLT

3.5 程序控制指令

3.5.1 无条件转移指令 JMP

JMP指无条件使程序转移到指定的目标地址,并从该地址执行新的程序段。寻找目标地址有直接的方式和间接的方式。又由于8086/8088内存是分段的,所以又分为段内和段间。

1)段内直接转移

段内直接转移比较直接,指令后面有直接给出标志号。

MOV AX , BX
JMP NEXT
AND CL , 0FH

NEXT : OR CL , 7FH

2)段内间接转移

JMP OPRD

OPRD必须是16位寄存器或存储器地址,指令将OPRD的内容作为转移目标的偏移地址取代IP,如果OPRD是存储器,则要加上WORD PTR,由于是段内转移,CS不变。

JMP BX
JMP WORD PTR [ BX + DI ]

3)段内直接转移

JMP FAR NEXT
JMP 8000H : 1200H

前者指跳转的NEXT是其他代码段的,后者直接给出偏移地址,CS=8000H,IP=1200H。

4)段间间接转移

该方式将连续四个内存单元的内容送入CS、IP,高位送CS,低位送IP。

例题:
例题

(1)

(2)IP = [ 212AH * 16 + 0500H ] = [ 217A0 ] = 2300H
物理地址 = CS * 16 + IP = 0200H * 16 + 2300H = 4300H

(3)[ BX + DATA ] = 212AH * 16 + 0500H + 40H = 217E0H
JMP DWORD PTR[ 217E0H ] = JMP 9000H : 0400H
CS = 9000H , IP = 0400H
物理地址 = 9000H * 16 + 0400H = 90400H

JMP不影响标志位。

3.5.2 条件转移指令 JCC

条件转移指令

  • 13
    点赞
  • 77
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值