ARM32汇编执行至第9行时SP寄存器值求解问题
ARM32栈操作与SP寄存器值计算问题
问题描述
初始栈顶地址为0x00000000,从第一行开始执行下方ARM32汇编代码,请问执行第9行语句时,SP寄存器中的值是多少?
选项
0x00000000
0xFFFFFFF8
0xFFFFFFFC
汇编代码(修正语法错误后)
1) start: bl subroutine1 2) end 3) subroutine1: str lr, [sp, #−4]! 4) mov r0,#2 5) mov r1,#4 6) bl subroutine2 7) ldr pc,[sp],#4 8) subroutine2: str lr, [sp, #−4]! // 原代码此处缺失str指令,属于语法错误 9) cmp r0,#0 10) beq subroutine2_end 11) mov r2,r0 12) mov r0,#0 13) loop: add r0, r0, r1, lsl #1 14) subs r2, r2, #1 15) bne loop 16) subroutine2_end: ldr pc, [sp], #4
分析与计算
首先修正原代码的语法错误:第8行必须是str lr, [sp, #−4]!,否则无法完成栈存储操作。接下来逐步跟踪SP的变化:
- 初始状态:SP =
0x00000000 - 执行第3行
str lr, [sp, #−4]!:这是ARM的前变址指令,先将SP减去4(0x00000000 - 4 = 0xFFFFFFFC),再把LR的值存入更新后的SP指向的地址。此时SP =0xFFFFFFFC - 执行第6行
bl subroutine2:BL指令会自动将下一条指令(第7行)的地址写入LR,然后跳转到subroutine2入口,此操作不修改SP - 执行第8行修正后的
str lr, [sp, #−4]!:再次执行前变址操作,SP再减4(0xFFFFFFFC - 4 = 0xFFFFFFF8),然后存储LR的值。此时SP =0xFFFFFFF8 - 接下来进入第9行
cmp r0,#0,此时SP寄存器的值就是0xFFFFFFF8
对两种思路的纠正
- “SP为保留寄存器,子程序不应修改”:这个理解错误。在ARM的调用规范(如APCS/AAPCS)中,SP作为栈指针寄存器,子程序可以合法修改它来保存返回地址、分配局部变量栈空间,只要在返回前恢复到调用前的状态即可。
- “栈需按4的倍数递减,但结果不在选项中”:栈确实要求4字节对齐(ARM32的强制对齐要求),我们的计算中每次SP减4,完全符合对齐规则,最终结果
0xFFFFFFF8是选项2,属于有效选项。
内容的提问来源于stack exchange,提问作者user22051194
相关产品推荐
相关产品推荐

