mikrocontroller.net

Forum: Compiler & IDEs undefined reference to `main' in Assembler??


Autor: Peter_Silie (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich brauche dringend eure Hilfe.

Mein erstes winAVR-Projekt ist ein Assemblerprogramm zur Ansteuerung 
eines 8x24 Text-LCD an einem myAVR-ATmega8-Board mit myUSB MK2
winAVR Version 20090313

Ich verwende Assebler weil ich in C noch keine Erfolge erzielen konnte 
:-))

Mein Programm läuft auch schon weitgehend, habe es bis jetzt immer mit 
dem Demoprogramm von myAVR in den Controller reingebügelt. Das gefällt 
mir aber nicht (nach zehn Minuten kommt die erste Meldung von wegen 
"Demoprogramm...bezahlen...bla").

Ich habe nun schon Stunden damit verbracht (länger als für mein 
ASS-Programm!) die Zusammenhänge im Makefile zu verstehen und habe auch 
einige Forenbeträge hierzu gelesen, die mich aber nicht weiterbringen.

Beim "make all" kommt folgende Meldung:

> "make.exe" all

-------- begin --------
avr-gcc (WinAVR 20090313) 4.3.2
Copyright (C) 2008 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is 
NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR 
PURPOSE.


Assembling: disp_m8_v3_1.S
avr-gcc -c -mmcu=atmega8 -I. -x assembler-with-cpp -DF_CPU=3686400 
-Wa,-adhlns=./disp_m8_v3_1.lst,-gstabs,--listing-cont-lines=100 
disp_m8_v3_1.S -o disp_m8_v3_1.o

Linking: disp_m8_v3_1.elf
avr-gcc -mmcu=atmega8 -I.  -MMD -MP -MF .dep/disp_m8_v3_1.elf.d 
disp_m8_v3_1.o --output disp_m8_v3_1.elf 
-Wl,-Map=disp_m8_v3_1.map,--cref     -lm
c:/programme/winavr/bin/../lib/gcc/avr/4.3.2/../../../../avr/lib/avr4/cr 
tm8.o:(.init9+0x0):  undefined reference to `main'
make.exe: *** [disp_m8_v3_1.elf] Error 1

> Process Exit Code: 2
> Time Taken: 00:00

Wofür brauche ich denn diese .elf-Datei überhaupt? Die .hex-Datei wird 
übrigens nicht erzeugt. Ich weis nicht wo ich ansetzen soll.
Danke vorab für jede Hilfe.

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die hex wird aus der elf erzeugt.

In deinem Makefile erzeugt du das Projekt wie ein C-Projekt, und ein 
C-Programm hat eben ne main-Funktion...

Das Problem ist, weil du gegen die crtm8.o links, da steht der 
Startup-Code drinne mit initialisierung von .data, .bss den Constructors 
und danach eben den Spring zu main.

Es gibt ne gcc-Option -nostartfiles (oder so ähnlich, möglicherweise 
auch ne ld-Option), falls das ist, was du suchst...

Johann

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nenn den Beginn deines Hauptprogramms doch einfach main, dann ist der 
linker glücklich, und baut dir auch ein .hex-File. Als Vorlage kannst du 
am besten ein einfaches WinAVR-C-Beispiel kompilieren, und dir im 
.lss-File den erzeugten Assemblercode ansehen.

Oliver

Autor: Peter_Silie (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oh, ich habe ja schon Antworten.

Vielen Dank.

@Johann:
Was du da schreibst ist für mich wie Chinesisch.
Sie Frage, die in dem letzen Satz mitschwingt, kann ich leider nicht 
beantworten :-))
Was ist eine gcc-Option?

@Oliver:
Die Hauptroutine war in dem Grundgerüst ursprünglich mit "main" benannt.
Dabei ist aber das gleiche Problem aufgetreten. Ich habe die 
Hauptroutine dann umbenannt, weil ich dachte der Compiler hällt es für 
einen Verweis auf ein c-Programm, dass ich nicht verwende. Wie gesagt: 
Das Problem war vorher das gleiche, gerade auch nochmal getestet: 
gleicher Fehler.

Was kann ich da machen?

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter_Silie schrieb:

> Die Hauptroutine war in dem Grundgerüst ursprünglich mit "main" benannt.
> Dabei ist aber das gleiche Problem aufgetreten.

Dann vermutlich das .global vergessen.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Ich habe nun schon Stunden damit verbracht (länger als für mein
> ASS-Programm!) die Zusammenhänge im Makefile

Mein Rat

Für Assembler nimm das AVR-Studio
Für C nimm ebenfalls das AVR-Sudio

Autor: Peter Silie (peter_silie)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stefan Ernst schrieb:

> ...
> Dann vermutlich das .global vergessen.

Danke für den Hinweis

Stimmt. Ich wusste ja nicht, dass ich es brauche :)
Wohin und wie müsste es denn?

Autor: Peter Silie (peter_silie)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
>
> Mein Rat
>
> Für Assembler nimm das AVR-Studio
> Für C nimm ebenfalls das AVR-Studio

Danke für den Tipp.
Das AVR-Studio habe ich auch schon installiert, bin aber von dem 
Funktionumfang fast erschlagen worden =:-|
Damit wollte ich mich vertraut machen wenn ich in C-Programmierung 
einsteige und den geplanten ATxmega verwende.
Ich kann ja noch gar nicht beurteilen welches Programm für meine Zwecke 
besser geeignet ist.

AVR-Studio scheint mir auch eine Testversion zu sein.
winAVR ist etwas übersichtlicher, hier stecken aber die Stolperfallen im 
Makefile

Habe schon einige Forenbeiträge gelesen, am Ende ist es wohl 
Geschmackssache.
Werde das aber gleich mal ausprobieren.

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter_Silie schrieb:

> @Johann:
> Was du da schreibst ist für mich wie Chinesisch.

Naja, es ist das, was du in deinem Makefile machst...

Peter Silie schrieb:
> Karl heinz Buchegger schrieb:
>>
>> Mein Rat
>>
>> Für Assembler nimm das AVR-Studio
>> Für C nimm ebenfalls das AVR-Studio
>
> Danke für den Tipp.
> Das AVR-Studio habe ich auch schon installiert, bin aber von dem
> Funktionumfang fast erschlagen worden =:-|

Jepp, ist nicht jedermanns Sache. Ich mag's auch nicht.

Zunächst solltest du dich mal für die Sprache entscheiden, also C, 
Atmel-Assembler oder GNU-Assembler. Letztere beiden sind nicht 
identisch. Während Atmel-ASM besser im AStudio unterstützt ist, kannst 
du letzteren gut innerhalb von C-Projekten verwenden und C von Assembler 
aus verwenden und umgekehrt.

> winAVR ist etwas übersichtlicher, hier stecken aber die Stolperfallen im
> Makefile

Die Frage ist, warum die ein Makefile, das offenbar für ein C-Projekt 
gedacht ist, für ein reines ASM-Projekt hernimmst. C-Programme haben 
bestimmte (nicht viele) Konventionen, zB daß es eine main() gibt und daß 
globale Variablen initialisiert werden etc. In ASM ist das nicht der 
Fall.

Es ist nicht unbedingt Zeitverschwendung, sich mit make bzw. Makefiles 
auseinanderzuseten. Automatisch erzeugte Makefiles sind schnell erzeugt, 
aber leicht verständlich und nervensparend sind sie nicht unbedingt. 
Trifft mehr oder weniger aber für alle Makefiles zu ;-)

Johann

Autor: Peter Silie (peter_silie)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Johann L. schrieb:

> Zunächst solltest du dich mal für die Sprache entscheiden, also C,
> Atmel-Assembler oder GNU-Assembler. Letztere beiden sind nicht
> identisch. Während Atmel-ASM besser im AStudio unterstützt ist, kannst
> du letzteren gut innerhalb von C-Projekten verwenden und C von Assembler
> aus verwenden und umgekehrt.

Das habe ich auch schon festgestellt :-(


> Die Frage ist, warum die ein Makefile, das offenbar für ein C-Projekt
> gedacht ist, für ein reines ASM-Projekt hernimmst. C-Programme haben
> bestimmte (nicht viele) Konventionen, zB daß es eine main() gibt und daß
> globale Variablen initialisiert werden etc. In ASM ist das nicht der
> Fall.

Ich habe das makefile über das von "MFile" mitgebrachte Template 
erzeugt.
Keine Ahnung wie ich das für ASM umwurschteln soll, da ich nicht weis 
welche Einträge zwingend sind (und wofür), habe ich es so gelassen.

> Es ist nicht unbedingt Zeitverschwendung, sich mit make bzw. Makefiles
> auseinanderzuseten. Automatisch erzeugte Makefiles sind schnell erzeugt,
> aber leicht verständlich und nervensparend sind sie nicht unbedingt.
> Trifft mehr oder weniger aber für alle Makefiles zu ;-)

Würde mich schon gerne damit befassen, finde aber keinen Einstieg.
Da bräuchte ich wohl etwas Hilfe. Kannst Du mir evtl. sagen wie ich das 
Makefile anpassen muss? Die Einträge für den C-compiler habe ich wohl 
schon gesehen. Kann ich die einfach löschen? Was ist dann mit diesem 
"Linker"??

Werde heute Abend nochmal reinschauen
Vielen Dank für die Hilfe :-)
Andreas

Autor: Ludger Manten (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Johann L. (gjlayde) Benutzerseite
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Ludger Manten schrieb:
> Schau mal hier:
>
> Beitrag "Minimalprogramm WINAVR Assembler (native)"

Damit ergibt sich das gleiche Problem, weil keine main darin ist. Oder 
man muss eben von Hand seine Makefiles machen -- mach ich überigens 
auch, weil mir mfile zu kompliziert ist.

Ein Minimalbeispiel könnte wie im Anhang aussehen, wobei ganz minimal 
ist es nicht. Es definiert eine ISR nun initialisiert globale Daten. 
Geschrieben ist es für einen ATmega48/88/168.

Übersetzen kann man zB mit
avr-gcc -mmcu=atmegsa88 minimal.S -o minimal.elf

Es wird dann automatisch ne Vektor-Tabell aufgebaut und .data 
initialisiert (IRQs aktivieren geht natürlich simpler per SEI:
minimal.elf:     file format elf32-avr

Disassembly of section .text:

00000000 <__vectors>:
   0:  19 c0         rjmp  .+50       ; 0x34 <__ctors_end>
   2:  2a c0         rjmp  .+84       ; 0x58 <__bad_interrupt>
   4:  29 c0         rjmp  .+82       ; 0x58 <__bad_interrupt>
   6:  28 c0         rjmp  .+80       ; 0x58 <__bad_interrupt>
   8:  27 c0         rjmp  .+78       ; 0x58 <__bad_interrupt>
   a:  26 c0         rjmp  .+76       ; 0x58 <__bad_interrupt>
   c:  25 c0         rjmp  .+74       ; 0x58 <__bad_interrupt>
   e:  38 c0         rjmp  .+112      ; 0x80 <__vector_7>
  10:  23 c0         rjmp  .+70       ; 0x58 <__bad_interrupt>
  12:  22 c0         rjmp  .+68       ; 0x58 <__bad_interrupt>
  14:  21 c0         rjmp  .+66       ; 0x58 <__bad_interrupt>
  16:  20 c0         rjmp  .+64       ; 0x58 <__bad_interrupt>
  18:  1f c0         rjmp  .+62       ; 0x58 <__bad_interrupt>
  1a:  1e c0         rjmp  .+60       ; 0x58 <__bad_interrupt>
  1c:  1d c0         rjmp  .+58       ; 0x58 <__bad_interrupt>
  1e:  1c c0         rjmp  .+56       ; 0x58 <__bad_interrupt>
  20:  1b c0         rjmp  .+54       ; 0x58 <__bad_interrupt>
  22:  1a c0         rjmp  .+52       ; 0x58 <__bad_interrupt>
  24:  19 c0         rjmp  .+50       ; 0x58 <__bad_interrupt>
  26:  18 c0         rjmp  .+48       ; 0x58 <__bad_interrupt>
  28:  17 c0         rjmp  .+46       ; 0x58 <__bad_interrupt>
  2a:  16 c0         rjmp  .+44       ; 0x58 <__bad_interrupt>
  2c:  15 c0         rjmp  .+42       ; 0x58 <__bad_interrupt>
  2e:  14 c0         rjmp  .+40       ; 0x58 <__bad_interrupt>
  30:  13 c0         rjmp  .+38       ; 0x58 <__bad_interrupt>
  32:  12 c0         rjmp  .+36       ; 0x58 <__bad_interrupt>

00000034 <__ctors_end>:
  34:  11 24         eor  r1, r1
  36:  1f be         out  0x3f, r1  ; 63
  38:  cf ef         ldi  r28, 0xFF  ; 255
  3a:  d4 e0         ldi  r29, 0x04  ; 4
  3c:  de bf         out  0x3e, r29  ; 62
  3e:  cd bf         out  0x3d, r28  ; 61

00000040 <__do_copy_data>:
  40:  11 e0         ldi  r17, 0x01  ; 1
  42:  a0 e0         ldi  r26, 0x00  ; 0
  44:  b1 e0         ldi  r27, 0x01  ; 1
  46:  e4 e8         ldi  r30, 0x84  ; 132
  48:  f0 e0         ldi  r31, 0x00  ; 0
  4a:  02 c0         rjmp  .+4        ; 0x50 <.do_copy_data_start>

0000004c <.do_copy_data_loop>:
  4c:  05 90         lpm  r0, Z+
  4e:  0d 92         st  X+, r0

00000050 <.do_copy_data_start>:
  50:  a2 30         cpi  r26, 0x02  ; 2
  52:  b1 07         cpc  r27, r17
  54:  d9 f7         brne  .-10       ; 0x4c <.do_copy_data_loop>
  56:  01 c0         rjmp  .+2        ; 0x5a <main>

00000058 <__bad_interrupt>:
  58:  d3 cf         rjmp  .-90       ; 0x0 <__vectors>

0000005a <main>:
  5a:  00 91 00 01   lds  r16, 0x0100
  5e:  10 91 01 01   lds  r17, 0x0101
  62:  22 e0         ldi  r18, 0x02  ; 2
  64:  20 93 b0 00   sts  0x00B0, r18
  68:  22 e0         ldi  r18, 0x02  ; 2
  6a:  20 93 b1 00   sts  0x00B1, r18
  6e:  2d e3         ldi  r18, 0x3D  ; 61
  70:  20 93 b3 00   sts  0x00B3, r18
  74:  2f b7         in  r18, 0x3f  ; 63
  76:  20 68         ori  r18, 0x80  ; 128
  78:  2f bf         out  0x3f, r18  ; 63
  7a:  20 9a         sbi  0x04, 0  ; 4
  7c:  ff cf         rjmp  .-2        ; 0x7c <main+0x22>
  7e:  08 95         ret

00000080 <__vector_7>:
  80:  18 9a         sbi  0x03, 0  ; 3
  82:  18 95         reti

Johann

Autor: Peter Silie (peter_silie)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für die freundliche Hilfestellung, aber leider produziert das 
Miniprogramm auch Fehlermeldungen...

Ich bin jetzt mal dem Wink gefolgt, es mit AVR-Studio zu versuchen.
Dazu habe ich mein bisheriges Programm geladen und angepasst.
Die simulation läuft scheinbar auch, ich habe nur noch nicht 
herausgefunden wie man Portzustände simuliert, damit das Programm auch 
was zu schaffen hat.

Zumindest bekomme ich beim "build"-Prozess keine Fehlermeldungen :-))

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter Silie schrieb:
> Danke für die freundliche Hilfestellung, aber leider produziert das
> Miniprogramm auch Fehlermeldungen...

"Es gibt nen Fehler" ist die beste Fehlerbeschreibung überhaupt. Absolut 
nutzlos, à la "nachts ist kälter als draussen"... Bingo.

Autor: Ludger Manten (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hatte doch die Architekturen als Kommentar ins makefile geschrieben. 
Fuer Deinen Mega8 must du statt -mavr3 (fuer meinen 103er) -mavr4 
eintragen.

Danach kann ich es zumindest hier fuer einen Mega8 fehlerfrei umsetzen.

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ludger Manten schrieb:
> Ich hatte doch die Architekturen als Kommentar ins makefile geschrieben.
> Fuer Deinen Mega8 must du statt -mavr3 (fuer meinen 103er) -mavr4
> eintragen.

Doch wohl -mmcu=avr4?
Oder besser den µC direkt angeben.

Autor: Peter Silie (peter_silie)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Johann L. schrieb:

> ...
> Doch wohl -mmcu=avr4?
> Oder besser den µC direkt angeben.

Bitte nicht falsch verstehen. Aber weil mir das alles spanisch vorkommt 
und ich nicht einmal beurteilen kann, ob es sich hier (oder da) um einen 
Tippfehler handelt oder ob ich es nur nicht verstehe, habe ich mich 
entschieden das Problem zu vertagen.

Ich werde wohl doch erstmal AVR-Studio arbeiten. Bin gestern schon ein 
Stück weiter gekommen. Compilieren, Brennen und Debugging funktionieren 
hier und das reicht mir eigentlich

Deswegen habe ich das Problem bewusst nicht weiter ausgeführt, um das 
Thema nicht weiter zu strapazieren. Es gibt ja unzählige Beiträge zu 
diesem Stichwort. Wenn ich mal Muße habe, lese ich mich mal durch. Ich 
habe ungefähr verstanden woran es liegen könnte, habe aber jetzt nicht 
die Zeit mich damit zu befassen. Ich will ja nur meinen Controller 
programmieren lernen.
Vielen Dank für die Interstützung.

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.
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.