Hey there,
I'm building a small but usable computer/terminal from a Teensy 3. So far the Teensy directly outputs a (40x40) colored VGA character matrix, interfaces an SD card and I can happily type away on screen using a directly interfaced PS/2 keyboard.
Everything works fine so far, but my goal is to have a little compiler or at least an assembler running on the device itself. I wrote a little hex monitor and ported DARM to the device (http://darm.re/) so I can see what's going on in memory. My challenge now is to figure out how to execute Thumb-2 machine code from RAM.
Here's one of my failing approaches (the CPU freezes, I don't know what it's state is at that point because I don't have JTAG yet):
So in the first executeAsm() I just try to let GCC generate the code to execute the instructions in testAsmFunc[]. Disassembled, this looks like:
Which looks kinda OK to me, but I'm not an expert (yet). The expected result is that nothing special should happen because the CPU should just see the BX LR and return.
In executeAsm2(), I just tried to load the target address manually and branch to it (I dumped the actual address from hardware before). I know this is not a feasible approach, though.
So my real question boils down to:
What is the proper way to jump to a block of memory that contains Thumb-2 instructions and come back safely, in C?
I also read that to execute Thumb-2 code, it should be aligned on odd addresses. But the Cortex-M4 only knows about Thumb/-2 instructions anyway, am I right (no ARM mode)? Does this matter?
Any help or pointers in the right direction are greatly appreciated.
Best,
Lukas
I'm building a small but usable computer/terminal from a Teensy 3. So far the Teensy directly outputs a (40x40) colored VGA character matrix, interfaces an SD card and I can happily type away on screen using a directly interfaced PS/2 keyboard.
Everything works fine so far, but my goal is to have a little compiler or at least an assembler running on the device itself. I wrote a little hex monitor and ported DARM to the device (http://darm.re/) so I can see what's going on in memory. My challenge now is to figure out how to execute Thumb-2 machine code from RAM.
Here's one of my failing approaches (the CPU freezes, I don't know what it's state is at that point because I don't have JTAG yet):
Code:
volatile uint8_t testAsmFunc[] = {
0x70, 0x47, // 4770 BX LR
0x00, 0xbf, // BF00 NOP
0x70, 0x47, // 4770 BX LR
0x00, 0xbf, // BF00 NOP
0x70, 0x47, // 4770 BX LR
0x00, 0xbf, // BF00 NOP -- ignore the asm below, it shouldn't be reached anyway right now --
0x4f, 0xf0, 0x00, 0x50, // F04F 5000 MOV R0, #0x20000000
0x4f, 0xf4, 0x40, 0x71, // F44F 7140 MOV R1, #768
0x08, 0x44, // 4408 ADD R0, R0, R1
0x4f, 0xf0, 0x03, 0x01, // F04F 0103 MOV R1, #3 <-- char
0x01, 0x60, // STR R1, [R0]
0x70, 0x47, // BX LR
};
void (*testFuncPtr)() = (void(*)())(testAsmFunc);
void executeAsm() {
testFuncPtr();
}
void executeAsm2() {
asm("mov r0, #0x20000000\nsub r0, r0, #474\nblx r0\n");
}
So in the first executeAsm() I just try to let GCC generate the code to execute the instructions in testAsmFunc[]. Disassembled, this looks like:
Code:
00000000 <_Z10executeAsmv>:
0: b508 push {r3, lr}
2: 4b02 ldr r3, [pc, #8] ; (c <_Z10executeAsmv+0xc>)
4: 681b ldr r3, [r3, #0]
6: 4798 blx r3
8: bd08 pop {r3, pc}
a: bf00 nop
c: 00000000 .word 0x00000000
Which looks kinda OK to me, but I'm not an expert (yet). The expected result is that nothing special should happen because the CPU should just see the BX LR and return.
In executeAsm2(), I just tried to load the target address manually and branch to it (I dumped the actual address from hardware before). I know this is not a feasible approach, though.
So my real question boils down to:
What is the proper way to jump to a block of memory that contains Thumb-2 instructions and come back safely, in C?
I also read that to execute Thumb-2 code, it should be aligned on odd addresses. But the Cortex-M4 only knows about Thumb/-2 instructions anyway, am I right (no ARM mode)? Does this matter?
Any help or pointers in the right direction are greatly appreciated.
Best,
Lukas