我将简要说明问题。我有一个Leon3开发板(gr-ut-g99)。使用GRMON2,我可以在板上的所需地址加载可执行文件。

我有两个程序。我们称它们为A和B。我试图将它们加载到内存中,并且它们分别工作。

我现在想做的是使A程序称为B程序。

这两个程序都是使用gcc编译器(Gaisler Sparc GCC)的变体用C编写的。

为了进行跳转,我在程序A中编写了一个微型内联汇编函数,该函数跳转到加载程序B的内存地址。

在程序A的摘要下方

 unsigned int return_address;
 unsigned int * const RAM_pointer = (unsigned int *) RAM_ADDRESS;
 printf("RAM pointer set to: 0x%08x \n",(unsigned int)RAM_pointer);
 printf("jumping...\n");

 __asm__(" nop;" //clean the pipeline
         "jmp %1;" // jmp to programB
       :"=r" (return_address)
       :"r" (RAM_pointer)
     );


RAM_ADDRESS是#define

#define RAM_ADDRESS 0x60000000


程序B是一个简单的hello世界。程序B加载在0x60000000地址。如果我尝试运行它,它将起作用!

int main()
{
  printf ("HELLO! I'M BOOTED! \n");
  fflush(stdout);

  return 0;
}


当我运行ProgramA时,我期望在控制台上看到“正在跳跃...”消息,然后看到“ HELLO!I BOOTED!”从程序B

会发生什么,而不是IU异常。
我在下面发布了grmon2 Monitor显示的消息。我还报告了“ inst”报告,该报告应显示异常之前执行的最后操作。

  grmon2> run

  IU exception (tt = 0x07, mem address not aligned)

  0x60004824: 9fc04000  call  %g1


grmon2> inst
  TIME     ADDRESS   INSTRUCTION                   RESULT      SYMBOL

   407085  600047FC  mov  %i3, %o2                 [600063B8]  -

   407086  60004800  cmp  %i4                      [00000013]  -

   407089  60004804  be  0x60004970                [00000000]  -

   407090  60004808  mov  %i0, %o0                 [6000646C]  -

   407091  6000480C  mov  %i4, %o3                 [00000013]  -

   407092  60004810  cmp  %i4, %l0                 [80000413]  -

   407108  60004814  bleu  0x60004820              [00000000]  -

   407144  60004818  ld  [%i1 + 0x20], %o1         [FFFFFFFF]  -

   407179  60004820  ld  [%i1 + 0x28], %g1         [FFFFFFFF]  -

   407186  60004824  call  %g1                     [  TRAP  ]  -


我还尝试用“ jmpl”或“ call”代替“ jmp”,但是它不起作用。
我很困惑
我不知道如何很好地解决该问题,因此我不知道还需要提供什么其他信息。

我可以说,programB在0x60000000处加载,而entry_point当然是0x60000000。从该入口点直接运行程序B效果很好!

在此先感谢您的帮助!

最佳答案

在我看来,您确实执行了跳转,并且跳转到了程序B,这由跟踪缓冲区中的指令地址证明。但是您崩溃的地方是在stdio中尝试打印内容。 Stdio大量使用了函数指针,该序列清楚地显示了一个调用指令,其中目标地址位于寄存器中,指示了函数指针的使用。

我建议将fflush(stdout)放在跳转之前的程序A中,这将允许您在执行跳转之前查看消息。然后,在程序B中,不使用printf,而是将一些已知值放入内存中,然后可以通过监视器检查该值,以确认它是否在那里。

我的猜测是stdio库具有一些需要在程序开始时设置的数据或参数,而这些数据或参数未完成或未正确完成。不确定正在运行的平台,但是您是否具有某种调试功能或单步执行功能,例如在调试器中?如果是这样,只需单步执行跳转,然后跟踪程序的运行位置即可。

关于c - SPARC汇编jmp\boot,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49535410/

10-11 11:41