Dear all,
I'm trying to check the register values in inline-assembly in c as the below code. In especially, R0 and R1 values what I want to know which value is loaded to register. But as you can see that code, that is a In-line assembly.
Is there any way to check the register which values are loaded?
main.c
... __asm void ST0(void) { MOVS R0,#0 LDR R1,[R0] ; Get initial MSP value MOV SP, R1 LDR R1,[R0, #4] ; Get initial PC value BX R1 } ... int main (void) { ST0(); return 0; }
Get the compiler to produce an assembly listing. Or disassemble the module after compilation.
Use a debugger and step the code?
It's impossible.
Hello Carter,
I assume you are using the ARM Compiler 5, (ARMCC) not ARM compiler 6.
If so - risking being pedantic, there is a difference between inline assembly and embedded assembly.
In inline assembly, you add assembly code in the middle of a function - there is no way to control the registers used. See:
infocenter.arm.com/.../index.jsp
In embedded assembly, you can specify registers to be used:
...
when you single step through the debugger, you can view the registers window to see which registers get loaded. Or you can view the disassembly window to see the final assembly code.
http://www.keil.com/support/man/docs/uv4/uv4_db_dbg_cpuregs.htm
http://www.keil.com/support/man/docs/uv4/uv4_db_dbg_disasmwin.htm
Thanks for letting me know kevin,
I'd like to experiment in uVision, but not sure, should I have to go to ask another with this question ? What If I can do ask to here, how can I implement that Inline assembly code ?
unsigned int bar(unsigned int r0) { unsigned int r1; unsigned int r4 = 1234; __asm { MOVS r0,#0 LDR r1,[r0] ; Get initial MSP value MOV SP, r1 LDR r1,[r0, #4] ; Get initial PC value BX r1 } return(r1); }
I've got the below error messages when I compile it as the below.
*** Using Compiler 'V5.06 update 5 (build 528)', folder: 'C:\Keil_v5\ARM\ARMCC\Bin' Build target 'STM32F429_439xx' compiling main.c... ../main.c(79): error: #3061: unrecognized instruction opcode LDR r1,[r0] ; Get initial MSP value ../main.c(80): error: #20: identifier "SP" is undefined MOV SP, r1 ../main.c(81): error: #3061: unrecognized instruction opcode LDR r1,[r0, #4] ; Get initial PC value ../main.c(82): error: #1084: This instruction not permitted in inline assembler BX r1 ../main.c(71): warning: #177-D: variable "r4" was declared but never referenced unsigned int r4 = 1234; ../main.c(82): error: #114: label "r1" was referenced but not defined BX r1 ../main.c: 1 warning, 5 errors "STM32F429_439xx\STM32F429_439xx.axf" - 5 Error(s), 1 Warning(s). Target not created. Build Time Elapsed: 00:00:01
What am I supposed to do to resolve this problem?
You are using inline assembly here, so you are defining variables as R0, SP and so on. You are NOT using the actual registers on the device.
To modify the real registers, you would have to use embedded assembly.
See an example of embedded assembler:
#include <stdio.h> __asm void my_strcpy(const char *src, char *dst) { loop LDRB r2, [r0], #1 STRB r2, [r1], #1 CMP r2, #0 BNE loop BX lr } int main(void) { const char *a = "Hello world!"; char b[20]; my_strcpy (a, b); printf("Original string: '%s'\n", a); printf("Copied string: '%s'\n", b); return 0; }
(from infocenter.arm.com/.../index.jsp )
putting __asm in front of the function name lets you modify the registers directly.