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

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

代码说明

  1. 缓冲区设计:4字节缓冲区预留了存储3位十进制数和字符串结束符的空间,从后往前存储拆分出的每一位,最后正向输出即可得到正确顺序的十进制字符串。
  2. 数值拆分:通过div 10将十六进制数值逐位拆分,余数转为ASCII字符后存入缓冲区,直到商为0停止循环。
  3. 长度计算:用缓冲区末尾地址减去当前起始地址,得到实际要写入的字符数,避免写入多余的占位符。
  4. 系统调用:使用Linux的sys_write系统调用,将转换后的十进制字符串写入目标文件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 07:50:25