2
\$\begingroup\$

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

\$\endgroup\$
4
  • \$\begingroup\$ Can I ask what you seek to achieve by having control over register allocation? \$\endgroup\$ Commented Sep 22, 2015 at 10:38
  • \$\begingroup\$ @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. \$\endgroup\$
    – rockstar
    Commented Sep 22, 2015 at 10:49
  • 3
    \$\begingroup\$ Maybe better do that totally in assembler (in a .ams file)? \$\endgroup\$ Commented Sep 22, 2015 at 11:24
  • \$\begingroup\$ 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. \$\endgroup\$
    – Dave Tweed
    Commented Sep 22, 2015 at 13:37

2 Answers 2

3
\$\begingroup\$

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.

\$\endgroup\$
1
  • \$\begingroup\$ Yes that is exactly what i did finally,works well now :) \$\endgroup\$
    – rockstar
    Commented Nov 5, 2015 at 2:38
0
\$\begingroup\$

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
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.