Forum: Mikrocontroller und Digitale Elektronik AVR Assenbler 16 Bit Zahl auf Intervall testen


von Fritz (Gast)


Lesenswert?

Hi,

irgendwie komme ich nicht mit cp und cpc zurande ...

also sagen wir mal ich habe in r16 und r17 eine Zahl 1 und in r20 und 
r21 eine 3.

ldi r16, 1
ldi r17, 1
ldi r20, 3
ldi r21, 3

in r18 und r19 steckt nun irgendeine Zahl.

Wie muss ich die Abfrage in Assembler gestalten um herauszufinden, dass 
diese Zahl

r18,r19 >= r16,r17 und r16,r17 <= r20,r21 ist. Also im Intervall 
inklusive der Grenzen?


mfg
Fritz

: Verschoben durch User
von Jacko (Gast)


Lesenswert?

Da gibt es die passenden Befehle für: CP und CPC und BR??...

von Karl M. (Gast)


Lesenswert?

Hallo,

über das Carry-Bit.

CP Rd,Rm und CPC Rd,Rm

dann die entsprechen Sprünge für unsigned Vergleiche nutzen.

Denke daran "A <= B" kann man auch als "not(A > B)" und "A >= B" als 
"not(A < B)" schreiben.

von Jacko (Gast)


Lesenswert?

Tz-tz Karl.M!

Du weißt doch nicht, ob big/little-endian. Oder signed/unsigned.
Na dafür vergleichst du vorsichtshalber nur ein Registerpaar zweimal.

Gut so! ;-)
Warten wir mal lieber auf Nachfragen...

von Falk B. (falk)


Lesenswert?

@Fritz (Gast)

>irgendwie komme ich nicht mit cp und cpc zurande ...

Hmm.

>also sagen wir mal ich habe in r16 und r17 eine Zahl 1 und in r20 und
>r21 eine 3.

>ldi r16, 1
>ldi r17, 1
>ldi r20, 3
>ldi r21, 3

Ok, aber dann hast du in deinem Registerpaar R16/r17 die 16 Bit Zahl 
1*256 + 1 = 257 sowie in r20/r21 3*256 + 3 = 771. Das sollte man auch so 
formulieren, vor allem im Quelltext.

>in r18 und r19 steckt nun irgendeine Zahl.

>Wie muss ich die Abfrage in Assembler gestalten um herauszufinden, dass
>diese Zahl

>r18,r19 >= r16,r17 und r16,r17 <= r20,r21 ist. Also im Intervall
>inklusive der Grenzen?

Passende Vergleiche mittels cp und cpc. Ein Vergleich mittels cp/cpc ist 
mathematisch identisch mit sub/sbc, nur daß das Ergebnis nicht im 
Zielregister gespeichert wird, wohl aber die Flags beeinflußt. da es 
hier um 16 Bit Operationen auf einer 8 Bit CPU geht, muss man low und 
high Byte der Reihne nach vergleichen und beim High Byte das Carry Bit 
berücksichtigen. Das tuen cp/cpc.
1
vergleich:
2
    ldi     r16, low(257)
3
    ldi     r17, high(257)      ; untere Grenze
4
    ldi     r20, low(771)
5
    ldi     r21, high(771)      ; obere Grenze
6
7
    ldi     r18, low(772)
8
    ldi     r19, high(772)      ; Prüfwert für Simulation
9
10
    cp      r18, r16            ; berechne r19:r18 - r17:r16
11
    cpc     r19, r17
12
    brlo    wert_ausserhalb     ; r19:r18 < r17:r16
13
14
    cp      r20, r18            ; berechne r21:r20 - r19:r18
15
    cpc     r21, r19
16
    brlo    wert_ausserhalb     ; r21:r20 < r19:r18
17
18
wert_im_intervall:
19
    ; mach hier was
20
    nop
21
    rjmp    weiter_hier
22
23
wert_ausserhalb:
24
    ; mach hier was anderes
25
    nop
26
27
weiter_hier:

Es ist manchmal ein wenig tricky, weil die Sprungbedingungen beim AVR 
nur gleich (=) ungleich (!=), größer gleich (>=) und kleiner (<) kennen. 
Das Gegenteil muss man durch Vertauschen der Operanden logisch 
erreichen, siehe  Tabelle der Sprungbefehle in der Assemblerdoku 
(Conditional Branch Summary).

von Falk B. (falk)


Lesenswert?


von Jacko (Gast)


Lesenswert?

Hach, da wurden mal wieder vom lieben Onkel die Hausarbeiten
gemacht.

Lerneffekt: NULL.

Ganz abgesehen davon, dass vielleicht BRLT erforderlich gewesen
wäre, oder die big/little-endian-Frage gelöst werden sollte.

von Fritz (Gast)


Lesenswert?

@Falk

Vielen Dank für den Code. Zwischenzeitlich ist es mir gelungen. Ich 
frage mit BRSH ab.

@Jacko

Lerneffekt: NULL.

Danke!



Fritz

von Dünnwandtroll (Gast)


Lesenswert?

allenfalls gaebs noch den Simulator, da kann man sich durchpermutieren 
bis es passt.

von --- (Gast)


Lesenswert?

> da kann man sich durchpermutieren bis es passt

Das ist immerhin wissenschaftlich anerkanntes Vorgehen.

von Holger (Gast)


Lesenswert?

Servus, man sieht es hier wieder einmal. Wenn die ganzen Klugscheißer, 
Spacken, Schlauberger, Highpotentials und was weiß ich nicht noch alles 
einfach mal die Fresse halten, dann wäre dieser Thread mit maximal drei 
Posts erledigt gewesen.

Fritz fragt, Falk antwortet, Fritz dankt.


Leider zieht sich das durch das ganze Forum. Warum halten diejenigen, 
die sich von einer einfachen Fragestellung angepisst fühlen, nicht 
einfach die Finger still?


Holger

Beitrag #5259550 wurde von einem Moderator gelöscht.
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.