Hallo, ich bin Anfänger in Assembler und wollte mir nun ein paar Hilfs-funktionen schreiben, die ich dann in einer externen .asm-Datei speichere und bei bedarf zu meinem Hauptprogramm dazulinke (ähnlich wie in C). Kann mir jemand sagen, wie man sowas prinzipiell am Besten macht ? Mit .INCLUDE kann ich eine Datei am Anfang einfügen, aber dadurch überschreibe ich mir meine .DEF- und .EQU-Definitionen. Kann man das nicht irgendwie lokal regeln ? Gruß Ralf
Wenn Du von "linken" redest, dann müsstest Du auch den Linker bemühen. .INCLUDE ist nur das Äquivalent von #include, das Deklarationen, aber eben nicht den Code einbindet. Der Code wird vom Assembler in Objektdateien übersetzt, aus denen der Linker dann den endgültigen ausführbaren Code erzeugt. .INCLUDE ist erforderlich, damit ein Assemblermodul die Symbole kennt, die in einem anderen Assemblermodul definiert sind. C funktioniert auf exakt die gleiche Art und Weise, nur daß erstmal C in Assembler (oder direkt in Objektcode) übersetzt wird. Danach kommt der Linker ... Wie das nun bei Deinem Assembler vonstatten geht, entzieht sich meiner Kenntnist - sowas sollte im Handbuch beschrieben sein.
Hallo Rufus, erstmal Danke für die schnelle Antwort. Ich verwende den AVR-Assembler und das AVR-Studio. Ich habe das Tutorial (hier auf der Seite) durchgearbeitet. Wie ich aber ein Programm auf 2 Dateien aufteilen kann, habe ich nicht gefunden. Ich lade mir mal die ASM.zip bei atmel.com herunter - und hoffe ich finde da etwas. Gruß Ralf
Da der Assembler ja nicht wissen kann, ob ne "Funktion" gebraucht wird, kann er nicht entscheiden, ober die Befehle nun mitnehmen muss oder nicht, deswegen: ".include" ist genau das gleiche, als würde an dieser stelle die Datei stehen.. Entsprechend überschreibst du deine .DEF und .EQUs nicht.., aber es ist unvorteilshaft Porgrammtext ganz oben einzufügen, deswegen: Befehle erst UNTER der INIT-Routine (oder der Routine, die durch den Reset-IRQ angesprungen wird) anhängen, so machs ich immer. (so siehts zumindest bei AVR aus ... bzw. so hab ichs rausgefunden G) dave
Hier noch nen Beispiel: .include "m32def.inc" .include "header.asm" .equ debug_mode = 0 .equ passwort_active = 0 ;------------------------------ ; allgemein ;------------------------------ .equ clock = 8000000 .equ preload1 = (clock/256) .equ baudrate = 38400 .equ baud_wert = clock/(16*baudrate)-1 ;---------------------------------- ; F L A S H ;---------------------------------- ;---------------------------------- ; IRQ - VECTORS ;---------------------------------- .cseg .org 0 rjmp init .org 0x008 rjmp t2_ocie2 .org 0x00e rjmp t1_ocie1a ;.org 0x016 ; rjmp t0_ovf ;---------------------------------- ; INIT ;---------------------------------- init: ; stack pointer ldi temp1, LOW(RAMEND) out SPL, temp1 ldi temp1, HIGH(RAMEND) out SPH, temp ist natürlich gekürzt... die m32def.inc ist klar, was es ist, und im header sind die Register-Definitionen,die Aufteilung vom Ram und andres .EQU. Am Ende der Datei (nach Zeilenweise Code (meist IRQs)) gehts dann so zu Ende: ;--------------------------------- ; PC-KOMMUNIKATION ;--------------------------------- serial: ret serial_out: sbis UCSRA,UDRE rjmp serial_out out UDR, temp1 ret .include "lcd.asm" .include "menu.asm" Und das ist dann richtiger Code... und funktionieren tuts auch noch. dave
Hallo dave, Danke für den Tipp. Hab ich Dich richtig verstanden: die .INCLUDE-Anweisung mit den Hilfsprogrammen erst am Ende der des Hauptprogramms einfügen ? Ist das nicht ein bischen ... durcheinander ? Gruß Ralf
Hallo dave, ich hab Dich richtig verstanden :). Danke nochmal für den Tipp. Bei mir funktioniert das auch. Gruß Ralf
Schlag dir das mit dem Hilfsprogramm aussem Kopf.. Es ist ganz und gar nur zur Übersichtlichkeit. Der "Text" aus der includeten Datei wir beim kompilieren einfach an die Stelle gesetzt, wo es steht... du könntest genau so, das machen: .include "header.asm" .include "stackpointer.asm" .include "timer0.asm" .include "timer1.asm" .include "tasterabfrage.asm" .include "egal.was" Oder du kannst es auch ohne jegliches include machen, doch wenn du z.b. (wie ich) an dem Menü rumschreibst, dann haste da schon genug Zeilen und willst nicht noch das Hauptprogramm hin-und-her scrollen. Ich kenn mich jetzt zwar nicht bei C aus, aber da wird so ne angehängte Datei (oder nur Header Datein?) einfach nur als Option angesehn.. Wenn man sie aufruft, dann wird sie mitkompiliert. dave ps. aber solange es funktioniert G... nerver touch a running system
Theoretisch kann man auch verschiedene Assemblerfiles zusammen linken, aber praktisch macht das kaum einer. Man muß dann nämlich noch nen Haufen Verwaltungskrams mit einfügen, damit der Assembler verschiebbaren Code erzeugt und der Linker weiß, wo eine Funktion anfängt, wo sie endet und welche Daten dazugehören. Schreib einfach mal ne leere Funktion in C und lasse sie nach Assembler übersetzen, da wird Dir schwarz vor Augen, was da für ein Wust an Text fabriziert wird. Deshalb assembliert man besser nur ein File und includiert die einzelnen Unterfunktionen. Da die Include-Reihenfolge auch die Codeplazierung bestimmt, sollte man Unterfunktionen immer am Ende includieren bzw. frühestens nach der Interruptvektortabelle. Braucht man Unterfunktionen nur einmal, kann man sie auch genau an der Stelle includieren, wo sie ausgeführt werden sollen, das spart den CALL und das RET ein. Peter
Danke dave, Peter, jetzt ist mir das schon klarer. Ich glaub ich mach das so ähnlich wie dave in seinem Beispiel. Eine Datei für die Definitionen (ich nehm mal an das meinst Du mit header.asm ?!), dann mein 'RJMP main', dann die .INCLUDE "Hilfsfct.asm" und dann 'main:'. Sollte so funktionieren. An Peter: Das mit dem 'zusammenlinken' hab ich anders gemeint. Ich wollte nur wiederverwendbare Programmteile in eine zweite Datei auslagen und dann einbinden (-> -INCLUDE). Also nochmal Danke an Alle. Gruß Ralf
Mach die Hilfsfunktionen ans Ende von der Datei, solange sie noch mit RCALL erreichbar sind. Ja, header.asm da sind die Definitionen drin. Du hasses ja verstanden ;) Wie dus jetzt machst, musste für dich selbst finden.. und AVR-Studio zeigt auch immer schön errors an. dave
@Peter: Deine Herangehensweise mag bei heutigen Entwicklungssystemen die praktikable sein, aber ich würde sie allenfalls pragmatisch nennen. Ich habe größere Projekte in 6809-Assembler geschrieben, und das auf Entwicklungssystemen, wo ich froh um jedes bisschen Zeitersparnis war. Ein anständiger Assembler & Linker hat mir - zusammen mit einem Librarymanager - da deutlich geholfen. (Das Entwicklungssystem war an den Exorciser von Motorola angelehnt, hatte 1 MHz Takt, 48 kByte RAM und arbeitete mit 8"-Diskettenlaufwerken, die nicht wirklich schnell waren. Das suboptimale Dateisystem sorgte für wirklich lange Assemblierzeiten, was den Grundstock meiner Kaffeeabhängigkeit legte) Die pragmatische Herangehensweise ist in größeren Projekten nicht nur aus Geschwindigkeitsgründen problematisch - werden beispielsweise lokale Label verwendet (das sind Symbole, die nur innerhalb eines Modules "sichtbar" sind), dann muss man beim .INCLUD(E)ieren aufpassen, diese nicht mehrfach zu verwenden. Möchte man fremden Code verwenden, muss man diesen vorsichtig auf darin enthaltene Symbole überprüfen - das kann bei Objektdateien prinzipiell einfacher sein. Die Tatsache, ob der Assembler oder der Linker eine Fehlermeldung ausspuckt, kann ein bedeutender Hinweis sein ... Die Arbeitsweise mit dem (relokatiblen) Assembler erscheint zunächst aufwendiger - beim Deklarieren von Variablen sollte man nicht deren Speicherort, sondern nur deren Namen, Größe und Linkersichtbarkeit definieren. Der Linker kümmert sich dann darum, alle Variablen etc. aller Module zu organisieren. Diese Konzepte sollten einem vertraut sein, wenn man mit C arbeitet, da sie sich 1:1 abbilden lassen. (Ein lokales Label ist beispielsweise äquivalent zu einer als static deklarierten Funktion). Da im Threadtitel von linken die Rede war, erschien mir meine Beschreibung der Vorgehensweise die naheliegendere.
@Rufus, der Geschwindigkeitsfaktor dürfte zumindest bei µCs Schnee von gestern sein. Ein üblicher 3GHz PC ist mit Assemblieren fertig, da hat man die Maustaste kaum wieder losgelassen. Und größere Programme macht man besser in C und nicht in Assembler. Aber auch bei der C-Programmierung habe ich mit einem Objektfile angefangen und includiert. Erst viel später habe ich größere Programme wirklich in mehrere C-Files unterteilt. Allerdings machen es einem die Windows-IDEs etwas schwer, man muß jedes File manuell dem Build hinzufügen. Deshalb bevorzuge ich das Compilieren im DOS-Fenster, da nehme ich eine Batch, die vollautomatisch alle *.C-Files im Verzeichnis zusammen linkt. Auch wenn dabei immer sämtliche Sourcen neu compiliert werden, stellt das keinen erwähnenswerten Zeitfaktor dar. Peter
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.