# Initialize ARM registers to specific value via Inline assembly

I have a need to initialize the ARM registers of my ARM7TDMI development board to a specific values using inline assembly. For example currently I do something like the following :

    #pragma ARM
void init(char * reg)  {

__asm  {
MOV    R0,#0x0
MOV    R1,#0x1
MOV    R2,#0x2
MOV    R3,#0x3
...
}


The idea is to closely control the contents of each of the registers here. I am using KEIL UVision 5 and it warns me that this may not be a smart thing to do . And looking at the debugger there is no guarantee that the initialization will happen as per my request. For example the value 0x2 maybe stored in register r12 instead of r2 as i requested in my inline assembly ..

a.c(102): warning:  #1267-D: Implicit physical register R0 should be defined as a variable


Reading up on Keil documentation http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka11441.html it suggests using variable names. Something like this

{
int val2;

__asm
{
MOV val2,0xFFFF0000
MOV val,val,LSL #16
}


Well this is not good enough for me as I want precise control over my register contents. How is it possible to do ? Any ideas ?

Thanks

• Can I ask what you seek to achieve by having control over register allocation? – Houston Fortney Sep 22 '15 at 10:38
• @HoustonFortney i want to generate a checksum/verification value using the contents of all the registers (it will include the PC CPSR values as well). The value will be unique if the inputs are initialized in a certain way. Any change in the inputs will generate a wrong value. – rockstar Sep 22 '15 at 10:49
• Maybe better do that totally in assembler (in a .ams file)? – Wouter van Ooijen Sep 22 '15 at 11:24
• To put Wouter's comment more strongly: If you need to control the state of all of the CPU registers, then you CANNOT use a C compiler, which uses most, if not all, of the registers for its own purposes. That's what all the warnings are about. You MUST do this in pure assembly -- perhaps as a function that you can call from C, but then you need to write your function so that it is compatible with the C runtime environment. – Dave Tweed Sep 22 '15 at 13:37

The IDE you're using, like most IDEs, automates initialization CPU to the lowest level. It is responsible for generating, for example, the content of the vector table.

Using a language of higher level than assembler, everything related to manipulation of registers and initialization is quite hidden, especially if enabled compiler optimizations.

I think you should write the critical code in assembler, to ensure the performance of the CPU. Perhaps the rest of your application can be developed at the highest level, having the low-level code as a library.

• Yes that is exactly what i did finally,works well now :) – rockstar Nov 5 '15 at 2:38

I use the following function in my code with uVision 4.70

__asm void SetPOWCON(
u16 u16POWCON)  // POWCON register value
{
Z_PLL   EQU     0xFFFF0400  // PLL base address
R_NUM   EQU     0x12345678  // Random Number for Dummy Multiplication

LDR      r3,=R_NUM      // Load random number for multiplication
LDR      r1,=Z_PLL      // Load base address of PLL / POWCON related MMRs
MOV      r2,#1          // POWKEY0 = 1
STR      r2,[r1,#4]
STR      r0,[r1,#8]     // Set POWCON value
MOV      r0,#0xf4       // POWKEY1 = 0xF4
STR      r0,[r1,#0xc]
UMLAL    r2,r0,r3,r1
BX       lr
}