www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Wie bindet man Unterprogramme in asm ein?


Autor: Moschder (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

ich habe mir in asm ein Programm geschrieben, das für ein 16x2 Display 
sämtliche Routinen enthält.
Wie kann ich dieses Programm in mein eigentliches Hauptprogramm 
einfügen?

Habe es so versucht: mein Hauptprogramm heißt
messung.asm, dort habe ich an den Anfang .include "LCD_routins.asm"
geschrieben, so heißt mein Programm für die LCD Routinen.
Das Programm Messung habe ich im AVR Studio als entry file markiert.
wenn ich das Ganze nun im Debugger laufen lasse beginnt das Programm
mit dem abarbeiten des LCD_routins.asm und das obwohl
es nicht als entry file gekennzeichnet ist. das wiederum bringt den 
Fehler
dass der Stack überläuft, da dieser im messung.asm initialisiert wird 
und nicht im Messung.asm.
Wenn ich nun beide Programme zusammen in ein Fenster schreibe läuft es 
im
Debugger sowie auf meinem ATMEGA8 problemlos.
Also, wie mache ich das wenn ich mehrere Programme zu einem großen
zusammenbauen möchte ohne alles in ein Fenster zu schreiben?


Gruß
Moschder

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Die Include-Anweisung muss ans Ende vom Hauptprogramm. An den Anfang 
kann man  nur Include-Dateien setzen, die KEINEN Programmcode enthalten.

MfG Spess

Autor: Moschder (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
besten Dank :), nun funktionierts.
Du hast mir den Weg zu größerem Code geöffnet.

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Noch ein Hinweis: Include-Dateien sollten keine .org-Anweisungen haben.

MfG Spess

Autor: 6641 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Man kann die ASM anweisungen und die includes mischen. Ich hab zuerst 
die Interrupt tabelle, und dann kommen gleich die Includes. Und dann die 
Makros.

Autor: Moschder (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ok, ist bei mir nicht der Fall, habe überhaupt keine org Anweisungen 
drin,
wie setzte ich die denn sinnvollerweise ein?

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

.org-Anweisungen bewirken, das der nachfolgende Programmcode (in cseg) 
bzw. die Speicherstellen (dseg/eseg) an der Adresse beginnen, die in der 
Org-Anweisung steht.

Noch mal zur Include-Anweisung: Beim Assemblieren wird der Code,der in 
der Include-Datei steht, an dieser Stelle eingefügt. Das geht an jeder 
Stelle (hat 6641 natürlich Recht), wo das nicht stört. Ich bevorzuge das 
Ende des Hauptprogramms.

Erläuterungen findest du auch in der AVR-Studio-Hilfe: 
Assembler->Directives

MfG Spess

Autor: Moschder (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wenn ich nun an der ersten möglichen Speicherstelle mit meinem Code 
beginnen will, wie muß dann dir org anweisung lauten? Und wann macht es 
sinn eben nicht an der ersten Stelle zu beginnen?

Gruß
Moschder

Autor: 6641 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wo man die Includes einfuegt haengt natuerlich sehr mit deren Inhalt 
zusammen. Der ASM ist ein Einpass Assembler. Daher kann man nichts 
baruchen was nicht voerher deklariert wurde. Wenn man nun library 
funktionalitaet zur Verfuegung stellen will, die spaeter gebraucht 
werden kann, dann fuegt man die oben ein, zB HexToByte, ByteToHex, Einen 
generischen Algorithmus, der vorher parametrisiert wird, kommt am Ende 
hin. Ich hab das main() jeweils unten.

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Der Assembler beginnt automatisch an der Speicherstelle 0. Dort muss der 
Sprung zum Anfang des Programms stehen. Der µC fängt nämlich nach jedem 
Reset an dieser Stelle an. Zu deiner Frage: '.org 0'. Schadet zwar 
nicht, ist aber unnötig.

MfG Spess

Autor: 6641 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ein Bootloader beginnt zB nicht an der Stelle Null. Mit ORG kann man 
auch Variablen an eine Adresse setzen.  Sei das nun im RAM oder im 
EEPROM.

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Wo man die Includes einfuegt haengt natuerlich sehr mit deren Inhalt
>zusammen. Der ASM ist ein Einpass Assembler. Daher kann man nichts
>baruchen was nicht voerher deklariert wurde. Wenn man nun library...

Über diese Brücke würde ich nicht gehen. Man kann problemlos auf 
Unterprogramme zugreifen, die hinter dem Aufruf stehen. Der 
AVR-Assembler (mit Sicherheit KEIN Ein-Pass-Assembler) benötigt keine 
Forward-Deklarationen. Und eine main() kennt er schon gar nicht. Ich 
glaube da bringst du etwas durcheinander.

MfG Spess

Autor: Michael U. (amiga)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

@6641:
>Der ASM ist ein Einpass Assembler.

Das bezweifle ich.

Ansonsten:
Der Assembler beginnt mit Programmspeicheradresse 0, wenn man ihm nicht 
mit .org was anderes sagt.

Der AVR beginnt beim Reset an Adresse 0. Dort steht üblicherweise ein 
Sprung zum eigentliche Programmbeginn. Das ist sinnvoll, weil danach 
unmittelbar die IRQ-Vektoren kommen und wenn die nutzen will, muß man 
sie sozusagen freilassen.

Eine (bei AVR) für mich allgemeingültige Methode:
; ATiny2313

; 09.03.2008 M'Soft Berlin

.include "tn2313def.inc"  ; erstmal die Prozessordefinition includen

.include "Definitionen.inc" ; jetzt meine Definitionen, Konstanten, Registernamen, Bitnamen usw. usw

;**** Verktor-Liste ********

.CSEG ; Begin Codesegment, Adresse ist 0 für den Assembler, weil nichts anderes angegebn
  rjmp    reset ; Sprung zum Programmbegin

.org  OVF1addr     ; benutzter IRQ-Vector
  rjmp  irq_overflow

.org  OC0Aaddr
  rjmp  irq_timer

;***** Programm-Beginn ******

;****************************
;  Initialisierungsroutine
;****************************

; Hardware initialisieren

.org  INT_VECTORS_SIZE ; ist in allen AVR-Definitionen definiert und zeigt auf die erste Adresse hinter der IRQ-Vectorliste

reset:
    ldi  TEMP_0,low(RAMEND) ; Stack an das interne Ram-Ende
    out  SPL,TEMP_0

; Port B ********************* nur als Beispiel!!!

    ldi   TEMP_0,(1<<KEY_MODE)|(1<<KEY_CAL) ; PullUp ein Tasten
   out     PORTB,TEMP_0                
    ldi    TEMP_0,(1<<LCD_RS)|(1<<LCD_E)|(1<<LCD_D4)|(1<<LCD_D5)|(1<<LCD_D6)|(1<<LCD_D7)
    out     DDRB,TEMP_0  ; LCD Ausgang

usw. usw.

;************************ 
; Software initialisieren

   clr  MENU
   clr  FLAGS

usw. usw

   sei

;************************
;  Main-Loop
;************************
main:          
   tst  KEY_CODE ; Taste?
   breq  main_end ; nein

usw. usw

;************************
;  Main-End
;************************

.include "IRQ.inc"
.include "LCD.inc"
.include "Subroutinen.inc"
.include "Funktionen.inc"

.include "Tabellen.inc"


Die leere Struktur benutze ich eigentlich für jedes Programm, die 
Reihenfolge der Includes ist egal, die Tabellen (Texte im Flash usw) 
lasse ich an Ende.

Es kann nur passieren, daß beim Assemblieren die Meckermeldung kommt, 
daß die Sprungweite eines RCALL überschritten wurde, Erste Lösung ist 
dann für mich, die Reihenfolge der Includes umzusortieren, der Abstand 
hängt ja nur davon ab, welche Routine aus welchem Includen was aufruft. 
Oft reicht das schon oder umsortieren der Funktionen innerhalb der 
Includes hilft.

Das sind dann alles nur reine Copy-Paste mit etwas überlegung, das 
kostet nichtmal Zeit.

Vielleicht hilft das ja jemandem.

Gruß aus Berlin
Michael

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.