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 ...):
- 第一次提取
00011b,加60H得到01100011b(ASCII 'c')存入EDI; - 第二次提取
00010b,加60H得到01100010b(ASCII 'b')存入EDI; - 第三次提取
11010b,加60H得到01111010b(ASCII 'z')存入EDI; - 提取到
00000b后终止循环,写入00H结束符,最终EDI内容与示例完全匹配。
内容的提问来源于stack exchange,提问作者roditu
相关产品推荐
相关产品推荐

