mikrocontroller.net

Forum: Compiler & IDEs Alternative zu 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.
Autor: Torsten R. (Firma: robitzki.de) (torstenrobitzki)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich schreibe gerade für meine BLE Debug Probe einige Flash Routinen für 
verschiedene Microcontroller.

Diese Routinen werden ins RAM des Targets geladen und dort ausgeführt, 
um das flash der Controller zu beschreiben. Ausgeführt werden diese 
Routinen, in dem die Parameter direkt in Register geladen werden, der PC 
auf den Start der Routine gesetzt wird und die CPU nach einen Halt 
wieder los gelassen wird. Am Ende der rennt die Routine auf einen 
Break-Point und der Debugger wartet auf das Erreichen des Breakpoints. 
Dann kann sich der Debugger das Ergebnis der  Routine in einem Register 
abholen (so grob skizziert).

Im Moment geht es ausschließlich um ARM Assembler (Thumb). Einige Flash 
Controller sind allerdings komplex genug, damit es recht schnell 
unübersichtlich wird, diese Routinen von Hand in Assembler zu schreiben.

Welche Alternativen hätte ich? (Einen Stack könnte ich wohl in der Regel 
aufsetzen). Verwendete Toolchain ist arm-none-eabi-gcc.

schöne Grüße,

Torsten

Autor: Dr. Sommer (Gast)
Datum:

Bewertung
3 lesenswert
nicht lesenswert
Seltsame Frage...

Torsten R. schrieb:
> Verwendete Toolchain ist arm-none-eabi-gcc.

Das unterstützt C, C++ und Assembler. Die sollten alle drei gehen. Wo 
ist das Problem?

Autor: Torsten R. (Firma: robitzki.de) (torstenrobitzki)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dr. Sommer schrieb:
> Seltsame Frage...
>
> Torsten R. schrieb:
>> Verwendete Toolchain ist arm-none-eabi-gcc.
>
> Das unterstützt C, C++ und Assembler. Die sollten alle drei gehen. Wo
> ist das Problem?

Ich kann in C, C++ keinen ausführbaren Code deklarieren, der ausserhalb 
einer Funktion steht:
start:
    MOV R7, #result_ok
    LDR R3, nvmc_ready                  /* R3 == NVMC_READY                         */
    LDR R4, nvmc_config                 /* R4 == NVMC_CONFIG                        */

    MOV R5, #NVMC_CONFIG_WEN_Wen
    STR R5, [ R4 ]                      /* NVMC_CONFIG = NVMC_CONFIG_WEN_Wen        */
...
    BKPT

Aufgerufen wird so eine "Routine", in dem ich die CPU des Controllers 
anhalte, die Routine ins RAM lade. Den PC auf den Anfang der Routine 
setze, die Register mit Parametern fülle und die CPU dann wieder weiter 
laufen lasse.

Am Ende der Routine ist dann ein SW-Breakpoint, auf den wartet der 
Debugger.

Ich könnte natürlich von dieser ASM-Routine aus, eine C Funktion 
aufrufen. Ich frage mich, ob es aber ggf. einfacher geht, ohne direkt 
Assembler schreiben zu müssen.

Autor: Torsten R. (Firma: robitzki.de) (torstenrobitzki)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe gerade mal in die Source von der Blackmagic Probe geguckt. Die 
verwenden C Funktionen, der mit `__attribute__((naked))` anotiert ist:
void __attribute__((naked))
efm32_flash_write_stub(uint32_t *dest, uint32_t *src, uint32_t size, uint32_t msc)
{
  ...
}

Die Dokumentation vom GCC sagt dazu aber:
naked
This attribute allows the compiler to construct the requisite function declaration, while allowing the body of the function to be assembly code. The specified function will not have prologue/epilogue sequences generated by the compiler. Only basic asm statements can safely be included in naked functions (see Basic Asm). While using extended asm or a mixture of basic asm and C code may appear to work, they cannot be depended upon to work reliably and are not supported.

Autor: Vincent H. (vinci)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das Problem ist dass es keinerlei Garantie gibt dass Code innerhalb 
einer Funktion nicht munter am Stack herumspielt. Das Attribut entfernt 
lediglich Stackpointer Manipulation am Anfang und Ende einer Funktion, 
nicht aber dazwischen.

Autor: Bernd K. (prof7bit)
Datum:

Bewertung
2 lesenswert
nicht lesenswert
Dann mach halt normale C-Funktionen, auf die paar Byte wirds ja wohl 
nicht ankommen. Initialisier den Stackpointer, ruf die Funktion auf und 
wenn sie zurückkommt lass es in den Breakpoint laufen. Dann hast Du ne 
kleine Hand voll Assembler der immer gleich ist und eine bliebig 
komplexe stinknormale C-Funktion.

Autor: Torsten R. (Firma: robitzki.de) (torstenrobitzki)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vincent H. schrieb:
> Das Problem ist dass es keinerlei Garantie gibt dass Code innerhalb
> einer Funktion nicht munter am Stack herumspielt. Das Attribut entfernt
> lediglich Stackpointer Manipulation am Anfang und Ende einer Funktion,
> nicht aber dazwischen.

Genau, und ich würde den Compiler gerne dazu bringen, z.B. eine 
Fehlermeldung auszugeben, wenn er doch einen Stackframe braucht (z.B. 
weil die Register nicht ausreichen).

Autor: Christopher J. (christopher_j23)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Torsten R. schrieb:
> Vincent H. schrieb:
>> Das Problem ist dass es keinerlei Garantie gibt dass Code innerhalb
>> einer Funktion nicht munter am Stack herumspielt. Das Attribut entfernt
>> lediglich Stackpointer Manipulation am Anfang und Ende einer Funktion,
>> nicht aber dazwischen.
>
> Genau, und ich würde den Compiler gerne dazu bringen, z.B. eine
> Fehlermeldung auszugeben, wenn er doch einen Stackframe braucht (z.B.
> weil die Register nicht ausreichen).

Beim GCC kann man sich mit -fstack-usage den Stackbedarf der einzelnen 
Funktionen ausgeben lassen. Das landet dann in einer .su-Datei die du 
mit einem Python-Script o.Ä., aufgerufen durch dein Build-System 
auswerten könntest.

Eine direkte Warnung kannst du ausgeben, wenn du die Compileroption 
-Wstack-usage=byte-size nutzt, wobei byte-size in deinem Fall dann 
logischerweise 0 sein müsste.

Autor: Mike (Gast)
Datum:

Bewertung
-3 lesenswert
nicht lesenswert
>Welche Alternativen hätte ich? (Einen Stack könnte ich wohl in der Regel
>aufsetzen). Verwendete Toolchain ist arm-none-eabi-gcc.

Nimm C, das ist nichts anderes als ein Makro-Assembler!

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]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [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.

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