c++ - 在裸函数内部 - 如何进行简单的赋值
问题描述
这是已经存在并有效的功能的开始;注释行是我的补充,其目的是切换一个别针。
inline __attribute__((naked))
void CScheduler::SwapToThread(void* pNew, void* pPrev)
{
//*(volatile DWORD*)0x400FF08C = (1 << 14);
if (pPrev != NULL)
{
if (pPrev == this) // Special case to save scheduler stack on startup
{
asm("mov lr,%0"::"p"(&CScheduler_Run_Exit)); // load r1 with schedulers End thread
asm("orr lr, 1");
当我取消注释我的添加时,我的硬故障处理程序将执行。我知道这与这是一个naked
函数有关,但我不明白为什么简单的赋值会导致问题。
两个问题:
- 为什么这条线会触发硬故障?
- 如何在此函数中执行此分配?
解决方案
幸运的是,您以前版本的函数碰巧可以正常工作而不会崩溃。
唯一可以安全地放入naked
函数中的是纯基本 Asm 语句。 https://gcc.gnu.org/onlinedocs/gcc/ARM-Function-Attributes.html。您可以将其拆分为多个基本 Asm 语句,而不是asm("insn \n\t"
/ "insn2 \n\t"
/ ...);
,但您必须自己在 asm 中编写整个函数。
虽然使用扩展 asm 或基本 asm 和 C 代码的混合似乎可以工作,但它们不能可靠地工作并且不受支持。
如果你想从一个裸函数运行 C++ 代码,你可以call
使用一个常规函数(或bl
在 ARM、jal
MIPS 等上),遵循标准调用约定。
至于本案的具体原因?也许在寄存器中创建该地址会踩在函数 args 上,导致分支出错?如果需要,请检查生成的 asm,但它 100% 不受支持。
或者它最终使用了更多的寄存器,因为它naked
没有正确保存/恢复调用保留的寄存器?我自己还没有查看代码生成的裸函数。
你确定这个功能需要naked
吗?我想那是因为你操纵lr
返回到新的上下文。
如果您不想在 asm 中编写更多逻辑,也许让这个函数的调用者做更多工作(并且可能传递指针和/或布尔参数更简单地告诉它需要做什么,所以您的输入已经在寄存器中,并且您不需要访问全局变量)。
推荐阅读
- laravel-5.8 - 如何在 Laravel Envoy 脚本中设置密码?
- css - 是否可以将位置粘性行为限制在特定的网格行中?
- c++11 - 如何根据类中的编译时常量创建类型别名?
- python - 在 Robotframework-AutoItLibrary 中控制 Click 什么都不做
- python - 如何将 MapDataset 变量转换为 np.array?
- excel - 使用 VBA 抓取不在源代码中的数据
- sonata-admin - 删除 SonataAdmin 徽标
- java - ArchiveException:归档程序同时将参数传递给 Jar 文件
- mongodb - 获取 MongoDB 集合的数组中嵌入文档的总数
- scala - 当DataFrame为空时抛出AnalysisException(没有这样的结构字段)