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

scanf转换成功后仍触发jl跳转?函数是否依返回值设置FLAGS?

问题分析与修复方案

代码中的核心错误

  • 寄存器拼写错误:movl $var, %edin: 存在笔误,正确写法是 movl $var, %edx,且末尾多余的冒号需删除。
  • 缺失循环入口标签:代码中使用 jmp in 跳转,但未定义 in 标签,导致第一次执行后无法进入循环逻辑。
  • 栈清理时机错误:调用 scanf 后未立即清理栈,直接进行条件判断和跳转,会造成栈溢出,进而干扰 scanf 返回值的正确性。

修复后的代码

.global main
main:
    movl $var, %edx  # 修正寄存器拼写,移除多余冒号
in:                  # 添加循环入口标签
    push %edx        # 压入当前存储输入的地址
    push $inp        # 压入格式串地址
    call scanf
    add $8, %esp     # 调用者清理栈,弹出两个参数
    jl done          # 返回值<0(EOF或输入错误)时跳转到结束
    add $4, %edx     # 指针移动到下一个int位置
    jmp in           # 继续循环读取输入
done:
    movl $0, %eax    # main函数正常返回0
    ret

.data
inp: .asciz "%d"
var: .space 4*100    # 分配100个int的存储空间

关键说明

  • scanf返回值逻辑:scanf 返回成功读取的参数个数,当输入非数字字符或遇到EOF时,会返回 EOF(通常为-1),此时jl done会触发跳转,终止循环。
  • 栈管理规则:cdecl调用约定要求调用者负责清理栈,因此每次调用scanf后必须用add $8, %esp清理压入的两个参数,避免栈数据堆积破坏程序执行环境。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 14:20:59