ARM32汇编实现int power(int n,int m)函数错误排查求助
问题排查与修复
你的ARM32汇编实现的power函数存在多个关键错误,导致输出不符合预期,以下是具体问题和修复方案:
错误点分析
参数寄存器完全混淆
ARM32 APCS调用约定中,int power(int n, int m)的参数传递规则是:第一个参数n存入r0,第二个参数m存入r1。但你的代码错误地将m对应到未使用的r2,同时把r1(本该是m)赋值给r4当初始值,这直接导致循环条件cmp r2, r3永远是0和0比较,触发beq end直接返回,最终返回错误的初始值。非易失性寄存器未保存
r4属于ARM APCS中的非易失性寄存器,函数调用者依赖其值保持不变,你的代码未在函数开头将r4压栈保存,会破坏调用者的上下文。结果赋值语句不可达
mov r0, r4被放在b loop和end标签之间,当循环触发beq end跳转时,这条语句永远不会被执行,导致返回的r0还是函数传入的初始值。幂运算初始值逻辑错误
当m=0时,任何数的0次幂应为1;当m>=1时,初始值应设为1(然后乘n共m次),你的代码初始值设为r1(m)完全错误。
修复后的汇编代码
@ int power(int n, int m) @ r0 = n, r1 = m .text .align 2 .global power power: stmfd sp!, {fp, lr, r4} @ 保存非易失性寄存器r4,以及fp、lr mov fp, sp mov r3, #0 @ 循环计数器初始化为0 mov r4, #1 @ 结果初始化为1(处理m=0的情况) loop: cmp r3, r1 @ 比较计数器和m beq end @ 计数器等于m时退出循环 mul r4, r4, r0 @ r4 = r4 * n add r3, r3, #1 @ 计数器+1 b loop @ 回到循环开头 end: mov r0, r4 @ 将结果存入r0(返回值寄存器) ldmfd sp!, {fp, lr, r4} @ 恢复寄存器 bx lr @ 返回(等价于Ldmfd sp!, {fp,pc},更规范)
验证说明
修复后的代码遵循ARM32调用约定,处理了以下场景:
- 当
m=0时,直接返回1 - 当
m>=1时,循环m次,将1乘以n共m次得到结果 - 正确保存和恢复非易失性寄存器,避免破坏调用者上下文
对于你的测试用例power(4,2),会计算144=16;power(5,2)会计算155=25,符合预期输出。
内容的提问来源于stack exchange,提问作者Marko Petrovic
相关产品推荐
相关产品推荐

