使用FASM编写的for循环为何陷入无限循环?
问题分析与修复
无限循环的核心原因
你的代码里循环计数器被系统调用的寄存器操作直接覆盖了:
- 你用
ax存储循环计数器(初始值8) - 但循环体里执行
mov eax,4(32位write系统调用号)时,整个eax寄存器被设为4,而ax是eax的低16位,这直接把之前的计数器值冲没了 - 之后
sub ax,1把ax变成3,下次循环判断cmp ax,0时永远是3,永远不会触发.exit分支,自然陷入无限循环
修复方案
- 把计数器放到不会被系统调用修改的寄存器:比如
bx、cx,或者存在内存里,避开系统调用要用到的eax、ebx等寄存器 - (可选)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
相关产品推荐
相关产品推荐

