8051: Problem mit mov bzw. rlc / rrc Befehlen

OP #2555229
Hallo zusammen,
ich hab das Problem, dass beim hin und her Kopieren eines Bytes nach 
einem rotier Befehl auf einmal alle Bits gelöscht sind. Konkret geht es 
um die Stelle an der auskommentiert "weiterer Code" steht. Wenn ich die 
mov Befehle davor und danach (mov nb0,a & mov a,nb0) entferne 
funktioniert es auf einmal. Ich komm einfach nicht drauf woran das 
liegen könnte. Eigentlich wird doch nur der Akku auf nb0 geschrieben und 
danach wieder nb0 auf den Akku.
Komischerweise werden die Bits nicht gelöscht wenn ich den Rotierbefehl 
weglasse. Aber ohne macht das Programm halt keinen Sinn.
1
#include <REG8253.H>
2

3
;Stack-Bereich im indirekt adressierbaren internen RAM
4
stackbereich  segment idata
5
  rseg  stackbereich
6
  ds  10h    ;16 Byte
7

8
;Bytes im int. direkt adressierbaren RAM
9
dir_daten  segment data
10
  rseg  dir_daten
11
nb0: ds 1
12

13
;LJMP von Adresse 0 im Code-Speicher zum Programmanfang
14
  cseg  at  0
15
  ljmp  start
16

17
;Programmcode (Code-Beginn über Linker festgelegt)
18
programmcode  segment code
19
  rseg  programmcode
20
  using  0    ;Registerbank 0 für Programmcode (rseg -> verschiebbar)
21

22
;Initialisierung  Stack
23
start:
24
  mov sp,#stackbereich-1  ;STACK-Definition
25

26
;--------------------------------------------------------------------------
27

28

29
  mov nb0,#0a6h
30
main:
31

32
  clr c
33
  mov a,nb0    ;Nennerbyte 0 durch Carry nach links
34
  rlc a
35
  mov nb0,a
36

37
  ;!!!weiterer Code!!!
38

39
  mov a,nb0    ;Nennerbyte 0 auf Port 0 ausgeben
40
  cpl a
41
  mov p0,a
42

43
  ljmp main
44

45

46
  end

Gruß
Michael
#2555320
Alle Segmente beginnnen bei 0.
Dein nb0 zeigt also auf R0 der ersten Bank und der Stack auch.

Du mußt daher sinnvolle Adressen vergeben.
Daten legt man gerne hinter den bitadressierbaren Bereich, also ab 30h.
Und den Stack einfach hinter das letzte Datenbyte.
1
  rseg at 30h
2
nb0:   ds 1
3
; hier alle weiteren Daten
4
stack: ds 10h


Peter
#2555338
Wenn ich das richtig verstehe, funktioniert dieser Fetzen schon nicht. 
Korrekt?

Michael L. schrieb:
> mov nb0,#0a6h
> main:
>
>   clr c
>   mov a,nb0    ;Nennerbyte 0 durch Carry nach links
>   rlc a
>   mov nb0,a

Der Stack ist dem hier nicht im Weg. Auch R0 nicht.

Was passiert, wenn Du vor und hinter das 'rlc a' ein nop setzt?
Sollte das funktionieren, dann hast Du einen handfesten Hardware-Bug 
gefunden.


Gruß

Jobst
OP #2555413
@ Peter:
Zur Speicherplatzeinteilung fehlen mir leider noch einige Grundlagen. 
Das hab ich bisher nur aus einer Vorlage genommen und halt versucht zu 
verstehen. Was die einzelnen Direktiven machen ist inzwischen glaub 
relativ klar. Aber bei dem Sinn der dahinter steckt haperts noch. Hast 
du dazu vielleicht einen guten Link oder ähnliches. Hab im Netz noch 
nichts wirklich hilfreiches gefunden.
rseg bedeutet doch reloctable segment, also verschiebbares Segment. 
Sucht der Linker dann nicht selbst eine passende Adresse aus? Die 
Direktive at hab ich bisher nur in Kombination mit cseg (code segment) 
gesehen. Daher dachte ich dass rseg für variable Adressen ist und cseg 
at für feste Adressen.
Den Stack hinter den Programmcode zu hängen werd ich gleich mal 
ausprobieren.

@Jobst:
Ein nop vor und hinter dem rlc bringt nichts. Aber ich konnte das 
Problem noch ein bischen eingrenzen. Wenn ich nur den Befehl mov nb0,a 
also die Zeile nach rlc und vor "weiterer Code"auskommentiere werden die 
Bits nicht gelöscht. Das wär also in dem von dir genannten Codesegment.

Gruß
Michael
OP #2555740
Also, da sollt ich wohl doch etwas genauer werden. Der Codeblock 
"Nennerbyte 0 auf Port 0 ausgeben" ist dazu da um den Wert von nb0 
anzuzeigen. Zwischen diesem Open-Drain-Port und VCC hängen LEDs mit 
Vorwiderstand. Deswegen auch cpl. Darauf dass alle Bits 0 sind bin ich 
gekommen weil keine LED leuchtet.

Der Befehl "mov nb0,a" muss sein, da es eim eigentlichen Programm (3 
Byte Division) außer nb0 noch nb1 und nb2 gibt und die Werte im Programm 
immer wieder gebraucht werden. Eigentlich sollen die Bits in nb0 rotiert 
werden, aber das geht ja nicht direkt.

Wenn ich das gesamte Programm / den Programmablaufplan posten soll 
einfach melden.

Gruß
Michael
OP #2556284
So ein blöder Fehler...
Klar dass es dann nicht funktionieren kann. Ich hätt einfach die 
Wertzuweisung hinter oder die Rotation vor die main Marke setzen müssen.

Das eigentliche Unterprogramm für das der Test war funktioniert zwar 
immer noch nicht richtig. Doch zumindest krieg ich nichtmehr lauter 
Nullen. Aber ich versuchs besser erstmal selbst hinzukriegen.

Danke für die Hilfe

Gruß
Michael

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 14 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.