ARM汇编test函数实现求助:调用bit_pos返回结果和未通过测试
问题:ARM汇编test函数无法通过测试用例
需求
编写等价于以下C代码的ARM汇编test函数:
int test( unsigned int v1, unsigned int v2 ) { int res1, res2; res1 = bit_pos( v1 ); res2 = bit_pos( v2 ); return res1 + res2; }
要求test接收r0(v1)和r1(v2)作为参数,两次调用bit_pos后返回结果之和。已知bit_pos功能正常,但test始终无法通过测试。
当前汇编代码
.arch armv4 .syntax unified .arm .text .align 2 .type bit_pos, %function .global bit_pos bit_pos: mov r1,r0 mov r0, #1 top: cmp r1,#0 beq done add r0,r0,#1 lsr r1, #1 b top done: mov pc, lr .align 2 .type test, %function .global test test: push {r0, r1, r2, lr} mov r0, #0x80000000 bl bit_pos mov r1, r0 mov r0, #0x00000001 bl bit_pos mov r2, r0 pop {r0, r1, r2, lr} mov pc, lr
尝试过的其他test实现
test: push {r4, lr} mov r4, r0 bl bit_pos bl bit_pos add r0, r4 pop {r4, lr} mov pc, lr
测试用例及失败情况
测试用例
checking 5 20 res=6 checking 1 0 res=-1 checking 175 100000 res=21
第一次尝试失败
checking 5 20 res=5 got 5, expected 6
当前尝试失败
checking 5 20 res=6 checking 1 0 res=0 got 0, expected -1 Test failed
问题分析与修正
问题点
- 第一个
test实现硬编码了固定值作为bit_pos参数,完全未使用传入的r0(v1)和r1(v2),必然无法匹配测试用例。 - 第二个
test实现存在两处致命错误:- 第一次调用
bit_pos后r0被覆盖为res1,第二次调用时错误地将res1作为参数传入,而非原始的v2。 - 最终将
res2与原始v1相加,而非正确的res1 + res2。
- 第一次调用
- 额外注意:
bit_pos会修改r1寄存器,因此必须提前保存v2的值,避免被破坏。
正确的test实现
test: push {r4, lr} ; 保存非易失寄存器r4和返回地址lr mov r4, r1 ; 保存v2到r4,防止被bit_pos修改 bl bit_pos ; 调用bit_pos(v1),结果存入r0(res1) mov r1, r0 ; 暂存res1到r1 mov r0, r4 ; 将v2作为参数传入r0 bl bit_pos ; 调用bit_pos(v2),结果存入r0(res2) add r0, r0, r1 ; 计算res1 + res2,存入r0作为返回值 pop {r4, lr} ; 恢复寄存器 mov pc, lr ; 返回
补充说明(针对测试用例1和0返回-1的情况)
如果bit_pos处理输入0时需要返回-1,当前bit_pos代码存在逻辑错误,需修改如下:
bit_pos: cmp r0, #0 ; 先判断输入是否为0 beq return_neg1 ; 是则返回-1 mov r1, r0 mov r0, #1 top: cmp r1, #1 ; 判断是否只剩最高位1 beq done add r0, r0, #1 lsr r1, #1 b top return_neg1: mov r0, #-1 ; 设置返回值为-1 done: mov pc, lr
内容的提问来源于stack exchange,提问作者Jeff924D
相关产品推荐
相关产品推荐

