为什么这个 ARM 子程序将参数放入堆栈帧并直接取出?

逆向工程 拆卸 手臂
2021-07-07 19:59:13

我有这个小子程序(来自 Hopper,但 IDA 类似):

             sub_stringbegin:
000127b8         push       {r11, lr}                                          
000127bc         add        r11, sp, #0x4
000127c0         sub        sp, sp, #0x8
000127c4         str        r0, [r11, #-0x8]
000127c8         ldr        r0, [r11, #-0x8]
000127cc         bl         _ZNSs5beginEv@PLT                                   
000127d0         mov        r3, r0
000127d4         mov        r0, r3
000127d8         sub        sp, r11, #0x4
000127dc         pop        {r11, pc}
                        ; endp

参数在 r0 中传递给 this。

为什么将其存储到堆栈帧中然后立即读出?好像很浪费。

我知道 r0-r3 没有保留在 ARM 调用约定中,但在那种情况下,只需将它存储在堆栈帧中或将它弹出到堆栈中就足够了。

同样,在分支之后将 r0 移入 r3 并再次移回似乎是浪费。

这是一个来自 Busybox 系统的 ELF 可执行文件。

2个回答

这很可能只是未优化的代码。当优化被禁用时,编译器可能会做最愚蠢的事情。

我听说许多老嵌入式工程师原则上不启用优化,因为他们被旧编译器中的优化错误烧毁了。

这是一个简单的翻译

x = foo;
doSomething(x);

优化通过会意识到它x仍然在r0这里。据推测,优化已关闭。

顺便说一句,这并没有那么浪费,因为有问题的内存位置仍将在 L1 缓存中。