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

x86 MASM从内存提取5位编码并转ASCII的实现方法问询

提取5位简化ASCII并转换的MASM实现

核心思路

内存以字节(8位)为最小寻址单位,5位字符会跨字节存储,因此需要维护位偏移计数器跟踪当前从字节的哪一位开始提取。每次提取5位后更新偏移量;若偏移量超过8,则切换到下一个字节并调整偏移值。循环提取直到遇到00000b结束符,最后在EDI指向地址写入00H作为终止标记。

具体代码实现

; 初始化寄存器
    XOR     ECX, ECX          ; ECX = 位偏移量(0-7,初始为0)
    MOV     EDX, 0            ; EDX 暂存当前拼接的5位数据

extract_loop:
    ; 读取当前ESI指向的字节
    MOV     AL, [ESI]
    ; 计算当前字节剩余可提取位数
    MOV     EBX, 8
    SUB     EBX, ECX          ; EBX = 当前字节剩余位数
    CMP     EBX, 5
    JGE     extract_full_five ; 剩余位足够5位,直接提取

    ; 剩余位不足5位,先提取剩余EBX位
    MOV     CL, BL
    SHL     AL, CL            ; 有效位移至高位
    SHR     AL, 3             ; 保留对应位到高5位区域
    OR      EDX, EAX          ; 拼接到暂存寄存器
    ADD     ECX, EBX          ; 更新偏移量
    INC     ESI               ; 切换到下一个字节
    ; 从下一个字节补全剩余(5-EBX)位
    MOV     AL, [ESI]
    MOV     CL, 5
    SUB     CL, BL
    SHL     AL, 8 - CL        ; 需要的位移至高位
    SHR     AL, 3             ; 保留到高5位区域
    OR      EDX, EAX
    MOV     ECX, CL           ; 更新偏移量为已用位数
    JMP     check_value

extract_full_five:
    ; 从当前字节直接提取5位
    MOV     CL, ECX
    SHL     AL, CL            ; 起始位移至最高位
    SHR     AL, 3             ; 右移3位得到完整5位值
    MOV     EDX, EAX          ; 保存提取结果
    ADD     ECX, 5            ; 更新偏移量
    CMP     ECX, 8
    JL      check_value       ; 偏移未超8,无需切换字节
    SUB     ECX, 8            ; 偏移超8,重置为剩余值
    INC     ESI               ; 切换到下一个字节

check_value:
    ; 判断是否为结束符00000b
    CMP     EDX, 0
    JE      end_conversion
    ; 转换为标准ASCII:加60H
    ADD     DL, 60H
    ; 存储到EDI指向地址
    MOV     [EDI], DL
    INC     EDI
    ; 重置暂存寄存器,准备下一次提取
    XOR     EDX, EDX
    JMP     extract_loop

end_conversion:
    ; 写入结束符00H
    MOV     BYTE PTR [EDI], 0

代码说明

  • 位偏移跟踪:通过ECX记录当前字节内的偏移位置(0-7),每次提取后更新,偏移量超过8时自动切换字节并重置。
  • 跨字节拼接:当当前字节剩余位数不足5位时,先提取剩余位,再从下一字节补全剩余位数,通过移位操作拼接成完整的5位值。
  • 终止逻辑:提取到00000b时终止循环,在EDI写入00H作为标准ASCII字符串的结束标记。

示例验证

针对输入[ESI] = 00011 00010 11010 00000b(内存字节存储为00011000 10110100 ...):

  1. 第一次提取00011b,加60H得到01100011b(ASCII 'c')存入EDI;
  2. 第二次提取00010b,加60H得到01100010b(ASCII 'b')存入EDI;
  3. 第三次提取11010b,加60H得到01111010b(ASCII 'z')存入EDI;
  4. 提取到00000b后终止循环,写入00H结束符,最终EDI内容与示例完全匹配。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 19:45:48