Hallo zusammen,
alle Jubeljahre beschäftige ich mich mit Mini-Controller-Projekten, so
dass ich nicht wirklich tief in der Materie stecke.
Momentan habe ich einen kleinen Temperatur- und Spannungswächter auf dem
Tisch, soll mit einem ATTiny45 realisiert werden (habe ich gerade in der
Bastelkiste, ist schon überdimmensioniert).
Zum Punkt: ich möchte 16 Bit Messwerte im RAM mit 16 Bit Konstanten
vergleichen. Dabei fällt auf, dass der Zugriff mit low / high(Name) bei
den Konstanten funktioniert, aber bei Variablen im RAM Müll liefert.
Beispiel:
;Konstante
.equ NTCblau = 0x0123 ; kalt, <60 Grad
;Variable im RAM
.DSEG ; Umschalten auf das SRAM Datensegment
NTCMittel: .BYTE 2
;...
; Das funktioniert
ldi r22, low (NTCblau)
ldi r23, high(NTCblau)
;Das liefert Müll
lds r22, low (NTCMittel)
lds r23, high(NTCMittel)
;Der Workaround
lds r22, NTCMittel
lds r23, NTCMittel+1
Kann man das low/high Konstrukt nicht für RAM-Zugriff nutzen?
Warum meckert dann der Assembler nicht?
Hast du denn überhaupt erst was an die Stelle im RAM geschrieben?!
Einfach nur etwas Laden liefert irgendwelche zufälligen Werte, die beim
Reset da drin stehen.
Holler schrieb:> Kann man das low/high Konstrukt nicht für RAM-Zugriff nutzen?
Nein. Es ergibt an dieser Stelle auch überhaupt keinen Sinn. NTCblau ist
eine Konstante, die kann der Assembler zur Übersetzungszeit in low- und
high-Teil zerlegen. NTCMittel hingegen ist eine Adresse. Eine 16-Bit
Variable belegt im Speicher aber zwei aufeinanderfolgende
Speicherplätze. Vulgo: die Startadresse und Startadresse+1
> Warum meckert dann der Assembler nicht?
Weil es syntaktisch korrekt ist.
Wenn du mit derartigen Trivialitäten wie dem Zugriff auf Variablen mit
mehr als einem Byte überfordert bist, dann verwende nicht Assembler,
sondern eine Hochsprache. Z.B. C. Oder meinetwegen auch BASIC (BASCOM)
oder LunaAVR. Die verbergen diese Details vor dem Anwender.
Äh, moment, falsch gelesen.
Holler schrieb:> ;Das liefert Müll> lds r22, low (NTCMittel)> lds r23, high(NTCMittel)
Das kann nicht funktionieren... Das lädt r22 von der Adresse
low(NTCMittel) - also einer völlig anderen als gewünscht, und r23 von
high(NTCMittel), also von einer noch ganz anderen Adresse.
Holler schrieb:> lds r22, NTCMittel> lds r23, NTCMittel+1
Das ist richtig - r22 kommt von der Adresse NTCMittel, und r23 von der
nächsten.
Holler schrieb:> Hallo zusammen,> alle Jubeljahre beschäftige ich mich mit Mini-Controller-Projekten, so> dass ich nicht wirklich tief in der Materie stecke.>> Momentan habe ich einen kleinen Temperatur- und Spannungswächter auf dem> Tisch, soll mit einem ATTiny45 realisiert werden (habe ich gerade in der> Bastelkiste, ist schon überdimmensioniert).>> Zum Punkt: ich möchte 16 Bit Messwerte im RAM mit 16 Bit Konstanten> vergleichen. Dabei fällt auf, dass der Zugriff mit low / high(Name) bei> den Konstanten funktioniert, aber bei Variablen im RAM Müll liefert.> Beispiel:>> ;Konstante> .equ NTCblau = 0x0123 ; kalt, <60 Grad>> ;Variable im RAM> .DSEG ; Umschalten auf das SRAM Datensegment> NTCMittel: .BYTE 2> ;...> ; Das funktioniert> ldi r22, low (NTCblau)> ldi r23, high(NTCblau)>> ;Das liefert Müll> lds r22, low (NTCMittel)> lds r23, high(NTCMittel)>> ;Der Workaround> lds r22, NTCMittel> lds r23, NTCMittel+1>> Kann man das low/high Konstrukt nicht für RAM-Zugriff nutzen?
Nein,
lds erwartet eine 16Bit-Speicheradresse des SRAM,
Low liefert dir die unteren 8-Bit der Adresse, High die oberen 8-Bit
1
lds r22,NTCMittel
2
lds r23,NTCMittel+1
ist die richtige Wahl
ich habe mir da entsprechende Makros angelegt
1
.macro ldsw
2
lds @0H,@1
3
lds @0L,@1+1
4
.endmacro
5
6
im Code:
7
lsw X,NTCMittel
Ob du im Ram erst das H und dann das L Byte oder umgekehrt speicherst
bleibt dir überlassen.
Sascha
Fred schrieb:> Ich würde NTCMittel ja mal als .Word Variable definieren, dann klappts> vielleich auch mit dem Low/High Zugriff...
Völlig egal, Assembler ist nicht typisiert... Für manche Leute der
Hauptgrund, das zu verwenden!
Danke für die superschnellen Antworten!
@Dr. Sommer (Gast): ja da stand etwas sinnvolles im RAM. Der Zugriff
über das low/high Kontrukt lieferte aber weder den Inhalt noch die
Adresse sondern irgendwas beliebiges.
@Axel Schwenke: Überfordert fühle ich mich nicht, Assembler ist schon
das einfachst mögliche Werkzeug. Habe die Lösung ja schon in meinem
Eingangspost skizziert. Dachte halt, dass der Assembler das selbst
auflösen kann wenn er schon nicht meckert. Das Kontextwissen hat er ja.
Man könnte sich den Maschinencode ansehen was der Assembler daraus
macht.
Holler schrieb:> Dachte halt, dass der Assembler das selbst> auflösen kann wenn er schon nicht meckert. Das Kontextwissen hat er ja.
Naja, was genau soll der Assembler da sehen? Er sieht zwei völlig
unterschiedliche Adressen, aber das kann ja Absicht sein. Woher soll er
wissen dass du die Adressen falsch berechnest, und dass r22 und r23
zusammen gehören?
Disassemblierten Code anschauen kann helfen...
Dr. Sommer schrieb:> Disassemblierten Code anschauen kann helfen...
Was soll der Quatsch? Das Assemblat hast Du vor Dir- da gibts nix zu
"Disassemblieren"...
Fred schrieb:> Was soll der Quatsch? Das Assemblat hast Du vor Dir- da gibts nix zu> "Disassemblieren"...
Doch, in der Disassembly sieht man die vom Assembler/Linker berechneten
Adressen in "Reinform". Da würde man erkennen, dass das genutzte
low()/high() -Konstrukt nicht das beabsichtigte produziert.
Dr. Sommer schrieb:> Fred schrieb:> Was soll der Quatsch? Das Assemblat hast Du vor Dir- da gibts nix zu> "Disassemblieren"...>> Doch, in der Disassembly sieht man die vom Assembler/Linker berechneten> Adressen in "Reinform". Da würde man erkennen, dass das genutzte> low()/high() -Konstrukt nicht das beabsichtigte produziert.
Ok, da hast Du Recht.
Wenn die Variable z.B. auf 400/401H steht würde via lds zum einen (low)
der Inhalt von 00H, zum anderen (high) von 04H gelesen. Was sich auf
diesen Adressen lesbar befindet steht noch einmal auf einem anderen
Blatt.
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