Forum: Mikrocontroller und Digitale Elektronik STM32 Assembler


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von kilaz (Gast)


Bewertung
0 lesenswert
nicht 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?

von Dr. Sommer (Gast)


Bewertung
0 lesenswert
nicht 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.

von Dr. Sommer (Gast)


Bewertung
0 lesenswert
nicht lesenswert
PS: Direkt in den PC eine Adresse zu schreiben ist etwas unüblich und 
hat gewisse Einschränkungen - normalerweise nimmt man dafür die 
Branch-Anweisung "B".

von Jim M. (turboj)


Bewertung
0 lesenswert
nicht 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).

von Dr. Sommer (Gast)


Bewertung
0 lesenswert
nicht 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.

von foobar (Gast)


Bewertung
0 lesenswert
nicht 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

von no asm (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Schon richtig, wenn die Befehle verfügbar sind: unbedingter Sprung, 
sonst Push-Pop.

von Markus F. (mfro)


Bewertung
-1 lesenswert
nicht 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

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
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.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.