Forum: Compiler & IDEs ARM GCC Problem mit Stack?


von Tobias P. (hubertus)


Lesenswert?

Hallo,
ich bemerke hier ein komisches Problem. Benutze den neuesten 
arm-none-eabi-gcc. Beim Eintritt in eine Funktion wird ja jeweils was 
auf den Stack gelegt:

push {r7, lr}
....
pop {r7, pc}

Ich habe festgestellt, dass das bei mir irgendwie nicht funktioniert!
Wenn ich den Code im Debugger verfolge und an ein solches push / pop 
Statement komme, dann passiert einfach gar nichts.

Beispiel:

SP zeigt auf Adresse 0x20001000
R7 beinhaltet den Wert 0xa5a5

ich führe ein push {r7} aus, nach meinem dafürhalten müsste jetzt der SP 
um 4 dekrementiert werden und an Adresse 0x20000ffc müsste der Wert 
0xa5a5 abgelegt werden. Richtig?

Wenn ich im Cortex M4 Generic User Guide von ARM nachschaue, dann heisst 
es dort "PUSH and POP are synonyms for STMDB and LDMIA." Das heisst doch 
dass

push {r7}

den gleichen Opcode ergeben müsste wie

stmdb {r7}

oder? Macht mein GCC hier aber nicht. Was könnte da das Problem sein?

ich benutze -mcpu=cortex-m4 und -mthumb zum Compilieren.

Auszug aus der Disassembly:
1
  asm("push {r7}");
2
200002c0:  b480        push  {r7}
3
  asm("stmdb sp!, {r7}");
4
200002c2:  f84d 7d04   str.w  r7, [sp, #-4]!

man erkennt gut, dass push anders übersetzt wird, als stmdb, obwohl es 
dieselben Instruktionen sein sollen, gemäss ARM Manual. Mein Prozessor 
macht bei STMDB genau das richtige, er dekrementiert den SP und 
speichert R7 an dieser Adresse; bei PUSH wird nur SP dekrementiert und 
es wird nichts gespeichert.

Es handelt sich um einen Cortex M4F. (Discovery Board)

von Dr. Sommer (Gast)


Lesenswert?

Tobias Plüss schrieb:
> Ich habe festgestellt, dass das bei mir irgendwie nicht funktioniert!
> Wenn ich den Code im Debugger verfolge und an ein solches push / pop
> Statement komme, dann passiert einfach gar nichts.
Vielleicht ein Problem des Debuggers...

Tobias Plüss schrieb:
> oder? Macht mein GCC hier aber nicht. Was könnte da das Problem sein?
Dass die STMDB -Instruktion nur die 32bit-Encoding hat (die es nur in 
ARMv7M gibt), aber PUSH außerdem noch eine 16bit-Encoding, die dann in 
deinem Fall bevorzugt genommen wird.
Kein Problem also, STMDB ist nur 2 Bytes größer.

Tobias Plüss schrieb:
> Wenn ich im Cortex M4 Generic User Guide von ARM nachschaue,
Falsche Datei, du musst im ARMv7M Architecture Reference Manual lesen

von (prx) A. K. (prx)


Lesenswert?

Tobias Plüss schrieb:
> Wenn ich im Cortex M4 Generic User Guide von ARM nachschaue, dann heisst
> es dort "PUSH and POP are synonyms for STMDB and LDMIA."

Eine nicht sonderlich geglückte Aussage. PUSH hat 3 verschiedene 
Codierungen, von denen nur eine dem STMDB entspricht.

von Tobias P. (hubertus)


Lesenswert?

Moin zusammen,
o.k. schaue ich heute noch im ARMv7M Architecture Reference Manual. Aber 
das Problem kommt niemand bekannt vor?
Wie müsste denn ein push {r7} richtig übersetzt werden?

Also bei mir ist der MSP und der PSP korrekt initialisiert und zeigt auf 
das int. RAM, und bei pish {r7} wird zwar der MSP dekrementiert um 4, 
aber an der Adresse, auf die er zeigt, wird nichts gespeichert. Dass es 
ein Problem des Debuggers ist, denke ich nicht, denn wenn ich ein stmdb 
sp!, {r7} ausführe, dann sehe ich, dass es funktioniert.

Problem des Debuggers könnte natürlich sein, aber kann ich fast nicht 
glauben. J-Link.... der hat bisher immer tadellos funktioniert!

von (prx) A. K. (prx)


Lesenswert?

Tobias Plüss schrieb:
> Wie müsste denn ein push {r7} richtig übersetzt werden?

B480

von Tobias P. (hubertus)


Lesenswert?

Dachte ich mir, Compiler bzw. Assembler machen ja eigentlich keine 
Fehler. Wo könnte das Problem denn liegen?
Denn so funktioniert natürlich der Rücksprung aus einer Funktion nicht, 
weil auf dem Stack irgendwelcher Mist liegt... Dann geht er mir sofort 
in den HardFault, wenn ich pop {pc} mache :-(

von Tobias P. (hubertus)


Lesenswert?

Hallo allerseits,

Problem gelöst. Ich habe in meinem GDB initialisierungsskript die Zeile

monitor device STM32F407VG

vergessen. Wird sie eingefügt, dann geht auch das Debuggen einwandfrei, 
Programm läuft sowohl aus dem Flash als auch aus dem RAM. Dass eine 
solche Initialisierung noch benötigt wird, steht nirgends in den Segger 
Manuals :-)

Wäre noch interessant zu wissen, was die Zeile bewirkt. Im Prinzip 
sollte ja das Downloaden & Debuggen unabhängig vom Device funktionieren.

von Dr. Sommer (Gast)


Lesenswert?

Tobias Plüss schrieb:
> Dass eine
> solche Initialisierung noch benötigt wird, steht nirgends in den Segger
> Manuals :-)
Bei mir funktionierts auch ohne die, und "monitor device" gibts laut 
Manual nicht. Was allerdings gebraucht wird ist "monitor flash device = 
STM32F407VG" und das steht auch im GDB Server User Guide drin.

Tobias Plüss schrieb:
> Wäre noch interessant zu wissen, was die Zeile bewirkt. Im Prinzip
> sollte ja das Downloaden & Debuggen unabhängig vom Device funktionieren.
Nö, das Flashen ist device-abhängig, da die ARM Architektur nichts bzgl. 
Flash definiert; das macht der Mikrocontroller-Hersteller.

Und hab ichs nicht gesagt, dass da was mit dem Debugger nicht stimmt :o)

von Tobias P. (hubertus)


Lesenswert?

Ja, sorry, es müsste monitor flash device heissen.
Allerdings lasse ich ja mein Programm aus dem RAM laufen. Daher sollte 
der Flash keine Rolle spielen, dachte ich immer.

Gruss

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.