Ale*_*pus 6 c assembly stack gcc arm
我提到ARM工具链可以生成不同的函数序言.实际上,我看到了两个完全不同的功能序言的obj文件(vmlinux):
第一种情况看起来像:
push {some registers maybe, fp, lr} (lr ommited in leaf function)
Run Code Online (Sandbox Code Playgroud)
第二种情况如下:
push {some registers maybe, fp, sp, lr, pc} (i can confuse the order)
Run Code Online (Sandbox Code Playgroud)
所以当我看到第二个推动额外的pc和sp.此外,我在崩溃实用程序(kdump项目)中看到了一些注释,其中内核堆栈框架应该具有格式{...,fp,sp,lr,pc}让我更加困惑的是,因为我看到在某些情况下它不是真正.
1.)我是否正确需要一些gcc额外的标志来推动额外的pc和sp在功能prolog?如果是的话他们是什么?
2.)这用于什么?基本上,据我所知,我可以只用FP和LR展开堆栈,为什么我需要这个额外的值?
3.)如果这个东西没有编译标志 - 我怎么能强制生成这个扩展函数prolog,又是什么目的?
谢谢.
1.) 我关于在函数序言中额外推送 pc 和 sp 需要一些 gcc 额外标志的说法正确吗?如果是的话,它们是什么?
有许多 gcc 选项会影响堆栈帧(-march例如-mtune, 、 等可能会影响所使用的指令)。就你而言,它是-mapcs-frame。此外,-fomit-frame-pointer将从叶函数中删除框架。多个静态函数可以合并到一个生成函数中,进一步减少帧数。APCS可能会导致代码稍微慢一些,但对于简单的堆栈跟踪来说是必需的。
2.) 这是做什么用的?基本上,据我所知,我只能使用 FP 和 LR 来展开堆栈,为什么我需要这个附加值?
所有非参数(r0-r3)的寄存器都需要保存,因为它们在返回给调用者时需要恢复。编译器将在堆栈上分配额外的局部变量,因此sp在更改时几乎总是会更改fp。至于为什么pc要存储,请参见下文。
3.)如果这件事与编译标志无关 - 我如何强制生成此扩展函数序言,目的是什么?
正如您所猜测的,它是编译器标志。
; Prologue - setup
mov ip, sp ; get a copy of sp.
stm sp!, {fp, ip, lr, pc} ; Save the frame on the stack. See Addendum
sub fp, ip, #4 ; Set the new frame pointer.
...
; Epilogue - return
ldm sp, {fp, sp, lr} ; restore stack, frame pointer and old link.
... ; maybe more stuff here.
bx lr ; return.
典型的保存stm sp!, {fp, ip, lr, pc}和恢复是ldm sp, {fp, sp, lr}. 如果您检查 ABI/APCS 文档,这是正确的。请注意,没有“!” 尝试修复堆栈。它是从存储的ip值中显式加载的。
pc另外,尾声中不使用保存的内容。它只是堆栈上丢弃的数据。那么为什么要这样做呢?异常处理程序(中断、信号或 C++ 异常)和其他堆栈跟踪机制想要知道谁保存了帧。ARM 始终只有一个函数序言(一个入口点)。然而,有多个出口。在某些情况下, return likereturn function();实际上可能会变成 a b functionin the Maybe more stuff here。这称为尾调用。此外,当在例程中间调用叶子函数并发生异常时,它将看到PC叶子的范围,但叶子可能没有调用框架。通过保存pc,可以在 leaf 中发生异常时检查调用帧,以了解谁真正保存了堆栈。可以存储与析构函数等的表pc,以允许释放对象或弄清楚如何调用信号处理程序。当跟踪堆栈时,额外的功能pc非常好,并且由于管道衬里,操作几乎是免费的。
另请参阅:ARM 链接和帧寄存器问题,了解编译器如何使用这些寄存器。
| 归档时间: |
|
| 查看次数: |
2294 次 |
| 最近记录: |