我有一个本应获得致电者的LR寄存器的值到一个局部变量C函数。
我试过下面的代码:
volatile long lr;
asm(
"str %0, [sp, #4]\n" :
"=r", (lr)
);
但是,这并不能改变什么。这并不是说我得到了错误的价值,它只是在局部LR变量的值并没有改变(包括垃圾)。
有任何想法吗?
谢谢!
要直接回答这个问题,有两种解决方案。
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
的。
您的代码就会在地址SP+4
值。无论那个位置包含初始LR
依赖于编译器,优化设置,特定的功能,或者在你把这个代码功能的新位置。总之,它很可能只是偶然的工作。
编辑:您的代码甚至没有阅读相关的东西,它只是存储在堆栈上未初始化的变量的值(提示:命名您的变量lr
不会使奇迹般地把寄存器LR
的值)。在最好的情况下,它不会做任何事情,在最坏的,你会覆盖一些重要的事情,它会崩溃。
我假设你真正想要得到的函数的返回地址,而不是专门LR。存在于特定的编译器选项。
__builtin_return_address()
内在返回当前函数(如果调用0),或者可能在调用堆栈的其他功能(虽然我不会依赖后者)的返回地址。_ReturnAddress()
甚至_AddressOfReturnAddress()
内部函数。我会建议使用一个以上(假设你使用GCC或VC),而不是依靠技巧可以随时停止工作。