我试图理解链接寄存器和帧指针在ARM中是如何工作的.我去过几个网站,我想确认一下我的理解.
假设我有以下代码:
int foo(void)
{
// ..
bar();
// (A)
// ..
}
int bar(void)
{
// (B)
int b1;
// ..
// (C)
baz();
// (D)
}
int baz(void)
{
// (E)
int a;
int b;
// (F)
}
Run Code Online (Sandbox Code Playgroud)
我叫foo().将链接寄存器包含在点(A)的地址码和帧指针包含在代码点(B)的地址?在声明了所有本地人之后,堆栈指针可以是bar()内的任何位置吗?
[编辑]添加了另一个函数调用baz()
我正在使用mbxxx目标处理Contiki 2.7.在构建我的代码时,链接器抱怨.ARM.exidx和.data部分的重叠.在使用链接器脚本contiki-2.7/cpu/stm32w108/gnu-stm32w108.ld进行了一些修补之后,我通过替换修复了问题:
__exidx_start = .;
__exidx_end = .;
Run Code Online (Sandbox Code Playgroud)
有:
.ARM.exidx : {
__exidx_start = .;
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
__exidx_end = .;
} >ROM_region
Run Code Online (Sandbox Code Playgroud)
后来当我试图通过使用objdump -h看到其他一些示例应用程序的标题列表时,我没有找到这个特定的.ARM.exidx部分,而它存在于我的应用程序中.谷歌搜索.ARM.exidx让我知道它用于一些c ++异常处理.由于我的代码是纯C代码,为什么这部分出现在我的代码中?通常.ARM.exidx存在于代码中,它的实用性是什么?
================================================== ================================
嗯不,我没有任何这样的编译器选项.我实际上正在使用AxTLS api并撕掉证书处理代码并将其移植到contiki.在进一步的挖掘中,我在bigint实现中发现了一个可疑的行为.简而言之......这是bigint.c文件中函数的主体:
static bigint *bi_int_multiply(BI_CTX *ctx, bigint *bia, comp b)
{
int j = 0, n = bia->size;
bigint *biR = alloc(ctx, n + 1);
comp carry = 5;
comp *r = biR->comps;
comp *a = bia->comps;
check(bia);
/* clear things to start with */
memset(r, 0, ((n+1)*COMP_BYTE_SIZE));
do …Run Code Online (Sandbox Code Playgroud) 我提到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,又是什么目的?
谢谢.