6

我目前正在为 ARM Cortex M3 开发引导加载程序。

我有两个函数,一个在C中,一个在汇编中,但是当我尝试调用汇编函数时,我的程序挂起并产生某种错误。

功能如下,

C:

extern void asmJump(void* Address) __attribute__((noreturn));

void load(void* Address)
{
    asmJump(Address);
}

集会:

.section .text

.global asmJump

asmJump:                   @ Accepts the address of the Vector Table
                           @ as its first parameter (passed in r0)

    ldr r2, [r0]           @ Move the stack pointer addr. to a temp register.
    ldr r3, [r0, #4]       @ Move the reset vector addr. to a temp register.

    mov sp, r2             @ Set the stack pointer

    bx  r3                 @ Jump to the reset vector

我的问题是这样的:

代码通过串行打印“Hello”,然后调用load. 加载的代码打印“再见”,然后重置芯片。

如果我慢慢地通过load调用asmJump一切正常的部分。但是,当我让代码运行时,我的代码会遇到“内存故障”。我知道这是一个内存故障,因为它Hard Fault以某种方式导致了(当我在 4 或 5 秒后暂停时,硬故障处理程序的无限 while 循环正在执行)。

有没有人遇到过这个问题?如果是这样,你能告诉我如何解决它吗?

如您所见,我尝试使用函数属性来解决问题,但尚未设法找到解决方案。我希望有人可以帮助我首先了解问题所在。

编辑:

感谢@JoeHass 的回答,以及@MartinRosenau 的评论,从那以后我继续找到这个 SO 答案,它对我为什么需要这个标签有一个非常详尽的解释。这是一个很长的阅读,但值得。

4

3 回答 3

8

我认为您需要告诉汇编器使用统一语法并明确声明您的函数是拇指函数。GNU 汇编器有这方面的指令:

  .syntax unified
  .section .text
  .thumb_func
  .global asmJump
asmJump:

.syntax unified指令告诉汇编器您正在为汇编代码使用现代语法。我认为这是一些遗留语法的不幸遗物。

.thumb_func指令告诉汇编器该函数将在 thumb 模式下执行,因此用于符号的值将asmJump其 LSB 设置为 1。当 Cortex-M 执行分支时,它会检查目标地址的 LSB 以查看它是否为 1。如果是,则目标代码以拇指模式执行。由于这是 Cortex-M 支持的唯一模式,因此如果目标地址的 LSB 为零,它将发生故障。

于 2013-09-17T14:11:42.803 回答
1

既然你提到你有调试器工作,使用它!

查看故障状态寄存器以确定故障源。也许它不是asmJump崩溃,而是您正在调用的代码。

于 2013-09-17T10:32:03.013 回答
0

如果那是您所有的代码..我想您对 SP 的更改称为段错误或类似的东西。您应该在更改之前保存您的 SP,并在使用后恢复它。

ldr r6, =registerbackup
str sp, [r6]
#your code
...
ldr r6, =registerbackup
ldr sp, [r6]
于 2013-09-17T08:51:59.973 回答