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

.586汇编下使用gets()获取字符串转十进制的实现问题

x86(.586 32位)汇编字符串转十进制数值实现方案

你提到的两个基础认知都是正确的:

  1. 标准C库的gets()函数调用完成后,输入字符串的首地址确实会存储在eax寄存器中
  2. 单个ASCII数字字符转对应十进制值的核心操作就是减去48(即ASCII编码中'0'的编码值0x30),这个思路没有问题,你测试未生效通常是缺少了多位数的累加处理逻辑,或操作对象错误导致的。

完整转换步骤

  • 首先初始化寄存器:用ecx作为字符串遍历指针,初始赋值为eax的值;用ebx存储最终转换得到的整数,初始设为0
  • 进入循环逐位处理:
    1. 读取ecx指针指向的1字节内容到8位寄存器dl,判断该值是否为0x0(字符串结束符'\0'),若是则结束转换
    2. 将ebx中当前存储的数值乘以10,给新的数位腾出个位空间
    3. 将dl中的ASCII字符减去'0'(即48),得到当前位的十进制数值
    4. 将转换后的数值零扩展为32位后,累加至ebx中
    5. ecx自增1,指向下一个字符,回到循环开头
  • 转换完成后,ebx中存储的就是输入字符串对应的十进制整数

常见错误排查(对应你提到的减48未生效的场景):

  1. 操作对象错误:直接对eax寄存器本身(存储的是字符串地址)做减法,而非对eax指向的内存地址中的字符值做减法
  2. 缺少进位逻辑:仅对单个字符做了减法,未执行乘10累加的操作,只能得到单个字符对应的数值,无法得到多位数的完整结果
  3. 未做结束判断:遍历到字符串结束符后仍继续读取后续内存的垃圾值,导致最终结果异常

示例核心代码(NASM语法,32位环境)

; 调用gets()后,eax已存储输入字符串首地址
mov ecx, eax        ; 初始化字符串遍历指针
xor ebx, ebx        ; 最终结果寄存器清零

convert_loop:
    mov dl, [ecx]       ; 读取当前字符到dl
    test dl, dl         ; 判断是否为字符串结束符
    jz convert_done     ; 是结束符则跳出循环
    imul ebx, ebx, 10   ; 现有结果乘10
    sub dl, '0'         ; ASCII字符转十进制数字
    movzx edx, dl       ; 8位值零扩展为32位,避免加法溢出
    add ebx, edx        ; 累加当前位到结果
    inc ecx             ; 指针后移一位
    jmp convert_loop

convert_done:
; 此时ebx寄存器中即为转换完成的十进制整数

如果按照上述逻辑调整后仍然无法得到正确结果,你可以附上你的完整代码拆解内容做进一步排查。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 16:15:08