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

NASM汇编实现十进制转二进制:除法存余数遇段错误求助

问题分析与修复

你的代码触发段错误主要有几个核心问题,逐个解决:

错误点1:字符串未转成整数就执行除法

dec_input是用户输入的十进制字符串(比如"123"),你直接把它的内存地址放到eax里执行div ebx,相当于用一个超大的地址数值做除法,完全不符合逻辑——必须先把字符串格式的十进制数转换为整数。

错误点2:余数未转成ASCII字符

div ebx得到的余数edx是数值0或1,直接存入binary_res的话,存储的是0x00或0x01(非打印字符),而且最终字符串没有以0h结尾,调用str_print时会越界访问内存,触发段错误。

错误点3:系统调用常量可能未定义

如果functions.asm里没定义SYS_READ(值为3)、STDIN(值为0),直接用这些符号会导致系统调用参数错误,引发异常。


修复后的完整代码

先补充字符串转整数的函数(可放入functions.asm)

; 字符串转整数:ebx=字符串地址,返回eax=整数数值
str_to_int:
    xor eax, eax    ; 初始化结果为0
    xor ecx, ecx
str_to_int_loop:
    mov cl, [ebx]   ; 取当前字符
    cmp cl, 0h      ; 遇到终止符结束
    je str_to_int_end
    cmp cl, 0Ah     ; 遇到输入时的换行符也结束
    je str_to_int_end
    sub cl, '0'     ; 字符转数值
    imul eax, 10    ; 结果*10
    add eax, ecx    ; 加上当前位数值
    inc ebx         ; 移动到下一个字符
    jmp str_to_int_loop
str_to_int_end:
    ret

主程序修正

%include    'functions.asm'

section .data
    ip_prompt   db  "Enter a decimal number to be converted to binary: ", 0h
    binary_res  db  32 dup('0'), 0h  ; 提前加字符串终止符,避免越界

section .bss
    dec_input resb 32    

section .text
    global _start
    
_start:
    mov     eax, ip_prompt
    call    str_print

    ; 直接用数值调用系统读取,避免常量未定义问题
    mov     eax, 3       ; SYS_READ
    mov     ebx, 0       ; STDIN
    mov     ecx, dec_input
    mov     edx, 32
    int     80h

    mov     eax, dec_input
    call    str_print

    ; 将输入的字符串转为整数
    mov ebx, dec_input
    call str_to_int

    mov ecx, 0
    mov ebx, 2
convert_to_bin:
    xor edx, edx    ; 每次div前必须清零edx,避免旧余数干扰
    div     ebx
    add     dl, '0'  ; 把余数转成ASCII字符(取edx低8位操作)
    mov     [binary_res + ecx], dl
    inc     ecx
    cmp     eax, 0
    jne     convert_to_bin

    ; 可选:反转字符串得到正常顺序的二进制(当前存储的是逆序,余数先存最低位)
    mov eax, binary_res
    mov edx, ecx    ; ecx是二进制位数,传入反转函数
    call reverse_str

    mov     eax, binary_res
    call    str_print_endl

    call    quit

可选:添加字符串反转函数(得到高位在前的二进制)

如果需要输出正常顺序的二进制,补充反转函数到functions.asm:

; 反转字符串:eax=字符串地址,edx=字符串长度
reverse_str:
    push ebx
    push esi
    push edi
    mov esi, eax
    mov edi, eax
    add edi, edx
    dec edi         ; edi指向最后一个有效字符
reverse_loop:
    cmp esi, edi
    jge reverse_end
    mov bl, [esi]
    mov cl, [edi]
    mov [esi], cl
    mov [edi], bl
    inc esi
    dec edi
    jmp reverse_loop
reverse_end:
    pop edi
    pop esi
    pop ebx
    ret

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 08:25:32