理解 ARM64 Obj-C Prolog

逆向工程 拆卸 部件 手臂
2021-06-24 23:06:30

我试图了解以下许多 obj-c 函数反编译的函数序言之间的差异。

我知道他们存储变量供调用者在函数返回时使用。但为什么会有差异呢?

示例 1

void * -[Issue ideal](void * self, void * _cmd)
sub        sp, sp, #0x40
stp        x22, x21, [sp, #0x10]
stp        x20, x19, [sp, #0x20]
stp        x29, x30, [sp, #0x30]
add        x29, sp, #0x30
mov        x19, x0

样本 2

void * -[Issue path](void * self, void * _cmd)
stp        x26, x25, [sp, #-0x50]!
stp        x24, x23, [sp, #0x10]
stp        x22, x21, [sp, #0x20]
stp        x20, x19, [sp, #0x30]
stp        x29, x30, [sp, #0x40]
add        x29, sp, #0x40
mov        x19, x0

示例 3

void -[ContentView showPageThumb:page:data:guid:](void * self, void * _cmd, void * arg2, long long arg3, void * arg4, void * arg5)
stp        x24, x23, [sp, #-0x40]!
stp        x22, x21, [sp, #0x10]
stp        x20, x19, [sp, #0x20]
stp        x29, x30, [sp, #0x30]
add        x29, sp, #0x30
mov        x20, x5
mov        x21, x4
mov        x22, x3
mov        x19, x0
mov        x0, x2
1个回答

我有一段时间没有接触过这些东西,但我想说编译器只是保存操作码或遵循复杂的模板,也许与优化有关。请注意

stp        x24, x23, [sp, #-0x40]!
stp        x22, x21, [sp, #0x10]
stp        x20, x19, [sp, #0x20]
stp        x29, x30, [sp, #0x30]

做同样的工作

sub        sp, sp, #0x40
stp        x22, x21, [sp, #0x10]
stp        x20, x19, [sp, #0x20]
stp        x29, x30, [sp, #0x30]

plus 存储一个额外的寄存器x24这是因为第一个示例在[sp, #-0x40]!

http://www.davespace.co.uk/arm/introduction-to-arm/addressing.html(关于 ARM 寻址模式的随机谷歌结果)。

与您的第二个示例相同 - 它仍然在堆栈上分配 x50 字节。区别是很肤浅的,他们都做同样的工作。add, movs 不是序言 IIRC 的一部分。