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

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中的返回值
  • 输出时错误使用固定寄存器值,而非函数返回结果

调试建议

  1. 单独验证C函数:编写纯C测试程序,调用checkPrimeNumber传入不同数值(如2、3、4、5),确认返回值是否符合预期(质数返回非0,非质数返回0)
  2. 断点监控寄存器:在汇编的bl checkPrimeNumber指令前后添加断点:
    • 调用前检查r0是否为当前要判断的数字
    • 调用后检查r0的返回值是否符合预期
  3. 检查栈操作:确认调用函数前sp是8字节对齐,且必要寄存器已正确保存/恢复
  4. 验证输出逻辑:确认输出的是r0中的返回值,而非固定值

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 04:27:33