You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过逻辑运算高效检测通用寄存器中的零字节

通用寄存器零字节高效检测方法

针对存储多字节ASCII序列的通用寄存器,无需逐位移位、逐字节遍历,仅用3次基础位运算即可完成零字节存在性判定,所有操作均为单CPU周期级别,性能远高于逐字节检查逻辑。

核心实现逻辑

整个检测流程无分支、无循环,步骤如下:

  1. 根据寄存器位宽准备两个固定魔数:
    • 减法魔数:每个字节均为0x01,即n位寄存器对应值为0x0101...01(总长度为n/8个0x01)
    • 掩码魔数:每个字节最高位为1、其余位为0,即n位寄存器对应值为0x8080...80(总长度为n/8个0x80)
  2. 对寄存器存储的目标值x做运算:(x - 减法魔数) & (~x) & 掩码魔数
  3. 判定运算结果:
    • 结果为0:不存在零字节
    • 结果非0:存在零字节

不同常见位宽寄存器对应的魔数参考:

  • 16位寄存器:减法魔数0x0101,掩码魔数0x8080
  • 32位寄存器(如eax):减法魔数0x01010101,掩码魔数0x80808080
  • 64位寄存器(如rax):减法魔数0x0101010101010101,掩码魔数0x8080808080808080

效果验证

用题目给出的两个32位场景示例验证:

示例1:待检测值为0x7172706b,无零字节

  1. 计算x - 0x01010101 = 0x7172706b - 0x01010101 = 0x70716f6a
  2. 计算~x = ~0x7172706b = 0x8e8d8f94
  3. 做与运算:0x70716f6a & 0x8e8d8f94 & 0x80808080 = 0,结果为0,判定无零字节,符合预期。

示例2:待检测值为0x7172006b,存在零字节

  1. 计算x - 0x01010101 = 0x7172006b - 0x01010101 = 0x7171ff6a
  2. 计算~x = ~0x7172006b = 0x8e8dff94
  3. 做与运算:0x7171ff6a & 0x8e8dff94 & 0x80808080 = 0x00008000,结果非0,判定存在零字节,符合预期。

原理说明

对任意单字节值:

  • 如果字节值在0x01~0xFF(非零),减1操作产生的借位不会传递到该字节的最高位(即0x80对应的比特位),和~x、掩码魔数做与运算后,该字节最高位结果一定为0
  • 如果字节值为0x00,减1操作会产生连续借位,最终将该字节的最高位置为1,和~x、掩码魔数做与运算后,该字节最高位结果为1
    最终只要提取到任意一个字节的最高位为1,就说明对应位置原本是零字节。

汇编实现参考(64位场景)

; 入参:rax存储待检测的ASCII字节序列
; 出参:ZF标志位为1表示无零字节,ZF为0表示存在零字节
mov     rbx, rax
mov     rcx, 0x0101010101010101
mov     rdx, 0x8080808080808080
sub     rbx, rcx
not     rax
test    rbx, rax
test    rbx, rdx
; 后续可直接通过jz/jnz指令跳转处理对应逻辑

内容的提问来源于stack exchange,提问作者Ben Heckmann

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.02 07:18:17