Forum: Mikrocontroller und Digitale Elektronik Assembler Variablen setzen


von Der G. (jonnyk)


Lesenswert?

Hallo Leute habe da mal ne frage zu ASM (nicht inline ASM)

Wenn ich in assembler Variablen deklariere

Lenge_01 EQU 1
Lenge_02 EQU 1
Lenge_23 EQU 1

wie kann ich ihnen werte zuweisen?

also wenn ich folgendes mache passiert leider nix:

LDA 8
STA Lenge_01
LDA 1
STA Lenge_23
LDA 30
STA Lenge_02

Weiss jemand rat?

ich programmiere mit einem C167 von infineon.
Es würde mich auch weiter bringen wenn jemand ein beispiel für einen 
anderen µC hat. Oder zumindestens einen Denkanstoß wie ich es 
realisieren kann.

von Christian Erker (Gast)


Lesenswert?

Hallo,

EQU definert in der Regel "Equal" .. also mehr oder weniger ein
Textersatz.. du versuchst also an die ADRESSE 0x0001 zu schreiben, dort 
liegt vermutlich ein ROM und das kann nicht beschrieben werden.

Ich kenne den Assembler nicht, aber schau mal ob es sowas wie "DS" 
(Define Space), "DB" (Data Block) oder so gibt.

Gruß,
Christian

von Der G. (jonnyk)


Lesenswert?

JA das Gibt es aber habe leider keine Hilfe oder so dazu

von Der G. (jonnyk)


Lesenswert?

Wenn ich die variablen folgender massen deklariere müsste es gehen?

Lenge_23 DB 1

von 6645 (Gast)


Lesenswert?

Nein. Denn, db ist eine flashconstante. Dh das symbol Laenge_23 ist eine 
Flashconstante.

Variablen liegen im RAM bereich und sind eratmal nicht initialisiert. 
Moeglicherweise gibt es Assembler, die eine Initialisierung vornehmen, 
meist aber nicht. Um welchen Prozessor geht es denn ?

von Der G. (jonnyk)


Lesenswert?

Also weder mit DS noch mit DB funktioniert es. Aber ich habe folgendes:

Position  EQU 62

Ich habe das im Programm deklariert

weiter unten steht

Position +48

dann wird 62 mit 48 addiert.

Wie ist es moglich?

von Latissimo (Gast)


Lesenswert?

drei variablen an EINER Speicheradresse?

wie wäre es mit verschiedenen Speicheradressen?

laenge01 equ 0x123
laenge02 equ 0x124

Im datasheet müssten d. freien Speicheradr. stehen, die du verwenden 
darfst.

von Sebastian (Gast)


Lesenswert?

Vielleicht hilfts ja als Denkanstoss:
Bei AVRs kann man Variablen im Ram so anlegen:

Variable1: .Byte 2

Die Zahl nach .Byte gibt an, wie viel Byte man reservieren will.
Ist natürlich für AVRs, aber vielleicht ist's bei dir ja ähnlich.

Sebastian

von Der G. (jonnyk)


Lesenswert?

Hallo Leute.

Nein das stimmt nicht ganz.
Also wenn ich den wert nach EQU verändere verändert sich der wert der 
Variablen und nicht ihre addresse.

Das steht schon mal fest.
Abe ich habe auch mal gelesen das man mit EQU eine konstante anlegt und 
keine variable.

is es möglich?

von 6645 (Gast)


Lesenswert?

In AVRASM geht das so :

deklaration

MyInteger:   .byte 2;

zuweisung

    ldi temp, low(1234)
    sts MyInteger,temp
    ldi temp, high(1234)
    sts MyInteger+1,temp

Alles andere geht bei AVR nicht

von aminox86 (Gast)


Lesenswert?

Hallo Grosser,

bevor der Assembler/Compiler mit einer Variablen arbeiten kann,
muß diese dem Assembler/Compiler erst bekanntgegeben werden.

Der Name einer Variablen ist nichts anderes als die Adresse eines
Speicherplatzes im Datenraum des Prozessors. Erst wenn der
Copmiler/Assembler die Adresse der Variablen kennt, kann er
sinnvoll mit ihr arbeiten. Abhängig vom Assembler und/oder der
Maschinenarchitektur sind die Möglichkeiten ziemlich
unterschiedlich.
Generell muß es allerdings möglich sein, diese elementaren
Operationen mit jedem System in angebenen Reihenfolgen
durchzuführen.

Ich habe mal einige Beispiele in 8051-Assembler notiert, die dieses 
verdeutlichen sollen.

8051-Architektur, Assembler unterstützt keine Segmente
;** 1.Beispiel, kurz und kryptisch **
mov  20h, #1    ;die Speicherzelle (fehlendes Caret!) an
                ;Adresse 20h wird mit 1 belegt.
                ;Im Befehl sind sowohl der Adressraum
                ;(der interne Ram) als auch die Adresse
                ;der Speicherzelle kodiert
                ;(direkte Adressierung)

;** 2.Beispiel, kurz und lesbar **
;anweisungen an den Assembler
laenge  equ  1       ;laenge wird der Wert 1 zugewiesen
var_1  equ  20h      ;var_1 wird der Wert 20h zugewiesen
;ab hier wird der Prozessor aktiv
mov  var_1, #laenge  ;Speichermechanismus wie oben
                     ;fehlendes Caret bei var_1 ->
                     ;var_1 ist Speicherzelle
                     ;
;** oder 3.Beispiel, länger und auch lesbar **

mov  r0, #var_1      ;var_1 mit Caret -> var_1 Zahl, nämlich
                     ;20h wird nach r0 geladen
mov  @r0, #laenge    ;indirekte(indizierte) Adressierung von
                     ;var_1 über r0

Der vom Assembler erzeugte Programmcode kann dem Prozessor (in
der Regel) direkt zur Ausführung übergeben werden. Im Programm
verwendete Variablen, die im Ram liegen, müssen 'von Hand'
initialisiert werden.


8051-Architektur, Assembler unterstützt Segmente
;** 1.Beispiel **
laenge   equ  1
;Variable im internen Ram des Prozessors
;----------------------------------------------------------
_data  segment  name1 ;Erkärung eines (Daten)Segmentes im
                      ;internen Ram, beginnend ab Adresse 0000h
  org  20h
var_1  db  ?          ;var_1 wird an Adresse #20h, gerechnet ab
                      ;Segmentanfang,positioniert und es wird
                      ;Speicherplatz für 1 Byte reserviert
;----------------------------------------------------------
_code  segment name2  ;Erklärung des Programmsegmentes ab
                      ;Adresse 0000h
  .                   ;
  .                   ;irgendwelche Befehle
  .
mov  var_1, #laenge   ;Programm wie oben, var_1(im internen Ram)
                      ;wird mit 1 belegt
mov  r1, #var_1       ;oder hier indiziert durch r1, Wert über
                      ;den Akku in die Variable
mov  a, #laenge
mov  @r1, a
  .
  .                    ;weiter im Programm
  .
;** 2.Beispiel **
;!!initialisierte!! Variable im Rom
laenge   equ  1
;----------------------------------------------------------
_code  segment name1  ;Erklärung des Programmsegmentes ab
                      ;Adresse 0000h
  .                   ;
  .                   ;irgendwelche Befehle
  .
mov  dptr, #var_1     ;datapointer mit der 16-Bit-Adresse
                      ;der Variablen laden
clr  a                ;Zugriff auf den Wert von var_1 über den Akku
movc a, @a+dptr       ;Akku enthält jetzt laenge
  .                   ;
  .                   ;weitere Befehle

;Achtung: Das Programm darf die folgende Zeile nie erreichen,
;sonst gibt es ein Unglück

var_1  db  laenge     ;Romspeicherplatz an der Position von var_1
                      ;mit laenge initialisieren



Der in diesen Beispielen vom Assembler ausgebene Code muß (in der
Regel) an den Linker weitergereicht werden, der die in der
Assemblerdatei enthaltenen Positionierungsinformationen auswertet,
ggf weitere Module einbindet und ein ausführbares Programm erzeugt.
Daher sind die Adressangaben zu den Segmenten eher zur Orientierung
gedacht, der Linker kann die Segmente an jede sinnvolle Position
im Adressraum des Prozessors legen.
Für die Benennung bzw. Typisierung der Segmente gibt es keine
bindenden Übereinkünfte zwischen den Softwareherstellern. Jeder
kocht sein eigenes Süpplein.Daher sind die Segmentbezeichnungen
auch hier nur Orientierungspunkte.

Diese Verhältnisse ändern sich schlagartig, wenn das
Assemblerprogramm zusammen mit einem Hochsprachenprogramm
ausgeführt werden soll.
Das Assemblerprogramm muß korrekt in den Kontext der Hochsprache
eingebunden werden, damit das komplette System funktioniert. Es ist
unbedingt notwendig, die vom Compilerhersteller vorgebenen
Konventionen für Reservierung von Speicherplatz, Anlage von
Segmenten und den Datenaustausch zwischen den verschiedenen
Programmteilen zu beachten.

Eine der besten und ausführlichsten Darstellungen zu dieser
Thematik, die mir bekannt sind, ist hier zu finden:
  http://www.netzmafia.de/skripten/ad/thomas-c/index.html
Hier wird am Beispiel der 'X86-Architektur unter anderem das
Zusammenspiel von C und Turbo-Assembler ausführlich erörtert.

mfg

von W. B. (wb1)


Lesenswert?

Bei AVR

.equ wert1 = 0x80       ; Ram Adresse hex80
.equ wert1a = wert1+1   ;Ram Adresse hex81
.equ wert2 = 0x88       ;Ram Adresse hex88
.equ wert2a = wert2-1   ;Ram Adresse hex87

ldi r16,200
sts wert1,r16
sts wert2,yl
sts wert2a,yh
sts wert1a,r17



Ich mach das immer so, daß ich eine Anfangsadresse benutze von der ich 
dann die einzelnen Zellenbezeichner hochzähle

von Guido Körber (Gast)


Lesenswert?

Mit EQU definiert man keine Variablen, sondern Konstanten.

xyz EQU 5

Bedeutet, dass xyz dem Wert 5 entspricht. Ändern kann man das nicht mehr 
im weiteren Verlauf des Quelltextes (es sei denn es ist eine lokale 
Definition, aber das führt jetzt zu weit).

Wie man Variablen handhabt hängt vom jeweiligen Assembler und dem 
Prozessor ab. Prinzipiell muss man eine Speicheradresse angeben an die 
dann der Wert geschrieben wird. Wie diese Speicheradresse zugewiesen 
wird ist völlig unterschiedlich je nach Assembler, ebenso wie die 
Schreibweise für den Zugriff auf den Speicher vom Assembler abhängt.

Wenn der Assembler keine Speicherzuteilung a la DS/DB o.ä. hat, muss 
mann ggf. die Speicheradressen mit EQU definieren, also etwa:

Variable1 EQU $45

Dabei ist $45 die Adresse im RAM wo die Daten hin sollen. Macht man dann 
ein

STA Variable1

Dann wird (so der Assembler nicht völlig anders funktioniert als ich es 
erwarte) der Wert in A in die Speicherstelle $45 geschrieben.

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.