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

NASM汇编入门求助:十进制转二进制程序无输出问题排查

十进制转二进制程序无输出的问题分析与修复

你的汇编程序无输出的核心问题是对64位Linux系统调用的参数理解错误,同时存在退出方式不匹配的问题,以下是具体问题和修复方案:

核心问题点

  • sys_write参数错误:LOOP2中,你将ASCII字符值直接放入rsi,但64位sys_write的rsi要求是指向输出字符的内存地址,而非字符本身。这会导致内核尝试访问非法内存,调用失败。
  • 退出调用不匹配:END段使用32位的int 80h调用,但代码是64位汇编(使用64位寄存器和syscall指令),调用规范不兼容,可能导致程序异常终止。
  • 冗余代码:LOOP中的mov rcx, rax完全多余,div rcx执行后商已存在rax中,无需额外存储。

修复后的代码

section .data
    decimal:     db  "enter decimal"
    decimalLen:  equ $-decimal
    binaer: db 'Binary equivalent',10
    binaerLen: equ  $-binaer
    nummer  dq 546
    zaehler  dq 0
    temp_char db 0  ; 临时存储单个二进制字符

section .text
    global _start

_start:
    and rsp, -16  ; 栈对齐,64位调用要求栈指针16字节对齐
    mov rax,[nummer]
    mov r8,[zaehler]

LOOP:
    cmp rax,0
    je LOOP2
    inc r8
    xor rdx,rdx
    mov rcx,2
    div rcx
    push rdx       ; 压入余数(0或1)
    jmp LOOP

LOOP2:
    cmp r8,0
    je END
    dec r8
    pop rdx        ; 取出余数到rdx
    add dl, '0'    ; 转换为ASCII字符,用dl避免破坏高位
    mov [temp_char], dl  ; 存入临时缓冲区
    ; 调用sys_write输出单个字符
    mov rax,1
    mov rdi,1
    mov rsi, temp_char  ; 传递字符的内存地址
    mov rdx,1
    syscall
    jmp LOOP2

END:
    ; 64位正确退出调用:sys_exit
    mov rax,60
    mov rdi,0
    syscall

修复说明

  1. 添加临时缓冲区:在.data段新增temp_char字节,用于存储转换后的ASCII字符,给sys_write提供合法的内存地址。
  2. 修正sys_write参数:将余数存入rdx的低8位(dl),转换为ASCII后写入缓冲区,再将缓冲区地址传给rsi。
  3. 修正退出调用:使用64位标准的sys_exit调用(rax=60,rdi=0为正常退出码),替换错误的32位int 80h。
  4. 移除冗余代码:删除LOOP中无用的mov rcx, rax。

运行修复后的代码,会输出546的二进制值1000100010。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 17:35:15