在arm gcc中控制函数的prelog和epilog

标签 c gcc assembly arm

我注意到有时当我编译C代码时,有时会在方法1中生成汇编代码:

STR R11, [SP, #-4]!
ADD R11, SP, #0
SUB SP, SP, #4

有时使用方法 2:

STMFD SP!, {R11, LR}
ADD R11, SP, #4
SUB SP, SP, #4

第一种方法和第二种方法的区别在于第二种方法将LR保存到栈中。

现在我面临一个问题,我的函数像第一个方法一样启动,使用链接寄存器(BL)调用另一个函数,并且由于我的函数首先不保存LR,所以会导致严重的问题。 如果我可以告诉编译器使用第二种方法它可以解决我的问题。

这可能与该函数使用内联汇编调用内部函数这一事实有关,因此“无法识别”存在对另一个函数的调用,并且认为保存 LR 没有意义。调用内联汇编是必须的,因为被调用的函数获取 SP 的值作为参数。

这是一个相当棘手的问题,希望有人能帮助我解决这个问题。 谢谢!

最佳答案

lr 标记为破坏以使编译器保存它:

extern void foo(void);
extern void bar(void)
{
    asm ( "bl foo" : : : "lr" );
}

生成以下代码:

bar:
    str lr, [sp, #-4]!
    bl foo
    ldr lr, [sp], #4
    bx  lr

参见the documentation更多细节。请记住将您使用的所有其他寄存器也标记为已损坏。否则,编译器可能会将变量放入其中之一。您可能还需要将所有调用者保存的寄存器标记为已损坏。

关于在arm gcc中控制函数的prelog和epilog,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37562932/

相关文章:

c - 为什么 gdb-7.4 不显示最新编译器生成的二进制文件的源信息?

c++ - 在 extern C 中使用 _attribute__ ((nothrow)) 有意义吗?

c - gcc 使用警告/优化标志链接目标文件

assembly - 错误: impossible register constraint in 'asm'

c++ - 在不使用其他变量的情况下用 C++ 编写程序集

c - 将数据上传至 MAX 7219

c - 多核处理器中的线程

c++ - 使用 EBP 从堆栈中获取参数

c - 为什么 C 程序在打印指针时会给出这样的输出?

c - 是否可以在三元运算符中包含语句(在生成的代码中)?