ARM汇编main.s与checkPrimeNumber.c联动异常:输入数字恒输出1
ARM汇编调用C质数判断函数,输出始终为1的问题排查
问题背景
我实现了一个ARM汇编程序main.s,配合C语言的checkPrimeNumber.c完成以下功能:提示用户输入两个正整数,输出两者之间的所有质数(示例:输入2和6,预期输出3、5)。逻辑上在汇编的main中调用C函数checkPrimeNumber判断每个数是否为质数,但目前无论输入什么数字,程序运行后只输出1。已通过调试器调整寄存器,但问题未解决,不确定是内存分配错误还是比较逻辑问题,附上代码:
代码片段
main.s
; 此处为用户实际编写的ARM汇编代码 .global main .extern printf .extern scanf .extern checkPrimeNumber main: ; 输入处理、循环遍历区间逻辑 ; 调用checkPrimeNumber判断当前数是否为质数 bl checkPrimeNumber ; 输出逻辑 mov r1, r0 ldr r0, =output_fmt bl printf b exit output_fmt: .asciz "%d\n" exit: mov r7, #1 swi 0
checkPrimeNumber.c
#include <stdio.h> int checkPrimeNumber(int num) { // 用户编写的质数判断逻辑 if (num <= 1) return 0; for (int i = 2; i * i <= num; i++) { if (num % i == 0) return 0; } return 1; }
核心排查方向
1. ARM函数调用ABI合规性问题
ARM架构遵循AAPCS(ARM架构过程调用标准),调用C函数时必须遵守规则,否则会导致参数传递或返回值读取错误:
- 整型参数通过
r0-r3传递:要判断的数字必须放入r0寄存器后,再调用checkPrimeNumber - 返回值存储在
r0:调用完成后,r0即为函数返回结果,必须正确读取该值用于后续逻辑 - 栈对齐要求:调用函数前,栈指针
sp必须保持8字节对齐,否则会引发内存访问异常,间接导致返回值异常 - 寄存器保存:如果汇编中使用了
r4-r11这类被调用者保存寄存器,必须在调用前压栈保存,调用后恢复
2. C函数逻辑错误
如果checkPrimeNumber本身逻辑有误,会导致返回值始终为1:
- 边界条件处理错误:比如将1、0这类非质数误判为质数返回1
- 循环逻辑错误:比如循环终止条件写错,导致所有输入都返回1
- 返回值语义搞反:比如函数用1表示非质数、0表示质数,但汇编逻辑将返回1当作质数输出
3. 汇编输出逻辑错误
如果汇编代码忽略checkPrimeNumber的返回值,直接输出固定值1,也会出现问题:
- 硬编码输出1,而非读取
r0中的返回值 - 输出时错误使用固定寄存器值,而非函数返回结果
调试建议
- 单独验证C函数:编写纯C测试程序,调用
checkPrimeNumber传入不同数值(如2、3、4、5),确认返回值是否符合预期(质数返回非0,非质数返回0) - 断点监控寄存器:在汇编的
bl checkPrimeNumber指令前后添加断点:- 调用前检查
r0是否为当前要判断的数字 - 调用后检查
r0的返回值是否符合预期
- 调用前检查
- 检查栈操作:确认调用函数前
sp是8字节对齐,且必要寄存器已正确保存/恢复 - 验证输出逻辑:确认输出的是
r0中的返回值,而非固定值
内容的提问来源于stack exchange,提问作者Cartoon
相关产品推荐
相关产品推荐

