调用汇编例程的C代码- ARM

hlswsv35  于 2023-08-03  发布在  其他
关注(0)|答案(3)|浏览(81)

我目前正在为ARM Cortex M3做一个 Bootstrap 。
我有两个函数,一个在 C 中,一个在 assembly 中,但是当我试图调用 *assembly函数 * 时,我的程序挂起并产生某种错误。
功能如下,

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秒后暂停时,Hard Fault处理程序的无限while循环正在执行)。
以前有人遇到过这个问题吗?如果是这样,你能告诉我如何解决吗?
正如您所看到的,我已经尝试使用函数属性来解决这个问题,但还没有找到解决方案。我希望有人能帮助我了解问题是什么摆在首位。

编辑:

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

p4rjhz4m

p4rjhz4m1#

我认为你需要告诉汇编器使用统一的语法,并显式地声明你的函数是一个thumb函数。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为零,则会出现故障。

cunj1qz1

cunj1qz12#

既然你提到你有调试器工作,使用它!
查看determine the fault source的故障状态寄存器。也许不是asmJump崩溃,而是你调用的代码。

bxpogfeg

bxpogfeg3#

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

ldr r6, =registerbackup
str sp, [r6]
#your code
...
ldr r6, =registerbackup
ldr sp, [r6]

字符串

相关问题