《x86_x64体系结构探索》读书笔记 —— 第四章

《x86_x64体系结构探索》读书笔记 —— 第四章

识别处理器–CPUID

测试是否支持CPUID

eflags bit21:能修改成功,则支持CPUID
CPUID表达
在这里插入图片描述

a. 查询
从cpuid获得信息必须先提供相应的leaf(功能号main leaf),功能号
main leaf:查询DPUID的01号功能,即CPUID的01 leaf;main leaf输入到EAX中
sub leaf: 对于一些复杂的功能,需要复制的子叶,sub leaf输入到ECX中
mov eax, 0Bh //功能号0B
mov ecx, 0 //子叶0
cpuid //查询COUID的0B号功能,子叶为0
b. 返回
cpuid的返回,当使用cpuid进行cpu功能查询时,查询到的信息存放在eax、ebx、ecx、edx中

test1:测试是否支持CPUID

在这里插入图片描述

基本信息与扩展信息

不同的处理器,CPUID支持的leaf数量是不同的,在使用某个leaf查询之前,必查询段处理器是否支持该leaf
a. 基本最大功能号
使用CPUID的00H leaf来查询,最大的基本功能号放回在EAX中;
使用CPUID的80000000H leaf来查询,最大的扩展功能号放回在EAX中;
功能号0,也返回处理器厂商名,Intel机器上
ebx–Genu,ecx–ntel,edx–iniI,

test 2:获取最大的功能号

在这里插入图片描述

注:如果早eax中输入的功能号查过了最大的功能号,那么将返回基本最大功能号

test 3:当eax提供的值超过了最大功能号之后返回的结果是什么?

在这里插入图片描述

总结:
当eax的值大于或等于最大功能号时,返回的是最大功能号的信息
当eax的值小于或等于最大功能号时,若处理器支持该功能号,则返回该功能号的信息

处理器型号 (01H leaf)

CPUID.01H:EAX可以返回处理器的family、model、stepping
EAX[7:4] model
EAX[11:8] family
EAX[19:16] 扩展model
EAX[27:20] 扩展family Pentium4之后支持扩展family
Displayfamily计算方法
if (family == 0FH) { //Pentium4
Displayfamily = ExtendedFamily + Family;
}else{
Displayfamily = Family;
}
Displaymodel计算方法
if (family == 06H || family == 0FH) { //Pentium4 and P6
Displaymodel = Displaymodel << 4 + model;
}else{
Displaymodel = model;
}

test 4调用lib16.asm中的get_Displayfamily()和get_Displaymodel()来获取到Displayfamily和Displaymodel

在这里插入图片描述

最大的物理地址和线性地址 (80000008H leaf)

CPUID.80000008H leaf中,可以获得处理器支持的最大物理地址和线性地址
实验2中80000008中返回的是eax是0x00003028
低byte是物理地址宽度,28h就是40位
高byte是线性地址,CPU支持long mode就是30h,否则就是20h,表示long mode下最高支持48位的线性地址,线性地址的高16位被用作sign位,在32位机器上这个值就是20h(32位)。
最大物理地址 MAXPHYADDR
80000008K leaf返回的EAX[7:0]就是MAXPHYADDR
处理器不支持80000008H时
CPUID.01H:EDX[6] = 1(PAE=1),支持最高36位物理地址
PAE = 0(不支持PAE),MAXPHYADDR是32位

处理器扩展状态信息 (0DH leaf)

0DH leaf是活的处理器对processor extended state(处理器扩展状态)的支持,对于AVX指令的编程是非常重要的
mov eax, 0Dh //0DH main leaf
mov ecx, 0 //sub leaf 0
cpuid //获得0DH的main leaf功能
0DH main leaf的功能,会在eax和edx寄存器中返回processor extended state的enable/disable位图
返回的edx和eax组成了一个64位的processor extended state功能表,高32位在edx,低32位在eax,每一位对应一个扩展状态功能的enable位
processor extended state会影响到XCR0(extended control register)的值
当state值的某位为0时,XCR0的相应位为保留位(此为不能被XSAVE指令设置)
目前的X86处理器只用到了低3位(bit0~2):
bit0 对应X87 FPU状态
bit1 对应SSE状态,
bit2 对应YMM状态(AVX指令)
a. processor extended state子叶
b. processor extended state子叶所需内存size
0DH leaf,ebx和ecx会返回一个内存size
ebx返回的是在XCR0里设置了开启某个位去迟迟处理器状态所需要的内存size
//此处有图
XCR0和CPUID(EAX=0D和,ECX=0h)返回的64位processor extended state的结构是一样的。
XCR0可以设置SSE状态问enabe/disable
XCR0和processor extended state的关系
XCR0是一个功能开关,用来开启或关闭某些state的保存
processor extended state决定处理器保存那些state信息的能力
OS通过XSETBV指令对XCR0进行相应的设置,如果某些位被disable掉,这时候,XCR0和processor extended state的值会不一致;
因此,ebx寄存器返回的是这个XCR0设置的保存状态所需要的内存size
ecx寄存器返回的是CPU所支持的所有状态(即,在main leaf里返回的eax位图),保存这些转台需要的内存size
因此ebx和ecx不一定相等
例:
如果CPUID(eax=0Dh,ecx=0h)返回的eax继勋奇为07H值,说明支持AVX,这时候可以使用0Dh的2号子叶来查看。
c. processor extended state的保存 XSAVE
processor extended state通过使用XSAVE指令来保存处理器的状态。
对于processor extended state中状态的保存,取决于Xsave指令提供的64位MASK码和XCR0上面相应为的enable,
如果XCR0.YMM=0,表明不保存YMM状态,那么state中YMM的区域不被更新
同样的,在edx:eax这个64位的MASK码中,如果YMM state mask位为0,YMM区域也不会被更新;
必须XCR0和MASK值同时置一,相应的区域才会被更新
上面的例子,由于不支持AVX指令,eax返回0x03,表示支持X87 FPU和SSE状态,
ebx和ecx的返回值是0x240,512+64=576(0x240),X87 FPU需要512字节,还要加上一个header部分,
这个header的首64bit(8byte)是一个XSTATE_BV结构,当XSAVE保存状态时,用来记录部分状态被保存了,若保存了SSE状态,就set bit1,否则就clear bit1,否则就clear bit1.
d. processor extended state的恢复 XSTORE
//此处有图
使用XSTORE指令可以从内存的state映像中恢复原来保存的state信息
header结构64字节,首8字节是一个64位的MASK值,用来记录state映像中那些区域被更新过,相应的位为1,表示相应的位被更新过
XSTATE_BV的位在执行XSAVE指令保存state时被CPU设置。执行XSTORE指令时,CPU会根据 XSTATE_BV被置起来的位,做相应的恢复。

处理器的特性

EAX=01H
CPUID返回,eax存放处理器的family、model、stepping,ebx[15:8]返回CLFLUSH line size,这个值乘以8就是cache line的size,
ebx[23:16]返回逻辑处理器最大可寻址的数目

test 5 在这里插入图片描述

处理器的cache与TLB信息

1)CPUID.EAX=02H,获取CPU的cache与TLB信息
返回值
eax:
byte0:表示需要执行几次CPUID.EAX=02H,才能获得完整的信息,byt0是FF,表示不返回cache和TLB的信息,需要通过CPUID.EAX=04H来查询;
MSB标志位,0指示有效,1指示无效
ebx:
2)CPUID.EAX=04H,获取CPU的cache与TLB信息,从ECX中输入子叶,开始查询
ecx=0h 子叶,
返回值:
EAX[4:0]:cache类型,1:data cache;2:instruction cache;3:unidied cache,0表示终止,已经没有子叶可以枚举了。其他值保留
EAX[7:5]:返回cache的level
EAX[31:26]:处理器的core数,需要加上1
EBX[11:00]:cache line size
EBX[21:12]:physical line aprtition
EBX[31:22]:cache的way数
ECX:32位的cache set数

test 6:使用CPUID.EAX=02H查看cache以及TLB的信息

在这里插入图片描述

long mode

extended 功能号80000001H
EDX[29]:long mode标志位
EDX[11]:SYSCALL/SYSRET指令支持标志位
EDX[26]:1G-page支持位

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
目录 第一篇 x86 基础 第1 章数与数据类型2 1.1 数 2 1.1.1 数字 2 1.1.2 二进制数 3 1.1.3 二进制数的排列 3 1.1.4 十六进制数 5 1.1.5 八进制数与十进制数 5 1.2 数据类型 6 1.2.1 integer 数 6 1.2.2 floating-point 数. 9 1.2.3 real number(实数)与NaN(not a number) . 11 1.2.4 unsupported 编码值 14 1.2.5 浮点数精度的转换 15 1.2.6 浮点数的溢出 17 1.2.7 BCD 码 20 1.2.8 SIMD 数据 21 第2 章 x86/x64 编程基础 23 2.1 选择编译器 23 2.2 机器语言 24 2.3 Hello world 25 2.3.1 使用寄存器传递参数 26 2.3.2 调用过程 27 2.3.3 定义变量 27 2.4 16 位编程、32 位编程,以及64 位编程 28 2.4.1 通用寄存器 28 2.4.2 操作数大小 30 2.4.2 64 位模式下的内存地址 30 2.4.4 内存寻址模式 31 2.4.5 内存寻址范围 34 2.4.6 使用的指令限制 34 2.5 编程基础 34 2.5.1 操作数寻址 35 2.5.2 传送数据指令 39 2.5.3 位操作指令 45 2.5.4 算术指令 47 2.5.5 CALL 与RET 指令 48 2.5.6 跳转指令 48 2.6 编辑与编译、运行 48 第 3 章编写本书的实验例子 50 3.1 实验的运行环境 50 3.2 生成空白的映像文件 52 3.2.1 使用nasm 编译器生成 52 3.2.2 使用bximage 工具 52 3.3 设置bochs 配置文件. 53 3.4 源代码的基本结构 54 3.5 编译源代码55 3.6 映像文件内的组织 55 3.7 使用merge 工具 56 3.7.1 merge 的配置文件 57 3.7.2 执行merge 命令 57 3.8 使用U 盘启动真实机器 58 3.8.1 使用merge 工具写U 盘 58 3.8.2 使用hex 编辑软件写U 盘 59 3.9 编写boot 代码 60 3.9.1 LBA 转换为CHS 62 3.9.2 测试是否支持int 13h 扩展功能 63 3.9.3 使用int 13h 扩展读磁盘 64 3.9.4 最后看看load_module() 64 3.10 总结 66 第4 章处理器的身份 67 4.1 测试是否支持CPUID 指令 67 4.2 CPUID 指令的术语及表达 68 4.3 基本信息与扩展信息 68 4.4 处理器的型号(family,model 与stepping) 72 4.5 最大的物理地址和线性地址 73 4.6 处理器扩展状态信息74 4.6.1 探测Processor Extended State 子叶 75 4.6.2 Processor Extended State 子叶所需内存size 76 4.6.3 Processor Extended State 的保存 77 4.6.4 Processor Extended State 的恢复 78 4.7 处理器的特性 78 4.8 处理器的Cache 与TLB 信息 80 4.9 MONITOR/MWAIT 信息 83 4.10 处理器的long mode 84 第 5 章了解 Flags 85 5.1 Eflags 中的状态标志位 86 5.1.1 signed 数的运算 86 5.1.2 unsigned 数的运算 89 5.2 IOPL 标志位 90 5.3 TF 标志与RF 标志 93 5.4 NT 标志 95 5.5 AC 标志 96 5.6 VM 标志 98 5.7 eflags 寄存器的其他事项 99 第 6 章处理器的控制寄存器 101 6.1 CR8 102 6.2 CR3 103 6.3 CR0 104 6.3.1 保护模式位PE 104 6.3.2 x87 FPU 单元的执行环境 104 6.3.3 CR0.PG 控制位 108 6.3.4 CR0.CD 与CR0.NW 控制位 108 6.3.5 CR0.WP 控制位 110 6.3.6 CR0.AM 控制位 110 6.4 CR4 110 6.4.1 CR4.TSD 与CR4.PCE 控制位 110 6.4.2 CR4.DE 与CR4.MCD 控制位 111 6.4.3 CR4.OSFXSR 控制位 111 6.4.4 CR4.VMXE 与CR4.SMXE 控制位 111 6.4.5 CR4.PCIDE 与CR4.SMEP 控制位 112 6.4.6 CR4.OSXSAVE 控制位 113 6.4.7 CR4 中关于页的控制位 113 6.5 EFER 扩展功能寄存器 114 第 7 章 MSR. 116 7.1 MSR 的使用 116 7.2 MTRR 117 7.2.1 Fixed-range 区域的映射 118 7.2.2 MTRR 的功能寄存器 120 7.3 MSR 中对特殊指令的支持 124 7.3.1 支持sysenter/sysexit 指令的MSR 125 7.3.2 支持syscall/sysret 指令的MSR 126 7.3.3 支持swapgs 指令的MSR 127 7.3.4 支持monitor/mwait 指令的MSR 128 7.4 提供processor feature 管理 129 7.5 其他未列出来的MSR 129 7.6 关于MSR 一些后续说明 129 第二篇 处理器的工作模式 第8 章实地址模式 132 8.1 真实的地址 132 8.2 real mode 的编址 132 8.3 real mode 的状态 133 8.4 段基址的计算 134 8.5 第1 条执行的指令 134 8.6 实模式下的执行环境 135 8.7 实模式下的IVT 135 8.8 突破64K 段限 136 8.9 A20 地址线 137 第 9 章 SMM系统管理模式探索 138 9.1 进入SMM 138 9.2 SMM 的运行环境 141 9.2.1 SMRAM 区域 141 9.2.2 SMM 执行环境的初始化 143 9.2.3 SMM 下的operand 与address 144 9.2.4 SMM 下的CS 与EIP 144 9.2.5 SMM 下的SS 与ESP 145 9.3 SMM 里的中断 145 9.4 SMI 的Back-to-Back 响应 147 9.5 SMM 里开启保护模式 147 9.6 SMM 的版本 148 9.7 I/O 指令的重启及Halt 重启 151 9.8 SMM 的退出 152 9.9 SMBASE 的重定位. 153 9.10 SMI 处理程序的初始化 154 9.11 SMM 的安全 156 9.11.1 芯片组的控制 156 9.11.2 处理器对SMRAM 空间的限制 158 9.11.3 cache 的限制 160 9.12 测试SMI 处理程序 161 第 10 章 x86/x64 保护模式体系(上) 163 10.1 x86/x64 的权限 164 10.2 保护模式下的环境 164 10.2.1 段式管理所使用的资源 165 10.2.2 paging 分页机制所使用的资源 165 10.3 物理地址的产生 166 10.4 段式管理机制 167 10.4.1 段式内存管理 168 10.4.2 段式的保护措施 168 10.5 段式管理的数据结构 169 10.5.1 Segment Selector(段选择子) 169 10.5.2 Descriptor Table(描述符表) 172 10.5.3 Segment Selector Register(段寄存器) 174 10.5.4 Segment Descriptor(段描述符) 175 10.5.5 LDT 描述符与LDT 258 10.6 开启保护模式 259 10.6.1 初始化GDT 260 10.6.2 初始化IDT. 262 10.6.3 切换到保护模式 263 第11 章 x86/x64 保护模式体系(下) 265 11.1 物理页面 265 11.1.1 处理器的最高物理地址(MAXPHYADDR) 266 11.1.2 物理页面的大小 267 11.1.3 页转换模式(Paging Mode) 268 11.2 paging 机制下使用的资源 270 11.2.1 寄存器 270 11.2.2 CPUID 查询leaf 270 11.2.3 寄存器的控制位 271 11.2.4 页转换表资源 272 11.3 32 位paging 模式(non-PAE 模式) 273 11.3.1 CR3 结构 274 11.3.2 32 位paging 模式下的PDE 结构 275 11.3.3 使用32 位paging 279 11.4 PAE paging 模式. 282 11.4.1 在Intel64 下的CR3 与PDPTE 寄存器 283 11.4.2 在AMD64 下的CR3 285 11.4.3 PAE paging 模式里的PDPTE 结构 286 11.4.4 PAE paging 模式里的PDE 结构 286 11.4.5 PAE paging 模式里的PTE 结构 288 11.4.6 使用和测试PAE paging 模式 288 11.4.7 使用和测试Execution Disable 功能 292 11.5 IA-32e pagi
目录 第一篇 x86 基础 第1 章数与数据类型2 1.1 数 2 1.1.1 数字 2 1.1.2 二进制数 3 1.1.3 二进制数的排列 3 1.1.4 十六进制数 5 1.1.5 八进制数与十进制数 5 1.2 数据类型 6 1.2.1 integer 数 6 1.2.2 floating-point 数. 9 1.2.3 real number(实数)与NaN(not a number) . 11 1.2.4 unsupported 编码值 14 1.2.5 浮点数精度的转换 15 1.2.6 浮点数的溢出 17 1.2.7 BCD 码 20 1.2.8 SIMD 数据 21 第2 章 x86/x64 编程基础 23 2.1 选择编译器 23 2.2 机器语言 24 2.3 Hello world 25 2.3.1 使用寄存器传递参数 26 2.3.2 调用过程 27 2.3.3 定义变量 27 2.4 16 位编程、32 位编程,以及64 位编程 28 2.4.1 通用寄存器 28 2.4.2 操作数大小 30 2.4.2 64 位模式下的内存地址 30 2.4.4 内存寻址模式 31 2.4.5 内存寻址范围 34 2.4.6 使用的指令限制 34 2.5 编程基础 34 2.5.1 操作数寻址 35 2.5.2 传送数据指令 39 2.5.3 位操作指令 45 2.5.4 算术指令 47 2.5.5 CALL 与RET 指令 48 2.5.6 跳转指令 48 2.6 编辑与编译、运行 48 第 3 章编写本书的实验例子 50 3.1 实验的运行环境 50 3.2 生成空白的映像文件 52 3.2.1 使用nasm 编译器生成 52 3.2.2 使用bximage 工具 52 3.3 设置bochs 配置文件. 53 3.4 源代码的基本结构 54 3.5 编译源代码55 3.6 映像文件内的组织 55 3.7 使用merge 工具 56 3.7.1 merge 的配置文件 57 3.7.2 执行merge 命令 57 3.8 使用U 盘启动真实机器 58 3.8.1 使用merge 工具写U 盘 58 3.8.2 使用hex 编辑软件写U 盘 59 3.9 编写boot 代码 60 3.9.1 LBA 转换为CHS 62 3.9.2 测试是否支持int 13h 扩展功能 63 3.9.3 使用int 13h 扩展读磁盘 64 3.9.4 最后看看load_module() 64 3.10 总结 66 第4 章处理器的身份 67 4.1 测试是否支持CPUID 指令 67 4.2 CPUID 指令的术语及表达 68 4.3 基本信息与扩展信息 68 4.4 处理器的型号(family,model 与stepping) 72 4.5 最大的物理地址和线性地址 73 4.6 处理器扩展状态信息74 4.6.1 探测Processor Extended State 子叶 75 4.6.2 Processor Extended State 子叶所需内存size 76 4.6.3 Processor Extended State 的保存 77 4.6.4 Processor Extended State 的恢复 78 4.7 处理器的特性 78 4.8 处理器的Cache 与TLB 信息 80 4.9 MONITOR/MWAIT 信息 83 4.10 处理器的long mode 84 第 5 章了解 Flags 85 5.1 Eflags 中的状态标志位 86 5.1.1 signed 数的运算 86 5.1.2 unsigned 数的运算 89 5.2 IOPL 标志位 90 5.3 TF 标志与RF 标志 93 5.4 NT 标志 95 5.5 AC 标志 96 5.6 VM 标志 98 5.7 eflags 寄存器的其他事项 99 第 6 章处理器的控制寄存器 101 6.1 CR8 102 6.2 CR3 103 6.3 CR0 104 6.3.1 保护模式位PE 104 6.3.2 x87 FPU 单元的执行环境 104 6.3.3 CR0.PG 控制位 108 6.3.4 CR0.CD 与CR0.NW 控制位 108 6.3.5 CR0.WP 控制位 110 6.3.6 CR0.AM 控制位 110 6.4 CR4 110 6.4.1 CR4.TSD 与CR4.PCE 控制位 110 6.4.2 CR4.DE 与CR4.MCD 控制位 111 6.4.3 CR4.OSFXSR 控制位 111 6.4.4 CR4.VMXE 与CR4.SMXE 控制位 111 6.4.5 CR4.PCIDE 与CR4.SMEP 控制位 112 6.4.6 CR4.OSXSAVE 控制位 113 6.4.7 CR4 中关于页的控制位 113 6.5 EFER 扩展功能寄存器 114 第 7 章 MSR. 116 7.1 MSR 的使用 116 7.2 MTRR 117 7.2.1 Fixed-range 区域的映射 118 7.2.2 MTRR 的功能寄存器 120 7.3 MSR 中对特殊指令的支持 124 7.3.1 支持sysenter/sysexit 指令的MSR 125 7.3.2 支持syscall/sysret 指令的MSR 126 7.3.3 支持swapgs 指令的MSR 127 7.3.4 支持monitor/mwait 指令的MSR 128 7.4 提供processor feature 管理 129 7.5 其他未列出来的MSR 129 7.6 关于MSR 一些后续说明 129 第二篇 处理器的工作模式 第8 章实地址模式 132 8.1 真实的地址 132 8.2 real mode 的编址 132 8.3 real mode 的状态 133 8.4 段基址的计算 134 8.5 第1 条执行的指令 134 8.6 实模式下的执行环境 135 8.7 实模式下的IVT 135 8.8 突破64K 段限 136 8.9 A20 地址线 137 第 9 章 SMM系统管理模式探索 138 9.1 进入SMM 138 9.2 SMM 的运行环境 141 9.2.1 SMRAM 区域 141 9.2.2 SMM 执行环境的初始化 143 9.2.3 SMM 下的operand 与address 144 9.2.4 SMM 下的CS 与EIP 144 9.2.5 SMM 下的SS 与ESP 145 9.3 SMM 里的中断 145 9.4 SMI 的Back-to-Back 响应 147 9.5 SMM 里开启保护模式 147 9.6 SMM 的版本 148 9.7 I/O 指令的重启及Halt 重启 151 9.8 SMM 的退出 152 9.9 SMBASE 的重定位. 153 9.10 SMI 处理程序的初始化 154 9.11 SMM 的安全 156 9.11.1 芯片组的控制 156 9.11.2 处理器对SMRAM 空间的限制 158 9.11.3 cache 的限制 160 9.12 测试SMI 处理程序 161 第 10 章 x86/x64 保护模式体系(上) 163 10.1 x86/x64 的权限 164 10.2 保护模式下的环境 164 10.2.1 段式管理所使用的资源 165 10.2.2 paging 分页机制所使用的资源 165 10.3 物理地址的产生 166 10.4 段式管理机制 167 10.4.1 段式内存管理 168 10.4.2 段式的保护措施 168 10.5 段式管理的数据结构 169 10.5.1 Segment Selector(段选择子) 169 10.5.2 Descriptor Table(描述符表) 172 10.5.3 Segment Selector Register(段寄存器) 174 10.5.4 Segment Descriptor(段描述符) 175 10.5.5 LDT 描述符与LDT 258 10.6 开启保护模式 259 10.6.1 初始化GDT 260 10.6.2 初始化IDT. 262 10.6.3 切换到保护模式 263 第11 章 x86/x64 保护模式体系(下) 265 11.1 物理页面 265 11.1.1 处理器的最高物理地址(MAXPHYADDR) 266 11.1.2 物理页面的大小 267 11.1.3 页转换模式(Paging Mode) 268 11.2 paging 机制下使用的资源 270 11.2.1 寄存器 270 11.2.2 CPUID 查询leaf 270 11.2.3 寄存器的控制位 271 11.2.4 页转换表资源 272 11.3 32 位paging 模式(non-PAE 模式) 273 11.3.1 CR3 结构 274 11.3.2 32 位paging 模式下的PDE 结构 275 11.3.3 使用32 位paging 279 11.4 PAE paging 模式. 282 11.4.1 在Intel64 下的CR3 与PDPTE 寄存器 283 11.4.2 在AMD64 下的CR3 285 11.4.3 PAE paging 模式里的PDPTE 结构 286 11.4.4 PAE paging 模式里的PDE 结构 286 11.4.5 PAE paging 模式里的PTE 结构 288 11.4.6 使用和测试PAE paging 模式 288 11.4.7 使用和测试Execution Disable 功能 292 11.5 IA-32e pagi

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值