movlw: Berechnung des Literal

OP #7371005
Lesenswert?

MPLAB, Assembler, PIC16F1512:

Warum funktioniert der folgende Ausdruck nicht?

[movlw 0x90+kanal-0x1]

Inhalt von "kanal" = 0x1 Adresse von "kanal" = 0x30

w soll geladen werden mit 0x90 + 0x1 - 0x1 = 0x90

Tatsächlich berechnet der Assembler diesen Wert aber mit 0xC0.
Statt den Inhalt der Zelle "kanal" zu nehmen, rechnet der Assembler wohl mit der Adresse der Zelle "kanal". Wie erreiche ich das richtige Ergebnis?

OP #7371045
Lesenswert?

Vielen Dank für die schnelle Information!

An welcher Stelle fehlt das #-Zeichen?

Wenn ich die Antwort richtig verstehe, dann kann ich mit oder ohne #-Zeichen keinesfalls auf den Inhalt von "kanal" zugreifen. Der Assembler rechnet immer nur mit der Adresse.

Zum Studium der Adressierungsarten: Ja, das ist notwendig, denn ich bin Anfänger...

OP #7371074
Lesenswert?

Vielen Dank für den Hinweis. Dann muss ich das wohl auflösen in folgende Programmzeilen:

movlw h'90' addwf kanal,0 ;w = w + kanal (Inhalt von kanal) movwf ON ;ON = w decf ON,1 ;ON = ON - 1

Schade, ich hatte geglaubt, dass man dies mit nur einer Zeile machen könnte: movlw 0x90+kanal-0x1

Jetzt sind es immerhin 4!

#7371125
Lesenswert?

addwf kanal,0 ;w = w + kanal (Inhalt von kanal)

Das ist zwar nicht falsch, besser waere: addwf kanal,w ;w = w + kanal (Inhalt von kanal)

Dann ist der Kommentar unnoetig.

Genau so: decf ON,1 ;ON = ON - 1

decf ON,f ;ON = ON - 1 oder gleich decf ON ;ON = ON - 1

Das ein PIC kein ARM ist, hast du ja schon festgestellt.

Und sparen kann man beim PIC am besten, wenn man sich klar macht, dass das w-Register eben kein Akku ist, sondern nur ein Hilfsregister um literale Werte laden zu koennen. Man rechnet eben direkt mit den Registern. Das Ergebnis einer Operation steht danach im Register. Weiteres Speichern: ueberfluessig.

OP #7371179
Lesenswert?

Vielen Dank für die wertvollen Tipps. Dennoch habe ich noch folgende Fragen:

In der PIC-Befehlsbeschreibung steht aber, dass man "0" oder "1" hinter dem Komma schreiben soll, nicht aber "f", "w" oder gar "nichts"! Das verwirrt natürlich den Laien und wirft die Frage auf, wo man nachlesen kann, welche Bezeichnungen hinter dem Komma zulässig sind. In der Befehlsbeschreibung PIC kennt man nur "0" oder "1". Ersetzt "f" die "1"? Ersetzt "w" oder " " die "0"? Jedenfalls ist "f" oder "w" viel anschaulicher, als "0" oder "1"!

#7371205
Lesenswert?

Jedenfalls ist "f" oder "w" viel anschaulicher, als "0" oder "1"!

Ja eben :).

Der Fall

"nichts"

ist der Default. Und der steht sehr wohl in der Beschreibung. Ob das f und w in den Assembler "eingebaut" ist, oder einfach als EQU in einem Headerfile steht? Das kannst du ja selbst rauskriegen.

Zum Lesen: https://www.sprut.de/electronic/pic/grund/grund.htm https://www.sprut.de/electronic/pic/assemble/befehle.html

#7371453
Lesenswert?

Michael B. schrieb:

Schade, ich hatte geglaubt, dass man dies mit nur einer Zeile machen könnte: movlw 0x90+kanal-0x1

Man muß sich schon mit dem Befehlssatz beschäftigen, wenn man Assembler programmieren will.

MOVLW erwartet eine Konstante als Argument. Es kann also keine Variable aus dem RAM lesen. Der Assembler berechnet daher 0x90+0x30-0x1 und übergibt es dem MOVLW.

Angehängte Dateien:
OP #7371523
Lesenswert?

Vielen Dank für diese Informationen und die Zusammenhänge sind jetzt völlig klar. Meine Bemerkung zum Befehlssatz und der "0" bzw. "1" bezog sich mehr auf den Befehl ADDWF, dessen Beschreibung wie folgt lautet:

ADDWF Add W and f Syntax: [ label ] ADDWF f,d Operands: 0  f  127 d 0,1 Operation: (W) + (f)  (destination) Status Affected: C, DC, Z Description: Add the contents of the W register with register ‘f’. If ‘d’ is ‘0’, the result is stored in the W register. If ‘d’ is ‘1’, the result is stored back in register ‘f’.

Hier kann man für "d" gemäß Beschreibung nur "1" oder "0" einsetzen. Von "w" oder "f" ist hier keine Rede. Nach Deinen Erklärungen verstehe ich das wie folgt: "0" würde dann "ADDWF xxx,w" entsprechen und "1" "ADDWF xxx,f". "w" ist somit Platzhalter für "0" und "f" ist somit Platzhalter für "1". Das dürfte im Assembler eingebaut sein, denn ansonsten bekäme ich eine Fehlermeldung bei Anwendung von "w" oder "f".

#7371616
Lesenswert?

Das dürfte im Assembler eingebaut sein, denn ansonsten bekäme ich eine Fehlermeldung bei Anwendung von "w" oder "f".

Vermutlich ja. Weil der Assembler ja auch ohne weitere Hilfe den Default kennt. Trotzdem koennte "irgendwo" in einem Includefile ja auch ein:

f EQU 1 w EQU 0

stehen. Das koenntest du zur Vervollstaendigung deines Wissens ja mal ausprobieren. So ein EQU wuerde ja dann ueberall in einem Assemblerfile seine Wirkung tun. Nicht nur in der Zielangabe von Befehlen.

Also z.B. movlw #f

:)

#7371729
Lesenswert?

Michael B. schrieb:

Vielen Dank für den Hinweis. Dann muss ich das wohl auflösen in folgende Programmzeilen:

movlw h'90' addwf kanal,0 ;w = w + kanal (Inhalt von kanal) movwf ON ;ON = w decf ON,1 ;ON = ON - 1

Schade, ich hatte geglaubt, dass man dies mit nur einer Zeile machen könnte: movlw 0x90+kanal-0x1

Jetzt sind es immerhin 4!

Dass es 4 Zeilen sind, liegt daran, dass du das Ergebnis noch nach ON transportierst, sonst wären es 3 Zeilen. Man kann aber noch eine Zeile einsparen, wenn man nicht extra dekrementiert sondern:

movlw 0x90 - 0x01 addwf kanal,w

OP #7371830
Lesenswert?

Hallo motopick,

vermutlich findet man das im File "p16F1512" (include <p16F1512.inc>). Leider kann ich diese Datei im MPLAB nicht öffnen. Unter "Projects" ist dieses File nicht zu finden...

Noch einmal herzlichen Dank für Deine Zeit, die Du mit der Beantwortung meiner Fragen geopfert hast. Das hat mir deutlich weitergeholfen!

Gast #7371837
Lesenswert?

Michael B. schrieb:

vermutlich findet man das im File "p16F1512" (include <p16F1512.inc>).

So ist es:

;===================================================================== ; ; Register Definitions ; ;=====================================================================

W EQU H'0000' F EQU H'0001'

OP #7371838
Lesenswert?

Hallo berndmm,

vielen Dank für Deinen heißen Tipp! Dann geht es ja doch erheblich kürzer (kanal=0x1):

1
movlw  0x90-0x01       ;w = 0x8F
2
addwf  kanal,w         ;w = 0x8F + kanal = 0x90

Das sind sogar 2 Zeilen weniger, wenn ich ON nicht brauche! Wie konnte ich das übersehen? Jetzt werde ich das gesamte Programm danach untersuchen, ob ich diesen Fehler auch noch woanders gemacht habe... Herzlichen Dank!

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren