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

NASM x86_64 Linux递增循环打印代码故障排查请求

问题排查与修复方案

咱们一步步拆解你代码里的问题并修复——你这里混淆了32位和64位系统调用规则,对write系统调用的寄存器用法有误解,还缺少了数值初始化与ASCII转换的关键环节,导致代码无法正常运行。


核心问题分析

1. 错误的系统调用号

在x86_64 Linux环境中,syscall指令使用的系统调用号和32位的int 0x80完全不同:

  • 32位下write的调用号是4,但64位下write的调用号是1。你设置mov rax,4会触发错误的系统调用(实际是sys_writev),直接导致行为异常。

2. 对rsi寄存器的用途理解错误

write系统调用的64位参数规则是:

  • rax=1:调用号(标识要执行write)
  • rdi=1:文件描述符(stdout,这部分你是对的)
  • rsi:指向要写入数据的内存指针,而非你要打印的数值本身
  • rdx:写入的字节数(你设的1是对的,因为要打印单个字符)

你把rsi当成了要递增的数值来操作,直接add rsi,1后作为指针传入write,这会让程序访问随机内存地址(程序启动时rsi初始值未定义),大概率触发段错误。

3. 未初始化计数寄存器

程序启动时通用寄存器的初始值是未定义的,直接对rsi做递增操作会得到随机起始值,完全不符合你“从1开始打印10次”的预期。

4. 缺少整数到ASCII的转换

整数1的二进制值是0x01,对应ASCII不可见控制字符;要打印可见的数字字符,必须把整数加上0x30(即ASCII的'0'),比如1→0x31(对应字符'1')。


修复后的代码(实现打印1-10的可见数字)

section .data
    digit      db 0    ; 存储转换后的单个数字字符
    char_one   db '1'  ; 用于打印10的十位
    char_zero  db '0'  ; 用于打印10的个位

section .text
global _start
_start:
    mov rcx, 1          ; 用rcx作为计数器,从1开始初始化
loop:
    ; 处理两位数(这里仅需处理10)
    cmp rcx, 10
    jl print_single_digit

    ; 打印10的十位'1'
    mov rax, 1
    mov rdi, 1
    mov rsi, char_one
    mov rdx, 1
    syscall
    ; 打印10的个位'0'
    mov rax, 1
    mov rdi, 1
    mov rsi, char_zero
    mov rdx, 1
    syscall
    jmp update_counter

print_single_digit:
    ; 把整数转换为ASCII字符
    mov rax, rcx
    add rax, 0x30
    mov [digit], rax
    ; 调用write打印字符
    mov rax, 1
    mov rdi, 1
    mov rsi, digit
    mov rdx, 1
    syscall

update_counter:
    inc rcx
    cmp rcx, 11         ; 计数到11时停止(共打印1-10十次)
    jne loop

exit:
    mov rax, 60         ; exit系统调用号(这部分你是对的)
    xor rdi, rdi        ; 退出码0
    syscall

代码关键修改说明

  1. 新增.data段存储字符数据,给write提供合法的内存指针;
  2. 改用rcx作为计数寄存器,避免占用write需要的rsi指针寄存器;
  3. 初始化计数器为1,消除未定义值的影响;
  4. 添加整数到ASCII的转换逻辑,确保打印可见数字;
  5. 单独处理10的两位数打印,符合预期输出;
  6. 修正write的系统调用号为64位正确值1。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 04:22:52