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