ASM-Problem bei Speicher >16 Bit

Gast #3261988
Lesenswert?

Hi

>Das muß ich erst einmal verdauen.

Lass es doch einfach den Assembler machen:
1
  .macro load_z
2
    ldi ZL,Low(@0)
3
    ldi ZH,High(@0)
4
    .if Low(@0)+ 256*High(@0) < $8000
5
      clr r16
6
    .else
7
      ldi r16,1              
8
    .endif
9
      out RAMPZ,r16
10
  .endmacro

MfG Spess
OP #3262082
Lesenswert?

Hallo Spess,

zum besseren Verständnis mein Problem:

Ich habe den Speicher mit Bilddaten gefüllt, die ich jetzt von oben 
(d.h. höchste Adresse) nach unten auslesen und zu einem Controller 
übertragen will.

Wenn ich es richtig verstehe, dann kann ich durch setzen des RAMPZ Bits 
den Zeiger auf die oberste Adresse setzen und dann mit lpm (oder elpm?) 
und sbiw nach unten gehen. Muß ich dann bei Erreichen der 64K Grenze das 
RAMPZ Bit wieder löschen?

Gruß Bruno
Gast #3262138
Lesenswert?

Hi

>Wenn ich es richtig verstehe, dann kann ich durch setzen des RAMPZ Bits
>den Zeiger auf die oberste Adresse setzen und dann mit lpm (oder elpm?)
>und sbiw nach unten gehen.

Ja.

Muß ich dann bei Erreichen der 64K Grenze das RAMPZ Bit wieder löschen?

Ja. Allerdings würde ich das 'automatisieren':
1
  clr r2    ; Null
2

3
  .....
4

5
  ldi ZL,1
6
  mov r3,ZL           ;
7
  out RAMPZ,r3        ; RAMPZ laden
8
  ldi ZL,Low(xy*2)
9
  ldi ZH,High(xy*2)   ; Z laden
10

11
  ....
12

13
  lpm r16,Z           ; Byte holen
14
  sbiw Z,1
15
  sbc r3,r2
16
  out RAMPZ,r3        ; (RAMPZ:Z) - 1

also keine Vergleiche und bedingte Sprünge.

>Ich habe den Speicher mit Bilddaten gefüllt, die ich jetzt von oben
>(d.h. höchste Adresse) nach unten auslesen und zu einem Controller
>übertragen will.

Die ungedrehte Reihenfolge wäre besser. Dann könntest du
1
  elpm r16,Z+

benutzen. Bei elpm wird Z und PAMPZ als 24 Bit Register benutzt und du 
brauchst dich nicht um die 64K-Grenzen zu kümmern. Allerdings kennt elpm 
nur das postincrement.

MfG Spess
Gast #3262841
Lesenswert?

Hi

>Woher kommt der Wert in r2 wenn die Adresse von Z nach - geht??

Von hier:

Beitrag "Re: ASM-Problem bei Speicher >16 Bit"

  clr r2    ; Null

Wenn Z = $0000 ist und das sbiw ausgeführt wird enthält Z den Wert $FFFF 
und das Carry-Flag wird gesetzt. sbc subtrahiert dadurch 1 (0 + C-Flag) 
von r3. Mit dem 'out RAMPZ, r3' wird dann das RAMPZ0-Bit gelöscht. Damit 
zeigt dann Z auf die oberste Adresse der unteren 64k.

MfG Spess
Gast #3263430
Lesenswert?

Hi

>Was ich aber nach wie vor nicht verstehe ist,
>warum das Carry Flag von Z in r2 gesetzt wird.

Nicht in r2. Das ist immer Null.

Dir ist anscheinend sbc (Subtract with Carry) nicht so richtig geläufig.

Mal mit Zahlen:

C-Flag = 0   sbc 5,2       Ergebnis: 3
C-Flag = 1   sbc 5,2       Ergebnis: 2

Solange Z>=1 ist wird bei sbiw Z,1 das Carry-Flag nicht gesetzt. r3 
bleibt damit unverändert (1-0/0-0). Bei einem negativen Überlauf (Z=0 - 
1) setzt sbiw das Carry-Flag. Und in dem Fall wird von r3 (0+1) 
abgezogen. Bei out wird dann RAMPZ0 gelöscht.

MfG Spess
Gast #3263434
Lesenswert?

Ich würde Dir dringend empfehlen, so Du weiterhin in Assembler 
programmieren willst, Dir die Beschreibung der Befehle anzuschauen.
Der Prozessor schleppt einen ganzen Sack voll Flags mit sich herum, die, 
in der Hauptsache, von arithmetischen Operationen gesetzt bzw. gelöscht 
werden.
OP #3263463
Lesenswert?

Ich meine ich habe es verstanden.
Das Carry Flag oder auch andere Flags sind unabhängig von den Registern 
und werden beim nächsten Carry-Befehl wirksam. In unserem Beispiel 
könnte somit statt r2 auch jedes andere Register stehen, soferne es 0 
ist.

Danke für die Geduld!
Gast #3263512
Lesenswert?

@Bruno

>Ich meine ich habe es verstanden.

Etwas vereinfacht ausgedrückt kann man sagen:
a) Es gibt Befehle, die die Flags beeinflussen und
b) Befehle, die diese unverändert lassen.

Man muss dabei aber höllisch aufpassen. Z.B.

LDI  R16,20       ; Lade 20 nach R16, keine Flagänderung
SUBI    R16,20       ; Subtrahiere 20 von R16, Flags verändert (Z)
; Ein BREQ XXX an dieser Stelle würde zu einer Verzweigung führen
; da Z=1 (stimmt ja auch)
LDI     R16,10       ; Lade 10 nach R16, keine Flagänderung
; Ein BREQ XXX an dieser Stelle würde zu einer Verzweigung führen
; da immer noch Z=1 - Obwohl R16 mittlerweile 10 ist.
#3263546
Lesenswert?

>; Ein BREQ XXX an dieser Stelle würde zu einer Verzweigung führen
>; da Z=1 (stimmt ja auch)
>LDI     R16,10       ; Lade 10 nach R16, keine Flagänderung
>; Ein BREQ XXX an dieser Stelle würde zu einer Verzweigung führen
>; da immer noch Z=1 - Obwohl R16 mittlerweile 10 ist.

Das kann ich mir nicht vorstellen. Hast du das mal ausprobiert?

Gruß Jonas
Gast #3263554
Lesenswert?

Hi

>Das kann ich mir nicht vorstellen. Hast du das mal ausprobiert?

Ist schon richtig so. Ein ldi-Befehl beeinflusst keine Flags. Um auf das 
veränderte Register r16 zu reagieren müsste ein 'tst r16' gemacht 
werden.

MfG Spess
OP #3265448
Lesenswert?

Hi,

ich muß mich noch einmal melden!
In der Zwischenzeit habe ich versucht meinen Code arbeitsfähig zu 
machen, was mir letztendlich auch gelungen ist.
Ich bin dabei allerdings auf ein Problem gestoßen, das ich mir wieder 
einmal nicht erklären kann.

Ich habe zuerst versucht die Version von Spess zu realisieren u.z.wie 
folgt:
1
Bild_loop:
2
  elpm  temp, Z
3
  st  X+, temp
4
  sbiw  Z, 1
5
  sbc  r3, r2
6
  out  RAMPZ, r3
7
  cp  XH, temp1
8
  brne  Bild_loop
9
  ret

mit X und temp1 wird die Speicheradresse neu eingestellt und hat hiermit 
eigentlich nichts zu tun.

Das Ergebnis ist in Bild1 zu sehen, wobei jetzt aber auch noch 
Spiegelungen von der Kamera enthalten sind. Bei Vergrößerung sind die 
Fehler im Mittelteil aber deutlich zu sehen. Dazu kommen noch die 
Doppelungen oben und unten, die auf einen Speicherfehler hindeuten.
Erklären kann ich mir das nicht, da ich mit dem Debugger eigentlich 
keinen Fehler finden konnte.

Funktioniert hat es letztendlich damit:
1
Bild_loop:
2
  elpm  temp, Z
3
  st  X+, temp
4
  sbiw  Z, 1
5
  cpi  ZH, 0
6
  breq  RAMP
7
_Bild_loop:  
8
  cp  XH, temp1
9
  brne  Bild_loop
10
  ret
11
RAMP:
12
  cpi  ZL, 0
13
  brne  _Bild_loop
14
  clr  r3
15
  out  RAMPZ, r3
16
  rjmp  _Bild_loop

Das Ergebnis sieht man in Bild2

Hat jemand eine Erklärung?

Mfg Bruno
Angehängte Dateien:
OP #3265470
Lesenswert?

Hallo Spess,

> Bist du sicher, das du r2 auf Null gesetzt hast?

Ich muß gestehen, daß ich es nicht ausdrücklich auf Null gesetzt habe, 
da ich es im restlichen Programm nicht benutzt habe. Das ist natürlich 
Lotterie, ich weiß. Ich melde Dir das Ergebnis nach Korrektur.

Gruß Bruno

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