Initialisieren Sie ARM-Register mit einem bestimmten Wert über die Inline-Assemblierung

Ich muss die ARM-Register meines ARM7TDMI-Entwicklungsboards mithilfe der Inline-Assemblierung auf einen bestimmten Wert initialisieren. Zum Beispiel mache ich derzeit so etwas wie das Folgende:

    #pragma ARM
        void init(char * reg)  {

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

Die Idee ist, den Inhalt jedes Registers hier genau zu kontrollieren. Ich verwende KEIL UVision 5 und es warnt mich, dass dies möglicherweise nicht klug ist. Und wenn man sich den Debugger ansieht, gibt es keine Garantie dafür, dass die Initialisierung gemäß meiner Anfrage erfolgt. Zum Beispiel kann der Wert 0x2 in Register r12 anstelle von r2 gespeichert werden, wie ich es in meiner Inline-Assembly angefordert habe.

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

Beim Lesen der Keil-Dokumentation http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka11441.html wird die Verwendung von Variablennamen empfohlen. Etwas wie das

{
  int val2;

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

Nun, das ist mir nicht gut genug, da ich eine genaue Kontrolle über meine Registerinhalte haben möchte. Wie ist das möglich? Irgendwelche Ideen ?

Danke

Darf ich fragen, was Sie erreichen wollen, indem Sie die Kontrolle über die Registerzuordnung haben?
@HoustonFortney Ich möchte anhand des Inhalts aller Register einen Prüfsummen-/Verifizierungswert generieren (der auch die PC-CPSR-Werte enthält). Der Wert ist eindeutig, wenn die Eingänge auf eine bestimmte Weise initialisiert werden. Jede Änderung der Eingaben erzeugt einen falschen Wert.
Vielleicht besser komplett in Assembler (in einer .ams-Datei)?
Um Wouters Kommentar stärker auszudrücken: Wenn Sie den Status aller CPU-Register steuern müssen, können Sie KEINEN C-Compiler verwenden, der die meisten, wenn nicht alle Register für seine eigenen Zwecke verwendet. Darum geht es bei all den Warnungen. Sie MÜSSEN dies in reiner Assemblierung tun - vielleicht als Funktion, die Sie von C aus aufrufen können, aber dann müssen Sie Ihre Funktion so schreiben, dass sie mit der C-Laufzeitumgebung kompatibel ist.

Antworten (2)

Die von Ihnen verwendete IDE automatisiert, wie die meisten IDEs, die Initialisierung der CPU auf der niedrigsten Ebene. Sie ist beispielsweise für die Generierung des Inhalts der Vektortabelle zuständig.

Bei Verwendung einer höheren Sprache als Assembler ist alles, was mit der Manipulation von Registern und der Initialisierung zu tun hat, ziemlich verborgen, insbesondere wenn Compiler-Optimierungen aktiviert sind.

Ich denke, Sie sollten den kritischen Code in Assembler schreiben , um die Leistung der CPU sicherzustellen. Vielleicht kann der Rest Ihrer Anwendung auf der höchsten Ebene entwickelt werden, wobei der Low-Level-Code als Bibliothek vorhanden ist.

Ja, genau das habe ich endlich gemacht, funktioniert jetzt gut :)

Ich verwende die folgende Funktion in meinem Code mit 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
}