我有一个C函数,它应该将调用者的lr寄存器的值转换为局部变量。
我尝试过以下代码:
volatile long lr;
asm(
"str %0, [sp, #4]\n" :
"=r", (lr)
);
然而,这并没有改变任何事情。这不是我得到错误的值,只是lr局部变量的值根本不会改变(包含垃圾)。
有什么想法吗?
谢谢!
答案 0 :(得分:5)
要直接回答这个问题,有两种解决方案。
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
本质上是不可移植的。
有关使用lr
的更多信息,请参阅:ARM link register and frame pointer。
答案 1 :(得分:3)
您的代码将获取地址 SP+4
的值。该位置是否包含初始LR
取决于编译器,优化设置,特定函数或放置此代码的函数中的位置。简而言之,它可能只会偶然发挥作用。
编辑:您的代码甚至没有读取任何相关内容,它只是在堆栈中存储未初始化变量的值(提示:命名变量lr
不会让它神奇地取寄存器的值 LR
)。在最好的情况下,它不会做任何事情,在最糟糕的情况下,你会覆盖重要的东西,它会崩溃。
我假设您确实想要获取函数的返回地址,而不是LR。存在特定于编译器的选项。
GCC提供__builtin_return_address()
内在函数,它返回当前函数的返回地址(如果用0调用),或者可能是调用堆栈中的其他函数(尽管我不会依赖后者) )。
Visual C ++有_ReturnAddress()
甚至_AddressOfReturnAddress()
内在函数。
我建议使用上述之一(假设您正在使用GCC或VC)并且不依赖可能随时停止工作的技巧。