Forum: Compiler & IDEs Interpretation AVR-GCC *.lss File


von Sebastian S. (rudimentor)


Lesenswert?

Hallo,
ich versuche gerade den Assemblercode, der als .lss von AVR-GCC mit 
ausgegeben wird zu verstehen.

Jetzt gibt es natürlich viele Tuts die den Assemblercode erklären jedoch 
oft nur sehr rudimentär. Mir geht es eher hier um das drumherum. Das lss 
File sieht wesentlich komplexer aus und enthält leider Teile sowohl 
hinter den Befehlen (Wer mit wem) als auch davor, die ich nicht mit den 
gängigen Einführungen, Tuts oder Forenbeiträgen erschlagen konnte.

Als Bsp:
Zeile     ?       Befehl  (Wer mit wem)   Kommentar
aaa:  1f 86         std  Y+15, r1         ;
aac:  27 c0         rjmp  .+78            ;

1. Was bedeuten denn die Angaben unter Fragezeichen und falls ich die 
anderen Spalten falsch interpretiere korrigiert mich bitte.

2. Der C-Code steht vor dem Assembler und dann folgen Befehle. Ein paar 
Zeilen später wird der selbe C-Code wiederholt und danach folgen NICHT 
die selben Assembleranweisungen wie zuvor. Wie ist das zu verstehen?

Und bezüglich des Codes:

1. Was bedeutet das Y bzw. wo wird das belegt? (z.B. std  Y+15, r1)

2. Wie ist die Sprungmarke .+78 zu verstehen, bzw. wo muß ich die Zeile
   suchen, an der es weitergeht?

Vielen Dank schon mal im Vorraus....

von Oliver (Gast)


Lesenswert?

Sebastian S. schrieb:
> Jetzt gibt es natürlich viele Tuts die den Assemblercode erklären jedoch
> oft nur sehr rudimentär.

Auch das rudimentärste Tutorial sollte den grössten Teil deiner Fragen 
beantworten können. Du musst es halt lesen. z.b.

http://www.avr-asm-tutorial.net/avr_de/beginner/index.html

Sebastian S. schrieb:
> 1. Was bedeuten denn die Angaben unter Fragezeichen und falls ich die
> anderen Spalten falsch interpretiere korrigiert mich bitte.

Unter dem ? steht der Hexcode des Befehls (das, was da wirklich im 
Speicher steht), der dann in lesbare Mnemonics üebersetzt wird.

Sebastian S. schrieb:
> 2. Der C-Code steht vor dem Assembler und dann folgen Befehle. Ein paar
> Zeilen später wird der selbe C-Code wiederholt und danach folgen NICHT
> die selben Assembleranweisungen wie zuvor. Wie ist das zu verstehen?

Gar nicht. Die eingestreuten C-Zeilen sind bei eingeschaltetem 
Optimierer mehr oder weniger sinnlos im Assemblercode verteilt. Ohne 
Optimierung passt das, mit nicht.

für den Rest: s.o.

Oliver

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Sebastian S. schrieb:

> 1. Was bedeuten denn die Angaben unter Fragezeichen

Das ist der Opcode, der disassembliert worden ist.

> 2. Der C-Code steht vor dem Assembler und dann folgen Befehle.

Naja, der C-Code steht irgendwo.  Die Optimierung des Compilers
führt nämlich dazu, dass da alles andere als irgendwas annähernd
lineares als Übersetzung herauskommt.

Meine Meinung: die ganzen lss-Dateien sind Unfug, weil sie in
ihrem Mischmasch kaum zu verstehen sind.  Ich zumindest lege
mir auf die eine Seite das pure Disassemblerlisting, rechts
daneben den C-Code, und dann versuche ich zu verstehen, welche
Logik im Assemblercode realisiert worden ist und wie sie zum
C-Code passt.

> 1. Was bedeutet das Y bzw. wo wird das belegt? (z.B. std  Y+15, r1)

Siehe Datenblatt zum AVR: X, Y und Z sind Zugriffe über die
Zeigerregisterpaare (r26:27 => X, r28:29 => Y, r30:31 => Z).

> 2. Wie ist die Sprungmarke .+78 zu verstehen,

78 Bytes hinter dem aktuellen location counter.

> bzw. wo muß ich die Zeile
>    suchen, an der es weitergeht?

Sprungmarke?  Das ist kein Assembler, sondern ein Disassembler.
Marken kennt der nicht.

Allerdings sollte der Disassembler normalerweise auch eine
Absolutadresse ausrechnen.  Hier ein Beispiel für ein Disassembler-
listing eines wahllos rausgegriffenen Stückchens aus dem Startup-
Code:
1
000003a6 <__do_clear_bss>:
2
     3a6:       19 e1           ldi     r17, 0x19       ; 25
3
     3a8:       aa e1           ldi     r26, 0x1A       ; 26
4
     3aa:       b3 e0           ldi     r27, 0x03       ; 3
5
     3ac:       01 c0           rjmp    .+2             ; 0x3b0 <.do_clear_bss_start>
6
7
000003ae <.do_clear_bss_loop>:
8
     3ae:       1d 92           st      X+, r1
9
10
000003b0 <.do_clear_bss_start>:
11
     3b0:       ae 39           cpi     r26, 0x9E       ; 158

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Zum Erzeugen eines Assembler-Dumps gibt es mehrer Möglichkeiten, die in 
[1] beschrieben sind, wie z.B.:

* Dump des Compilers (avr-gcc)
* Dump des Assemblers (avr-as)
* Disassembly aus einem Objekt (o-Datei) mit avr-objdump
* Disassembly aus einem Executable (elf-Datei) mit avr-objdump
* Disassembly aus einem Executable (ihex-Datei) mit avr-objdump

Je nach Gusto wird man diese oder jene Möglichkeit wählen; ich bevorzuge 
die Ausgabe des Compilers (s-File), weil es die meisten Infos enthält.

[1] http://rn-wissen.de/index.php/Assembler-Dump_erstellen_mit_avr-gcc

von Sebastian S. (rudimentor)


Lesenswert?

Super...
Danke für die Zahlreichen Antworten!
Ich habe für mein lss File -OO benutzt um zu kompilieren. Das ist doch 
ohne Optimierung, oder? Dennoch war das lss ein bisschen durcheinander 
was die C Anweisungen anging.

>Meine Meinung: die ganzen lss-Dateien sind Unfug, weil sie in
>ihrem Mischmasch kaum zu verstehen sind.  Ich zumindest lege
>mir auf die eine Seite das pure Disassemblerlisting, rechts
>daneben den C-Code, und dann versuche ich zu verstehen, welche
>Logik im Assemblercode realisiert worden ist und wie sie zum
>C-Code passt.

Welches File wäre das denn?

Danke für die Hilfe nochmal und ich werde mich dann noch mal ein 
bisschen tiefer in die Materie reinfuchsen.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Sebastian S. schrieb:

> Welches File wäre das denn?

Es gibt hier nicht "das File".  "Das .lss-File" ist die Ausgabe des
Kommandos

avr-objdump -d -S filename.elf > filename.lss

Wenn du aus diesem Kommando einfach das -S weglässt (welches den
Sourcecode über die Debuginformationen versucht hineinzumischen),
dann bleibt das reine Disassembler-Listing übrig.

Ansonsten sehe ich das wie Johann: der vom Compiler generierte
Assemblercode ist eigentlich das, was am aussagefähigsten ist.  Den
bekommst du entweder, indem du die Datei mit der Option -S statt -c
compilierst (und dann ggf. bei der Option -o einen anderen Dateinamen
angibst; Konvention ist hier die Endung .s), oder indem du dem GCC
die Option -save-temps mitgibst, die ihn veranlasst, all die Zwischen-
dateien in $TMPDIR (/var/tmp auf Unixen, keine Ahnung, wo das bei
Windows liegt) stehen zu lassen.

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.