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
修复说明
- 添加临时缓冲区:在
.data段新增temp_char字节,用于存储转换后的ASCII字符,给sys_write提供合法的内存地址。 - 修正sys_write参数:将余数存入
rdx的低8位(dl),转换为ASCII后写入缓冲区,再将缓冲区地址传给rsi。 - 修正退出调用:使用64位标准的
sys_exit调用(rax=60,rdi=0为正常退出码),替换错误的32位int 80h。 - 移除冗余代码:删除LOOP中无用的
mov rcx, rax。
运行修复后的代码,会输出546的二进制值1000100010。
内容的提问来源于stack exchange,提问作者berti
相关产品推荐
相关产品推荐

