获得从子程序调用者的LR为C变量 - 手臂

问题描述 投票:2回答:2

我有一个本应获得致电者的LR寄存器的值到一个局部变量C函数。

我试过下面的代码:

volatile long lr;
asm(
    "str %0, [sp, #4]\n" :
    "=r", (lr)
);

但是,这并不能改变什么。这并不是说我得到了错误的价值,它只是在局部LR变量的值并没有改变(包括垃圾)。

有任何想法吗?

谢谢!

assembly arm
2个回答
6
投票

要直接回答这个问题,有两种解决方案。

    long lr;
    asm(" mov %0,lr\n" :: "=r" (lr));

这将使lr值的LR变量。你不妨这样做是为了分析的东西。如果你假设lr包含返回地址,那么这是不真实的Igor解释。在一个非叶函数,编译器可以计算一个函数的参数时,因为它是要被打一顿使用lr作为临时。

    register long lr asm("lr");

这种形式让你随时随地引用变量LR和编译器将使用现场lr值。该值可以通过时的功能改变。例如,当你调用另一个函数,它通常会在当前激活的功能设定到返回点。

作为Igor解释是否得到lr可能不会给你你期待什么。而我们所使用的机制的是GCC的特殊。你不能在一个可移植的方式做到这一点;但是访问一个lr在本质上是不便携的。

请参阅:ARM link register and frame pointer问题多一点就用lr的。


4
投票

您的代码就会在地址SP+4值。无论那个位置包含初始LR依赖于编译器,优化设置,特定的功能,或者在你把这个代码功能的新位置。总之,它很可能只是偶然的工作。

编辑:您的代码甚至没有阅读相关的东西,它只是存储在堆栈上未初始化的变量的值(提示:命名您的变量lr不会使奇迹般地把寄存器LR的值)。在最好的情况下,它不会做任何事情,在最坏的,你会覆盖一些重要的事情,它会崩溃。

我假设你真正想要得到的函数的返回地址,而不是专门LR。存在于特定的编译器选项。

  1. GCC提供__builtin_return_address()内在返回当前函数(如果调用0),或者可能在调用堆栈的其他功能(虽然我不会依赖后者)的返回地址。
  2. VISUAL C ++有_ReturnAddress()甚至_AddressOfReturnAddress()内部函数。

我会建议使用一个以上(假设你使用GCC或VC),而不是依靠技巧可以随时停止工作。

© www.soinside.com 2019 - 2024. All rights reserved.