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
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.
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...
@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).
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.
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