当前位置: 首页 > news >正文

x86 汇编逻辑运算全解析:从【位操作】到实际应用(AND,OR,NOT,XOR,TEST)

一、逻辑运算的本质:二进制世界的 "开关游戏"

在数字电路中,所有信息都以二进制(0 和 1)表示。逻辑运算就是对这些二进制位进行独立处理的规则,类似拨动一个个开关。例如:

  • 开关闭合(1)→ 通电
  • 开关断开(0)→ 断电

x86 汇编提供了 5 种基本逻辑运算指令,它们的核心是逐位操作,不涉及进位或借位:

  1. AND(与):全 1 才 1,否则为 0
  2. OR(或):有 1 则 1,全 0 才 0
  3. NOT(非):取反(1 变 0,0 变 1)
  4. XOR(异或):不同为 1,相同为 0
  5. TEST(测试):与运算,但结果不保存,仅影响标志位

 二、五大逻辑指令详解

1. AND 指令:二进制世界的 "筛选器"

1.1. 核心功能:按位相乘,筛选有效信息
  • 数学本质:逐位执行 "逻辑与" 运算(1×1=1,其余为 0)
  • 典型场景
    • 提取特定二进制位(如掩码操作)
    • 强制清零某些位(如清除状态标志)
    • 判断奇偶性(检查最低位)
1.2. 执行逻辑:比特级的 "安检门"
  • 操作规则
    0 AND 0 → 0  
    0 AND 1 → 0  
    1 AND 0 → 0  
    1 AND 1 → 1  
    
  • 示例
    MOV AL, 0b10101010  ; AL = 170 (二进制: 10101010)  
    AND AL, 0b00001111  ; 执行 AND 操作:  ;   1010 1010  ; & 0000 1111  ;   ---------  ;   0000 1010 → AL = 10 (只保留低4位)  
    
1.3. 关键特性:掩码与清零的艺术
  • 掩码(Mask)技术

    • 用 1 保留目标位,用 0 屏蔽无关位
    • 示例:提取 IP 地址中的子网掩码
      MOV EAX, 0xC0A80101  ; IP地址: 192.168.1.1 (C0 A8 01 01)  
      AND EAX, 0xFFFFFF00  ; 子网掩码: 255.255.255.0 → 保留前3字节  
      ; 结果: EAX = 0xC0A80100 (192.168.1.0)  
      
  • 清零技巧

    • AND 自身与 0 可快速清零寄存器
      AND EAX, 0  ; 等价于 MOV EAX, 0 (但可能执行更快)  
      
1.4. 实战案例:奇偶校验与权限检查
  • 奇偶性判断

    MOV AL, 7    ; AL = 0000 0111 (奇数)  
    AND AL, 1    ; 仅保留最低位 → AL = 0000 0001  
    JZ EVEN      ; ZF=0 → 结果非零 → 奇数  
    ; 处理奇数逻辑  
    
  • 权限位检查

    MOV EAX, 0x1F  ; 权限标志: rwxr-xr-x (二进制: 0001 1111)  
    AND EAX, 0x04  ; 检查用户写权限 (第3位)  
    JZ NO_WRITE    ; ZF=1 → 结果为零 → 无写权限  
    ; 有权限执行写操作  
    
1.5. 标志位影响:无声的状态记录者
  • ZF(零标志)

    • 结果全 0 时 ZF=1(如 AND AL, 0
    • 常用于条件判断(如 JZ/JNZ 跳转)
  • CF/OF(进位 / 溢出标志)

    • 固定清零(CF=0, OF=0)
    • 可用于重置标志位状态
1.6. 性能对比:比 MOV 更高效?
  • 指令长度

    • AND 通常为 2 字节(如 AND AL, 0Fh
    • MOV 立即数可能更长(如 MOV AL, 0 需要 3 字节)
  • 执行速度

    • 在现代 CPU 中,AND 与 MOV 性能接近
    • 但 AND 无需访问内存取立即数,可能略快
1.7. 常见误区:别把 AND 当赋值用
  • 错误示例

    AND AL, 255  ; 想将AL设为255?大错特错!  
    ; 实际执行: AL = AL & 255 (等价于AL保持原值)  
    
  • 正确写法

    MOV AL, 255  ; 直接赋值  
    
1.8. 一句话总结:

AND 指令就像二进制世界的 "滤网",通过精心设计的掩码(Mask),可以精准地保留你需要的信息,过滤掉无关的噪音。无论是数据提取、权限校验还是状态清零,AND 都是你最可靠的二进制 "安检员"!


2. OR 指令:二进制中的 "状态合并器"

2.1 核心功能:按位相或,激活有效状态
  • 数学本质:逐位执行 1 OR 1 = 11 OR 0 = 10 OR 0 = 0(只要有 1 则结果为 1)。
  • 核心场景
    • 强制置位:将特定位固定为 1(如激活权限标志)。
    • 合并标志:组合多个独立状态(如同时激活读写权限)。
    • 逻辑或运算:实现多条件判断的底层操作(如 A || B)。
2.2 执行逻辑:比特级的 "并联开关"
  • 操作规则
       0b0000 1010  
    OR 0b0000 0101  
    -----------  
    0b0000 1111 (只要某一位有1,结果为1)  
    
  • 示例代码
    MOV AL, 0b10100000  ; AL = 160(目标:保留高4位,低4位置1)  
    OR  AL, 0b00001111   ; 低4位强制置1  
    ; 结果:AL = 0b10101111(175)  
    
2.3 关键特性:置位掩码与多标志合并
  • 置位掩码技术

    • 用 1 强制置位目标位,0 保留其他位不变。
    MOV CX, 0x0000  ; 初始权限为0  
    OR CX, 0x0001  ; 设置执行权限(第0位为1)  
    OR CX, 0x0004  ; 设置写权限(第2位为1)  
    ; 结果:CX = 0x0005(执行+写权限)  
    
  • 多标志并行激活

    MOV AL, FLAG_A  ; FLAG_A = 0b0001(标志A)  
    OR AL, FLAG_B  ; FLAG_B = 0b0010(标志B)  
    ; 同时激活标志A和B,AL = 0b0011  
    
2.4 实战案例:权限系统与状态机
  • 文件权限设置(读 + 写 + 执行)

    MOV EAX, 0       ; 初始无权限  
    OR EAX, 0x01     ; 执行权限(第0位)  
    OR EAX, 0x02     ; 写权限(第1位)  
    OR EAX, 0x04     ; 读权限(第2位)  
    ; 结果:EAX = 0x07(rwx---)  
    
  • 状态机条件判断

    MOV AL, 0        ; 初始状态为0(假)  
    OR AL, COND1     ; COND1为非零→AL=1(真)  
    OR AL, COND2     ; COND2为非零→AL保持1(只要一个为真,结果为真)  
    JNZ ALLOW_ACTION  ; 条件满足时跳转  
    
2.5 标志位影响:逻辑运算的状态记录
标志位变化规则示例
ZF结果全 0 则 ZF=1,否则 ZF=0OR AL, 0 → ZF=1;OR AL, 5 → ZF=0
SF结果最高位为 1 则 SF=1(反映符号属性)OR AL, 0x80 → SF=1(负数标志)
CF/OF固定清零(逻辑运算无进位 / 溢出)任何 OR 操作后 CF=0、OF=0
2.6 性能与优化:高效的位操作
  • 指令长度
    • 寄存器 - 立即数:2 字节(如 OR AL, 0FH)。
    • 寄存器 - 寄存器:3 字节(如 OR AX, BX)。
  • 执行速度
    • 单周期指令,与 AND 性能相当,远快于算术运算。
2.7 常见错误:避免逻辑混淆
  1. 误用 OR 实现数值加法

    OR AX, BX  ; 错误!逻辑或≠加法(如AX=3,BX=5,OR结果为7,加法结果为8)  
    ADD AX, BX ; 正确:数值运算用ADD  
    
  2. 忽略标志位的逻辑含义

    OR AL, 0x80  ; 设置符号位为1(AL=0x80,十进制-128)  
    CMP AL, 0     ; 比较结果为负数,但实际数值可能非预期  
    
2.8 一句话总结

OR 指令是二进制世界的 “并联开关”,通过掩码将特定位强制置 1,或合并多个独立状态。适用于权限激活、标志组合和逻辑或判断,是构建高效状态系统的核心工具 ——只要有一个条件满足,结果就为真


3. NOT 指令:二进制取反的 "镜像操作"

3.1 核心功能:逐位取反,生成二进制反码
  • 数学本质:对操作数的每一位执行 逻辑非 运算(1→00→1)。
  • 典型场景
    • 生成补码运算的中间步骤(配合 ADD 1 实现负数计算)。
    • 反转寄存器 / 内存中的所有位状态(如切换标志位组合)。
    • 构建与原掩码互补的反向掩码(如 NOT 0x0F 得到 0xF0)。
3.2 执行逻辑:比特级的 "镜面反转"
  • 操作规则
    输入:0babcdefgh  
    输出:0bABCDEFGH(每一位取反,A=1-a,B=1-b,以此类推)  
    
  • 示例代码
    MOV AL, 0b10101010  ; AL = 170(二进制:10101010)  
    NOT AL              ; 逐位取反 → AL = 0b01010101(85)  
    
3.3 关键特性:反码生成与位状态切换
  • 补码运算流程
    ; 计算 -N 的补码(N为正数)  
    MOV AL, N          ; 例如 N=5(0b00000101)  
    NOT AL             ; 反码:0b11111010  
    ADD AL, 1          ; 补码:0b11111011(-5的补码)  
    
  • 全位反转示例
    MOV AX, 0x0000  ; 初始全0  
    NOT AX          ; AX = 0xFFFF(所有位变为1)  
    
3.4 实战案例:负数计算与掩码反转
  • 计算 -128 的补码(8 位)
    MOV AL, 0x80    ; AL = 10000000(-128的原码,补码同形)  
    NOT AL          ; 反码:01111111(不改变符号位,此处仅演示取反)  
    ; 注意:-128是特殊值,补码无法通过取反+1生成,需直接使用原值  
    
  • 构建反向掩码(保留高 4 位,反转低 4 位)

    assembly

    MOV AL, 0x0F    ; 原掩码:00001111(低4位为1)  
    NOT AL          ; 反向掩码:11110000(高4位为1)  
    
3.5 标志位影响:无标志位变动
  • NOT 指令的特殊性
    • 不影响任何标志位(CF、ZF、SF 等均保持原值)。
    • 仅修改操作数的二进制位,不涉及数值运算的进位 / 溢出逻辑。
3.6 性能与优化:单周期位操作
  • 指令长度
    • 1 字节(寄存器操作,如 NOT AL)。
    • 3 字节(内存操作,如 NOT DWORD PTR [NUM])。
  • 执行速度
    • 单时钟周期完成,是 x86 中最快的指令之一。
3.7 常见错误:避免逻辑混淆
  1. 误用 NOT 实现负数运算
    NOT AX  ; 错误!想得到 -AX?需配合 ADD 1 生成补码  
    ; 正确:NEG AX(等价于 NOT AX + 1)  
    
  2. 对内存操作的误判
    NOT BYTE PTR [ESI]  ; 直接修改内存中的字节,需确保地址正确  
    
3.8 一句话总结

NOT 指令是二进制世界的 “镜像工具”,通过逐位取反生成原数据的反码。尽管不影响标志位,但其在补码运算、状态切换和掩码构建中不可或缺 ——每一位的反转,都是对原数据的彻底重构


4. XOR 指令:二进制世界的 "差异探测器"

4.1 核心功能:按位异或,识别不同状态
  • 数学本质:逐位执行 相同为0,不同为1 的逻辑运算(1 XOR 1 = 00 XOR 0 = 01 XOR 0 = 1)。
  • 典型场景
    • 检测差异:找出两个二进制值中不一致的位(如数据校验)。
    • 状态翻转:切换特定位的状态(如开 / 关标志)。
    • 无临时变量交换:高效交换两个寄存器的值。
    • 快速清零:通过 XOR reg, reg 清零寄存器。
4.2 执行逻辑:比特级的 "对比引擎"
  • 操作规则
    输入A:0b10101010  
    输入B:0b11110000  
    输出 :0b01011010 (仅保留A与B不同的位)  
    
  • 示例代码
    MOV AL, 0b10101010  ; AL = 170  
    MOV BL, 0b11110000  ; BL = 240  
    XOR AL, BL          ; AL = 0b01011010(90) → 差异位被标记为1  
    
4.3 关键特性:差异检测与状态切换
  • 差异检测掩码

    MOV EAX, [OLD_DATA]  ; 原始数据  
    MOV EBX, [NEW_DATA]  ; 新数据  
    XOR EAX, EBX         ; 差异位→1,相同位→0  
    ; 若EAX=0,表示数据未变更  
    
  • 状态翻转技术

    MOV AL, 0b10101010  ; 初始状态  
    XOR AL, 0b00001111  ; 翻转低4位 → AL = 0b10100101  
    ; 再次XOR相同值可恢复原始状态  
    
4.4 实战案例:高效交换与校验
  • 无临时变量交换两值

    MOV AX, 5  ; AX = 0b0101  
    MOV BX, 3  ; BX = 0b0011  
    XOR AX, BX ; AX = 0b0110(6)  
    XOR BX, AX ; BX = 0b0101(5)  
    XOR AX, BX ; AX = 0b0011(3)  
    ; 结果:AX=3,BX=5(值交换完成)  
    
  • 数据完整性校验

    MOV AL, [DATA]     ; 待校验数据  
    MOV BL, CHECKSUM   ; 预存校验和  
    XOR AL, BL         ; 计算差异  
    JZ DATA_VALID      ; 若结果为0,表示数据未篡改  
    
4.5 标志位影响:逻辑运算的状态反馈
标志位变化规则示例
ZF结果全 0 则 ZF=1(两值完全相同)XOR AX, AX → ZF=1
SF结果最高位为 1 则 SF=1(反映符号属性)XOR AL, 0x80 → SF=1
CF/OF固定清零(逻辑运算无进位 / 溢出)任何 XOR 操作后 CF=0、OF=0
4.6 性能与优化:单周期的高效指令
  • 指令长度
    • 寄存器 - 立即数:2 字节(如 XOR AL, 0FH)。
    • 寄存器 - 寄存器:3 字节(如 XOR AX, BX)。
  • 执行速度
    • 单周期完成,与 ANDOR 同为最快的逻辑指令。
4.7 常见错误:避免逻辑混淆
  1. 误用 XOR 实现加法

    XOR AX, BX  ; 错误!XOR≠加法(如AX=5,BX=3,XOR结果为6,加法结果为8)  
    ADD AX, BX  ; 正确:数值运算用ADD  
    
  2. 重复 XOR 导致状态恢复

    XOR AL, 0xFF  ; 第一次翻转所有位  
    XOR AL, 0xFF  ; 再次翻转→恢复原值(陷阱!)  
    
4.8 一句话总结

XOR 指令是二进制世界的 “差异放大镜”,通过逐位对比找出数据的不同之处。其在数据校验、状态切换和无临时变量交换中表现卓越 ——相同为 0,不同为 1,差异一目了然!


5. TEST 指令:秘密检测的 "暗箱操作"

5.1 核心功能:按位与运算,静默检测状态
  • 数学本质:执行 目标操作数 & 源操作数,但不保存结果,仅影响标志位。
  • 典型场景
    • 检测特定位是否为 1(如权限标志、状态位)。
    • 判断寄存器是否为 0(替代 CMP reg, 0)。
    • 静默检查条件(不改变原数据,仅设置标志位)。
5.2 执行逻辑:比特级的 "隐形安检"
  • 操作规则
    TEST AL, 0x01  ; 检测AL的最低位是否为1  
    ; 等效于: AND AL, 0x01,但TEST不修改AL的值  
    
  • 标志位影响
    标志位变化规则示例
    ZF若结果为 0 则 ZF=1(如检测位全为 0)TEST AL, 0x01 → 若 AL 最低位为 0,ZF=1
    SF结果最高位为 1 则 SF=1(反映符号属性)TEST AL, 0x80 → 检测符号位
    PF结果低 8 位中 1 的个数为偶数则 PF=1TEST AL, 0xFF → 统计 1 的奇偶性
    CF/OF固定清零(逻辑运算无进位 / 溢出)任何 TEST 操作后 CF=0、OF=0
5.3 关键特性:无损检测与条件跳转
  • 特定位检测掩码

    TEST EAX, 0x00000004  ; 检测EAX的第2位(从0开始计数)  
    JZ BIT_NOT_SET        ; ZF=1 → 第2位为0  
    ; 处理第2位为1的逻辑  
    
  • 高效判断零值

    TEST ECX, ECX  ; 等效于 CMP ECX, 0,但指令更短(2字节 vs 3字节)  
    JZ EMPTY_LOOP  ; ZF=1 → ECX=0,跳过循环  
    
5.4 实战案例:权限校验与边界检查
  • 文件权限校验(检查写权限)

    MOV EAX, [FILE_PERM]  ; 权限标志(如rwxr-xr-x = 0x1FF)  
    TEST EAX, 0x02        ; 检查第1位(写权限)  
    JZ NO_WRITE_ACCESS    ; ZF=1 → 无写权限  
    ; 执行写操作  
    
  • 数组越界检测

    MOV ECX, [INDEX]      ; 数组索引  
    MOV EDX, [ARRAY_SIZE] ; 数组大小  
    TEST ECX, ECX         ; 检测索引是否为负(SF=1表示负数)  
    JNS CHECK_UPPER_BOUND ; 非负则继续检查上限  
    JMP INDEX_ERROR       ; 索引为负,跳转错误处理  
    CHECK_UPPER_BOUND:  
    CMP ECX, EDX          ; 比较 INDEX < ARRAY_SIZE  
    JAE INDEX_ERROR       ; 越界则跳转  
    
5.5 性能对比:轻量级条件判断
  • 指令长度
    • 寄存器 - 立即数:2 字节(如 TEST AL, 0x01)。
    • 寄存器 - 寄存器:3 字节(如 TEST AX, BX)。
  • 执行速度
    • 单周期完成,比 CMP 指令略快(因无需保存临时结果)。
5.6 常见错误:避免结果误用
  1. 误以为 TEST 修改操作数

    TEST AL, 0x0F  ; 错误:认为AL被修改为0x0F?实际AL保持原值  
    ; 若需修改值,应使用AND指令  
    
  2. 混淆 ZF 标志的含义

    TEST AL, 0x01  ; ZF=1表示最低位为0(结果全0)  
    JNZ BIT_SET    ; 若ZF=0(结果非零),说明最低位为1  
    
5.7 优化建议:替代 CMP 的场景
  • 检测寄存器是否为 0

    TEST EAX, EAX  ; 比 CMP EAX, 0 更高效(少1字节,可能少1个微操作)  
    
  • 检测符号位

    TEST EAX, 0x80000000  ; 检测最高位(符号位)  
    JS IS_NEGATIVE        ; SF=1 → 负数  
    
5.8 一句话总结

TEST 指令是二进制世界的 “隐形探测器”,通过静默执行按位与运算,仅修改标志位而不改变原数据。其在权限校验、边界检查和条件判断中表现卓越 ——不改变数据,却能洞察一切!

三、逻辑运算与标志位的深度关系

标志位是 CPU 内部的特殊寄存器,反映指令执行后的状态。逻辑运算对标志位的影响非常规律:

1. 强制清零的标志位:CF 和 OF

  • CF(进位标志):逻辑运算不涉及进位,因此 CF 始终为 0
  • OF(溢出标志):逻辑运算不涉及符号数溢出,OF 始终为 0

2. 反映结果特性的标志位:ZF、SF、PF

  • ZF(零标志):结果全 0 时 ZF=1,否则 ZF=0
  • SF(符号标志):结果最高位为 1 时 SF=1(表示负数)
  • PF(奇偶标志):结果中 1 的个数为偶数时 PF=1,奇数时 PF=0

3. 标志位应用示例:

mov al, 10101010b  ; AL = 0xAA
and al, 00001111b  ; AL = 0x0A (1010b); 此时标志位状态:
; ZF = 0(结果不为0)
; SF = 0(最高位为0)
; PF = 1(1的个数为2,偶数)
; CF = 0(逻辑运算强制CF=0)
; OF = 0(逻辑运算强制OF=0)

四、逻辑运算的性能考量

  1. XOR 清零比 MOV 更高效

    xor ax, ax         ; 1个时钟周期
    mov ax, 0          ; 2个时钟周期(现代CPU可能优化)
    
  2. AND/OR/XOR 的执行速度

    • 均为单周期指令(现代 CPU)
    • 避免频繁访问内存操作数,优先使用寄存器
  3. TEST 比 CMP 更轻量

    test ax, ax        ; 仅影响标志位
    cmp ax, 0          ; 需执行减法运算
    

五、实战案例:用逻辑运算实现位操作

1. 提取 IP 地址的各段(假设 IP 存于 EAX)

; EAX = 0x0A0B0C0D (10.11.12.13)
mov ebx, eax        ; 复制IP到EBX
and ebx, 0xFF000000 ; 提取第一段 (0x0A000000)
shr ebx, 24         ; 右移24位 → EBX = 0x0000000A (10)mov ebx, eax        ; 重新复制IP
and ebx, 0x00FF0000 ; 提取第二段 (0x000B0000)
shr ebx, 16         ; 右移16位 → EBX = 0x0000000B (11); 以此类推提取第三段(0x0C)和第四段(0x0D)

2. 实现大小写转换(利用 ASCII 码规律)

; ASCII码:
; 'A'-'Z' = 0x41-0x5A (二进制:0100XXXX)
; 'a'-'z' = 0x61-0x7A (二进制:0110XXXX)
; 规律:大小写仅第5位不同(大写为0,小写为1)mov al, 'A'         ; AL = 0x41 (01000001b)
xor al, 00100000b   ; 翻转第5位 → AL = 0x61 ('a')mov al, 'b'         ; AL = 0x62 (01100010b)
xor al, 00100000b   ; 翻转第5位 → AL = 0x42 ('B')

3. 位图操作(假设用 AL 存储 8 个开关状态)

; AL = 00000000b (初始状态:所有开关关闭); 打开第3个开关(从右到左编号0-7)
or al, 00000100b    ; AL = 00000100b; 关闭第5个开关
mov bl, 00100000b   ; 掩码:00100000b
not bl              ; 取反:11011111b
and al, bl          ; AL = 00000100b; 切换第7个开关(开→关,关→开)
xor al, 10000000b   ; AL = 10000100b

六、常见误区与注意事项

  1. 逻辑运算 vs 算术运算

    • 逻辑运算(AND/OR/XOR)逐位操作,不考虑进位
    • 算术运算(ADD/SUB)会产生进位 / 借位,影响 CF 和 OF
  2. NOT 与 NEG 的区别

    mov al, 5          ; AL = 00000101b
    not al             ; AL = 11111010b (补码表示-6,但这是逻辑取反)mov al, 5
    neg al             ; AL = 11111011b (-5的补码,算术取负)
    
  3. XOR 交换值的局限性

    • 若两个操作数指向同一内存地址,会导致数据丢失
    mov ax, 5
    xor [var], [var]   ; 错误![var]会被清零
    

七、总结:逻辑运算的核心价值

  1. 位级控制:直接操作二进制位,实现精细控制(如硬件寄存器配置)
  2. 高效算法:利用位运算特性,实现比算术运算更高效的操作(如取模、交换)
  3. 内存优化:用单个字节存储 8 个布尔值(位图),节省内存空间
  4. 底层编程基础:操作系统、驱动开发中不可或缺的工具

掌握逻辑运算,就像获得了一把打开二进制世界的钥匙,让你能够直接与计算机最底层的信息表示方式对话。

相关文章:

  • NeRF PyTorch 源码解读 - NDC空间
  • 6.04打卡
  • 使用 React Native 开发鸿蒙(HarmonyOS)运动健康类应用的系统化准备工作
  • Axios学习笔记
  • 《高等数学》(同济大学·第7版)第一章第七节无穷小的比较
  • 稻米分类和病害检测数据集(猫脸码客第237期)
  • Springfox 和 Knife4j 集成404 问题
  • el-input限制输入数字,输入中文后数字校验失效
  • 回归任务和分类任务损失函数详解
  • 采用 Docker GPU 部署的 Ubuntu 或者 windows 桌面环境
  • el-table 树形数据,子行数据可以异步加载
  • 录制mp4
  • 【设计模式-4.8】行为型——中介者模式
  • OPENCV重点结构体Mat的讲解
  • C语言数据结构笔记3:Union联合体+结构体取8位Bool量
  • CentOS7关闭防火墙、Linux开启关闭防火墙
  • WebFuture:Ubuntu 系统上在线安装.NET Core 8 的步骤
  • OpenCV 键盘响应来切换图像
  • 实现C语言中srand()和rand()函数
  • .NET Core接口IServiceProvider
  • 慈利做网站在哪里/今天发生的重大新闻5条
  • 做下载网站赚钱/活动营销推广方案
  • 手机网站营销方案/优化大师官方免费
  • 网站logo怎么做/百度收录技巧
  • 重庆网站推广网络推广/互联网销售怎么做
  • 长沙网站建设方面/营销模式方案