繁体   English   中英

ARM GCC生成的函数序言

[英]ARM GCC generated functions prolog

我提到ARM工具链可以生成不同的功能序言。 实际上,我看到了两个obj文件(vmlinux),它们的功能序言完全不同:

第一种情况如下:

push {some registers maybe, fp, lr} (lr ommited in leaf function)

第二种情况如下:

push {some registers maybe, fp, sp, lr, pc} (i can confuse the order)

因此,如我所见,第二个按钮会另外推动pc和sp。 我也看到了崩溃实用程序(kdump项目)中的一些注释,其中,内核堆栈帧应该具有{...,fp,sp,lr,pc}格式,这让我更加困惑,因为在某些情况下,我发现并非如此真正。

1.)我是否正确,需要一些gcc额外标志来在功能序言中额外推送pc和sp? 如果是,那是什么?

2.)这是做什么用的? 基本上,据我了解,我只能使用FP和LR展开堆栈,为什么我需要此附加值?

3.)如果用编译标志没有任何作用,我该如何强制生成此扩展功能序言,目的又是什么?

谢谢。

1.)我是否正确,需要一些gcc额外标志来在功能序言中额外推送pc和sp? 如果是,那是什么?

有许多gcc选项会影响堆栈帧( -march-mtune等可能会影响所使用的指令)。 在您的情况下,它是-mapcs-frame 同样, -fomit-frame-pointer将从叶函数中删除帧。 几个静态函数可以合并到一个生成的函数中,从而进一步减少了帧数。 APCS可能会导致代码稍慢一些,但是堆栈跟踪需要它。

2.)这是做什么用的? 基本上,据我了解,我只能使用FP和LR展开堆栈,为什么我需要此附加值?

所有非参数寄存器(r0-r3)都需要保存,因为返回到调用方时需要恢复它们。 编译器将在堆栈上分配其他本地变量,因此当fp更改时, sp几乎总是更改。 有关存储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 function();这样的return function(); 可能实际上在这里的更多内容中变成了b function 这被称为尾叫。 同样,当在例程中间调用叶子函数并发生异常时,它将看到叶子的PC范围,但是叶子可能没有调用帧。 通过保存pc ,可以在叶子中发生异常时检查调用框架 ,以了解谁真正保存了堆栈。 pc与析构函数等的表可能被存储,以允许对象被释放或弄清楚如何调用信号处理程序。 跟踪堆栈时,多余的pc非常好用,而且由于管道内衬,操作几乎是免费的。

另请参阅: ARM链接和帧寄存器问题,以了解编译器如何使用这些寄存器。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM