我正在开发 Arm Cortex M0+ STM32 Nucleo 开发板并使用 Keil MDK 5.36 版。 注意 - 我有嵌入式背景,但我是 ARM 汇编魔术的新手并且正在学习它。
挑战: 我想在执行其他应用程序时将字节码从一些汇编代码行复制到 RAM 中,并通过分支到它来在 RAM 中执行代码。
现在我坚持将循环实现为与位置无关的代码,以便在将其复制到 RAM 中的“随机”地址后它可以工作。
这是代码 - 它包括用于测试它的整个代码框架。我想复制到 RAM 的相关代码是“copy_loop”
Stack EQU 0x00000100 ;Define Stacksize of 256 Bytes
AREA STACK, NOINIT, READWRITE, ALIGN=3
StackMem SPACE Stack
AREA RESET,DATA, READONLY
EXPORT __Vectors
__Vectors
DCD StackMem+ Stack
DCD Reset_Handler
ALIGN
AREA simpleProject, CODE, READONLY, ALIGN=2
ENTRY
EXPORT Reset_Handler
Reset_Handler
LDR r0, =0x00000000 ; Source Address
LDR r1, =0x20000300 ; Destination address
LDR r2, =100 ;number of bytes to copy
copy_loop LDRB r3, [r0] ;read 1 byte
ADDS r0, r0, #1 ;increment source pointer
STRB r3, [r1] ; write 1 Byte
ADDS r1, r1, #1 ; increment destination pointer
subs r2, r2, #1 ;decrement loop counter
BNE copy_loop ;loop untill all data copied
END
在Debugger/Dissassmbler中运行我看到,条件跳转是用绝对地址实现的。
28: BNE copy_loop ;loop untill all data copied
0x08000018 D1F9 BNE 0x0800000E
我怎样才能让它进入与位置无关的条件跳转(使用 M0+ 指令集),以便它可以从它被复制到的任何位置运行。 非常感谢您的帮助!一直在阅读大量的东西,但错过了 HEUREKA 时刻。
你需要做的就是阅读说明文档,看看它是严格的 pc 相对偏移量。
或者试试看
.thumb
lab0: nop; nop; nop; bne lab0
lab1: nop; nop; nop; bne lab1
lab2: nop; nop; nop; bne lab2
lab3: nop; nop; nop; bne lab3
lab4: nop; nop; nop; bne lab4
lab5: nop; nop; nop; bne lab5
lab6: nop; nop; nop; bne lab6
arm-none-eabi-objdump -d so.o | grep bne
6: d1fb bne.n 0 <lab0>
e: d1fb bne.n 8 <lab1>
16: d1fb bne.n 10 <lab2>
1e: d1fb bne.n 18 <lab3>
26: d1fb bne.n 20 <lab4>
2e: d1fb bne.n 28 <lab5>
36: d1fb bne.n 30 <lab6>
位置独立。
cortex-m0+不是指令集,是IP产品。当您查看 cortex-m0+ 的技术参考手册时,上面写着 arv6-m,然后您可以获得 armv6-m 的体系结构参考手册。在这种情况下,这条指令一直回到拇指的开头,所以任何架构参考手册,全尺寸或其他(非 64 位)都有这条指令。