C arm(裸机):调用二进制文件作为函数

C arm(裸机):调用二进制文件作为函数,c,arm,bare-metal,C,Arm,Bare Metal,我有AT91sam9 ARM控制器的AT91Bootloader。我需要添加一些额外的硬件初始化,但我只编译了.bin文件。 我将bin文件加载到内存并尝试调用它: ((void (*)())0x00005000)(); 但是,没有任何结果。请尽量少用汇编语言。我以前被介绍给汇编程序,但由于它的共谋,我无法理解ARM汇编程序。如何从引导加载程序的中间调用,执行bin文件(例如,它将位于某个内存扇区中,0x00005000),然后返回引导加载程序并继续执行它自己的代码?ARM汇编是一个简单的汇编

我有AT91sam9 ARM控制器的AT91Bootloader。我需要添加一些额外的硬件初始化,但我只编译了.bin文件。 我将bin文件加载到内存并尝试调用它:

((void (*)())0x00005000)();

但是,没有任何结果。请尽量少用汇编语言。我以前被介绍给汇编程序,但由于它的共谋,我无法理解ARM汇编程序。如何从引导加载程序的中间调用,执行bin文件(例如,它将位于某个内存扇区中,0x00005000),然后返回引导加载程序并继续执行它自己的代码?

ARM汇编是一个简单的汇编,非常简单。如果你想继续做裸机,你将需要学习至少一些组装。例如,理解Alexey的评论

您要查找的指令是BX,它分支到一个地址,您需要分支到引导加载程序下载的代码的程序集是:

.globl tramp
tramp:
   bx r0
C原型是

void tramp ( unsigned int address );
正如注释中提到的,程序需要针对运行它的地址进行编译,和/或它需要独立于位置,否则它将无法工作。此外,您还需要使用适当的入口点构建应用程序,如果它是原始二进制文件,并且分支到加载二进制文件的地址,则二进制文件需要能够以这种方式启动,方法是将二进制文件中的第一个字作为执行入口点

还要了解elf格式文件包含要加载的数据,但总体上不是要加载的数据。这是一个“二进制文件”,是的,但要运行其中包含的程序,您需要解析和提取可加载的部分,并将它们加载到正确的位置

如果您不知道这些术语的含义,请使用谷歌和/或搜索,答案就在那里。

如果ARM asm“太复杂”,您将发现很难调试您遇到的任何问题。Basic*ARM汇编是我见过的最不复杂的汇编语言之一

如果“.bin”格式正确,您的代码应该可以工作(尽管我不会在那里使用硬编码地址)。共同问题:

  • 入口点应为ARM代码;有些编译器默认使用Thumb。让Thumb代码工作是可能的(如果有点棘手的话)
  • 入口点必须位于文件的开头。如果不进行分解,很难判断您是否正确完成了此操作
  • 链接器将在必要时插入“thunks”(又称“stubs”)。某些链接器中的一个怪癖意味着thunk可以放在入口点之前。您可以使用
    --stub group size=-1
    (文档)来解决这个问题

*忽略Thumb/VFP/NEON等您不需要开始的东西。

提供的信息太少。顺便说一句,如果您正在调用的函数没有编译并链接到地址0x5000处执行,则上述操作可能无法正常工作(我不认为该二进制文件只包含位置无关的代码)。