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

使用FASM编写的for循环为何陷入无限循环?

问题分析与修复

无限循环的核心原因

你的代码里循环计数器被系统调用的寄存器操作直接覆盖了:

  • 你用ax存储循环计数器(初始值8)
  • 但循环体里执行mov eax,4(32位write系统调用号)时,整个eax寄存器被设为4,而ax是eax的低16位,这直接把之前的计数器值冲没了
  • 之后sub ax,1把ax变成3,下次循环判断cmp ax,0时永远是3,永远不会触发.exit分支,自然陷入无限循环

修复方案

  1. 把计数器放到不会被系统调用修改的寄存器:比如bx、cx,或者存在内存里,避开系统调用要用到的eax、ebx等寄存器
  2. (可选)ELF64程序建议用64位系统调用(syscall指令)替代32位的int 0x80,避免寄存器宽度不匹配的潜在问题

修复后的代码

format ELF64 executable 3
segment readable executable
entry main

main:
        mov bx, 8       ; 用bx存计数器,不会被write调用覆盖
        jmp .loop
.loop:
        cmp bx, 0
        je .exit
        ; 64位write系统调用:rax=1(write), rdi=1(stdout), rsi=msg, rdx=12(长度)
        mov rax, 1
        mov rdi, 1
        mov rsi, msg
        mov rdx, 12     ; "Hello World\n"共12字节,原代码11会截断输出
        syscall
        sub bx, 1
        jmp .loop
.exit:
        mov rax, 60     ; 64位exit系统调用号是60,不是32位的1
        mov rdi, 0
        syscall

segment readable writable
msg db  "Hello World", 10, 0

额外注意点

  • 原代码中消息长度写11是错误的,"Hello World"加换行符一共12字节,会导致输出最后少一个字符
  • 32位int 0x80调用在64位程序中可以运行,但容易出现寄存器溢出或值被覆盖的问题,更推荐遵循64位系统调用规范

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 04:28:13