AVR Assenbler 16 Bit Zahl auf Intervall testen

Gast #5258255
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
Gast #5258348
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.
Gast #5258359
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...
#5258383
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).
Gast #5258397
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.
Gast #5258872
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.

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