STM32 Assembler

Gast #5496237
Lesenswert?
• ▲
▼
Hi,

ich verwende ein STM32F4 Board mit FreeRTOS und ich versuche gerade, 
mein Assembler etwas zu verbessern.

unsigned int my_pc = 0x08000890;
_asm __volatile_
(
  "movw R1, #0x0fd0\n"
  "movt R1, #0x1000\n"
  "ldr r15,[r1]\n"
);

Ich speichere in my_pc einen gewünschen, neuen Program-Counter. Der Wert 
0x08... ist der PC an der Stelle unsigned int my_pc. Dannach lade ich 
mir diesen Wert in Register R1 - dabei ist 0x10000fd0 die Adresse im 
Speicher, wo my_pc liegt. Nun möchte ich meinen tatsächlichen PC 
abändern, sodass ich erneut bei unsigned int my_pc lande.
Mit gdb habe ich rausgefunden, dass ich R1 nun tatsächlich 0x10000fd0 
steht. Allerdings komme ich hier in den Trap handler:
prvGetRegistersFromStack (pulFaultStackAddress=0x10000f90
Wieso stimmt die Adresse nicht überein?

Verwende ich nun diesen Code, funktioniert mein Vorhaben wie gewünscht:
unsigned int my_pc = 0x08000890;
_asm __volatile_
(
  "movw R1, #0x0fd0\n"
  "movt R1, #0x1000\n"
  "ldr r4,[r1]\n"
  "mov pc,r4\n"
);
Wo liegt hier das Problem?
Gast #5496248
Lesenswert?
• ▲
▼
Das unterste Bit der Adresse muss 1 sein, sonst weist du den Prozessor 
an, in den ARM-Modus zu wechseln, was der Cortex-M4 nicht kann. Ich 
würde dir empfehlen, erstmal nur mit nacktem Assembler anzufangen, weil 
Inline Assembler noch eine ganze Reihe an Tücken hat und auch noch 
schlecht dokumentiert ist.
#5496259
Lesenswert?
• ▲
▼
Auf einem Cortex-M kann man keinen graden Wert in den PC laden => 
Thumb-Bit muss gesetzt sein, sonst Fault.

In der Version die funktionier muss also noch was anders sein.

Noch eine Kleinigkeit: Der Wert im PC selbst ist grade, wenn man den 
ausliesst. Die "push PC" und BL/BLX Instruktionen handhaben das mit dem 
Thumb Bit korrekt AFAIK (so das man den Wert hinterher einlesen kann, 
Bit 0 hat den Wert 1).
Gast #5496288
Lesenswert?
• ▲
▼
Jim M. schrieb:
> In der Version die funktionier muss also noch was anders sein.

Bei manchen Schreib-Operationen auf den PC wird das Thumb Bit ignoriert, 
und der aktuelle Modus beibehalten. Welche das sind kann ich mir aber 
auch nicht merken :)
"B" schaltet nicht um, "BX" schon, und nur letzteres kann man mit 
Registern als Ziel nutzen.
Gast #5496301
Lesenswert?
• ▲
▼
1
unsigned int my_pc = 0x08000890;
2
void foo() {
3
    asm("bx %0"::"r"(my_pc));
4
    //oder
5
    goto *my_pc;
6
}
1
foo:
2
  push  {r7}
3
  add  r7, sp, #0
4

5
  movw  r3, #:lower16:my_pc
6
  movt  r3, #:upper16:my_pc
7
  ldr  r3, [r3, #0]
8
  bx r3
9

10
  movw  r3, #:lower16:my_pc
11
  movt  r3, #:upper16:my_pc
12
  ldr  r3, [r3, #0]
13
  orr  r3, r3, #1
14
  bx  r3
#5496442
Lesenswert?
• ▲
▼
kilaz schrieb:
> unsigned int my_pc = 0x08000890;
> _asm __volatile_
> (
>   "movw R1, #0x0fd0\n"
>   "movt R1, #0x1000\n"
>   "ldr r15,[r1]\n"
> );

Das kann (neben dem schon erwähnten Thumb-Bit) gut gehen oder auch nicht 
(je nachdem, was sonst noch an C-Code aussenrum ist).

Wenn Du dem C-Compiler Register klaust, ohne ihm das mitzuteilen, geht 
das früher oder später schief. Lies' dir das Kapitel "extended asm" im 
gcc-Handbuch aufmerksam durch.

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.