Loading... ## 进位计数制 - 基数:每个数码位所用到的不同符号的个数,$r$ 进制的基数为 $r$ 。 十进制转二进制:整数使用除二取余法,小数使用乘二取整法。其他进制依此类推。 ## 定点数的表示 - **无符号数**:所有二进制位都是数值位,没有符号位。 表示范围为 $0$ ~ $2^n - 1$ 。 - 有符号数: ![image-20240718001325121.png][1] - 原码:用尾数表示真值的绝对值,符号位对应正负。 - 反码:若符号位为 0 ,则反码与原码相同;若符号位为 1 ,则数值位全部取反。 - 补码:若符号位为 0 ,则与原码相同;若符号位为 1 ,则取反码并对数值位加一 (尾数取反并加一) 。 - 移码:补码的基础上将符号位取反。(移码只能用来表示整数) 移码表示的整数可以很方便地比较大小。 ![image-20240806004634432.png][2] ### C语言中的定点整数 > C 语言中定点整数是用**补码**存储的。 - 无符号整数和有符号整数之间的转换: 不改变数据内容,改变解释方式。 - 长整数变短整数: 高位截断,保留低位。 - 短整数变长整数: 拓展符号位。无符号整数使用**零扩展**,有符号数使用**符号扩展**。 ## 逻辑门电路 ![image-20240806115512748.png][3] > 逻辑运算的优先级为 非 > 与 > 或 。 > > 如果存在括号,则括号内的优先级更高。非运算符下面默认隐含一个括号。 ### 逻辑运算公式 - 分配律:$A(C + D) = AC + AD$ - 与运算的结合律:$ABC = A(BC)$ - 或运算的结合律:$A + B + C = A + (B + C)$ - 反演律:$\overline{A + B} = \overline{A} \cdot \overline{B}$ , $\overline{A \cdot B} = \overline{A} + \overline{B}$ ### 多路选择器 (MUX) 多路选择器 (multiplexer, MUX) 的作用是在多个输入数据中,只允许一个数据通过 MUX 。 通常使用梯形来表示,有多个输入,一个输出,一个控制信号 (梯形的长短是输入端,短边为输出端) 。 若有 $k$ 个输入,则控制信号的位数 $m \geq \lceil log_2k \rceil$ bit 。 ![image-20240806205739845.png][4] ### 三态门 作用:根据控制信号决定是否让输入的数据通过。有一个输入,一个输出,一个控制信号。 ![image-20240806212442624.png][5] 三态门的控制信号只需要 1bit 。 ## 加法器 ### 一位全加器 ![image-20240806214025540.png][6] ### 串行加法器 将 $n$ 个 FA 连接起来就可以得到 $n \ bit$ 的加法器。 但这种方法存在不足,因为进位信息是串行产生的,所以计算速度取决于进位产生和传递的速度。位数越多,运算速度越慢。 - 电信号到达稳态需要一定时间,因此进位的产生会存在延迟。 - 串行进位又称为行波进位,每一级进位直接依赖于前一集的进位,即进位信号是逐级形成的。 由于进位信息是串行产生的,因此从进位方式来看,这种加法器称为 :**串行进位加法器**。但由于两个输入端允许并行输入 $n \ bit$ ,因此也有将这种加法器称为并行加法器的,或者称为**串行进位的并行加法器**。 ### 并行进位的并行加法器 > 下面的并行加法器都指并行进位的并行加法器。 相比于串行加法器,并行加法器的**所有进位信息都是同时产生的**,几乎没有延迟。 并行加法器的思想类似 DP 。从上面一位全加器的实现中我们得知第 $i$ 位向高位的进位信息为 $$ C_i = A_iB_i + (A_i \oplus B_i) C_{i - 1} $$ 显然这是一个递归式,可以将 $C_{i - 1}$ 继续展开: $$ C_i = A_iB_i + (A_i \oplus B_i) (A_{i - 1} B_{i - 1} + (A_{i - 1} \oplus B_{i - 1}) C_{i - 2}) $$ 直到展开至 $C_0$ 为止。由于 $A_i, B_i$ 都是事先知道的,所以我们可以在 $O(1)$ 的时间内算出所有进位信息 $C_i$ ,从而在 $O(1)$ 的时间内计算出相加的结果。 但这么做也有缺陷,即计算越后面的进位需要越多的信息,导致逻辑电路越来越复杂。因此日常实现的加法器一般是由四个一位全加器和一些新的线路,运算逻辑组成。 ### 带标志位的加法器 ![image-20240806233942470.png][7] - OF (Overflow Flag) :溢出标志,用于判断带符号数加减运算是否溢出。 - SF (Sign Flag) :符号标志,用于判断带符号数加减运算的正负。 - ZF (Zero Flag) :零标志,用于判断加减运算的结果是否为 0 。 - CF (Carry Flag) :进位 / 借位标志,用于判断无符号数加减运算是否溢出。 **标志位的生成**: ![image-20240806234509930.png][8] ## 算术逻辑单源 ALU CPU 由控制器和运算器组成。控制器负责解析指令,并根据指令功能发出相应的控制信号;运算器负责对数据进行处理,如加减乘除等。 ![image-20240807211634991.png][9] ALU (Arithmetic and Logic Unit) 是一种组合逻辑电路,实现了**加减乘除与或非**等功能,因此 **ALU 是运算器的核心**。 由于加减乘除等运算都要**基于加法实现**,因此**加法器是 ALU 的核心**。 ### ALU 的功能 - 算数运算:加减乘除 等; - 逻辑运算:与或非,异或,移位 等; - 其他:求补码,直送 等。 > 如果 ALU 支持 $k$ 种功能,则控制信号位数 $m \geq \lceil log_2k \rceil$ 。 ### 实现原理 简单了解即可。一种 ALU 的简单实现就是将输入传给各种运算电路,然后全部汇聚到 MUX 中,通过 MUX 筛选出需要的结果作为输出。 ![image-20240807231115144.png][10] ### 考点 - 如果 ALU 支持 $k$ 种功能,则控制信号位数 $m \geq \lceil log_2k \rceil$ 。 - ALU的**运算数,运算结果位数**与计算机的**机器字长**相同。 - 标志位:ZF, OF, SF, CF ,用于表示本次运算结果的特征。 - 标志信息通常会被送入 PSW 程序状态字寄存器中。 有的计算机系统把 PSW 寄存器称为标志寄存器 FR (Flag Register) 。 ![image-20240807231532558.png][11] > Cin 是进位输入信号,Cout 是进位输出信号 。(类似于带标志位的加法器) ![image-20240807231853267.png][12] ## 定点数的运算 ### 有符号数的移位运算 #### 算数移位 - 原码的算数移位:符号位不变,仅对数值位进行移位。 右移时高位补 0 ,低位舍弃。若舍弃的位不为 0 ,则会**丢失精度**。 左移时低位补 0 ,高位舍弃。若舍弃的位不为 0 ,则会出现**严重误差**。 - 反码的算数移位: 正数的反码和原码相同,因此正数的移位和原码相同。 负数的反码和原码相反,**移位时应该补 1** ,其余和原码相同。 - 补码的算数移位: 正数的补码和原码相同,因此正数的移位和原码相同。 因为补码的特性,导致反码最右边的几个连续的 1 都因为进位而变成 0 ,直到进位碰到第一个 0 为止。因此负数补码中,**最右边的 1 及其右边的数移码操作同原码,最右边的 1 的左边同反码。** **右移时同反码**,高位补 1 ,低位舍弃;左移时同原码,低位补 0 ,高位舍弃。 #### 逻辑移位 - 逻辑右移:高位补 0 ,低位舍弃。 - 逻辑左移:低位补 0 ,高位舍弃。 > 逻辑移位可以看作是对无符号数的算数移位。 #### 循环移位 ![image-20240808005722769.png][13] ### 有符号数的加减运算 原码的加法运算: - 正数 + 正数:绝对值做加法,结果为正数。 - 负数 + 负数:绝对值做加法,结果为负数。 - 一正一负相加:绝对值大的减去绝对值小的,符号同绝对值大的数。 减法运算可以转换成加法运算,只需要将减数的符号取反即可。 使用原码进行加减运算需要复杂的电路设计,因此一般使用补码进行加减运算。补码的加法只需要直接相加即可,得到的结果即为两个数相加后的结果。减法也同样可以转换成加法运算。 #### 溢出判断 - 若**两个正数**相加得到了一个**负数**,那么就可以判断发生了**上溢出**。 - 若**两个负数**相加得到了一个**正数**,那么就可以判断发生了**下溢出**。 方法一:采用一位符号位。设 $A$ 的符号为 $A_S$ ,$B$ 的符号为 $B_S$ ,运算结果的符号为 $S_S$ ,则溢出的逻辑表达式为 : $$ V = A_S B_S \overline{S_S} + \overline{A_S} \overline{B_S} S_S $$ 若 $V = 0$ ,则表示无溢出;反之则为溢出。 方法二:采用一位符号为,根据数据位的进位情况判断溢出。设符号位的进位为 $C_S$ ,最高位数值位的进位为 $C_1$ 。若 $C_S \oplus C_1 = 1$ ,则表示有溢出。 方法三:采用双符号位。正数使用 00 ,负数使用 11 。若两个符号位为 **01** ,则说明发生了**上溢出**;若两个符号位为 **10** ,则说明发生了下溢出。 > 双符号位的补码又称为**模4补码**,单符号位的补码又称**模2补码**。 > > 双符号位实际存储时**只存储一个**符号位,**运算时会多复制一个**符号位。 ### 无符号数的加减运算 无符号数的加法很简单,全部按位相加并向更高位进位即可。 减法相当于加上负数。根据补码的定义,一个数的补码表示的是该数的补数。因此无符号数的减法只需要被减数加上减数的补码即可。 #### 溢出判断 手算的方法只需要判断是否超过 $2^n - 1$ 即可。 - 无符号数加法过程中,若最高位发生了进位,则表明出现了溢出; - 无符号数减法过程中,若最高位没有发生进位,则表明出现了溢出。 ### 补码加减运算电路 ![image-20240808212808130.png][14] ### 乘法运算 运算器的基本组成: ![image-20240811002218130.png][15] #### 原码的一位乘法 ![image-20240811002316469.png][16] #### 补码的一位乘法 - 进行 $n$ 轮加法,移位,**最后再多一次加法**。 - 每次加法可能是 $+0, +[x]_{补}, +[-x]_{补}$ ,根据当前 MQ 中 "最低位" 和**辅助位**来确定。 - 每次移位是补码的**算术右移**。 - 符号位参与运算。 ![image-20240811010519188.png][17] - 辅助位 - MQ 中 "最低位" = 1 时,$ACC = ACC + [x]_{补}$ ; - 辅助位 - MQ 中 "最低位" = 0 时,$ACC = ACC + 0$ ; - 辅助位 - MQ 中 "最低位" = -1 时,$ACC = ACC + [-x]_{补}$ ; ![image-20240811010814688.png][18] #### 异同 | 原码一位乘法 | 补码一位乘法 | | ------------------------------------------------------------ | ------------------------------------------------------------ | | 符号位通过异或确定,数值位由被乘数和乘数的绝对值进行 $n$ 轮加法,移位获得。 | 符号位,数值位都是由被乘数和乘数进行 $n$ 轮加法,移位,**最后再多来一次加法**得到。 | | 每次加法可能为 $+0, +[|x|]_{原}$ 。 | 每次加法可能为 $+0, +[x]_{补}, +[-x]_{补}$ 。 | | 每次位移是**逻辑右移**。 | 每次位移是**算数右移**。 | | 乘数的**符号位不参与**运算。 | 乘数的**符号位参与**运算。 | | MQ 中最低位 = 1 时,$ACC = ACC + [|x|]_{原}$ 。<br>MQ 中最低位 = 1 时,$ACC = ACC + 0$ 。 | 辅助位 - MQ 中 "最低位" = 1 时,$ACC = ACC + [x]_{补}$ ; <br>辅助位 - MQ 中 "最低位" = 0 时,$ACC = ACC + 0$ ;<br> 辅助位 - MQ 中 "最低位" = -1 时,$ACC = ACC + [-x]_{补}$ ; | ### 除法运算 > 这里讨论的是定点小数的除法,由于定点小数无法表示大于 1 的数,所以默认被除数是小于除数的。 > > 对于硬件来说,若检测到第一位的运算结果不是 0 ,就表明被除数是大于除数的,硬件电路会直接返回。 #### 原码除法 原码除法和原码乘法一样,**符号位需要单独处理**,将被除数和除数的符号位进行**异或**运算即可。确定了符号位之后,**数值位**的计算需要**取绝对值**进行。 首先先看运算器中各寄存器存放的都是什么: ![image-20240812012611687.png][19] ##### 恢复余数法 运算电路中没有比较大小的电路,因此计算机会**默认当前位的商为 1** ,用余数减去除数。如果相减后结果为负数,则表明之前的假设有误,需要将该位的商改成 0 ,并恢复余数。 计算出当前位的商后,需要进行**向左的逻辑移位**。 ![image-20240812014421492.png][20] ##### 加减交替法 恢复余数法每次商 0 的时候都需要加上除数来恢复余数,这个过程复杂且耗时。如何将恢复余数这个过程简化掉呢? ![image-20240812020017365.png][21] 观察恢复余数的过程,当检测到余数为负数的时候,需要将余数加上除数,左移,减去除数,然后再次判断余数是否为负。这个过程最终相当于将余数乘 2 之后再加上除数,因此可以将恢复余数的过程直接简化为**余数左移一位后再加上除数**。 ![image-20240812020509971.png][22] 加减交替法又称为不回复余数法,但最终余数如果为负,还是需要加一次除数来恢复余数。 #### 补码除法 补码除法使用的也是**加减交替法**。其中**符号位需要参与运算**,且被除数,余数,除数都使用**双符号位**。 补码除法的操作和当前被除数,余数和除数的符号有关: - 第一步的时候,被除数和除数**同号**,则被除数需要**减去**除数;**异号**则被除数**加上**除数。 - 后面的运算中就是判断余数和除数的关系了。**同号**则**商 1** ,**余数左移一位减去除数**;异号则**商 0** ,**余数左移一位加上除数**。 - 末尾的商恒置 1 ,这样的话比较方便硬件电路设计,并且精度误差不超过 $2^{-n}$ 。 ![image-20240813005513733.png][23] #### 异同 | 除法类型 | 符号位参与运算 | 加减次数 | 移位方向 | 移位次数 | 上商,加减原则 | 说明 | | -------------- | -------------- | ---------- | -------- | -------- | ------------------ | ------------------------------ | | 原码加减交替法 | 否 | N+1 或 N+2 | 左移 | N | 余数的正负 | 若最终余数为负,则需恢复余数。 | | 补码加减交替法 | 是 | N+1 | 左移 | N | 余数和除数是否同号 | 商末尾恒置 1 。 | ## 浮点数的表示 定点数可表示的数字范围有限,且无限制地增加数据地长度是一个不现实的想法。此时想要增加数据的表示范围可以使用浮点数。 ![image-20240813145458260.png][24] - **阶码**:常用补码或移码表示的**定点整数**,反映浮点数的**表示范围**以及小数点的实际位置。 - **尾数**:常用原码或补码表示的**定点小数**,尾数的数值部分的**位数**反映浮点数的**精度**。 - **真值**:$N = r^E \times M$ 。其中 $r$ 为阶码的底,通常为 2 ;$E$ 为阶码,$M$ 为尾数。 > 尾数给出了一个小数,阶码指明了小数点要向前 / 向后移动几位。 ### 浮点数尾数的规格化 尾数部分**最高的数值位必须是一个有效值**,这样才可以获取最大的精度。如果不满足这个条件就需要进行**规格化**。 - **左规**:当浮点数运算的结果为非规格化时要进行规格化处理,将尾数**算数左移一位**,**阶码减一**。 - **右规**:当浮点数运算的结果尾数出现溢出 (双符号位为 01 或者 10) 时,将尾数**算数右移一位**,**阶码加一**。 > 采用双符号位,在出现溢出时可以进行挽救。 - 原码表示的尾数规格化后尾数的**最高数值位必须为 1** 。 - 补码表示的尾数规格化后尾数的最高数值位**必须和尾数符号相反**。 > 规定如此,可以方便计算机硬件判断是否已经规格化。 #### 规格化浮点数的范围 > 不考,了解即可。 ![image-20240813150234544.png][25] 用原码表示的尾数进行规格化后: - 正数为 0.1xxxx 的形式,最大值为 0.11 ... 1 ;最小值为 0.10 ... 0 。 因此尾数的表示范围为 $\frac{1}{2} \leq M \leq (1 - 2^{-n})$ 。 - 负数为 1.1xxxx 的形式,最大值为 1.10 ... 0 ;最小值为 1.11 ... 1 。 因此尾数的表示范围为 $(2^{-n} - 1) \leq M \leq - \frac{1}{2}$ 。 用补码表示的尾数进行规格化后: - 正数为 0.1xxxx 的形式,最大值为 0.11 ... 1 ;最小值为 0.10 ... 0 。 因此尾数的表示范围为 $\frac{1}{2} \leq M \leq (1 - 2^{-n})$ 。 - 负数为 1.0xxxx 的形式,最大值为 1.01 ... 1 ;最小值为 1.00 ... 0 。 因此尾数的表示范围为 $-1 \leq M \leq -(\frac{1}{2} + 2^{-n})$ 。 ### IEEE 754 > 移码的定义:移码 = 真值 + 偏置值 IEEE754 中,浮点数的阶码是使用移码来表示的,但偏置值是 127D ,即 $2^{n - 1} - 1$ 。 > 相当于浮点数的阶码需要减去 127 才是真正的指数。 ![image-20240814012136942.png][26] | 类型 | 数符 | 阶码 | 尾数数值 | 总位数 | 偏置值 | | ----------- | ---- | ---- | -------- | ------ | ------ | | float | 1 | 8 | 23 | 32 | 127 | | double | 1 | 11 | 52 | 64 | 1023 | | long double | 1 | 15 | 64 | 80 | 16383 | > 尾数最高位隐藏了一个 1 ,计算尾数的时候需要补上。 **由浮点数确定真值** (阶码不是全 0 ,也不是全 1 ) : 1. 根据某浮点数确定数符,阶码,尾数的分布; 2. 确定尾数 1.M (补充最高位隐含的 1 ) ; 3. 确定阶码的真值 (移码 - 偏置值) ; 4. $(-1)^S \times 1.M \times 2^{E - 偏置值}$ 。 #### 单精度浮点数的极值情况 | 类别 | 正负号 | 实际指数 | 有偏移指数 | 指数域 | 尾数域 | 数值 | | :----------------- | :----: | :------- | :--------- | :-------- | :--------------------------- | :----------------------------------------------------------- | | 零 | 0 | -127 | 0 | 0000 0000 | 000 0000 0000 0000 0000 0000 | $0.0$ | | 负零 | 1 | -127 | 0 | 0000 0000 | 000 0000 0000 0000 0000 0000 | $−0.0$ | | $1$ | 0 | 0 | 127 | 0111 1111 | 000 0000 0000 0000 0000 0000 | $1.0$ | | $-1$ | 1 | 0 | 127 | 0111 1111 | 000 0000 0000 0000 0000 0000 | $−1.0$ | | 最小的非规约数 | \* | -126 | 0 | 0000 0000 | 000 0000 0000 0000 0000 0001 | $\pm 2^{−23} \times 2^{−126} = \pm 2^{−149} \approx \pm 1.4 \times 10^{-45}$ | | 中间大小的非规约数 | \* | -126 | 0 | 0000 0000 | 100 0000 0000 0000 0000 0000 | $\pm 2^{−1} \times 2^{−126} = \pm 2^{−127} \approx \pm 5.88 \times 10^{-39}$ | | 最大的非规约数 | \* | -126 | 0 | 0000 0000 | 111 1111 1111 1111 1111 1111 | $\pm (1−2^{−23}) \times 2^{−126} \approx \pm 1.18 \times 10^{-38}$ | | 最小的规约数 | \* | -126 | 1 | 0000 0001 | 000 0000 0000 0000 0000 0000 | $\pm 2^{−126} \approx \pm 1.18 \times 10^{-38}$ | | 最大的规约数 | \* | 127 | 254 | 1111 1110 | 111 1111 1111 1111 1111 1111 | $\pm (2−2^{−23}) \times 2^{127} \approx \pm 3.4 \times 10^{38}$ | | 正无穷 | 0 | 128 | 255 | 1111 1111 | 000 0000 0000 0000 0000 0000 | $+\infty$ | | 负无穷 | 1 | 128 | 255 | 1111 1111 | 000 0000 0000 0000 0000 0000 | $−\infty$ | | $NaN$ | \* | 128 | 255 | 1111 1111 | 非全0 | $NaN$ | > 符号位中的 * 表示可以为 0 或者 1 。 ## 浮点数的运算 ### 加减运算 1. 对阶。需要将两个浮点数的阶码对齐,将阶码较小的转换成阶码较大的数。尾数每右移一位,阶码加一。 2. 尾数加减。 3. 规格化。尾数加减运算后出现不符合规定的形式,则需要进行左规或右规。 4. 舍入。按照规定保留有效尾数,一般有以下两种保留方法: - 0 舍 1 入法:类似于十进制中的四舍五入。在尾数右移时,被移去的最高数值位为 0 ,则直接舍去;若被移去的最高数值位为 1 ,则在位数的末位加 1 。 这样做可能会导致尾数又产生溢出,所以需要再做一次右规。 - 恒置 1 法:尾数右移时,不论丢掉的最高数位是 0 还是 1 ,都将右移后的尾数末尾置为 1 。 这种方法同样有使尾数变大和变小的两种可能。 5. 判溢出。判断阶码是否超过了规定的范围。 注意尾数溢出未必导致整体溢出,规格化和舍入后可能还是一个正常的浮点数。 遇到下溢的情况直接当作机器 0 即可,上溢的情况才需要抛出异常。 ### 强制类型转换 > 考试中一般使用 32 位机器 C 语言中不同类型在不同位数的机器上所占的字节数: | 类型 | 16位机器 | 32位机器 | 64位机器 | | :-------: | :------: | :------: | :------: | | char | 8 | 8 | 8 | | short | 16 | 16 | 16 | | int | 16 | 32 | 32 | | long | 32 | 32 | 64 | | long long | 64 | 64 | 64 | | float | 16 | 32 | 32 | | double | 64 | 64 | 64 | - 范围,精度从小到大,转换过程中不会有损失;反之则会导致精度损失或溢出。 ## 数据的存储和排列 ### 大小端模式 - 大端存储:地址从低到高,存储的字节也是从低到高,更加符合人类的阅读直觉。 - 小端存储:地址从低到高,存储的字节是从高到底,更方便计算机读取。 ![image-20240814135232798.png][27] ### 边界对齐 现代计算机通常是按字节编址,即每个字节对应一个地址。通常也支持按字,按半字,按字节寻址。 假设存储字长为 32 位,则一个字为 32 bit ,一个半字为 16 bit ,每次访问只能读写一个字; ![image-20240814135558572.png][28] > 空间换时间的思想 [1]: https://blog.domineto.top/usr/uploads/2024/09/1423081556.png [2]: https://blog.domineto.top/usr/uploads/2024/09/1210195291.png [3]: https://blog.domineto.top/usr/uploads/2024/09/1688062641.png [4]: https://blog.domineto.top/usr/uploads/2024/09/3320466826.png [5]: https://blog.domineto.top/usr/uploads/2024/09/3734271581.png [6]: https://blog.domineto.top/usr/uploads/2024/09/2624890111.png [7]: https://blog.domineto.top/usr/uploads/2024/09/177529366.png [8]: https://blog.domineto.top/usr/uploads/2024/09/862174920.png [9]: https://blog.domineto.top/usr/uploads/2024/09/3362059940.png [10]: https://blog.domineto.top/usr/uploads/2024/09/921917041.png [11]: https://blog.domineto.top/usr/uploads/2024/09/2532419981.png [12]: https://blog.domineto.top/usr/uploads/2024/09/3484307592.png [13]: https://blog.domineto.top/usr/uploads/2024/09/537996158.png [14]: https://blog.domineto.top/usr/uploads/2024/09/3796190491.png [15]: https://blog.domineto.top/usr/uploads/2024/09/3117809617.png [16]: https://blog.domineto.top/usr/uploads/2024/09/2359280241.png [17]: https://blog.domineto.top/usr/uploads/2024/09/2386034758.png [18]: https://blog.domineto.top/usr/uploads/2024/09/1257662948.png [19]: https://blog.domineto.top/usr/uploads/2024/09/3428687842.png [20]: https://blog.domineto.top/usr/uploads/2024/09/665097357.png [21]: https://blog.domineto.top/usr/uploads/2024/09/3604602226.png [22]: https://blog.domineto.top/usr/uploads/2024/09/89440087.png [23]: https://blog.domineto.top/usr/uploads/2024/09/2914227.png [24]: https://blog.domineto.top/usr/uploads/2024/09/4204921599.png [25]: https://blog.domineto.top/usr/uploads/2024/09/1594587425.png [26]: https://blog.domineto.top/usr/uploads/2024/09/4057442417.png [27]: https://blog.domineto.top/usr/uploads/2024/09/648714417.png [28]: https://blog.domineto.top/usr/uploads/2024/09/3491971835.png 最后修改:2024 年 11 月 21 日 © 允许规范转载 赞 如果觉得我的文章对你有用,请随意赞赏