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
相关产品推荐
相关产品推荐

