<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="de">
		<id>https://rn-wissen.de/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Corpsman</id>
		<title>RN-Wissen.de - Benutzerbeiträge [de]</title>
		<link rel="self" type="application/atom+xml" href="https://rn-wissen.de/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Corpsman"/>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Spezial:Beitr%C3%A4ge/Corpsman"/>
		<updated>2026-04-12T08:26:59Z</updated>
		<subtitle>Benutzerbeiträge</subtitle>
		<generator>MediaWiki 1.25.1</generator>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Assembler-Dump_erstellen_mit_avr-gcc&amp;diff=20403</id>
		<title>Assembler-Dump erstellen mit avr-gcc</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Assembler-Dump_erstellen_mit_avr-gcc&amp;diff=20403"/>
				<updated>2012-07-21T09:15:47Z</updated>
		
		<summary type="html">&lt;p&gt;Corpsman: /* Compiler dumpt Assembler */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Aus den unterschiedlichsten Gründen kann es wünschenswert sein, den Assembler-Code zu sehen, den [[avr-gcc]] (oder [[gcc]] im Allgemeinen) aus einer C/C++-Quelle erzeugt. &lt;br /&gt;
Die Ausgabe von gcc geschieht immer in Form von Assembler-Code als ASCII-Datei. Ohne die Angabe spezieller Optionen ist diese Datei jedoch nur temporär und wird nach Beenden der von gcc aufgerufenen Programme &amp;lt;tt&amp;gt;cc1&amp;lt;/tt&amp;gt; ([[Compiler]]), &amp;lt;tt&amp;gt;as&amp;lt;/tt&amp;gt; (Assembler) und &amp;lt;tt&amp;gt;ld&amp;lt;/tt&amp;gt; (Linker) wieder gelöscht.&lt;br /&gt;
&lt;br /&gt;
Ein Weg, an den zu einer C-Quelle gehörenden Assembler-Code zu kommen ist also, diese temporäre Datei zu erhalten. Dazu gibt man die gcc-Option &amp;lt;tt&amp;gt;-save-temps&amp;lt;/tt&amp;gt; an oder man lässt gcc lediglich assemblieren, was mit der Option &amp;lt;tt&amp;gt;-S&amp;lt;/tt&amp;gt; geschieht.&lt;br /&gt;
&lt;br /&gt;
Alternativ dazu kann man mit objcopy ein Disassemble der erzeugten Objekte erzeugen.&lt;br /&gt;
&lt;br /&gt;
Ja nach dem, welchen dieser Möglichkeiten man wählt, enthält die Assembler-Ausgabe unterschiedliche Informationen, Darstellungen und Erläuterungen. Während die Assembler-Ausgabe von gcc direkt als Eingabe für den GNU-Assembler verwendet werden kann, sind die Disassembles und Assembler-Dumps des Assemblers für diesen Zweck nicht verwendbar.&lt;br /&gt;
&lt;br /&gt;
Zum besseren Verständnis der folgenden Abschnitte ist es hilfreich, den  [[avr-gcc/Interna#Ablauf der Codegenerierung|Ablauf der Codegenerierung bei gcc]] zu kennen.&lt;br /&gt;
&lt;br /&gt;
==C-Quelle==&lt;br /&gt;
Als C-Beispiel dient eine kleine Funktion, die einem Foren-Beitrag zu selbigem Thema entstammt. Die Assembler-Dumps sind jedoch nur Snips der kleinen Funktion &amp;lt;tt&amp;gt;foo&amp;lt;/tt&amp;gt;, um die es hier gehen soll. Für komplexere Funktionen oder andere gcc-Targets (etwa &amp;lt;tt&amp;gt;arm7-gcc&amp;lt;/tt&amp;gt;) ist die Vorgehensweise analog. Die &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;-Funktion wird nur gebraucht, damit für das letzte Beispiel ein elf erzeugt werden kann, da hier gegen &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; gelinkt wird.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
unsigned char command_rc5; &lt;br /&gt;
unsigned char Ir_data_tmp; &lt;br /&gt;
&lt;br /&gt;
void foo()&lt;br /&gt;
{&lt;br /&gt;
   uint8_t cmd = command_rc5 &amp;amp; ~(1&amp;lt;&amp;lt;7);&lt;br /&gt;
&lt;br /&gt;
   if (Ir_data_tmp &amp;amp; (1&amp;lt;&amp;lt;5))       &lt;br /&gt;
      cmd |= (1&amp;lt;&amp;lt;7);&lt;br /&gt;
   &lt;br /&gt;
   command_rc5 = cmd;   &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
int main main()&lt;br /&gt;
{&lt;br /&gt;
	return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Compiler dumpt Assembler==&lt;br /&gt;
&lt;br /&gt;
GCC erzeugt seine Ausgabe als Assembler-Datei; allerdings wird diese Assemblerdatei nur temporär angelegt und automatisch wieder gelöscht, nachdem der Assembler diese Datei gelesen und verarbeitet hat.&lt;br /&gt;
&lt;br /&gt;
Um ein Löschen dieser Datei zu unterbinden, dient ein Aufruf folgender Form:&lt;br /&gt;
&lt;br /&gt;
'''Kommando:'''&lt;br /&gt;
 &amp;gt; gcc -c -fverbose-asm -save-temps ...&lt;br /&gt;
&lt;br /&gt;
Die Assembler-Datei wird als &amp;lt;tt&amp;gt;*.s&amp;lt;/tt&amp;gt;-Datei angelegt. Zusätzlich wird mit &amp;lt;tt&amp;gt;-save-temps&amp;lt;/tt&amp;gt; auch die&lt;br /&gt;
präcompilierte Quelle gesichert und zwar mit der Endung &amp;lt;tt&amp;gt;*.i&amp;lt;/tt&amp;gt; für C-Quellen bzw. &amp;lt;tt&amp;gt;*.ii&amp;lt;/tt&amp;gt; für C++-Quellen. Hier die &amp;lt;tt&amp;gt;.s&amp;lt;/tt&amp;gt;-Datei für obige C-Quelle. &amp;lt;tt&amp;gt;-fverbose-asm&amp;lt;/tt&amp;gt; hat die Assembler-Datei mit zusätzlichen, hilfreichen Informationen angereichert, wie&lt;br /&gt;
* Anzahl der gesicherten Register auf dem Stack.&lt;br /&gt;
* Die Größe des Frames, also des Bereichs, in dem lokale Variablen gespeichert werden, die nicht in Registern gehalten werden.&lt;br /&gt;
* Variablennamen soweit verfügbar, bzw. automatisch erzeugte Namen für Hilfsvariablen wie &amp;lt;tt&amp;gt;tmp23&amp;lt;/tt&amp;gt;.&lt;br /&gt;
* Die durch Optimierungsschalter wie &amp;lt;tt&amp;gt;-Os&amp;lt;/tt&amp;gt; aktivierten Schalter.&lt;br /&gt;
&lt;br /&gt;
'''Ausgabe''' (hier für avr-gcc):&lt;br /&gt;
&amp;lt;pre&amp;gt;.global   foo&lt;br /&gt;
        .type   foo, @function&lt;br /&gt;
foo:&lt;br /&gt;
/* prologue: frame size=0 */&lt;br /&gt;
/* prologue end (size=0) */&lt;br /&gt;
        lds r25,command_rc5      ;  cmd, command_rc5&lt;br /&gt;
        andi r25,lo8(127)        ;  cmd,&lt;br /&gt;
        lds r24,Ir_data_tmp      ;  Ir_data_tmp, Ir_data_tmp&lt;br /&gt;
        sbrc r24,5       ;  Ir_data_tmp,&lt;br /&gt;
        ori r25,lo8(-128)        ;  cmd,&lt;br /&gt;
.L2:&lt;br /&gt;
        sts command_rc5,r25      ;  command_rc5, cmd&lt;br /&gt;
/* epilogue: frame size=0 */&lt;br /&gt;
        ret&lt;br /&gt;
/* epilogue end (size=1) */&lt;br /&gt;
/* function foo size 11 (10) */&lt;br /&gt;
        .size   foo, .-foo&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bei diesem Ansatz ist es günstig, ohne Debug-Informationen zu übersetzen, da ansonsten die Assembler-Ausgabe unleserlicher und deutlich größer wird.&lt;br /&gt;
&lt;br /&gt;
==Assembler dumpt Assembler==&lt;br /&gt;
'''Kommando:'''&lt;br /&gt;
 &amp;gt; gcc -Wa,-alhd=dump.s ...&lt;br /&gt;
Die Option &amp;lt;tt&amp;gt;-Wa&amp;lt;/tt&amp;gt; bewirkt, daß die Zeichen nach dem Komma mit an die Assembler-Kommandozeile übergeben werden. Der Assembler wird also zusätzlich mit der Option &amp;lt;tt&amp;gt;-alhd=dump.s&amp;lt;/tt&amp;gt; gestartet, was das Schreiben der Ausgabe bewirkt.&lt;br /&gt;
&lt;br /&gt;
'''Ausgabe:'''&lt;br /&gt;
&amp;lt;pre&amp;gt;  18                      .global foo&lt;br /&gt;
  20                    foo:&lt;br /&gt;
  21                    .LFB2:&lt;br /&gt;
  22                    .LM1:&lt;br /&gt;
  23                    /* prologue: frame size=0 */&lt;br /&gt;
  24                    /* prologue end (size=0) */&lt;br /&gt;
  25                    .LM2:&lt;br /&gt;
  26 0000 9091 0000             lds r25,command_rc5&lt;br /&gt;
  27 0004 9F77                  andi r25,lo8(127)&lt;br /&gt;
  28                    .LM3:&lt;br /&gt;
  29 0006 8091 0000             lds r24,Ir_data_tmp&lt;br /&gt;
  30 000a 85FD                  sbrc r24,5&lt;br /&gt;
  31                    .LM4:&lt;br /&gt;
  32 000c 9068                  ori r25,lo8(-128)&lt;br /&gt;
  33                    .L2:&lt;br /&gt;
  34                    .LM5:&lt;br /&gt;
  35 000e 9093 0000             sts command_rc5,r25&lt;br /&gt;
  36                    /* epilogue: frame size=0 */&lt;br /&gt;
  37 0012 0895                  ret&lt;br /&gt;
  38                    /* epilogue end (size=1) */&lt;br /&gt;
  39                    /* function foo size 11 (10) */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==objdump erzeugt Disassemble==&lt;br /&gt;
=== aus Object (nicht lokatiert)===&lt;br /&gt;
Damit die Quellschnippsel im Dump angezeigt werden muss das Object mit Debug-Informationen erzeugt worden sein, und die Quelle muss noch vorhanden sein.&lt;br /&gt;
&lt;br /&gt;
'''Kommando:'''&lt;br /&gt;
 &amp;gt; avr-objdump -d -S ...&lt;br /&gt;
&lt;br /&gt;
'''Ausgabe:'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
00000000 &amp;lt;foo&amp;gt;:&lt;br /&gt;
uint8_t command_rc5, Ir_data_tmp; &lt;br /&gt;
&lt;br /&gt;
void foo()&lt;br /&gt;
{&lt;br /&gt;
   uint8_t cmd = command_rc5 &amp;amp; ~(1&amp;lt;&amp;lt;7);&lt;br /&gt;
   0:   90 91 00 00     lds     r25, 0x0000&lt;br /&gt;
   4:   9f 77           andi    r25, 0x7F       ; 127&lt;br /&gt;
&lt;br /&gt;
   if (Ir_data_tmp &amp;amp; (1&amp;lt;&amp;lt;5))       &lt;br /&gt;
   6:   80 91 00 00     lds     r24, 0x0000&lt;br /&gt;
   a:   85 fd           sbrc    r24, 5&lt;br /&gt;
      cmd |= (1&amp;lt;&amp;lt;7);&lt;br /&gt;
   c:   90 68           ori     r25, 0x80       ; 128&lt;br /&gt;
   &lt;br /&gt;
   command_rc5 = cmd;   &lt;br /&gt;
   e:   90 93 00 00     sts     0x0000, r25&lt;br /&gt;
  12:   08 95           ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== aus elf (lokatiert)===&lt;br /&gt;
'''Kommando:'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt; avr-objdump -h -S ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Ausgabe:'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0000005c &amp;lt;foo&amp;gt;:&lt;br /&gt;
uint8_t command_rc5, Ir_data_tmp; &lt;br /&gt;
&lt;br /&gt;
void foo()&lt;br /&gt;
{&lt;br /&gt;
   uint8_t cmd = command_rc5 &amp;amp; ~(1&amp;lt;&amp;lt;7);&lt;br /&gt;
  5c:   90 91 60 00     lds     r25, 0x0060&lt;br /&gt;
  60:   9f 77           andi    r25, 0x7F       ; 127&lt;br /&gt;
&lt;br /&gt;
   if (Ir_data_tmp &amp;amp; (1&amp;lt;&amp;lt;5))       &lt;br /&gt;
  62:   80 91 61 00     lds     r24, 0x0061&lt;br /&gt;
  66:   85 fd           sbrc    r24, 5&lt;br /&gt;
      cmd |= (1&amp;lt;&amp;lt;7);&lt;br /&gt;
  68:   90 68           ori     r25, 0x80       ; 128&lt;br /&gt;
   &lt;br /&gt;
   command_rc5 = cmd;   &lt;br /&gt;
  6a:   90 93 60 00     sts     0x0060, r25&lt;br /&gt;
  6e:   08 95           ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== aus ihex (lokatiert)===&lt;br /&gt;
Intel-HEX ist ein recht &amp;quot;dummes&amp;quot; Format, es speichert weder [[avr-gcc/Interna#Sections|Section]]-Informationen noch Symbole, Debug-Informationen oder Quellbezüge. Dementsprechend muss man wissen, wo man nach was zu suchen hat im disassemblierten Spaghetti-Code. Zudem kann objdump nicht wissen, ob eine Sequqnz als Befehl oder als Datum zu interpretieren ist und hat keine Alignment-Info, was zu verwirrenden Disassembles führen kann, wenn objcopy z.B. mitten in einem 4-Byte-Befehl aufsetzt.&lt;br /&gt;
&lt;br /&gt;
Da dieses Format auch nicht weiß, für welche Maschine es codiert, muss man dies wissen und angeben. Hier wurde der Code für einen [[ATmega8]] erzeugt, welcher zur [[avr-gcc#Maschinenspezifische Optionen für avr-gcc|Gruppe &amp;lt;tt&amp;gt;avr4&amp;lt;/tt&amp;gt;]] gehört.&lt;br /&gt;
&lt;br /&gt;
'''Kommando:'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt; avr-objdump -D -mavr4 ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Ausgabe:'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     file format ihex&lt;br /&gt;
&lt;br /&gt;
Disassembly of section .sec1:&lt;br /&gt;
&lt;br /&gt;
00000000 &amp;lt;.sec1&amp;gt;:&lt;br /&gt;
...&lt;br /&gt;
  5c:	90 91 60 00 	lds	r25, 0x0060&lt;br /&gt;
  60:	9f 77       	andi	r25, 0x7F	; 127&lt;br /&gt;
  62:	80 91 61 00 	lds	r24, 0x0061&lt;br /&gt;
  66:	85 fd       	sbrc	r24, 5&lt;br /&gt;
  68:	90 68       	ori	r25, 0x80	; 128&lt;br /&gt;
  6a:	90 93 60 00 	sts	0x0060, r25&lt;br /&gt;
  6e:	08 95       	ret&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Siehe auch==&lt;br /&gt;
* [[avr-gcc]]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Quellcode C]]&lt;br /&gt;
[[Kategorie:Quellcode Assembler AVR]]&lt;br /&gt;
[[Kategorie:Software]]&lt;/div&gt;</summary>
		<author><name>Corpsman</name></author>	</entry>

	</feed>