如何退出 ARM 汇编中的主子程序?
How can I exit main subroutine in ARM assembly?
如何完成程序,因为下面的代码在 __mainCode 和 funcOne 子例程之间不断循环?
__mainCode PROC
MOV R0, 5 ;0x0800 0008
LDR R1, =0xA ;0x0800 000C
BL funcOne ;0x0800 0010
POP {R3} ;0x0800 0014
ENDP ; end of function
funcOne PROC
MOV R2, #11 ;0x0800 0018
PUSH {R2} ;0x0800 001c
BX LR ;0x0800 001e
ENDP
ALIGN ; fill rest of bytes with 0s
END
裸机代码没有任何“退出”例程,因为它没有任何东西可以将控制传递给。
当您从 main
函数 return 编写“普通”C 程序时,启动代码只是禁用中断并进入无限循环。
下面是 STMCube 生成的启动代码片段(他们甚至不关心中断)
/* Call the application's entry point.*/
bl main
LoopForever:
b LoopForever
你的代码在做什么?
- 执行完
BX LR
后跳转到POP {R3}
继续执行
- 它再次到达
BX LR
(LR 未被修改)并循环重复。
当你按下 R2
和下一个 pop R3
时,堆栈指针保持不变并且永远不会到达不合法的地址,这可能会引发 BusError 并可能打破这个死循环。
但是如果去掉pop指令最终uC会访问非法地址,说明你没有设置中断向量。它会尝试跳转到 0xffffffff 地址(flash 默认用 0xff 值填充),这个地址也是非法的。它将再次引发 BusFault,您的程序将最终进入死异常引发循环。
如果你不完全了解架构并且不熟练地为ARM uC编写C代码,IMO学习ARM汇编是没有意义的。汇编很少使用(我个人在 10 年前写了 50 行代码,当时我正在编写自己的 RTOS,并且需要很少的指令来交换堆栈指针值和访问一些系统寄存器)——而编程(主要是 ARM)uC 是我的白天工作。
如何完成程序,因为下面的代码在 __mainCode 和 funcOne 子例程之间不断循环?
__mainCode PROC
MOV R0, 5 ;0x0800 0008
LDR R1, =0xA ;0x0800 000C
BL funcOne ;0x0800 0010
POP {R3} ;0x0800 0014
ENDP ; end of function
funcOne PROC
MOV R2, #11 ;0x0800 0018
PUSH {R2} ;0x0800 001c
BX LR ;0x0800 001e
ENDP
ALIGN ; fill rest of bytes with 0s
END
裸机代码没有任何“退出”例程,因为它没有任何东西可以将控制传递给。
当您从 main
函数 return 编写“普通”C 程序时,启动代码只是禁用中断并进入无限循环。
下面是 STMCube 生成的启动代码片段(他们甚至不关心中断)
/* Call the application's entry point.*/
bl main
LoopForever:
b LoopForever
你的代码在做什么?
- 执行完
BX LR
后跳转到POP {R3}
继续执行 - 它再次到达
BX LR
(LR 未被修改)并循环重复。
当你按下 R2
和下一个 pop R3
时,堆栈指针保持不变并且永远不会到达不合法的地址,这可能会引发 BusError 并可能打破这个死循环。
但是如果去掉pop指令最终uC会访问非法地址,说明你没有设置中断向量。它会尝试跳转到 0xffffffff 地址(flash 默认用 0xff 值填充),这个地址也是非法的。它将再次引发 BusFault,您的程序将最终进入死异常引发循环。
如果你不完全了解架构并且不熟练地为ARM uC编写C代码,IMO学习ARM汇编是没有意义的。汇编很少使用(我个人在 10 年前写了 50 行代码,当时我正在编写自己的 RTOS,并且需要很少的指令来交换堆栈指针值和访问一些系统寄存器)——而编程(主要是 ARM)uC 是我的白天工作。