8086 YASM环境下如何将十六进制计数转为十进制写入文件
问题描述
处理一个格式固定的文本文件:
- 文件行数范围:0-1000行
- 每行包含6列,列间用分号分隔:
- 第1、2列:由字母、数字、空格组成的字符串,长度1-20个字符
- 第3-5列:取值范围-100到100的整数
- 第6列:取值范围-9.99到9.99的两位小数
需求:统计前两列不含字母B/b/C/c的行数,将统计结果写入另一个文件。
已完成大部分处理逻辑,但卡在统计数lineCount的输出环节:内存中lineCount以十六进制形式存储,需要将其转为十进制,并根据数值的实际位数(1-3位)写入目标文件,不知如何实现。
十六进制转十进制并写入文件的YASM实现方案
核心逻辑是通过取余+除法拆分十六进制数值为十进制各位,转为ASCII字符后按正确顺序写入文件。
实现代码片段
; 假设统计数lineCount已加载至eax寄存器(范围0-1000,十六进制存储) section .bss decBuffer resb 4 ; 缓冲区:最多存3位十进制数+结束符 section .text ; 转换并写入文件的函数 convert_write: mov ecx, 10 ; 十进制基数,用作除数 mov edi, decBuffer + 3 ; 从缓冲区末尾开始存储(倒序存各位) mov byte [edi], 0 ; 写入字符串结束符 convert_loop: xor edx, edx ; 清空edx,为除法做准备 div ecx ; eax = eax / 10,edx = eax % 10(余数) add dl, '0' ; 将余数转为ASCII字符 dec edi ; 指针前移,准备存下一位 mov [edi], dl ; 存储当前十进制位的ASCII值 test eax, eax ; 判断商是否为0 jnz convert_loop ; 商不为0,继续拆分 ; 调用sys_write写入文件(假设目标文件描述符已存在于ebx) write_result: mov eax, 4 ; Linux sys_write系统调用号 mov ecx, edi ; 待写入字符串的起始地址 mov edx, decBuffer + 3 - edi ; 计算实际写入长度(1-3位) int 0x80 ; 触发系统调用 ret
代码说明
- 缓冲区设计:4字节缓冲区预留了存储3位十进制数和字符串结束符的空间,从后往前存储拆分出的每一位,最后正向输出即可得到正确顺序的十进制字符串。
- 数值拆分:通过
div 10将十六进制数值逐位拆分,余数转为ASCII字符后存入缓冲区,直到商为0停止循环。 - 长度计算:用缓冲区末尾地址减去当前起始地址,得到实际要写入的字符数,避免写入多余的占位符。
- 系统调用:使用Linux的
sys_write系统调用,将转换后的十进制字符串写入目标文件。
内容的提问来源于stack exchange,提问作者Kurbamit
相关产品推荐
相关产品推荐

