Inicialice los registros ARM a un valor específico a través del ensamblaje en línea

Tengo la necesidad de inicializar los registros ARM de mi placa de desarrollo ARM7TDMI a valores específicos usando ensamblaje en línea. Por ejemplo, actualmente hago algo como lo siguiente:

    #pragma ARM
        void init(char * reg)  {

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

La idea es controlar de cerca el contenido de cada uno de los registros aquí. Estoy usando KEIL UVision 5 y me advierte que esto puede no ser una decisión inteligente. Y mirando el depurador, no hay garantía de que la inicialización ocurra según mi solicitud. Por ejemplo, el valor 0x2 puede almacenarse en el registro r12 en lugar de r2 como lo solicité en mi ensamblaje en línea.

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

Leyendo la documentación de Keil http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka11441.html sugiere usar nombres de variables. Algo como esto

{
  int val2;

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

Bueno, esto no es lo suficientemente bueno para mí, ya que quiero un control preciso sobre el contenido de mi registro. ¿Cómo es posible hacer? Algunas ideas ?

Gracias

¿Puedo preguntar qué busca lograr al tener control sobre la asignación de registros?
@HoustonFortney quiero generar un valor de suma de verificación/verificación usando el contenido de todos los registros (también incluirá los valores de CPSR de la PC). El valor será único si las entradas se inicializan de cierta manera. Cualquier cambio en las entradas generará un valor incorrecto.
¿Tal vez sea mejor hacerlo totalmente en ensamblador (en un archivo .ams)?
Para poner el comentario de Wouter con más fuerza: si necesita controlar el estado de todos los registros de la CPU, entonces NO PUEDE usar un compilador C, que usa la mayoría, si no todos, los registros para sus propios fines. De eso se tratan todas las advertencias. DEBE hacer esto en ensamblaje puro, tal vez como una función a la que puede llamar desde C, pero luego necesita escribir su función para que sea compatible con el entorno de tiempo de ejecución de C.

Respuestas (2)

El IDE que está utilizando, como la mayoría de los IDE, automatiza la inicialización de la CPU al nivel más bajo. Se encarga de generar, por ejemplo, el contenido de la tabla de vectores.

Al utilizar un lenguaje de mayor nivel que ensamblador, todo lo relacionado con la manipulación de registros e inicialización queda bastante oculto, especialmente si se habilitan optimizaciones del compilador.

Creo que debería escribir el código crítico en ensamblador para garantizar el rendimiento de la CPU. Quizás el resto de su aplicación pueda desarrollarse al más alto nivel, teniendo el código de bajo nivel como biblioteca.

Sí, eso es exactamente lo que hice finalmente, funciona bien ahora :)

Uso la siguiente función en mi código con 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
}