扩展 Rad Lexus 的评论,它很好地描述了情况,但如果没有示例可能无法理解:
在函数中,堆栈指针在大多数情况下不是常量。当函数/方法/子例程的参数被推送时,当程序员使用诸如 之类的东西alloca以及其他原因时,它可能会发生变化,具体取决于编译器和处理器。
这使得跟踪参数和局部变量的位置变得非常困难。例如,类似的代码f(i++)可能会导致类似的结果
mov r0, [sp, #8] ; read the variable
mov [sp], r0 ; put it on the argument stack
sub sp, sp, #4 ; adjust the stack pointer
add r0, r0, #1 ; calculate the ++
mov [sp, #12], r0 ; write back result
这是一个使更改sp可见的版本;通常,该更改将隐藏在类似stmfd sp!, {r0}
在这种情况下,很难看到“读取”和“写入”操作访问内存中的相同地址而sp值已更改。
这就是像 IDA 这样的反编译器为这些位置分配名称的原因 - 作为示例,让我们假设在我的示例中变量的命名var_4值为 4。
现在 IDA 可以发出
mov r0, [sp, var_4+#4] ; read the variable
mov [sp, var_4+#8], r0 ; write back result
与var_4在“相同的变量”,并且暗示#4/#8在从偏移[sp],需要被加入到var_4在每一种情况下。